test: add playwright config and e2e tests
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
const mockTasks = {
|
||||
code: 200,
|
||||
data: {
|
||||
records: [
|
||||
{
|
||||
id: 1,
|
||||
taskNum: 'T001',
|
||||
taskName: '学习 Vue3 组合式 API',
|
||||
taskDescription: '掌握 Composition API 的核心概念',
|
||||
taskPriority: 5,
|
||||
materialUrl: 'https://vuejs.org/guide',
|
||||
lastLearningStatus: '进行中',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
taskNum: 'T002',
|
||||
taskName: 'TypeScript 类型体操',
|
||||
taskDescription: '练习 TypeScript 高级类型',
|
||||
taskPriority: 3,
|
||||
materialUrl: '',
|
||||
lastLearningStatus: '未开始',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const mockTasksEmpty = { code: 200, data: { records: [] } };
|
||||
const mockFeed = { code: 200, data: [] };
|
||||
|
||||
const authAndNavigate = async (page: any) => {
|
||||
await page.goto('/login');
|
||||
await page.evaluate(() => localStorage.setItem('isLoggedIn', 'true'));
|
||||
};
|
||||
|
||||
test.describe('Study page', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.route('**/api/tasks**', (route) => {
|
||||
const url = route.request().url();
|
||||
if (url.includes('/tasks') && !url.includes('/tasks/')) {
|
||||
return route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockTasks),
|
||||
});
|
||||
}
|
||||
return route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ code: 200, data: {} }),
|
||||
});
|
||||
});
|
||||
await page.route('**/api/review/feed**', (route) =>
|
||||
route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockFeed) }),
|
||||
);
|
||||
|
||||
await authAndNavigate(page);
|
||||
await page.goto('/study');
|
||||
await page.waitForSelector('.study-page', { timeout: 10_000 });
|
||||
});
|
||||
|
||||
test('displays task list with names and priorities', async ({ page }) => {
|
||||
const taskItems = page.locator('.task-list-item');
|
||||
await expect(taskItems).toHaveCount(2);
|
||||
await expect(taskItems.first().locator('.task-name')).toContainText('学习 Vue3 组合式 API');
|
||||
await expect(taskItems.nth(1).locator('.task-name')).toContainText('TypeScript 类型体操');
|
||||
});
|
||||
|
||||
test('selecting a task shows its details', async ({ page }) => {
|
||||
const taskItems = page.locator('.task-list-item');
|
||||
await taskItems.nth(1).click();
|
||||
await expect(page.locator('.detail-head h3')).toContainText('TypeScript 类型体操');
|
||||
});
|
||||
|
||||
test('clicking add navigates to add-task form', async ({ page }) => {
|
||||
await page.locator('.action-card').locator('button', { hasText: '添加任务' }).click();
|
||||
await expect(page).toHaveURL(/\/add-task/);
|
||||
});
|
||||
|
||||
test('clicking update navigates to update-task form', async ({ page }) => {
|
||||
await page.locator('.action-card').locator('button', { hasText: '更新任务' }).click();
|
||||
await expect(page).toHaveURL(/\/update-task/);
|
||||
});
|
||||
|
||||
test('delete task removes it from the list', async ({ page }) => {
|
||||
await page.route('**/api/tasks/1', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ code: 200, message: '删除成功' }),
|
||||
}),
|
||||
);
|
||||
|
||||
await page.locator('.action-card').locator('button', { hasText: '删除任务' }).click();
|
||||
await expect(page.locator('.task-list-item')).toHaveCount(1, { timeout: 5000 });
|
||||
});
|
||||
|
||||
test('shows empty state when no tasks', async ({ page }) => {
|
||||
await page.route('**/api/tasks**', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockTasksEmpty),
|
||||
}),
|
||||
);
|
||||
|
||||
await page.goto('/study');
|
||||
await page.waitForSelector('.study-page', { timeout: 10_000 });
|
||||
await expect(page.locator('.el-empty')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user