|
|
|
@ -0,0 +1,247 @@
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 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()
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|