fix: save_auth 改为纯手动模式,不再尝试自动填表
用户自己在浏览器中完成验证码登录后按 Enter,脚本仅负责检测并保存 storage_state
This commit is contained in:
+25
-63
@@ -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(" 请检查后重试。")
|
||||
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(1)
|
||||
sys.exit(0)
|
||||
|
||||
# ── 验证登录成功 ──
|
||||
if "/login" in page.url or "/#/login" in page.url:
|
||||
print("\n❌ 登录失败,仍然停留在登录页。请检查账号密码。")
|
||||
browser.close()
|
||||
sys.exit(1)
|
||||
print(f"\n✅ 当前页面: {current}")
|
||||
|
||||
print(f"✅ 登录成功!当前页面: {page.url}")
|
||||
|
||||
# ── 保存登录态 ──
|
||||
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__":
|
||||
|
||||
Reference in New Issue
Block a user