fix: explicitly select student role in teacher-switching E2E
User has multiple roles, first grid item may not be STUDENT. Add loginAsStudent helper to find and click the "学生" role. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+106
-100
@@ -2,40 +2,85 @@ import { expect, test } from './fixtures';
|
|||||||
|
|
||||||
const moicenUnionid = process.env.MOICEN_E2E_UNIONID?.trim();
|
const moicenUnionid = process.env.MOICEN_E2E_UNIONID?.trim();
|
||||||
|
|
||||||
async function handleOrgSelect(page: any): Promise<boolean> {
|
async function loginAsStudent(page: any) {
|
||||||
// Returns true if org was selected, false if skipped
|
const q = new URLSearchParams({
|
||||||
if (!page.url().includes('/org/select')) return true;
|
unionid: moicenUnionid!,
|
||||||
|
status: '2',
|
||||||
await page.waitForTimeout(2000);
|
});
|
||||||
|
await page.goto(`/?${q.toString()}`, {
|
||||||
if (
|
waitUntil: 'domcontentloaded',
|
||||||
await page
|
timeout: 60_000,
|
||||||
.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 });
|
|
||||||
await expect(page.locator('#app')).toBeVisible({ 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<boolean> {
|
||||||
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,56 +90,19 @@ test.describe('学生老师切换', () => {
|
|||||||
test('profile 页显示当前老师且可切换', async ({ page }) => {
|
test('profile 页显示当前老师且可切换', async ({ page }) => {
|
||||||
test.setTimeout(180_000);
|
test.setTimeout(180_000);
|
||||||
|
|
||||||
// 1. Login
|
await loginAsStudent(page);
|
||||||
const q = new URLSearchParams({
|
const ok = await ensureOrgContext(page);
|
||||||
unionid: moicenUnionid!,
|
if (!ok) return;
|
||||||
status: '2',
|
|
||||||
});
|
|
||||||
await page.goto(`/?${q.toString()}`, {
|
|
||||||
waitUntil: 'domcontentloaded',
|
|
||||||
timeout: 60_000,
|
|
||||||
});
|
|
||||||
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
|
||||||
|
|
||||||
// Handle role selection if needed
|
// Now we should be on /student/profile with STUDENT role
|
||||||
if (
|
// Check profile page shows teacher section
|
||||||
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
|
|
||||||
const teacherSection = page.locator('.current-teacher');
|
const teacherSection = page.locator('.current-teacher');
|
||||||
await expect(teacherSection).toBeVisible({ timeout: 30_000 });
|
await expect(teacherSection).toBeVisible({ timeout: 30_000 });
|
||||||
|
|
||||||
const teacherText = await teacherSection.locator('span').textContent();
|
const teacherText = await teacherSection.locator('span').textContent();
|
||||||
expect(teacherText).toContain('当前老师');
|
expect(teacherText).toContain('当前老师');
|
||||||
|
|
||||||
// 4. Check "切换老师" button exists and works
|
// Check "切换老师" button exists
|
||||||
const switchBtn = teacherSection.locator('.van-button');
|
const switchBtn = teacherSection.locator('.van-button');
|
||||||
await expect(switchBtn).toBeVisible({ timeout: 10_000 });
|
await expect(switchBtn).toBeVisible({ timeout: 10_000 });
|
||||||
|
|
||||||
@@ -107,12 +115,12 @@ test.describe('学生老师切换', () => {
|
|||||||
const teacherCount = await teacherCells.count();
|
const teacherCount = await teacherCells.count();
|
||||||
expect(teacherCount).toBeGreaterThan(0);
|
expect(teacherCount).toBeGreaterThan(0);
|
||||||
|
|
||||||
// 5. Select a different teacher and verify change
|
// Select a different teacher
|
||||||
if (teacherCount > 1) {
|
if (teacherCount > 1) {
|
||||||
await teacherCells.nth(1).click();
|
await teacherCells.nth(1).click();
|
||||||
await page.waitForTimeout(1500);
|
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');
|
const updatedTeacherSection = page.locator('.current-teacher');
|
||||||
await expect(updatedTeacherSection).toBeVisible({ timeout: 15_000 });
|
await expect(updatedTeacherSection).toBeVisible({ timeout: 15_000 });
|
||||||
const newTeacherText = await updatedTeacherSection
|
const newTeacherText = await updatedTeacherSection
|
||||||
@@ -125,26 +133,7 @@ test.describe('学生老师切换', () => {
|
|||||||
test('「我的老师」列表显示本机构老师', async ({ page }) => {
|
test('「我的老师」列表显示本机构老师', async ({ page }) => {
|
||||||
test.setTimeout(180_000);
|
test.setTimeout(180_000);
|
||||||
|
|
||||||
// Login
|
await loginAsStudent(page);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Navigate through org select to ensure org context
|
// Navigate through org select to ensure org context
|
||||||
await page.goto('/org/select', {
|
await page.goto('/org/select', {
|
||||||
@@ -153,8 +142,25 @@ test.describe('学生老师切换', () => {
|
|||||||
});
|
});
|
||||||
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
||||||
|
|
||||||
const orgOk = await handleOrgSelect(page);
|
if (page.url().includes('/org/select')) {
|
||||||
if (!orgOk) return;
|
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
|
// Navigate to my teachers page
|
||||||
await page.goto('/student/teachers', {
|
await page.goto('/student/teachers', {
|
||||||
|
|||||||
Reference in New Issue
Block a user