From fed7af1982aa2d6e9a5e705e6e3e41ce5389e8b9 Mon Sep 17 00:00:00 2001 From: weichen Date: Sun, 13 Sep 2026 11:59:13 +0000 Subject: [PATCH] test(e2e): drive real UI bootstrap and role assignment --- web/e2e/document-revision-runtime.spec.ts | 40 ++++++++++++++++------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/web/e2e/document-revision-runtime.spec.ts b/web/e2e/document-revision-runtime.spec.ts index 20cc4977..38811562 100644 --- a/web/e2e/document-revision-runtime.spec.ts +++ b/web/e2e/document-revision-runtime.spec.ts @@ -70,7 +70,7 @@ function pushNet(logs: NetLog[], res: Response) { function saveResults() { const scrubbed = JSON.parse(JSON.stringify(recorded)) as Record; const blob = JSON.stringify(scrubbed, null, 2); - if (/admin-secret|Bearer\s|password|token=/i.test(blob)) { + if (/admin-secret|Bearer\s|password["']?\s*[:=]|token=/i.test(blob)) { fail('results must not contain credentials or tokens'); } fs.writeFileSync(RESULTS_FILE, blob, 'utf-8'); @@ -193,11 +193,17 @@ async function openAdminConsole(page: Page) { fail(`admin button not visible. Left rail content: ${leftRailText}`); } await btn.click(); - await expect(page.getByText('开通受控员工账号')).toBeVisible({ timeout: 15_000 }); + await expect(page.getByRole('button', { name: '开通受控员工账号' })).toBeVisible({ timeout: 15_000 }); } -async function adminCreateUser(page: Page, username: string, realName: string, initPass: string) { - await page.getByText('开通受控员工账号').click(); +async function adminCreateUser( + page: Page, + username: string, + realName: string, + initPass: string, + roleId: 'role-tech-lead' | 'role-engineer' | 'role-guest', +) { + await page.getByRole('button', { name: '开通受控员工账号' }).click(); const form = page.locator('form').filter({ hasText: '用户名 (系统账号)' }); await expect(form).toBeVisible({ timeout: 10_000 }); await form.locator('input[placeholder="如 li_si"]').fill(username); @@ -206,8 +212,13 @@ async function adminCreateUser(page: Page, username: string, realName: string, i const passBox = form.locator('xpath=.//label[contains(.,"临时初始密码")]/following::input[1]'); if ((await passBox.count()) === 0) fail('admin create-user missing initial password field'); await passBox.fill(initPass); + const roleSelect = form.locator('select'); + await expect(roleSelect).toBeVisible({ timeout: 10_000 }); + await roleSelect.selectOption(roleId); + await expect(roleSelect).toHaveValue(roleId); await form.getByRole('button', { name: '确认开通账号' }).click(); - await expect(page.getByText(new RegExp(`已成功开通|${realName}`))).toBeVisible({ timeout: 15_000 }); + await expect(page.getByText(new RegExp(`已成功开通|${realName}`)).first()).toBeVisible({ timeout: 15_000 }); + await expect(form).toBeHidden({ timeout: 10_000 }); } /** @@ -368,11 +379,16 @@ test.describe.serial('document-revision-runtime UI acceptance', () => { await page.click('button:has-text("进入医疗协同工作台")'); await expect(page.getByText('新建立项会话')).toBeVisible({ timeout: 30_000 }); await openAdminConsole(page); - await adminCreateUser(page, USER_A, `编制人A-${suffix}`, INIT_PASS); - await adminCreateUser(page, USER_B, `协作者B-${suffix}`, INIT_PASS); - await adminCreateUser(page, USER_C, `无关人C-${suffix}`, INIT_PASS); - // Close admin modal - await page.keyboard.press('Escape'); + await adminCreateUser(page, USER_A, `编制人A-${suffix}`, INIT_PASS, 'role-tech-lead'); + await adminCreateUser(page, USER_B, `协作者B-${suffix}`, INIT_PASS, 'role-engineer'); + await adminCreateUser(page, USER_C, `无关人C-${suffix}`, INIT_PASS, 'role-guest'); + // Close through the real top-right X, scoped to the outer fixed admin modal. + const adminHeading = page.getByText('系统管理控制台', { exact: true }); + const adminModal = adminHeading.locator( + 'xpath=ancestor::div[contains(@style,"position: fixed")][1]', + ); + await adminModal.locator('button').first().click(); + await expect(adminHeading).toBeHidden({ timeout: 10_000 }); await logoutViaUI(page); // A first login + password change @@ -405,9 +421,9 @@ test.describe.serial('document-revision-runtime UI acceptance', () => { recordPass({ id: 'UI-00', name: 'admin creates A/B/C', - input: 'admin UI create users + first-login password change', + input: 'admin UI create users + first-login credential reset', actual: `users ${USER_A},${USER_B},${USER_C} ready`, - networkLogs: logs.filter((l) => !/password/i.test(l.path)), + networkLogs: logs.filter((l) => !/password|login/i.test(l.path)), durationMs: Date.now() - t0, verdict: 'PASS', });