- 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
55 lines
2.0 KiB
Python
55 lines
2.0 KiB
Python
"""登录页面 — Page Object。
|
|
|
|
Usage:
|
|
from tests.pages.admin.login_page import LoginPage
|
|
|
|
login_page = LoginPage(page)
|
|
login_page.login(phone="super_admin", password="***")
|
|
"""
|
|
|
|
from playwright.sync_api import Page, expect
|
|
|
|
from tests.pages.base.web_base_page import BasePage
|
|
|
|
|
|
class LoginPage(BasePage):
|
|
"""运八管理端登录页。"""
|
|
|
|
def __init__(self, page: Page):
|
|
super().__init__(page)
|
|
# ── 定位器声明 ──
|
|
self.username_input = page.get_by_placeholder("请输入用户名")
|
|
self.password_input = page.get_by_placeholder("请输入密码")
|
|
self.login_btn = page.get_by_role("button", name="登录")
|
|
self.error_tip = page.locator(".ant-form-item-explain-error")
|
|
|
|
def login(self, phone: str, password: str, expect_success: bool = True) -> None:
|
|
"""执行登录流程。
|
|
|
|
Args:
|
|
phone: 用户名/手机号
|
|
password: 密码
|
|
expect_success: True=预期成功跳转,False=预期留在登录页并有错误提示
|
|
"""
|
|
self.fill_field(self.username_input, phone)
|
|
self.fill_field(self.password_input, password)
|
|
self.click_when_ready(self.login_btn)
|
|
|
|
if expect_success:
|
|
# 等待登录成功后页面跳转(hash 路由模式)
|
|
self.page.wait_for_timeout(3000)
|
|
assert "/#/login" not in self.page.url and "/login" not in self.page.url, \
|
|
"登录失败,仍在登录页"
|
|
else:
|
|
# 预期登录失败,停留在当前页
|
|
expect(self.page).to_have_url("**/login**", timeout=5_000)
|
|
|
|
def get_error_message(self) -> str:
|
|
"""获取登录失败时的错误提示文本。"""
|
|
self.wait_visible(self.error_tip)
|
|
return self.error_tip.inner_text()
|
|
|
|
def is_on_login_page(self) -> bool:
|
|
"""检查是否仍在登录页(兼容 hash 路由)。"""
|
|
return "/login" in self.page.url or "/#/login" in self.page.url
|