import { test, expect, Page } from '@playwright/test'; test.describe('菜单管理集成测试', () => { test.beforeEach(async ({ page }) => { await page.goto('/login'); await page.fill('[data-testid="username-input"] input', 'admin'); await page.fill('[data-testid="password-input"] input', 'admin123456'); await page.click('[data-testid="login-button"]'); await expect(page).toHaveURL(/.*\//, { timeout: 15000 }); await page.goto('/system/menu'); await page.waitForLoadState('networkidle'); }); test('菜单列表页面 - 应正确显示', async ({ page }) => { await expect(page.locator('[data-testid="menu-management-container"], .menu-management')).toBeVisible(); await expect(page.locator('table, .el-table')).toBeVisible(); }); test('菜单树形结构 - 应正确展开收起', async ({ page }) => { const expandButton = page.locator('.el-table__expand-icon, .el-tree-node__expand-icon'); if (await expandButton.count() > 0) { await expandButton.first().click(); await page.waitForTimeout(500); } }); test('新增菜单 - 成功', async ({ page }) => { const timestamp = Date.now(); const addButton = page.locator('button:has-text("新增"), button:has-text("添加")'); if (await addButton.count() > 0) { await addButton.first().click(); await expect(page.locator('.el-dialog')).toBeVisible(); const nameInput = page.locator('input[placeholder*="菜单名"], input[placeholder*="名称"]'); if (await nameInput.count() > 0) { await nameInput.fill(`测试菜单_${timestamp}`); } const pathInput = page.locator('input[placeholder*="路径"], input[placeholder*="path"]'); if (await pathInput.count() > 0) { await pathInput.fill(`/test-menu-${timestamp}`); } const submitButton = page.locator('.el-dialog button:has-text("确定"), .el-dialog button:has-text("保存")'); if (await submitButton.count() > 0) { await submitButton.click(); await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 10000 }); } } }); test('编辑菜单 - 成功', async ({ page }) => { const editButton = page.locator('table button:has-text("编辑"), .el-table button:has-text("编辑")'); if (await editButton.count() > 0) { await editButton.first().click(); await expect(page.locator('.el-dialog')).toBeVisible(); const submitButton = page.locator('.el-dialog button:has-text("确定"), .el-dialog button:has-text("保存")'); if (await submitButton.count() > 0) { await submitButton.click(); await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 10000 }); } } }); test('删除菜单 - 成功', async ({ page }) => { const deleteButton = page.locator('table button:has-text("删除"), .el-table button:has-text("删除")'); if (await deleteButton.count() > 0) { await deleteButton.first().click(); const confirmButton = page.locator('.el-popconfirm button:has-text("确定"), .el-message-box button:has-text("确定")'); if (await confirmButton.count() > 0) { await confirmButton.click(); await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 10000 }); } } }); test('菜单排序 - 应正确调整顺序', async ({ page }) => { const sortInput = page.locator('input[type="number"]').first(); if (await sortInput.count() > 0) { const currentValue = await sortInput.inputValue(); const newValue = parseInt(currentValue) + 1; await sortInput.fill(newValue.toString()); await page.keyboard.press('Enter'); } }); test('菜单图标选择 - 应正确显示图标选择器', async ({ page }) => { const addButton = page.locator('button:has-text("新增"), button:has-text("添加")'); if (await addButton.count() > 0) { await addButton.first().click(); const iconPicker = page.locator('.icon-picker, .el-icon-picker, [class*="icon"]'); if (await iconPicker.count() > 0) { await iconPicker.first().click(); } } }); }); test.describe('菜单权限测试', () => { test('菜单权限控制 - 无权限菜单不显示', async ({ page, context }) => { await context.clearCookies(); await page.evaluate(() => localStorage.clear()); await page.goto('/login'); await page.fill('[data-testid="username-input"] input', 'testuser'); await page.fill('[data-testid="password-input"] input', 'test123456'); await page.click('[data-testid="login-button"]'); await page.goto('/system/menu'); const addButton = page.locator('button:has-text("新增"), button:has-text("添加")'); const isVisible = await addButton.isVisible().catch(() => false); expect(isVisible).toBe(false); }); });