diff --git a/tests/clazz-ui.spec.ts b/tests/clazz-ui.spec.ts index 0b07bb6..355eeab 100644 --- a/tests/clazz-ui.spec.ts +++ b/tests/clazz-ui.spec.ts @@ -1,5 +1,8 @@ import { expect, test } from './fixtures'; +const moicenUnionid = (process.env.MOICEN_E2E_UNIONID || 'o66lo5iK98xBI9pX-0RBqveqDryI').trim(); +const ROLE_TEACHER = 2; + test.describe('排课页面 UI', () => { test('排课日历页应正常加载(无JS崩溃)', async ({ page }) => { await page.goto('/clazz', { waitUntil: 'domcontentloaded', timeout: 60_000 }); @@ -22,9 +25,35 @@ test.describe('排课页面 UI', () => { expect(errors.filter(e => !e.includes('ResizeObserver') && !e.includes('not implemented'))).toEqual([]); }); - test.fixme('排课日历 FullCalendar 应初始化(需已登录)', async ({ page }) => { - // FullCalendar 在已登录状态下应渲染 + test('排课日历 FullCalendar 应初始化(需已登录)', async ({ page }) => { + test.setTimeout(120_000); + + // 登录 + const q = new URLSearchParams({ unionid: moicenUnionid, status: '2' }); + await page.goto(`/?${q.toString()}`, { waitUntil: 'domcontentloaded', timeout: 60_000 }); + await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); + await page.waitForTimeout(3000); + + // 选择身份(如果弹出) + const rs = page.getByText('请选择您的登录身份'); + if (await rs.isVisible().catch(() => false)) { + 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); + } + + // 导航到排课页面 await page.goto('/clazz', { waitUntil: 'domcontentloaded', timeout: 60_000 }); + await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); + await page.waitForTimeout(5000); + + // FullCalendar 应渲染 await expect(page.locator('.fc')).toBeVisible({ timeout: 30_000 }); await expect(page.locator('.fc-timegrid')).toBeVisible({ timeout: 30_000 }); await expect(page.locator('.fc-toolbar')).toBeVisible({ timeout: 15_000 }); diff --git a/tests/department-single-transparent.spec.ts b/tests/department-single-transparent.spec.ts index 4971b12..8ea20cd 100644 --- a/tests/department-single-transparent.spec.ts +++ b/tests/department-single-transparent.spec.ts @@ -26,6 +26,21 @@ test.describe('单部门透明', () => { await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); + // 等待登录完成(Authorization + HtySudoerToken 写入 localStorage) + // 避免在第一个页面的路由守卫未跑完时直接 full navigation 导致 token 丢失 + await expect(async () => { + const auth = await page.evaluate(() => + window.localStorage.getItem('Authorization') + ); + expect(auth).toBeTruthy(); + }).toPass({ timeout: 30_000 }); + await expect(async () => { + const sudo = await page.evaluate(() => + window.localStorage.getItem('HtySudoerToken') + ); + expect(sudo).toBeTruthy(); + }).toPass({ timeout: 15_000 }); + // 身份选择 if ( await page @@ -34,9 +49,18 @@ test.describe('单部门透明', () => { .catch(() => false) ) { await page.locator('.van-grid-item').first().click(); + await page.waitForTimeout(2_000); } - // 等待路由稳定、机构上下文写入 + // 导航到排课页触发路由守卫中的 org 加载 + 部门自动选中 + await page.goto('/clazz', { + waitUntil: 'domcontentloaded', + timeout: 60_000, + }); + + await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); + + // 等待异步的部门加载完成 await page.waitForTimeout(3_000); // 验证 localStorage 写入了 CurrentDepartmentId @@ -60,8 +84,12 @@ test.describe('单部门透明', () => { expect(parts.length).toBe(3); const payloadRaw = parts[1].replace(/-/g, '+').replace(/_/g, '/'); const payload = JSON.parse(atob(payloadRaw)); - expect(payload.current_department_id).toBeTruthy(); - expect(typeof payload.current_department_id).toBe('string'); + let subjectPayload: Record = {}; + if (typeof payload.sub === 'string') { + subjectPayload = JSON.parse(payload.sub); + } + expect(subjectPayload.current_department_id).toBeTruthy(); + expect(typeof subjectPayload.current_department_id).toBe('string'); } }); @@ -86,9 +114,7 @@ test.describe('单部门透明', () => { await page.locator('.van-grid-item').first().click(); } - await page.waitForTimeout(3_000); - - // 导航到排课页,页面应正常渲染 + // 导航到排课页触发 org 加载 + 部门自动选中,验证页面正常渲染 await page.goto('/clazz', { waitUntil: 'domcontentloaded', timeout: 60_000,