184 lines
6.7 KiB
TypeScript
184 lines
6.7 KiB
TypeScript
|
|
/**
|
|||
|
|
* 超管端 E2E 测试 - 完整流程集成测试
|
|||
|
|
*
|
|||
|
|
* 本测试用例从登录开始,依次测试所有主要功能模块,
|
|||
|
|
* 模拟真实用户的使用流程。
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import { test, expect } from '@playwright/test';
|
|||
|
|
import { loginAsAdmin, waitForTable } from './helpers';
|
|||
|
|
import { TEST_DATA, ADMIN_CONFIG } from './fixtures';
|
|||
|
|
|
|||
|
|
test.describe('超管端完整流程集成测试', () => {
|
|||
|
|
test('超管端全功能流程测试', async ({ page }) => {
|
|||
|
|
// ==================== 1. 登录 ====================
|
|||
|
|
console.log('步骤 1: 登录系统');
|
|||
|
|
await loginAsAdmin(page);
|
|||
|
|
console.log('✓ 登录成功');
|
|||
|
|
|
|||
|
|
// ==================== 2. 数据看板 ====================
|
|||
|
|
console.log('步骤 2: 验证数据看板');
|
|||
|
|
await expect(page).toHaveURL(new RegExp(`${ADMIN_CONFIG.dashboardPath}`));
|
|||
|
|
|
|||
|
|
// 验证统计卡片
|
|||
|
|
await page.waitForSelector('.ant-statistic, [class*="statistic"]', { timeout: 10000 });
|
|||
|
|
const tenantCard = page.getByText(/租户数 | 租户总数 | 机构数/).first();
|
|||
|
|
await expect(tenantCard).toBeVisible();
|
|||
|
|
console.log('✓ 数据看板验证通过');
|
|||
|
|
|
|||
|
|
// ==================== 3. 租户管理 ====================
|
|||
|
|
console.log('步骤 3: 测试租户管理');
|
|||
|
|
await page.goto('/admin/tenants');
|
|||
|
|
await waitForTable(page);
|
|||
|
|
|
|||
|
|
// 验证租户列表加载
|
|||
|
|
const table = page.locator('table, .ant-table');
|
|||
|
|
await expect(table).toBeVisible();
|
|||
|
|
console.log('✓ 租户列表加载成功');
|
|||
|
|
|
|||
|
|
// 点击添加租户
|
|||
|
|
const addTenantButton = page.getByText(/添加租户 | 新建租户/);
|
|||
|
|
if (await addTenantButton.isVisible()) {
|
|||
|
|
await addTenantButton.click();
|
|||
|
|
await page.waitForTimeout(500);
|
|||
|
|
|
|||
|
|
// 填写租户信息
|
|||
|
|
const nameInput = page.locator('input[placeholder*="学校名称"]');
|
|||
|
|
if (await nameInput.isVisible()) {
|
|||
|
|
await nameInput.fill(TEST_DATA.tenant.name);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const accountInput = page.locator('input[placeholder*="登录账号"]');
|
|||
|
|
if (await accountInput.isVisible()) {
|
|||
|
|
await accountInput.fill(TEST_DATA.tenant.account);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 关闭弹窗,不实际创建
|
|||
|
|
const cancelButton = page.locator('.ant-modal button:has-text("取消")');
|
|||
|
|
if (await cancelButton.isVisible()) {
|
|||
|
|
await cancelButton.click();
|
|||
|
|
}
|
|||
|
|
console.log('✓ 租户创建流程测试完成');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ==================== 4. 课程包管理 ====================
|
|||
|
|
console.log('步骤 4: 测试课程包管理');
|
|||
|
|
await page.goto('/admin/courses');
|
|||
|
|
await waitForTable(page);
|
|||
|
|
|
|||
|
|
// 验证课程包列表加载
|
|||
|
|
const courseTable = page.locator('table, .ant-table');
|
|||
|
|
await expect(courseTable).toBeVisible();
|
|||
|
|
console.log('✓ 课程包列表加载成功');
|
|||
|
|
|
|||
|
|
// 点击创建课程包
|
|||
|
|
const createCourseButton = page.getByText(/新建课程包 | 创建课程包/);
|
|||
|
|
if (await createCourseButton.isVisible()) {
|
|||
|
|
await createCourseButton.click();
|
|||
|
|
await page.waitForURL(/\/admin\/courses\/create/);
|
|||
|
|
|
|||
|
|
// 验证步骤导航存在
|
|||
|
|
await expect(page.locator('.ant-steps')).toBeVisible();
|
|||
|
|
|
|||
|
|
// 填写基本信息
|
|||
|
|
const nameInput = page.locator('input[placeholder*="课程包名称"]');
|
|||
|
|
if (await nameInput.isVisible()) {
|
|||
|
|
await nameInput.fill(TEST_DATA.course.name);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 返回课程包列表
|
|||
|
|
await page.goto('/admin/courses');
|
|||
|
|
console.log('✓ 课程包创建流程测试完成');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ==================== 5. 套餐管理 ====================
|
|||
|
|
console.log('步骤 5: 测试套餐管理');
|
|||
|
|
await page.goto('/admin/packages');
|
|||
|
|
await waitForTable(page);
|
|||
|
|
|
|||
|
|
// 验证套餐列表加载
|
|||
|
|
const packageTable = page.locator('table, .ant-table');
|
|||
|
|
await expect(packageTable).toBeVisible();
|
|||
|
|
console.log('✓ 套餐列表加载成功');
|
|||
|
|
|
|||
|
|
// ==================== 6. 主题字典 ====================
|
|||
|
|
console.log('步骤 6: 测试主题管理');
|
|||
|
|
await page.goto('/admin/themes');
|
|||
|
|
await waitForTable(page);
|
|||
|
|
|
|||
|
|
// 验证主题列表加载
|
|||
|
|
const themeTable = page.locator('table, .ant-table');
|
|||
|
|
await expect(themeTable).toBeVisible();
|
|||
|
|
console.log('✓ 主题列表加载成功');
|
|||
|
|
|
|||
|
|
// ==================== 7. 资源库 ====================
|
|||
|
|
console.log('步骤 7: 测试资源库管理');
|
|||
|
|
await page.goto('/admin/resources');
|
|||
|
|
await waitForTable(page);
|
|||
|
|
|
|||
|
|
// 验证资源列表加载
|
|||
|
|
const resourceTable = page.locator('table, .ant-table');
|
|||
|
|
await expect(resourceTable).toBeVisible();
|
|||
|
|
console.log('✓ 资源列表加载成功');
|
|||
|
|
|
|||
|
|
// ==================== 8. 系统设置 ====================
|
|||
|
|
console.log('步骤 8: 测试系统设置');
|
|||
|
|
await page.goto('/admin/settings');
|
|||
|
|
await page.waitForTimeout(500);
|
|||
|
|
|
|||
|
|
// 验证基本设置标签页
|
|||
|
|
const basicTab = page.locator('.ant-tabs-tab:has-text("基本设置")');
|
|||
|
|
await expect(basicTab).toBeVisible();
|
|||
|
|
|
|||
|
|
// 切换到安全设置标签页
|
|||
|
|
const securityTab = page.locator('.ant-tabs-tab:has-text("安全设置")');
|
|||
|
|
await securityTab.click();
|
|||
|
|
await page.waitForTimeout(200);
|
|||
|
|
await expect(page.getByText('密码强度')).toBeVisible();
|
|||
|
|
|
|||
|
|
// 切换到通知设置标签页
|
|||
|
|
const notificationTab = page.locator('.ant-tabs-tab:has-text("通知设置")');
|
|||
|
|
await notificationTab.click();
|
|||
|
|
await page.waitForTimeout(200);
|
|||
|
|
await expect(page.getByText('邮件通知')).toBeVisible();
|
|||
|
|
|
|||
|
|
// 切换到存储设置标签页
|
|||
|
|
const storageTab = page.locator('.ant-tabs-tab:has-text("存储设置")');
|
|||
|
|
await storageTab.click();
|
|||
|
|
await page.waitForTimeout(200);
|
|||
|
|
await expect(page.getByText('存储类型')).toBeVisible();
|
|||
|
|
|
|||
|
|
console.log('✓ 系统设置验证通过');
|
|||
|
|
|
|||
|
|
// ==================== 9. 退出登录 ====================
|
|||
|
|
console.log('步骤 9: 退出登录');
|
|||
|
|
const logoutButton = page.getByRole('button', { name: /退出登录 | 退出 | logout/i });
|
|||
|
|
if (await logoutButton.isVisible()) {
|
|||
|
|
await logoutButton.click();
|
|||
|
|
} else {
|
|||
|
|
const userMenu = page.locator('.ant-dropdown-trigger').or(page.locator('[class*="user"]'));
|
|||
|
|
if (await userMenu.isVisible()) {
|
|||
|
|
await userMenu.click();
|
|||
|
|
await page.waitForTimeout(200);
|
|||
|
|
const dropdownLogout = page.getByText(/退出登录 | 退出/);
|
|||
|
|
if (await dropdownLogout.isVisible()) {
|
|||
|
|
await dropdownLogout.click();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 等待跳转到登录页
|
|||
|
|
await page.waitForURL('**/login*');
|
|||
|
|
await expect(page).toHaveURL(/\/login/);
|
|||
|
|
|
|||
|
|
// 验证 token 已清除
|
|||
|
|
const tokenAfterLogout = await page.evaluate(() => localStorage.getItem('token'));
|
|||
|
|
expect(tokenAfterLogout).toBeFalsy();
|
|||
|
|
|
|||
|
|
console.log('✓ 退出登录成功');
|
|||
|
|
console.log('======================');
|
|||
|
|
console.log('✓ 完整流程测试通过!');
|
|||
|
|
console.log('======================');
|
|||
|
|
});
|
|||
|
|
});
|