Files
ShiErFeng/shierfeng-fastapi-test/system/test_dict_management.py
T
2026-07-24 09:43:10 +08:00

202 lines
8.0 KiB
Python

from datetime import datetime
import pytest
from playwright.async_api import async_playwright
from common.base_page_test import BasePageTest
from common.config import Config
class DictManagementTest(BasePageTest):
"""字典管理测试类"""
def generate_dict_data(self) -> dict:
"""生成测试数据"""
timestamp = datetime.now().strftime('%H%M%S')
return {
'dict_name': f'测试字典_{timestamp}',
'dict_type': f'test_dict_{timestamp}',
'dict_data_label_1': '正常',
'dict_data_value_1': '1',
'dict_data_label_2': '异常',
'dict_data_value_2': '2',
'remark': f'备注_{timestamp}',
}
async def create_dict_type(self, dict_name: str, dict_type: str) -> None:
"""创建字典类型"""
# 点击新增按钮
await self.page.get_by_role('button', name='新增').first.click()
# 等待对话框
dialog = self.page.get_by_role('dialog')
await dialog.wait_for()
# 填写表单
await dialog.get_by_role('textbox', name='字典名称').fill(dict_name)
await dialog.get_by_role('textbox', name='字典类型').fill(dict_type)
# 提交
await dialog.get_by_role('button', name='确 定').click()
# 验证成功
await self.wait_for_selector("div:has-text('新增成功')", timeout=10000)
async def search_dict_type(self, dict_name: str, dict_type: str) -> None:
"""搜索字典类型"""
form = self.page.locator('form').first
await form.get_by_role('textbox', name='字典名称').fill(dict_name)
await form.get_by_role('textbox', name='字典类型').fill(dict_type)
# 点击搜索按钮
await self.page.get_by_role('button', name='搜索').click()
await self.page.wait_for_timeout(1000)
async def edit_dict_type(self, dict_name: str, remark: str) -> None:
"""修改字典类型"""
await self.search_dict_type(dict_name, '')
# 点击修改按钮
row = self.page.locator('tbody tr').first
await row.get_by_role('button', name='修改').click()
dialog = self.page.get_by_role('dialog')
await dialog.wait_for()
await dialog.get_by_role('textbox', name='备注').fill(remark)
await dialog.get_by_role('button', name='确 定').click()
await self.wait_for_selector("div:has-text('修改成功')", timeout=10000)
async def manage_dict_data(self, dict_type: str, data: dict) -> None:
"""管理字典数据"""
# 1. 进入字典数据页面
# 点击字典类型链接
row = self.page.locator('tbody tr').first
await row.get_by_role('link', name=dict_type).click()
# 等待页面切换(Playwright在SPA中通常不需要处理多标签页,除非新开tab)
# 这里是 router-link,应该是页内跳转
# 检查是否到了字典数据页面
# 或者等待URL变化,或者等待特定元素
# data.vue 有 "关闭" 按钮
await self.wait_for_selector("button:has-text('关闭')", timeout=5000)
# 2. 新增数据1 (正常)
await self.create_dict_data(data['dict_data_label_1'], data['dict_data_value_1'], '1', '主要(primary)')
# 3. 新增数据2 (异常)
await self.create_dict_data(data['dict_data_label_2'], data['dict_data_value_2'], '2', '危险(danger)')
# 4. 修改数据
await self.edit_dict_data(data['dict_data_label_2'], '测试备注')
# 5. 删除数据
await self.delete_dict_data(data['dict_data_label_2'])
await self.delete_dict_data(data['dict_data_label_1'])
# 6. 关闭页面 (返回字典类型)
await self.page.get_by_role('button', name='关闭', exact=True).click()
# 等待返回
await self.wait_for_selector('text=字典名称') # 假设返回后能看到原来的页面元素
async def create_dict_data(self, label: str, value: str, sort: str, list_class: str) -> None:
"""创建字典数据"""
# 点击新增按钮
await self.page.get_by_role('button', name='新增').first.click()
dialog = self.page.get_by_role('dialog')
await dialog.wait_for()
await dialog.get_by_role('textbox', name='数据标签').fill(label)
await dialog.get_by_role('textbox', name='数据键值').fill(value)
await dialog.get_by_role('spinbutton', name='显示排序').fill(sort)
# 选择回显样式
# 点击下拉框触发器
# el-select 的结构通常是 wrapper -> input (readonly)
# 我们可以点击 label 为 "回显样式" 的 form-item 下的 select
select_trigger = dialog.locator("label:has-text('回显样式') + div .el-select")
if await select_trigger.count() == 0:
# 尝试直接找 .el-select,可能布局不同
select_trigger = dialog.locator('.el-select').filter(has_text='默认(default)').first
# 如果还是找不到,尝试点击那个默认值文本
if await select_trigger.count() == 0:
await dialog.get_by_text('默认(default)').click()
else:
await select_trigger.click()
# 选择选项 (选项在 body 的 el-popper 中)
# 等待选项出现
await self.page.get_by_role('option', name=list_class).click()
await dialog.get_by_role('button', name='确 定').click()
await self.wait_for_selector("div:has-text('新增成功')", timeout=10000)
async def edit_dict_data(self, label: str, remark: str) -> None:
"""修改字典数据"""
# 点击修改按钮
row = self.page.locator('tbody tr').filter(has_text=label).first
await row.get_by_role('button', name='修改').click()
dialog = self.page.get_by_role('dialog')
await dialog.wait_for()
await dialog.get_by_role('textbox', name='备注').fill(remark)
await dialog.get_by_role('button', name='确 定').click()
await self.wait_for_selector("div:has-text('修改成功')", timeout=10000)
async def delete_dict_data(self, label: str) -> None:
"""删除字典数据"""
# 点击删除按钮
row = self.page.locator('tbody tr').filter(has_text=label).first
await row.get_by_role('button', name='删除').click()
await self.page.get_by_role('button', name='确定').click()
await self.wait_for_selector("div:has-text('删除成功')", timeout=10000)
async def delete_dict_type(self, dict_name: str) -> None:
"""删除字典类型"""
await self.search_dict_type(dict_name, '')
# 点击删除按钮
row = self.page.locator('tbody tr').filter(has_text=dict_name).first
await row.get_by_role('button', name='删除').click()
await self.page.get_by_role('button', name='确定').click()
await self.wait_for_selector("div:has-text('删除成功')", timeout=10000)
async def test_dict_crud_operations(self) -> None:
"""测试字典管理全流程"""
data = self.generate_dict_data()
# 1. 进入字典管理
await self.goto_page(Config.frontend_url + '/system/dict')
# 等待页面加载
await self.wait_for_selector('text=字典名称') # 页面标题或其他标识
# 2. 创建字典类型
await self.create_dict_type(data['dict_name'], data['dict_type'])
# 3. 搜索并修改
await self.edit_dict_type(data['dict_name'], data['remark'])
# 4. 管理字典数据
await self.manage_dict_data(data['dict_type'], data)
# 5. 删除字典类型
await self.delete_dict_type(data['dict_name'])
@pytest.mark.asyncio
async def test_dict_management_page() -> None:
"""测试字典管理页面功能"""
async with async_playwright() as p:
test_instance = DictManagementTest()
await test_instance.setup(p)
try:
await test_instance.test_dict_crud_operations()
finally:
await test_instance.teardown()