import { Page, Locator, expect } from '@playwright/test'; export class DictionaryManagementPage { readonly page: Page; readonly table: Locator; readonly createDictTypeButton: Locator; readonly createDictDataButton: Locator; readonly searchInput: Locator; readonly searchButton: Locator; readonly successMessage: Locator; readonly dictTypeTable: Locator; readonly dictDataTable: Locator; constructor(page: Page) { this.page = page; this.table = page.locator('.el-table').or(page.locator('.dict-table')); this.createDictTypeButton = page.getByRole('button', { name: '新增字典类型' }).or(page.locator('button:has-text("新增字典类型")')); this.createDictDataButton = 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.dictTypeTable = page.locator('.dict-type-table').or(page.locator('.el-table').first()); this.dictDataTable = page.locator('.dict-data-table').or(page.locator('.el-table').nth(1)); } async goto() { try { console.log('导航到字典管理页面...'); await this.page.goto('/dict'); await this.page.waitForLoadState('networkidle'); await this.table.waitFor({ state: 'visible', timeout: 10000 }); await expect(this.page).toHaveURL(/.*dict/); console.log('字典管理页面加载完成'); } catch (error) { await this.page.screenshot({ path: `test-results/dict-management-error-${Date.now()}.png` }); console.error('导航到字典管理页面失败:', error); throw new Error(`导航到字典管理页面失败: ${error instanceof Error ? error.message : String(error)}`); } } async clickCreateDictType() { await this.createDictTypeButton.click(); await this.page.waitForTimeout(500); } async clickCreateDictData() { await this.createDictDataButton.click(); await this.page.waitForTimeout(500); } async fillDictTypeForm(dictTypeData: { dictName: string; dictType: string; status?: string; remark?: string; }) { const dialog = this.page.locator('.el-dialog'); await dialog.locator('input').first().fill(dictTypeData.dictName); await dialog.locator('input').nth(1).fill(dictTypeData.dictType); if (dictTypeData.status) { const statusRadio = dialog.locator(`input[value="${dictTypeData.status}"]`); if (await statusRadio.count() > 0) { await statusRadio.check(); } } if (dictTypeData.remark) { const remarkInput = dialog.locator('textarea'); if (await remarkInput.count() > 0) { await remarkInput.fill(dictTypeData.remark); } } } async fillDictDataForm(dictData: { dictLabel: string; dictValue: string; dictType?: string; cssClass?: string; listClass?: string; isDefault?: string; status?: string; sort?: number; }) { const dialog = this.page.locator('.el-dialog'); await dialog.locator('input').first().fill(dictData.dictLabel); await dialog.locator('input').nth(1).fill(dictData.dictValue); if (dictData.dictType) { const dictTypeSelect = dialog.locator('.el-select'); if (await dictTypeSelect.count() > 0) { await dictTypeSelect.click(); await this.page.waitForTimeout(300); await this.page.getByRole('option', { name: dictData.dictType }).click(); } } if (dictData.cssClass) { const cssClassInput = dialog.locator('input[placeholder*="CSS"]'); if (await cssClassInput.count() > 0) { await cssClassInput.fill(dictData.cssClass); } } if (dictData.listClass) { const listClassInput = dialog.locator('input[placeholder*="列表"]'); if (await listClassInput.count() > 0) { await listClassInput.fill(dictData.listClass); } } if (dictData.isDefault) { const defaultRadio = dialog.locator(`input[value="${dictData.isDefault}"]`); if (await defaultRadio.count() > 0) { await defaultRadio.check(); } } if (dictData.status) { const statusRadio = dialog.locator(`input[value="${dictData.status}"]`); if (await statusRadio.count() > 0) { await statusRadio.check(); } } if (dictData.sort !== undefined) { const sortInput = dialog.locator('input[type="number"]'); if (await sortInput.count() > 0) { await sortInput.fill(String(dictData.sort)); } } } async submitForm() { await this.page.getByRole('button', { name: '确定' }).or(this.page.locator('button:has-text("确定")')).click(); } async editDictType(dictName: string) { const dictTypeRow = this.dictTypeTable.locator('tbody tr').filter({ hasText: dictName }); await dictTypeRow.getByRole('button', { name: '编辑' }).or(this.page.locator('.edit-button')).click(); } async editDictData(dictLabel: string) { const dictDataRow = this.dictDataTable.locator('tbody tr').filter({ hasText: dictLabel }); await dictDataRow.getByRole('button', { name: '编辑' }).or(this.page.locator('.edit-button')).click(); } async deleteDictType(dictName: string) { const dictTypeRow = this.dictTypeTable.locator('tbody tr').filter({ hasText: dictName }); await dictTypeRow.getByRole('button', { name: '删除' }).or(this.page.locator('.delete-button')).click(); } async deleteDictData(dictLabel: string) { const dictDataRow = this.dictDataTable.locator('tbody tr').filter({ hasText: dictLabel }); await dictDataRow.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 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 getDictTypeCount(): Promise { return await this.dictTypeTable.locator('tbody tr').count(); } async getDictDataCount(): Promise { return await this.dictDataTable.locator('tbody tr').count(); } async reload() { await this.page.reload(); } }