239 lines
9.3 KiB
TypeScript
239 lines
9.3 KiB
TypeScript
|
|
/**
|
|||
|
|
* 课程包创建 E2E 测试 - 基于"折耳兔奇奇"模板
|
|||
|
|
*
|
|||
|
|
* 测试流程:
|
|||
|
|
* 1. 超管登录
|
|||
|
|
* 2. 进入课程管理页面
|
|||
|
|
* 3. 新建课程包
|
|||
|
|
* 4. 完成 7 个步骤
|
|||
|
|
* 5. 验证创建成功
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import { test, expect } from '@playwright/test';
|
|||
|
|
import { loginAsAdmin, waitForTable } from './helpers';
|
|||
|
|
|
|||
|
|
// 测试数据 - 基于 JSON 模板简化(使用实际存在的主题和领域)
|
|||
|
|
const TEST_COURSE = {
|
|||
|
|
name: '折耳兔奇奇测试课程 01',
|
|||
|
|
theme: '社会认知', // 使用实际存在的主题
|
|||
|
|
grades: ['小班'],
|
|||
|
|
bookName: '折耳兔奇奇',
|
|||
|
|
coreContent: '通过折耳兔奇奇的故事,帮助孩子理解友谊和分享的重要性',
|
|||
|
|
domainTags: ['倾听与表达'], // 使用实际存在的选项文本
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
test.describe('课程包创建 - 折耳兔奇奇模板', () => {
|
|||
|
|
test('完整流程:创建课程包并验证', async ({ page }) => {
|
|||
|
|
test.setTimeout(180000); // 设置更长的超时时间(3 分钟)
|
|||
|
|
|
|||
|
|
// 步骤 1: 登录
|
|||
|
|
await loginAsAdmin(page);
|
|||
|
|
console.log('✅ 登录成功');
|
|||
|
|
|
|||
|
|
// 验证登录成功 - 检查是否跳转到 admin 页面
|
|||
|
|
await page.waitForURL('**/admin/**', { timeout: 15000 }).catch(() => {
|
|||
|
|
console.log('警告:URL 等待超时,但继续执行');
|
|||
|
|
});
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
|
|||
|
|
// 步骤 2: 进入课程管理页面
|
|||
|
|
await page.goto('/admin/courses', { timeout: 30000, waitUntil: 'commit' });
|
|||
|
|
await waitForTable(page, 15000);
|
|||
|
|
await page.waitForTimeout(500);
|
|||
|
|
console.log('✅ 进入课程管理页面');
|
|||
|
|
|
|||
|
|
// 步骤 3: 点击新建课程包按钮
|
|||
|
|
const createButton = page.getByText(/新建|创建|新增课程/);
|
|||
|
|
await createButton.click();
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
console.log('✅ 点击新建课程包');
|
|||
|
|
|
|||
|
|
// 验证进入创建页面
|
|||
|
|
await expect(page.getByText('创建课程包')).toBeVisible({ timeout: 5000 });
|
|||
|
|
await expect(page.getByText('基本信息')).toBeVisible();
|
|||
|
|
|
|||
|
|
// ==================== 步骤 1: 基本信息 ====================
|
|||
|
|
console.log('开始步骤 1: 基本信息');
|
|||
|
|
|
|||
|
|
// 填写课程包名称
|
|||
|
|
await page.getByPlaceholder('请输入课程包名称').fill(TEST_COURSE.name);
|
|||
|
|
console.log(' - 填写课程名称');
|
|||
|
|
|
|||
|
|
// 选择关联主题 - 先点击 selector 打开下拉框
|
|||
|
|
await page.locator('.ant-select-selector').first().click();
|
|||
|
|
await page.waitForTimeout(500);
|
|||
|
|
// 选择主题(主题选项在页面底部,直接使用 getByText)
|
|||
|
|
await page.getByText(TEST_COURSE.theme, { exact: true }).first().click();
|
|||
|
|
await page.waitForTimeout(300);
|
|||
|
|
console.log(' - 选择主题');
|
|||
|
|
|
|||
|
|
// 选择适用年级 - 使用 checkbox
|
|||
|
|
await page.getByRole('checkbox', { name: TEST_COURSE.grades[0] }).click();
|
|||
|
|
await page.waitForTimeout(300);
|
|||
|
|
console.log(' - 选择年级');
|
|||
|
|
|
|||
|
|
// 填写核心内容
|
|||
|
|
await page.getByPlaceholder('请输入课程包核心内容').fill(TEST_COURSE.coreContent);
|
|||
|
|
console.log(' - 填写核心内容');
|
|||
|
|
|
|||
|
|
// 填写绘本名称
|
|||
|
|
await page.getByPlaceholder('请输入关联绘本名称(可选)').fill(TEST_COURSE.bookName);
|
|||
|
|
console.log(' - 填写绘本名称');
|
|||
|
|
|
|||
|
|
// 选择领域标签 - 使用 selector 组件
|
|||
|
|
const domainSelector = page.locator('.ant-select-selector').last();
|
|||
|
|
await domainSelector.click();
|
|||
|
|
await page.waitForTimeout(800);
|
|||
|
|
// 选择领域标签(使用实际存在的选项文本)
|
|||
|
|
for (const tag of TEST_COURSE.domainTags) {
|
|||
|
|
await page.getByText(tag, { exact: true }).first().click({ force: true });
|
|||
|
|
await page.waitForTimeout(300);
|
|||
|
|
}
|
|||
|
|
// 关闭下拉
|
|||
|
|
await page.keyboard.press('Escape');
|
|||
|
|
await page.waitForTimeout(300);
|
|||
|
|
console.log(' - 选择领域标签');
|
|||
|
|
|
|||
|
|
// 点击下一步
|
|||
|
|
await page.getByRole('button', { name: '下一步' }).click();
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
console.log('✅ 步骤 1 完成');
|
|||
|
|
|
|||
|
|
// ==================== 步骤 2: 课程介绍 ====================
|
|||
|
|
console.log('开始步骤 2: 课程介绍');
|
|||
|
|
|
|||
|
|
// 验证步骤标题(使用更精确的选择器)
|
|||
|
|
await expect(page.locator('.ant-steps-item-title').nth(1)).toBeVisible();
|
|||
|
|
|
|||
|
|
// 切换到课程简介标签页并填写
|
|||
|
|
await page.getByRole('tab', { name: '课程简介' }).click();
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
const summaryTextarea = page.locator('.tab-content textarea:visible').first();
|
|||
|
|
await summaryTextarea.waitFor({ state: 'visible', timeout: 10000 });
|
|||
|
|
await summaryTextarea.fill('这是一门专为小班幼儿设计的课程,通过有趣的故事情节,培养孩子的语言表达能力和社交技能。');
|
|||
|
|
console.log(' - 填写课程简介');
|
|||
|
|
|
|||
|
|
// 切换到课程亮点标签页
|
|||
|
|
await page.getByRole('tab', { name: '课程亮点' }).click();
|
|||
|
|
await page.waitForTimeout(500);
|
|||
|
|
await page.locator('.tab-content textarea:visible').first().fill('1. 故事情节生动有趣\n2. 互动性强\n3. 培养分享意识');
|
|||
|
|
console.log(' - 填写课程亮点');
|
|||
|
|
|
|||
|
|
// 切换到课程目标标签页
|
|||
|
|
await page.getByRole('tab', { name: '课程总目标' }).click();
|
|||
|
|
await page.waitForTimeout(500);
|
|||
|
|
await page.locator('.tab-content textarea:visible').first().fill('1. 理解故事内容\n2. 学会分享\n3. 培养语言表达能力');
|
|||
|
|
console.log(' - 填写课程目标');
|
|||
|
|
|
|||
|
|
// 点击下一步
|
|||
|
|
await page.getByRole('button', { name: '下一步' }).click();
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
console.log('✅ 步骤 2 完成');
|
|||
|
|
|
|||
|
|
// ==================== 步骤 3: 排课参考 ====================
|
|||
|
|
console.log('开始步骤 3: 排课参考');
|
|||
|
|
|
|||
|
|
// 验证步骤标题
|
|||
|
|
await expect(page.getByText('排课参考')).toBeVisible();
|
|||
|
|
|
|||
|
|
// 填写总课时
|
|||
|
|
await page.locator('input[placeholder="请输入总课时"]').fill('8');
|
|||
|
|
console.log(' - 填写总课时');
|
|||
|
|
|
|||
|
|
// 填写课时时长 (分钟)
|
|||
|
|
await page.locator('input[placeholder="请输入课时时长"]').fill('30');
|
|||
|
|
console.log(' - 填写课时时长');
|
|||
|
|
|
|||
|
|
// 填写排课建议
|
|||
|
|
const scheduleTextarea = page.locator('textarea[placeholder*="排课建议"]').first();
|
|||
|
|
await scheduleTextarea.fill('建议每周 1-2 课时,可根据实际情况调整');
|
|||
|
|
console.log(' - 填写排课建议');
|
|||
|
|
|
|||
|
|
// 点击下一步
|
|||
|
|
await page.getByRole('button', { name: '下一步' }).click();
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
console.log('✅ 步骤 3 完成');
|
|||
|
|
|
|||
|
|
// ==================== 步骤 4: 导入课 ====================
|
|||
|
|
console.log('开始步骤 4: 导入课');
|
|||
|
|
|
|||
|
|
// 验证步骤标题
|
|||
|
|
await expect(page.getByText('导入课')).toBeVisible();
|
|||
|
|
|
|||
|
|
// 跳过导入课配置(可选步骤)
|
|||
|
|
console.log(' - 跳过导入课(可选)');
|
|||
|
|
|
|||
|
|
// 点击下一步
|
|||
|
|
await page.getByRole('button', { name: '下一步' }).click();
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
console.log('✅ 步骤 4 完成');
|
|||
|
|
|
|||
|
|
// ==================== 步骤 5: 集体课 ====================
|
|||
|
|
console.log('开始步骤 5: 集体课');
|
|||
|
|
|
|||
|
|
// 验证步骤标题
|
|||
|
|
await expect(page.getByText('集体课')).toBeVisible();
|
|||
|
|
|
|||
|
|
// 跳过集体课配置(可选步骤)
|
|||
|
|
console.log(' - 跳过集体课(可选)');
|
|||
|
|
|
|||
|
|
// 点击下一步
|
|||
|
|
await page.getByRole('button', { name: '下一步' }).click();
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
console.log('✅ 步骤 5 完成');
|
|||
|
|
|
|||
|
|
// ==================== 步骤 6: 领域课 ====================
|
|||
|
|
console.log('开始步骤 6: 领域课');
|
|||
|
|
|
|||
|
|
// 验证步骤标题
|
|||
|
|
await expect(page.getByText('领域课')).toBeVisible();
|
|||
|
|
|
|||
|
|
// 跳过领域课配置(可选步骤)
|
|||
|
|
console.log(' - 跳过领域课(可选)');
|
|||
|
|
|
|||
|
|
// 点击下一步
|
|||
|
|
await page.getByRole('button', { name: '下一步' }).click();
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
console.log('✅ 步骤 6 完成');
|
|||
|
|
|
|||
|
|
// ==================== 步骤 7: 环创建设 ====================
|
|||
|
|
console.log('开始步骤 7: 环创建设');
|
|||
|
|
|
|||
|
|
// 验证步骤标题
|
|||
|
|
await expect(page.getByText('环创建设')).toBeVisible();
|
|||
|
|
|
|||
|
|
// 填写环创建设内容
|
|||
|
|
const envTextarea = page.locator('textarea').filter({ hasText: '主题墙布置建议' }).first();
|
|||
|
|
await envTextarea.fill('主题墙布置建议:\n1. 展示折耳兔奇奇的故事图片\n2. 设置分享主题墙\n3. 展示幼儿作品');
|
|||
|
|
console.log(' - 填写环创建设内容');
|
|||
|
|
|
|||
|
|
// 点击提交
|
|||
|
|
await page.getByRole('button', { name: '提交' }).click();
|
|||
|
|
console.log('✅ 步骤 7 完成');
|
|||
|
|
|
|||
|
|
// ==================== 验证创建成功 ====================
|
|||
|
|
console.log('验证创建结果...');
|
|||
|
|
|
|||
|
|
// 等待成功提示
|
|||
|
|
await page.waitForSelector('.ant-message-success', { timeout: 5000 });
|
|||
|
|
await expect(page.getByText('创建成功')).toBeVisible({ timeout: 5000 });
|
|||
|
|
console.log('✅ 创建成功提示显示');
|
|||
|
|
|
|||
|
|
// 等待跳转到列表页
|
|||
|
|
await page.waitForURL('**/admin/courses**', { timeout: 10000 });
|
|||
|
|
console.log('✅ 页面跳转到课程列表');
|
|||
|
|
|
|||
|
|
// 验证新课程包在列表中显示
|
|||
|
|
await page.waitForTimeout(2000);
|
|||
|
|
const table = page.locator('.ant-table').first();
|
|||
|
|
await expect(table).toBeVisible();
|
|||
|
|
|
|||
|
|
// 查找新课程包
|
|||
|
|
const courseRow = table.getByText(TEST_COURSE.name);
|
|||
|
|
await expect(courseRow).toBeVisible({ timeout: 5000 });
|
|||
|
|
console.log(`✅ 新课程包 "${TEST_COURSE.name}" 在列表中显示`);
|
|||
|
|
|
|||
|
|
console.log('\n🎉 课程包创建测试全部通过!');
|
|||
|
|
});
|
|||
|
|
});
|