0be2b1c26e
覆盖场景:暂停后点击开始触发 continue API、 ONGOING 状态开始按钮 disabled、结束会话展示后端提示 注:需 Node.js >= 18.19 运行 Playwright
181 lines
5.5 KiB
TypeScript
181 lines
5.5 KiB
TypeScript
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 });
|
|
});
|
|
});
|