test: 新增 StartTask E2E 测试 (3 cases)
覆盖场景:暂停后点击开始触发 continue API、 ONGOING 状态开始按钮 disabled、结束会话展示后端提示 注:需 Node.js >= 18.19 运行 Playwright
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
const mockSessionOngoing = {
|
||||
code: 200,
|
||||
data: {
|
||||
sessionNum: 'SESSION_001',
|
||||
sessionState: 'ONGOING',
|
||||
taskName: '学习 Vue3',
|
||||
taskNum: 'T001',
|
||||
startTime: '2026-05-30T10:00:00',
|
||||
endTime: null,
|
||||
lastStartTime: '2026-05-30T10:00:00',
|
||||
actualTime: 0,
|
||||
effectiveTime: 0,
|
||||
effectivenessRatio: '--',
|
||||
pointerPosition: 1500000,
|
||||
systemMessage: '',
|
||||
},
|
||||
};
|
||||
|
||||
const mockSessionPaused = {
|
||||
code: 200,
|
||||
data: {
|
||||
...mockSessionOngoing.data,
|
||||
sessionState: 'PAUSED',
|
||||
lastStartTime: '2026-05-30T10:05:00',
|
||||
actualTime: 300,
|
||||
effectiveTime: 300,
|
||||
},
|
||||
};
|
||||
|
||||
const mockApiResponse = (code = 200, data: any = null, message = '请求成功') => ({
|
||||
code,
|
||||
message,
|
||||
data,
|
||||
});
|
||||
|
||||
test.describe('StartTask - 暂停后继续', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// 模拟登录
|
||||
await page.goto('/login');
|
||||
await page.evaluate(() => localStorage.setItem('isLoggedIn', 'true'));
|
||||
|
||||
// mock startOrContinue API(初始加载返回 ONGOING 状态)
|
||||
await page.route('**/api/tasks/*/study-sessions/start-or-continue', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockSessionOngoing),
|
||||
}),
|
||||
);
|
||||
|
||||
// mock fragments API
|
||||
await page.route('**/api/study-sessions/*/all-fragments', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockApiResponse(200, [])),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
test('暂停后点击开始,应触发 continue API', async ({ page }) => {
|
||||
// 记录 API 调用
|
||||
const apiCalls: string[] = [];
|
||||
|
||||
// mock pause API
|
||||
await page.route('**/api/study-sessions/SESSION_001/study-sessions/pause', (route) => {
|
||||
apiCalls.push('pause');
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockApiResponse()),
|
||||
});
|
||||
});
|
||||
|
||||
// mock continue API
|
||||
await page.route('**/api/study-sessions/SESSION_001/study-sessions/continue', (route) => {
|
||||
apiCalls.push('continue');
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockApiResponse()),
|
||||
});
|
||||
});
|
||||
|
||||
// 进入 start-task 页面
|
||||
await page.goto('/start-task/T001');
|
||||
await page.waitForSelector('.start-page', { timeout: 10_000 });
|
||||
|
||||
// 等待计时器启动
|
||||
await expect(page.locator('.status-text')).toContainText('进行中');
|
||||
|
||||
// 点击暂停按钮
|
||||
await page.locator('button', { hasText: '暂停' }).click();
|
||||
|
||||
// 验证暂停 API 被调用
|
||||
expect(apiCalls).toContain('pause');
|
||||
|
||||
// 验证状态变为已暂停
|
||||
await expect(page.locator('.status-text')).toContainText('已暂停');
|
||||
|
||||
// 点击开始按钮
|
||||
await page.locator('button', { hasText: '开始' }).click();
|
||||
|
||||
// 验证 continue API 被调用
|
||||
expect(apiCalls).toContain('continue');
|
||||
|
||||
// 验证状态恢复为进行中
|
||||
await expect(page.locator('.status-text')).toContainText('进行中');
|
||||
});
|
||||
|
||||
test('暂停后点击开始,不暂停时开始不应触发 continue API', async ({ page }) => {
|
||||
const apiCalls: string[] = [];
|
||||
|
||||
await page.route('**/api/study-sessions/SESSION_001/study-sessions/pause', (route) => {
|
||||
apiCalls.push('pause');
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockApiResponse()),
|
||||
});
|
||||
});
|
||||
|
||||
await page.route('**/api/study-sessions/SESSION_001/study-sessions/continue', (route) => {
|
||||
apiCalls.push('continue');
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockApiResponse()),
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto('/start-task/T001');
|
||||
await page.waitForSelector('.start-page', { timeout: 10_000 });
|
||||
await expect(page.locator('.status-text')).toContainText('进行中');
|
||||
|
||||
// ONGOING 状态下,开始按钮是 disabled 的,不应触发 continue
|
||||
const startBtn = page.locator('button', { hasText: '开始' });
|
||||
await expect(startBtn).toBeDisabled();
|
||||
|
||||
// continue API 不应被调用
|
||||
expect(apiCalls).not.toContain('continue');
|
||||
});
|
||||
|
||||
test('暂停后结束会话,应正确调用 ended API 并展示提示', async ({ page }) => {
|
||||
await page.route('**/api/study-sessions/SESSION_001/study-sessions/pause', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockApiResponse()),
|
||||
}),
|
||||
);
|
||||
|
||||
await page.route('**/api/study-sessions/SESSION_001/study-sessions/ended', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockApiResponse(200, null, '本次有效学习时间不足10分钟,不计入总学习时间')),
|
||||
}),
|
||||
);
|
||||
|
||||
await page.goto('/start-task/T001');
|
||||
await page.waitForSelector('.start-page', { timeout: 10_000 });
|
||||
|
||||
// 暂停
|
||||
await page.locator('button', { hasText: '暂停' }).click();
|
||||
await expect(page.locator('.status-text')).toContainText('已暂停');
|
||||
|
||||
// 结束会话
|
||||
await page.locator('button', { hasText: '结束会话' }).click();
|
||||
|
||||
// 在弹窗中输入总结内容
|
||||
await page.locator('.el-dialog textarea').fill('测试总结');
|
||||
await page.locator('.el-dialog button', { hasText: '确认结束' }).click();
|
||||
|
||||
// 应看到 warning 提示(有效时间不足)
|
||||
await expect(page.locator('.el-message--warning')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user