feat: align upcoming with list layout
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
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 mutate(request: APIRequestContext, baseURL: string, path: string, options: Parameters<APIRequestContext['fetch']>[1]) {
|
||||
return request.fetch(path, { ...options, headers: { ...options?.headers, 'x-csrf-token': await csrf(request), origin: baseURL } })
|
||||
}
|
||||
|
||||
async function openSidebarView(page: Page, name: string) {
|
||||
const sidebar = page.locator('.sidebar')
|
||||
const target = sidebar.getByRole('button', { name, exact: true })
|
||||
if (await page.locator('.shell').evaluate(element => element.classList.contains('sidebar-collapsed'))) {
|
||||
await page.getByRole('button', { name: '展开菜单' }).click()
|
||||
} else if (await page.evaluate(() => window.innerWidth <= 930)) {
|
||||
await page.locator('main .topbar > button').first().click()
|
||||
} else if (!await target.isVisible()) {
|
||||
await page.getByRole('button', { name: /展开菜单|收起菜单/ }).click()
|
||||
}
|
||||
await target.click()
|
||||
}
|
||||
|
||||
function futureDueAt(days: number) {
|
||||
const date = new Date()
|
||||
date.setDate(date.getDate() + days)
|
||||
date.setHours(12, 0, 0, 0)
|
||||
return date.toISOString()
|
||||
}
|
||||
|
||||
test('Upcoming shares the task-list hierarchy while keeping its date scope and no manual reorder', async ({ page, request, baseURL }) => {
|
||||
const bootstrapResponse = await request.get('/api/v1/bootstrap')
|
||||
expect(bootstrapResponse.ok()).toBeTruthy()
|
||||
const inbox = (await bootstrapResponse.json()).lists.find((item: { is_inbox: boolean }) => item.is_inbox)
|
||||
expect(inbox).toBeTruthy()
|
||||
|
||||
for (const [title, days] of [['未来一天任务', 1], ['未来三天任务', 3]] as const) {
|
||||
const response = await mutate(request, baseURL!, '/api/v1/tasks', {
|
||||
method: 'POST',
|
||||
data: { title, list_id: inbox.id, due_at: futureDueAt(days), due_has_time: false },
|
||||
})
|
||||
expect(response.ok(), await response.text()).toBeTruthy()
|
||||
}
|
||||
|
||||
await page.goto('/')
|
||||
await openSidebarView(page, '最近 7 天')
|
||||
|
||||
await expect(page.locator('main')).toHaveClass(/list-main/)
|
||||
await expect(page.locator('.topbar-title')).toHaveCount(0)
|
||||
const header = page.locator('.list-page-context')
|
||||
await expect(header.getByRole('heading', { name: '最近 7 天' })).toBeVisible()
|
||||
await expect(header).toContainText(/还有 \d+ 项待完成/)
|
||||
await expect(header.getByRole('switch', { name: '显示已完成' })).toBeVisible()
|
||||
await expect(page.locator('.list-section-heading')).toContainText('任务')
|
||||
await expect(page.getByRole('button', { name: '调整顺序' })).toHaveCount(0)
|
||||
await expect(page.locator('.task-row')).toHaveCount(2)
|
||||
await expect(page.locator('.task-row')).toContainText(['未来一天任务', '未来三天任务'])
|
||||
|
||||
const geometry = await page.evaluate(() => {
|
||||
const rect = (selector: string) => {
|
||||
const value = document.querySelector<HTMLElement>(selector)!.getBoundingClientRect()
|
||||
return { left: value.left, right: value.right, width: value.width, top: value.top, bottom: value.bottom }
|
||||
}
|
||||
return {
|
||||
viewportWidth: innerWidth,
|
||||
overflow: document.documentElement.scrollWidth - document.documentElement.clientWidth,
|
||||
header: rect('.list-page-context'),
|
||||
search: rect('.list-search-reveal'),
|
||||
section: rect('.list-section-heading'),
|
||||
list: rect('.task-list'),
|
||||
}
|
||||
})
|
||||
expect(geometry.overflow).toBe(0)
|
||||
expect(geometry.header.left).toBeCloseTo(geometry.search.left, 0)
|
||||
expect(geometry.search.left).toBeCloseTo(geometry.section.left, 0)
|
||||
expect(geometry.section.left).toBeCloseTo(geometry.list.left, 0)
|
||||
expect(geometry.header.width).toBeCloseTo(geometry.list.width, 0)
|
||||
if (geometry.viewportWidth <= 720) {
|
||||
expect(geometry.header.left).toBeCloseTo(29, 0)
|
||||
expect(geometry.list.right).toBeCloseTo(geometry.viewportWidth - 29, 0)
|
||||
}
|
||||
|
||||
const fab = page.getByRole('button', { name: '添加任务' })
|
||||
await expect(fab).toBeVisible()
|
||||
await fab.click()
|
||||
await expect(page.getByRole('dialog', { name: '添加任务' })).toBeVisible()
|
||||
})
|
||||
Reference in New Issue
Block a user