[verified] harden trash actions and mobile details
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import type { APIRequestContext, Page } from '@playwright/test'
|
||||
import { expect, test } from './fixtures'
|
||||
import { allowExpectedError, expect, test } from './fixtures'
|
||||
|
||||
async function csrf(request: APIRequestContext) {
|
||||
const state = await request.storageState()
|
||||
@@ -51,10 +51,33 @@ test('Trash uses compact deadline groups without exposing child-level actions',
|
||||
const row = page.locator('.task-row--trash').filter({ hasText: title })
|
||||
await expect(row).toHaveCount(1)
|
||||
await expect(row.getByRole('button', { name: '恢复' })).toBeVisible()
|
||||
await expect(row.getByRole('button', { name: '永久删除' })).toBeVisible()
|
||||
await expect(row.getByRole('button', { name: '打开任务操作' })).toBeVisible()
|
||||
expect(await row.locator('.task-check').count()).toBe(0)
|
||||
}
|
||||
await expect(page.locator('.trash-safety-note')).toContainText('不支持子任务脱离父任务单独恢复或删除')
|
||||
|
||||
const overdueRow = page.locator('.task-row--trash').filter({ hasText: overdueTitle })
|
||||
await expect(overdueRow.locator('.task-tail')).toBeVisible()
|
||||
const actionTrigger = overdueRow.getByRole('button', { name: '打开任务操作' })
|
||||
await actionTrigger.focus()
|
||||
await actionTrigger.press('Enter')
|
||||
const menu = page.getByRole('menu', { name: '回收站任务操作' })
|
||||
await expect(menu).toBeVisible()
|
||||
await expect(menu.getByRole('menuitem', { name: '永久删除' })).toBeFocused()
|
||||
await menu.getByRole('menuitem', { name: '永久删除' }).press('Tab')
|
||||
await expect(menu.getByRole('menuitem', { name: '永久删除' })).toBeFocused()
|
||||
await menu.getByRole('menuitem', { name: '永久删除' }).press('Shift+Tab')
|
||||
await expect(menu.getByRole('menuitem', { name: '永久删除' })).toBeFocused()
|
||||
await menu.getByRole('menuitem', { name: '永久删除' }).press('Escape')
|
||||
await expect(menu).toBeHidden()
|
||||
await expect(actionTrigger).toBeFocused()
|
||||
await actionTrigger.click()
|
||||
await page.getByRole('menuitem', { name: '永久删除' }).click()
|
||||
const dialog = page.getByRole('dialog')
|
||||
await expect(dialog).toContainText(`输入任务名称“${overdueTitle}”确认`)
|
||||
await dialog.getByRole('button', { name: '永久删除' }).click()
|
||||
await expect(dialog.getByRole('alert')).toContainText('任务名称不匹配')
|
||||
await dialog.getByRole('button', { name: '取消' }).click()
|
||||
await expect(actionTrigger).toBeFocused()
|
||||
|
||||
const geometry = await page.evaluate(() => ({
|
||||
viewport: innerWidth,
|
||||
@@ -69,4 +92,12 @@ test('Trash uses compact deadline groups without exposing child-level actions',
|
||||
expect(control.width).toBeGreaterThanOrEqual(44)
|
||||
expect(control.height).toBeGreaterThanOrEqual(44)
|
||||
}
|
||||
|
||||
await actionTrigger.click()
|
||||
await page.getByRole('menuitem', { name: '永久删除' }).click()
|
||||
await dialog.getByLabel(`输入任务名称“${overdueTitle}”确认`).fill(overdueTitle)
|
||||
allowExpectedError(page, `requestfailed: DELETE ${baseURL}/api/v1/trash/`)
|
||||
await dialog.getByRole('button', { name: '永久删除' }).click()
|
||||
await expect(overdueRow).toHaveCount(0)
|
||||
await expect(page.getByRole('heading', { name: '回收站', exact: true })).toBeFocused()
|
||||
})
|
||||
|
||||
@@ -103,24 +103,25 @@ test('task rows use the body for detail and Trash keeps distinct actions', async
|
||||
await openSidebarView(page, '回收站')
|
||||
await expect(page.locator('.trash-page-context')).toContainText('删除的任务保留在这里,可整组恢复或永久删除。')
|
||||
await expect(page.getByRole('heading', { name: '无截止日期', exact: true })).toBeVisible()
|
||||
await expect(page.locator('.trash-safety-note')).toContainText('不支持子任务脱离父任务单独恢复或删除')
|
||||
const restoreRow = await taskRow(page, restoreTitle)
|
||||
const purgeRow = await taskRow(page, purgeTitle)
|
||||
for (const deletedRow of [restoreRow, purgeRow]) {
|
||||
await expect(deletedRow.getByRole('button', { name: '恢复' })).toBeVisible()
|
||||
await expect(deletedRow.getByRole('button', { name: '永久删除' })).toBeVisible()
|
||||
await expect(deletedRow.getByRole('button', { name: '打开任务操作' })).toBeVisible()
|
||||
await expect(deletedRow.locator('.task-main')).not.toHaveAttribute('role')
|
||||
await expect(deletedRow.locator('.task-main')).not.toHaveAttribute('tabindex')
|
||||
expect(await deletedRow.locator('.task-detail-trigger, .task-check').count()).toBe(0)
|
||||
}
|
||||
await restoreRow.getByRole('button', { name: '恢复' }).click()
|
||||
await expect(restoreRow).toHaveCount(0)
|
||||
await purgeRow.getByRole('button', { name: '永久删除' }).click()
|
||||
await purgeRow.getByRole('button', { name: '打开任务操作' }).click()
|
||||
await page.getByRole('menuitem', { name: '永久删除' }).click()
|
||||
const purgeDialog = page.getByRole('dialog', { name: `永久删除“${purgeTitle}”?` })
|
||||
await expect(purgeDialog).toBeVisible()
|
||||
// The UI can abort the completed 204 request while the confirmation overlay closes.
|
||||
allowExpectedError(page, `requestfailed: DELETE ${baseURL}/api/v1/trash/`)
|
||||
await purgeDialog.getByRole('button', { name: '确认', exact: true }).click()
|
||||
await purgeDialog.getByLabel(`输入任务名称“${purgeTitle}”确认`).fill(purgeTitle)
|
||||
await purgeDialog.getByRole('button', { name: '永久删除', exact: true }).click()
|
||||
await expect(purgeRow).toHaveCount(0)
|
||||
await page.reload()
|
||||
await expect(page.locator('.task-row').filter({ hasText: restoreTitle })).toHaveCount(0)
|
||||
|
||||
Reference in New Issue
Block a user