7b4a54f1ce
Web 端 (storage_state): - 新增 tests/web/save_auth.py: 手动登录后保存 cookies+localStorage - conftest.py: skip_login:true 时自动加载 storage_state,跳过 UI 登录 - ensure_login fixture: 登录态有效则直接通过,过期则给出明确指引 App 端 (noReset): - conftest.py: ensure_logged_in fixture,手动登录后无需重新登录 - noReset=true 持久化登录态,未登录自动检测并给出明确引导 配置文件: - web.skip_login: true + storage_state_dir - app.skip_login: true + 手动登录说明
106 lines
4.9 KiB
Python
106 lines
4.9 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"])
|
|
# 已登录状态下不应重定向到登录页
|
|
assert "/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"])
|
|
assert "/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.getByPlaceholder("请输入用户名").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.getByPlaceholder("请输入用户名").is_visible()
|
|
assert page.getByPlaceholder("请输入密码").is_visible()
|
|
assert page.getByRole("button", name="登录").is_visible()
|
|
|
|
@pytest.mark.p1
|
|
def test_double_login_session_redirect(self, page: Page, web_config, ensure_login):
|
|
"""验证已登录用户访问 /login 页自动重定向。"""
|
|
ensure_login("super_admin")
|
|
page.goto(web_config["base_url"])
|
|
assert "/login" not in page.url
|
|
|
|
# 已登录状态再次访问 /login
|
|
page.goto(f"{web_config['base_url']}/login")
|
|
# 应被重定向到后台
|
|
assert "/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"])
|
|
assert "/login" not in page.url
|