import { Page, Locator } from '@playwright/test'; export class MenuManagementPage { readonly page: Page; readonly table: Locator; readonly createMenuButton: Locator; readonly searchInput: Locator; readonly searchButton: Locator; readonly successMessage: Locator; readonly treeContainer: Locator; readonly expandAllButton: Locator; readonly collapseAllButton: Locator; constructor(page: Page) { this.page = page; this.table = page.locator('.el-table').or(page.locator('.menu-table')); this.createMenuButton = page.getByRole('button', { name: '新增菜单' }).or(page.locator('button:has-text("新增菜单")')); this.searchInput = page.locator('input[placeholder*="搜索"]').or(page.locator('input[name*="keyword"]')); this.searchButton = page.getByRole('button', { name: '搜索' }).or(page.locator('button:has-text("搜索")')); this.successMessage = page.locator('.el-message--success').or(page.locator('.success-message')); this.treeContainer = page.locator('.el-tree').or(page.locator('.menu-tree')); this.expandAllButton = page.getByRole('button', { name: '展开全部' }).or(page.locator('button:has-text("展开全部")')); this.collapseAllButton = page.getByRole('button', { name: '折叠全部' }).or(page.locator('button:has-text("折叠全部")')); } async goto() { await this.page.goto('/menus'); await this.page.waitForLoadState('networkidle'); } async clickCreateMenu() { await this.createMenuButton.click(); await this.page.waitForTimeout(500); } async fillMenuForm(menuData: { menuName: string; menuType?: string; path?: string; component?: string; permission?: string; sort?: number; visible?: string; status?: string; }) { const dialog = this.page.locator('.el-dialog'); await dialog.locator('input').first().fill(menuData.menuName); if (menuData.menuType) { const menuTypeSelect = dialog.locator('.el-select').first(); await menuTypeSelect.click(); await this.page.waitForTimeout(300); await this.page.getByRole('option', { name: menuData.menuType }).click(); } if (menuData.path) { const pathInput = dialog.locator('input[placeholder*="路径"]'); if (await pathInput.count() > 0) { await pathInput.fill(menuData.path); } } if (menuData.component) { const componentInput = dialog.locator('input[placeholder*="组件"]'); if (await componentInput.count() > 0) { await componentInput.fill(menuData.component); } } if (menuData.permission) { const permissionInput = dialog.locator('input[placeholder*="权限"]'); if (await permissionInput.count() > 0) { await permissionInput.fill(menuData.permission); } } if (menuData.sort !== undefined) { const sortInput = dialog.locator('input[type="number"]'); if (await sortInput.count() > 0) { await sortInput.fill(String(menuData.sort)); } } if (menuData.visible) { const visibleRadio = dialog.locator(`input[value="${menuData.visible}"]`); if (await visibleRadio.count() > 0) { await visibleRadio.check(); } } if (menuData.status) { const statusRadio = dialog.locator(`input[value="${menuData.status}"]`); if (await statusRadio.count() > 0) { await statusRadio.check(); } } } async submitForm() { await this.page.getByRole('button', { name: '确定' }).or(this.page.locator('button:has-text("确定")')).click(); } async editMenu(menuName: string) { const menuRow = this.table.locator('tbody tr').filter({ hasText: menuName }); await menuRow.getByRole('button', { name: '编辑' }).or(this.page.locator('.edit-button')).click(); } async deleteMenu(menuName: string) { const menuRow = this.table.locator('tbody tr').filter({ hasText: menuName }); await menuRow.getByRole('button', { name: '删除' }).or(this.page.locator('.delete-button')).click(); } async confirmDelete() { await this.page.getByRole('button', { name: '确定' }).or(this.page.locator('.confirm-dialog .confirm-button')).click(); } async search(keyword: string) { await this.searchInput.fill(keyword); await this.searchButton.click(); } async expandAll() { await this.expandAllButton.click(); await this.page.waitForTimeout(500); } async collapseAll() { await this.collapseAllButton.click(); await this.page.waitForTimeout(500); } async containsText(text: string): Promise { return await this.table.getByText(text).count() > 0; } async isSuccessMessageVisible(): Promise { try { return await this.successMessage.isVisible({ timeout: 3000 }); } catch { return false; } } async getMenuCount(): Promise { return await this.table.locator('tbody tr').count(); } async reload() { await this.page.reload(); } }