751 lines
27 KiB
Python
751 lines
27 KiB
Python
"""
|
|
用户生命周期UAT测试 - 模拟真实业务场景
|
|
"""
|
|
|
|
import pytest
|
|
import time
|
|
from playwright.async_api import async_playwright, Page
|
|
from httpx import AsyncClient
|
|
|
|
from config.settings import settings
|
|
|
|
|
|
@pytest.mark.uat
|
|
@pytest.mark.user_lifecycle
|
|
class TestUserLifecycleUAT:
|
|
"""用户生命周期UAT测试"""
|
|
|
|
@pytest.fixture
|
|
async def browser(self):
|
|
"""浏览器fixture"""
|
|
async with async_playwright() as p:
|
|
browser = await p.chromium.launch(headless=True)
|
|
yield browser
|
|
await browser.close()
|
|
|
|
@pytest.fixture
|
|
async def context(self, browser):
|
|
"""浏览器上下文fixture"""
|
|
context = await browser.new_context()
|
|
yield context
|
|
await context.close()
|
|
|
|
@pytest.fixture
|
|
async def page(self, context):
|
|
"""页面fixture"""
|
|
page = await context.new_page()
|
|
page.set_default_timeout(30000)
|
|
yield page
|
|
await page.close()
|
|
|
|
@pytest.fixture
|
|
async def authenticated_client(self):
|
|
"""已认证的HTTP客户端"""
|
|
async with AsyncClient(base_url=settings.API_BASE_URL) as client:
|
|
response = await client.post(
|
|
"/api/auth/login",
|
|
json={
|
|
"username": settings.TEST_USERNAME,
|
|
"password": settings.TEST_PASSWORD
|
|
}
|
|
)
|
|
assert response.status_code == 200
|
|
token = response.json().get("token")
|
|
client.headers.update({"Authorization": f"Bearer {token}"})
|
|
yield client
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_user_registration_and_login(self, page, authenticated_client):
|
|
"""UAT: 用户注册和登录流程"""
|
|
timestamp = int(time.time() * 1000)
|
|
username = f"uat_user_{timestamp}"
|
|
email = f"uat_{timestamp}@example.com"
|
|
password = "Test123!@#"
|
|
|
|
# 步骤1: 通过API创建用户
|
|
response = await authenticated_client.post(
|
|
"/api/users",
|
|
json={
|
|
"username": username,
|
|
"password": password,
|
|
"email": email,
|
|
"phone": "13800138000",
|
|
"status": 1
|
|
}
|
|
)
|
|
assert response.status_code == 201, f"创建用户失败: {response.text}"
|
|
user_id = response.json()["id"]
|
|
|
|
try:
|
|
# 步骤2: 通过前端登录
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await page.fill('input[placeholder="请输入用户名"]', username)
|
|
await page.fill('input[placeholder="请输入密码"]', password)
|
|
await page.click('button[type="submit"]')
|
|
|
|
await page.wait_for_url("**/")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 步骤3: 验证登录成功
|
|
title = await page.title()
|
|
assert "首页" in title or "Dashboard" in title, "登录后未跳转到首页"
|
|
|
|
# 步骤4: 验证用户信息显示
|
|
user_info = await page.query_selector('.user-info')
|
|
assert user_info is not None, "用户信息元素未找到"
|
|
|
|
finally:
|
|
# 清理
|
|
await authenticated_client.delete(f"/api/users/{user_id}")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_user_profile_update(self, page, authenticated_client):
|
|
"""UAT: 用户资料更新流程"""
|
|
timestamp = int(time.time() * 1000)
|
|
username = f"uat_profile_{timestamp}"
|
|
email = f"uat_profile_{timestamp}@example.com"
|
|
|
|
# 步骤1: 创建测试用户
|
|
response = await authenticated_client.post(
|
|
"/api/users",
|
|
json={
|
|
"username": username,
|
|
"password": "Test123!@#",
|
|
"email": email,
|
|
"phone": "13800138000",
|
|
"status": 1
|
|
}
|
|
)
|
|
assert response.status_code == 201
|
|
user_id = response.json()["id"]
|
|
|
|
try:
|
|
# 步骤2: 登录
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.fill('input[placeholder="请输入用户名"]', username)
|
|
await page.fill('input[placeholder="请输入密码"]', "Test123!@#")
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_url("**/")
|
|
|
|
# 步骤3: 访问用户资料页面
|
|
await page.click('text=用户管理')
|
|
await page.wait_for_url("**/users")
|
|
|
|
# 步骤4: 编辑用户
|
|
await page.click('text=编辑')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 步骤5: 更新资料
|
|
await page.fill('input[placeholder=""]', '测试用户昵称')
|
|
await page.fill('input[placeholder=""]', '13900139000')
|
|
|
|
await page.click('button:has-text("确定")')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 步骤6: 验证更新
|
|
page_content = await page.content()
|
|
assert "测试用户昵称" in page_content
|
|
|
|
finally:
|
|
await authenticated_client.delete(f"/api/users/{user_id}")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_user_status_change(self, page, authenticated_client):
|
|
"""UAT: 用户状态变更流程"""
|
|
timestamp = int(time.time() * 1000)
|
|
username = f"uat_status_{timestamp}"
|
|
|
|
# 创建用户
|
|
response = await authenticated_client.post(
|
|
"/api/users",
|
|
json={
|
|
"username": username,
|
|
"password": "Test123!@#",
|
|
"email": f"uat_status_{timestamp}@example.com",
|
|
"status": 1
|
|
}
|
|
)
|
|
assert response.status_code == 201
|
|
user_id = response.json()["id"]
|
|
|
|
try:
|
|
# 登录并禁用用户
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.fill('input[placeholder="请输入用户名"]', username)
|
|
await page.fill('input[placeholder="请输入密码"]', "Test123!@#")
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_url("**/")
|
|
|
|
# 尝试禁用用户
|
|
await page.click('text=用户管理')
|
|
await page.wait_for_url("**/users")
|
|
|
|
# 禁用用户
|
|
await page.click('button:has-text("禁用")')
|
|
await page.click('button:has-text("确定")')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 验证状态变更
|
|
page_content = await page.content()
|
|
assert "禁用" in page_content
|
|
|
|
finally:
|
|
await authenticated_client.delete(f"/api/users/{user_id}")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_user_delete(self, page, authenticated_client):
|
|
"""UAT: 用户删除流程"""
|
|
timestamp = int(time.time() * 1000)
|
|
username = f"uat_delete_{timestamp}"
|
|
|
|
# 创建用户
|
|
response = await authenticated_client.post(
|
|
"/api/users",
|
|
json={
|
|
"username": username,
|
|
"password": "Test123!@#",
|
|
"email": f"uat_delete_{timestamp}@example.com",
|
|
"status": 1
|
|
}
|
|
)
|
|
assert response.status_code == 201
|
|
user_id = response.json()["id"]
|
|
|
|
# 登录并删除用户
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.fill('input[placeholder="请输入用户名"]', username)
|
|
await page.fill('input[placeholder="请输入密码"]', "Test123!@#")
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_url("**/")
|
|
|
|
await page.click('text=用户管理')
|
|
await page.wait_for_url("**/users")
|
|
|
|
await page.click('button:has-text("删除")')
|
|
await page.click('button:has-text("确定")')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 验证删除
|
|
page_content = await page.content()
|
|
assert username not in page_content
|
|
|
|
|
|
@pytest.mark.uat
|
|
@pytest.mark.role_workflow
|
|
class TestRoleWorkflowUAT:
|
|
"""角色工作流UAT测试"""
|
|
|
|
@pytest.fixture
|
|
async def browser(self):
|
|
async with async_playwright() as p:
|
|
browser = await p.chromium.launch(headless=True)
|
|
yield browser
|
|
await browser.close()
|
|
|
|
@pytest.fixture
|
|
async def context(self, browser):
|
|
context = await browser.new_context()
|
|
yield context
|
|
await context.close()
|
|
|
|
@pytest.fixture
|
|
async def page(self, context):
|
|
page = await context.new_page()
|
|
page.set_default_timeout(30000)
|
|
yield page
|
|
await page.close()
|
|
|
|
@pytest.fixture
|
|
async def authenticated_client(self):
|
|
async with AsyncClient(base_url=settings.API_BASE_URL) as client:
|
|
response = await client.post(
|
|
"/api/auth/login",
|
|
json={
|
|
"username": settings.TEST_USERNAME,
|
|
"password": settings.TEST_PASSWORD
|
|
}
|
|
)
|
|
assert response.status_code == 200
|
|
token = response.json().get("token")
|
|
client.headers.update({"Authorization": f"Bearer {token}"})
|
|
yield client
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_role_assignment(self, page, authenticated_client):
|
|
"""UAT: 角色分配流程"""
|
|
timestamp = int(time.time() * 1000)
|
|
username = f"uat_role_user_{timestamp}"
|
|
role_name = f"UAT_Role_{timestamp}"
|
|
|
|
# 创建角色
|
|
role_response = await authenticated_client.post(
|
|
"/api/roles",
|
|
json={
|
|
"roleName": role_name,
|
|
"roleKey": f"uat_role_{timestamp}",
|
|
"roleSort": 1,
|
|
"status": 1
|
|
}
|
|
)
|
|
assert role_response.status_code == 201
|
|
role_id = role_response.json()["id"]
|
|
|
|
try:
|
|
# 创建用户
|
|
user_response = await authenticated_client.post(
|
|
"/api/users",
|
|
json={
|
|
"username": username,
|
|
"password": "Test123!@#",
|
|
"email": f"uat_role_user_{timestamp}@example.com",
|
|
"status": 1
|
|
}
|
|
)
|
|
assert user_response.status_code == 201
|
|
user_id = user_response.json()["id"]
|
|
|
|
# 登录并分配角色
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.fill('input[placeholder="请输入用户名"]', username)
|
|
await page.fill('input[placeholder="请输入密码"]', "Test123!@#")
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_url("**/")
|
|
|
|
await page.click('text=用户管理')
|
|
await page.wait_for_url("**/users")
|
|
|
|
# 分配角色
|
|
await page.click('text=分配角色')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 选择角色
|
|
await page.click(f'text={role_name}')
|
|
|
|
await page.click('button:has-text("确定")')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 验证角色分配
|
|
user_info = await authenticated_client.get(f"/api/users/{user_id}")
|
|
assert user_info.status_code == 200
|
|
user_data = user_info.json()
|
|
assert user_data["roleId"] == role_id
|
|
|
|
finally:
|
|
await authenticated_client.delete(f"/api/users/{user_id}")
|
|
await authenticated_client.delete(f"/api/roles/{role_id}")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_role_permission_management(self, page, authenticated_client):
|
|
"""UAT: 角色权限管理流程"""
|
|
timestamp = int(time.time() * 1000)
|
|
role_name = f"UAT_Permission_Role_{timestamp}"
|
|
|
|
# 创建角色
|
|
role_response = await authenticated_client.post(
|
|
"/api/roles",
|
|
json={
|
|
"roleName": role_name,
|
|
"roleKey": f"uat_perm_role_{timestamp}",
|
|
"roleSort": 1,
|
|
"status": 1
|
|
}
|
|
)
|
|
assert role_response.status_code == 201
|
|
role_id = role_response.json()["id"]
|
|
|
|
try:
|
|
# 登录并访问角色管理
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.fill('input[placeholder="请输入用户名"]', settings.TEST_USERNAME)
|
|
await page.fill('input[placeholder="请输入密码"]', settings.TEST_PASSWORD)
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_url("**/")
|
|
|
|
await page.click('text=角色管理')
|
|
await page.wait_for_url("**/roles")
|
|
|
|
# 编辑角色权限
|
|
await page.click('text=编辑')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 更新角色信息
|
|
await page.fill('input[placeholder=""]', f"{role_name}_updated")
|
|
|
|
await page.click('button:has-text("确定")')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 验证更新
|
|
roles_response = await authenticated_client.get("/api/roles")
|
|
roles = roles_response.json()
|
|
role_exists = any(r['roleName'] == f"{role_name}_updated" for r in roles)
|
|
assert role_exists
|
|
|
|
finally:
|
|
await authenticated_client.delete(f"/api/roles/{role_id}")
|
|
|
|
|
|
@pytest.mark.uat
|
|
@pytest.mark.config_workflow
|
|
class TestConfigWorkflowUAT:
|
|
"""配置工作流UAT测试"""
|
|
|
|
@pytest.fixture
|
|
async def browser(self):
|
|
async with async_playwright() as p:
|
|
browser = await p.chromium.launch(headless=True)
|
|
yield browser
|
|
await browser.close()
|
|
|
|
@pytest.fixture
|
|
async def context(self, browser):
|
|
context = await browser.new_context()
|
|
yield context
|
|
await context.close()
|
|
|
|
@pytest.fixture
|
|
async def page(self, context):
|
|
page = await context.new_page()
|
|
page.set_default_timeout(30000)
|
|
yield page
|
|
await page.close()
|
|
|
|
@pytest.fixture
|
|
async def authenticated_client(self):
|
|
async with AsyncClient(base_url=settings.API_BASE_URL) as client:
|
|
response = await client.post(
|
|
"/api/auth/login",
|
|
json={
|
|
"username": settings.TEST_USERNAME,
|
|
"password": settings.TEST_PASSWORD
|
|
}
|
|
)
|
|
assert response.status_code == 200
|
|
token = response.json().get("token")
|
|
client.headers.update({"Authorization": f"Bearer {token}"})
|
|
yield client
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_system_config_update(self, page, authenticated_client):
|
|
"""UAT: 系统配置更新流程"""
|
|
timestamp = int(time.time() * 1000)
|
|
|
|
# 登录并访问系统配置
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.fill('input[placeholder="请输入用户名"]', settings.TEST_USERNAME)
|
|
await page.fill('input[placeholder="请输入密码"]', settings.TEST_PASSWORD)
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_url("**/")
|
|
|
|
await page.click('text=系统配置')
|
|
await page.wait_for_url("**/config")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 编辑配置
|
|
await page.click('text=编辑')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 更新配置
|
|
await page.fill('input[placeholder=""]', f"Test_Config_{timestamp}")
|
|
await page.fill('textarea[placeholder=""]', '测试配置内容')
|
|
|
|
await page.click('button:has-text("确定")')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 验证更新
|
|
config_response = await authenticated_client.get("/api/config")
|
|
assert config_response.status_code == 200
|
|
|
|
|
|
@pytest.mark.uat
|
|
@pytest.mark.data_dict_workflow
|
|
class TestDataDictWorkflowUAT:
|
|
"""数据字典工作流UAT测试"""
|
|
|
|
@pytest.fixture
|
|
async def browser(self):
|
|
async with async_playwright() as p:
|
|
browser = await p.chromium.launch(headless=True)
|
|
yield browser
|
|
await browser.close()
|
|
|
|
@pytest.fixture
|
|
async def context(self, browser):
|
|
context = await browser.new_context()
|
|
yield context
|
|
await context.close()
|
|
|
|
@pytest.fixture
|
|
async def page(self, context):
|
|
page = await context.new_page()
|
|
page.set_default_timeout(30000)
|
|
yield page
|
|
await page.close()
|
|
|
|
@pytest.fixture
|
|
async def authenticated_client(self):
|
|
async with AsyncClient(base_url=settings.API_BASE_URL) as client:
|
|
response = await client.post(
|
|
"/api/auth/login",
|
|
json={
|
|
"username": settings.TEST_USERNAME,
|
|
"password": settings.TEST_PASSWORD
|
|
}
|
|
)
|
|
assert response.status_code == 200
|
|
token = response.json().get("token")
|
|
client.headers.update({"Authorization": f"Bearer {token}"})
|
|
yield client
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_dict_type_management(self, page, authenticated_client):
|
|
"""UAT: 字典类型管理流程"""
|
|
timestamp = int(time.time() * 1000)
|
|
dict_type = f"UAT_DICT_{timestamp}"
|
|
|
|
# 登录并访问字典管理
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.fill('input[placeholder="请输入用户名"]', settings.TEST_USERNAME)
|
|
await page.fill('input[placeholder="请输入密码"]', settings.TEST_PASSWORD)
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_url("**/")
|
|
|
|
await page.click('text=字典管理')
|
|
await page.wait_for_url("**/dicts")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 创建字典类型
|
|
await page.click('text=新增字典')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await page.fill('input[placeholder=""]', dict_type)
|
|
await page.fill('input[placeholder=""]', f"uat_dict_{timestamp}")
|
|
await page.fill('textarea[placeholder=""]', '测试字典类型')
|
|
|
|
await page.click('button:has-text("确定")')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 验证创建
|
|
dicts_response = await authenticated_client.get("/api/dict/types")
|
|
assert dicts_response.status_code == 200
|
|
dicts = dicts_response.json()
|
|
dict_exists = any(d['type'] == dict_type for d in dicts)
|
|
assert dict_exists
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_dict_data_management(self, page, authenticated_client):
|
|
"""UAT: 字典数据管理流程"""
|
|
timestamp = int(time.time() * 1000)
|
|
|
|
# 登录并访问字典管理
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.fill('input[placeholder="请输入用户名"]', settings.TEST_USERNAME)
|
|
await page.fill('input[placeholder="请输入密码"]', settings.TEST_PASSWORD)
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_url("**/")
|
|
|
|
await page.click('text=字典管理')
|
|
await page.wait_for_url("**/dicts")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 查看字典数据
|
|
await page.click('text=查看')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 验证字典数据列表
|
|
page_content = await page.content()
|
|
assert "字典数据" in page_content or "code" in page_content.lower()
|
|
|
|
|
|
@pytest.mark.uat
|
|
@pytest.mark.audit_workflow
|
|
class TestAuditWorkflowUAT:
|
|
"""审计工作流UAT测试"""
|
|
|
|
@pytest.fixture
|
|
async def browser(self):
|
|
async with async_playwright() as p:
|
|
browser = await p.chromium.launch(headless=True)
|
|
yield browser
|
|
await browser.close()
|
|
|
|
@pytest.fixture
|
|
async def context(self, browser):
|
|
context = await browser.new_context()
|
|
yield context
|
|
await context.close()
|
|
|
|
@pytest.fixture
|
|
async def page(self, context):
|
|
page = await context.new_page()
|
|
page.set_default_timeout(30000)
|
|
yield page
|
|
await page.close()
|
|
|
|
@pytest.fixture
|
|
async def authenticated_client(self):
|
|
async with AsyncClient(base_url=settings.API_BASE_URL) as client:
|
|
response = await client.post(
|
|
"/api/auth/login",
|
|
json={
|
|
"username": settings.TEST_USERNAME,
|
|
"password": settings.TEST_PASSWORD
|
|
}
|
|
)
|
|
assert response.status_code == 200
|
|
token = response.json().get("token")
|
|
client.headers.update({"Authorization": f"Bearer {token}"})
|
|
yield client
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_operation_log_audit(self, page, authenticated_client):
|
|
"""UAT: 操作日志审计流程"""
|
|
timestamp = int(time.time() * 1000)
|
|
|
|
# 登录并访问操作日志
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.fill('input[placeholder="请输入用户名"]', settings.TEST_USERNAME)
|
|
await page.fill('input[placeholder="请输入密码"]', settings.TEST_PASSWORD)
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_url("**/")
|
|
|
|
await page.click('text=操作日志')
|
|
await page.wait_for_url("**/operation-logs")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 验证操作日志列表
|
|
await page.wait_for_selector('.el-card', timeout=10000)
|
|
|
|
# 通过API验证
|
|
logs_response = await authenticated_client.get("/api/audit/operation-logs")
|
|
assert logs_response.status_code == 200
|
|
logs = logs_response.json()
|
|
assert len(logs) > 0, "操作日志为空"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_login_log_audit(self, page, authenticated_client):
|
|
"""UAT: 登录日志审计流程"""
|
|
# 登录并访问登录日志
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.fill('input[placeholder="请输入用户名"]', settings.TEST_USERNAME)
|
|
await page.fill('input[placeholder="请输入密码"]', settings.TEST_PASSWORD)
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_url("**/")
|
|
|
|
await page.click('text=登录日志')
|
|
await page.wait_for_url("**/login-logs")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
# 验证登录日志列表
|
|
await page.wait_for_selector('.el-card', timeout=10000)
|
|
|
|
# 通过API验证
|
|
login_logs_response = await authenticated_client.get("/api/audit/login-logs")
|
|
assert login_logs_response.status_code == 200
|
|
login_logs = login_logs_response.json()
|
|
assert len(login_logs) > 0, "登录日志为空"
|
|
|
|
|
|
@pytest.mark.uat
|
|
@pytest.mark.comprehensive_workflow
|
|
class TestComprehensiveWorkflowUAT:
|
|
"""综合业务流程UAT测试"""
|
|
|
|
@pytest.fixture
|
|
async def browser(self):
|
|
async with async_playwright() as p:
|
|
browser = await p.chromium.launch(headless=True)
|
|
yield browser
|
|
await browser.close()
|
|
|
|
@pytest.fixture
|
|
async def context(self, browser):
|
|
context = await browser.new_context()
|
|
yield context
|
|
await context.close()
|
|
|
|
@pytest.fixture
|
|
async def page(self, context):
|
|
page = await context.new_page()
|
|
page.set_default_timeout(30000)
|
|
yield page
|
|
await page.close()
|
|
|
|
@pytest.fixture
|
|
async def authenticated_client(self):
|
|
async with AsyncClient(base_url=settings.API_BASE_URL) as client:
|
|
response = await client.post(
|
|
"/api/auth/login",
|
|
json={
|
|
"username": settings.TEST_USERNAME,
|
|
"password": settings.TEST_PASSWORD
|
|
}
|
|
)
|
|
assert response.status_code == 200
|
|
token = response.json().get("token")
|
|
client.headers.update({"Authorization": f"Bearer {token}"})
|
|
yield client
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uat_complete_business_workflow(self, page, authenticated_client):
|
|
"""UAT: 完整业务流程测试"""
|
|
timestamp = int(time.time() * 1000)
|
|
|
|
# 步骤1: 用户注册
|
|
username = f"uat_complete_{timestamp}"
|
|
response = await authenticated_client.post(
|
|
"/api/users",
|
|
json={
|
|
"username": username,
|
|
"password": "Test123!@#",
|
|
"email": f"uat_complete_{timestamp}@example.com",
|
|
"phone": "13800138000",
|
|
"status": 1
|
|
}
|
|
)
|
|
assert response.status_code == 201
|
|
user_id = response.json()["id"]
|
|
|
|
try:
|
|
# 步骤2: 用户登录
|
|
await page.goto("http://localhost:3002/login")
|
|
await page.fill('input[placeholder="请输入用户名"]', username)
|
|
await page.fill('input[placeholder="请输入密码"]', "Test123!@#")
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_url("**/")
|
|
|
|
# 步骤3: 浏览用户管理
|
|
await page.click('text=用户管理')
|
|
await page.wait_for_url("**/users")
|
|
|
|
# 步骤4: 浏览角色管理
|
|
await page.click('text=角色管理')
|
|
await page.wait_for_url("**/roles")
|
|
|
|
# 步骤5: 浏览系统配置
|
|
await page.click('text=系统配置')
|
|
await page.wait_for_url("**/config")
|
|
|
|
# 步骤6: 浏览字典管理
|
|
await page.click('text=字典管理')
|
|
await page.wait_for_url("**/dicts")
|
|
|
|
# 步骤7: 浏览通知管理
|
|
await page.click('text=通知管理')
|
|
await page.wait_for_url("**/notices")
|
|
|
|
# 步骤8: 浏览文件管理
|
|
await page.click('text=文件管理')
|
|
await page.wait_for_url("**/files")
|
|
|
|
# 步骤9: 浏览审计日志
|
|
await page.click('text=操作日志')
|
|
await page.wait_for_url("**/operation-logs")
|
|
|
|
# 步骤10: 登出
|
|
await page.click('text=退出登录')
|
|
await page.wait_for_url("**/login")
|
|
|
|
finally:
|
|
await authenticated_client.delete(f"/api/users/{user_id}") |