test: add teacherless student redirect test + fix flaky role switch tests
- Fix action sheet item selection to use nth() instead of hasText filter (role names use "教师" not "老师" in action sheet, and hasText caused multiple matches with "主管教师") - Add waitFor for action sheet animation to fix visibility race condition - Add test: teacherless student auto-redirect to /student/teacher-select via API route interception Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -159,7 +159,7 @@ test.describe('学生老师切换', () => {
|
|||||||
expect(teacherCount).toBeGreaterThan(0);
|
expect(teacherCount).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('从老师切换到学生角色后显示老师选择页面', async ({ page }) => {
|
test('角色切换后自动选择老师且不会回机构选择页', async ({ page }) => {
|
||||||
test.setTimeout(180_000);
|
test.setTimeout(180_000);
|
||||||
|
|
||||||
// Login as student to establish session
|
// Login as student to establish session
|
||||||
@@ -173,19 +173,17 @@ test.describe('学生老师切换', () => {
|
|||||||
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
||||||
await page.waitForTimeout(3000);
|
await page.waitForTimeout(3000);
|
||||||
|
|
||||||
// Click the role switcher icon
|
|
||||||
const roleSwitcher = page.locator('.van-icon-exchange');
|
const roleSwitcher = page.locator('.van-icon-exchange');
|
||||||
if (!(await roleSwitcher.isVisible().catch(() => false))) {
|
|
||||||
test.skip(true, '未找到角色切换按钮');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await roleSwitcher.click();
|
await roleSwitcher.click();
|
||||||
|
|
||||||
|
// Wait for action sheet to appear and settle
|
||||||
|
await page.locator('.van-action-sheet').waitFor({ state: 'visible', timeout: 10_000 });
|
||||||
await page.waitForTimeout(1000);
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
// Select TEACHER role
|
// Select TEACHER role (index 2 in ["测试员","学生","教师","管理员","主管教师"])
|
||||||
const teacherRoleBtn = page.locator('.van-action-sheet__item').filter({ hasText: '老师' });
|
const teacherRoleBtn = page.locator('.van-action-sheet__item').nth(2);
|
||||||
if (!(await teacherRoleBtn.isVisible().catch(() => false))) {
|
if (!(await teacherRoleBtn.isVisible().catch(() => false))) {
|
||||||
test.skip(true, '未找到老师角色选项');
|
test.skip(true, '未找到教师角色选项');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await teacherRoleBtn.click();
|
await teacherRoleBtn.click();
|
||||||
@@ -217,15 +215,14 @@ test.describe('学生老师切换', () => {
|
|||||||
|
|
||||||
// Now switch back to STUDENT role
|
// Now switch back to STUDENT role
|
||||||
const roleSwitcher2 = page.locator('.van-icon-exchange');
|
const roleSwitcher2 = page.locator('.van-icon-exchange');
|
||||||
if (!(await roleSwitcher2.isVisible().catch(() => false))) {
|
|
||||||
test.skip(true, '未找到角色切换按钮');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await roleSwitcher2.click();
|
await roleSwitcher2.click();
|
||||||
|
|
||||||
|
// Wait for action sheet to appear and settle
|
||||||
|
await page.locator('.van-action-sheet').waitFor({ state: 'visible', timeout: 10_000 });
|
||||||
await page.waitForTimeout(1000);
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
// Select STUDENT role
|
// Select STUDENT role (index 1 in ["测试员","学生","教师","管理员","主管教师"])
|
||||||
const studentRoleBtn = page.locator('.van-action-sheet__item').filter({ hasText: '学生' });
|
const studentRoleBtn = page.locator('.van-action-sheet__item').nth(1);
|
||||||
if (!(await studentRoleBtn.isVisible().catch(() => false))) {
|
if (!(await studentRoleBtn.isVisible().catch(() => false))) {
|
||||||
test.skip(true, '未找到学生角色选项');
|
test.skip(true, '未找到学生角色选项');
|
||||||
return;
|
return;
|
||||||
@@ -240,28 +237,32 @@ test.describe('学生老师切换', () => {
|
|||||||
await page.waitForTimeout(5000);
|
await page.waitForTimeout(5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for role switch to complete
|
// Wait for role switch and auto-select to complete
|
||||||
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
||||||
await page.waitForTimeout(5000);
|
await page.waitForTimeout(5000);
|
||||||
|
|
||||||
// We should be on teacher-select page or index page (both show teacher selection)
|
// Auto-select should have picked a teacher and redirected to /student/home
|
||||||
const currentPath = new URL(page.url()).pathname;
|
const currentPath = new URL(page.url()).pathname;
|
||||||
const validPaths = ['/student/teacher-select', '/'];
|
|
||||||
expect(validPaths).toContain(currentPath);
|
|
||||||
|
|
||||||
// Verify we did NOT end up on org-select page
|
// Verify we did NOT end up on org-select page
|
||||||
expect(currentPath).not.toBe('/org/select');
|
expect(currentPath).not.toBe('/org/select');
|
||||||
|
|
||||||
// Verify teacher selection UI is present
|
// Should be on a valid student page (not org-select)
|
||||||
if (currentPath === '/student/teacher-select') {
|
const isStudentPage = currentPath.startsWith('/student/') || currentPath === '/';
|
||||||
await expect(page.locator('.van-cell').first()).toBeVisible({ timeout: 10_000 });
|
expect(isStudentPage).toBe(true);
|
||||||
// Select a teacher
|
|
||||||
await page.locator('.van-cell').first().click();
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
|
|
||||||
// After selection, verify we're NOT on org-select
|
// Verify teacher is auto-selected: navigate to profile and check
|
||||||
const afterPath = new URL(page.url()).pathname;
|
await page.goto('/student/profile', {
|
||||||
expect(afterPath).not.toBe('/org/select');
|
waitUntil: 'domcontentloaded',
|
||||||
|
timeout: 60_000,
|
||||||
|
});
|
||||||
|
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
||||||
|
await page.waitForTimeout(3000);
|
||||||
|
|
||||||
|
const teacherSection = page.locator('.current-teacher');
|
||||||
|
if (await teacherSection.isVisible().catch(() => false)) {
|
||||||
|
const teacherText = await teacherSection.locator('span').first().textContent();
|
||||||
|
// Teacher should be selected (not "未选择老师")
|
||||||
|
expect(teacherText).not.toContain('未选择老师');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -304,4 +305,51 @@ test.describe('学生老师切换', () => {
|
|||||||
// Should still be on a valid student page
|
// Should still be on a valid student page
|
||||||
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('无老师学生自动跳转到选择老师页面', async ({ page }) => {
|
||||||
|
test.setTimeout(120_000);
|
||||||
|
|
||||||
|
// Intercept the teachers API to return empty (simulating student with no claimed teachers)
|
||||||
|
await page.route('**/find_all_teachers_by_student_id/**', async route => {
|
||||||
|
await route.fulfill({
|
||||||
|
status: 200,
|
||||||
|
contentType: 'application/json',
|
||||||
|
body: JSON.stringify({ r: true, d: [], e: null })
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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 page.waitForTimeout(5000);
|
||||||
|
|
||||||
|
// Pick STUDENT role explicitly
|
||||||
|
const roleSelect = page.getByText('请选择您的登录身份');
|
||||||
|
if (await roleSelect.isVisible().catch(() => false)) {
|
||||||
|
const studentRole = page.locator('.van-grid-item').filter({ hasText: '学生' });
|
||||||
|
if (await studentRole.isVisible().catch(() => false)) {
|
||||||
|
await studentRole.click();
|
||||||
|
await page.waitForTimeout(5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle org select if needed
|
||||||
|
if (page.url().includes('/org/select')) {
|
||||||
|
const orgCells = page.locator('#app .van-cell-group .van-cell');
|
||||||
|
const n = await orgCells.count();
|
||||||
|
expect(n).toBeGreaterThan(0);
|
||||||
|
await orgCells.first().click();
|
||||||
|
await page.waitForTimeout(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Student with no teachers should be redirected to teacher-select page
|
||||||
|
// The redirect happens asynchronously via watchEffect
|
||||||
|
await expect(async () => {
|
||||||
|
const url = page.url();
|
||||||
|
expect(url).toContain('/student/teacher-select');
|
||||||
|
}).toPass({ timeout: 30_000 });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user