| | |
| | | const browser = await chromium.launch({ channel: 'chrome', headless: true }) |
| | | const now = Date.UTC(2026, 8, 5, 11, 0, 0) |
| | | let receptionStatus = 'RECEIVING' |
| | | let deviceStatus = 'OFFLINE' |
| | | const warnings = ['CABINET_CHANNEL', 'COLLECTOR'].map((sourceType, index) => ({ |
| | | exceptionId: index + 1, testId: 1, testName: '离线告警验收', exceptionType: 'DEVICE_OFFLINE', |
| | | sourceType, sourceIdentity: index ? '9' : 'dev-sim:22:1:1:1', metricCode: 'DEVICE_ONLINE', |
| | |
| | | binding: { channelId: 1, cabinetId: 1, cabinetName: '演示检测柜', adapterCode: 'dev-sim', devtype: 22, devid: 1, subdevid: 1, chlid: 1 } }], |
| | | }) |
| | | const live = () => ({ testId: 1, testStatus: detail().testStatus, receptionStatus, serverTime: now, testPlan: null, |
| | | sources: ['CABINET_CHANNEL', 'COLLECTOR'].map(sourceType => ({ sourceType, sourceId: sourceType === 'COLLECTOR' ? 9 : 1, batteryNo: 'B-01', deviceStatus: 'OFFLINE', latestSnapshot: {} })), |
| | | exceptions: receptionStatus === 'RECEIVING' ? warnings.filter(w => w.exceptionStatus === 'OPEN').map(w => ({ ...w, status: w.exceptionStatus, value: null, message: '接收期间设备离线,等待处理' })) : [], |
| | | sources: ['CABINET_CHANNEL', 'COLLECTOR'].map(sourceType => ({ sourceType, sourceId: sourceType === 'COLLECTOR' ? 9 : 1, batteryNo: 'B-01', deviceStatus, latestSnapshot: {} })), |
| | | exceptions: receptionStatus === 'RECEIVING' && deviceStatus === 'OFFLINE' ? warnings.map(w => ({ |
| | | exceptionType: 'DEVICE_OFFLINE', sourceType: w.sourceType, sourceIdentity: w.sourceIdentity, |
| | | status: 'OPEN', message: '接收中数据来源离线,当前无法取得测量数据', |
| | | })) : [], |
| | | }) |
| | | try { |
| | | const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } }) |
| | | const errors = [] |
| | | page.on('pageerror', error => errors.push(error.message)) |
| | | await page.addInitScript(() => localStorage.setItem('battery_detection_auth_token', 'browser-test')) |
| | | await page.addInitScript(() => { |
| | | const fetch = window.fetch.bind(window) |
| | | window.fetch = (input, init) => { |
| | | if (!String(input).endsWith('/test/1/live')) return fetch(input, init) |
| | | // 保持实时流打开,直接验证设备状态和异常事件无需刷新即可更新页面。 |
| | | const body = new ReadableStream({ start(controller) { |
| | | window.emitOfflineTestEvent = (event, data) => controller.enqueue( |
| | | new TextEncoder().encode(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`)) |
| | | } }) |
| | | return Promise.resolve(new Response(body, { headers: { 'Content-Type': 'text/event-stream' } })) |
| | | } |
| | | }) |
| | | await page.route(`${origin}/**`, async route => { |
| | | const path = new URL(route.request().url()).pathname |
| | | if (path.startsWith('/assets/')) return route.fulfill({ body: await readFile(`dist${path}`), contentType: path.endsWith('.css') ? 'text/css' : 'application/javascript' }) |
| | |
| | | await expect(alarm).toContainText('检测柜通道离线') |
| | | await expect(alarm).toContainText('采集器离线') |
| | | await expect(alarm).not.toContainText('超限') |
| | | await expect(alarm).not.toContainText('处理') |
| | | await expect(alarm).not.toContainText('暂无异常') |
| | | await alarm.screenshot({ path: `${output}/console-alarm.png` }) |
| | | await page.setViewportSize({ width: 390, height: 844 }) |
| | |
| | | if (status === 'RECEIVING') await expect(alarm).toContainText('采集器离线') |
| | | else await expect(alarm).toContainText('暂无异常') |
| | | } |
| | | deviceStatus = 'ONLINE' |
| | | await page.evaluate(state => { |
| | | window.emitOfflineTestEvent('device-status', state.sources) |
| | | window.emitOfflineTestEvent('exception', state.exceptions) |
| | | }, live()) |
| | | await expect(alarm).toContainText('暂无异常') |
| | | await page.reload() |
| | | await expect(alarm).toContainText('暂无异常') |
| | | assert.ok(warnings.every(w => w.exceptionStatus === 'OPEN')) |
| | | if (process.argv[2] !== 'console') { |
| | | await page.goto(`${origin}/exception`) |
| | | const table = page.locator('.exception-page table') |
| | | await expect(table.locator('tbody tr')).toHaveCount(2) |
| | | await expect(table).toContainText('设备离线') |
| | | await expect(table).toContainText('待处理') |
| | | await expect(table).toContainText('2026-09-05') |
| | | await expect(table).not.toContainText('null') |
| | | await table.locator('tbody tr').first().getByRole('button', { name: '处理', exact: true }).click() |
| | |
| | | await page.reload() |
| | | await expect(table).toContainText('已处理') |
| | | await page.screenshot({ path: `${output}/exception-management.png`, fullPage: true, animations: 'disabled' }) |
| | | await page.goto(`${origin}/test-list/1/console`) |
| | | await expect(alarm).toContainText('暂无异常') |
| | | deviceStatus = 'OFFLINE' |
| | | await page.evaluate(state => window.emitOfflineTestEvent('snapshot', state), live()) |
| | | await expect(alarm.locator('.alarm-list > div')).toHaveCount(2) |
| | | await expect(alarm).toContainText('检测柜通道离线') |
| | | await expect(alarm).toContainText('采集器离线') |
| | | await expect(alarm).not.toContainText('处理') |
| | | assert.equal(warnings[0].exceptionStatus, 'CLOSED') |
| | | } |
| | | assert.deepEqual(errors, []) |
| | | console.log('离线告警浏览器验证通过:接收中告警、暂停和结束隐藏、刷新及异常记录处理。') |
| | | console.log('离线告警浏览器验证通过:接收中告警、暂停和结束隐藏、恢复在线移除提醒;完整模式同时检查异常处理与实时提醒独立。') |
| | | } finally { |
| | | await browser.close() |
| | | } |