/** * 调试课程创建 - 捕获页面错误和 handleSave 调用 */ import { test, expect } from '@playwright/test'; import { loginAsAdmin } from './helpers'; test.describe('课程创建调试 - 错误捕获', () => { test('调试 handleSave 调用和页面错误', async ({ page }) => { test.setTimeout(180000); const courseName = '调试测试课程包-' + Date.now(); console.log('=== 测试开始 ==='); console.log('测试课程名称:', courseName); // 捕获页面错误 page.on('pageerror', error => { console.log(`[Page Error] ${error.message}`); console.log(`[Page Error Stack] ${error.stack}`); }); // 捕获所有控制台日志 page.on('console', msg => { const text = msg.text(); // 过滤掉无关的日志 if (text.includes('[vite]') || text.includes('GET') || text.includes('POST')) { return; } console.log(`[Console ${msg.type()}] ${text}`); }); // 捕获所有网络请求 page.on('request', request => { const url = request.url(); const method = request.method(); if (url.includes('/api/') && !url.includes('/courses?page')) { console.log(`[Network] ${method} ${url}`); } }); page.on('response', response => { const url = response.url(); const status = response.status(); if (url.includes('/api/') && !url.includes('/courses?page')) { console.log(`[Network] <- ${status} ${url}`); if (status >= 400) { response.text().then(text => { console.log(`[Error Response] ${text}`); }).catch(() => {}); } } }); // 步骤 1: 登录 console.log('=== 步骤 1: 登录 ==='); await loginAsAdmin(page); await page.waitForTimeout(1000); // 步骤 2: 进入课程创建页面 console.log('=== 步骤 2: 进入课程创建页面 ==='); await page.goto('/admin/courses', { timeout: 30000, waitUntil: 'networkidle' }); await page.waitForTimeout(2000); await page.getByRole('button', { name: '新建课程包' }).click(); await page.waitForTimeout(2000); // 验证进入创建页面 const pageTitle = await page.getByText('创建课程包').isVisible(); console.log('进入创建页面:', pageTitle); // 步骤 3: 填写基本信息 console.log('=== 步骤 3: 填写基本信息 ==='); await page.getByPlaceholder('请输入课程包名称').fill(courseName); // 选择关联主题 await page.locator('.ant-select-selector').first().click(); await page.waitForTimeout(500); await page.getByText('社会认知', { exact: true }).first().click(); await page.waitForTimeout(300); // 选择适用年级 await page.getByRole('checkbox', { name: '小班' }).check(); await page.waitForTimeout(300); // 填写核心内容 await page.getByPlaceholder('请输入课程包核心内容').fill('调试测试课程内容'); console.log('基本信息已填写完成'); // 步骤 4: 快速点击下一步到最后 console.log('=== 步骤 4: 点击下一步 ==='); for (let i = 0; i < 6; i++) { const nextButton = page.getByRole('button', { name: '下一步' }); if (await nextButton.isVisible().catch(() => false)) { console.log(`点击第 ${i + 1} 次"下一步"`); await nextButton.click(); await page.waitForTimeout(800); } } await page.waitForTimeout(1000); // 步骤 5: 点击创建按钮 console.log('=== 步骤 5: 点击创建 ==='); const submitButton = page.getByRole('button', { name: '创建' }); console.log('创建按钮可见:', await submitButton.isVisible()); // 在点击前注入监控代码 await page.evaluate(() => { console.log('=== 开始监控 handleSave 调用 ==='); // 这里只是日志,实际监控在浏览器控制台 }); console.log('准备点击创建按钮...'); await submitButton.click(); console.log('已点击创建按钮'); // 等待更长时间观察 await page.waitForTimeout(5000); // 步骤 6: 检查状态 console.log('=== 步骤 6: 检查结果 ==='); // 检查是否有成功/错误消息 const successMsg = await page.locator('.ant-message-success').count(); const errorMsg = await page.locator('.ant-message-error').count(); console.log('成功消息数量:', successMsg); console.log('错误消息数量:', errorMsg); // 检查 saving 状态 const isSaving = await page.locator('.ant-btn-loading').isVisible().catch(() => false); console.log('按钮是否在 loading 状态:', isSaving); // 检查当前 URL const currentUrl = page.url(); console.log('当前 URL:', currentUrl); // 检查表格中的课程数量 const table = page.locator('.ant-table').first(); const rows = await table.locator('tbody tr').count(); console.log('表格中的课程数量:', rows); // 截图 await page.screenshot({ path: 'test-results/debug-save-error.png' }); console.log('截图已保存'); // 如果没有任何消息,尝试检查控制台是否有 handleSave 相关日志 if (successMsg === 0 && errorMsg === 0) { console.log('=== 没有检测到任何消息,可能 handleSave 未被调用 ==='); console.log('可能原因:'); console.log('1. 按钮点击事件未绑定'); console.log('2. handleSave 函数内部有静默失败'); console.log('3. 表单验证未通过但未显示错误'); } }); });