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);
|
||||
});
|
||||
|
||||
test('从老师切换到学生角色后显示老师选择页面', async ({ page }) => {
|
||||
test('角色切换后自动选择老师且不会回机构选择页', async ({ page }) => {
|
||||
test.setTimeout(180_000);
|
||||
|
||||
// Login as student to establish session
|
||||
@@ -173,19 +173,17 @@ test.describe('学生老师切换', () => {
|
||||
await expect(page.locator('#app')).toBeVisible({ timeout: 60_000 });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Click the role switcher icon
|
||||
const roleSwitcher = page.locator('.van-icon-exchange');
|
||||
if (!(await roleSwitcher.isVisible().catch(() => false))) {
|
||||
test.skip(true, '未找到角色切换按钮');
|
||||
return;
|
||||
}
|
||||
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);
|
||||
|
||||
// Select TEACHER role
|
||||
const teacherRoleBtn = page.locator('.van-action-sheet__item').filter({ hasText: '老师' });
|
||||
// Select TEACHER role (index 2 in ["测试员","学生","教师","管理员","主管教师"])
|
||||
const teacherRoleBtn = page.locator('.van-action-sheet__item').nth(2);
|
||||
if (!(await teacherRoleBtn.isVisible().catch(() => false))) {
|
||||
test.skip(true, '未找到老师角色选项');
|
||||
test.skip(true, '未找到教师角色选项');
|
||||
return;
|
||||
}
|
||||
await teacherRoleBtn.click();
|
||||
@@ -217,15 +215,14 @@ test.describe('学生老师切换', () => {
|
||||
|
||||
// Now switch back to STUDENT role
|
||||
const roleSwitcher2 = page.locator('.van-icon-exchange');
|
||||
if (!(await roleSwitcher2.isVisible().catch(() => false))) {
|
||||
test.skip(true, '未找到角色切换按钮');
|
||||
return;
|
||||
}
|
||||
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);
|
||||
|
||||
// Select STUDENT role
|
||||
const studentRoleBtn = page.locator('.van-action-sheet__item').filter({ hasText: '学生' });
|
||||
// Select STUDENT role (index 1 in ["测试员","学生","教师","管理员","主管教师"])
|
||||
const studentRoleBtn = page.locator('.van-action-sheet__item').nth(1);
|
||||
if (!(await studentRoleBtn.isVisible().catch(() => false))) {
|
||||
test.skip(true, '未找到学生角色选项');
|
||||
return;
|
||||
@@ -240,28 +237,32 @@ test.describe('学生老师切换', () => {
|
||||
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 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 validPaths = ['/student/teacher-select', '/'];
|
||||
expect(validPaths).toContain(currentPath);
|
||||
|
||||
// Verify we did NOT end up on org-select page
|
||||
expect(currentPath).not.toBe('/org/select');
|
||||
|
||||
// Verify teacher selection UI is present
|
||||
if (currentPath === '/student/teacher-select') {
|
||||
await expect(page.locator('.van-cell').first()).toBeVisible({ timeout: 10_000 });
|
||||
// Select a teacher
|
||||
await page.locator('.van-cell').first().click();
|
||||
await page.waitForTimeout(2000);
|
||||
// Should be on a valid student page (not org-select)
|
||||
const isStudentPage = currentPath.startsWith('/student/') || currentPath === '/';
|
||||
expect(isStudentPage).toBe(true);
|
||||
|
||||
// After selection, verify we're NOT on org-select
|
||||
const afterPath = new URL(page.url()).pathname;
|
||||
expect(afterPath).not.toBe('/org/select');
|
||||
// Verify teacher is auto-selected: navigate to profile and check
|
||||
await page.goto('/student/profile', {
|
||||
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
|
||||
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