fix: leave setup wizard after completion
Release / release (push) Canceled after 0s

This commit is contained in:
Qiufeng
2026-08-18 11:38:28 +08:00
parent bb5e63aaf0
commit 10d2e2f0d1
3 changed files with 75 additions and 10 deletions
+66
View File
@@ -137,3 +137,69 @@ test('confirms completion after the setup response is interrupted by a service r
await expect(page.getByText('网络请求失败')).toHaveCount(0);
await expect(page).toHaveURL(/\/login$/, { timeout: 15_000 });
});
test('leaves the completed wizard when post-completion status polling is unavailable', async ({ page }) => {
let completionStarted = false;
await page.route('**/api/v1/setup/**', async (route) => {
const request = route.request();
const pathname = new URL(request.url()).pathname;
if (pathname === '/api/v1/setup/status') {
if (completionStarted) {
await route.abort('connectionreset');
return;
}
await route.fulfill({
json: {
data: {
required: true,
locked: false,
ready: false,
supportedDatabaseTypes: ['MYSQL'],
message: '请完成安装',
},
},
});
return;
}
const body = request.postDataJSON() as Record<string, unknown>;
if (pathname.endsWith('/test-connection')) {
await route.fulfill({
json: {
data: {
successful: true,
databaseType: 'MYSQL',
serverVersion: '8.4.6',
schemaReady: true,
message: 'MySQL 8.4 连接、排序规则和完整迁移权限验证通过',
},
},
});
return;
}
expect(body.adminUsername).toBe('admin');
completionStarted = true;
await route.fulfill({
json: {
data: {
completed: true,
username: 'admin',
message: '安装完成,系统正在切换到正式模式',
restartAfterSeconds: 1,
},
},
});
});
await page.goto('/setup');
await page.getByLabel('数据库密码').fill('fixture-db-password');
await page.getByLabel('安装码').fill('fixture-setup-code');
await page.getByRole('button', { name: '测试连接' }).click();
await page.getByRole('button', { name: '下一步' }).click();
await page.getByLabel('管理员密码').fill('SetupAdmin@2026Strong');
await page.getByLabel('确认密码').fill('SetupAdmin@2026Strong');
await page.getByRole('button', { name: '完成安装' }).click();
await page.getByRole('button', { name: '确定', exact: true }).click();
await expect(page.getByText('安装完成', { exact: true })).toBeVisible();
await expect(page).toHaveURL(/\/login$/, { timeout: 5_000 });
});
+8 -9
View File
@@ -378,19 +378,18 @@ function confirmSetup() {
function startCountdown() {
window.clearInterval(countdownTimer);
countdownTimer = window.setInterval(() => {
countdown.value -= 1;
if (countdown.value <= 0) void openLogin();
countdown.value = Math.max(0, countdown.value - 1);
if (countdown.value === 0) openLogin();
}, 1000);
}
async function openLogin() {
function openLogin() {
window.clearInterval(countdownTimer);
completionMessage.value = '系统正在启动,请稍候。';
if (await waitForSetupCompletion()) {
await router.replace('/login');
return;
}
completionMessage.value = '系统启动时间较长,请稍后刷新页面。';
countdown.value = 0;
completionMessage.value = '正在进入登录页。';
// A full navigation clears the setup-mode SPA state retained across the
// service restart. The login route guard performs the final setup check.
window.location.replace('/login');
}
onMounted(async () => {