2026-05-01 19:46:11 +08:00
|
|
|
import { expect, test } from './fixtures';
|
|
|
|
|
|
2026-05-02 18:30:05 +08:00
|
|
|
const moicenUnionid = (process.env.MOICEN_E2E_UNIONID || 'o66lo5iK98xBI9pX-0RBqveqDryI').trim();
|
|
|
|
|
const ROLE_TEACHER = 2;
|
|
|
|
|
|
2026-05-01 19:46:11 +08:00
|
|
|
test.describe('排课页面 UI', () => {
|
|
|
|
|
test('排课日历页应正常加载(无JS崩溃)', async ({ page }) => {
|
|
|
|
|
await page.goto('/clazz', { waitUntil: 'domcontentloaded', timeout: 60_000 });
|
|
|
|
|
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
2026-05-01 19:53:02 +08:00
|
|
|
// 未登录时可能被路由守卫重定向到首页,但不应该崩溃
|
|
|
|
|
const errors: string[] = [];
|
|
|
|
|
page.on('pageerror', (err) => errors.push(err.message));
|
|
|
|
|
await page.waitForTimeout(3000);
|
|
|
|
|
expect(errors.filter(e => !e.includes('ResizeObserver') && !e.includes('not implemented'))).toEqual([]);
|
2026-05-01 19:46:11 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('排课日历无报错', async ({ page }) => {
|
|
|
|
|
const errors: string[] = [];
|
|
|
|
|
page.on('pageerror', (err) => errors.push(err.message));
|
|
|
|
|
|
|
|
|
|
await page.goto('/clazz', { waitUntil: 'domcontentloaded', timeout: 60_000 });
|
|
|
|
|
await page.waitForTimeout(3000);
|
|
|
|
|
|
|
|
|
|
// 不应有 JS 运行时错误
|
|
|
|
|
expect(errors.filter(e => !e.includes('ResizeObserver') && !e.includes('not implemented'))).toEqual([]);
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-02 18:30:05 +08:00
|
|
|
test('排课日历 FullCalendar 应初始化(需已登录)', async ({ page }) => {
|
|
|
|
|
test.setTimeout(120_000);
|
|
|
|
|
|
|
|
|
|
// 登录
|
|
|
|
|
const q = new URLSearchParams({ unionid: moicenUnionid, status: '2' });
|
2026-05-03 19:14:36 +08:00
|
|
|
await page.goto(`/?${q.toString()}`, { waitUntil: 'domcontentloaded', timeout: 120_000 });
|
2026-05-02 18:30:05 +08:00
|
|
|
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
|
|
|
|
|
2026-05-03 03:39:50 +08:00
|
|
|
// 等待身份选择弹窗(最多 15 秒)
|
2026-05-02 18:30:05 +08:00
|
|
|
const rs = page.getByText('请选择您的登录身份');
|
2026-05-03 03:39:50 +08:00
|
|
|
try {
|
|
|
|
|
await rs.waitFor({ state: 'visible', timeout: 15_000 });
|
2026-05-02 18:30:05 +08:00
|
|
|
const items = page.locator('.van-grid-item');
|
|
|
|
|
const count = await items.count();
|
|
|
|
|
// items[0]=测试员, items[1]=学生, items[2]=教师
|
|
|
|
|
if (count >= 3) {
|
|
|
|
|
await items.nth(ROLE_TEACHER).click();
|
|
|
|
|
} else {
|
|
|
|
|
await items.first().click();
|
|
|
|
|
}
|
|
|
|
|
await page.waitForTimeout(3000);
|
2026-05-03 03:39:50 +08:00
|
|
|
} catch {
|
|
|
|
|
// 无弹窗 — 已有身份
|
2026-05-02 18:30:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 导航到排课页面
|
2026-05-01 19:46:11 +08:00
|
|
|
await page.goto('/clazz', { waitUntil: 'domcontentloaded', timeout: 60_000 });
|
2026-05-02 18:30:05 +08:00
|
|
|
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
|
|
|
|
await page.waitForTimeout(5000);
|
|
|
|
|
|
|
|
|
|
// FullCalendar 应渲染
|
2026-05-01 19:53:02 +08:00
|
|
|
await expect(page.locator('.fc')).toBeVisible({ timeout: 30_000 });
|
2026-05-01 19:46:11 +08:00
|
|
|
await expect(page.locator('.fc-timegrid')).toBeVisible({ timeout: 30_000 });
|
2026-05-03 19:14:36 +08:00
|
|
|
await expect(page.locator('.view-toolbar')).toBeVisible({ timeout: 15_000 });
|
2026-05-01 19:46:11 +08:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test.describe('审计日志 API', () => {
|
2026-05-01 19:53:02 +08:00
|
|
|
test('审计日志列表API不返回500', async ({ request }) => {
|
2026-05-01 19:46:11 +08:00
|
|
|
const resp = await request.get('/api/v1/clazz/audit-log/list?clazz_id=nonexistent');
|
|
|
|
|
// 未带有效 auth 应返回 401 或 400, 但不应 500
|
2026-05-01 19:53:02 +08:00
|
|
|
expect(resp.status()).not.toBe(500);
|
2026-05-01 19:46:11 +08:00
|
|
|
expect([400, 401, 403]).toContain(resp.status());
|
|
|
|
|
});
|
|
|
|
|
});
|