Files
lpt-fe/e2e/navigation.spec.ts
cat-shark 3adbeb183c fix:Transition 白屏——组件多根节点 + Vite 模块请求拦截
- Welcome.vue:回忆卡片 el-dialog 和根 section 共存导致多根节点,<Transition>
  无法动画。包裹一层 <div>
- Study.vue:同上(权重配置对话框)
- MindMapViewer.vue:事件名 selectNode→selectNewNode(类型错误)
- e2e/study.spec.ts + navigation.spec.ts:地址栏 Vite 在模块 URL 后追加
  ?t=... 时间戳,.endsWith('.ts') 匹配失效,改用 url.includes('/src/')
2026-07-04 09:43:07 +08:00

66 lines
3.0 KiB
TypeScript

import { test, expect } from '@playwright/test';
const mockTasks = { code: 200, data: { records: [] } };
const mockFeed = { code: 200, data: [] };
test.describe('Header navigation', () => {
test('shows brand title on login page', async ({ page }) => {
await page.goto('/login');
await expect(page.locator('.login-page')).toBeVisible({ timeout: 10_000 });
await expect(page.locator('.login-panel h1')).toBeVisible();
});
test('shows logout button on authenticated pages', async ({ page }) => {
await page.route('**/api/review/feed**', (route) =>
route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockFeed) }),
);
await page.goto('/login');
await page.evaluate(() => localStorage.setItem('isLoggedIn', 'true'));
await page.goto('/welcome');
await page.waitForSelector('.welcome-page', { timeout: 10_000 });
await expect(page.locator('.head .logout-btn')).toBeVisible();
});
test('logout clears auth and redirects to /login', async ({ page }) => {
await page.route('**/api/review/feed**', (route) =>
route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockFeed) }),
);
await page.goto('/login');
await page.evaluate(() => localStorage.setItem('isLoggedIn', 'true'));
await page.goto('/welcome');
await page.waitForSelector('.welcome-page', { timeout: 10_000 });
await page.locator('.head .logout-btn').click();
await expect(page).toHaveURL(/\/login/, { timeout: 5000 });
const isLoggedIn = await page.evaluate(() => localStorage.getItem('isLoggedIn'));
expect(isLoggedIn).toBeNull();
});
test('back button shows on sub-pages and navigates to /welcome', async ({ page }) => {
await page.route('**/api/tasks**', (route) => {
if (route.request().url().includes('/src/')) return route.continue();
route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockTasks) });
});
await page.route('**/api/review/feed**', (route) =>
route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockFeed) }),
);
await page.goto('/login');
await page.evaluate(() => localStorage.setItem('isLoggedIn', 'true'));
await page.goto('/study');
await page.waitForSelector('.study-page', { timeout: 10_000 });
await expect(page.locator('.head .back-btn')).toBeVisible();
await page.locator('.head .back-btn').click();
await expect(page).toHaveURL(/\/welcome/);
});
test('no back button on welcome page', async ({ page }) => {
await page.route('**/api/review/feed**', (route) =>
route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockFeed) }),
);
await page.goto('/login');
await page.evaluate(() => localStorage.setItem('isLoggedIn', 'true'));
await page.goto('/welcome');
await page.waitForSelector('.welcome-page', { timeout: 10_000 });
await expect(page.locator('.head .back-btn')).not.toBeVisible();
});
});