/** * CNC管理后台 - 三模块重构E2E测试 * * 测试范围: * 1. 仪表盘新布局(NC程序排行+分布饼图、无告警区域) * 2. 产量报表3子页导航+筛选联动 * 3. 设备详情页(latest-tags实时状态+采集时间+日期筛选) * * 使用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) }) // ════════════════════════════════════════════════════════════════ // 套件1:仪表盘重设计 // ════════════════════════════════════════════════════════════════ test.describe('仪表盘重设计', () => { test.beforeEach(async ({ page }) => { await page.goto('/mock/dashboard', { waitUntil: 'networkidle' }) }) test('4个统计卡片存在且标签正确', async ({ page }) => { const cards = page.locator('.stat-card') await expect(cards).toHaveCount(4) // 逐个验证标签文本包含预期关键字 await expect(cards.nth(0)).toContainText('在线机床数') await expect(cards.nth(1)).toContainText('今日总产量') await expect(cards.nth(2)).toContainText('采集服务') await expect(cards.nth(3)).toContainText('运行机床') }) test('不包含旧版告警和状态分布区域', async ({ page }) => { // 验证以下文字在页面中不存在,确保已移除旧布局 await expect(page.locator('text=活跃告警')).toHaveCount(0) await expect(page.locator('text=最新告警')).toHaveCount(0) await expect(page.locator('text=机床状态分布')).toHaveCount(0) await expect(page.locator('text=采集成功率')).toHaveCount(0) }) test('NC程序产量排行表可见', async ({ page }) => { // 第4行的NC程序排行卡片标题包含"NC程序产量排行" await expect(page.locator('.card-title:has-text("NC程序产量排行")')).toBeVisible() }) test('NC程序产量分布饼图区域可见', async ({ page }) => { // 第2行右侧卡片的标题包含"NC程序产量分布" await expect(page.locator('.card-title:has-text("NC程序产量分布")')).toBeVisible() }) test('排行区域排序控件为el-select下拉选择', async ({ page }) => { // 机床排行和工人排行在 .rank-row 中,验证含有 el-select const rankSelects = page.locator('.rank-row .el-select') // 至少应存在一个:机床排序(v-model="machineSortOrder") await expect(rankSelects.first()).toBeVisible() }) test('产量趋势图表区域可见', async ({ page }) => { // 第2行左侧卡片 await expect(page.locator('.card-title:has-text("产量趋势")')).toBeVisible() }) test('车间平均单机产量区域可见', async ({ page }) => { // 第5行右侧卡片,标题动态包含日期标签 await expect(page.locator('.card-title:has-text("车间平均单机产量")')).toBeVisible() }) }) // ════════════════════════════════════════════════════════════════ // 套件2:产量报表子菜单导航 // ════════════════════════════════════════════════════════════════ test.describe('产量报表子菜单', () => { test.beforeEach(async ({ page }) => { await page.goto('/mock/dashboard', { waitUntil: 'networkidle' }) }) test('产量报表有子菜单且可见', async ({ page }) => { // Sidebar中产量报表是 el-sub-menu,内部 span 包含"产量报表"文字 const submenu = page.locator('.el-sub-menu:has-text("产量报表")') await expect(submenu).toBeVisible() }) test('点击机床产量导航到正确路径', async ({ page }) => { // 先展开子菜单(点击产量报表标题) await page.locator('.el-sub-menu:has-text("产量报表")').click() // 点击"机床产量"子项(使用精确匹配避免与"机床产量排行"混淆) await page.locator('.el-menu-item:has-text("机床产量")').click() await expect(page).toHaveURL(/\/production\/machine/) }) test('点击员工产量导航到正确路径', async ({ page }) => { await page.locator('.el-sub-menu:has-text("产量报表")').click() await page.locator('.el-menu-item:has-text("员工产量")').click() await expect(page).toHaveURL(/\/production\/worker/) }) test('点击程序产量导航到正确路径', async ({ page }) => { await page.locator('.el-sub-menu:has-text("产量报表")').click() await page.locator('.el-menu-item:has-text("程序产量")').click() await expect(page).toHaveURL(/\/production\/program/) }) test('/production重定向到/production/machine', async ({ page }) => { await page.goto('/mock/production', { waitUntil: 'networkidle' }) await expect(page).toHaveURL(/\/production\/machine/) }) }) // ════════════════════════════════════════════════════════════════ // 套件3:机床产量子页面 // ════════════════════════════════════════════════════════════════ test.describe('机床产量子页面', () => { test.beforeEach(async ({ page }) => { await page.goto('/mock/production/machine', { waitUntil: 'networkidle' }) }) test('页面加载后统计卡片可见', async ({ page }) => { // 机床产量页面有4个统计卡片(总产量/运行机床数/平均单产/最高单产机床) const cards = page.locator('.stat-card') await expect(cards.first()).toBeVisible() }) test('筛选栏包含日期范围和查询按钮', async ({ page }) => { // 验证筛选控件存在 await expect(page.locator('text=日期范围')).toBeVisible() await expect(page.locator('button:has-text("查询")')).toBeVisible() await expect(page.locator('button:has-text("重置")')).toBeVisible() }) test('图表区域可见', async ({ page }) => { // 验证柱状图和饼图的卡片标题 await expect(page.locator('.card-title:has-text("机床产量柱状图")')).toBeVisible() await expect(page.locator('.card-title:has-text("各机床产量占比")')).toBeVisible() }) test('明细排行表格可见', async ({ page }) => { // 验证表格存在 await expect(page.locator('.card-title:has-text("明细排行")')).toBeVisible() }) }) // ════════════════════════════════════════════════════════════════ // 套件4:员工产量子页面 // ════════════════════════════════════════════════════════════════ test.describe('员工产量子页面', () => { test('页面加载成功且有统计卡片', async ({ page }) => { await page.goto('/mock/production/worker', { waitUntil: 'networkidle' }) const cards = page.locator('.stat-card') await expect(cards.first()).toBeVisible() }) test('筛选栏存在', async ({ page }) => { await page.goto('/mock/production/worker', { waitUntil: 'networkidle' }) await expect(page.locator('text=日期范围')).toBeVisible() await expect(page.locator('button:has-text("查询")')).toBeVisible() }) }) // ════════════════════════════════════════════════════════════════ // 套件5:程序产量子页面 // ════════════════════════════════════════════════════════════════ test.describe('程序产量子页面', () => { test('页面加载成功且有统计卡片', async ({ page }) => { await page.goto('/mock/production/program', { waitUntil: 'networkidle' }) const cards = page.locator('.stat-card') await expect(cards.first()).toBeVisible() }) test('筛选栏存在', async ({ page }) => { await page.goto('/mock/production/program', { waitUntil: 'networkidle' }) await expect(page.locator('text=日期范围')).toBeVisible() await expect(page.locator('button:has-text("查询")')).toBeVisible() }) }) // ════════════════════════════════════════════════════════════════ // 套件6:设备详情页改造 // ════════════════════════════════════════════════════════════════ test.describe('设备详情页改造', () => { test('实时状态表格有采集时间列', async ({ page }) => { await page.goto('/mock/machine/1', { waitUntil: 'networkidle' }) // latest-tags 实时状态表格有"采集时间"列头(th>div>采集时间) await expect(page.locator('th:has-text("采集时间")')).toBeVisible() }) test('基本信息卡片存在', async ({ page }) => { await page.goto('/mock/machine/1', { waitUntil: 'networkidle' }) await expect(page.locator('text=基本信息')).toBeVisible() }) test('实时状态卡片存在', async ({ page }) => { await page.goto('/mock/machine/1', { waitUntil: 'networkidle' }) await expect(page.locator('text=实时状态')).toBeVisible() }) test('采集记录区域有日期选择器', async ({ page }) => { await page.goto('/mock/machine/1', { waitUntil: 'networkidle' }) // 最近采集记录卡片的头部包含一个日期选择器 const datepickers = page.locator('.el-date-editor') await expect(datepickers.first()).toBeVisible() }) test('今日产量表格存在', async ({ page }) => { await page.goto('/mock/machine/1', { waitUntil: 'networkidle' }) await expect(page.locator('text=今日产量')).toBeVisible() }) })