diff --git a/tests/e2e/helpers/meshTrafficTest.ts b/tests/e2e/helpers/meshTrafficTest.ts new file mode 100644 index 0000000..d561cf3 --- /dev/null +++ b/tests/e2e/helpers/meshTrafficTest.ts @@ -0,0 +1,33 @@ +/** + * Extended Playwright test fixture for tests that depend on receiving + * messages from other nodes on the mesh network. + * + * Usage: + * import { test, expect } from '../helpers/meshTrafficTest'; + * test('my test', { tag: '@mesh-traffic' }, async ({ page }) => { ... }); + * + * When a @mesh-traffic-tagged test fails, an advisory annotation is added + * to the HTML report and a console message is printed, letting the user + * know the failure may be due to low mesh traffic rather than a real bug. + */ +import { test as base, expect } from '@playwright/test'; + +export { expect }; + +const TRAFFIC_ADVISORY = + 'This test depends on receiving messages from other nodes on the mesh ' + + 'network. Failure may indicate insufficient mesh traffic rather than a bug.'; + +export const test = base.extend<{ _meshTrafficAdvisory: void }>({ + _meshTrafficAdvisory: [ + async ({}, use, testInfo) => { + await use(); + if (testInfo.status !== 'passed' && testInfo.tags.includes('@mesh-traffic')) { + testInfo.annotations.push({ type: 'notice', description: TRAFFIC_ADVISORY }); + // Also print to console so it's visible in terminal output + console.log(`\n⚠️ ${TRAFFIC_ADVISORY}\n`); + } + }, + { auto: true }, + ], +}); diff --git a/tests/e2e/specs/incoming-message.spec.ts b/tests/e2e/specs/incoming-message.spec.ts index 7719fae..3987579 100644 --- a/tests/e2e/specs/incoming-message.spec.ts +++ b/tests/e2e/specs/incoming-message.spec.ts @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/test'; +import { test, expect } from '../helpers/meshTrafficTest'; import { createChannel, getChannels, getMessages } from '../helpers/api'; /** @@ -54,7 +54,7 @@ test.describe('Incoming mesh messages', () => { } }); - test('receive an incoming message in any room', async ({ page }) => { + test('receive an incoming message in any room', { tag: '@mesh-traffic' }, async ({ page }) => { await page.goto('/'); await expect(page.getByText('Connected')).toBeVisible(); @@ -102,7 +102,7 @@ test.describe('Incoming mesh messages', () => { }); }); - test('incoming message with path shows hop badge and path modal', async ({ page }) => { + test('incoming message with path shows hop badge and path modal', { tag: '@mesh-traffic' }, async ({ page }) => { await page.goto('/'); await expect(page.getByText('Connected')).toBeVisible(); diff --git a/tests/e2e/specs/packet-feed.spec.ts b/tests/e2e/specs/packet-feed.spec.ts index 6dca2a7..8d84fed 100644 --- a/tests/e2e/specs/packet-feed.spec.ts +++ b/tests/e2e/specs/packet-feed.spec.ts @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/test'; +import { test, expect } from '../helpers/meshTrafficTest'; test.describe('Packet Feed page', () => { test('packet feed page loads and shows header', async ({ page }) => { @@ -7,7 +7,7 @@ test.describe('Packet Feed page', () => { await expect(page.getByText('Raw Packet Feed')).toBeVisible({ timeout: 10_000 }); }); - test('a packet appears in the raw packet feed', async ({ page }) => { + test('a packet appears in the raw packet feed', { tag: '@mesh-traffic' }, async ({ page }) => { // This test waits for real RF traffic — needs 180s timeout test.setTimeout(180_000);