import { expect, type Browser, type Page } from '@playwright/test' export const E2E_PASSWORD = 'e2e-password' export async function login(page: Page, path = '/') { await page.goto(path) await expect(page).toHaveURL(/\/login/) await page.getByLabel('登录口令').fill(E2E_PASSWORD) await page.getByLabel('登录口令').press('Enter') await expect(page).toHaveURL(/\/s\//) await expect(page.getByText('已同步', { exact: true }).first()).toBeVisible() } /** 新开一个独立的浏览器上下文,相当于另一台设备 */ export async function openDevice(browser: Browser, path = '/') { const context = await browser.newContext({ reducedMotion: 'reduce', locale: 'zh-CN' }) const page = await context.newPage() await login(page, path) return { context, page } } /** 在当前空间正中新建一张便笺并改标题 */ export async function createNote(page: Page, title: string) { const before = await page.locator('.note-card').count() await page.getByRole('button', { name: '新便笺' }).click() await expect(page.locator('.note-card')).toHaveCount(before + 1) const card = page.locator('.note-card--selected') await card.locator('.note-card__title').fill(title) return card } /** 当前画布上所有卡片的标题(输入框的值不会出现在 DOM 属性里,只能这样读) */ export function noteTitles(page: Page) { return page .locator('.note-card__title') .evaluateAll((inputs) => inputs.map((input) => (input as HTMLInputElement).value)) } export async function expectNoteTitle(page: Page, title: string, present = true) { const poll = expect.poll(() => noteTitles(page), { timeout: 10_000 }) if (present) await poll.toContain(title) else await poll.not.toContain(title) } export async function noteByTitle(page: Page, title: string) { await expectNoteTitle(page, title) const index = (await noteTitles(page)).indexOf(title) return page.locator('.note-card').nth(index) } /** 新建一个空间并切换过去,避免用例之间互相影响 */ export async function createSpace(page: Page, name: string) { await page.getByRole('button', { name: '创建空间' }).click() await page.getByPlaceholder('例如:灵感收纳盒、工作面板…').fill(name) await page.getByRole('button', { name: '立即创建' }).click() await expect(page.locator('.space-title')).toContainText(name) await expect(page.getByText('已同步', { exact: true }).first()).toBeVisible() }