- 修改后端目录从 reading-platform-backend 改为 reading-platform-java - 修改后端端口从 3000 改为 8080 - 修改启动命令从 npm run start:dev 改为 mvn spring-boot:run - 添加 JAVA_HOME 自动检测和设置(默认使用 /f/Java/jdk-17) - 修改日志文件从 reading-platform-backend.log 改为 reading-platform-java.log - 修改健康检查接口为 /actuator/health - 增加启动等待超时时间到 60 秒(Java 启动较慢) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
120 lines
3.4 KiB
TypeScript
120 lines
3.4 KiB
TypeScript
/**
|
||
* 超管端 E2E 测试 - 通用工具函数
|
||
*/
|
||
|
||
import { Page, expect } from '@playwright/test';
|
||
import { ADMIN_CONFIG } from './fixtures';
|
||
|
||
/**
|
||
* 使用超管账号登录
|
||
*/
|
||
export async function loginAsAdmin(page: Page) {
|
||
await page.goto('/login', { timeout: 30000, waitUntil: 'commit' });
|
||
await page.waitForTimeout(500);
|
||
|
||
// 点击超管角色按钮 - 查找包含"超管"文本的元素
|
||
await page.getByText('超管').first().click();
|
||
await page.waitForTimeout(300);
|
||
|
||
// 输入账号密码
|
||
await page.getByPlaceholder('请输入账号').fill(ADMIN_CONFIG.account);
|
||
await page.getByPlaceholder('请输入密码').fill(ADMIN_CONFIG.password);
|
||
|
||
// 点击登录按钮
|
||
await page.locator('button:has-text("登 录")').first().click();
|
||
|
||
// 等待登录 API 请求完成
|
||
await page.waitForResponse(
|
||
response => response.url().includes('/api/v1/auth/login') && response.status() === 200,
|
||
{ timeout: 15000 }
|
||
).catch(() => {
|
||
console.log('登录请求等待超时');
|
||
});
|
||
|
||
// 等待登录成功后的重定向
|
||
await page.waitForLoadState('networkidle', { timeout: 20000 }).catch(() => {});
|
||
|
||
// 验证是否已跳转到管理页面
|
||
await page.waitForURL('**/admin/**', { timeout: 10000 }).catch(() => {
|
||
console.log('URL 等待超时,但继续执行');
|
||
});
|
||
|
||
// 验证是否看到管理页面的特征元素
|
||
await page.locator('.ant-layout:has-text("课程管理")').first().waitFor({ state: 'visible', timeout: 10000 }).catch(() => {
|
||
console.log('管理页面容器未找到,但继续执行');
|
||
});
|
||
|
||
await page.waitForTimeout(1000);
|
||
}
|
||
|
||
/**
|
||
* 退出登录
|
||
*/
|
||
export async function logout(page: Page) {
|
||
// 点击右上角用户菜单
|
||
await page.getByRole('button', { name: /退出登录|退出|logout/i }).click();
|
||
await page.waitForURL('**/login*');
|
||
}
|
||
|
||
/**
|
||
* 等待表格加载完成
|
||
*/
|
||
export async function waitForTable(page: Page, timeout = 30000) {
|
||
// 使用 first() 避免严格模式 violation
|
||
const table = page.locator('.ant-table').first();
|
||
// 等待表格附加到 DOM(允许空表状态)
|
||
await table.waitFor({ state: 'attached', timeout }).catch(() => {
|
||
console.log('表格等待超时,继续执行');
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 等待弹窗显示
|
||
*/
|
||
export async function waitForModal(page: Page, title?: string, timeout = 5000) {
|
||
if (title) {
|
||
await page.getByText(title).waitFor({ timeout });
|
||
} else {
|
||
await page.waitForSelector('.ant-modal', { timeout });
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 等待成功提示
|
||
*/
|
||
export async function waitForSuccess(page: Page, message?: string, timeout = 5000) {
|
||
if (message) {
|
||
await page.getByText(message).waitFor({ timeout });
|
||
} else {
|
||
await page.waitForSelector('.ant-message-success', { timeout });
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 等待错误提示
|
||
*/
|
||
export async function waitForError(page: Page, message?: string, timeout = 5000) {
|
||
if (message) {
|
||
await page.getByText(message).waitFor({ timeout });
|
||
} else {
|
||
await page.waitForSelector('.ant-message-error', { timeout });
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 在表格中查找并点击操作按钮
|
||
*/
|
||
export async function clickRowAction(page: Page, rowName: string, action: string) {
|
||
const row = page.getByRole('row').filter({ hasText: rowName });
|
||
await row.getByRole('button', { name: action }).click();
|
||
}
|
||
|
||
/**
|
||
* 关闭弹窗
|
||
*/
|
||
export async function closeModal(page: Page) {
|
||
await page.keyboard.press('Escape');
|
||
// 或者点击关闭按钮
|
||
await page.locator('.ant-modal-close').click();
|
||
}
|