diff --git a/.github/agents/pr-reviewer.agent.md b/.github/agents/pr-reviewer.agent.md index 357fbca5..9def873b 100644 --- a/.github/agents/pr-reviewer.agent.md +++ b/.github/agents/pr-reviewer.agent.md @@ -28,7 +28,7 @@ You will pay special attention to the following areas during your review: - **Project Architecture**: Does the PR respect the single Node.js server + static frontend architecture? Are changes in the right place? ### 2. Testing and Validation -- **No commit without tests**: Is the backend logic change covered by unit tests? Is `test-packet-filter.js` or `test-aging.js` updated if necessary? +- **No commit without tests**: Is the backend logic change covered by unit tests? Is `tests/unit/test-packet-filter.js` or `tests/unit/test-aging.js` updated if necessary? - **Browser Validation**: Has the contributor confirmed the change works in a browser? Is there a screenshot for visual changes? - **Cache Busters**: If any `public/` assets (`.js`, `.css`) were modified, has the cache buster in `public/index.html` been bumped in the *same commit*? This is critical. diff --git a/.github/instructions/copilot.instructions.md b/.github/instructions/copilot.instructions.md index 357fbca5..9def873b 100644 --- a/.github/instructions/copilot.instructions.md +++ b/.github/instructions/copilot.instructions.md @@ -28,7 +28,7 @@ You will pay special attention to the following areas during your review: - **Project Architecture**: Does the PR respect the single Node.js server + static frontend architecture? Are changes in the right place? ### 2. Testing and Validation -- **No commit without tests**: Is the backend logic change covered by unit tests? Is `test-packet-filter.js` or `test-aging.js` updated if necessary? +- **No commit without tests**: Is the backend logic change covered by unit tests? Is `tests/unit/test-packet-filter.js` or `tests/unit/test-aging.js` updated if necessary? - **Browser Validation**: Has the contributor confirmed the change works in a browser? Is there a screenshot for visual changes? - **Cache Busters**: If any `public/` assets (`.js`, `.css`) were modified, has the cache buster in `public/index.html` been bumped in the *same commit*? This is critical. diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 737fee93..bd522b19 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -472,7 +472,7 @@ jobs: - name: Run Playwright E2E tests (fail-fast) run: | - BASE_URL=http://localhost:13581 node test-e2e-playwright.js 2>&1 | tee e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-e2e-playwright.js 2>&1 | tee e2e-output.txt # M5+M6 of #1668 — axe-core CI gate. # M5: color-contrast on desktop dark+light. # M6: expanded ruleset (image-alt, label, aria-required-attr, @@ -483,100 +483,100 @@ jobs: # Allowlist: tests/a11y-allowlist.yaml (0 entries — hard pass policy). # Per-viewport summary printed at the end; any net>0 fails the build. BASE_URL=http://localhost:13581 AXE_SCREENSHOT_DIR=/tmp/axe-1668 \ - node test-a11y-axe-1668.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-filter-ux-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-channel-issue-1087-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-channel-issue-1111-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-map-modal-fluid-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-map-nodes-pagination-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-observer-iata-1188-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1639-observers-sort-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1758-ng-filter-rerenders-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-nav-fluid-1055-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-nav-priority-1102-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-nav-priority-1311-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-nav-priority-1391-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1413-nav-overlap-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1400-nav-vertical-clip.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-nav-more-floor-1139-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-bottom-nav-1061-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-gestures-1062-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-gestures-1185-scroll-discriminator-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-gesture-hints-1065-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-touch-gestures-coverage-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-channel-fluid-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-table-fluid-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-charts-fluid-1058-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-slideover-1056-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1692-packets-init-parallel-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-slideover-1168-munger-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-logo-pulse-1173-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1122-packets-filter-ux-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1128-packets-layout-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1128-multi-viewport-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1136-live-region-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-live-multibyte-only-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1150-404-state-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1146-path-link-contrast-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 node test-issue-1705-subpath-contrast-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1147-section-order-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1151-orphan-separators-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1486-collapse-reopens-detail-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-logo-rebrand-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-logo-theme-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-logo-default-sage-teal-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1109-hamburger-dropdown-visible-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-live-layout-1178-1179-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1205-live-controls-anchor-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-live-mql-leak-1180-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1204-live-panel-structure-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1234-live-chrome-pass2-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1206-vcr-overlap-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1244-live-vcr-row-hints-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1510-live-nav-pin-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-live-fullscreen-1572-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1599-replay-freeze-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1648-m1-icons-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1648-m2-icons-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1648-m3-icons-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1648-m4-icons-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1657-analytics-channels-group-sprites-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1224-channels-mobile-ux-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1367-channels-chat-app-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1236-map-mobile-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1329-map-controls-accordion-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1273-qr-overlay-height-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1281-location-row-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1279-legend-p2-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-issue-1799-label-vocab-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-home-coverage-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-path-inspector-coverage-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1206-resize-observer-leak-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-nav-drawer-1064-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-audio-live-1297-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-audio-lab-1297-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-channel-decrypt-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-channel-qr-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-channel-color-picker-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-customize-theme-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-customize-branding-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-customize-display-e2e.js 2>&1 | tee -a e2e-output.txt - BASE_URL=http://localhost:13581 node test-customize-export-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-drag-manager-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1567-corner-clears-drag-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1306-collisions-terminology-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1374-route-map-a11y-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-channels-list-render-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-channels-selection-flow-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-channels-add-modal-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-channels-share-color-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-channels-ws-batch-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-channels-ws-race-1498-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1487-byop-modal-layout-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1630-reach-mobile-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-node-reach-coverage-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node test-issue-1640-compare-discovery-e2e.js 2>&1 | tee -a e2e-output.txt - CHROMIUM_REQUIRE=1 node test-neighbor-map-btn-clip-e2e.js 2>&1 | tee -a e2e-output.txt + node tests/e2e/test-a11y-axe-1668.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-filter-ux-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-channel-issue-1087-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-channel-issue-1111-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-map-modal-fluid-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-map-nodes-pagination-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-observer-iata-1188-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1639-observers-sort-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1758-ng-filter-rerenders-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-nav-fluid-1055-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-nav-priority-1102-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-nav-priority-1311-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-nav-priority-1391-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1413-nav-overlap-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1400-nav-vertical-clip.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-nav-more-floor-1139-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-bottom-nav-1061-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-gestures-1062-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-gestures-1185-scroll-discriminator-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-gesture-hints-1065-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-touch-gestures-coverage-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-channel-fluid-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-table-fluid-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-charts-fluid-1058-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-slideover-1056-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1692-packets-init-parallel-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-slideover-1168-munger-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-logo-pulse-1173-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1122-packets-filter-ux-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1128-packets-layout-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1128-multi-viewport-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1136-live-region-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-live-multibyte-only-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1150-404-state-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1146-path-link-contrast-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 node tests/e2e/test-issue-1705-subpath-contrast-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1147-section-order-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1151-orphan-separators-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1486-collapse-reopens-detail-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-logo-rebrand-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-logo-theme-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-logo-default-sage-teal-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1109-hamburger-dropdown-visible-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-live-layout-1178-1179-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1205-live-controls-anchor-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-live-mql-leak-1180-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1204-live-panel-structure-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1234-live-chrome-pass2-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1206-vcr-overlap-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1244-live-vcr-row-hints-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1510-live-nav-pin-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-live-fullscreen-1572-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1599-replay-freeze-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1648-m1-icons-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1648-m2-icons-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1648-m3-icons-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1648-m4-icons-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1657-analytics-channels-group-sprites-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1224-channels-mobile-ux-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1367-channels-chat-app-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1236-map-mobile-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1329-map-controls-accordion-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1273-qr-overlay-height-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1281-location-row-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1279-legend-p2-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1799-label-vocab-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-home-coverage-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-path-inspector-coverage-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1206-resize-observer-leak-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-nav-drawer-1064-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-audio-live-1297-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-audio-lab-1297-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-channel-decrypt-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-channel-qr-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-channel-color-picker-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-customize-theme-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-customize-branding-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-customize-display-e2e.js 2>&1 | tee -a e2e-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-customize-export-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-drag-manager-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1567-corner-clears-drag-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1306-collisions-terminology-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1374-route-map-a11y-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-channels-list-render-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-channels-selection-flow-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-channels-add-modal-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-channels-share-color-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-channels-ws-batch-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-channels-ws-race-1498-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1487-byop-modal-layout-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1630-reach-mobile-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-node-reach-coverage-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 BASE_URL=http://localhost:13581 node tests/e2e/test-issue-1640-compare-discovery-e2e.js 2>&1 | tee -a e2e-output.txt + CHROMIUM_REQUIRE=1 node tests/e2e/test-neighbor-map-btn-clip-e2e.js 2>&1 | tee -a e2e-output.txt # #1616: slide-over focus-restore flake-gate. Runs the slide-over # E2E 20 consecutive times against the SAME backend instance so @@ -594,7 +594,7 @@ jobs: set -e for i in $(seq 1 3); do echo "--- slide-over E2E run $i/20 ---" - BASE_URL=http://localhost:13581 node test-slideover-1056-e2e.js 2>&1 | tee -a slideover-repeat-output.txt + BASE_URL=http://localhost:13581 node tests/e2e/test-slideover-1056-e2e.js 2>&1 | tee -a slideover-repeat-output.txt done echo "3 passed" diff --git a/.squad/agents/bishop/charter.md b/.squad/agents/bishop/charter.md index 09b0a5d8..5ce7d6fe 100644 --- a/.squad/agents/bishop/charter.md +++ b/.squad/agents/bishop/charter.md @@ -10,16 +10,15 @@ Unit tests, Playwright E2E, coverage gates, and quality assurance for CoreScope. ## Responsibilities -- Unit tests: test-packet-filter.js, test-aging.js, test-decoder.js, test-decoder-spec.js, test-server-helpers.js, test-server-routes.js, test-packet-store.js, test-db.js, test-frontend-helpers.js, test-regional-filter.js, test-regional-integration.js, test-live-dedup.js -- Playwright E2E: test-e2e-playwright.js (8 browser tests, default localhost:3000) -- E2E tools: tools/e2e-test.js, tools/frontend-test.js +- Unit tests: `tests/unit/`, all listed in `test-all.sh` (e.g. test-packet-filter.js, test-aging.js, test-frontend-helpers.js); Go tests under `cmd/` +- Playwright E2E: `tests/e2e/`, classified in `scripts/non-unit-tests.json` (e.g. test-e2e-playwright.js, default localhost:3000) - Coverage: Backend 85%+ (c8), Frontend 42%+ (Istanbul + nyc). Both only go up. - Review authority: May approve or reject work from Hicks and Newt based on test results ## Boundaries - Test the REAL code — import actual modules, don't copy-paste functions into test files -- Use vm.createContext for frontend helpers (see test-frontend-helpers.js pattern) +- Use vm.createContext for frontend helpers (see tests/unit/test-frontend-helpers.js pattern) - Playwright tests default to localhost:3000 — NEVER run against prod - Every bug fix gets a regression test - Every new feature must add tests — test count only goes up @@ -37,10 +36,9 @@ Unit tests, Playwright E2E, coverage gates, and quality assurance for CoreScope. npm test # all backend tests + coverage summary npm run test:unit # fast: unit tests only npm run test:coverage # all tests + HTML coverage report -node test-packet-filter.js # filter engine -node test-decoder.js # packet decoder -node test-server-routes.js # API routes via supertest -node test-e2e-playwright.js # 8 Playwright browser tests +sh test-all.sh # every suite in tests/unit +node tests/unit/test-packet-filter.js # filter engine +node tests/e2e/test-e2e-playwright.js # Playwright browser tests ``` ## Model diff --git a/.squad/agents/newt/charter.md b/.squad/agents/newt/charter.md index 223f424b..fc87a6f5 100644 --- a/.squad/agents/newt/charter.md +++ b/.squad/agents/newt/charter.md @@ -24,7 +24,7 @@ Vanilla JS UI, Leaflet maps, live visualization, theming, and all public/ module - Use shared helpers from roles.js (ROLE_COLORS, TYPE_COLORS, getNodeStatus, getHealthThresholds) - Prefer `n.last_heard || n.last_seen` for display and status - No per-packet API calls from frontend — fetch bulk, filter client-side -- Run `node test-packet-filter.js` and `node test-frontend-helpers.js` after filter/helper changes +- Run `node tests/unit/test-packet-filter.js` and `node tests/unit/test-frontend-helpers.js` after filter/helper changes - Always bump cache busters in the SAME commit as code changes ## Key Files diff --git a/AGENTS.md b/AGENTS.md index fb25c6d5..badc8208 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -90,7 +90,7 @@ Every change must consider performance impact BEFORE implementation. This codeba No proof = no merge. ### 1. No commit without tests -Every change that touches logic MUST have tests. For Go backend: `cd cmd/server && go test ./...` and `cd cmd/ingestor && go test ./...`, or `make test` for all 14 modules. For frontend: `node test-packet-filter.js && node test-aging.js && node test-frontend-helpers.js`. If you add new logic, add tests. No exceptions. +Every change that touches logic MUST have tests. For Go backend: `cd cmd/server && go test ./...` and `cd cmd/ingestor && go test ./...`, or `make test` for all 14 modules. For frontend: `node tests/unit/test-packet-filter.js && node tests/unit/test-aging.js && node tests/unit/test-frontend-helpers.js`. If you add new logic, add tests. No exceptions. The SQLite driver (`github.com/mattn/go-sqlite3`) is cgo. **`CGO_ENABLED=0` still *builds*** — that is the trap. It links a stub, and the binary dies on the first query with `go-sqlite3 requires cgo to work. This is a stub`, so a green build proves nothing. A plain `GOOS=linux go build` likewise cannot cross-compile it. Use `make build` / `make crossbuild` — the latter needs [`zig`](https://ziglang.org/download/) as the cross C compiler and produces static musl binaries. Never re-add `CGO_ENABLED=0`. @@ -202,7 +202,7 @@ All colors MUST use CSS variables. Never hardcode `#hex` values outside of `:roo ### Packet Filter (packet-filter.js) Standalone module. No dependencies on app globals (copies what it needs). Testable in Node.js: ```bash -node test-packet-filter.js +node tests/unit/test-packet-filter.js ``` Uses firmware-standard type names (GRP_TXT, TXT_MSG, REQ) with aliases for convenience. @@ -219,21 +219,13 @@ npm run test:full-coverage # backend + instrumented frontend coverage via Playw ### Test Files ```bash # Backend (deterministic, run before every push) -node test-packet-filter.js # filter engine -node test-aging.js # node aging system -node test-regional-filter.js # regional observer filtering -node test-decoder.js # packet decoder -node test-decoder-spec.js # spec-driven + golden fixture tests -node test-server-helpers.js # extracted server functions -node test-server-routes.js # API route tests via supertest -node test-packet-store.js # in-memory packet store -node test-db.js # SQLite operations -node test-frontend-helpers.js # frontend logic (via vm.createContext) -node tools/e2e-test.js # E2E: temp server + synthetic packets -node tools/frontend-test.js # frontend smoke: HTML, JS refs, API shapes +sh test-all.sh # every suite in tests/unit +node tests/unit/test-packet-filter.js # filter engine +node tests/unit/test-aging.js # node aging system +node tests/unit/test-frontend-helpers.js # frontend logic (via vm.createContext) # Frontend E2E (requires running server or Playwright) -node test-e2e-playwright.js # 8 Playwright browser tests (default: localhost:3000) +node tests/e2e/test-e2e-playwright.js # Playwright browser tests (default: localhost:3000) ``` ### Rules @@ -248,14 +240,14 @@ node test-e2e-playwright.js # 8 Playwright browser tests (default: localho 2. Write unit tests for the logic 3. Write/update Playwright tests if it's a UI change 4. Run `npm test` — all tests must pass -5. Run `node test-e2e-playwright.js` against a local server — E2E must pass +5. Run `node tests/e2e/test-e2e-playwright.js` against a local server — E2E must pass 6. THEN push to master ### Testing infrastructure - **Backend coverage**: c8 tracks server-side code in-process - **Frontend coverage**: Istanbul instruments `public/*.js` → Playwright exercises them → `window.__coverage__` extracted → nyc reports. Instrumented files are generated fresh each CI run, never checked in. - **CI pipeline**: backend tests + coverage → instrument frontend → start local server → Playwright E2E + coverage collection → badges update → deploy (only if all pass) -- **Playwright tests default to localhost:3000** — NEVER run against prod. CI sets `BASE_URL=http://localhost:13581`. Running locally: start your server, then `node test-e2e-playwright.js` +- **Playwright tests default to localhost:3000** — NEVER run against prod. CI sets `BASE_URL=http://localhost:13581`. Running locally: start your server, then `node tests/e2e/test-e2e-playwright.js` - **ARM machines**: Basic Playwright tests work with system chromium (`CHROMIUM_PATH=/usr/bin/chromium-browser`). Heavy coverage collection scripts may crash — use CI for those. Tests that need live mesh data can use `https://analyzer.00id.net` — all API endpoints are public, no auth required. @@ -290,7 +282,7 @@ If the same logic exists in two places, it MUST be extracted into a shared funct ### Testability - **Write functions that are easy to test.** Pure functions (input → output, no side effects) are ideal. If a function reads from the DOM, the DB, and localStorage, it's untestable without mocking everything. - **Dependency injection enables testing.** Pass the node list, the map reference, the API function as parameters. Tests can substitute fakes. -- **Test the real code, not copies.** Don't paste a function into a test file and test the copy. Import/require the actual module. If the module isn't importable (IIFE, browser-only), refactor it so it is — or use `vm.createContext` like `test-frontend-helpers.js` does. +- **Test the real code, not copies.** Don't paste a function into a test file and test the copy. Import/require the actual module. If the module isn't importable (IIFE, browser-only), refactor it so it is — or use `vm.createContext` like `tests/unit/test-frontend-helpers.js` does. - **Every bug fix gets a regression test.** If it broke once, it'll break again. The test proves it stays fixed. ### Type Safety (without TypeScript) @@ -372,7 +364,7 @@ One logical change per commit. Each commit is deployable. Each commit has its te | Subagent timed out mid-work | 4 | Give clear scope, don't try to run slow pipelines locally | ## File Naming -- Tests: `test-{feature}.js` in repo root +- Tests: `test-{feature}.js` in `tests/unit/` (standalone, listed in `test-all.sh`) or `tests/e2e/` (browser, listed in `scripts/non-unit-tests.json`) — never in repo root - No build step, no transpilation — write ES2020 for server, ES5/6 for frontend (broad browser support) ### Deep Linking diff --git a/README.md b/README.md index b06d54a4..7345d3d0 100644 --- a/README.md +++ b/README.md @@ -228,7 +228,8 @@ corescope/ │ └── entrypoint-go.sh # Container entrypoint ├── Dockerfile # Multi-stage Go build + Alpine runtime ├── config.example.json # Example configuration -├── test-*.js # Node.js test suite (frontend + legacy) +├── tests/ # Node.js test suite: unit/ (test-all.sh) and e2e/ (Playwright) +├── test-all.sh # Runs every suite in tests/unit └── tools/ # Generators, E2E tests, utilities ``` @@ -266,7 +267,7 @@ make test npm test # Playwright E2E (requires running server on localhost:3000) -node test-e2e-playwright.js +node tests/e2e/test-e2e-playwright.js ``` ### Generate Test Data diff --git a/docs/agents/skills/fix-issue.md b/docs/agents/skills/fix-issue.md index dc2397a2..6fe5109b 100644 --- a/docs/agents/skills/fix-issue.md +++ b/docs/agents/skills/fix-issue.md @@ -55,7 +55,7 @@ If the fix touches ANY frontend file (`public/*.js`, `public/*.css`, or HTML) AN as a user-visible UX behavior (click/hover/navigation/rendering), the PR MUST include a browser-level assertion that would have caught the original bug — NOT only unit tests. -- Look for an existing E2E harness first (e.g. `test-e2e-playwright.js`, `e2e/`, `tests/e2e/`, +- Look for an existing E2E harness first (e.g. `tests/e2e/test-e2e-playwright.js`, `e2e/`, `tests/e2e/`, `playwright.config.*`, or whatever the repo uses). Add the assertion there. - If no E2E harness exists, ADD a small one rather than skip. A 30-line Playwright fixture hitting a public staging URL is acceptable. diff --git a/docs/frontend-testing.md b/docs/frontend-testing.md index ec2803bf..a13eaa3c 100644 --- a/docs/frontend-testing.md +++ b/docs/frontend-testing.md @@ -13,13 +13,17 @@ Windows, use Git Bash and ensure `python3` resolves to Python 3 rather than a Microsoft Store alias; set `PYTHONUTF8=1` for the gate's Unicode output. No server or browser is started by this runner. -When adding a root `test-*.js` file: +Tests live in `tests/unit/` (standalone Node, run by `test-all.sh`) and +`tests/e2e/` (needs a browser, a server or extra tooling). They run from the +repo root, and refer to it as `REPO_ROOT`. When adding a `test-*.js` file: -1. Add its `node test-name.js` command to `test-all.sh` if it runs standalone. -2. Otherwise add it to `scripts/non-unit-tests.json`, with a prerequisite or +1. If it runs standalone, put it in `tests/unit/` and add its + `node tests/unit/test-name.js` command to `test-all.sh`. +2. Otherwise put it in `tests/e2e/` and add it to `scripts/non-unit-tests.json`, with a prerequisite or reason explaining why it belongs outside the unit runner. Browser suites still need explicit selection in the E2E workflow to become CI gates. -3. Run `node test-test-inventory.js`. The guard rejects unclassified files, +3. Run `node tests/unit/test-test-inventory.js`. The guard rejects `test-*.js` + files in the repo root, unclassified files, duplicate assignments, removed files left in a list, undocumented groups, and local/CI entry points that bypass the unit runner. diff --git a/scripts/non-unit-tests.json b/scripts/non-unit-tests.json index 85770ed6..3d7c59fc 100644 --- a/scripts/non-unit-tests.json +++ b/scripts/non-unit-tests.json @@ -2,129 +2,129 @@ "browser": { "reason": "Requires Playwright and Chromium; most suites also require a running local fixture server via BASE_URL. Existing E2E workflow steps retain their separate setup and selection. Never point these tests at production.", "files": [ - "test-1110-live-filter.js", - "test-a11y-axe-1668.js", - "test-analytics-fluid-charts.js", - "test-audio-lab-1297-e2e.js", - "test-audio-live-1297-e2e.js", - "test-bottom-nav-1061-e2e.js", - "test-channel-color-picker-e2e.js", - "test-channel-decrypt-e2e.js", - "test-channel-fluid-e2e.js", - "test-channel-issue-1087-e2e.js", - "test-channel-issue-1111-e2e.js", - "test-channel-modal-e2e.js", - "test-channel-qr-e2e.js", - "test-channels-add-modal-e2e.js", - "test-channels-list-render-e2e.js", - "test-channels-selection-flow-e2e.js", - "test-channels-share-color-e2e.js", - "test-channels-ws-batch-e2e.js", - "test-channels-ws-race-1498-e2e.js", - "test-charts-fluid-1058-e2e.js", - "test-customize-branding-e2e.js", - "test-customize-display-e2e.js", - "test-customize-export-e2e.js", - "test-customize-theme-e2e.js", - "test-drag-manager-e2e.js", - "test-e2e-1267-mobile-vcr.js", - "test-e2e-playwright.js", - "test-filter-ux-e2e.js", - "test-gesture-hints-1065-e2e.js", - "test-gestures-1062-e2e.js", - "test-gestures-1185-scroll-discriminator-e2e.js", - "test-home-coverage-e2e.js", - "test-issue-1109-hamburger-dropdown-visible-e2e.js", - "test-issue-1122-packets-filter-ux-e2e.js", - "test-issue-1128-multi-viewport-e2e.js", - "test-issue-1128-packets-layout-e2e.js", - "test-issue-1136-live-region-e2e.js", - "test-issue-1146-path-link-contrast-e2e.js", - "test-issue-1147-section-order-e2e.js", - "test-issue-1150-404-state-e2e.js", - "test-issue-1151-orphan-separators-e2e.js", - "test-issue-1204-live-panel-structure-e2e.js", - "test-issue-1205-live-controls-anchor-e2e.js", - "test-issue-1206-resize-observer-leak-e2e.js", - "test-issue-1206-vcr-overlap-e2e.js", - "test-issue-1224-channels-mobile-ux-e2e.js", - "test-issue-1234-live-chrome-pass2-e2e.js", - "test-issue-1236-map-mobile-e2e.js", - "test-issue-1244-live-vcr-row-hints-e2e.js", - "test-issue-1273-qr-overlay-height-e2e.js", - "test-issue-1274-legend-coverage-e2e.js", - "test-issue-1279-legend-p2-e2e.js", - "test-issue-1281-location-row-e2e.js", - "test-issue-1306-collisions-terminology-e2e.js", - "test-issue-1329-map-controls-accordion-e2e.js", - "test-issue-1367-channels-chat-app-e2e.js", - "test-issue-1374-route-map-a11y-e2e.js", - "test-issue-1400-nav-vertical-clip.js", - "test-issue-1413-nav-overlap-e2e.js", - "test-issue-1486-collapse-reopens-detail-e2e.js", - "test-issue-1487-byop-modal-layout-e2e.js", - "test-issue-1510-live-nav-pin-e2e.js", - "test-issue-1567-corner-clears-drag-e2e.js", - "test-issue-1599-replay-freeze-e2e.js", - "test-issue-1630-reach-mobile-e2e.js", - "test-issue-1639-observers-sort-e2e.js", - "test-issue-1640-compare-discovery-e2e.js", - "test-issue-1648-m1-icons-e2e.js", - "test-issue-1648-m2-icons-e2e.js", - "test-issue-1648-m3-icons-e2e.js", - "test-issue-1648-m4-icons-e2e.js", - "test-issue-1648-m5-icons-e2e.js", - "test-issue-1657-analytics-channels-group-sprites-e2e.js", - "test-issue-1692-packets-init-parallel-e2e.js", - "test-issue-1705-subpath-contrast-e2e.js", - "test-issue-1758-ng-filter-rerenders-e2e.js", - "test-issue-1799-label-vocab-e2e.js", - "test-live-dedup.js", - "test-live-fullscreen-1572-e2e.js", - "test-live-layout-1178-1179-e2e.js", - "test-live-mql-leak-1180-e2e.js", - "test-live-multibyte-only-e2e.js", - "test-logo-default-sage-teal-e2e.js", - "test-logo-pulse-1173-e2e.js", - "test-logo-rebrand-e2e.js", - "test-logo-theme-e2e.js", - "test-map-modal-fluid-e2e.js", - "test-map-nodes-pagination-e2e.js", - "test-nav-drawer-1064-e2e.js", - "test-nav-fluid-1055-e2e.js", - "test-nav-more-floor-1139-e2e.js", - "test-nav-priority-1102-e2e.js", - "test-nav-priority-1311-e2e.js", - "test-nav-priority-1391-e2e.js", - "test-neighbor-map-btn-clip-e2e.js", - "test-node-reach-coverage-e2e.js", - "test-node-reach-e2e.js", - "test-nodes-export-e2e.js", - "test-observer-iata-1188-e2e.js", - "test-packets-scope-column.js", - "test-path-inspector-coverage-e2e.js", - "test-rx-coverage-mobile-nav-e2e.js", - "test-show-neighbors.js", - "test-slideover-1056-e2e.js", - "test-slideover-1168-munger-e2e.js", - "test-table-fluid-e2e.js", - "test-touch-gestures-coverage-e2e.js", - "test-touch-targets.js" + "tests/e2e/test-1110-live-filter.js", + "tests/e2e/test-a11y-axe-1668.js", + "tests/e2e/test-analytics-fluid-charts.js", + "tests/e2e/test-audio-lab-1297-e2e.js", + "tests/e2e/test-audio-live-1297-e2e.js", + "tests/e2e/test-bottom-nav-1061-e2e.js", + "tests/e2e/test-channel-color-picker-e2e.js", + "tests/e2e/test-channel-decrypt-e2e.js", + "tests/e2e/test-channel-fluid-e2e.js", + "tests/e2e/test-channel-issue-1087-e2e.js", + "tests/e2e/test-channel-issue-1111-e2e.js", + "tests/e2e/test-channel-modal-e2e.js", + "tests/e2e/test-channel-qr-e2e.js", + "tests/e2e/test-channels-add-modal-e2e.js", + "tests/e2e/test-channels-list-render-e2e.js", + "tests/e2e/test-channels-selection-flow-e2e.js", + "tests/e2e/test-channels-share-color-e2e.js", + "tests/e2e/test-channels-ws-batch-e2e.js", + "tests/e2e/test-channels-ws-race-1498-e2e.js", + "tests/e2e/test-charts-fluid-1058-e2e.js", + "tests/e2e/test-customize-branding-e2e.js", + "tests/e2e/test-customize-display-e2e.js", + "tests/e2e/test-customize-export-e2e.js", + "tests/e2e/test-customize-theme-e2e.js", + "tests/e2e/test-drag-manager-e2e.js", + "tests/e2e/test-e2e-1267-mobile-vcr.js", + "tests/e2e/test-e2e-playwright.js", + "tests/e2e/test-filter-ux-e2e.js", + "tests/e2e/test-gesture-hints-1065-e2e.js", + "tests/e2e/test-gestures-1062-e2e.js", + "tests/e2e/test-gestures-1185-scroll-discriminator-e2e.js", + "tests/e2e/test-home-coverage-e2e.js", + "tests/e2e/test-issue-1109-hamburger-dropdown-visible-e2e.js", + "tests/e2e/test-issue-1122-packets-filter-ux-e2e.js", + "tests/e2e/test-issue-1128-multi-viewport-e2e.js", + "tests/e2e/test-issue-1128-packets-layout-e2e.js", + "tests/e2e/test-issue-1136-live-region-e2e.js", + "tests/e2e/test-issue-1146-path-link-contrast-e2e.js", + "tests/e2e/test-issue-1147-section-order-e2e.js", + "tests/e2e/test-issue-1150-404-state-e2e.js", + "tests/e2e/test-issue-1151-orphan-separators-e2e.js", + "tests/e2e/test-issue-1204-live-panel-structure-e2e.js", + "tests/e2e/test-issue-1205-live-controls-anchor-e2e.js", + "tests/e2e/test-issue-1206-resize-observer-leak-e2e.js", + "tests/e2e/test-issue-1206-vcr-overlap-e2e.js", + "tests/e2e/test-issue-1224-channels-mobile-ux-e2e.js", + "tests/e2e/test-issue-1234-live-chrome-pass2-e2e.js", + "tests/e2e/test-issue-1236-map-mobile-e2e.js", + "tests/e2e/test-issue-1244-live-vcr-row-hints-e2e.js", + "tests/e2e/test-issue-1273-qr-overlay-height-e2e.js", + "tests/e2e/test-issue-1274-legend-coverage-e2e.js", + "tests/e2e/test-issue-1279-legend-p2-e2e.js", + "tests/e2e/test-issue-1281-location-row-e2e.js", + "tests/e2e/test-issue-1306-collisions-terminology-e2e.js", + "tests/e2e/test-issue-1329-map-controls-accordion-e2e.js", + "tests/e2e/test-issue-1367-channels-chat-app-e2e.js", + "tests/e2e/test-issue-1374-route-map-a11y-e2e.js", + "tests/e2e/test-issue-1400-nav-vertical-clip.js", + "tests/e2e/test-issue-1413-nav-overlap-e2e.js", + "tests/e2e/test-issue-1486-collapse-reopens-detail-e2e.js", + "tests/e2e/test-issue-1487-byop-modal-layout-e2e.js", + "tests/e2e/test-issue-1510-live-nav-pin-e2e.js", + "tests/e2e/test-issue-1567-corner-clears-drag-e2e.js", + "tests/e2e/test-issue-1599-replay-freeze-e2e.js", + "tests/e2e/test-issue-1630-reach-mobile-e2e.js", + "tests/e2e/test-issue-1639-observers-sort-e2e.js", + "tests/e2e/test-issue-1640-compare-discovery-e2e.js", + "tests/e2e/test-issue-1648-m1-icons-e2e.js", + "tests/e2e/test-issue-1648-m2-icons-e2e.js", + "tests/e2e/test-issue-1648-m3-icons-e2e.js", + "tests/e2e/test-issue-1648-m4-icons-e2e.js", + "tests/e2e/test-issue-1648-m5-icons-e2e.js", + "tests/e2e/test-issue-1657-analytics-channels-group-sprites-e2e.js", + "tests/e2e/test-issue-1692-packets-init-parallel-e2e.js", + "tests/e2e/test-issue-1705-subpath-contrast-e2e.js", + "tests/e2e/test-issue-1758-ng-filter-rerenders-e2e.js", + "tests/e2e/test-issue-1799-label-vocab-e2e.js", + "tests/e2e/test-live-dedup.js", + "tests/e2e/test-live-fullscreen-1572-e2e.js", + "tests/e2e/test-live-layout-1178-1179-e2e.js", + "tests/e2e/test-live-mql-leak-1180-e2e.js", + "tests/e2e/test-live-multibyte-only-e2e.js", + "tests/e2e/test-logo-default-sage-teal-e2e.js", + "tests/e2e/test-logo-pulse-1173-e2e.js", + "tests/e2e/test-logo-rebrand-e2e.js", + "tests/e2e/test-logo-theme-e2e.js", + "tests/e2e/test-map-modal-fluid-e2e.js", + "tests/e2e/test-map-nodes-pagination-e2e.js", + "tests/e2e/test-nav-drawer-1064-e2e.js", + "tests/e2e/test-nav-fluid-1055-e2e.js", + "tests/e2e/test-nav-more-floor-1139-e2e.js", + "tests/e2e/test-nav-priority-1102-e2e.js", + "tests/e2e/test-nav-priority-1311-e2e.js", + "tests/e2e/test-nav-priority-1391-e2e.js", + "tests/e2e/test-neighbor-map-btn-clip-e2e.js", + "tests/e2e/test-node-reach-coverage-e2e.js", + "tests/e2e/test-node-reach-e2e.js", + "tests/e2e/test-nodes-export-e2e.js", + "tests/e2e/test-observer-iata-1188-e2e.js", + "tests/e2e/test-packets-scope-column.js", + "tests/e2e/test-path-inspector-coverage-e2e.js", + "tests/e2e/test-rx-coverage-mobile-nav-e2e.js", + "tests/e2e/test-show-neighbors.js", + "tests/e2e/test-slideover-1056-e2e.js", + "tests/e2e/test-slideover-1168-munger-e2e.js", + "tests/e2e/test-table-fluid-e2e.js", + "tests/e2e/test-touch-gestures-coverage-e2e.js", + "tests/e2e/test-touch-targets.js" ] }, "playwrightRunner": { "reason": "Requires the @playwright/test runner (not plain node), its configuration, Chromium, and a local server. @playwright/test is not currently declared in package.json; these suites are inventoried but not part of the standalone unit gate.", "files": [ - "test-issue-1522-trace-url-sync-e2e.js", - "test-marker-outline-weight.js", - "test-path-inspector-e2e.js", - "test-pr-1490-live-map-gpu-animations-e2e.js" + "tests/e2e/test-issue-1522-trace-url-sync-e2e.js", + "tests/e2e/test-marker-outline-weight.js", + "tests/e2e/test-path-inspector-e2e.js", + "tests/e2e/test-pr-1490-live-map-gpu-animations-e2e.js" ] }, "domIntegration": { "reason": "Requires jsdom, which is not currently declared in package.json. This DOM integration suite is inventoried separately; no new dependency is installed by the unit gate.", "files": [ - "test-table-sort.js" + "tests/e2e/test-table-sort.js" ] } } diff --git a/test-all.sh b/test-all.sh index 58c8b4f6..3d6d5245 100755 --- a/test-all.sh +++ b/test-all.sh @@ -1,185 +1,186 @@ #!/bin/sh # Authoritative standalone frontend test list for local runs and CI. -# Every root test is listed here or classified in scripts/non-unit-tests.json. +# Every suite in tests/unit is listed here; every suite in tests/e2e is classified +# in scripts/non-unit-tests.json. set -e cd "$(dirname "$0")" -node test-test-inventory.js -node test-1108-region-hide-nodes.js -node test-1659-analytics-warmup.js -node test-a11y-1705-subpath-hop-prefix-e2e.js -node test-a11y-1715-dark-role-swatches.js -node test-a11y-1716-rf-range-btn-active.js -node test-a11y-1719-contrast-root-causes-e2e.js -node test-a11y-axe-1668-selftest.js -node test-a11y-axe-routes-coverage.js -node test-aging.js -node test-analytics-channels-integration.js -node test-anl1-tooltip-render.js -node test-area-filter.js -node test-channel-color-picker.js -node test-channel-colors.js -node test-channel-decrypt-ecb.js -node test-channel-decrypt-insecure-context.js -node test-channel-decrypt-m345.js -node test-channel-fluid-layout.js -node test-channel-issue-1087.js -node test-channel-issue-1101.js -node test-channel-live-decrypt-userprefix.js -node test-channel-live-decrypt.js -node test-channel-modal-ux.js -node test-channel-psk-ux.js -node test-channel-qr-wiring.js -node test-channel-qr.js -node test-channel-sidebar-layout.js -node test-channel-ux-followup.js -node test-channel-ux-round2.js -node test-channels-merge-1498-unit.js -node test-clear-filters.js -node test-color-picker-ux.js -node test-compare-flood-filter.js -node test-compare-overlap.js -node test-confidence-indicator.js -node test-coverage-gate.js -node test-customizer-v2.js -node test-drag-manager.js -node test-embed-mode-1369.js -node test-fetch-all-nodes-pagination.js -node test-fluid-scaffolding.js -node test-frontend-helpers.js -node test-geofilter-draft.js -node test-hash-color.js -node test-hop-resolver-affinity.js -node test-issue-1065-gesture-hints-gates.js -node test-issue-1107-live-layout.js -node test-issue-1136-observer-iata-map.js -node test-issue-1166-first-seen-column.js -node test-issue-1189-composed-cell.js -node test-issue-1189-live-iata-badge.js -node test-issue-1279-p2-code-filter.js -node test-issue-1293-marker-shapes.js -node test-issue-1356-map-a11y.js -node test-issue-1360-pill-letter-count.js -node test-issue-1361-cb-presets.js -node test-issue-1364-pill-no-clamp.js -node test-issue-1375-scope-stats-fetch.js -node test-issue-1380-cb-reset-button.js -node test-issue-1380-cb-sim-overlay.js -node test-issue-1407-cb-preset-propagation.js -node test-issue-1409-no-encrypted-flood.js -node test-issue-1412-customizer-no-override.js -node test-issue-1415-packets-layout.js -node test-issue-1418-cb-preset-ramp.js -node test-issue-1418-deeplink-hops-channels.js -node test-issue-1418-edge-weights.js -node test-issue-1418-polish-review.js -node test-issue-1418-raw-hex-extraction.js -node test-issue-1418-spider-fan.js -node test-issue-1420-tile-providers.js -node test-issue-1438-customizer-mcrole.js -node test-issue-1438-marker-css-vars.js -node test-issue-1446-cb-preset-cascade.js -node test-issue-1450-logo-aspect.js -node test-issue-1454-channels-toggle.js -node test-issue-1456-score-labels.js -node test-issue-1461-mobile-page-actions.js -node test-issue-1470-card-bg-contrast.js -node test-issue-1470-node-tile-helper.js -node test-issue-1473-prefix-generator.js -node test-issue-1473-reserved-prefixes.js -node test-issue-1485-live-anim-z.js -node test-issue-1488-marker-stroke-vars.js -node test-issue-1496-reset-all-complete.js -node test-issue-1509-detect-preset.js -node test-issue-1509-nav-active-bg.js -node test-issue-1518-home-url.js -node test-issue-1532-live-fullscreen.js -node test-issue-1562-observers-summary.js -node test-issue-1563-aggregate-and-inflight.js -node test-issue-1574-live-map-max-nodes.js -node test-issue-1606-pagination.js -node test-issue-1614-tile-url-function.js -node test-issue-1619-feed-detail-card-draggable.js -node test-issue-1633-hide-1byte-hops.js -node test-issue-1644-redesign.js -node test-issue-1646-compare-polish.js -node test-issue-1648-followup-phosphor-leaks.js -node test-issue-1648-m1-emoji-scan.js -node test-issue-1648-m2-emoji-scan.js -node test-issue-1648-m3-emoji-scan.js -node test-issue-1648-m4-emoji-scan.js -node test-issue-1648-m5-emoji-scan.js -node test-issue-1648-m6-final-sweep.js -node test-issue-1648-m6-lint-self.js -node test-issue-1668-m2-contrast.js -node test-issue-1668-m3-typography.js -node test-issue-1668-m4-per-route.js -node test-issue-1697-mqtt-mobile-e2e.js -node test-issue-1699-retransmission-chart.js -node test-issue-1705-subpath-contrast.js -node test-issue-1753-copy-url-slash.js -node test-issue-1770-mobile-row-clamp.js -node test-issue-1789-observer-firmware-cols.js -node test-issue-1825-observer-node-cross-links.js -node test-issue-1833-legend-toggle-vcr-offset.js -node test-issue-1836-crossnav-case-normalization.js -node test-issue-1843-node-qr-quiet-zone.js -node test-issue-1846-observers-width.js -node test-issue-1849-trace-hashbytes.js -node test-issue-1851-channel-message-scope.js -node test-issue-1862-map-region-filter.js -node test-issue-1868-control-decode.js -node test-issue-1890-og-url.js -node test-issue-1956-release-routing.js -node test-issue-1979-scope-adverts-by-role.js -node test-issue-2001-map-scope-state.js -node test-issue-2012-clear-filters-selection.js -node test-live-anims.js -node test-live-dt-cap-1524.js -node test-live-legend-helper.js -node test-live-multibyte-filter.js -node test-live-region-filter.js -node test-live.js -node test-map-clustering.js -node test-mqtt-status-panel.js -node test-my-repeaters-dashboard.js -node test-naive-banner-tone.js -node test-node-hop-analytics.js -node test-node-reach-coverage-debounce.js -node test-node-reach-coverage.js -node test-nodes-export-wiring.js -node test-nodes-export.js -node test-observer-iata-1188.js -node test-observer-menu-interactions.js -node test-observer-naive-clock-1478.js -node test-observer-search-filter.js -node test-observers-headings.js -node test-packet-filter-time.js -node test-packet-filter-ux.js -node test-packet-filter.js -node test-packets-local-channels.js -node test-packets.js -node test-panel-corner.js -node test-path-inspector.js -node test-payload-labels-content.js -node test-payload-labels-namespace.js -node test-perf-anomaly.js -node test-perf-disk-io-1120.js -node test-perf-go-runtime.js -node test-perf-render-1258.js -node test-preflight-xss-gate.js -node test-pull-to-reconnect-1091.js -node test-pull-to-reconnect.js -node test-repeater-metric-scatter.js -node test-rx-coverage-config-race.js -node test-rx-coverage-escape.js -node test-scope-audit-styles-linked.js -node test-slideover-1056-rowsel-strict.js -node test-top-routes-overlay.js -node test-traces.js -node test-url-state.js -node test-warmup-banner.js -node test-ws-stale-watchdog-1074.js -node test-xss-escape-sinks.js +node tests/unit/test-test-inventory.js +node tests/unit/test-1108-region-hide-nodes.js +node tests/unit/test-1659-analytics-warmup.js +node tests/unit/test-a11y-1705-subpath-hop-prefix-e2e.js +node tests/unit/test-a11y-1715-dark-role-swatches.js +node tests/unit/test-a11y-1716-rf-range-btn-active.js +node tests/unit/test-a11y-1719-contrast-root-causes-e2e.js +node tests/unit/test-a11y-axe-1668-selftest.js +node tests/unit/test-a11y-axe-routes-coverage.js +node tests/unit/test-aging.js +node tests/unit/test-analytics-channels-integration.js +node tests/unit/test-anl1-tooltip-render.js +node tests/unit/test-area-filter.js +node tests/unit/test-channel-color-picker.js +node tests/unit/test-channel-colors.js +node tests/unit/test-channel-decrypt-ecb.js +node tests/unit/test-channel-decrypt-insecure-context.js +node tests/unit/test-channel-decrypt-m345.js +node tests/unit/test-channel-fluid-layout.js +node tests/unit/test-channel-issue-1087.js +node tests/unit/test-channel-issue-1101.js +node tests/unit/test-channel-live-decrypt-userprefix.js +node tests/unit/test-channel-live-decrypt.js +node tests/unit/test-channel-modal-ux.js +node tests/unit/test-channel-psk-ux.js +node tests/unit/test-channel-qr-wiring.js +node tests/unit/test-channel-qr.js +node tests/unit/test-channel-sidebar-layout.js +node tests/unit/test-channel-ux-followup.js +node tests/unit/test-channel-ux-round2.js +node tests/unit/test-channels-merge-1498-unit.js +node tests/unit/test-clear-filters.js +node tests/unit/test-color-picker-ux.js +node tests/unit/test-compare-flood-filter.js +node tests/unit/test-compare-overlap.js +node tests/unit/test-confidence-indicator.js +node tests/unit/test-coverage-gate.js +node tests/unit/test-customizer-v2.js +node tests/unit/test-drag-manager.js +node tests/unit/test-embed-mode-1369.js +node tests/unit/test-fetch-all-nodes-pagination.js +node tests/unit/test-fluid-scaffolding.js +node tests/unit/test-frontend-helpers.js +node tests/unit/test-geofilter-draft.js +node tests/unit/test-hash-color.js +node tests/unit/test-hop-resolver-affinity.js +node tests/unit/test-issue-1065-gesture-hints-gates.js +node tests/unit/test-issue-1107-live-layout.js +node tests/unit/test-issue-1136-observer-iata-map.js +node tests/unit/test-issue-1166-first-seen-column.js +node tests/unit/test-issue-1189-composed-cell.js +node tests/unit/test-issue-1189-live-iata-badge.js +node tests/unit/test-issue-1279-p2-code-filter.js +node tests/unit/test-issue-1293-marker-shapes.js +node tests/unit/test-issue-1356-map-a11y.js +node tests/unit/test-issue-1360-pill-letter-count.js +node tests/unit/test-issue-1361-cb-presets.js +node tests/unit/test-issue-1364-pill-no-clamp.js +node tests/unit/test-issue-1375-scope-stats-fetch.js +node tests/unit/test-issue-1380-cb-reset-button.js +node tests/unit/test-issue-1380-cb-sim-overlay.js +node tests/unit/test-issue-1407-cb-preset-propagation.js +node tests/unit/test-issue-1409-no-encrypted-flood.js +node tests/unit/test-issue-1412-customizer-no-override.js +node tests/unit/test-issue-1415-packets-layout.js +node tests/unit/test-issue-1418-cb-preset-ramp.js +node tests/unit/test-issue-1418-deeplink-hops-channels.js +node tests/unit/test-issue-1418-edge-weights.js +node tests/unit/test-issue-1418-polish-review.js +node tests/unit/test-issue-1418-raw-hex-extraction.js +node tests/unit/test-issue-1418-spider-fan.js +node tests/unit/test-issue-1420-tile-providers.js +node tests/unit/test-issue-1438-customizer-mcrole.js +node tests/unit/test-issue-1438-marker-css-vars.js +node tests/unit/test-issue-1446-cb-preset-cascade.js +node tests/unit/test-issue-1450-logo-aspect.js +node tests/unit/test-issue-1454-channels-toggle.js +node tests/unit/test-issue-1456-score-labels.js +node tests/unit/test-issue-1461-mobile-page-actions.js +node tests/unit/test-issue-1470-card-bg-contrast.js +node tests/unit/test-issue-1470-node-tile-helper.js +node tests/unit/test-issue-1473-prefix-generator.js +node tests/unit/test-issue-1473-reserved-prefixes.js +node tests/unit/test-issue-1485-live-anim-z.js +node tests/unit/test-issue-1488-marker-stroke-vars.js +node tests/unit/test-issue-1496-reset-all-complete.js +node tests/unit/test-issue-1509-detect-preset.js +node tests/unit/test-issue-1509-nav-active-bg.js +node tests/unit/test-issue-1518-home-url.js +node tests/unit/test-issue-1532-live-fullscreen.js +node tests/unit/test-issue-1562-observers-summary.js +node tests/unit/test-issue-1563-aggregate-and-inflight.js +node tests/unit/test-issue-1574-live-map-max-nodes.js +node tests/unit/test-issue-1606-pagination.js +node tests/unit/test-issue-1614-tile-url-function.js +node tests/unit/test-issue-1619-feed-detail-card-draggable.js +node tests/unit/test-issue-1633-hide-1byte-hops.js +node tests/unit/test-issue-1644-redesign.js +node tests/unit/test-issue-1646-compare-polish.js +node tests/unit/test-issue-1648-followup-phosphor-leaks.js +node tests/unit/test-issue-1648-m1-emoji-scan.js +node tests/unit/test-issue-1648-m2-emoji-scan.js +node tests/unit/test-issue-1648-m3-emoji-scan.js +node tests/unit/test-issue-1648-m4-emoji-scan.js +node tests/unit/test-issue-1648-m5-emoji-scan.js +node tests/unit/test-issue-1648-m6-final-sweep.js +node tests/unit/test-issue-1648-m6-lint-self.js +node tests/unit/test-issue-1668-m2-contrast.js +node tests/unit/test-issue-1668-m3-typography.js +node tests/unit/test-issue-1668-m4-per-route.js +node tests/unit/test-issue-1697-mqtt-mobile-e2e.js +node tests/unit/test-issue-1699-retransmission-chart.js +node tests/unit/test-issue-1705-subpath-contrast.js +node tests/unit/test-issue-1753-copy-url-slash.js +node tests/unit/test-issue-1770-mobile-row-clamp.js +node tests/unit/test-issue-1789-observer-firmware-cols.js +node tests/unit/test-issue-1825-observer-node-cross-links.js +node tests/unit/test-issue-1833-legend-toggle-vcr-offset.js +node tests/unit/test-issue-1836-crossnav-case-normalization.js +node tests/unit/test-issue-1843-node-qr-quiet-zone.js +node tests/unit/test-issue-1846-observers-width.js +node tests/unit/test-issue-1849-trace-hashbytes.js +node tests/unit/test-issue-1851-channel-message-scope.js +node tests/unit/test-issue-1862-map-region-filter.js +node tests/unit/test-issue-1868-control-decode.js +node tests/unit/test-issue-1890-og-url.js +node tests/unit/test-issue-1956-release-routing.js +node tests/unit/test-issue-1979-scope-adverts-by-role.js +node tests/unit/test-issue-2001-map-scope-state.js +node tests/unit/test-issue-2012-clear-filters-selection.js +node tests/unit/test-live-anims.js +node tests/unit/test-live-dt-cap-1524.js +node tests/unit/test-live-legend-helper.js +node tests/unit/test-live-multibyte-filter.js +node tests/unit/test-live-region-filter.js +node tests/unit/test-live.js +node tests/unit/test-map-clustering.js +node tests/unit/test-mqtt-status-panel.js +node tests/unit/test-my-repeaters-dashboard.js +node tests/unit/test-naive-banner-tone.js +node tests/unit/test-node-hop-analytics.js +node tests/unit/test-node-reach-coverage-debounce.js +node tests/unit/test-node-reach-coverage.js +node tests/unit/test-nodes-export-wiring.js +node tests/unit/test-nodes-export.js +node tests/unit/test-observer-iata-1188.js +node tests/unit/test-observer-menu-interactions.js +node tests/unit/test-observer-naive-clock-1478.js +node tests/unit/test-observer-search-filter.js +node tests/unit/test-observers-headings.js +node tests/unit/test-packet-filter-time.js +node tests/unit/test-packet-filter-ux.js +node tests/unit/test-packet-filter.js +node tests/unit/test-packets-local-channels.js +node tests/unit/test-packets.js +node tests/unit/test-panel-corner.js +node tests/unit/test-path-inspector.js +node tests/unit/test-payload-labels-content.js +node tests/unit/test-payload-labels-namespace.js +node tests/unit/test-perf-anomaly.js +node tests/unit/test-perf-disk-io-1120.js +node tests/unit/test-perf-go-runtime.js +node tests/unit/test-perf-render-1258.js +node tests/unit/test-preflight-xss-gate.js +node tests/unit/test-pull-to-reconnect-1091.js +node tests/unit/test-pull-to-reconnect.js +node tests/unit/test-repeater-metric-scatter.js +node tests/unit/test-rx-coverage-config-race.js +node tests/unit/test-rx-coverage-escape.js +node tests/unit/test-scope-audit-styles-linked.js +node tests/unit/test-slideover-1056-rowsel-strict.js +node tests/unit/test-top-routes-overlay.js +node tests/unit/test-traces.js +node tests/unit/test-url-state.js +node tests/unit/test-warmup-banner.js +node tests/unit/test-ws-stale-watchdog-1074.js +node tests/unit/test-xss-escape-sinks.js echo "All standalone frontend suites passed" diff --git a/test-1110-live-filter.js b/tests/e2e/test-1110-live-filter.js similarity index 100% rename from test-1110-live-filter.js rename to tests/e2e/test-1110-live-filter.js diff --git a/test-a11y-axe-1668.js b/tests/e2e/test-a11y-axe-1668.js similarity index 99% rename from test-a11y-axe-1668.js rename to tests/e2e/test-a11y-axe-1668.js index f260ff5f..5c38dab6 100644 --- a/test-a11y-axe-1668.js +++ b/tests/e2e/test-a11y-axe-1668.js @@ -31,6 +31,7 @@ */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); @@ -41,7 +42,7 @@ const path = require('path'); const BASE = process.env.BASE_URL || 'http://localhost:13581'; const ROUTES_FILTER = (process.env.AXE_ROUTES_ONLY || '').split(',').filter(Boolean); const SHOT_DIR = process.env.AXE_SCREENSHOT_DIR || '/tmp/axe-1668'; -const ALLOWLIST_PATH = path.join(__dirname, 'tests', 'a11y-allowlist.yaml'); +const ALLOWLIST_PATH = path.join(REPO_ROOT, 'tests', 'a11y-allowlist.yaml'); // Routes: M1 audit baseline (already proven coverage). // Hash routes — CoreScope is a SPA, server returns the same shell for any path. diff --git a/test-analytics-fluid-charts.js b/tests/e2e/test-analytics-fluid-charts.js similarity index 98% rename from test-analytics-fluid-charts.js rename to tests/e2e/test-analytics-fluid-charts.js index b160700b..ba56f252 100644 --- a/test-analytics-fluid-charts.js +++ b/tests/e2e/test-analytics-fluid-charts.js @@ -19,12 +19,13 @@ * Usage: node test-analytics-fluid-charts.js */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const { chromium } = require('playwright'); const fs = require('fs'); const path = require('path'); const os = require('os'); -const CSS_PATH = path.join(__dirname, 'public', 'style.css'); +const CSS_PATH = path.join(REPO_ROOT, 'public', 'style.css'); const cssHref = 'file://' + CSS_PATH; // Minimal harness: a sized wrapper that defines the available width diff --git a/test-audio-lab-1297-e2e.js b/tests/e2e/test-audio-lab-1297-e2e.js similarity index 100% rename from test-audio-lab-1297-e2e.js rename to tests/e2e/test-audio-lab-1297-e2e.js diff --git a/test-audio-live-1297-e2e.js b/tests/e2e/test-audio-live-1297-e2e.js similarity index 100% rename from test-audio-live-1297-e2e.js rename to tests/e2e/test-audio-live-1297-e2e.js diff --git a/test-bottom-nav-1061-e2e.js b/tests/e2e/test-bottom-nav-1061-e2e.js similarity index 100% rename from test-bottom-nav-1061-e2e.js rename to tests/e2e/test-bottom-nav-1061-e2e.js diff --git a/test-channel-color-picker-e2e.js b/tests/e2e/test-channel-color-picker-e2e.js similarity index 100% rename from test-channel-color-picker-e2e.js rename to tests/e2e/test-channel-color-picker-e2e.js diff --git a/test-channel-decrypt-e2e.js b/tests/e2e/test-channel-decrypt-e2e.js similarity index 100% rename from test-channel-decrypt-e2e.js rename to tests/e2e/test-channel-decrypt-e2e.js diff --git a/test-channel-fluid-e2e.js b/tests/e2e/test-channel-fluid-e2e.js similarity index 100% rename from test-channel-fluid-e2e.js rename to tests/e2e/test-channel-fluid-e2e.js diff --git a/test-channel-issue-1087-e2e.js b/tests/e2e/test-channel-issue-1087-e2e.js similarity index 100% rename from test-channel-issue-1087-e2e.js rename to tests/e2e/test-channel-issue-1087-e2e.js diff --git a/test-channel-issue-1111-e2e.js b/tests/e2e/test-channel-issue-1111-e2e.js similarity index 100% rename from test-channel-issue-1111-e2e.js rename to tests/e2e/test-channel-issue-1111-e2e.js diff --git a/test-channel-modal-e2e.js b/tests/e2e/test-channel-modal-e2e.js similarity index 100% rename from test-channel-modal-e2e.js rename to tests/e2e/test-channel-modal-e2e.js diff --git a/test-channel-qr-e2e.js b/tests/e2e/test-channel-qr-e2e.js similarity index 100% rename from test-channel-qr-e2e.js rename to tests/e2e/test-channel-qr-e2e.js diff --git a/test-channels-add-modal-e2e.js b/tests/e2e/test-channels-add-modal-e2e.js similarity index 100% rename from test-channels-add-modal-e2e.js rename to tests/e2e/test-channels-add-modal-e2e.js diff --git a/test-channels-list-render-e2e.js b/tests/e2e/test-channels-list-render-e2e.js similarity index 100% rename from test-channels-list-render-e2e.js rename to tests/e2e/test-channels-list-render-e2e.js diff --git a/test-channels-selection-flow-e2e.js b/tests/e2e/test-channels-selection-flow-e2e.js similarity index 100% rename from test-channels-selection-flow-e2e.js rename to tests/e2e/test-channels-selection-flow-e2e.js diff --git a/test-channels-share-color-e2e.js b/tests/e2e/test-channels-share-color-e2e.js similarity index 100% rename from test-channels-share-color-e2e.js rename to tests/e2e/test-channels-share-color-e2e.js diff --git a/test-channels-ws-batch-e2e.js b/tests/e2e/test-channels-ws-batch-e2e.js similarity index 100% rename from test-channels-ws-batch-e2e.js rename to tests/e2e/test-channels-ws-batch-e2e.js diff --git a/test-channels-ws-race-1498-e2e.js b/tests/e2e/test-channels-ws-race-1498-e2e.js similarity index 100% rename from test-channels-ws-race-1498-e2e.js rename to tests/e2e/test-channels-ws-race-1498-e2e.js diff --git a/test-charts-fluid-1058-e2e.js b/tests/e2e/test-charts-fluid-1058-e2e.js similarity index 100% rename from test-charts-fluid-1058-e2e.js rename to tests/e2e/test-charts-fluid-1058-e2e.js diff --git a/test-customize-branding-e2e.js b/tests/e2e/test-customize-branding-e2e.js similarity index 100% rename from test-customize-branding-e2e.js rename to tests/e2e/test-customize-branding-e2e.js diff --git a/test-customize-display-e2e.js b/tests/e2e/test-customize-display-e2e.js similarity index 100% rename from test-customize-display-e2e.js rename to tests/e2e/test-customize-display-e2e.js diff --git a/test-customize-export-e2e.js b/tests/e2e/test-customize-export-e2e.js similarity index 100% rename from test-customize-export-e2e.js rename to tests/e2e/test-customize-export-e2e.js diff --git a/test-customize-theme-e2e.js b/tests/e2e/test-customize-theme-e2e.js similarity index 100% rename from test-customize-theme-e2e.js rename to tests/e2e/test-customize-theme-e2e.js diff --git a/test-drag-manager-e2e.js b/tests/e2e/test-drag-manager-e2e.js similarity index 100% rename from test-drag-manager-e2e.js rename to tests/e2e/test-drag-manager-e2e.js diff --git a/test-e2e-1267-mobile-vcr.js b/tests/e2e/test-e2e-1267-mobile-vcr.js similarity index 100% rename from test-e2e-1267-mobile-vcr.js rename to tests/e2e/test-e2e-1267-mobile-vcr.js diff --git a/test-e2e-playwright.js b/tests/e2e/test-e2e-playwright.js similarity index 99% rename from test-e2e-playwright.js rename to tests/e2e/test-e2e-playwright.js index a307959a..1c53d079 100644 --- a/test-e2e-playwright.js +++ b/tests/e2e/test-e2e-playwright.js @@ -1,3 +1,4 @@ +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); /** * Playwright E2E tests — proof of concept * Runs against prod (analyzer.00id.net), read-only. @@ -2313,7 +2314,7 @@ async function run() { if (coverage) { const fs = require('fs'); const path = require('path'); - const outDir = path.join(__dirname, '.nyc_output'); + const outDir = path.join(REPO_ROOT, '.nyc_output'); if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true }); fs.writeFileSync(path.join(outDir, 'e2e-coverage.json'), JSON.stringify(coverage)); console.log(`Frontend coverage from E2E: ${Object.keys(coverage).length} files`); diff --git a/test-filter-ux-e2e.js b/tests/e2e/test-filter-ux-e2e.js similarity index 100% rename from test-filter-ux-e2e.js rename to tests/e2e/test-filter-ux-e2e.js diff --git a/test-gesture-hints-1065-e2e.js b/tests/e2e/test-gesture-hints-1065-e2e.js similarity index 100% rename from test-gesture-hints-1065-e2e.js rename to tests/e2e/test-gesture-hints-1065-e2e.js diff --git a/test-gestures-1062-e2e.js b/tests/e2e/test-gestures-1062-e2e.js similarity index 100% rename from test-gestures-1062-e2e.js rename to tests/e2e/test-gestures-1062-e2e.js diff --git a/test-gestures-1185-scroll-discriminator-e2e.js b/tests/e2e/test-gestures-1185-scroll-discriminator-e2e.js similarity index 100% rename from test-gestures-1185-scroll-discriminator-e2e.js rename to tests/e2e/test-gestures-1185-scroll-discriminator-e2e.js diff --git a/test-home-coverage-e2e.js b/tests/e2e/test-home-coverage-e2e.js similarity index 100% rename from test-home-coverage-e2e.js rename to tests/e2e/test-home-coverage-e2e.js diff --git a/test-issue-1109-hamburger-dropdown-visible-e2e.js b/tests/e2e/test-issue-1109-hamburger-dropdown-visible-e2e.js similarity index 100% rename from test-issue-1109-hamburger-dropdown-visible-e2e.js rename to tests/e2e/test-issue-1109-hamburger-dropdown-visible-e2e.js diff --git a/test-issue-1122-packets-filter-ux-e2e.js b/tests/e2e/test-issue-1122-packets-filter-ux-e2e.js similarity index 100% rename from test-issue-1122-packets-filter-ux-e2e.js rename to tests/e2e/test-issue-1122-packets-filter-ux-e2e.js diff --git a/test-issue-1128-multi-viewport-e2e.js b/tests/e2e/test-issue-1128-multi-viewport-e2e.js similarity index 100% rename from test-issue-1128-multi-viewport-e2e.js rename to tests/e2e/test-issue-1128-multi-viewport-e2e.js diff --git a/test-issue-1128-packets-layout-e2e.js b/tests/e2e/test-issue-1128-packets-layout-e2e.js similarity index 100% rename from test-issue-1128-packets-layout-e2e.js rename to tests/e2e/test-issue-1128-packets-layout-e2e.js diff --git a/test-issue-1136-live-region-e2e.js b/tests/e2e/test-issue-1136-live-region-e2e.js similarity index 100% rename from test-issue-1136-live-region-e2e.js rename to tests/e2e/test-issue-1136-live-region-e2e.js diff --git a/test-issue-1146-path-link-contrast-e2e.js b/tests/e2e/test-issue-1146-path-link-contrast-e2e.js similarity index 100% rename from test-issue-1146-path-link-contrast-e2e.js rename to tests/e2e/test-issue-1146-path-link-contrast-e2e.js diff --git a/test-issue-1147-section-order-e2e.js b/tests/e2e/test-issue-1147-section-order-e2e.js similarity index 100% rename from test-issue-1147-section-order-e2e.js rename to tests/e2e/test-issue-1147-section-order-e2e.js diff --git a/test-issue-1150-404-state-e2e.js b/tests/e2e/test-issue-1150-404-state-e2e.js similarity index 100% rename from test-issue-1150-404-state-e2e.js rename to tests/e2e/test-issue-1150-404-state-e2e.js diff --git a/test-issue-1151-orphan-separators-e2e.js b/tests/e2e/test-issue-1151-orphan-separators-e2e.js similarity index 100% rename from test-issue-1151-orphan-separators-e2e.js rename to tests/e2e/test-issue-1151-orphan-separators-e2e.js diff --git a/test-issue-1204-live-panel-structure-e2e.js b/tests/e2e/test-issue-1204-live-panel-structure-e2e.js similarity index 100% rename from test-issue-1204-live-panel-structure-e2e.js rename to tests/e2e/test-issue-1204-live-panel-structure-e2e.js diff --git a/test-issue-1205-live-controls-anchor-e2e.js b/tests/e2e/test-issue-1205-live-controls-anchor-e2e.js similarity index 100% rename from test-issue-1205-live-controls-anchor-e2e.js rename to tests/e2e/test-issue-1205-live-controls-anchor-e2e.js diff --git a/test-issue-1206-resize-observer-leak-e2e.js b/tests/e2e/test-issue-1206-resize-observer-leak-e2e.js similarity index 100% rename from test-issue-1206-resize-observer-leak-e2e.js rename to tests/e2e/test-issue-1206-resize-observer-leak-e2e.js diff --git a/test-issue-1206-vcr-overlap-e2e.js b/tests/e2e/test-issue-1206-vcr-overlap-e2e.js similarity index 100% rename from test-issue-1206-vcr-overlap-e2e.js rename to tests/e2e/test-issue-1206-vcr-overlap-e2e.js diff --git a/test-issue-1224-channels-mobile-ux-e2e.js b/tests/e2e/test-issue-1224-channels-mobile-ux-e2e.js similarity index 100% rename from test-issue-1224-channels-mobile-ux-e2e.js rename to tests/e2e/test-issue-1224-channels-mobile-ux-e2e.js diff --git a/test-issue-1234-live-chrome-pass2-e2e.js b/tests/e2e/test-issue-1234-live-chrome-pass2-e2e.js similarity index 100% rename from test-issue-1234-live-chrome-pass2-e2e.js rename to tests/e2e/test-issue-1234-live-chrome-pass2-e2e.js diff --git a/test-issue-1236-map-mobile-e2e.js b/tests/e2e/test-issue-1236-map-mobile-e2e.js similarity index 100% rename from test-issue-1236-map-mobile-e2e.js rename to tests/e2e/test-issue-1236-map-mobile-e2e.js diff --git a/test-issue-1244-live-vcr-row-hints-e2e.js b/tests/e2e/test-issue-1244-live-vcr-row-hints-e2e.js similarity index 100% rename from test-issue-1244-live-vcr-row-hints-e2e.js rename to tests/e2e/test-issue-1244-live-vcr-row-hints-e2e.js diff --git a/test-issue-1273-qr-overlay-height-e2e.js b/tests/e2e/test-issue-1273-qr-overlay-height-e2e.js similarity index 100% rename from test-issue-1273-qr-overlay-height-e2e.js rename to tests/e2e/test-issue-1273-qr-overlay-height-e2e.js diff --git a/test-issue-1274-legend-coverage-e2e.js b/tests/e2e/test-issue-1274-legend-coverage-e2e.js similarity index 100% rename from test-issue-1274-legend-coverage-e2e.js rename to tests/e2e/test-issue-1274-legend-coverage-e2e.js diff --git a/test-issue-1279-legend-p2-e2e.js b/tests/e2e/test-issue-1279-legend-p2-e2e.js similarity index 100% rename from test-issue-1279-legend-p2-e2e.js rename to tests/e2e/test-issue-1279-legend-p2-e2e.js diff --git a/test-issue-1281-location-row-e2e.js b/tests/e2e/test-issue-1281-location-row-e2e.js similarity index 100% rename from test-issue-1281-location-row-e2e.js rename to tests/e2e/test-issue-1281-location-row-e2e.js diff --git a/test-issue-1306-collisions-terminology-e2e.js b/tests/e2e/test-issue-1306-collisions-terminology-e2e.js similarity index 100% rename from test-issue-1306-collisions-terminology-e2e.js rename to tests/e2e/test-issue-1306-collisions-terminology-e2e.js diff --git a/test-issue-1329-map-controls-accordion-e2e.js b/tests/e2e/test-issue-1329-map-controls-accordion-e2e.js similarity index 100% rename from test-issue-1329-map-controls-accordion-e2e.js rename to tests/e2e/test-issue-1329-map-controls-accordion-e2e.js diff --git a/test-issue-1367-channels-chat-app-e2e.js b/tests/e2e/test-issue-1367-channels-chat-app-e2e.js similarity index 100% rename from test-issue-1367-channels-chat-app-e2e.js rename to tests/e2e/test-issue-1367-channels-chat-app-e2e.js diff --git a/test-issue-1374-route-map-a11y-e2e.js b/tests/e2e/test-issue-1374-route-map-a11y-e2e.js similarity index 100% rename from test-issue-1374-route-map-a11y-e2e.js rename to tests/e2e/test-issue-1374-route-map-a11y-e2e.js diff --git a/test-issue-1400-nav-vertical-clip.js b/tests/e2e/test-issue-1400-nav-vertical-clip.js similarity index 100% rename from test-issue-1400-nav-vertical-clip.js rename to tests/e2e/test-issue-1400-nav-vertical-clip.js diff --git a/test-issue-1413-nav-overlap-e2e.js b/tests/e2e/test-issue-1413-nav-overlap-e2e.js similarity index 100% rename from test-issue-1413-nav-overlap-e2e.js rename to tests/e2e/test-issue-1413-nav-overlap-e2e.js diff --git a/test-issue-1486-collapse-reopens-detail-e2e.js b/tests/e2e/test-issue-1486-collapse-reopens-detail-e2e.js similarity index 100% rename from test-issue-1486-collapse-reopens-detail-e2e.js rename to tests/e2e/test-issue-1486-collapse-reopens-detail-e2e.js diff --git a/test-issue-1487-byop-modal-layout-e2e.js b/tests/e2e/test-issue-1487-byop-modal-layout-e2e.js similarity index 100% rename from test-issue-1487-byop-modal-layout-e2e.js rename to tests/e2e/test-issue-1487-byop-modal-layout-e2e.js diff --git a/test-issue-1510-live-nav-pin-e2e.js b/tests/e2e/test-issue-1510-live-nav-pin-e2e.js similarity index 100% rename from test-issue-1510-live-nav-pin-e2e.js rename to tests/e2e/test-issue-1510-live-nav-pin-e2e.js diff --git a/test-issue-1522-trace-url-sync-e2e.js b/tests/e2e/test-issue-1522-trace-url-sync-e2e.js similarity index 100% rename from test-issue-1522-trace-url-sync-e2e.js rename to tests/e2e/test-issue-1522-trace-url-sync-e2e.js diff --git a/test-issue-1567-corner-clears-drag-e2e.js b/tests/e2e/test-issue-1567-corner-clears-drag-e2e.js similarity index 100% rename from test-issue-1567-corner-clears-drag-e2e.js rename to tests/e2e/test-issue-1567-corner-clears-drag-e2e.js diff --git a/test-issue-1599-replay-freeze-e2e.js b/tests/e2e/test-issue-1599-replay-freeze-e2e.js similarity index 100% rename from test-issue-1599-replay-freeze-e2e.js rename to tests/e2e/test-issue-1599-replay-freeze-e2e.js diff --git a/test-issue-1630-reach-mobile-e2e.js b/tests/e2e/test-issue-1630-reach-mobile-e2e.js similarity index 100% rename from test-issue-1630-reach-mobile-e2e.js rename to tests/e2e/test-issue-1630-reach-mobile-e2e.js diff --git a/test-issue-1639-observers-sort-e2e.js b/tests/e2e/test-issue-1639-observers-sort-e2e.js similarity index 100% rename from test-issue-1639-observers-sort-e2e.js rename to tests/e2e/test-issue-1639-observers-sort-e2e.js diff --git a/test-issue-1640-compare-discovery-e2e.js b/tests/e2e/test-issue-1640-compare-discovery-e2e.js similarity index 100% rename from test-issue-1640-compare-discovery-e2e.js rename to tests/e2e/test-issue-1640-compare-discovery-e2e.js diff --git a/test-issue-1648-m1-icons-e2e.js b/tests/e2e/test-issue-1648-m1-icons-e2e.js similarity index 100% rename from test-issue-1648-m1-icons-e2e.js rename to tests/e2e/test-issue-1648-m1-icons-e2e.js diff --git a/test-issue-1648-m2-icons-e2e.js b/tests/e2e/test-issue-1648-m2-icons-e2e.js similarity index 100% rename from test-issue-1648-m2-icons-e2e.js rename to tests/e2e/test-issue-1648-m2-icons-e2e.js diff --git a/test-issue-1648-m3-icons-e2e.js b/tests/e2e/test-issue-1648-m3-icons-e2e.js similarity index 100% rename from test-issue-1648-m3-icons-e2e.js rename to tests/e2e/test-issue-1648-m3-icons-e2e.js diff --git a/test-issue-1648-m4-icons-e2e.js b/tests/e2e/test-issue-1648-m4-icons-e2e.js similarity index 100% rename from test-issue-1648-m4-icons-e2e.js rename to tests/e2e/test-issue-1648-m4-icons-e2e.js diff --git a/test-issue-1648-m5-icons-e2e.js b/tests/e2e/test-issue-1648-m5-icons-e2e.js similarity index 100% rename from test-issue-1648-m5-icons-e2e.js rename to tests/e2e/test-issue-1648-m5-icons-e2e.js diff --git a/test-issue-1657-analytics-channels-group-sprites-e2e.js b/tests/e2e/test-issue-1657-analytics-channels-group-sprites-e2e.js similarity index 100% rename from test-issue-1657-analytics-channels-group-sprites-e2e.js rename to tests/e2e/test-issue-1657-analytics-channels-group-sprites-e2e.js diff --git a/test-issue-1692-packets-init-parallel-e2e.js b/tests/e2e/test-issue-1692-packets-init-parallel-e2e.js similarity index 100% rename from test-issue-1692-packets-init-parallel-e2e.js rename to tests/e2e/test-issue-1692-packets-init-parallel-e2e.js diff --git a/test-issue-1705-subpath-contrast-e2e.js b/tests/e2e/test-issue-1705-subpath-contrast-e2e.js similarity index 98% rename from test-issue-1705-subpath-contrast-e2e.js rename to tests/e2e/test-issue-1705-subpath-contrast-e2e.js index 34cf6844..fdf417b9 100644 --- a/test-issue-1705-subpath-contrast-e2e.js +++ b/tests/e2e/test-issue-1705-subpath-contrast-e2e.js @@ -30,12 +30,13 @@ * to convert SKIP -> FAIL. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); const { chromium } = require('playwright'); -const CSS_PATH = path.resolve(__dirname, 'public', 'style.css'); +const CSS_PATH = path.resolve(REPO_ROOT, 'public', 'style.css'); function fail(msg) { console.error(`test-issue-1705-subpath-contrast-e2e.js: FAIL — ${msg}`); diff --git a/test-issue-1758-ng-filter-rerenders-e2e.js b/tests/e2e/test-issue-1758-ng-filter-rerenders-e2e.js similarity index 100% rename from test-issue-1758-ng-filter-rerenders-e2e.js rename to tests/e2e/test-issue-1758-ng-filter-rerenders-e2e.js diff --git a/test-issue-1799-label-vocab-e2e.js b/tests/e2e/test-issue-1799-label-vocab-e2e.js similarity index 100% rename from test-issue-1799-label-vocab-e2e.js rename to tests/e2e/test-issue-1799-label-vocab-e2e.js diff --git a/test-live-dedup.js b/tests/e2e/test-live-dedup.js similarity index 100% rename from test-live-dedup.js rename to tests/e2e/test-live-dedup.js diff --git a/test-live-fullscreen-1572-e2e.js b/tests/e2e/test-live-fullscreen-1572-e2e.js similarity index 100% rename from test-live-fullscreen-1572-e2e.js rename to tests/e2e/test-live-fullscreen-1572-e2e.js diff --git a/test-live-layout-1178-1179-e2e.js b/tests/e2e/test-live-layout-1178-1179-e2e.js similarity index 100% rename from test-live-layout-1178-1179-e2e.js rename to tests/e2e/test-live-layout-1178-1179-e2e.js diff --git a/test-live-mql-leak-1180-e2e.js b/tests/e2e/test-live-mql-leak-1180-e2e.js similarity index 100% rename from test-live-mql-leak-1180-e2e.js rename to tests/e2e/test-live-mql-leak-1180-e2e.js diff --git a/test-live-multibyte-only-e2e.js b/tests/e2e/test-live-multibyte-only-e2e.js similarity index 100% rename from test-live-multibyte-only-e2e.js rename to tests/e2e/test-live-multibyte-only-e2e.js diff --git a/test-logo-default-sage-teal-e2e.js b/tests/e2e/test-logo-default-sage-teal-e2e.js similarity index 100% rename from test-logo-default-sage-teal-e2e.js rename to tests/e2e/test-logo-default-sage-teal-e2e.js diff --git a/test-logo-pulse-1173-e2e.js b/tests/e2e/test-logo-pulse-1173-e2e.js similarity index 100% rename from test-logo-pulse-1173-e2e.js rename to tests/e2e/test-logo-pulse-1173-e2e.js diff --git a/test-logo-rebrand-e2e.js b/tests/e2e/test-logo-rebrand-e2e.js similarity index 100% rename from test-logo-rebrand-e2e.js rename to tests/e2e/test-logo-rebrand-e2e.js diff --git a/test-logo-theme-e2e.js b/tests/e2e/test-logo-theme-e2e.js similarity index 100% rename from test-logo-theme-e2e.js rename to tests/e2e/test-logo-theme-e2e.js diff --git a/test-map-modal-fluid-e2e.js b/tests/e2e/test-map-modal-fluid-e2e.js similarity index 100% rename from test-map-modal-fluid-e2e.js rename to tests/e2e/test-map-modal-fluid-e2e.js diff --git a/test-map-nodes-pagination-e2e.js b/tests/e2e/test-map-nodes-pagination-e2e.js similarity index 100% rename from test-map-nodes-pagination-e2e.js rename to tests/e2e/test-map-nodes-pagination-e2e.js diff --git a/test-marker-outline-weight.js b/tests/e2e/test-marker-outline-weight.js similarity index 100% rename from test-marker-outline-weight.js rename to tests/e2e/test-marker-outline-weight.js diff --git a/test-nav-drawer-1064-e2e.js b/tests/e2e/test-nav-drawer-1064-e2e.js similarity index 100% rename from test-nav-drawer-1064-e2e.js rename to tests/e2e/test-nav-drawer-1064-e2e.js diff --git a/test-nav-fluid-1055-e2e.js b/tests/e2e/test-nav-fluid-1055-e2e.js similarity index 100% rename from test-nav-fluid-1055-e2e.js rename to tests/e2e/test-nav-fluid-1055-e2e.js diff --git a/test-nav-more-floor-1139-e2e.js b/tests/e2e/test-nav-more-floor-1139-e2e.js similarity index 100% rename from test-nav-more-floor-1139-e2e.js rename to tests/e2e/test-nav-more-floor-1139-e2e.js diff --git a/test-nav-priority-1102-e2e.js b/tests/e2e/test-nav-priority-1102-e2e.js similarity index 100% rename from test-nav-priority-1102-e2e.js rename to tests/e2e/test-nav-priority-1102-e2e.js diff --git a/test-nav-priority-1311-e2e.js b/tests/e2e/test-nav-priority-1311-e2e.js similarity index 100% rename from test-nav-priority-1311-e2e.js rename to tests/e2e/test-nav-priority-1311-e2e.js diff --git a/test-nav-priority-1391-e2e.js b/tests/e2e/test-nav-priority-1391-e2e.js similarity index 100% rename from test-nav-priority-1391-e2e.js rename to tests/e2e/test-nav-priority-1391-e2e.js diff --git a/test-neighbor-map-btn-clip-e2e.js b/tests/e2e/test-neighbor-map-btn-clip-e2e.js similarity index 97% rename from test-neighbor-map-btn-clip-e2e.js rename to tests/e2e/test-neighbor-map-btn-clip-e2e.js index 59d04cee..a49b80a9 100644 --- a/test-neighbor-map-btn-clip-e2e.js +++ b/tests/e2e/test-neighbor-map-btn-clip-e2e.js @@ -35,15 +35,16 @@ * make the geometry assertions below fail. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('node:fs'); const path = require('node:path'); const assert = require('node:assert'); const { chromium } = require('playwright'); -const CSS = fs.readFileSync(path.join(__dirname, 'public', 'style.css'), 'utf8'); -const NODES_JS = fs.readFileSync(path.join(__dirname, 'public', 'nodes.js'), 'utf8'); -const ANALYTICS_JS = fs.readFileSync(path.join(__dirname, 'public', 'analytics.js'), 'utf8'); +const CSS = fs.readFileSync(path.join(REPO_ROOT, 'public', 'style.css'), 'utf8'); +const NODES_JS = fs.readFileSync(path.join(REPO_ROOT, 'public', 'nodes.js'), 'utf8'); +const ANALYTICS_JS = fs.readFileSync(path.join(REPO_ROOT, 'public', 'analytics.js'), 'utf8'); const HEIGHT = 900; // The bug's window: below ~640px the table finally overflows and the diff --git a/test-node-reach-coverage-e2e.js b/tests/e2e/test-node-reach-coverage-e2e.js similarity index 100% rename from test-node-reach-coverage-e2e.js rename to tests/e2e/test-node-reach-coverage-e2e.js diff --git a/test-node-reach-e2e.js b/tests/e2e/test-node-reach-e2e.js similarity index 100% rename from test-node-reach-e2e.js rename to tests/e2e/test-node-reach-e2e.js diff --git a/test-nodes-export-e2e.js b/tests/e2e/test-nodes-export-e2e.js similarity index 100% rename from test-nodes-export-e2e.js rename to tests/e2e/test-nodes-export-e2e.js diff --git a/test-observer-iata-1188-e2e.js b/tests/e2e/test-observer-iata-1188-e2e.js similarity index 100% rename from test-observer-iata-1188-e2e.js rename to tests/e2e/test-observer-iata-1188-e2e.js diff --git a/test-packets-scope-column.js b/tests/e2e/test-packets-scope-column.js similarity index 100% rename from test-packets-scope-column.js rename to tests/e2e/test-packets-scope-column.js diff --git a/test-path-inspector-coverage-e2e.js b/tests/e2e/test-path-inspector-coverage-e2e.js similarity index 100% rename from test-path-inspector-coverage-e2e.js rename to tests/e2e/test-path-inspector-coverage-e2e.js diff --git a/test-path-inspector-e2e.js b/tests/e2e/test-path-inspector-e2e.js similarity index 100% rename from test-path-inspector-e2e.js rename to tests/e2e/test-path-inspector-e2e.js diff --git a/test-pr-1490-live-map-gpu-animations-e2e.js b/tests/e2e/test-pr-1490-live-map-gpu-animations-e2e.js similarity index 100% rename from test-pr-1490-live-map-gpu-animations-e2e.js rename to tests/e2e/test-pr-1490-live-map-gpu-animations-e2e.js diff --git a/test-rx-coverage-mobile-nav-e2e.js b/tests/e2e/test-rx-coverage-mobile-nav-e2e.js similarity index 100% rename from test-rx-coverage-mobile-nav-e2e.js rename to tests/e2e/test-rx-coverage-mobile-nav-e2e.js diff --git a/test-show-neighbors.js b/tests/e2e/test-show-neighbors.js similarity index 100% rename from test-show-neighbors.js rename to tests/e2e/test-show-neighbors.js diff --git a/test-slideover-1056-e2e.js b/tests/e2e/test-slideover-1056-e2e.js similarity index 100% rename from test-slideover-1056-e2e.js rename to tests/e2e/test-slideover-1056-e2e.js diff --git a/test-slideover-1168-munger-e2e.js b/tests/e2e/test-slideover-1168-munger-e2e.js similarity index 100% rename from test-slideover-1168-munger-e2e.js rename to tests/e2e/test-slideover-1168-munger-e2e.js diff --git a/test-table-fluid-e2e.js b/tests/e2e/test-table-fluid-e2e.js similarity index 100% rename from test-table-fluid-e2e.js rename to tests/e2e/test-table-fluid-e2e.js diff --git a/test-table-sort.js b/tests/e2e/test-table-sort.js similarity index 98% rename from test-table-sort.js rename to tests/e2e/test-table-sort.js index a6255b91..af20c07e 100644 --- a/test-table-sort.js +++ b/tests/e2e/test-table-sort.js @@ -1,5 +1,6 @@ /* test-table-sort.js — Unit tests for TableSort utility */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const { JSDOM } = require('jsdom'); const fs = require('fs'); @@ -27,7 +28,7 @@ function createDOM(html) { runScripts: 'dangerously' }); // Load TableSort into this DOM - const script = fs.readFileSync(path.join(__dirname, 'public', 'table-sort.js'), 'utf8'); + const script = fs.readFileSync(path.join(REPO_ROOT, 'public', 'table-sort.js'), 'utf8'); const el = dom.window.document.createElement('script'); el.textContent = script; dom.window.document.head.appendChild(el); diff --git a/test-touch-gestures-coverage-e2e.js b/tests/e2e/test-touch-gestures-coverage-e2e.js similarity index 100% rename from test-touch-gestures-coverage-e2e.js rename to tests/e2e/test-touch-gestures-coverage-e2e.js diff --git a/test-touch-targets.js b/tests/e2e/test-touch-targets.js similarity index 99% rename from test-touch-targets.js rename to tests/e2e/test-touch-targets.js index c509c1f3..86575f4d 100644 --- a/test-touch-targets.js +++ b/tests/e2e/test-touch-targets.js @@ -17,13 +17,14 @@ * in CSS (:focus / :focus-within rule in the Touch Targets section). */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); const assert = require('assert'); const { chromium, devices } = require('playwright'); -const REPO = __dirname; +const REPO = REPO_ROOT; const CSS = fs.readFileSync(path.join(REPO, 'public/style.css'), 'utf8'); // Selectors we claim to make 48x48. Each entry: [selector, tag, classes, diff --git a/test-1108-region-hide-nodes.js b/tests/unit/test-1108-region-hide-nodes.js similarity index 96% rename from test-1108-region-hide-nodes.js rename to tests/unit/test-1108-region-hide-nodes.js index c693bfee..2a4b8d52 100644 --- a/test-1108-region-hide-nodes.js +++ b/tests/unit/test-1108-region-hide-nodes.js @@ -10,6 +10,7 @@ * (no DOM, no fetch). Mirrors the pattern from test-area-filter.js. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const vm = require('vm'); const fs = require('fs'); const assert = require('assert'); @@ -37,7 +38,7 @@ function buildCtx(initialStorage) { }; ctx.window = ctx; vm.createContext(ctx); - const src = fs.readFileSync(__dirname + '/public/region-filter.js', 'utf8'); + const src = fs.readFileSync(REPO_ROOT + '/public/region-filter.js', 'utf8'); vm.runInContext(src, ctx); return ctx; } diff --git a/test-1659-analytics-warmup.js b/tests/unit/test-1659-analytics-warmup.js similarity index 100% rename from test-1659-analytics-warmup.js rename to tests/unit/test-1659-analytics-warmup.js diff --git a/test-a11y-1705-subpath-hop-prefix-e2e.js b/tests/unit/test-a11y-1705-subpath-hop-prefix-e2e.js similarity index 98% rename from test-a11y-1705-subpath-hop-prefix-e2e.js rename to tests/unit/test-a11y-1705-subpath-hop-prefix-e2e.js index 98dfbefa..959ef6c4 100644 --- a/test-a11y-1705-subpath-hop-prefix-e2e.js +++ b/tests/unit/test-a11y-1705-subpath-hop-prefix-e2e.js @@ -45,11 +45,12 @@ * serves from). */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); -const STYLE_CSS_PATH = process.env.STYLE_CSS_PATH || path.join(__dirname, 'public', 'style.css'); +const STYLE_CSS_PATH = process.env.STYLE_CSS_PATH || path.join(REPO_ROOT, 'public', 'style.css'); const THEMES = ['dark', 'light']; // -------------------- Pure helpers (unit-testable) -------------------- diff --git a/test-a11y-1715-dark-role-swatches.js b/tests/unit/test-a11y-1715-dark-role-swatches.js similarity index 98% rename from test-a11y-1715-dark-role-swatches.js rename to tests/unit/test-a11y-1715-dark-role-swatches.js index e60b32fa..0b9ed182 100644 --- a/test-a11y-1715-dark-role-swatches.js +++ b/tests/unit/test-a11y-1715-dark-role-swatches.js @@ -32,12 +32,13 @@ * Usage: node test-a11y-1715-dark-role-swatches.js */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); const assert = require('assert'); -const ROOT = __dirname; +const ROOT = REPO_ROOT; const STYLE_CSS = process.env.STYLE_CSS_PATH || path.join(ROOT, 'public', 'style.css'); const ROLES = ['repeater', 'companion', 'room', 'sensor', 'observer']; diff --git a/test-a11y-1716-rf-range-btn-active.js b/tests/unit/test-a11y-1716-rf-range-btn-active.js similarity index 98% rename from test-a11y-1716-rf-range-btn-active.js rename to tests/unit/test-a11y-1716-rf-range-btn-active.js index db4b9afd..9cbbe641 100644 --- a/test-a11y-1716-rf-range-btn-active.js +++ b/tests/unit/test-a11y-1716-rf-range-btn-active.js @@ -31,11 +31,12 @@ * Usage: node test-a11y-1716-rf-range-btn-active.js */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); -const ROOT = __dirname; +const ROOT = REPO_ROOT; const STYLE_CSS = process.env.STYLE_CSS_PATH || path.join(ROOT, 'public', 'style.css'); // ---- WCAG helpers (copied small, no shared import) ---- diff --git a/test-a11y-1719-contrast-root-causes-e2e.js b/tests/unit/test-a11y-1719-contrast-root-causes-e2e.js similarity index 99% rename from test-a11y-1719-contrast-root-causes-e2e.js rename to tests/unit/test-a11y-1719-contrast-root-causes-e2e.js index d112555e..8517fb9d 100644 --- a/test-a11y-1719-contrast-root-causes-e2e.js +++ b/tests/unit/test-a11y-1719-contrast-root-causes-e2e.js @@ -37,11 +37,12 @@ * Usage: node test-a11y-1719-contrast-root-causes-e2e.js */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); -const ROOT = __dirname; +const ROOT = REPO_ROOT; const STYLE_CSS = process.env.STYLE_CSS_PATH || path.join(ROOT, 'public', 'style.css'); const CUSTOMIZE_JS = path.join(ROOT, 'public', 'customize.js'); diff --git a/test-a11y-axe-1668-selftest.js b/tests/unit/test-a11y-axe-1668-selftest.js similarity index 98% rename from test-a11y-axe-1668-selftest.js rename to tests/unit/test-a11y-axe-1668-selftest.js index 86bb8361..77f40f52 100644 --- a/test-a11y-axe-1668-selftest.js +++ b/tests/unit/test-a11y-axe-1668-selftest.js @@ -11,13 +11,14 @@ */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const assert = require('assert'); const fs = require('fs'); const os = require('os'); const path = require('path'); -const mod = require('./test-a11y-axe-1668.js'); +const mod = require('../e2e/test-a11y-axe-1668.js'); // ---- routes / themes -------------------------------------------------------- assert.ok(Array.isArray(mod.ROUTES), 'ROUTES must be an array'); @@ -103,7 +104,7 @@ for (const r of mod.ROUTES) { // Cross-check REGISTERED_* against actual source code so the constant cannot // drift silently from `registerPage()` calls or analytics tab `case` arms. -const repoRoot = __dirname; +const repoRoot = REPO_ROOT; const publicDir = path.join(repoRoot, 'public'); if (fs.existsSync(publicDir)) { const files = fs.readdirSync(publicDir).filter(f => f.endsWith('.js')); @@ -184,7 +185,7 @@ assert.throws( // And loadAllowlist must propagate the throw end-to-end via a tmpfile. const tmpMalformed = path.join(os.tmpdir(), `a11y-malformed-${process.pid}.yaml`); fs.writeFileSync(tmpMalformed, 'this :: is :: garbage\n!!! no\n'); -const ALLOWLIST_PATH_ORIG = require.resolve('./test-a11y-axe-1668.js'); +const ALLOWLIST_PATH_ORIG = require.resolve('../e2e/test-a11y-axe-1668.js'); // We can't easily redirect ALLOWLIST_PATH without re-requiring; instead call // parseAllowlistYaml directly on the tmpfile content for end-to-end coverage. assert.throws( @@ -382,7 +383,7 @@ assert.throws( ); // ---- repo allowlist file: shape sanity -------------------------------------- -const allowPath = path.join(__dirname, 'tests', 'a11y-allowlist.yaml'); +const allowPath = path.join(REPO_ROOT, 'tests', 'a11y-allowlist.yaml'); assert.ok(fs.existsSync(allowPath), `tests/a11y-allowlist.yaml missing at ${allowPath}`); const entries = mod.loadAllowlist(); for (const e of entries) { diff --git a/test-a11y-axe-routes-coverage.js b/tests/unit/test-a11y-axe-routes-coverage.js similarity index 93% rename from test-a11y-axe-routes-coverage.js rename to tests/unit/test-a11y-axe-routes-coverage.js index b2846281..66b25dc6 100644 --- a/test-a11y-axe-routes-coverage.js +++ b/tests/unit/test-a11y-axe-routes-coverage.js @@ -15,15 +15,16 @@ */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const assert = require('assert'); const fs = require('fs'); const path = require('path'); -const mod = require('./test-a11y-axe-1668.js'); +const mod = require('../e2e/test-a11y-axe-1668.js'); const analyticsSrc = fs.readFileSync( - path.join(__dirname, 'public', 'analytics.js'), + path.join(REPO_ROOT, 'public', 'analytics.js'), 'utf8' ); diff --git a/test-aging.js b/tests/unit/test-aging.js similarity index 100% rename from test-aging.js rename to tests/unit/test-aging.js diff --git a/test-analytics-channels-integration.js b/tests/unit/test-analytics-channels-integration.js similarity index 98% rename from test-analytics-channels-integration.js rename to tests/unit/test-analytics-channels-integration.js index 43059094..8d0296ed 100644 --- a/test-analytics-channels-integration.js +++ b/tests/unit/test-analytics-channels-integration.js @@ -16,6 +16,7 @@ * jump to channel activity stats. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); @@ -55,7 +56,7 @@ global.histogram = () => ({ svg: '' }); // Load analytics.js — it self-registers global helpers we test. const analyticsSrc = fs.readFileSync( - path.join(__dirname, 'public/analytics.js'), + path.join(REPO_ROOT, 'public/analytics.js'), 'utf8' ); // Strip top-level `await` / module syntax — analytics.js is plain IIFE so it's diff --git a/test-anl1-tooltip-render.js b/tests/unit/test-anl1-tooltip-render.js similarity index 100% rename from test-anl1-tooltip-render.js rename to tests/unit/test-anl1-tooltip-render.js diff --git a/test-area-filter.js b/tests/unit/test-area-filter.js similarity index 100% rename from test-area-filter.js rename to tests/unit/test-area-filter.js diff --git a/test-channel-color-picker.js b/tests/unit/test-channel-color-picker.js similarity index 96% rename from test-channel-color-picker.js rename to tests/unit/test-channel-color-picker.js index 54de759b..cbdc7f77 100644 --- a/test-channel-color-picker.js +++ b/tests/unit/test-channel-color-picker.js @@ -9,6 +9,7 @@ */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const vm = require('vm'); const fs = require('fs'); const path = require('path'); @@ -113,7 +114,7 @@ assert( // --- Test 3: channel-colors.js getRowStyle uses border-left only --- console.log('\n=== channel-colors.js getRowStyle ==='); -const ccSource = fs.readFileSync(path.join(__dirname, 'public', 'channel-colors.js'), 'utf8'); +const ccSource = fs.readFileSync(path.join(REPO_ROOT, 'public', 'channel-colors.js'), 'utf8'); const ccCtx = { window: {}, localStorage: { @@ -140,7 +141,7 @@ assert(advertStyle === '', 'getRowStyle returns empty for non-GRP_TXT type'); // --- Test 4: channel-color-picker.js palette --- console.log('\n=== channel-color-picker.js palette ==='); -const pickerSource = fs.readFileSync(path.join(__dirname, 'public', 'channel-color-picker.js'), 'utf8'); +const pickerSource = fs.readFileSync(path.join(REPO_ROOT, 'public', 'channel-color-picker.js'), 'utf8'); const pickerCtx = { window: { ChannelColors: ccCtx.window.ChannelColors, matchMedia: () => ({ matches: false }) }, document: { diff --git a/test-channel-colors.js b/tests/unit/test-channel-colors.js similarity index 97% rename from test-channel-colors.js rename to tests/unit/test-channel-colors.js index a3e2426b..19b537d1 100644 --- a/test-channel-colors.js +++ b/tests/unit/test-channel-colors.js @@ -1,5 +1,6 @@ /* Unit tests for channel color highlighting (M1) — #271 */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const vm = require('vm'); const fs = require('fs'); const assert = require('assert'); @@ -33,7 +34,7 @@ function makeSandbox() { }; ctx.window.ChannelColors = undefined; vm.createContext(ctx); - const src = fs.readFileSync(__dirname + '/public/channel-colors.js', 'utf8'); + const src = fs.readFileSync(REPO_ROOT + '/public/channel-colors.js', 'utf8'); vm.runInContext(src, ctx); return ctx; } @@ -217,7 +218,7 @@ test('channel-color-picker.js loads without error in sandbox', function() { ctx.setTimeout = function(fn) { fn(); }; ctx.window.innerWidth = 1024; ctx.window.innerHeight = 768; - const pickerSrc = fs.readFileSync(__dirname + '/public/channel-color-picker.js', 'utf8'); + const pickerSrc = fs.readFileSync(REPO_ROOT + '/public/channel-color-picker.js', 'utf8'); vm.runInContext(pickerSrc, ctx); assert.ok(ctx.window.ChannelColorPicker, 'ChannelColorPicker should be exported'); assert.strictEqual(typeof ctx.window.ChannelColorPicker.install, 'function'); @@ -247,7 +248,7 @@ test('ChannelColorPicker.install does not throw when elements missing', function ctx.setTimeout = function(fn) { fn(); }; ctx.window.innerWidth = 1024; ctx.window.innerHeight = 768; - const pickerSrc = fs.readFileSync(__dirname + '/public/channel-color-picker.js', 'utf8'); + const pickerSrc = fs.readFileSync(REPO_ROOT + '/public/channel-color-picker.js', 'utf8'); vm.runInContext(pickerSrc, ctx); // Should not throw when feed/table elements don't exist ctx.window.ChannelColorPicker.install(); diff --git a/test-channel-decrypt-ecb.js b/tests/unit/test-channel-decrypt-ecb.js similarity index 95% rename from test-channel-decrypt-ecb.js rename to tests/unit/test-channel-decrypt-ecb.js index 918a6ea1..bf98e2a0 100644 --- a/test-channel-decrypt-ecb.js +++ b/tests/unit/test-channel-decrypt-ecb.js @@ -17,6 +17,7 @@ * ciphertext = 69c4e0d86a7b0430d8cdb78070b4c55a */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const vm = require('vm'); const fs = require('fs'); @@ -47,12 +48,12 @@ function loadChannelDecrypt() { vm.createContext(sandbox); // Load vendored AES (if present) before channel-decrypt.js. - const vendorPath = path.join(__dirname, 'public/vendor/aes-ecb.js'); + const vendorPath = path.join(REPO_ROOT, 'public/vendor/aes-ecb.js'); if (fs.existsSync(vendorPath)) { vm.runInContext(fs.readFileSync(vendorPath, 'utf8'), sandbox); } vm.runInContext( - fs.readFileSync(path.join(__dirname, 'public/channel-decrypt.js'), 'utf8'), + fs.readFileSync(path.join(REPO_ROOT, 'public/channel-decrypt.js'), 'utf8'), sandbox ); return sandbox.window.ChannelDecrypt; diff --git a/test-channel-decrypt-insecure-context.js b/tests/unit/test-channel-decrypt-insecure-context.js similarity index 96% rename from test-channel-decrypt-insecure-context.js rename to tests/unit/test-channel-decrypt-insecure-context.js index 7f69179a..f39a856d 100644 --- a/test-channel-decrypt-insecure-context.js +++ b/tests/unit/test-channel-decrypt-insecure-context.js @@ -32,6 +32,7 @@ * mac = b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7 */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const vm = require('vm'); const fs = require('fs'); @@ -63,20 +64,20 @@ function loadChannelDecryptInsecureContext() { vm.createContext(sandbox); // Vendored AES (must load before channel-decrypt.js — same as index.html). - const vendorAesPath = path.join(__dirname, 'public/vendor/aes-ecb.js'); + const vendorAesPath = path.join(REPO_ROOT, 'public/vendor/aes-ecb.js'); if (fs.existsSync(vendorAesPath)) { vm.runInContext(fs.readFileSync(vendorAesPath, 'utf8'), sandbox); } // Optional vendored SHA-256 / HMAC (the fix). Load if present so the test // works whether the fix vendors it as a separate file OR inlines it into // channel-decrypt.js. - const vendorShaPath = path.join(__dirname, 'public/vendor/sha256-hmac.js'); + const vendorShaPath = path.join(REPO_ROOT, 'public/vendor/sha256-hmac.js'); if (fs.existsSync(vendorShaPath)) { vm.runInContext(fs.readFileSync(vendorShaPath, 'utf8'), sandbox); } vm.runInContext( - fs.readFileSync(path.join(__dirname, 'public/channel-decrypt.js'), 'utf8'), + fs.readFileSync(path.join(REPO_ROOT, 'public/channel-decrypt.js'), 'utf8'), sandbox ); return sandbox.window.ChannelDecrypt; diff --git a/test-channel-decrypt-m345.js b/tests/unit/test-channel-decrypt-m345.js similarity index 97% rename from test-channel-decrypt-m345.js rename to tests/unit/test-channel-decrypt-m345.js index 0dccbbdf..0c77eaa1 100644 --- a/test-channel-decrypt-m345.js +++ b/tests/unit/test-channel-decrypt-m345.js @@ -3,6 +3,7 @@ * Runs in Node.js via vm.createContext to simulate browser environment. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const vm = require('vm'); const fs = require('fs'); @@ -58,7 +59,7 @@ async function runTests() { console.log('\n=== M3: PSK hex key detection ==='); // Load channel-decrypt.js in sandbox - const cdSrc = fs.readFileSync(__dirname + '/public/channel-decrypt.js', 'utf8'); + const cdSrc = fs.readFileSync(REPO_ROOT + '/public/channel-decrypt.js', 'utf8'); const sandbox = createSandbox(); const context = vm.createContext(sandbox); vm.runInContext(cdSrc, context); diff --git a/test-channel-fluid-layout.js b/tests/unit/test-channel-fluid-layout.js similarity index 96% rename from test-channel-fluid-layout.js rename to tests/unit/test-channel-fluid-layout.js index 3d06a899..07bdb1a1 100644 --- a/test-channel-fluid-layout.js +++ b/tests/unit/test-channel-fluid-layout.js @@ -9,12 +9,13 @@ * Companion E2E (real viewport assertions): test-channel-fluid-e2e.js. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); const assert = require('assert'); -const css = fs.readFileSync(path.join(__dirname, 'public/style.css'), 'utf8'); +const css = fs.readFileSync(path.join(REPO_ROOT, 'public/style.css'), 'utf8'); let passed = 0, failed = 0; function test(name, fn) { diff --git a/test-channel-issue-1087.js b/tests/unit/test-channel-issue-1087.js similarity index 95% rename from test-channel-issue-1087.js rename to tests/unit/test-channel-issue-1087.js index ca3ace34..9bd52abc 100644 --- a/test-channel-issue-1087.js +++ b/tests/unit/test-channel-issue-1087.js @@ -20,6 +20,7 @@ * Companion E2E coverage: test-channel-issue-1087-e2e.js */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); @@ -31,10 +32,10 @@ function assert(cond, msg) { else { failed++; console.error(' ✗ ' + msg); } } -const chSrc = fs.readFileSync(path.join(__dirname, 'public/channels.js'), 'utf8'); -const qrSrc = fs.readFileSync(path.join(__dirname, 'public/channel-qr.js'), 'utf8'); -const decSrc = fs.readFileSync(path.join(__dirname, 'public/channel-decrypt.js'), 'utf8'); -const idxSrc = fs.readFileSync(path.join(__dirname, 'public/index.html'), 'utf8'); +const chSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/channels.js'), 'utf8'); +const qrSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/channel-qr.js'), 'utf8'); +const decSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/channel-decrypt.js'), 'utf8'); +const idxSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/index.html'), 'utf8'); console.log('\n=== #1087 Bug 1: QR vendor library is wired correctly ==='); diff --git a/test-channel-issue-1101.js b/tests/unit/test-channel-issue-1101.js similarity index 95% rename from test-channel-issue-1101.js rename to tests/unit/test-channel-issue-1101.js index d6c178ea..2a4877b4 100644 --- a/test-channel-issue-1101.js +++ b/tests/unit/test-channel-issue-1101.js @@ -11,6 +11,7 @@ * text, no Copy Key button overlapping it. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); @@ -21,8 +22,8 @@ function assert(cond, msg) { else { failed++; console.error(' ✗ ' + msg); } } -const channelsSrc = fs.readFileSync(path.join(__dirname, 'public', 'channels.js'), 'utf8'); -const qrSrc = fs.readFileSync(path.join(__dirname, 'public', 'channel-qr.js'), 'utf8'); +const channelsSrc = fs.readFileSync(path.join(REPO_ROOT, 'public', 'channels.js'), 'utf8'); +const qrSrc = fs.readFileSync(path.join(REPO_ROOT, 'public', 'channel-qr.js'), 'utf8'); console.log('\n=== #1101: Share modal markup ==='); diff --git a/test-channel-live-decrypt-userprefix.js b/tests/unit/test-channel-live-decrypt-userprefix.js similarity index 98% rename from test-channel-live-decrypt-userprefix.js rename to tests/unit/test-channel-live-decrypt-userprefix.js index 091bdcf2..eaffdc41 100644 --- a/test-channel-live-decrypt-userprefix.js +++ b/tests/unit/test-channel-live-decrypt-userprefix.js @@ -38,6 +38,7 @@ * 4. unread is NOT bumped on the channel currently being viewed */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const vm = require('vm'); const fs = require('fs'); @@ -150,7 +151,7 @@ function makeBrowserLikeSandbox() { } function loadInCtx(ctx, file) { - const src = fs.readFileSync(path.join(__dirname, file), 'utf8'); + const src = fs.readFileSync(path.join(REPO_ROOT, file), 'utf8'); vm.runInContext(src, ctx, { filename: file }); for (const k of Object.keys(ctx.window)) ctx[k] = ctx.window[k]; } diff --git a/test-channel-live-decrypt.js b/tests/unit/test-channel-live-decrypt.js similarity index 96% rename from test-channel-live-decrypt.js rename to tests/unit/test-channel-live-decrypt.js index e7db96a7..18bd8f5f 100644 --- a/test-channel-live-decrypt.js +++ b/tests/unit/test-channel-live-decrypt.js @@ -18,6 +18,7 @@ * channels the user is not currently viewing. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const vm = require('vm'); const fs = require('fs'); @@ -87,8 +88,8 @@ function buildEncryptedGrpTxt(channelName, sender, message) { async function run() { console.log('\n=== Live PSK decrypt: ChannelDecrypt helpers ==='); - const cdSrc = fs.readFileSync(path.join(__dirname, 'public/channel-decrypt.js'), 'utf8'); - const aesSrc = fs.readFileSync(path.join(__dirname, 'public/vendor/aes-ecb.js'), 'utf8'); + const cdSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/channel-decrypt.js'), 'utf8'); + const aesSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/vendor/aes-ecb.js'), 'utf8'); const sandbox = createSandbox(); const ctx = vm.createContext(sandbox); vm.runInContext(aesSrc, ctx); @@ -143,7 +144,7 @@ async function run() { 'tryDecryptLive returns null when encryptedData/mac missing'); console.log('\n=== Live PSK decrypt: channels.js integration contract ==='); - const chSrc = fs.readFileSync(path.join(__dirname, 'public/channels.js'), 'utf8'); + const chSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/channels.js'), 'utf8'); assert(/tryDecryptLive\s*\(/.test(chSrc), 'channels.js calls ChannelDecrypt.tryDecryptLive() in the WS path'); assert(/buildKeyMap\s*\(/.test(chSrc), diff --git a/test-channel-modal-ux.js b/tests/unit/test-channel-modal-ux.js similarity index 96% rename from test-channel-modal-ux.js rename to tests/unit/test-channel-modal-ux.js index 5c4e3b17..795e87cf 100644 --- a/test-channel-modal-ux.js +++ b/tests/unit/test-channel-modal-ux.js @@ -16,6 +16,7 @@ * Runs in Node.js — no browser. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); @@ -27,8 +28,8 @@ function assert(cond, msg) { else { failed++; console.error(' ✗ ' + msg); } } -const chSrc = fs.readFileSync(path.join(__dirname, 'public/channels.js'), 'utf8'); -const cssSrc = fs.readFileSync(path.join(__dirname, 'public/style.css'), 'utf8'); +const chSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/channels.js'), 'utf8'); +const cssSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/style.css'), 'utf8'); console.log('\n=== #1034 PR1: [+ Add Channel] sidebar button ==='); assert(/id="chAddChannelBtn"/.test(chSrc), diff --git a/test-channel-psk-ux.js b/tests/unit/test-channel-psk-ux.js similarity index 97% rename from test-channel-psk-ux.js rename to tests/unit/test-channel-psk-ux.js index 9123b7f4..a75ea5f7 100644 --- a/test-channel-psk-ux.js +++ b/tests/unit/test-channel-psk-ux.js @@ -9,6 +9,7 @@ * Runs in Node.js via vm.createContext to simulate the browser. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const vm = require('vm'); const fs = require('fs'); @@ -47,7 +48,7 @@ function createSandbox() { async function run() { console.log('\n=== #1020 PSK UX: ChannelDecrypt label storage ==='); - const cdSrc = fs.readFileSync(path.join(__dirname, 'public/channel-decrypt.js'), 'utf8'); + const cdSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/channel-decrypt.js'), 'utf8'); const sandbox = createSandbox(); vm.runInContext(cdSrc, vm.createContext(sandbox)); const CD = sandbox.window.ChannelDecrypt; @@ -78,7 +79,7 @@ async function run() { assert(!CD.getLabel('#LongFast'), 'no label means getLabel returns falsy'); console.log('\n=== #1020 PSK UX: channels.js DOM/contract ==='); - const chSrc = fs.readFileSync(path.join(__dirname, 'public/channels.js'), 'utf8'); + const chSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/channels.js'), 'utf8'); // E2E DOM: optional label input in add form (now in #1034 modal as #chPskName) assert(chSrc.includes('id="chPskName"') || chSrc.includes('id="chKeyLabelInput"'), diff --git a/test-channel-qr-wiring.js b/tests/unit/test-channel-qr-wiring.js similarity index 96% rename from test-channel-qr-wiring.js rename to tests/unit/test-channel-qr-wiring.js index 4d92a966..5284cce5 100644 --- a/test-channel-qr-wiring.js +++ b/tests/unit/test-channel-qr-wiring.js @@ -8,6 +8,7 @@ * E2E behavior is covered by test-channel-modal-e2e.js extensions. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); @@ -20,7 +21,7 @@ function assert(cond, msg) { } const src = fs.readFileSync( - path.join(__dirname, 'public/channels.js'), + path.join(REPO_ROOT, 'public/channels.js'), 'utf8' ); diff --git a/test-channel-qr.js b/tests/unit/test-channel-qr.js similarity index 96% rename from test-channel-qr.js rename to tests/unit/test-channel-qr.js index 310f6603..3bbd6f45 100644 --- a/test-channel-qr.js +++ b/tests/unit/test-channel-qr.js @@ -7,6 +7,7 @@ * elsewhere in the redesign series. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const vm = require('vm'); const fs = require('fs'); @@ -30,7 +31,7 @@ function loadChannelQR() { sandbox.self = sandbox; vm.createContext(sandbox); - const src = fs.readFileSync(path.join(__dirname, 'public/channel-qr.js'), 'utf8'); + const src = fs.readFileSync(path.join(REPO_ROOT, 'public/channel-qr.js'), 'utf8'); vm.runInContext(src, sandbox); return sandbox.window.ChannelQR; } diff --git a/test-channel-sidebar-layout.js b/tests/unit/test-channel-sidebar-layout.js similarity index 95% rename from test-channel-sidebar-layout.js rename to tests/unit/test-channel-sidebar-layout.js index 6d57f462..ec8e93e3 100644 --- a/test-channel-sidebar-layout.js +++ b/tests/unit/test-channel-sidebar-layout.js @@ -19,6 +19,7 @@ * clearer copy and stays grouped with the channel controls. */ 'use strict'; +const REPO_ROOT = require('path').resolve(__dirname, '..', '..'); const fs = require('fs'); const path = require('path'); @@ -29,8 +30,8 @@ function assert(cond, msg) { else { failed++; console.error(' ✗ ' + msg); } } -const chSrc = fs.readFileSync(path.join(__dirname, 'public/channels.js'), 'utf8'); -const cssSrc = fs.readFileSync(path.join(__dirname, 'public/style.css'), 'utf8'); +const chSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/channels.js'), 'utf8'); +const cssSrc = fs.readFileSync(path.join(REPO_ROOT, 'public/style.css'), 'utf8'); console.log('\n=== Sidebar layout: no nested