Files
QaAutomationHub/tests/web/admin/save_auth.py
T
xst 18890c0437 refactor(tests): restructure into layered POM architecture with Allure reporting
- Split framework into core/ (config, logger, db, driver factories, screenshot,
  allure integration) and pages/ (PO layer: base/admin/driver); flatten test
  files per platform (web/admin, app/driver_android, cross_end)
- Slim root conftest.py 656 -> ~100 lines: drop inline CN HTML report, add
  Allure severity mapping (p0/p1/p2 -> blocker/normal/minor) and
  environment.properties; support both tests.*-prefixed and bare imports
- Preserve TC-D2S-001/002 cross-end E2E cases with business logic unchanged,
  add allure epic/feature/story/step annotations
- Deduplicate: single makereport hook, shared failure-screenshot helpers,
  single SCREENSHOTS_DIR constant; deterministic auth-state role loading
- Move DB credentials from db_helper.py into test_config.yaml (database section)
- Move pytest.ini to repo root; switch reporting to allure-pytest
  (drop pytest-html/junitxml); update requirements.txt accordingly
- Delete deprecated scaffolding: test_freight_full_flow + 6 stale page
  objects, iOS/shipper empty shells, dead utils
- Fix flaky vxe-table action-row wait: wait for a visible td instead of
  hidden placeholder rows (fixed shipper-payment timeouts)
- Verified end-to-end against live env: both E2E cases pass (2 passed 3m12s);
  run artifacts (logs/screenshots/allure) included per repo convention
2026-08-17 14:29:52 +08:00

149 lines
5.1 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.
#!/usr/bin/env python3
"""手动登录并保存浏览器登录态(cookies + localStorage)。
目的: 绕过图形验证码——人工完成一次验证码登录后,
cookies + localStorage 序列化到 JSON 文件,后续用例自动复用。
用法:
python tests/web/admin/save_auth.py
流程:
1. 脚本打开浏览器到登录页
2. 自动填入账号、密码(从 tests/config/test_config.yaml 读取)
3. 你在浏览器中手动完成图形验证码并点击登录
4. 登录成功后按 Enter 键,脚本自动保存登录态
5. 后续 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.parent))
# Windows 中文控制台为 GBK 编码,emoji 等字符无法编码会导致 print 崩溃;
# 这里把所有无法编码的字符替换为 ?,保证脚本在任何终端都能运行。
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(errors="replace")
from tests.core.config_loader import load_config
from tests.core.playwright_support import fast_shutdown
# 登录页元素选择器(Elementor 全路径)。密码框带 is-error 类,仅在错误态出现时匹配,
# 因此 _fill_credentials 会先尝试这些选择器,失败再退回占位符/类型选择器。
USERNAME_SELECTOR = (
"#app > div > form > div:nth-child(2) > div "
"> div.elInput.el-input.el-input--medium > input"
)
PASSWORD_SELECTOR = (
"#app > div > form > div.el-form-item.el-tooltip.is-error.is-required.el-form-item--medium "
"> div > div.elInput.el-input.el-input--medium > input"
)
def _fill_credentials(page, account: dict) -> bool:
"""自动填写账号密码,用户名/密码独立处理,任一失败不影响另一个。"""
filled_user = False
for user_sel in (USERNAME_SELECTOR, "input[placeholder*='账号']"):
try:
page.wait_for_selector(user_sel, timeout=8000)
page.fill(user_sel, account["phone"])
filled_user = True
break
except Exception:
continue
filled_pwd = False
for pwd_sel in (PASSWORD_SELECTOR, "input[type='password']"):
try:
page.wait_for_selector(pwd_sel, timeout=5000)
page.fill(pwd_sel, account["password"])
filled_pwd = True
break
except Exception:
continue
return filled_user and filled_pwd
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["admin"]
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)
account = config.get("accounts", {}).get(args.role)
if account and _fill_credentials(page, account):
print(f"[{args.role}] 账号密码已自动填写")
else:
print(f"[{args.role}] 自动填写失败/无配置,请在浏览器中手动输入账号密码")
print(f"\n{'='*60}")
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("已取消。")
fast_shutdown(p)
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}")
# 强杀浏览器与驱动,跳过 Playwright 在本机 ~30s 的优雅关闭等待
fast_shutdown(p)
print(f"\n现在可以跑了: pytest tests/web/admin/ -m p0")
if __name__ == "__main__":
main()