90 lines
4.4 KiB
TypeScript
90 lines
4.4 KiB
TypeScript
import type { APIRequestContext, Page } from '@playwright/test'
|
|
import { expect, test } from './fixtures'
|
|
|
|
async function csrf(request: APIRequestContext) {
|
|
const state = await request.storageState()
|
|
return state.cookies.find(cookie => cookie.name === 'dodo_csrf')?.value ?? ''
|
|
}
|
|
|
|
async function createTask(request: APIRequestContext, baseURL: string, title: string) {
|
|
const bootstrap = await request.get('/api/v1/bootstrap')
|
|
expect(bootstrap.ok(), await bootstrap.text()).toBeTruthy()
|
|
const inbox = (await bootstrap.json()).lists.find((item: { is_inbox: boolean }) => item.is_inbox)
|
|
const response = await request.post('/api/v1/tasks', {
|
|
data: { title, list_id: inbox.id },
|
|
headers: { 'x-csrf-token': await csrf(request), origin: baseURL },
|
|
})
|
|
expect(response.ok(), await response.text()).toBeTruthy()
|
|
}
|
|
|
|
async function dragSeparator(page: Page, label: string, deltaX: number) {
|
|
const separator = page.getByRole('separator', { name: label })
|
|
const box = await separator.boundingBox()
|
|
expect(box).not.toBeNull()
|
|
const x = box!.x + box!.width / 2
|
|
const y = box!.y + Math.min(120, box!.height / 2)
|
|
await page.mouse.move(x, y)
|
|
await page.mouse.down()
|
|
await page.mouse.move(x + deltaX, y, { steps: 5 })
|
|
await page.mouse.up()
|
|
}
|
|
|
|
test('desktop panes resize by pointer and keyboard and restore after reload', async ({ page, request, baseURL }, testInfo) => {
|
|
test.skip((page.viewportSize()?.width ?? 0) <= 930, 'desktop-only behavior')
|
|
const title = `三栏拖动-${testInfo.project.name}-${Date.now()}`
|
|
await createTask(request, baseURL!, title)
|
|
await page.goto('/')
|
|
|
|
const sidebar = page.locator('.sidebar')
|
|
const main = page.locator('main')
|
|
const sidebarSeparator = page.getByRole('separator', { name: '调整菜单栏宽度' })
|
|
await expect(sidebarSeparator).toBeVisible()
|
|
await expect(sidebarSeparator).toHaveAttribute('aria-valuenow', '236')
|
|
|
|
const sidebarBefore = await sidebar.boundingBox()
|
|
await dragSeparator(page, '调整菜单栏宽度', 64)
|
|
const sidebarDraggedWidth = Number(await sidebarSeparator.getAttribute('aria-valuenow'))
|
|
expect(sidebarDraggedWidth - sidebarBefore!.width).toBeGreaterThanOrEqual(63)
|
|
expect(sidebarDraggedWidth - sidebarBefore!.width).toBeLessThanOrEqual(65)
|
|
await expect(sidebar).toHaveCSS('width', `${sidebarDraggedWidth}px`)
|
|
const sidebarAfter = await sidebar.boundingBox()
|
|
expect((await main.boundingBox())!.x).toBeCloseTo(sidebarAfter!.x + sidebarAfter!.width, 0)
|
|
|
|
await sidebarSeparator.press('ArrowLeft')
|
|
const sidebarKeyboardWidth = sidebarDraggedWidth - 12
|
|
await expect(sidebarSeparator).toHaveAttribute('aria-valuenow', String(sidebarKeyboardWidth))
|
|
await expect(sidebar).toHaveCSS('width', `${sidebarKeyboardWidth}px`)
|
|
|
|
await sidebar.getByRole('button', { name: '收集箱', exact: true }).click()
|
|
const row = page.locator('.task-row').filter({ has: page.locator('strong', { hasText: title }) })
|
|
await expect(row).toHaveCount(1)
|
|
await row.locator('.task-main').click()
|
|
|
|
const detail = page.getByRole('dialog', { name: '任务详情' })
|
|
const detailSeparator = page.getByRole('separator', { name: '调整任务详情宽度' })
|
|
await expect(detailSeparator).toBeVisible()
|
|
const detailBefore = await detail.boundingBox()
|
|
await dragSeparator(page, '调整任务详情宽度', -70)
|
|
const detailAfter = await detail.boundingBox()
|
|
const expectedDetailWidth = Math.min(detailBefore!.width + 70, (page.viewportSize()?.width ?? 0) - sidebarKeyboardWidth - 330)
|
|
expect(detailAfter!.width).toBeCloseTo(expectedDetailWidth, 0)
|
|
const mainAfter = await main.boundingBox()
|
|
expect(mainAfter!.x + mainAfter!.width).toBeCloseTo(detailAfter!.x, 0)
|
|
|
|
const widths = await page.evaluate(() => ({
|
|
sidebar: localStorage.getItem('dodo.desktop-pane.sidebar'),
|
|
detail: localStorage.getItem('dodo.desktop-pane.detail'),
|
|
}))
|
|
expect(widths).toEqual({ sidebar: String(Math.round(sidebarKeyboardWidth)), detail: String(Math.round(detailAfter!.width)) })
|
|
|
|
await page.reload()
|
|
await expect(sidebar).toHaveCSS('width', `${Math.round(sidebarKeyboardWidth)}px`)
|
|
const restoredRow = page.locator('.task-row').filter({ has: page.locator('strong', { hasText: title }) })
|
|
await restoredRow.locator('.task-main').click()
|
|
await expect(detail).toHaveCSS('width', `${Math.round(detailAfter!.width)}px`)
|
|
|
|
await page.setViewportSize({ width: 930, height: 900 })
|
|
await expect(sidebarSeparator).toBeHidden()
|
|
await expect(detailSeparator).toBeHidden()
|
|
})
|