{
  "test_date": "2026-06-20 12:28:43",
  "test_target": "家长端 (Parent)",
  "base_url": "http://localhost:3000",
  "parent_email": "parent_g1c1_1@xiaoxue.edu.cn",
  "summary": {
    "total": 24,
    "passed": 17,
    "failed": 7,
    "warnings": 0
  },
  "pages": {
    "parent_dashboard": {
      "url": "http://localhost:3000/parent/dashboard",
      "route": "/parent/dashboard",
      "category": "Dashboard",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/parent/dashboard",
      "redirect_url": null,
      "errors": [],
      "warnings": [],
      "content_checks": []
    },
    "parent_grades": {
      "url": "http://localhost:3000/parent/grades",
      "route": "/parent/grades",
      "category": "Grades",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/parent/grades",
      "redirect_url": null,
      "errors": [],
      "warnings": [],
      "content_checks": []
    },
    "parent_attendance": {
      "url": "http://localhost:3000/parent/attendance",
      "route": "/parent/attendance",
      "category": "Attendance",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/parent/attendance",
      "redirect_url": null,
      "errors": [],
      "warnings": [],
      "content_checks": []
    },
    "announcements": {
      "url": "http://localhost:3000/announcements",
      "route": "/announcements",
      "category": "Announcements",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/announcements",
      "redirect_url": null,
      "errors": [],
      "warnings": [],
      "content_checks": []
    },
    "messages": {
      "url": "http://localhost:3000/messages",
      "route": "/messages",
      "category": "Messages",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/messages",
      "redirect_url": null,
      "errors": [],
      "warnings": [],
      "content_checks": []
    },
    "messages_compose": {
      "url": "http://localhost:3000/messages/compose",
      "route": "/messages/compose",
      "category": "Messages",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/messages/compose",
      "redirect_url": null,
      "errors": [],
      "warnings": [],
      "content_checks": []
    },
    "profile": {
      "url": "http://localhost:3000/profile",
      "route": "/profile",
      "category": "Profile",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/profile",
      "redirect_url": null,
      "errors": [],
      "warnings": [],
      "content_checks": []
    },
    "settings": {
      "url": "http://localhost:3000/settings",
      "route": "/settings",
      "category": "Settings",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/settings",
      "redirect_url": null,
      "errors": [],
      "warnings": [],
      "content_checks": []
    },
    "settings_security": {
      "url": "http://localhost:3000/settings/security",
      "route": "/settings/security",
      "category": "Settings",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/settings/security",
      "redirect_url": null,
      "errors": [],
      "warnings": [],
      "content_checks": []
    },
    "parent_children_user_s_g1c1_1": {
      "url": "http://localhost:3000/parent/children/user_s_g1c1_1",
      "route": "/parent/children/user_s_g1c1_1",
      "category": "Child Detail",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/parent/children/user_s_g1c1_1",
      "redirect_url": null,
      "errors": [],
      "warnings": [
        "Error text on page: Due 2026年6月18日"
      ],
      "content_checks": []
    },
    "forbidden_admin_dashboard": {
      "url": "http://localhost:3000/admin/dashboard",
      "route": "/admin/dashboard",
      "category": "Cross-Role Access Control",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fdashboard&reason=forbidden",
      "redirect_url": "http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fdashboard&reason=forbidden",
      "errors": [],
      "warnings": [],
      "content_checks": [
        "跨角色访问被权限系统拦截"
      ]
    },
    "forbidden_admin_school": {
      "url": "http://localhost:3000/admin/school",
      "route": "/admin/school",
      "category": "Cross-Role Access Control",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fschool&reason=forbidden",
      "redirect_url": "http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fschool&reason=forbidden",
      "errors": [],
      "warnings": [],
      "content_checks": [
        "跨角色访问被权限系统拦截"
      ]
    },
    "forbidden_teacher_dashboard": {
      "url": "http://localhost:3000/teacher/dashboard",
      "route": "/teacher/dashboard",
      "category": "Cross-Role Access Control",
      "status": "failed",
      "http_status": 500,
      "final_url": "http://localhost:3000/teacher/dashboard",
      "redirect_url": null,
      "errors": [
        "跨角色访问返回 HTTP 500（应被重定向拦截）",
        "Failed to load resource: the server responded with a status of 500 (Internal Server Error)",
        "%o\n\n%s Error: Teacher not found\n    at getTeacherIdForMutations (about://React/Server/E:%5CDesktop%5CCICD%5C.next%5Cdev%5Cserver%5Cchunks%5Cssr%5C%5Broot-of-the-server%5D__458f1717._.js?61:9381:27)\n    at  TeacherDashboardPage (about://React/Server/E:%5CDesktop%5CCICD%5C.next%5Cdev%5Cserver%5Cchunks%5Cssr%5C%5Broot-of-the-server%5D__6e4018f8._.js?62:2019:23)\n    at resolveErrorDev (http://localhost:3000/_next/static/chunks/node_modules_next_dist_compiled_react-server-dom-turbopack_9212ccad._.js:...（已截断）"
      ],
      "warnings": [],
      "content_checks": []
    },
    "forbidden_teacher_exams": {
      "url": "http://localhost:3000/teacher/exams",
      "route": "/teacher/exams",
      "category": "Cross-Role Access Control",
      "status": "failed",
      "http_status": 200,
      "final_url": "http://localhost:3000/teacher/exams/all",
      "redirect_url": "http://localhost:3000/teacher/exams/all",
      "errors": [
        "⚠️ 安全漏洞：家长成功访问了受限页面（最终 URL: http://localhost:3000/teacher/exams/all），权限隔离失效",
        "%o\n\n%s Error: Failed query: select `exams`.`id`, `exams`.`title`, `exams`.`description`, `exams`.`structure`, `exams`.`creator_id`, `exams`.`subject_id`, `exams`.`grade_id`, `exams`.`start_time`, `exams`.`end_time`, `exams`.`exam_mode`, `exams`.`duration_minutes`, `exams`.`shuffle_questions`, `exams`.`allow_late_start`, `exams`.`late_start_grace_minutes`, `exams`.`anti_cheat_enabled`, `exams`.`status`, `exams`.`created_at`, `exams`.`updated_at`, `exams_subject`.`data` as `subject`, `exams_gradeE...（已截断）"
      ],
      "warnings": [],
      "content_checks": []
    },
    "forbidden_teacher_homework": {
      "url": "http://localhost:3000/teacher/homework",
      "route": "/teacher/homework",
      "category": "Cross-Role Access Control",
      "status": "failed",
      "http_status": 500,
      "final_url": "http://localhost:3000/teacher/homework/assignments",
      "redirect_url": "http://localhost:3000/teacher/homework/assignments",
      "errors": [
        "跨角色访问返回 HTTP 500（应被重定向拦截）",
        "Failed to load resource: the server responded with a status of 500 (Internal Server Error)",
        "%o\n\n%s Error: Teacher not found\n    at getTeacherIdForMutations (about://React/Server/E:%5CDesktop%5CCICD%5C.next%5Cdev%5Cserver%5Cchunks%5Cssr%5C%5Broot-of-the-server%5D__458f1717._.js?47:9381:27)\n    at  AssignmentsPage (about://React/Server/E:%5CDesktop%5CCICD%5C.next%5Cdev%5Cserver%5Cchunks%5Cssr%5C%5Broot-of-the-server%5D__8e4de1e6._.js?48:253:23)\n    at resolveErrorDev (http://localhost:3000/_next/static/chunks/node_modules_next_dist_compiled_react-server-dom-turbopack_9212ccad._.js:1882:1...（已截断）"
      ],
      "warnings": [],
      "content_checks": []
    },
    "forbidden_teacher_grades": {
      "url": "http://localhost:3000/teacher/grades",
      "route": "/teacher/grades",
      "category": "Cross-Role Access Control",
      "status": "failed",
      "http_status": 200,
      "final_url": "http://localhost:3000/teacher/grades",
      "redirect_url": null,
      "errors": [
        "⚠️ 安全漏洞：家长成功访问了受限页面（最终 URL: http://localhost:3000/teacher/grades），权限隔离失效"
      ],
      "warnings": [],
      "content_checks": []
    },
    "forbidden_teacher_questions": {
      "url": "http://localhost:3000/teacher/questions",
      "route": "/teacher/questions",
      "category": "Cross-Role Access Control",
      "status": "failed",
      "http_status": 200,
      "final_url": "http://localhost:3000/teacher/questions",
      "redirect_url": null,
      "errors": [
        "⚠️ 安全漏洞：家长成功访问了受限页面（最终 URL: http://localhost:3000/teacher/questions），权限隔离失效"
      ],
      "warnings": [],
      "content_checks": []
    },
    "forbidden_teacher_classes": {
      "url": "http://localhost:3000/teacher/classes",
      "route": "/teacher/classes",
      "category": "Cross-Role Access Control",
      "status": "failed",
      "http_status": 200,
      "final_url": "http://localhost:3000/teacher/classes/my",
      "redirect_url": "http://localhost:3000/teacher/classes/my",
      "errors": [
        "⚠️ 安全漏洞：家长成功访问了受限页面（最终 URL: http://localhost:3000/teacher/classes/my），权限隔离失效"
      ],
      "warnings": [],
      "content_checks": []
    },
    "forbidden_teacher_attendance": {
      "url": "http://localhost:3000/teacher/attendance",
      "route": "/teacher/attendance",
      "category": "Cross-Role Access Control",
      "status": "failed",
      "http_status": 200,
      "final_url": "http://localhost:3000/teacher/attendance",
      "redirect_url": null,
      "errors": [
        "⚠️ 安全漏洞：家长成功访问了受限页面（最终 URL: http://localhost:3000/teacher/attendance），权限隔离失效"
      ],
      "warnings": [],
      "content_checks": []
    },
    "forbidden_student_dashboard": {
      "url": "http://localhost:3000/student/dashboard",
      "route": "/student/dashboard",
      "category": "Cross-Role Access Control",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/parent/dashboard?from=%2Fstudent%2Fdashboard&reason=forbidden",
      "redirect_url": "http://localhost:3000/parent/dashboard?from=%2Fstudent%2Fdashboard&reason=forbidden",
      "errors": [],
      "warnings": [],
      "content_checks": [
        "跨角色访问被权限系统拦截"
      ]
    },
    "forbidden_student_learning": {
      "url": "http://localhost:3000/student/learning",
      "route": "/student/learning",
      "category": "Cross-Role Access Control",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/parent/dashboard?from=%2Fstudent%2Flearning&reason=forbidden",
      "redirect_url": "http://localhost:3000/parent/dashboard?from=%2Fstudent%2Flearning&reason=forbidden",
      "errors": [],
      "warnings": [],
      "content_checks": [
        "跨角色访问被权限系统拦截"
      ]
    },
    "forbidden_student_grades": {
      "url": "http://localhost:3000/student/grades",
      "route": "/student/grades",
      "category": "Cross-Role Access Control",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/parent/dashboard?from=%2Fstudent%2Fgrades&reason=forbidden",
      "redirect_url": "http://localhost:3000/parent/dashboard?from=%2Fstudent%2Fgrades&reason=forbidden",
      "errors": [],
      "warnings": [],
      "content_checks": [
        "跨角色访问被权限系统拦截"
      ]
    },
    "forbidden_student_attendance": {
      "url": "http://localhost:3000/student/attendance",
      "route": "/student/attendance",
      "category": "Cross-Role Access Control",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/parent/dashboard?from=%2Fstudent%2Fattendance&reason=forbidden",
      "redirect_url": "http://localhost:3000/parent/dashboard?from=%2Fstudent%2Fattendance&reason=forbidden",
      "errors": [],
      "warnings": [],
      "content_checks": [
        "跨角色访问被权限系统拦截"
      ]
    },
    "forbidden_management_grade_classes": {
      "url": "http://localhost:3000/management/grade/classes",
      "route": "/management/grade/classes",
      "category": "Cross-Role Access Control",
      "status": "passed",
      "http_status": 200,
      "final_url": "http://localhost:3000/parent/dashboard?from=%2Fmanagement%2Fgrade%2Fclasses&reason=forbidden",
      "redirect_url": "http://localhost:3000/parent/dashboard?from=%2Fmanagement%2Fgrade%2Fclasses&reason=forbidden",
      "errors": [],
      "warnings": [],
      "content_checks": [
        "跨角色访问被权限系统拦截"
      ]
    }
  },
  "functional_checks": [
    {
      "name": "返回仪表盘按钮",
      "expected": "存在 Back to Dashboard 链接",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "子女姓名标题",
      "expected": "显示子女姓名",
      "actual": "小明",
      "passed": true
    },
    {
      "name": "邮箱掩码处理",
      "expected": "邮箱被掩码为 j***@domain.com",
      "actual": "Masked",
      "passed": true
    },
    {
      "name": "作业摘要卡片",
      "expected": "显示 {childName}'s Homework",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "作业统计 - Pending",
      "expected": "显示 Pending 计数",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "作业统计 - Submitted",
      "expected": "显示 Submitted 计数",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "作业统计 - Graded",
      "expected": "显示 Graded 计数",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "成绩趋势卡片",
      "expected": "显示成绩信息",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "今日课表卡片",
      "expected": "显示 {childName}'s Today Schedule",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "View all 链接",
      "expected": "存在 View all 链接",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "仪表盘标题",
      "expected": "Parent Dashboard",
      "actual": "Parent Dashboard",
      "passed": true
    },
    {
      "name": "问候语显示",
      "expected": "Good morning/afternoon/evening 或 Welcome",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "Grades 快捷入口",
      "expected": "存在",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "Attendance 快捷入口",
      "expected": "存在",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "Announcements 快捷入口",
      "expected": "存在",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "子女卡片显示",
      "expected": "≥1 个子女卡片",
      "actual": "1 个",
      "passed": true
    },
    {
      "name": "子女卡片 - Pending 统计",
      "expected": "显示 Pending 计数",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "子女卡片 - Overdue 统计",
      "expected": "显示 Overdue 计数",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "子女数量提示",
      "expected": "显示 'N child(ren) linked'",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "侧边栏 - Dashboard",
      "expected": "显示 Dashboard 导航项",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "侧边栏 - Grades",
      "expected": "显示 Grades 导航项",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "侧边栏 - Attendance",
      "expected": "显示 Attendance 导航项",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "侧边栏 - Announcements",
      "expected": "显示 Announcements 导航项",
      "actual": "Found",
      "passed": true
    },
    {
      "name": "侧边栏 - Messages",
      "expected": "显示 Messages 导航项",
      "actual": "Found",
      "passed": true
    }
  ],
  "security_checks": [
    {
      "name": "访问不存在/非关联子女应被拒绝",
      "expected": "显示 Access denied 或 404",
      "actual": "Access denied",
      "passed": true
    }
  ],
  "console_errors": [],
  "navigation_issues": []
}