Why: the repo's @playwright/test version has no toBeReadOnly matcher. Evidence: failing run shows TypeError at the matcher; the attribute assertion works across versions. Impact: none beyond the spec assertion. Refs: 2026-10-12 diagnostic report, increment 3.
58 lines
3.3 KiB
TypeScript
58 lines
3.3 KiB
TypeScript
// 增量 3 验收(2026-10-12 诊断报告):改密弹窗表单语义——<form onSubmit> 承载提交
|
||
//(Enter 可提交)、autocomplete 三段标注(username/current-password/new-password)、
|
||
// 只读用户名关联、错误文案复用 humanChangePasswordError(401 不再一刀切)。
|
||
// 驱动:scripts/e2e.sh 第 4 阶段(E2E_PLAIN_BASE=1)——表单语义与命令面无关,
|
||
// 任意 auth-on 服务可验,普通基座段顺路覆盖;RDM 组合主跑(第 3 阶段)本文件自跳过。
|
||
import { test, expect, type Page } from '@playwright/test'
|
||
|
||
const OWNER = process.env.E2E_OWNER || 'e2e-auditor'
|
||
const PASSWORD = process.env.E2E_PASSWORD || 'E2eAudit#2026'
|
||
const PASSWORD2 = process.env.E2E_PASSWORD2 || 'E2eAudit#2026b'
|
||
|
||
test.skip(!(process.env.PLAYWRIGHT_BASE_URL && process.env.E2E_PLAIN_BASE),
|
||
'set PLAYWRIGHT_BASE_URL + E2E_PLAIN_BASE (scripts/e2e.sh phase 4 drives this suite)')
|
||
|
||
async function login(page: Page) {
|
||
await page.goto('/')
|
||
await page.getByPlaceholder('由管理员分配').fill(OWNER)
|
||
await page.getByPlaceholder('初始密码或常用密码').fill(PASSWORD)
|
||
await page.getByRole('button', { name: '登录', exact: true }).click()
|
||
const gate = page.getByText('修改密码')
|
||
const gated = await gate.waitFor({ state: 'visible', timeout: 5_000 }).then(() => true).catch(() => false)
|
||
if (gated) {
|
||
const pwInputs = page.locator('.lg-card input[type="password"]')
|
||
await pwInputs.nth(0).fill(PASSWORD)
|
||
await pwInputs.nth(1).fill(PASSWORD2)
|
||
await pwInputs.nth(2).fill(PASSWORD2)
|
||
await page.getByRole('button', { name: '设置新密码并进入' }).click()
|
||
} else {
|
||
await page.getByPlaceholder('初始密码或常用密码').fill(PASSWORD2)
|
||
await page.getByRole('button', { name: '登录', exact: true }).click()
|
||
}
|
||
await expect(page.locator('.tsb-tool', { hasText: '代理' })).toBeVisible({ timeout: 15_000 })
|
||
}
|
||
|
||
test('改密弹窗:form 提交、autocomplete/用户名关联、错误分类文案', async ({ page }) => {
|
||
await login(page)
|
||
await page.locator('.tsb-user').click()
|
||
await page.getByRole('button', { name: '修改密码…' }).click()
|
||
const dlg = page.getByRole('dialog', { name: '修改密码' })
|
||
await expect(dlg).toBeVisible()
|
||
|
||
// 用户名只读关联 + 三段 autocomplete。
|
||
const username = dlg.locator('input[autocomplete="username"]')
|
||
await expect(username).toHaveValue(OWNER)
|
||
// 本仓 @playwright/test 无 toBeReadOnly:以 readonly 属性断言只读关联。
|
||
await expect(username).toHaveAttribute('readonly', '')
|
||
await expect(dlg.locator('input[autocomplete="current-password"]')).toHaveCount(1)
|
||
await expect(dlg.locator('input[autocomplete="new-password"]')).toHaveCount(2)
|
||
|
||
// 表单语义:填错当前密码后按 Enter(不点按钮)提交——证明提交走 <form onSubmit>。
|
||
await dlg.locator('input[autocomplete="current-password"]').fill('definitely-wrong-pass')
|
||
await dlg.locator('input[autocomplete="new-password"]').first().fill('ANewPass#2026x')
|
||
await dlg.locator('input[autocomplete="new-password"]').nth(1).fill('ANewPass#2026x')
|
||
await dlg.locator('input[autocomplete="current-password"]').press('Enter')
|
||
// 后端 401 "current password incorrect" → humanChangePasswordError 的分类文案。
|
||
await expect(dlg.getByText('当前密码不正确')).toBeVisible({ timeout: 10_000 })
|
||
})
|