前后端目录重命名: - 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 文档中的路径引用
277 lines
8.6 KiB
TypeScript
277 lines
8.6 KiB
TypeScript
/**
|
|
* 超管端 E2E 测试 - 课程包管理
|
|
*/
|
|
|
|
import { test, expect } from '@playwright/test';
|
|
import { loginAsAdmin, waitForTable, waitForSuccess } from './helpers';
|
|
import { TEST_DATA } from './fixtures';
|
|
|
|
test.describe('课程包管理', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await loginAsAdmin(page);
|
|
// 导航到课程包列表页面
|
|
await page.goto('/admin/courses');
|
|
});
|
|
|
|
test.describe('列表页面', () => {
|
|
test('访问课程包列表页面', async ({ page }) => {
|
|
// 验证页面 URL
|
|
await expect(page).toHaveURL(/\/admin\/courses/);
|
|
});
|
|
|
|
test('验证列表加载', async ({ page }) => {
|
|
// 等待表格加载
|
|
await waitForTable(page);
|
|
|
|
// 验证表格存在
|
|
const table = page.locator('table, .ant-table');
|
|
await expect(table).toBeVisible();
|
|
|
|
// 验证新建按钮存在
|
|
const createButton = page.getByText(/新建课程包|创建课程包/);
|
|
await expect(createButton).toBeVisible();
|
|
});
|
|
|
|
test('搜索功能', async ({ page }) => {
|
|
await waitForTable(page);
|
|
|
|
// 输入搜索关键词
|
|
const searchInput = page.getByPlaceholder(/搜索课程包名称/);
|
|
await searchInput.fill('测试');
|
|
await searchInput.press('Enter');
|
|
|
|
// 等待搜索结果
|
|
await page.waitForTimeout(1000);
|
|
|
|
// 验证搜索结果
|
|
const table = page.locator('table, .ant-table');
|
|
await expect(table).toBeVisible();
|
|
});
|
|
|
|
test('筛选功能 - 按状态', async ({ page }) => {
|
|
await waitForTable(page);
|
|
|
|
// 选择状态筛选
|
|
const statusSelect = page.getByPlaceholder('状态');
|
|
await statusSelect.click();
|
|
await page.getByText('已发布').click();
|
|
|
|
// 等待筛选结果
|
|
await page.waitForTimeout(1000);
|
|
|
|
// 验证筛选结果
|
|
const table = page.locator('table, .ant-table');
|
|
await expect(table).toBeVisible();
|
|
});
|
|
|
|
test('分页功能', async ({ page }) => {
|
|
await waitForTable(page);
|
|
|
|
// 验证分页控件存在
|
|
const pagination = page.locator('.ant-pagination');
|
|
await expect(pagination).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('创建课程包', () => {
|
|
test('点击创建按钮', async ({ page }) => {
|
|
// 点击新建课程包按钮
|
|
const createButton = page.getByText(/新建课程包|创建课程包/);
|
|
await createButton.click();
|
|
|
|
// 验证跳转到创建页面
|
|
await page.waitForURL(/\/admin\/courses\/create/);
|
|
await expect(page.locator('.ant-steps')).toBeVisible();
|
|
});
|
|
|
|
test('步骤 1: 填写基本信息', async ({ page }) => {
|
|
// 导航到创建页面
|
|
await page.goto('/admin/courses/create');
|
|
await page.waitForTimeout(500);
|
|
|
|
// 填写课程包名称
|
|
const nameInput = page.locator('input[placeholder*="课程包名称"]');
|
|
await nameInput.fill(TEST_DATA.course.name);
|
|
|
|
// 选择年龄段
|
|
const ageSelect = page.locator('[placeholder*="年龄段"]');
|
|
if (await ageSelect.isVisible()) {
|
|
await ageSelect.click();
|
|
await page.getByText('3-4 岁').click();
|
|
}
|
|
|
|
// 点击下一步
|
|
const nextButton = page.getByText('下一步');
|
|
await nextButton.click();
|
|
|
|
// 验证进入步骤 2
|
|
await expect(page.getByText(/课程介绍|课程目标/)).toBeVisible({ timeout: 5000 });
|
|
});
|
|
|
|
test('步骤 2: 课程介绍', async ({ page }) => {
|
|
// 导航到创建页面并填写基本信息后进入步骤 2
|
|
await page.goto('/admin/courses/create');
|
|
await page.waitForTimeout(500);
|
|
|
|
// 填写基本信息
|
|
const nameInput = page.locator('input[placeholder*="课程包名称"]');
|
|
await nameInput.fill(TEST_DATA.course.name);
|
|
|
|
// 点击下一步进入步骤 2
|
|
const nextButton = page.getByText('下一步');
|
|
await nextButton.click();
|
|
|
|
// 等待步骤 2 加载
|
|
await page.waitForTimeout(500);
|
|
|
|
// 填写课程目标
|
|
const goalInput = page.locator('textarea[placeholder*="目标"]');
|
|
if (await goalInput.isVisible()) {
|
|
await goalInput.fill(TEST_DATA.course.goal);
|
|
}
|
|
|
|
// 点击下一步
|
|
await nextButton.click();
|
|
|
|
// 验证进入步骤 3
|
|
await expect(page.getByText(/排课参考/)).toBeVisible({ timeout: 5000 });
|
|
});
|
|
|
|
test('步骤 3: 排课参考', async ({ page }) => {
|
|
// 导航到步骤 3
|
|
await page.goto('/admin/courses/create');
|
|
await page.waitForTimeout(500);
|
|
|
|
// 填写基本信息
|
|
const nameInput = page.locator('input[placeholder*="课程包名称"]');
|
|
await nameInput.fill(TEST_DATA.course.name);
|
|
|
|
// 点击下一步两次进入步骤 3
|
|
const nextButton = page.getByText('下一步');
|
|
await nextButton.click();
|
|
await nextButton.click();
|
|
|
|
// 等待步骤 3 加载
|
|
await page.waitForTimeout(500);
|
|
|
|
// 填写排课参考内容
|
|
const textarea = page.locator('textarea').first();
|
|
if (await textarea.isVisible()) {
|
|
await textarea.fill('这是一个测试排课参考');
|
|
}
|
|
|
|
// 点击下一步
|
|
await nextButton.click();
|
|
|
|
// 验证进入步骤 4
|
|
await expect(page.getByText(/导入课/)).toBeVisible({ timeout: 5000 });
|
|
});
|
|
});
|
|
|
|
test.describe('编辑课程包', () => {
|
|
test('点击编辑按钮', async ({ page }) => {
|
|
await waitForTable(page);
|
|
|
|
// 查找第一个课程包的编辑按钮
|
|
const editButton = page.locator('button:has-text("编辑")').first();
|
|
if (await editButton.isVisible()) {
|
|
await editButton.click();
|
|
|
|
// 验证跳转到编辑页面
|
|
await page.waitForURL(/\/admin\/courses\/\d+\/edit/);
|
|
await expect(page.locator('.ant-steps')).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('修改基本信息', async ({ page }) => {
|
|
await waitForTable(page);
|
|
|
|
// 查找第一个课程包的编辑按钮
|
|
const editButton = page.locator('button:has-text("编辑")').first();
|
|
if (await editButton.isVisible()) {
|
|
await editButton.click();
|
|
await page.waitForTimeout(1000);
|
|
|
|
// 修改课程包名称
|
|
const nameInput = page.locator('input[placeholder*="课程包名称"]');
|
|
const originalName = await nameInput.inputValue();
|
|
await nameInput.fill(`${originalName}_已修改`);
|
|
|
|
// 点击保存草稿
|
|
const saveButton = page.getByText(/保存草稿|保存/);
|
|
await saveButton.click();
|
|
|
|
// 等待保存成功提示
|
|
await page.waitForTimeout(1000);
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('删除课程包', () => {
|
|
test('点击删除按钮', async ({ page }) => {
|
|
await waitForTable(page);
|
|
|
|
// 查找第一个课程包的删除按钮
|
|
const deleteButton = page.locator('button:has-text("删除")').first();
|
|
if (await deleteButton.isVisible()) {
|
|
// 注意:这里只是验证删除按钮存在,实际删除操作需要谨慎
|
|
await expect(deleteButton).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('确认删除弹窗', async ({ page }) => {
|
|
await waitForTable(page);
|
|
|
|
// 查找第一个课程包的删除按钮
|
|
const deleteButton = page.locator('button:has-text("删除")').first();
|
|
if (await deleteButton.isVisible()) {
|
|
await deleteButton.click();
|
|
|
|
// 等待确认弹窗
|
|
const confirmDialog = page.locator('.ant-modal-confirm');
|
|
await expect(confirmDialog).toBeVisible({ timeout: 5000 });
|
|
|
|
// 点击取消,不实际删除
|
|
const cancelButton = page.locator('.ant-modal-confirm button:has-text("取消")');
|
|
if (await cancelButton.isVisible()) {
|
|
await cancelButton.click();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('课程包详情', () => {
|
|
test('查看详情页', async ({ page }) => {
|
|
await waitForTable(page);
|
|
|
|
// 点击第一个课程包名称链接
|
|
const courseLink = page.locator('table a').first();
|
|
if (await courseLink.isVisible()) {
|
|
await courseLink.click();
|
|
|
|
// 验证跳转到详情页面
|
|
await page.waitForURL(/\/admin\/courses\/\d+/);
|
|
await expect(page.getByText(/课程包详情/)).toBeVisible({ timeout: 5000 });
|
|
}
|
|
});
|
|
|
|
test('查看课程资源', async ({ page }) => {
|
|
await waitForTable(page);
|
|
|
|
// 点击第一个课程包名称链接
|
|
const courseLink = page.locator('table a').first();
|
|
if (await courseLink.isVisible()) {
|
|
await courseLink.click();
|
|
await page.waitForTimeout(1000);
|
|
|
|
// 查找资源标签页
|
|
const resourceTab = page.getByText(/资源|课程资源/);
|
|
if (await resourceTab.isVisible()) {
|
|
await resourceTab.click();
|
|
await page.waitForTimeout(500);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|