Files
huike-e2e-moicen/tests/supervisor-features.spec.ts
T
weli e730e44391
music-room Playwright / playwright (push) Failing after 18m2s
test: 增加主管老师功能测试(首页/打卡/vConsole)
- SUPERVISOR 角色登录应到 /teacher/home
- 打卡页面加载无服务器错误
- vConsole 在有 SYS_CAN_SUDO tag 时可见

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-03 09:50:55 +08:00

112 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { expect, test } from './fixtures';
const moicenUnionid = process.env.MOICEN_E2E_UNIONID?.trim();
/**
* 登录并选择指定角色(支持多角色用户场景)
*/
async function loginAndSelectRole(page: any, roleText: string) {
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 });
// 等待 auth tokens
await expect(async () => {
const auth = await page.evaluate(() =>
window.localStorage.getItem('Authorization')
);
expect(auth).toBeTruthy();
}).toPass({ timeout: 30_000 });
// 逐层处理选择页:机构选择 → 身份选择(可能有 0~n 层)
let roleSelected = false;
for (let i = 0; i < 5 && !roleSelected; i++) {
const path = await page.evaluate(() => window.location.pathname);
if (path === '/org/select') {
await page.locator('.van-cell').first().click();
await page.waitForTimeout(3_000);
} else if (path === '/') {
const rs = page.getByText('请选择您的登录身份');
try {
await rs.waitFor({ state: 'visible', timeout: 10_000 });
await page.locator('.van-grid-item').filter({ hasText: roleText }).click();
await page.waitForTimeout(3_000);
roleSelected = true;
} catch {
// 无角色选择器 → 角色已自动选中
break;
}
} else {
// 已在目标页面
break;
}
}
}
test.describe('主管老师 功能验证', () => {
test.skip(!moicenUnionid, '需要 MOICEN_E2E_UNIONIDSecret 或 .env.e2e');
test('SUPERVISOR 登录后首页为本机构工作台 /teacher/home', async ({ page }) => {
await loginAndSelectRole(page, '主管教师');
// 主管教师与教师共享首页,不跳到"我的下属老师"
const path = await page.evaluate(() => window.location.pathname);
expect(path).toBe('/teacher/home');
// 页面应正常渲染(无 JS 崩溃)
await expect(page.locator('#app')).toBeVisible({ timeout: 15_000 });
});
test('打卡页面加载无服务器错误', async ({ page }) => {
// 收集请求失败
const failedRequests: string[] = [];
page.on('requestfailed', (req) => {
failedRequests.push(`${req.method()} ${req.url()} ${req.failure()?.errorText ?? ''}`);
});
await loginAndSelectRole(page, '主管教师');
// 导航到打卡页
await page.goto('/daka', { waitUntil: 'networkidle', timeout: 60_000 });
await expect(page.locator('#app')).toBeVisible({ timeout: 15_000 });
// 不应有服务器内部错误
const serverErrors = failedRequests.filter(
r => r.includes('500') || r.includes('Internal Server Error')
);
expect(serverErrors).toEqual([]);
// 打卡页应显示日期选择器
await expect(page.getByText('打卡起始')).toBeVisible({ timeout: 15_000 });
});
test('vConsole 可见性取决于 SYS_CAN_SUDO tag', async ({ page }) => {
await loginAndSelectRole(page, '主管教师');
// 等待 tags 异步加载 + vConsole 渲染
await page.waitForTimeout(5_000);
const state = await page.evaluate(() => {
const el = document.getElementById('__vconsole');
return { exists: !!el, hidden: el?.hidden ?? null };
});
// 检测用户是否有 SYS_CAN_SUDO tag
const hasSudoTag = await page.evaluate(() => {
return !!window.localStorage.getItem('HtySudoerToken');
});
console.log('[vConsole] state:', JSON.stringify(state), 'hasSudoTag:', hasSudoTag);
if (hasSudoTag) {
expect(state.exists).toBeTruthy();
expect(state.hidden).toBeFalsy();
}
// 无 tag 时仅验证页面正常,不做 vConsole 断言
});
});