/** * CNC管理后台 - Playwright浏览器UI测试 * * 测试范围:设备管理、员工管理、采集地址三个模块的批量删除和启用/停用功能 * 使用Mock模式(/mock前缀路由),不依赖后端API * * 测试在真实浏览器中执行,验证: * - 页面加载和表格数据渲染 * - 勾选行后批量操作按钮的显示 * - 批量删除操作(勾选→点击→确认弹窗→验证行数减少) * - 批量停用操作(勾选已启用行→确认→验证状态变为停用) * - 批量启用操作(勾选已停用行→确认→验证状态变为启用) * - 单个删除操作(点击行内删除→确认→验证行数减少) */ import { test, expect, type Page } from '@playwright/test' // 模拟登录Token(Mock模式下路由守卫只检查token存在性) const MOCK_TOKEN = 'mock-test-token' // 全局beforeEach:在每个测试前预设token到localStorage,避免路由守卫拦截 test.beforeEach(async ({ page }) => { await page.addInitScript((token) => { localStorage.setItem('token', token) }, MOCK_TOKEN) }) // 辅助函数:重置指定模块的mock数据 async function resetMockData(page: Page, endpoint: string) { await page.evaluate(async (url) => { await fetch(url, { method: 'POST' }) }, endpoint) } // 辅助函数:导航到页面并等待表格渲染完成 async function gotoPage(page: Page, path: string) { await page.goto(path, { waitUntil: 'networkidle' }) await page.waitForSelector('.el-table', { timeout: 15000 }) } // 辅助函数:勾选表格中指定行的checkbox async function selectRowsByIndex(page: Page, indices: number[]) { const checkboxes = page.locator('.el-table__body .el-checkbox') for (const idx of indices) { await checkboxes.nth(idx).waitFor({ state: 'visible' }) await checkboxes.nth(idx).click() } } // 辅助函数:处理Element Plus的ElMessageBox确认弹窗 async function confirmDialog(page: Page) { const dialog = page.locator('.el-message-box') await dialog.waitFor({ state: 'visible', timeout: 5000 }) await dialog.locator('.el-button--primary').click() await dialog.waitFor({ state: 'hidden', timeout: 5000 }) } // 辅助函数:等待ElMessage消息提示并验证文本 async function expectMessage(page: Page, expectedText: string) { const msg = page.locator('.el-message') await msg.waitFor({ state: 'visible', timeout: 10000 }) await expect(msg).toContainText(expectedText) } // ============================================================ // 套件1:设备管理(机床)页面测试 // ============================================================ test.describe('设备管理页面', () => { test.beforeEach(async ({ page }) => { await gotoPage(page, '/mock/machine') await resetMockData(page, '/mock-api/test/reset-machines') await page.reload({ waitUntil: 'networkidle' }) await page.waitForSelector('.el-table', { timeout: 15000 }) }) test('页面加载 - 表格显示5台机床', async ({ page }) => { const rows = page.locator('.el-table__body-wrapper .el-table__row') await expect(rows).toHaveCount(5) const checkboxes = page.locator('.el-table__body .el-checkbox') await expect(checkboxes).toHaveCount(5) }) test('勾选行后 - 批量操作按钮显示', async ({ page }) => { await expect(page.locator('button:has-text("批量删除")')).not.toBeVisible() await selectRowsByIndex(page, [0]) await expect(page.locator('button:has-text("批量停用")')).toBeVisible() await expect(page.locator('button:has-text("批量启用")')).toBeVisible() await expect(page.locator('button:has-text("批量删除")')).toBeVisible() await expect(page.locator('button:has-text("批量删除(1)")')).toBeVisible() }) test('批量删除 - 勾选2行后删除,表格行数减少', async ({ page }) => { const rows = page.locator('.el-table__body-wrapper .el-table__row') await expect(rows).toHaveCount(5) await selectRowsByIndex(page, [0, 1]) await page.locator('button:has-text("批量删除")').click() await confirmDialog(page) await expectMessage(page, '批量删除成功') await page.waitForTimeout(1000) await expect(rows).toHaveCount(3) }) test('批量停用 - 勾选已启用行后停用,状态标签变更', async ({ page }) => { await selectRowsByIndex(page, [0]) await page.locator('button:has-text("批量停用")').click() await confirmDialog(page) await expectMessage(page, '操作成功') await page.waitForTimeout(1000) const statusTag = page.locator('.el-table__body-wrapper .el-table__row').first().locator('.el-tag:has-text("停用")') await expect(statusTag).toBeVisible() }) test('批量启用 - 勾选已停用行后启用,状态标签变更', async ({ page }) => { // 第4行(东-2.5,isEnabled=0) await selectRowsByIndex(page, [3]) await page.locator('button:has-text("批量启用")').click() await confirmDialog(page) await expectMessage(page, '操作成功') await page.waitForTimeout(1000) const statusTag = page.locator('.el-table__body-wrapper .el-table__row').nth(3).locator('.el-tag:has-text("启用")') await expect(statusTag).toBeVisible() }) test('单个删除 - 点击行内删除按钮,确认后行消失', async ({ page }) => { const rows = page.locator('.el-table__body-wrapper .el-table__row') await expect(rows).toHaveCount(5) await rows.first().locator('button:has-text("删除")').click() await confirmDialog(page) await expectMessage(page, '已删除') await page.waitForTimeout(1000) await expect(rows).toHaveCount(4) }) }) // ============================================================ // 套件2:员工管理页面测试 // ============================================================ test.describe('员工管理页面', () => { test.beforeEach(async ({ page }) => { await gotoPage(page, '/mock/worker') await resetMockData(page, '/mock-api/test/reset-workers') await page.reload({ waitUntil: 'networkidle' }) await page.waitForSelector('.el-table', { timeout: 15000 }) }) test('页面加载 - 表格显示3名员工', async ({ page }) => { const rows = page.locator('.el-table__body-wrapper .el-table__row') await expect(rows).toHaveCount(3) }) test('勾选行后 - 批量操作按钮显示', async ({ page }) => { await expect(page.locator('button:has-text("批量删除")')).not.toBeVisible() await selectRowsByIndex(page, [0]) await expect(page.locator('button:has-text("批量启用")')).toBeVisible() await expect(page.locator('button:has-text("批量停用")')).toBeVisible() await expect(page.locator('button:has-text("批量删除")')).toBeVisible() }) test('批量删除 - 勾选1行后删除,表格行数减少', async ({ page }) => { const rows = page.locator('.el-table__body-wrapper .el-table__row') await expect(rows).toHaveCount(3) await selectRowsByIndex(page, [2]) await page.locator('button:has-text("批量删除")').click() await confirmDialog(page) await expectMessage(page, '批量删除成功') await page.waitForTimeout(1000) await expect(rows).toHaveCount(2) }) test('批量停用 - 勾选已启用员工后停用', async ({ page }) => { await selectRowsByIndex(page, [0]) await page.locator('button:has-text("批量停用")').click() await confirmDialog(page) await expectMessage(page, '操作成功') await page.waitForTimeout(1000) const statusTag = page.locator('.el-table__body-wrapper .el-table__row').first().locator('.el-tag:has-text("停用")') await expect(statusTag).toBeVisible() }) test('批量启用 - 勾选已停用员工后启用', async ({ page }) => { await selectRowsByIndex(page, [2]) await page.locator('button:has-text("批量启用")').click() await confirmDialog(page) await expectMessage(page, '操作成功') await page.waitForTimeout(1000) const statusTag = page.locator('.el-table__body-wrapper .el-table__row').nth(2).locator('.el-tag:has-text("启用")') await expect(statusTag).toBeVisible() }) }) // ============================================================ // 套件3:采集地址页面测试 // ============================================================ test.describe('采集地址页面', () => { test.beforeEach(async ({ page }) => { await gotoPage(page, '/mock/collect-address') await resetMockData(page, '/mock-api/test/reset-addresses') await page.reload({ waitUntil: 'networkidle' }) await page.waitForSelector('.el-table', { timeout: 15000 }) }) test('页面加载 - 表格显示3条采集地址', async ({ page }) => { const rows = page.locator('.el-table__body-wrapper .el-table__row') await expect(rows).toHaveCount(3) }) test('勾选行后 - 批量操作按钮显示', async ({ page }) => { await expect(page.locator('button:has-text("批量删除")')).not.toBeVisible() await selectRowsByIndex(page, [0]) await expect(page.locator('button:has-text("批量启用")')).toBeVisible() await expect(page.locator('button:has-text("批量停用")')).toBeVisible() await expect(page.locator('button:has-text("批量删除")')).toBeVisible() }) test('批量删除 - 勾选1行后删除,表格行数减少', async ({ page }) => { const rows = page.locator('.el-table__body-wrapper .el-table__row') await expect(rows).toHaveCount(3) await selectRowsByIndex(page, [2]) await page.locator('button:has-text("批量删除")').click() await confirmDialog(page) await expectMessage(page, '批量删除成功') await page.waitForTimeout(1000) await expect(rows).toHaveCount(2) }) test('批量停用 - 勾选已启用地址后停用', async ({ page }) => { await selectRowsByIndex(page, [0]) await page.locator('button:has-text("批量停用")').click() await confirmDialog(page) await expectMessage(page, '操作成功') await page.waitForTimeout(1000) const statusTag = page.locator('.el-table__body-wrapper .el-table__row').first().locator('.el-tag:has-text("停用")') await expect(statusTag).toBeVisible() }) test('批量启用 - 勾选已停用地址后启用', async ({ page }) => { await selectRowsByIndex(page, [2]) await page.locator('button:has-text("批量启用")').click() await confirmDialog(page) await expectMessage(page, '操作成功') await page.waitForTimeout(1000) const statusTag = page.locator('.el-table__body-wrapper .el-table__row').nth(2).locator('.el-tag:has-text("启用")') await expect(statusTag).toBeVisible() }) })