Files
NextEdu/scripts/test-modules.py
SpecialX cbc6e259fa chore(scripts): cleanup obsolete scripts and add new diagnostic scripts
- Remove temp-i18n-zh-fix.mjs, test-failing-modules.py, test-teacher-pages.py

- Add check-attendance-rules.mjs, check-db-state.mjs, test-modules.py
2026-07-04 10:23:55 +08:00

112 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
验证 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()