Files
QaAutomationHub/tests/web/test_login/test_login.py
T

112 lines
5.3 KiB
Python

"""Web 登录功能测试用例。
覆盖:
- (skip_login: true) 验证预登录态有效,不经过 UI 登录页
- (skip_login: false) 完整 UI 登录流程 + 表单校验
标记:
pytest -m web # 仅执行 Web 用例
pytest -m p0 # 仅执行 P0 冒烟
pytest -m smoke # 仅执行冒烟
"""
import pytest
from playwright.sync_api import Page
pytestmark = [pytest.mark.web]
# ═══════════════════════════════════════════════════════════════════
# P0 — 冒烟测试(依赖预登录态,不触发 UI 登录)
# ═══════════════════════════════════════════════════════════════════
class TestLoginSmoke:
"""验证预登录态有效 + 后台可正常访问。"""
@pytest.mark.p0
@pytest.mark.smoke
def test_admin_access_with_saved_auth(self, page: Page, web_config, ensure_login):
"""验证加载预登录态后可直接访问管理后台,无需重新登录。"""
ensure_login("super_admin")
page.goto(web_config["base_url"])
# 等 hash 路由完成
page.wait_for_timeout(2000)
# 已登录状态下不应重定向到登录页
assert "#/login" not in page.url and "/login" not in page.url, (
f"预登录态失效!仍然重定向到登录页。请运行: python tests/web/save_auth.py"
)
@pytest.mark.p0
@pytest.mark.smoke
def test_team_leader_access_with_saved_auth(self, page: Page, web_config, ensure_login):
"""验证车队长预登录态有效。"""
ensure_login("team_leader")
page.goto(web_config["base_url"])
page.wait_for_timeout(2000)
assert "#/login" not in page.url and "/login" not in page.url
@pytest.mark.p0
@pytest.mark.smoke
def test_dashboard_loads(self, page: Page, web_config, ensure_login):
"""验证登录后首页能正常加载。"""
ensure_login("super_admin")
page.goto(web_config["base_url"])
# 页面标题应包含"运八"或类似标识
assert page.title(), "首页应显示页面标题"
# ═══════════════════════════════════════════════════════════════════
# P1 — 登录页交互(仅在 skip_login: false 时才有意义)
# ═══════════════════════════════════════════════════════════════════
class TestLoginPageDirect:
"""直接访问登录页相关用例(不依赖账号)。"""
@pytest.mark.p1
def test_login_page_accessible(self, page: Page, web_config):
"""验证登录页可直接访问并正常渲染。"""
page.goto(f"{web_config['base_url']}/#/login")
# 登录页应存在用户名输入框
assert page.get_by_placeholder("请输入用户名").is_visible()
@pytest.mark.p1
def test_login_page_elements(self, page: Page, web_config):
"""验证登录页所有关键元素存在。"""
page.goto(f"{web_config['base_url']}/#/login")
assert page.get_by_placeholder("请输入用户名").is_visible()
assert page.get_by_placeholder("请输入密码").is_visible()
assert page.get_by_role("button", name="登录").is_visible()
@pytest.mark.p1
def test_double_login_session_redirect(self, page: Page, web_config, ensure_login):
"""验证已登录用户访问登录页自动重定向。"""
ensure_login("super_admin")
page.goto(web_config["base_url"])
page.wait_for_timeout(2000)
assert "#/login" not in page.url and "/login" not in page.url
# 已登录状态再次访问登录页
page.goto(f"{web_config['base_url']}/#/login")
page.wait_for_timeout(2000)
# 应被重定向到后台
assert "#/login" not in page.url and "/login" not in page.url, (
f"已登录用户访问 /login 应被重定向,当前: {page.url}"
)
# ═══════════════════════════════════════════════════════════════════
# P2 — UI 登录流程(仅 skip_login: false 时执行,有验证码时预期跳过)
# ═══════════════════════════════════════════════════════════════════
@pytest.mark.p2
@pytest.mark.skip_login_required # 自定义 marker:仅在 skip_login: false 时生效
class TestLoginUI:
"""完整 UI 登录(需要 skip_login: false)。"""
def test_full_ui_login_super_admin(self, page: Page, web_config, ensure_login):
"""通过 UI 完成完整登录(需要手动关闭 skip_login)。"""
ensure_login("super_admin")
page.goto(web_config["base_url"])
page.wait_for_timeout(2000)
assert "#/login" not in page.url and "/login" not in page.url