475 lines
16 KiB
TypeScript
475 lines
16 KiB
TypeScript
|
|
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' });
|
||
|
|
});
|
||
|
|
});
|