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, [])), }), ); // mock 学习预期(已存在,避免强制弹窗阻塞流程) await page.route('**/api/study-sessions/*/expectation', (route) => route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockApiResponse(200, { sessionNum: 'SESSION_001', description: '测试预期' })), }), ); // mock 报告草稿 await page.route('**/api/study-sessions/*/report-draft', (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 }); }); });