yeg
2026-08-30 044c5cced4746b02d04bcf4adb7e9314d155799f
补充断线恢复告警与重复周期测试
4个文件已修改
25 ■■■■■ 已修改文件
package.json 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/TestConsole.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tests/e2e/collector-disconnect-recovery.spec.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tests/test-console-live.contract.test.mjs 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -13,6 +13,7 @@
    "test:e2e:ticket07": "playwright test tests/e2e/test-required-device-bindings.spec.ts",
    "test:e2e:ticket08": "playwright test tests/e2e/running-start-and-reception-boundaries.spec.ts",
    "test:e2e:ticket10": "playwright test tests/e2e/pause-resume-reception.spec.ts",
    "test:e2e:ticket11": "playwright test tests/e2e/collector-disconnect-recovery.spec.ts",
    "test:contract:ticket09": "node tests/test-console-live.contract.test.mjs"
  },
  "dependencies": {
src/views/TestConsole.vue
@@ -177,7 +177,7 @@
// 实时告警只展示后端当前仍开放的异常,关闭区间保留在历史记录中追溯。
const currentExceptions = computed(() => (liveState.value?.exceptions || [])
  .filter(item => !item.status || item.status === 'OPEN'))
  .filter(item => item.sourceType !== 'COLLECTOR' || !item.status || item.status === 'OPEN'))
const steps = [
  { no: 1, name: '恒流充电', time: '-', voltage: '0.9000 V', state: '已完成' },
tests/e2e/collector-disconnect-recovery.spec.ts
@@ -1,13 +1,13 @@
import { expect, test } from '@playwright/test'
test('采集器断线异常开放并在恢复后关闭', async ({ page }) => {
  let recovered = false
  let cycle = 0
  const live = () => ({
    testId: 42, testStatus: recovered ? 'RUNNING' : 'RUNNING_ABNORMAL', receptionStatus: 'RECEIVING',
    testId: 42, testStatus: cycle % 2 === 1 ? 'RUNNING' : 'RUNNING_ABNORMAL', receptionStatus: 'RECEIVING',
    updatedAt: '2026-08-30T06:00:00Z', sources: [{
      sourceType: 'COLLECTOR', sourceId: 8, batteryNo: 'BAT-01', deviceStatus: recovered ? 'ONLINE' : 'OFFLINE',
      sourceType: 'COLLECTOR', sourceId: 8, batteryNo: 'BAT-01', deviceStatus: cycle % 2 === 1 ? 'ONLINE' : 'OFFLINE',
      latestSnapshot: { source: '采集器', measurements: [], units: [] },
    }], exceptions: recovered ? [{
    }], exceptions: cycle % 2 === 1 ? [{
      sourceType: 'COLLECTOR', sourceId: 8, channelCode: 'S-01', exceptionType: 'COLLECTOR_DISCONNECTED',
      status: 'CLOSED', missingFrom: '2026-08-30T05:59:00Z', recoveredAt: '2026-08-30T06:01:00Z',
    }] : [{
@@ -33,7 +33,18 @@
  await expect(page.getByText('采集器#8离线 · S-01', { exact: true })).toBeVisible()
  await expect(page.getByText('缺失区间开放 · 2026-08-30T05:59:00Z', { exact: true })).toBeVisible()
  recovered = true
  cycle = 1
  await page.evaluate(() => window.dispatchEvent(new Event('ticket11-reconnect')))
  await page.reload()
  await expect(page.getByText('暂无异常', { exact: true })).toBeVisible()
  cycle = 2
  await page.reload()
  await expect(page.getByText('测试状态:检测中(异常)', { exact: true })).toBeVisible()
  await expect(page.getByText('采集器#8离线 · S-01', { exact: true })).toBeVisible()
  await expect(page.getByText('缺失区间开放 · 2026-08-30T05:59:00Z', { exact: true })).toBeVisible()
  cycle = 3
  await page.evaluate(() => window.dispatchEvent(new Event('ticket11-reconnect')))
  await page.reload()
  await expect(page.getByText('暂无异常', { exact: true })).toBeVisible()
tests/test-console-live.contract.test.mjs
@@ -13,4 +13,5 @@
assert.match(view, /liveConnection/)
assert.match(view, /不纳入结果/)
assert.doesNotMatch(view, /localStorage\.(setItem|getItem)\([^)]*test/i)
assert.match(view, /item\.sourceType !== 'COLLECTOR' \|\| !item\.status \|\| item\.status === 'OPEN'/)
console.log('Ticket09 前端实时控制台契约通过')