e8f51309e5
- 更新 Page Object 模型适配新字段名 - 新增 UAT 测试套件与 journey 测试用例 - 优化测试辅助工具与数据工厂 - 更新 playwright 认证状态
222 lines
7.1 KiB
TypeScript
222 lines
7.1 KiB
TypeScript
import { Page } from '@playwright/test';
|
|
|
|
export class TestDataCleanup {
|
|
readonly page: Page;
|
|
private createdUsers: string[] = [];
|
|
private createdRoles: string[] = [];
|
|
private createdMenus: string[] = [];
|
|
private createdDictTypes: string[] = [];
|
|
private createdDictData: string[] = [];
|
|
|
|
constructor(page: Page) {
|
|
this.page = page;
|
|
}
|
|
|
|
trackUser(username: string) {
|
|
this.createdUsers.push(username);
|
|
}
|
|
|
|
trackRole(roleName: string) {
|
|
this.createdRoles.push(roleName);
|
|
}
|
|
|
|
trackMenu(menuName: string) {
|
|
this.createdMenus.push(menuName);
|
|
}
|
|
|
|
trackDictType(dictType: string) {
|
|
this.createdDictTypes.push(dictType);
|
|
}
|
|
|
|
trackDictData(dictData: string) {
|
|
this.createdDictData.push(dictData);
|
|
}
|
|
|
|
async cleanupAll() {
|
|
await this.cleanupUsers();
|
|
await this.cleanupRoles();
|
|
await this.cleanupMenus();
|
|
await this.cleanupDictTypes();
|
|
await this.cleanupDictData();
|
|
}
|
|
|
|
async cleanupUsers() {
|
|
for (const username of this.createdUsers) {
|
|
try {
|
|
await this.deleteUser(username);
|
|
} catch (error) {
|
|
console.warn(`Failed to delete user ${username}:`, error);
|
|
}
|
|
}
|
|
this.createdUsers = [];
|
|
}
|
|
|
|
async cleanupRoles() {
|
|
for (const roleName of this.createdRoles) {
|
|
try {
|
|
await this.deleteRole(roleName);
|
|
} catch (error) {
|
|
console.warn(`Failed to delete role ${roleName}:`, error);
|
|
}
|
|
}
|
|
this.createdRoles = [];
|
|
}
|
|
|
|
async cleanupMenus() {
|
|
for (const menuName of this.createdMenus) {
|
|
try {
|
|
await this.deleteMenu(menuName);
|
|
} catch (error) {
|
|
console.warn(`Failed to delete menu ${menuName}:`, error);
|
|
}
|
|
}
|
|
this.createdMenus = [];
|
|
}
|
|
|
|
async cleanupDictTypes() {
|
|
for (const dictType of this.createdDictTypes) {
|
|
try {
|
|
await this.deleteDictType(dictType);
|
|
} catch (error) {
|
|
console.warn(`Failed to delete dict type ${dictType}:`, error);
|
|
}
|
|
}
|
|
this.createdDictTypes = [];
|
|
}
|
|
|
|
async cleanupDictData() {
|
|
for (const dictData of this.createdDictData) {
|
|
try {
|
|
await this.deleteDictData(dictData);
|
|
} catch (error) {
|
|
console.warn(`Failed to delete dict data ${dictData}:`, error);
|
|
}
|
|
}
|
|
this.createdDictData = [];
|
|
}
|
|
|
|
private async deleteUser(username: string) {
|
|
try {
|
|
await this.page.goto('/users');
|
|
await this.page.waitForLoadState('networkidle', { timeout: 10000 });
|
|
|
|
const searchInput = this.page.locator('input[placeholder*="搜索"], input[name*="keyword"], .ant-input__inner').first();
|
|
await searchInput.fill(username);
|
|
|
|
const searchButton = this.page.getByRole('button', { name: '搜索' }).or(this.page.locator('button:has-text("搜索")'));
|
|
await searchButton.click();
|
|
await this.page.waitForTimeout(2000);
|
|
|
|
const userRow = this.page.locator('tbody tr').filter({ hasText: username });
|
|
const rowCount = await userRow.count();
|
|
|
|
if (rowCount > 0) {
|
|
const deleteButton = userRow.locator('.delete-button, .ant-btn--danger').first();
|
|
await deleteButton.click();
|
|
await this.page.waitForTimeout(500);
|
|
|
|
const confirmButton = this.page.getByRole('button', { name: '确定' }).or(this.page.locator('.ant-btn--primary:has-text("确定")'));
|
|
await confirmButton.click();
|
|
await this.page.waitForTimeout(1500);
|
|
}
|
|
} catch (error) {
|
|
console.warn(`Failed to delete user ${username}:`, error);
|
|
}
|
|
}
|
|
|
|
private async deleteRole(roleName: string) {
|
|
try {
|
|
await this.page.goto('/roles');
|
|
await this.page.waitForLoadState('networkidle', { timeout: 10000 });
|
|
|
|
const searchInput = this.page.locator('input[placeholder*="搜索"], input[name*="keyword"], .ant-input__inner').first();
|
|
await searchInput.fill(roleName);
|
|
|
|
const searchButton = this.page.getByRole('button', { name: '搜索' }).or(this.page.locator('button:has-text("搜索")'));
|
|
await searchButton.click();
|
|
await this.page.waitForTimeout(2000);
|
|
|
|
const roleRow = this.page.locator('tbody tr').filter({ hasText: roleName });
|
|
const rowCount = await roleRow.count();
|
|
|
|
if (rowCount > 0) {
|
|
const deleteButton = roleRow.locator('.delete-button, .ant-btn--danger').first();
|
|
await deleteButton.click();
|
|
await this.page.waitForTimeout(500);
|
|
|
|
const confirmButton = this.page.getByRole('button', { name: '确定' }).or(this.page.locator('.ant-btn--primary:has-text("确定")'));
|
|
await confirmButton.click();
|
|
await this.page.waitForTimeout(1500);
|
|
}
|
|
} catch (error) {
|
|
console.warn(`Failed to delete role ${roleName}:`, error);
|
|
}
|
|
}
|
|
|
|
private async deleteMenu(menuName: string) {
|
|
try {
|
|
await this.page.goto('/menus');
|
|
await this.page.waitForLoadState('networkidle', { timeout: 10000 });
|
|
|
|
const menuRow = this.page.locator('tbody tr').filter({ hasText: menuName });
|
|
const rowCount = await menuRow.count();
|
|
|
|
if (rowCount > 0) {
|
|
const deleteButton = menuRow.locator('.delete-button, .ant-btn--danger').first();
|
|
await deleteButton.click();
|
|
await this.page.waitForTimeout(500);
|
|
|
|
const confirmButton = this.page.getByRole('button', { name: '确定' }).or(this.page.locator('.ant-btn--primary:has-text("确定")'));
|
|
await confirmButton.click();
|
|
await this.page.waitForTimeout(1500);
|
|
}
|
|
} catch (error) {
|
|
console.warn(`Failed to delete menu ${menuName}:`, error);
|
|
}
|
|
}
|
|
|
|
private async deleteDictType(dictType: string) {
|
|
try {
|
|
await this.page.goto('/dict');
|
|
await this.page.waitForLoadState('networkidle', { timeout: 10000 });
|
|
|
|
const dictRow = this.page.locator('.dict-type-table tbody tr').filter({ hasText: dictType });
|
|
const rowCount = await dictRow.count();
|
|
|
|
if (rowCount > 0) {
|
|
const deleteButton = dictRow.locator('.delete-button, .ant-btn--danger').first();
|
|
await deleteButton.click();
|
|
await this.page.waitForTimeout(500);
|
|
|
|
const confirmButton = this.page.getByRole('button', { name: '确定' }).or(this.page.locator('.ant-btn--primary:has-text("确定")'));
|
|
await confirmButton.click();
|
|
await this.page.waitForTimeout(1500);
|
|
}
|
|
} catch (error) {
|
|
console.warn(`Failed to delete dict type ${dictType}:`, error);
|
|
}
|
|
}
|
|
|
|
private async deleteDictData(dictData: string) {
|
|
try {
|
|
await this.page.goto('/dict');
|
|
await this.page.waitForLoadState('networkidle', { timeout: 10000 });
|
|
|
|
const dictRow = this.page.locator('.dict-data-table tbody tr').filter({ hasText: dictData });
|
|
const rowCount = await dictRow.count();
|
|
|
|
if (rowCount > 0) {
|
|
const deleteButton = dictRow.locator('.delete-button, .ant-btn--danger').first();
|
|
await deleteButton.click();
|
|
await this.page.waitForTimeout(500);
|
|
|
|
const confirmButton = this.page.getByRole('button', { name: '确定' }).or(this.page.locator('.ant-btn--primary:has-text("确定")'));
|
|
await confirmButton.click();
|
|
await this.page.waitForTimeout(1500);
|
|
}
|
|
} catch (error) {
|
|
console.warn(`Failed to delete dict data ${dictData}:`, error);
|
|
}
|
|
}
|
|
}
|