test: update and add E2E, integration, visual, and webapp tests
Some checks failed
CI / scheduled-backup (push) Failing after 36s
CI / backup-verify (push) Has been skipped
CI / weekly-dr-drill (push) Failing after 0s
CI / build-deploy (push) Has been cancelled
CI / security-scan (push) Has been cancelled

- Update E2E tests: announcements, auth, auth-business-flow, full-route-regression, grades, navigation, smoke-auth, teacher-web-test

- Update integration tests: api-ai-chat, api-onboarding-complete, api-onboarding-status, proxy-guard, integration setup

- Update visual regression tests: admin-dashboard, homepage, student-dashboard, teacher-dashboard, visual config, helpers

- Update webapp tests: admin, parent, student full tests and debug scripts

- Add new webapp tests: announcements_messages, settings_profile, debug scripts

- Add webtest directory with test plans, screenshots, and diagnostic scripts
This commit is contained in:
SpecialX
2026-06-23 17:39:40 +08:00
parent f40ce0f560
commit d884c6d513
183 changed files with 19006 additions and 0 deletions

View File

@@ -0,0 +1,438 @@
{
"test_date": "2026-06-22 19:42:53",
"module": "学校管理 (School Management)",
"version": "v1",
"base_url": "http://localhost:3000",
"covered_submodules": [
"schools",
"departments",
"academic-year"
],
"summary": {
"total": 15,
"passed": 15,
"failed": 0,
"warnings": 0
},
"roles": {
"admin": {
"role": "admin",
"login_success": true,
"access_tests": [
{
"route_key": "schools_list",
"url": "http://localhost:3000/admin/school/schools",
"expected_access": true,
"http_status": 200,
"final_url": "http://localhost:3000/admin/school/schools",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "页面正常加载",
"passed": true
}
]
},
{
"route_key": "departments_list",
"url": "http://localhost:3000/admin/school/departments",
"expected_access": true,
"http_status": 200,
"final_url": "http://localhost:3000/admin/school/departments",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "页面正常加载",
"passed": true
}
]
},
{
"route_key": "academic_year_list",
"url": "http://localhost:3000/admin/school/academic-year",
"expected_access": true,
"http_status": 200,
"final_url": "http://localhost:3000/admin/school/academic-year",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "页面正常加载",
"passed": true
}
]
}
],
"crud_tests": [
{
"feature": "学校 CRUD",
"role": "admin",
"operations": [
{
"name": "列表加载",
"passed": true,
"detail": "列表/空状态正常显示"
},
{
"name": "打开创建对话框",
"passed": true,
"detail": "创建对话框已打开"
},
{
"name": "编辑入口存在",
"passed": true,
"detail": "无数据行,跳过编辑入口检查"
},
{
"name": "删除入口存在",
"passed": true,
"detail": "无数据行,跳过删除入口检查"
}
],
"status": "passed",
"errors": []
},
{
"feature": "院系 CRUD",
"role": "admin",
"operations": [
{
"name": "列表加载",
"passed": true,
"detail": "列表/空状态正常显示"
},
{
"name": "打开创建对话框",
"passed": true,
"detail": "创建对话框已打开"
},
{
"name": "编辑入口存在",
"passed": true,
"detail": "无数据行,跳过"
},
{
"name": "删除入口存在",
"passed": true,
"detail": "无数据行,跳过"
}
],
"status": "passed",
"errors": []
},
{
"feature": "学年 CRUD",
"role": "admin",
"operations": [
{
"name": "列表加载",
"passed": true,
"detail": "列表/空状态正常显示"
},
{
"name": "打开创建对话框",
"passed": true,
"detail": "创建对话框已打开"
},
{
"name": "编辑入口存在",
"passed": true,
"detail": "无数据行,跳过"
},
{
"name": "删除入口存在",
"passed": true,
"detail": "无数据行,跳过"
}
],
"status": "passed",
"errors": []
}
],
"errors": [],
"warnings": [
"控制台错误: A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client bran",
"控制台错误: A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client bran"
]
},
"teacher": {
"role": "teacher",
"login_success": true,
"access_tests": [
{
"route_key": "schools_list",
"url": "http://localhost:3000/admin/school/schools",
"expected_access": false,
"http_status": 200,
"final_url": "http://localhost:3000/teacher/dashboard?from=%2Fadmin%2Fschool%2Fschools&reason=forbidden",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "权限拒绝重定向",
"passed": true,
"detail": "正确重定向到 http://localhost:3000/teacher/dashboard?from=%2Fadmin%2Fschool%2Fschools&reason=forbidden"
}
]
},
{
"route_key": "departments_list",
"url": "http://localhost:3000/admin/school/departments",
"expected_access": false,
"http_status": 200,
"final_url": "http://localhost:3000/teacher/dashboard?from=%2Fadmin%2Fschool%2Fdepartments&reason=forbidden",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "权限拒绝重定向",
"passed": true,
"detail": "正确重定向到 http://localhost:3000/teacher/dashboard?from=%2Fadmin%2Fschool%2Fdepartments&reason=forbidden"
}
]
},
{
"route_key": "academic_year_list",
"url": "http://localhost:3000/admin/school/academic-year",
"expected_access": false,
"http_status": 200,
"final_url": "http://localhost:3000/teacher/dashboard?from=%2Fadmin%2Fschool%2Facademic-year&reason=forbidden",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "权限拒绝重定向",
"passed": true,
"detail": "正确重定向到 http://localhost:3000/teacher/dashboard?from=%2Fadmin%2Fschool%2Facademic-year&reason=forbidden"
}
]
}
],
"crud_tests": [
{
"feature": "学校 CRUD",
"role": "teacher",
"operations": [],
"status": "skipped",
"errors": [
"teacher 无 SCHOOL_MANAGE 权限,跳过 CRUD 测试"
]
},
{
"feature": "院系 CRUD",
"role": "teacher",
"operations": [],
"status": "skipped",
"errors": [
"teacher 无 SCHOOL_MANAGE 权限,跳过 CRUD 测试"
]
},
{
"feature": "学年 CRUD",
"role": "teacher",
"operations": [],
"status": "skipped",
"errors": [
"teacher 无 SCHOOL_MANAGE 权限,跳过 CRUD 测试"
]
}
],
"errors": [],
"warnings": []
},
"student": {
"role": "student",
"login_success": true,
"access_tests": [
{
"route_key": "schools_list",
"url": "http://localhost:3000/admin/school/schools",
"expected_access": false,
"http_status": 200,
"final_url": "http://localhost:3000/student/dashboard?from=%2Fadmin%2Fschool%2Fschools&reason=forbidden",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "权限拒绝重定向",
"passed": true,
"detail": "正确重定向到 http://localhost:3000/student/dashboard?from=%2Fadmin%2Fschool%2Fschools&reason=forbidden"
}
]
},
{
"route_key": "departments_list",
"url": "http://localhost:3000/admin/school/departments",
"expected_access": false,
"http_status": 200,
"final_url": "http://localhost:3000/student/dashboard?from=%2Fadmin%2Fschool%2Fdepartments&reason=forbidden",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "权限拒绝重定向",
"passed": true,
"detail": "正确重定向到 http://localhost:3000/student/dashboard?from=%2Fadmin%2Fschool%2Fdepartments&reason=forbidden"
}
]
},
{
"route_key": "academic_year_list",
"url": "http://localhost:3000/admin/school/academic-year",
"expected_access": false,
"http_status": 200,
"final_url": "http://localhost:3000/student/dashboard?from=%2Fadmin%2Fschool%2Facademic-year&reason=forbidden",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "权限拒绝重定向",
"passed": true,
"detail": "正确重定向到 http://localhost:3000/student/dashboard?from=%2Fadmin%2Fschool%2Facademic-year&reason=forbidden"
}
]
}
],
"crud_tests": [
{
"feature": "学校 CRUD",
"role": "student",
"operations": [],
"status": "skipped",
"errors": [
"student 无 SCHOOL_MANAGE 权限,跳过 CRUD 测试"
]
},
{
"feature": "院系 CRUD",
"role": "student",
"operations": [],
"status": "skipped",
"errors": [
"student 无 SCHOOL_MANAGE 权限,跳过 CRUD 测试"
]
},
{
"feature": "学年 CRUD",
"role": "student",
"operations": [],
"status": "skipped",
"errors": [
"student 无 SCHOOL_MANAGE 权限,跳过 CRUD 测试"
]
}
],
"errors": [],
"warnings": []
},
"parent": {
"role": "parent",
"login_success": true,
"access_tests": [
{
"route_key": "schools_list",
"url": "http://localhost:3000/admin/school/schools",
"expected_access": false,
"http_status": 200,
"final_url": "http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fschool%2Fschools&reason=forbidden",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "权限拒绝重定向",
"passed": true,
"detail": "正确重定向到 http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fschool%2Fschools&reason=forbidden"
}
]
},
{
"route_key": "departments_list",
"url": "http://localhost:3000/admin/school/departments",
"expected_access": false,
"http_status": 200,
"final_url": "http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fschool%2Fdepartments&reason=forbidden",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "权限拒绝重定向",
"passed": true,
"detail": "正确重定向到 http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fschool%2Fdepartments&reason=forbidden"
}
]
},
{
"route_key": "academic_year_list",
"url": "http://localhost:3000/admin/school/academic-year",
"expected_access": false,
"http_status": 200,
"final_url": "http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fschool%2Facademic-year&reason=forbidden",
"status": "passed",
"errors": [],
"warnings": [],
"checks": [
{
"name": "权限拒绝重定向",
"passed": true,
"detail": "正确重定向到 http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fschool%2Facademic-year&reason=forbidden"
}
]
}
],
"crud_tests": [
{
"feature": "学校 CRUD",
"role": "parent",
"operations": [],
"status": "skipped",
"errors": [
"parent 无 SCHOOL_MANAGE 权限,跳过 CRUD 测试"
]
},
{
"feature": "院系 CRUD",
"role": "parent",
"operations": [],
"status": "skipped",
"errors": [
"parent 无 SCHOOL_MANAGE 权限,跳过 CRUD 测试"
]
},
{
"feature": "学年 CRUD",
"role": "parent",
"operations": [],
"status": "skipped",
"errors": [
"parent 无 SCHOOL_MANAGE 权限,跳过 CRUD 测试"
]
}
],
"errors": [],
"warnings": []
}
},
"console_errors_global": [
{
"role": "admin",
"error": "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client branch `if (typeof window !== 'undefined')`.\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n- Date formatting in a user's locale which doesn't match the server.\n- External changing data without sending a snapshot of it along with the HTML.\n- Invalid HTML tag nesting.\n\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n\n%s%s https://react.dev/link/hydration-mismatch \n\n ...\n <MenuProvider scope={{Menu:[...], ...}} open={false} onOpenChange={function useCallbackRef.useMemo} content={null} ...>\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_2...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_2...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_2...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" disabled={false} type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-m...\"}\n disabled={false}\n type=\"button\"\n+ id=\"radix-_R_2d59bn5ritpevqbn6lb_\"\n- id=\"radix-_R_9kl5esnebn9evqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n"
},
{
"role": "admin",
"error": "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client branch `if (typeof window !== 'undefined')`.\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n- Date formatting in a user's locale which doesn't match the server.\n- External changing data without sending a snapshot of it along with the HTML.\n- Invalid HTML tag nesting.\n\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n\n%s%s https://react.dev/link/hydration-mismatch \n\n ...\n <MenuProvider scope={{Menu:[...], ...}} open={false} onOpenChange={function useCallbackRef.useMemo} content={null} ...>\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_j...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_j...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_j...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" disabled={false} type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-m...\"}\n disabled={false}\n type=\"button\"\n+ id=\"radix-_R_j59bn5ritpevqbn6lb_\"\n- id=\"radix-_R_2cl5esnebn9evqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n"
}
]
}