frontend/e2e/helpers.ts
Rama main · réplica de lectura del repositorio original.
import { expect, request, type APIRequestContext, type Page } from "@playwright/test"
import path from "node:path"
export const MEDIA = path.resolve(process.cwd(), "../.devdata/testmedia")
const BASE = process.env.E2E_BASE_URL ?? "https://localhost:8443"
const H = { "X-Requested-With": "mediahub" }
export async function adminApi(): Promise<APIRequestContext> {
const ctx = await request.newContext({ baseURL: BASE, ignoreHTTPSErrors: true, extraHTTPHeaders: H })
const r = await ctx.post("/api/auth/login", { data: { username: "admin", password: process.env.E2E_ADMIN_PASSWORD } })
expect(r.ok(), await r.text()).toBeTruthy()
return ctx
}
export async function newInvite(): Promise<string> {
const admin = await adminApi()
const r = await admin.post("/api/admin/invitations", { data: { note: "playwright" } })
const token = (await r.json()).token as string
await admin.dispose()
return token
}
let counter = 0
export function uniqueName(prefix: string) {
return `${prefix}${Date.now().toString(36)}${(counter++).toString(36)}${Math.floor(Math.random() * 1e4)}`
}
/** Register a brand-new user through the UI and land on Home. */
export async function registerUser(page: Page): Promise<{ username: string; password: string }> {
const token = await newInvite()
const username = uniqueName("u")
const password = "playwright-pass-123"
await page.goto(`/register?token=${token}`)
await expect(page.getByText("邀請有效")).toBeVisible()
await page.getByLabel("使用者名稱").fill(username)
await page.getByLabel("顯示名稱").fill("測試使用者")
await page.getByLabel("密碼", { exact: true }).fill(password)
await page.getByLabel("確認密碼").fill(password)
await page.getByRole("button", { name: "建立帳號" }).click()
await expect(page.getByRole("heading", { level: 1, name: "首頁" })).toBeVisible()
return { username, password }
}
/** Fail if the page scrolls horizontally (layout overflow). */
export async function expectNoHorizontalOverflow(page: Page) {
const { sw, iw } = await page.evaluate(() => ({ sw: document.documentElement.scrollWidth, iw: window.innerWidth }))
expect(sw, `page is ${sw}px wide in a ${iw}px viewport`).toBeLessThanOrEqual(iw + 1)
}
export function isMobile(page: Page) {
return (page.viewportSize()?.width ?? 1200) < 768
}
/** Navigate using the sidebar on desktop or the tab bar on mobile. */
export async function navTo(page: Page, label: "首頁" | "照片" | "影片" | "檔案" | "設定") {
const nav = page.getByRole("navigation", { name: "主要導覽" }).filter({ visible: true })
const desktopLabel = { 首頁: "首頁", 照片: "圖庫", 影片: "影片庫", 檔案: "我的檔案", 設定: "設定" }[label]
await nav.getByRole("link", { name: isMobile(page) ? label : desktopLabel, exact: true }).first().click()
}