import { test, expect } from '@playwright/test'; test.describe('课后记录流程', () => { let baseURL = 'http://localhost:5173'; test.beforeEach(async ({ page }) => { await page.goto(baseURL); await page.waitForLoadState('networkidle'); await page.click('text=教师'); await page.waitForTimeout(500); const accountInput = page.locator('input[placeholder*="账号"]').or(page.locator('input[name="account"]')); await accountInput.fill('teacher1'); const passwordInput = page.locator('input[placeholder*="密码"]').or(page.locator('input[type="password"]')); await passwordInput.fill('123456'); const loginButton = page.locator('button[type="submit"]').or(page.locator('.login-btn')).or(page.locator('button:has-text("登录")')); await loginButton.click(); await page.waitForURL('**/dashboard', { timeout: 10000 }).catch(() => { return page.waitForURL('**/courses', { timeout: 5000 }); }); await page.waitForTimeout(1000); }); test('测试1: 进入课后记录页面', async ({ page }) => { test.slow(); // 1. 进入上课记录 await page.click('text=上课记录'); await page.waitForTimeout(2000); // 2. 点击第一个记录的"课后记录"或"填写记录"按钮 const postClassButton = page.locator('button:has-text("课后记录")').or(page.locator('button:has-text("填写记录")')).or(page.locator('button:has-text("记录")')); const buttonExists = await postClassButton.count() > 0; if (buttonExists) { await postClassButton.first().click(); await page.waitForTimeout(2000); // 3. 验证进入课后记录页面 const url = page.url(); const isRecordPage = url.includes('record') || url.includes('feedback') || url.includes('post'); test.info().annotations.push({ type: 'info', description: isRecordPage ? `进入课后记录页: ${url}` : `当前URL: ${url}`, }); // 4. 验证页面结构 const form = page.locator('form, [class*="form"], [class*="record"]'); expect(await form.count()).toBeGreaterThan(0); } else { // 如果没有按钮,尝试直接点击记录项 const recordItems = page.locator('[class*="record"], [class*="lesson"]'); if (await recordItems.count() > 0) { await recordItems.first().click(); await page.waitForTimeout(2000); // 查找填写记录按钮 const fillButton = page.locator('button:has-text("填写")').or(page.locator('button:has-text("记录")')); if (await fillButton.count() > 0) { await fillButton.first().click(); await page.waitForTimeout(2000); } } } await page.screenshot({ path: 'test-results/post-class-enter.png' }); }); test('测试2: 基本信息填写', async ({ page }) => { test.slow(); // 进入课后记录页面 await page.click('text=上课记录'); await page.waitForTimeout(2000); const recordItems = page.locator('[class*="record"], [class*="lesson"]'); if (await recordItems.count() > 0) { await recordItems.first().click(); await page.waitForTimeout(2000); const fillButton = page.locator('button:has-text("填写")').or(page.locator('button:has-text("记录")')); if (await fillButton.count() > 0) { await fillButton.first().click(); await page.waitForTimeout(2000); } } await page.waitForTimeout(1000); // 1. 验证日期字段 const dateField = page.locator('[class*="date"]').or(page.locator('input[type="date"]')); const hasDateField = await dateField.count() > 0; // 2. 验证班级选择 const classField = page.locator('[class*="class"]').or(page.locator('select')); const hasClassField = await classField.count() > 0; // 3. 验证课程信息显示 const courseInfo = page.locator('[class*="course"], [class*="info"]'); const hasCourseInfo = await courseInfo.count() > 0; test.info().annotations.push({ type: 'info', description: `日期字段: ${hasDateField}, 班级字段: ${hasClassField}, 课程信息: ${hasCourseInfo}`, }); await page.screenshot({ path: 'test-results/post-class-basic-info.png' }); }); test('测试3: 教学反思填写', async ({ page }) => { test.slow(); // 进入课后记录页面 await page.click('text=上课记录'); await page.waitForTimeout(2000); const recordItems = page.locator('[class*="record"], [class*="lesson"]'); if (await recordItems.count() > 0) { await recordItems.first().click(); await page.waitForTimeout(2000); const fillButton = page.locator('button:has-text("填写")').or(page.locator('button:has-text("记录")')); if (await fillButton.count() > 0) { await fillButton.first().click(); await page.waitForTimeout(2000); } } await page.waitForTimeout(1000); // 1. 查找教学反思输入框 const reflectionField = page.locator('textarea, [contenteditable="true"], [class*="reflection"]').or(page.locator('text=教学反思')); const reflectionCount = await reflectionField.count(); if (reflectionCount > 0) { // 2. 填写教学反思 const textarea = reflectionField.first().locator('textarea').or(page.locator('[contenteditable="true"]')); const editableCount = await textarea.count(); if (editableCount > 0) { await textarea.first().fill('这是一次成功的授课,学生参与度很高,互动良好。'); await page.waitForTimeout(1000); test.info().annotations.push({ type: 'success', description: '教学反思填写成功', }); } } await page.screenshot({ path: 'test-results/post-class-reflection.png' }); }); test('测试4: 学生表现记录', async ({ page }) => { test.slow(); // 进入课后记录页面 await page.click('text=上课记录'); await page.waitForTimeout(2000); const recordItems = page.locator('[class*="record"], [class*="lesson"]'); if (await recordItems.count() > 0) { await recordItems.first().click(); await page.waitForTimeout(2000); const fillButton = page.locator('button:has-text("填写")').or(page.locator('button:has-text("记录")')); if (await fillButton.count() > 0) { await fillButton.first().click(); await page.waitForTimeout(2000); } } await page.waitForTimeout(1000); // 1. 查找学生表现区域 const performanceSection = page.locator('text=学生表现').or(page.locator('[class*="student"], [class*="performance"]')); const hasPerformanceSection = await performanceSection.count() > 0; // 2. 查找评分或评价控件 const ratingControl = page.locator('[class*="rate"], [class*="score"], .ant-rate'); const hasRating = await ratingControl.count() > 0; // 3. 查找学生列表 const studentList = page.locator('[class*="student"], [class*="child"]'); const studentCount = await studentList.count(); test.info().annotations.push({ type: 'info', description: `学生表现区域: ${hasPerformanceSection}, 评分控件: ${hasRating}, 学生数量: ${studentCount}`, }); await page.screenshot({ path: 'test-results/post-class-performance.png' }); }); test('测试5: 教学效果评估', async ({ page }) => { test.slow(); // 进入课后记录页面 await page.click('text=上课记录'); await page.waitForTimeout(2000); const recordItems = page.locator('[class*="record"], [class*="lesson"]'); if (await recordItems.count() > 0) { await recordItems.first().click(); await page.waitForTimeout(2000); const fillButton = page.locator('button:has-text("填写")').or(page.locator('button:has-text("记录")')); if (await fillButton.count() > 0) { await fillButton.first().click(); await page.waitForTimeout(2000); } } await page.waitForTimeout(1000); // 1. 查找教学效果评估区域 const effectSection = page.locator('text=教学效果').or(page.locator('text=效果评估')); const hasEffectSection = await effectSection.count() > 0; // 2. 查找目标达成度评估 const goalSection = page.locator('text=目标').or(page.locator('text=达成')); const hasGoalSection = await goalSection.count() > 0; test.info().annotations.push({ type: 'info', description: `效果评估: ${hasEffectSection}, 目标达成度: ${hasGoalSection}`, }); await page.screenshot({ path: 'test-results/post-class-effect.png' }); }); test('测试6: 照片/视频上传', async ({ page }) => { test.slow(); // 进入课后记录页面 await page.click('text=上课记录'); await page.waitForTimeout(2000); const recordItems = page.locator('[class*="record"], [class*="lesson"]'); if (await recordItems.count() > 0) { await recordItems.first().click(); await page.waitForTimeout(2000); const fillButton = page.locator('button:has-text("填写")').or(page.locator('button:has-text("记录")')); if (await fillButton.count() > 0) { await fillButton.first().click(); await page.waitForTimeout(2000); } } await page.waitForTimeout(1000); // 1. 查找上传按钮 const uploadButton = page.locator('button:has-text("上传")').or(page.locator('[class*="upload"]')); const uploadCount = await uploadButton.count(); // 2. 查找文件输入控件 const fileInput = page.locator('input[type="file"]'); const fileCount = await fileInput.count(); test.info().annotations.push({ type: 'info', description: `上传按钮: ${uploadCount}, 文件输入: ${fileCount}`, }); await page.screenshot({ path: 'test-results/post-class-upload.png' }); }); test('测试7: 保存课后记录', async ({ page }) => { test.slow(); // 进入课后记录页面 await page.click('text=上课记录'); await page.waitForTimeout(2000); const recordItems = page.locator('[class*="record"], [class*="lesson"]'); if (await recordItems.count() > 0) { await recordItems.first().click(); await page.waitForTimeout(2000); const fillButton = page.locator('button:has-text("填写")').or(page.locator('button:has-text("记录")')); if (await fillButton.count() > 0) { await fillButton.first().click(); await page.waitForTimeout(2000); } } await page.waitForTimeout(1000); // 1. 填写一些内容 const reflectionField = page.locator('textarea, [contenteditable="true"]'); if (await reflectionField.count() > 0) { await reflectionField.first().fill('测试课后记录内容'); await page.waitForTimeout(500); } // 2. 查找保存按钮 const saveButton = page.locator('button:has-text("保存")').or(page.locator('button:has-text("提交")')); const saveCount = await saveButton.count(); if (saveCount > 0) { // 3. 点击保存 await saveButton.first().click(); await page.waitForTimeout(2000); // 4. 检查是否有成功提示 const successMessage = page.locator('text=成功').or(page.locator('text=保存')); const hasSuccessMessage = await successMessage.count() > 0; test.info().annotations.push({ type: 'info', description: hasSuccessMessage ? '保存成功提示已显示' : '未检测到成功提示', }); } await page.screenshot({ path: 'test-results/post-class-save.png' }); }); test('测试8: 布置阅读任务', async ({ page }) => { test.slow(); // 进入课后记录页面 await page.click('text=上课记录'); await page.waitForTimeout(2000); const recordItems = page.locator('[class*="record"], [class*="lesson"]'); if (await recordItems.count() > 0) { await recordItems.first().click(); await page.waitForTimeout(2000); const fillButton = page.locator('button:has-text("填写")').or(page.locator('button:has-text("记录")')); if (await fillButton.count() > 0) { await fillButton.first().click(); await page.waitForTimeout(2000); } } await page.waitForTimeout(1000); // 1. 查找布置任务按钮或Tab const taskButton = page.locator('button:has-text("布置任务")').or(page.locator('text=布置任务')); const hasTaskButton = await taskButton.count() > 0; if (hasTaskButton) { // 2. 点击布置任务 await taskButton.first().click(); await page.waitForTimeout(1000); // 3. 验证任务布置界面 const taskModal = page.locator('[class*="modal"]').or(page.locator('[class*="task"]')); const hasTaskModal = await taskModal.count() > 0; test.info().annotations.push({ type: 'info', description: hasTaskModal ? '任务布置界面已显示' : '未找到任务布置界面', }); } await page.screenshot({ path: 'test-results/post-class-task.png' }); }); test('测试9: 查看历史记录', async ({ page }) => { test.slow(); // 1. 进入上课记录 await page.click('text=上课记录'); await page.waitForTimeout(2000); // 2. 查找已完成记录的标记 const completedRecords = page.locator('text=已完成').or(page.locator('[class*="completed"]')); const completedCount = await completedRecords.count(); // 3. 查看历史记录筛选 const filterControls = page.locator('.ant-select, [class*="filter"]'); const filterCount = await filterControls.count(); // 4. 点击一个已完成的记录查看详情 if (completedCount > 0) { await completedRecords.first().click(); await page.waitForTimeout(2000); // 5. 验证详情显示 const detailContent = page.locator('[class*="detail"], [class*="content"]'); const hasDetail = await detailContent.count() > 0; test.info().annotations.push({ type: 'info', description: hasDetail ? '记录详情已显示' : '未找到详情内容', }); } test.info().annotations.push({ type: 'info', description: `已完成记录: ${completedCount}, 筛选控件: ${filterCount}`, }); await page.screenshot({ path: 'test-results/post-class-history.png' }); }); test('测试10: 编辑和删除记录', async ({ page }) => { test.slow(); // 1. 进入上课记录 await page.click('text=上课记录'); await page.waitForTimeout(2000); // 2. 查找编辑按钮 const editButton = page.locator('button:has-text("编辑")'); const editCount = await editButton.count(); // 3. 查找删除按钮 const deleteButton = page.locator('button:has-text("删除")'); const deleteCount = await deleteButton.count(); test.info().annotations.push({ type: 'info', description: `编辑按钮: ${editCount}, 删除按钮: ${deleteCount}`, }); // 注意:不实际执行删除操作,避免影响数据 await page.screenshot({ path: 'test-results/post-class-edit-delete.png' }); }); test('测试11: 课程反馈提交', async ({ page }) => { test.slow(); // 1. 进入课程反馈页面 await page.click('text=课程反馈'); await page.waitForTimeout(2000); // 2. 验证反馈列表 const feedbackList = page.locator('[class*="feedback"], [class*="list"]'); const listCount = await feedbackList.count(); // 3. 查找填写反馈按钮 const createButton = page.locator('button:has-text("填写")').or(page.locator('button:has-text("添加")')); const createCount = await createButton.count(); test.info().annotations.push({ type: 'info', description: `反馈列表: ${listCount}, 创建按钮: ${createCount}`, }); await page.screenshot({ path: 'test-results/feedback-list.png' }); }); test('测试12: 记录统计和导出', async ({ page }) => { test.slow(); // 1. 进入上课记录 await page.click('text=上课记录'); await page.waitForTimeout(2000); // 2. 查找统计信息 const statCards = page.locator('[class*="stat"], [class*="summary"]'); const statCount = await statCards.count(); // 3. 查找导出按钮 const exportButton = page.locator('button:has-text("导出")'); const exportCount = await exportButton.count(); test.info().annotations.push({ type: 'info', description: `统计卡片: ${statCount}, 导出按钮: ${exportCount}`, }); await page.screenshot({ path: 'test-results/post-class-stats.png' }); }); });