#!/usr/bin/env python3 """手动登录并保存浏览器登录态(cookies + localStorage)。 目的: 绕过图形验证码——人工完成一次验证码登录后, cookies + localStorage 序列化到 JSON 文件,后续用例自动复用。 用法: python tests/web/save_auth.py 流程: 1. 脚本打开浏览器到登录页 2. 你在浏览器中手动输入账号、密码、完成验证码并点击登录 3. 登录成功后按 Enter 键,脚本自动保存登录态 4. 后续 pytest 用例自动复用 生成的 auth 文件: tests/web/auth/super_admin_chromium.json """ import argparse import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent.parent)) from tests.config.test_config import load_config def main(): parser = argparse.ArgumentParser( description="手动登录并保存浏览器登录态(绕过图形验证码)" ) parser.add_argument( "--role", default="super_admin", help="登录角色(默认: super_admin),会体现在文件名中", ) parser.add_argument( "--browser", default="chromium", choices=["chromium", "firefox", "webkit"], help="浏览器类型(默认: chromium)", ) args = parser.parse_args() config = load_config() web_config = config["web"] 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=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) print(f"\n{'='*60}") print(f"👤 角色: {args.role}") print(f" 请在浏览器中手动完成登录(输入账号密码 + 验证码)") print(f" 登录成功后回到此处按 Enter 键保存登录态...") print(f"{'='*60}\n") input(">>> 按 Enter 保存登录态...") # 检查是否真的登录成功了 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"\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" context.storage_state(path=str(auth_file)) print(f"💾 登录态已保存到: {auth_file}") browser.close() print(f"\n🎉 现在可以跑了: pytest tests/web/ -m p0") if __name__ == "__main__": main()