mirror of
https://github.com/wu736139669/hapi.git
synced 2026-11-07 01:21:37 +00:00
* feat(sessions): add explicit per-session title locks * fix(sessions): preserve title locks across rename entry points
60 lines
3.9 KiB
TypeScript
60 lines
3.9 KiB
TypeScript
import { expect, test } from '@playwright/test'
|
|
|
|
for (const width of [320, 390, 1280]) {
|
|
for (const locale of ['en', 'zh-CN']) {
|
|
test(`title lock draft, persistence and layout at ${width}px ${locale}`, async ({ page }, testInfo) => {
|
|
await page.setViewportSize({ width, height: 900 })
|
|
await page.addInitScript((language) => {
|
|
localStorage.setItem('hapi-lang', language)
|
|
document.documentElement.style.setProperty('--app-font-scale', '1.3')
|
|
}, locale)
|
|
await page.goto('/e2e-fixtures/session-title-lock-fixture.html')
|
|
await page.getByRole('button', { name: 'Rename 1', exact: true }).click()
|
|
const dialog = page.getByRole('dialog')
|
|
const lock = dialog.getByRole('button', { name: locale === 'en' ? 'Lock title against agent updates' : '锁定标题,阻止 AI 更新' })
|
|
const save = dialog.getByRole('button', { name: locale === 'en' ? 'Save' : '保存', exact: true })
|
|
const cancel = dialog.getByRole('button', { name: locale === 'en' ? 'Cancel' : '取消', exact: true })
|
|
await expect(lock).toHaveAttribute('aria-pressed', 'false')
|
|
await lock.click()
|
|
await expect(page.getByTestId('session-0')).toContainText('"locked":false')
|
|
await cancel.click()
|
|
await expect(dialog).not.toBeVisible()
|
|
await page.getByRole('button', { name: 'Rename 1', exact: true }).click()
|
|
await expect(lock).toHaveAttribute('aria-pressed', 'false')
|
|
await dialog.getByRole('textbox').fill('A deliberately long user title 测试标题')
|
|
await lock.click()
|
|
const bounds = await dialog.boundingBox()
|
|
expect(bounds!.x).toBeGreaterThanOrEqual(0)
|
|
expect(bounds!.x + bounds!.width).toBeLessThanOrEqual(width)
|
|
const inputBounds = await dialog.getByRole('textbox').boundingBox()
|
|
const lockBounds = await lock.boundingBox()
|
|
expect(lockBounds!.width).toBeGreaterThanOrEqual(40)
|
|
expect(lockBounds!.x + lockBounds!.width).toBeLessThanOrEqual(inputBounds!.x + inputBounds!.width + 1)
|
|
await page.screenshot({ path: testInfo.outputPath(`title-lock-${width}-${locale}.png`) })
|
|
await save.click()
|
|
await expect(dialog).not.toBeVisible()
|
|
await expect(page.getByTestId('session-0')).toContainText('"locked":true')
|
|
// Exercise the second production entry point, not just the isolated dialog.
|
|
await page.getByRole('button', { name: 'Show session list' }).click()
|
|
await page.getByRole('button', { name: /A deliberately long user title/ }).click({ button: 'right' })
|
|
await page.getByRole('menuitem', { name: locale === 'en' ? 'Rename' : '重命名', exact: true }).click()
|
|
await expect(lock).toHaveAttribute('aria-pressed', 'true')
|
|
await dialog.getByRole('textbox').fill('Human edit while locked')
|
|
await save.click()
|
|
await expect(dialog).not.toBeVisible()
|
|
await expect(page.getByTestId('session-0')).toContainText('Human edit while locked')
|
|
await expect(page.getByTestId('session-0')).toContainText('"locked":true')
|
|
await page.getByRole('button', { name: 'Rename 2', exact: true }).click()
|
|
await expect(lock).toHaveAttribute('aria-pressed', 'false')
|
|
await cancel.click()
|
|
await page.getByRole('button', { name: 'Rename 1', exact: true }).click()
|
|
await expect(lock).toHaveAttribute('aria-pressed', 'true')
|
|
await lock.press('Space')
|
|
await expect(lock).toHaveAttribute('aria-pressed', 'false')
|
|
await save.click()
|
|
await expect(page.getByTestId('session-0')).toContainText('"locked":false')
|
|
await expect(page.getByTestId('session-0')).toContainText('Human edit while locked')
|
|
})
|
|
}
|
|
}
|