76 lines
2.9 KiB
TypeScript
76 lines
2.9 KiB
TypeScript
/**
|
|
* 首页 + 导航:验证四个页面路由可访问、顶部导航正常
|
|
*/
|
|
import { test, expect, type TestInfo } from '@playwright/test'
|
|
|
|
// Firefox headless / WebKit headless 强制 webdriver=true,无法通过 JS 补丁隐藏
|
|
const isChromiumOnly = (ti: TestInfo) =>
|
|
ti.project.name !== 'Firefox' &&
|
|
!ti.project.name.startsWith('iPhone') &&
|
|
!ti.project.name.startsWith('iPad')
|
|
|
|
test.describe('首页与导航', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/')
|
|
// 等待 Vue SPA 挂载完成
|
|
await page.waitForSelector('.app, #app', { timeout: 10_000 })
|
|
})
|
|
|
|
test('访问根路径重定向到 /chat', async ({ page }) => {
|
|
await page.waitForURL(/\/(chat|collaboration|review|metrics)$/, { timeout: 5_000 })
|
|
})
|
|
|
|
test('顶部导航栏存在且有四个链接', async ({ page }) => {
|
|
await expect(page.locator('.topbar, nav')).toBeVisible()
|
|
const links = page.locator('.nav-links a, nav a')
|
|
await expect(links).toHaveCount(4)
|
|
})
|
|
|
|
test('导航到「对话」页', async ({ page }) => {
|
|
await page.click('text=对话')
|
|
await expect(page).toHaveURL(/\/chat/)
|
|
await expect(page.locator('.chat-view, .input-bar, input[placeholder*="问题"]').first()).toBeVisible()
|
|
})
|
|
|
|
test('导航到「协作」页', async ({ page }) => {
|
|
await page.click('text=协作')
|
|
await expect(page).toHaveURL(/\/collaboration/)
|
|
await expect(page.locator('.collab-view, .collab-sidebar').first()).toBeVisible()
|
|
})
|
|
|
|
test('导航到「检验」页', async ({ page }) => {
|
|
await page.click('text=检验')
|
|
await expect(page).toHaveURL(/\/review/)
|
|
await expect(page.locator('.review-view, .review-header').first()).toBeVisible()
|
|
})
|
|
|
|
test('导航到「指标」页', async ({ page }) => {
|
|
await page.click('text=指标')
|
|
await expect(page).toHaveURL(/\/metrics/)
|
|
await expect(page.locator('.metrics-view')).toBeVisible()
|
|
})
|
|
|
|
test('所有路由刷新后保持正确页面', async ({ page }) => {
|
|
const routes = ['/chat', '/collaboration', '/review', '/metrics']
|
|
for (const route of routes) {
|
|
await page.goto(route)
|
|
await expect(page).toHaveURL(new RegExp(route))
|
|
await page.waitForLoadState('networkidle')
|
|
}
|
|
})
|
|
|
|
test('反指纹检测:navigator.webdriver 必须为 false', async ({ page }, testInfo) => {
|
|
test.skip(!isChromiumOnly(testInfo), 'Firefox/WebKit headless 强制 webdriver=true,跳过')
|
|
await page.goto('/chat')
|
|
const webdriver = await page.evaluate(() => !!(navigator as any).webdriver)
|
|
expect(webdriver).toBe(false)
|
|
})
|
|
|
|
test('反指纹检测:User-Agent 不含 HeadlessChrome', async ({ page }, testInfo) => {
|
|
test.skip(!isChromiumOnly(testInfo), 'Firefox/WebKit headless 强制 webdriver=true,跳过')
|
|
await page.goto('/chat')
|
|
const ua = await page.evaluate(() => navigator.userAgent)
|
|
expect(ua).not.toContain('HeadlessChrome')
|
|
})
|
|
})
|