From 7da8b0561df3c2b5e9f8fcec6aa5c69bac31b156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E7=94=B7?= Date: Tue, 28 Apr 2026 08:17:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(e2e):=20=E6=9C=BA=E6=9E=84=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E9=9C=80=E6=B7=B1=E9=93=BE=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=EF=BC=9B=E6=9C=BA=E6=9E=84=E9=A1=B5=E4=B8=8E=E8=AF=BE=E7=A8=8B?= =?UTF-8?q?=E9=A1=B5=E7=AD=89=E5=BE=85=E6=9D=A1=E4=BB=B6=E6=94=BE=E5=AE=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Made-with: Cursor --- tests/org-data-isolation.spec.ts | 63 ++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/tests/org-data-isolation.spec.ts b/tests/org-data-isolation.spec.ts index 857077c..7b222c6 100644 --- a/tests/org-data-isolation.spec.ts +++ b/tests/org-data-isolation.spec.ts @@ -36,6 +36,49 @@ async function establishSession(page: Page) { ).toBeVisible({ timeout: 120_000 }); } +/** + * 停留在 `/` 时 main.ts 不会把 JWT 中的机构写入 CurrentOrgId。 + * 深链到 `/course` 会触发守卫;多机构且无上下文时会先进入 `/org/select`,需点选机构后再继续。 + */ +async function resolveOrgContextForCoursePage(page: Page) { + for (let attempt = 0; attempt < 6; attempt++) { + await page.goto('/course', { + waitUntil: 'domcontentloaded', + timeout: 90_000, + }); + await expect(page.locator('#app')).toBeVisible({ timeout: 90_000 }); + + if (!page.url().includes('/org/select')) { + return; + } + + await expect(page.getByText('请选择机构')).toBeVisible({ timeout: 60_000 }); + await Promise.race([ + page + .locator('.main .van-cell-group .van-cell') + .first() + .waitFor({ state: 'visible', timeout: 60_000 }), + page.getByText('暂无可用机构').waitFor({ state: 'visible', timeout: 60_000 }), + ]); + + const emptyOrgs = await page + .getByText('暂无可用机构') + .isVisible() + .catch(() => false); + if (emptyOrgs) { + test.skip(true, '账号无可用机构,跳过机构上下文用例'); + } + + const pickCells = page.locator('.main .van-cell-group .van-cell'); + const n = await pickCells.count(); + expect(n, '机构选择页应有可选机构').toBeGreaterThan(0); + await pickCells.first().click(); + await expect(page.locator('#app')).toBeVisible({ timeout: 90_000 }); + } + + throw new Error('resolveOrgContextForCoursePage: 无法在合理步数内离开机构选择页'); +} + test.describe('多机构数据隔离(会话与 token)', () => { test.skip(!moicenUnionid, '需要 MOICEN_E2E_UNIONID(Secret 或 .env.e2e)'); @@ -47,17 +90,19 @@ test.describe('多机构数据隔离(会话与 token)', () => { test.skip(true, '当前 unionid 会话未处于可用登录态'); } + await resolveOrgContextForCoursePage(page); + const storage = await page.evaluate(() => ({ currentOrgId: window.localStorage.getItem('CurrentOrgId'), authorization: window.localStorage.getItem('Authorization'), })); - expect(storage.currentOrgId, '登录后应写入 CurrentOrgId').toBeTruthy(); expect(storage.authorization, '登录后应有 Authorization').toBeTruthy(); const payload = decodeJwtPayload(storage.authorization!); expect(payload, 'Authorization 应为可解析的 JWT').not.toBeNull(); const jwtOrgId = payload!.current_org_id; expect(jwtOrgId, 'JWT 应包含 current_org_id').toBeTruthy(); + expect(storage.currentOrgId, '进入业务路由后应写入 CurrentOrgId').toBeTruthy(); expect(String(jwtOrgId)).toBe(storage.currentOrgId); }); @@ -71,12 +116,14 @@ test.describe('多机构数据隔离(会话与 token)', () => { test.skip(true, '当前 unionid 会话未处于可用登录态'); } + await resolveOrgContextForCoursePage(page); + await page.goto('/org/select', { waitUntil: 'domcontentloaded', timeout: 60_000, }); await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); - await expect(page.getByRole('heading', { name: '请选择机构' })).toBeVisible({ + await expect(page.getByText('请选择机构')).toBeVisible({ timeout: 60_000, }); @@ -90,7 +137,10 @@ test.describe('多机构数据隔离(会话与 token)', () => { const beforeOrg = await page.evaluate(() => window.localStorage.getItem('CurrentOrgId') ); - expect(beforeOrg).toBeTruthy(); + expect( + beforeOrg, + '切换前应已有当前机构(resolveOrgContextForCoursePage 已落库)' + ).toBeTruthy(); await orgCells.nth(1).click(); await page.waitForURL( @@ -129,11 +179,8 @@ test.describe('多机构数据隔离(会话与 token)', () => { test.skip(true, '当前 unionid 会话未处于可用登录态'); } - await page.goto('/course', { - waitUntil: 'domcontentloaded', - timeout: 90_000, - }); - await expect(page.locator('#app')).toBeVisible({ timeout: 90_000 }); + await resolveOrgContextForCoursePage(page); + await expect( page.getByPlaceholder('请输入课程体系名称搜索') ).toBeVisible({ timeout: 90_000 });