diff --git a/tests/teacher-switching.spec.ts b/tests/teacher-switching.spec.ts index 986df03..10f345e 100644 --- a/tests/teacher-switching.spec.ts +++ b/tests/teacher-switching.spec.ts @@ -2,40 +2,85 @@ import { expect, test } from './fixtures'; const moicenUnionid = process.env.MOICEN_E2E_UNIONID?.trim(); -async function handleOrgSelect(page: any): Promise { - // Returns true if org was selected, false if skipped - if (!page.url().includes('/org/select')) return true; - - await page.waitForTimeout(2000); - - if ( - await page - .getByText('暂无可用机构') - .isVisible() - .catch(() => false) - ) { - test.skip(true, '账号无可用机构,跳过'); - return false; - } - - if ( - await page - .getByText('请返回微信小程序完成登录') - .isVisible() - .catch(() => false) - ) { - test.skip(true, '当前 unionid 会话未处于可用登录态,跳过'); - return false; - } - - const orgCells = page.locator('#app .van-cell-group .van-cell'); - const n = await orgCells.count(); - expect(n, '机构选择页应有可选机构').toBeGreaterThan(0); - await orgCells.first().click(); - - // Org switch triggers window.location.assign('/'), wait for the new page - await page.waitForLoadState('domcontentloaded', { timeout: 90_000 }); +async function loginAsStudent(page: any) { + 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 }); + + // Select STUDENT role explicitly (user has multiple roles) + if ( + await page + .getByText('请选择您的登录身份') + .isVisible() + .catch(() => false) + ) { + // Find the "学生" grid item and click it + const studentRole = page.locator('.van-grid-item').filter({ hasText: '学生' }); + if (await studentRole.isVisible().catch(() => false)) { + await studentRole.click(); + await page.waitForTimeout(2000); + } else { + // Fallback: click first + await page.locator('.van-grid-item').first().click(); + await page.waitForTimeout(2000); + } + } +} + +async function ensureOrgContext(page: any): Promise { + // Navigate to a page that triggers org resolution + await page.goto('/student/profile', { + waitUntil: 'domcontentloaded', + timeout: 60_000, + }); + await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); + + // If redirected to org select, pick first org + if (page.url().includes('/org/select')) { + await page.waitForTimeout(2000); + + if ( + await page + .getByText('暂无可用机构') + .isVisible() + .catch(() => false) + ) { + test.skip(true, '账号无可用机构,跳过'); + return false; + } + + if ( + await page + .getByText('请返回微信小程序完成登录') + .isVisible() + .catch(() => false) + ) { + test.skip(true, '当前 unionid 会话未处于可用登录态,跳过'); + return false; + } + + const orgCells = page.locator('#app .van-cell-group .van-cell'); + const n = await orgCells.count(); + expect(n, '机构选择页应有可选机构').toBeGreaterThan(0); + await orgCells.first().click(); + + // Org switch triggers full page reload, wait for it + await page.waitForLoadState('domcontentloaded', { timeout: 90_000 }); + await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); + + // Navigate back to student profile + await page.goto('/student/profile', { + waitUntil: 'domcontentloaded', + timeout: 60_000, + }); + await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); + } return true; } @@ -45,56 +90,19 @@ test.describe('学生老师切换', () => { test('profile 页显示当前老师且可切换', async ({ page }) => { test.setTimeout(180_000); - // 1. Login - 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 loginAsStudent(page); + const ok = await ensureOrgContext(page); + if (!ok) return; - // Handle role selection if needed - if ( - await page - .getByText('请选择您的登录身份') - .isVisible() - .catch(() => false) - ) { - await page.locator('.van-grid-item').first().click(); - await page.waitForTimeout(1000); - } - - // 2. Navigate to student profile (triggers org resolution if needed) - await page.goto('/student/profile', { - waitUntil: 'domcontentloaded', - timeout: 60_000, - }); - await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); - - // Handle org selection if needed - const orgOk = await handleOrgSelect(page); - if (!orgOk) return; - - // After org switch, navigate to profile again - if (!page.url().includes('/student/profile')) { - await page.goto('/student/profile', { - waitUntil: 'domcontentloaded', - timeout: 60_000, - }); - await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); - } - - // 3. Check profile page shows teacher section + // Now we should be on /student/profile with STUDENT role + // Check profile page shows teacher section const teacherSection = page.locator('.current-teacher'); await expect(teacherSection).toBeVisible({ timeout: 30_000 }); const teacherText = await teacherSection.locator('span').textContent(); expect(teacherText).toContain('当前老师'); - // 4. Check "切换老师" button exists and works + // Check "切换老师" button exists const switchBtn = teacherSection.locator('.van-button'); await expect(switchBtn).toBeVisible({ timeout: 10_000 }); @@ -107,12 +115,12 @@ test.describe('学生老师切换', () => { const teacherCount = await teacherCells.count(); expect(teacherCount).toBeGreaterThan(0); - // 5. Select a different teacher and verify change + // Select a different teacher if (teacherCount > 1) { await teacherCells.nth(1).click(); await page.waitForTimeout(1500); - // Should be back on profile page + // Should be back on profile page, verify teacher name is set const updatedTeacherSection = page.locator('.current-teacher'); await expect(updatedTeacherSection).toBeVisible({ timeout: 15_000 }); const newTeacherText = await updatedTeacherSection @@ -125,26 +133,7 @@ test.describe('学生老师切换', () => { test('「我的老师」列表显示本机构老师', async ({ page }) => { test.setTimeout(180_000); - // Login - 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 }); - - if ( - await page - .getByText('请选择您的登录身份') - .isVisible() - .catch(() => false) - ) { - await page.locator('.van-grid-item').first().click(); - await page.waitForTimeout(1000); - } + await loginAsStudent(page); // Navigate through org select to ensure org context await page.goto('/org/select', { @@ -153,8 +142,25 @@ test.describe('学生老师切换', () => { }); await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); - const orgOk = await handleOrgSelect(page); - if (!orgOk) return; + if (page.url().includes('/org/select')) { + if ( + await page + .getByText('暂无可用机构') + .isVisible() + .catch(() => false) + ) { + test.skip(true, '账号无可用机构,跳过'); + return; + } + + const orgCells = page.locator('.van-cell'); + const n = await orgCells.count(); + if (n > 0) { + await orgCells.first().click(); + await page.waitForLoadState('domcontentloaded', { timeout: 90_000 }); + await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 }); + } + } // Navigate to my teachers page await page.goto('/student/teachers', {