diff --git a/tests/web/save_auth.py b/tests/web/save_auth.py index 179a4f6..3349a4e 100644 --- a/tests/web/save_auth.py +++ b/tests/web/save_auth.py @@ -5,41 +5,27 @@ cookies + localStorage 序列化到 JSON 文件,后续用例自动复用。 用法: - # 保存超级管理员的登录态(最常用) python tests/web/save_auth.py - # 保存指定角色的登录态 - python tests/web/save_auth.py --role team_leader - - # 指定浏览器 - python tests/web/save_auth.py --browser firefox - - # 查看帮助 - python tests/web/save_auth.py --help +流程: + 1. 脚本打开浏览器到登录页 + 2. 你在浏览器中手动输入账号、密码、完成验证码并点击登录 + 3. 登录成功后按 Enter 键,脚本自动保存登录态 + 4. 后续 pytest 用例自动复用 生成的 auth 文件: tests/web/auth/super_admin_chromium.json - tests/web/auth/team_leader_firefox.json - ... """ import argparse import sys from pathlib import Path -# 确保 tests/ 在 Python path 中 sys.path.insert(0, str(Path(__file__).parent.parent.parent)) from tests.config.test_config import load_config -# 登录页的 URL 后缀 -LOGIN_PATH = "/login" - -# 登录后验证成功的 URL 关键字 -SUCCESS_URL_KEYWORD = "/admin" - - def main(): parser = argparse.ArgumentParser( description="手动登录并保存浏览器登录态(绕过图形验证码)" @@ -47,8 +33,7 @@ def main(): parser.add_argument( "--role", default="super_admin", - choices=["super_admin", "team_leader", "driver"], - help="登录角色(默认: super_admin)", + help="登录角色(默认: super_admin),会体现在文件名中", ) parser.add_argument( "--browser", @@ -56,68 +41,48 @@ def main(): choices=["chromium", "firefox", "webkit"], help="浏览器类型(默认: chromium)", ) - parser.add_argument( - "--headless", - action="store_true", - help="无头模式(开启后将无法手动输入验证码,仅用于测试已保存的登录态)", - ) args = parser.parse_args() config = load_config() web_config = config["web"] - account = config["accounts"].get(args.role) - if not account: - print(f"❌ 未知角色 '{args.role}',可用: {list(config['accounts'].keys())}") - sys.exit(1) - base_url = web_config["base_url"] login_url = f"{base_url}/#/login" - # ── 打开浏览器 ── from playwright.sync_api import sync_playwright with sync_playwright() as p: browser_launcher = getattr(p, args.browser) - browser = browser_launcher.launch(headless=args.headless) + browser = browser_launcher.launch(headless=False) context = browser.new_context( viewport={"width": 1920, "height": 1080}, locale="zh-CN", ) page = context.new_page() - # ── 导航到登录页 ── print(f"\n🔗 打开登录页: {login_url}") page.goto(login_url) - # ── 填入账号密码 ── - page.get_by_placeholder("请输入用户名").fill(account["phone"]) - page.get_by_placeholder("请输入密码").fill(account["password"]) - print(f"👤 已填入账号: {account['phone']}(角色: {args.role})") - print("📝 请在浏览器中手动完成验证码并点击登录...") - print(" (登录成功后脚本会自动检测并保存)\n") + print(f"\n{'='*60}") + print(f"👤 角色: {args.role}") + print(f" 请在浏览器中手动完成登录(输入账号密码 + 验证码)") + print(f" 登录成功后回到此处按 Enter 键保存登录态...") + print(f"{'='*60}\n") - # ── 等待用户手动完成验证码 + 登录 ── - try: - # Hash 路由模式,用元素可见判断登录成功而不是 URL 变化 - page.wait_for_selector(".ant-layout-sider, .sidebar, [class*='sider']", timeout=300_000) - except Exception: - print("\n⚠️ 等待超时(5 分钟)。可能原因:") - print(" 1. 未在浏览器中完成验证码登录") - print(" 2. 账号密码错误") - print(" 3. 网络不可达") - print(" 请检查后重试。") - browser.close() - sys.exit(1) + input(">>> 按 Enter 保存登录态...") - # ── 验证登录成功 ── - if "/login" in page.url or "/#/login" in page.url: - print("\n❌ 登录失败,仍然停留在登录页。请检查账号密码。") - browser.close() - sys.exit(1) + # 检查是否真的登录成功了 + current = page.url + if "/login" in current or "/#/login" in current: + print(f"\n⚠️ 当前仍在登录页: {current}") + print(" 要保存吗?(y/n): ", end="") + choice = input().strip().lower() + if choice != "y": + print("已取消。") + browser.close() + sys.exit(0) - print(f"✅ 登录成功!当前页面: {page.url}") + print(f"\n✅ 当前页面: {current}") - # ── 保存登录态 ── auth_dir = Path(web_config.get("storage_state_dir", "tests/web/auth")) auth_dir.mkdir(parents=True, exist_ok=True) auth_file = auth_dir / f"{args.role}_{args.browser}.json" @@ -127,10 +92,7 @@ def main(): browser.close() - print("\n🎉 完成!现在可以运行用例了:") - print(f" pytest tests/web/ -m p0") - print(f"\n登录态过期后重新运行即可:") - print(f" python tests/web/save_auth.py --role {args.role}") + print(f"\n🎉 现在可以跑了: pytest tests/web/ -m p0") if __name__ == "__main__":