You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
haoliang-net/frontend/e2e/admin-redesign.spec.ts

217 lines
11 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* CNC管理后台 - 三模块重构E2E测试
*
* 测试范围:
* 1. 仪表盘新布局NC程序排行+分布饼图、无告警区域)
* 2. 产量报表3子页导航+筛选联动
* 3. 设备详情页latest-tags实时状态+采集时间+日期筛选)
*
* 使用Mock模式/mock前缀路由不依赖后端API
*/
import { test, expect, type Page } from '@playwright/test'
/** 模拟登录TokenMock模式下路由守卫只检查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()
})
})