kindergarten_java/lesingle-edu-reading-platform-frontend/tests/e2e/phase6-school-course/school-course.spec.ts
En 40589f59e7 chore: 重命名项目目录
前后端目录重命名:
- reading-platform-java/ → lesingle-edu-reading-platform-backend/
- reading-platform-frontend/ → lesingle-edu-reading-platform-frontend/

更新相关文件:
- 所有 shell 脚本中的目录引用
- pom.xml 和 application.yml 中的项目名称
- package.json 中的项目名称
- .claude/CLAUDE.md 中的路径引用
- README 文档中的路径引用
2026-03-26 11:31:47 +08:00

322 lines
11 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { test, expect } from '@playwright/test';
test.describe('Phase 6: 校本课程包功能测试', () => {
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();
// 等待登录成功 - 跳转到 dashboard 或 courses
await page.waitForURL('**/dashboard', { timeout: 10000 }).catch(() => {
// 如果没有跳转到 dashboard可能已经跳转到其他页面检查是否成功
return page.waitForURL('**/courses', { timeout: 5000 });
});
await page.waitForTimeout(1000);
});
test('测试1: 创建校本课程包流程', async ({ page }) => {
test.slow();
// 1. 进入课程中心
await page.click('text=课程中心');
await page.waitForURL('**/courses', { timeout: 10000 });
await page.waitForTimeout(1000);
// 2. 点击第一个课程卡片(整个卡片可点击)
const firstCourseCard = page.locator('.course-card').or(page.locator('[class*="course-card"]')).first();
const cardCount = await firstCourseCard.count();
if (cardCount > 0) {
await firstCourseCard.click();
await page.waitForTimeout(2000);
// 3. 检查是否有"创建校本版本"按钮
const createSchoolVersionButton = page.locator('button:has-text("创建校本版本")');
const buttonExists = await createSchoolVersionButton.count();
if (buttonExists > 0) {
// 记录当前URL
const beforeUrl = page.url();
// 4. 点击"创建校本版本"按钮
await createSchoolVersionButton.click();
// 5. 等待自动创建并跳转到编辑页面(系统自动创建并跳转)
await page.waitForURL('**/school-courses/**/edit', { timeout: 15000 });
await page.waitForTimeout(2000);
// 6. 验证页面标题显示正确
await expect(page.locator('text=创建校本课程包').or(page.locator('text=编辑校本课程包'))).toBeVisible();
// 7. 验证URL包含school-courses编辑页路径
const currentUrl = page.url();
expect(currentUrl).toMatch(/\/school-courses\/\d+\/edit/);
test.info().annotations.push({
type: 'result',
description: `创建成功,从 ${beforeUrl} 跳转到 ${currentUrl}`,
});
} else {
test.info().annotations.push({
type: 'warning',
description: '未找到"创建校本版本"按钮',
});
}
} else {
test.info().annotations.push({
type: 'warning',
description: '未找到课程卡片',
});
}
});
test('测试2: 个人课程中心列表', async ({ page }) => {
// 1. 进入校本课程包页面
await page.click('text=校本课程包');
await page.waitForURL('**/school-courses', { timeout: 10000 });
await page.waitForTimeout(2000);
// 2. 验证页面标题
await expect(page.locator('text=我的校本课程包').or(page.locator('text=校本课程包')).first()).toBeVisible({ timeout: 5000 });
// 3. 检查保存位置筛选器
const filterTabs = page.locator('text=全部').or(page.locator('text=个人')).or(page.locator('text=校本'));
const filterCount = await filterTabs.count();
test.info().annotations.push({
type: 'info',
description: `筛选器数量: ${filterCount}`,
});
// 4. 检查课程列表
const courseCards = page.locator('.ant-card, [class*="course"], [class*="Course"]');
const courseCount = await courseCards.count();
test.info().annotations.push({
type: 'info',
description: `课程数量: ${courseCount}`,
});
// 截图
await page.screenshot({ path: 'test-results/school-course-list.png' });
});
test('测试3: 编辑校本课程包', async ({ page }) => {
test.slow();
// 1. 进入校本课程包页面
await page.click('text=校本课程包');
await page.waitForURL('**/school-courses', { timeout: 10000 });
await page.waitForTimeout(2000);
// 2. 查找编辑按钮
const editButton = page.locator('button:has-text("编辑")').first();
if (await editButton.count() > 0) {
await editButton.click();
await page.waitForTimeout(2000);
// 3. 验证进入编辑页面
const url = page.url();
expect(url).toContain('/edit');
// 4. 检查步骤导航
const steps = page.locator('.ant-steps-item, [class*="step"]');
const stepCount = await steps.count();
test.info().annotations.push({
type: 'info',
description: `编辑步骤数量: ${stepCount}`,
});
// 5. 尝试切换步骤
const step2 = page.locator('text=课程介绍').or(page.locator('text=步骤2'));
if (await step2.count() > 0) {
await step2.first().click();
await page.waitForTimeout(1000);
}
// 6. 保存修改
const saveButton = page.locator('button:has-text("保存")').or(page.locator('button:has-text("保存到个人")'));
if (await saveButton.count() > 0) {
await saveButton.first().click();
await page.waitForTimeout(2000);
}
// 截图
await page.screenshot({ path: 'test-results/school-course-edit.png' });
} else {
test.info().annotations.push({
type: 'warning',
description: '未找到可编辑的课程',
});
}
});
test('测试4: 查看校本课程详情', async ({ page }) => {
// 1. 进入校本课程包页面
await page.click('text=校本课程包');
await page.waitForURL('**/school-courses', { timeout: 10000 });
await page.waitForTimeout(2000);
// 2. 查找查看按钮
const viewButton = page.locator('button:has-text("查看")').first();
if (await viewButton.count() > 0) {
await viewButton.click();
await page.waitForTimeout(2000);
// 3. 验证详情页面
const url = page.url();
expect(url).toContain('/school-courses/');
// 4. 检查详情页内容
const detailElements = page.locator('text=开始备课').or(page.locator('text=课程介绍'));
await expect(detailElements.first()).toBeVisible({ timeout: 5000 });
// 截图
await page.screenshot({ path: 'test-results/school-course-detail.png' });
} else {
test.info().annotations.push({
type: 'warning',
description: '未找到可查看的课程',
});
}
});
test('测试5: 备课模式', async ({ page }) => {
test.slow();
// 1. 进入校本课程包页面
await page.click('text=校本课程包');
await page.waitForURL('**/school-courses', { timeout: 10000 });
await page.waitForTimeout(2000);
// 2. 查找"开始备课"按钮
const prepareButton = page.locator('button:has-text("开始备课")').first();
if (await prepareButton.count() > 0) {
await prepareButton.click();
await page.waitForTimeout(3000);
// 3. 验证进入备课模式
const url = page.url();
expect(url).toContain('/prepare');
// 4. 检查备课模式布局
const navigation = page.locator('aside, [class*="navigation"], [class*="sidebar"]');
await expect(navigation.first()).toBeVisible({ timeout: 5000 });
// 5. 检查课程列表
const lessonItems = page.locator('[class*="lesson"], [class*="course"]');
const lessonCount = await lessonItems.count();
test.info().annotations.push({
type: 'info',
description: `备课模式课程数量: ${lessonCount}`,
});
// 截图
await page.screenshot({ path: 'test-results/prepare-mode.png' });
} else {
test.info().annotations.push({
type: 'warning',
description: '未找到"开始备课"按钮',
});
}
});
test('测试6: 删除校本课程包', async ({ page }) => {
// 1. 进入校本课程包页面
await page.click('text=校本课程包');
await page.waitForURL('**/school-courses', { timeout: 10000 });
await page.waitForTimeout(2000);
// 2. 记录删除前的课程数量
const courseCards = page.locator('.ant-card, [class*="course"]');
const beforeCount = await courseCards.count();
// 3. 查找删除按钮
const deleteButton = page.locator('button:has-text("删除")').first();
if (await deleteButton.count() > 0) {
// 4. 点击删除
await deleteButton.click();
await page.waitForTimeout(1000);
// 5. 确认删除
const confirmButton = page.locator('button:has-text("确定")').or(page.locator('button:has-text("确认")'));
if (await confirmButton.count() > 0) {
await confirmButton.first().click();
await page.waitForTimeout(2000);
}
// 6. 验证删除成功
const afterCount = await courseCards.count();
test.info().annotations.push({
type: 'info',
description: `删除前: ${beforeCount}, 删除后: ${afterCount}`,
});
} else {
test.info().annotations.push({
type: 'warning',
description: '未找到删除按钮',
});
}
});
test('测试7: 筛选功能', async ({ page }) => {
// 1. 进入校本课程包页面
await page.click('text=校本课程包');
await page.waitForURL('**/school-courses', { timeout: 10000 });
await page.waitForTimeout(2000);
// 2. 查找筛选器
const personalFilter = page.locator('text=个人').or(page.locator('[role="tab"]:has-text("个人")'));
const schoolFilter = page.locator('text=校本').or(page.locator('[role="tab"]:has-text("校本")'));
if (await personalFilter.count() > 0) {
// 3. 点击"个人"筛选
await personalFilter.first().click();
await page.waitForTimeout(1000);
// 4. 点击"校本"筛选
if (await schoolFilter.count() > 0) {
await schoolFilter.first().click();
await page.waitForTimeout(1000);
}
test.info().annotations.push({
type: 'success',
description: '筛选功能测试完成',
});
} else {
test.info().annotations.push({
type: 'warning',
description: '未找到筛选器',
});
}
// 截图
await page.screenshot({ path: 'test-results/school-course-filter.png' });
});
});