| New file |
| | |
| | | import assert from 'node:assert/strict' |
| | | import { readFile, mkdir } from 'node:fs/promises' |
| | | import { chromium, expect } from '@playwright/test' |
| | | |
| | | // 使用实际模拟器页面与拦截响应验证交互,不启动业务服务。 |
| | | const html = await readFile('../BatteryDetection/ruoyi-admin/src/main/resources/static/dev/bts-simulator.html', 'utf8') |
| | | const output = '../.scratch/simulator-and-data-import-v1/browser' |
| | | await mkdir(output, { recursive: true }) |
| | | const browser = await chromium.launch({ channel: 'chrome', headless: true }) |
| | | try { |
| | | const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } }) |
| | | const errors = [] |
| | | page.on('pageerror', error => errors.push(error.message)) |
| | | const state = { |
| | | running: true, softwareAccessible: true, listenAddress: '127.0.0.1:15020', |
| | | devices: [{ deviceId: 1, ip: '127.0.0.2', online: true, |
| | | profile: { devtype: 22, subDeviceId: 1, model: 'BTS Virtual Cabinet' }, |
| | | channels: [{ channelId: 1, online: true, workStatus: 'WORKING' }] }], |
| | | collectors: [{ collectorId: 1, deviceCode: 'dev-sim-collector-1', mac: '02:43:00:00:00:01', |
| | | name: 'dev-sim 采集器 1', ip: '127.0.1.2', online: true, channelCount: 1, |
| | | channels: [{ channelCode: 'S-01', workStatus: 'WORKING', |
| | | metrics: [{ metricCode: 'temperature', value: 25.1, unit: '℃' }] }], latestMeasurements: [] }], |
| | | recentRequests: [{ receivedAt: Date.now(), command: 'inquire', request: '<bts><cmd>inquire</cmd></bts>', |
| | | response: '<inquire voltage="3.700" />' }], |
| | | } |
| | | const calls = [] |
| | | let failSoftware = false |
| | | await page.route('http://simulator.test/**', async route => { |
| | | const request = route.request() |
| | | const path = new URL(request.url()).pathname |
| | | if (path === '/dev/bts-simulator.html') return route.fulfill({ contentType: 'text/html', body: html }) |
| | | const body = request.postDataJSON() |
| | | calls.push({ path, method: request.method(), body }) |
| | | if (path.endsWith('/software')) { |
| | | if (failSoftware) return route.fulfill({ status: 503, json: { message: '保存失败' } }) |
| | | state.softwareAccessible = body.accessible |
| | | } else if (path.endsWith('/devices/1/channels/1')) state.devices[0].channels[0] = { channelId: 1, ...body } |
| | | else if (path.endsWith('/collectors/1/channels/S-01/status')) state.collectors[0].channels[0].workStatus = body.workStatus |
| | | else if (path.endsWith('/devices/1')) Object.assign(state.devices[0], body) |
| | | else if (path.endsWith('/collectors/1')) Object.assign(state.collectors[0], body) |
| | | return route.fulfill({ json: state }) |
| | | }) |
| | | await page.goto('http://simulator.test/dev/bts-simulator.html') |
| | | await expect(page.getByLabel('新威软件可访问')).toBeChecked() |
| | | await page.getByLabel('新威软件可访问').uncheck() |
| | | await expect(page.getByLabel('新威软件可访问')).not.toBeChecked() |
| | | assert.equal(state.devices[0].online, true) |
| | | await page.getByLabel('检测柜 1 通道 1 工作状态').selectOption('PROTECTED') |
| | | await expect(page.getByLabel('检测柜 1 通道 1 工作状态')).toHaveValue('PROTECTED') |
| | | await page.getByLabel('S-01 工作状态').selectOption('UNOBSERVABLE') |
| | | await expect(page.getByLabel('S-01 工作状态')).toHaveValue('UNOBSERVABLE') |
| | | await page.locator('#devices').getByLabel('整机在线').uncheck() |
| | | await page.locator('#devices').getByRole('button', { name: '保存配置' }).click() |
| | | await expect(page.locator('#devices').getByLabel('整机离线')).not.toBeChecked() |
| | | await page.reload() |
| | | await expect(page.getByLabel('检测柜 1 通道 1 工作状态')).toHaveValue('PROTECTED') |
| | | await expect(page.getByLabel('新威软件可访问')).not.toBeChecked() |
| | | await expect(page.locator('#requests')).toContainText('voltage="3.700"') |
| | | await expect(page.getByText('600x', { exact: true })).toHaveCount(0) |
| | | await expect(page.getByRole('button', { name: '下载历史' })).toHaveCount(0) |
| | | await page.screenshot({ path: output + '/desktop.png', fullPage: true }) |
| | | for (const width of [390, 768]) { |
| | | await page.setViewportSize({ width, height: 844 }) |
| | | assert.equal(await page.evaluate(() => document.documentElement.scrollWidth > innerWidth), false) |
| | | await page.screenshot({ path: output + '/width-' + width + '.png', fullPage: true }) |
| | | } |
| | | failSoftware = true |
| | | await page.getByLabel('新威软件可访问').check() |
| | | await expect(page.locator('#error')).toContainText('保存失败') |
| | | assert.deepEqual(errors, []) |
| | | assert.ok(calls.some(call => call.path.endsWith('/software') && call.method === 'PUT')) |
| | | assert.ok(calls.every(call => !/playback|sampling|history/.test(call.path))) |
| | | console.log('模拟器页面:软件、设备、通道、刷新、失败提示及 1440/768/390 布局通过。') |
| | | } finally { |
| | | await browser.close() |
| | | } |