fix(e2e): 交替深链 /course/summary 与 /course;移除 networkidle;扩充壳层与超时
Made-with: Cursor
This commit is contained in:
@@ -38,25 +38,31 @@ function extractOrgIdFromTokenPayload(
|
||||
|
||||
/**
|
||||
* 教学资源相关任意壳层可见即可(`/course/summary` 入口链或课程体系列表)。
|
||||
* CI 上课程索引偶发长时间无搜索框;summary 页 Cell 更稳定。
|
||||
* CI 上 SPA 长连接会导致 networkidle 不可靠;此处只用 DOM 信号轮询。
|
||||
*/
|
||||
async function waitForCourseRealmVisible(page: Page) {
|
||||
const deadline = Date.now() + 95_000;
|
||||
while (Date.now() < deadline) {
|
||||
const titleHit = await page.title().catch(() => '');
|
||||
if (/教学资源库|课程体系/.test(titleHit)) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
await page.getByRole('link', { name: '课程体系' }).isVisible().catch(() => false)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
await page
|
||||
.locator('.van-cell')
|
||||
.filter({ hasText: /课程体系/ })
|
||||
.first()
|
||||
.isVisible()
|
||||
.catch(() => false)
|
||||
) {
|
||||
return;
|
||||
for (const label of ['课程体系', '课程', '课节']) {
|
||||
if (
|
||||
await page
|
||||
.locator('.van-cell')
|
||||
.filter({ hasText: new RegExp(label) })
|
||||
.first()
|
||||
.isVisible()
|
||||
.catch(() => false)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (
|
||||
await page
|
||||
@@ -73,9 +79,7 @@ async function waitForCourseRealmVisible(page: Page) {
|
||||
}
|
||||
await page.waitForTimeout(400);
|
||||
}
|
||||
throw new Error(
|
||||
`教学资源壳层未出现:${page.url()}`
|
||||
);
|
||||
throw new Error(`教学资源壳层未出现:${page.url()}`);
|
||||
}
|
||||
|
||||
async function establishSession(page: Page) {
|
||||
@@ -100,11 +104,15 @@ async function establishSession(page: Page) {
|
||||
|
||||
/**
|
||||
* 停留在 `/` 时 main.ts 不会把 JWT 中的机构写入 CurrentOrgId。
|
||||
* 深链到 `/course` 会触发守卫;多机构且无上下文时会先进入 `/org/select`,需点选机构后再继续。
|
||||
* 深链会触发守卫;多机构且无上下文时会先进入 `/org/select`,需点选机构后再继续。
|
||||
* 交替尝试 summary 与课程索引:部分账号在 CI 上只对其中之一稳定渲染壳层。
|
||||
*/
|
||||
async function resolveOrgContextForCoursePage(page: Page) {
|
||||
for (let attempt = 0; attempt < 6; attempt++) {
|
||||
await page.goto('/course/summary', {
|
||||
const deepPaths = ['/course/summary', '/course'] as const;
|
||||
|
||||
for (let attempt = 0; attempt < 8; attempt++) {
|
||||
const targetPath = deepPaths[attempt % deepPaths.length];
|
||||
await page.goto(targetPath, {
|
||||
waitUntil: 'domcontentloaded',
|
||||
timeout: 90_000,
|
||||
});
|
||||
@@ -138,13 +146,16 @@ async function resolveOrgContextForCoursePage(page: Page) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
page.url().includes('/course/summary') ||
|
||||
page.url().includes('/course')
|
||||
) {
|
||||
await page.waitForLoadState('networkidle', { timeout: 60_000 }).catch(() => {});
|
||||
await waitForCourseRealmVisible(page);
|
||||
return;
|
||||
try {
|
||||
const path = new URL(page.url()).pathname || '';
|
||||
const onCourseRealm =
|
||||
path === '/course' || path.startsWith('/course/');
|
||||
if (onCourseRealm) {
|
||||
await waitForCourseRealmVisible(page);
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
/* URL 解析失败则继续重试 */
|
||||
}
|
||||
|
||||
// 守卫可能暂时送回首页「进入工作台」等,下一循环再深链
|
||||
@@ -156,6 +167,8 @@ async function resolveOrgContextForCoursePage(page: Page) {
|
||||
}
|
||||
|
||||
test.describe('多机构数据隔离(会话与 token)', () => {
|
||||
test.describe.configure({ timeout: 180_000 });
|
||||
|
||||
test.skip(!moicenUnionid, '需要 MOICEN_E2E_UNIONID(Secret 或 .env.e2e)');
|
||||
|
||||
test('本地 CurrentOrgId 与 JWT current_org_id 一致', async ({ page }) => {
|
||||
@@ -201,7 +214,6 @@ test.describe('多机构数据隔离(会话与 token)', () => {
|
||||
});
|
||||
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
||||
await page.waitForURL(/\/org\/select/, { timeout: 60_000 });
|
||||
await page.waitForLoadState('networkidle', { timeout: 60_000 }).catch(() => {});
|
||||
await expect(page.getByText(/请选择机构|选择机构/)).toBeVisible({
|
||||
timeout: 60_000,
|
||||
});
|
||||
@@ -274,8 +286,9 @@ test.describe('多机构数据隔离(会话与 token)', () => {
|
||||
await expect(page.locator('#app')).toBeVisible({ timeout: 90_000 });
|
||||
await waitForCourseRealmVisible(page);
|
||||
|
||||
await expect(
|
||||
page.getByText('请求失败,点击重新加载')
|
||||
).not.toBeVisible({ timeout: 45_000 });
|
||||
const listError = page.getByText('请求失败,点击重新加载');
|
||||
await expect(listError).toHaveCount(0, {
|
||||
timeout: 45_000,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user