/** * 课程包创建 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🎉 课程包创建测试全部通过!'); }); });