""" 验证 6 个模块的页面是否能正常加载。 检测方式: 1. HTTP 状态码(非 200 即失败) 2. JavaScript pageerror 3. 可见错误边界元素([data-error-boundary], [role="alert"] 中的错误文本) 注意:不检查 content 中的 i18n 文本(翻译 JSON 会被误判) """ import sys from playwright.sync_api import sync_playwright BASE = "http://localhost:3000" EMAIL = "t_chinese_1@xiaoxue.edu.cn" PASSWORD = "123456" MODULES = [ ("考勤统计", "/teacher/attendance/stats"), ("学情诊断", "/teacher/diagnostic"), ("错题分析", "/teacher/error-book"), ("选修课", "/teacher/elective"), ("公告", "/announcements"), ("消息", "/messages"), ] def login(page): page.goto(f"{BASE}/login", wait_until="domcontentloaded", timeout=15000) page.wait_for_timeout(1000) email_input = page.locator('input[type="email"]') if email_input.count() == 0: email_input = page.locator('input[name="email"]') email_input.fill(EMAIL) pwd_input = page.locator('input[type="password"]') pwd_input.fill(PASSWORD) page.get_by_role("button", name="登录").click() page.wait_for_url("**/dashboard**", timeout=15000) page.wait_for_timeout(2000) def main(): results = [] with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() all_errors = [] page.on("pageerror", lambda err: all_errors.append(str(err)[:300])) print("登录中...") login(page) print(f"登录成功,URL: {page.url}") for name, path in MODULES: url = f"{BASE}{path}" all_errors.clear() try: response = page.goto(url, wait_until="domcontentloaded", timeout=30000) page.wait_for_timeout(4000) http_status = response.status if response else 0 # 检查可见错误边界(排除 i18n JSON 文本) # 只查找实际渲染的错误提示元素 visible_error = "" error_locators = [ 'text="发生未知错误"', 'text="Something went wrong"', '[data-error-boundary]', ] for sel in error_locators: loc = page.locator(sel).first if loc.count() > 0 and loc.is_visible(): visible_error = sel break status = "FAIL" error_info = "" if http_status != 200: status = "FAIL" error_info = f"HTTP {http_status}" elif len(all_errors) > 0: status = "FAIL" error_info = "PageError: " + " | ".join(all_errors[:2]) elif visible_error: status = "FAIL" error_info = f"可见错误: {visible_error}" else: status = "PASS" results.append((name, status, error_info)) print(f"[{status}] {name}: {error_info or 'OK'} (HTTP {http_status})") except Exception as e: results.append((name, "FAIL", str(e)[:100])) print(f"[FAIL] {name}: {str(e)[:100]}") browser.close() print("\n=== 汇总 ===") pass_count = sum(1 for _, s, _ in results if s == "PASS") fail_count = sum(1 for _, s, _ in results if s == "FAIL") print(f"总计: {pass_count} PASS, {fail_count} FAIL") sys.exit(0 if fail_count == 0 else 1) if __name__ == "__main__": main()