import assert from 'node:assert/strict'
|
import { readFile, mkdir } from 'node:fs/promises'
|
import { resolve } from 'node:path'
|
import { chromium, expect } from '@playwright/test'
|
|
// 读取真实构建产物并拦截 API,不启动服务或写入开发数据库。
|
const output = '../.scratch/simulator-and-data-import-v1/related-tests-browser'
|
await mkdir(output, { recursive: true })
|
const origin = 'http://device-relations.test'
|
const browser = await chromium.launch({ channel: 'chrome', headless: true })
|
const relatedTests = [
|
{ testId: 1, testName: '低温循环测试', testStatus: 'WAITING', channels: ['1-1', '1-2'] },
|
{ testId: 2, testName: '正在接收的测试', testStatus: 'RUNNING', channels: ['1-3'] },
|
{ testId: 3, testName: '暂停接收的测试', testStatus: 'PAUSED', channels: ['1-4'] },
|
{ testId: 4, testName: '已结束的长名称测试用于验证弹窗内容换行和窄屏布局', testStatus: 'COMPLETED', channels: ['2-1', '2-2', '2-3'] },
|
]
|
const devices = (kind) => [[], [relatedTests[0]], relatedTests].map((tests, index) => ({
|
[`${kind}Id`]: index + 1, [`${kind}Code`]: `${kind}-${index + 1}`, [`${kind}Name`]: `设备 ${index + 1}`,
|
ipAddress: '127.0.0.2', macAddress: '02:44:00:10:00:01', manufacturer: '开发模拟器', model: 'Virtual',
|
channelCount: 8, capacity: 1, onlineStatus: kind === 'cabinet' ? '0' : '1', status: '0',
|
relatedTests: kind === 'cabinet' ? tests : tests.map(test => ({ ...test, channels: ['S-01', 'S-02'] })),
|
}))
|
|
try {
|
const page = await browser.newPage({ viewport: { width: 1920, height: 1000 } })
|
const errors = []
|
let responseMode = 'normal'
|
page.on('pageerror', error => errors.push(error.message))
|
await page.addInitScript(() => localStorage.setItem('battery_detection_auth_token', 'browser-test'))
|
await page.route(`${origin}/**`, async route => {
|
const url = new URL(route.request().url())
|
const path = url.pathname
|
if (path.startsWith('/assets/')) {
|
const body = await readFile(resolve('dist', path.slice(1)))
|
return route.fulfill({ body, contentType: path.endsWith('.css') ? 'text/css' : 'application/javascript' })
|
}
|
if (path.includes('/system/')) {
|
if (path.includes('/system/test/')) return route.fulfill({ json: { code: 404, msg: '测试控制台响应未纳入设备页面夹具' } })
|
const kind = path.includes('/detectionCabinet') ? 'cabinet' : 'collector'
|
if (responseMode === 'error') return route.fulfill({ status: 500, json: { code: 500, msg: '设备查询失败' } })
|
if (responseMode === 'forbidden') return route.fulfill({ json: { code: 403, msg: '没有设备查询权限' } })
|
if (path.endsWith('/list')) {
|
assert.equal(url.searchParams.has('testStatus'), false)
|
const rows = responseMode === 'empty' ? [] : devices(kind)
|
return route.fulfill({ json: { code: 200, rows, total: rows.length } })
|
}
|
return route.fulfill({ json: { code: 200, data: devices(kind)[2] } })
|
}
|
if (path.includes('/getInfo')) return route.fulfill({ json: { code: 200, user: { userName: 'admin' }, roles: ['admin'] } })
|
return route.fulfill({ contentType: 'text/html', body: await readFile('dist/index.html', 'utf8') })
|
})
|
const kinds = process.argv[2] ? [process.argv[2]] : ['cabinet', 'collector']
|
for (const kind of kinds) {
|
const listUrl = `${origin}/device-${kind}`
|
await page.goto(listUrl)
|
const table = page.locator('.result-panel table')
|
await expect(table.locator('tbody tr')).toHaveCount(3)
|
await expect(table.getByRole('columnheader', { name: '关联测试' })).toBeVisible()
|
await expect(table.getByRole('columnheader', { name: '测试状态', exact: true })).toHaveCount(0)
|
await expect(page.getByText('当前测试', { exact: true })).toHaveCount(0)
|
const cellIndex = kind === 'cabinet' ? 10 : 9
|
await expect(table.locator('tbody tr').nth(0).locator('td').nth(cellIndex)).toHaveText('-')
|
await expect(table.getByRole('link', { name: '低温循环测试' })).toHaveAttribute('href', '/test-list/1/console')
|
await page.screenshot({ path: `${output}/${kind}-list.png`, fullPage: true })
|
for (const width of [1920, 768, 390]) {
|
await page.setViewportSize({ width, height: 900 })
|
await table.getByRole('button', { name: '4 项测试' }).click()
|
const dialog = page.getByRole('dialog', { name: '关联测试' })
|
await expect(dialog).toBeVisible()
|
await expect(dialog).toHaveCSS('opacity', '1')
|
await expect(dialog).toHaveCSS('transform', 'none')
|
await expect(dialog.locator('tbody tr')).toHaveCount(4)
|
for (const state of ['待测试', '检测中', '暂停', '检测完成']) await expect(dialog.getByRole('cell', { name: state, exact: true })).toBeVisible()
|
await expect(dialog.locator('tbody tr').first()).toContainText(kind === 'cabinet' ? '1-1、1-2' : 'S-01、S-02')
|
const box = await dialog.boundingBox()
|
assert.ok(box && box.x >= 0 && box.x + box.width <= width && box.y >= 0 && box.y + box.height <= 900, JSON.stringify({ width, box }))
|
assert.equal(await dialog.evaluate(element => element.scrollWidth > element.clientWidth), false)
|
await page.screenshot({ path: `${output}/${kind}-${width}.png`, fullPage: true, animations: 'disabled' })
|
await dialog.getByRole('button', { name: /关闭|Close/ }).click()
|
await expect(dialog).not.toBeVisible()
|
}
|
await page.setViewportSize({ width: 1920, height: 1000 })
|
await table.getByRole('link', { name: '低温循环测试' }).click()
|
await expect(page).toHaveURL(`${origin}/test-list/1/console`)
|
await page.goto(listUrl)
|
await table.getByRole('button', { name: '4 项测试' }).click()
|
await page.getByRole('dialog', { name: '关联测试' }).getByRole('link', { name: '暂停接收的测试' }).click()
|
await expect(page).toHaveURL(`${origin}/test-list/3/console`)
|
await page.goto(listUrl)
|
await page.reload()
|
await expect(table.getByRole('button', { name: '4 项测试' })).toBeVisible()
|
await page.goto(`${listUrl}/3/edit`)
|
await expect(page.locator('.device-summary').getByRole('button', { name: '4 项测试' })).toBeVisible()
|
await expect(page.locator('.device-summary').getByText('测试状态', { exact: true })).toHaveCount(0)
|
for (const mode of ['empty', 'error', 'forbidden']) {
|
responseMode = mode
|
await page.goto(listUrl)
|
await expect(table).not.toContainText('4 项测试')
|
await expect(table).toContainText('暂无符合条件')
|
if (mode === 'error') await expect(page.getByText('设备查询失败', { exact: true })).toBeVisible()
|
if (mode === 'forbidden') await expect(page.getByText('没有设备查询权限', { exact: true })).toBeVisible()
|
}
|
responseMode = 'normal'
|
}
|
assert.deepEqual(errors, [])
|
console.log(`关联测试浏览器验证通过:${kinds.join('、')};空值、单项链接、多项展开、状态、通道、刷新、编辑、错误及 1920/768/390 布局。`)
|
} finally {
|
await browser.close()
|
}
|