100 lines
3.5 KiB
TypeScript
100 lines
3.5 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
const mockTasksData = {
|
|
code: 200,
|
|
data: [
|
|
{
|
|
taskNum: 'T001',
|
|
taskName: '学习 Vue3',
|
|
reportCount: 3,
|
|
fragmentCount: 5,
|
|
effectiveTime: 9000,
|
|
},
|
|
{
|
|
taskNum: 'T002',
|
|
taskName: '学习 TypeScript',
|
|
reportCount: 1,
|
|
fragmentCount: 2,
|
|
effectiveTime: 4500,
|
|
},
|
|
],
|
|
};
|
|
const mockTasksEmpty = { code: 200, data: [] };
|
|
const mockFeed = { code: 200, data: [] };
|
|
|
|
test.describe('Review page', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.route('**/api/review/tasks**', (route) =>
|
|
route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify(mockTasksData),
|
|
}),
|
|
);
|
|
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('/review');
|
|
await page.waitForSelector('.review-page', { timeout: 10_000 });
|
|
});
|
|
|
|
test('displays summary metrics and task list', async ({ page }) => {
|
|
await expect(page.locator('.metric-card')).toHaveCount(3);
|
|
// Check metric values
|
|
await expect(page.locator('.metric-card').first().locator('strong')).toContainText('2');
|
|
// 任务以卡片列表展示(不再是 el-table)
|
|
await expect(page.locator('.task-card')).toHaveCount(2);
|
|
await expect(page.getByText('学习 Vue3')).toBeVisible();
|
|
await expect(page.getByRole('button', { name: '回忆复习' })).toHaveCount(2);
|
|
});
|
|
|
|
test('shows empty state when no tasks', async ({ page }) => {
|
|
await page.route('**/api/review/tasks**', (route) =>
|
|
route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify(mockTasksEmpty),
|
|
}),
|
|
);
|
|
|
|
await page.goto('/review');
|
|
await page.waitForSelector('.review-page', { timeout: 10_000 });
|
|
await expect(page.locator('.metric-card').first().locator('strong')).toContainText('0');
|
|
await expect(page.getByText('暂无复习任务')).toBeVisible();
|
|
});
|
|
|
|
test('接口失败时提示加载失败而不是显示空列表', async ({ page }) => {
|
|
await page.route('**/api/review/tasks**', (route) =>
|
|
route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({ code: 500, message: '服务异常', data: null }),
|
|
}),
|
|
);
|
|
|
|
await page.goto('/review');
|
|
await page.waitForSelector('.review-page', { timeout: 10_000 });
|
|
|
|
await expect(page.getByText('复习数据加载失败,请稍后重试')).toBeVisible();
|
|
await expect(page.getByRole('button', { name: '重新加载' })).toBeVisible();
|
|
await expect(page.getByText('暂无复习任务')).toHaveCount(0);
|
|
});
|
|
|
|
test('详情页返回按钮为「返回总览」并回到复习总览', async ({ page }) => {
|
|
await page.route('**/api/review/task/**', (route) =>
|
|
route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ code: 200, data: [] }) }),
|
|
);
|
|
|
|
await page.locator('.task-card').first().click();
|
|
await expect(page).toHaveURL(/\/review\/detail\/task\/T001/, { timeout: 5000 });
|
|
|
|
const backBtn = page.locator('.head .back-btn');
|
|
await expect(backBtn).toHaveText('← 返回总览');
|
|
await backBtn.click();
|
|
await expect(page).toHaveURL(/\/review$/, { timeout: 5000 });
|
|
});
|
|
});
|