From 0cf1dc0f55779e83ce9d6ff956be9913efcea844 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sat, 21 Feb 2026 20:45:47 -0500 Subject: [PATCH] improved playright integration --- .github/workflows/ci.yml | 48 +++ AGENTS.md | 18 + README.md | 14 +- components/profile-modal.html | 14 +- ...-integration-recommendations-2026-02-22.md | 63 ++++ js/testHarness.js | 313 +++++++++++++++++- .../ProfileBlockListController.js | 4 + js/userBlocks.js | 54 +-- package.json | 6 +- playwright.config.ts | 57 +++- .../playwright/run-extension-persistent.mjs | 49 +++ .../helpers/persistentExtensionFixture.ts | 88 +++++ .../nip07-extension.smoke.spec.ts | 34 ++ tests/e2e/agent-testability.spec.ts | 66 +++- tests/e2e/helpers/bitvidTestFixture.ts | 102 ++++++ .../e2e/profile-list-sync-diagnostics.spec.ts | 185 +++++++++++ tests/user-blocks.test.mjs | 107 ++++++ 17 files changed, 1165 insertions(+), 57 deletions(-) create mode 100644 docs/testing/playwright-integration-recommendations-2026-02-22.md create mode 100644 scripts/playwright/run-extension-persistent.mjs create mode 100644 tests/e2e-extension/helpers/persistentExtensionFixture.ts create mode 100644 tests/e2e-extension/nip07-extension.smoke.spec.ts create mode 100644 tests/e2e/profile-list-sync-diagnostics.spec.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8eb99fb..afcbe295 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -352,6 +352,54 @@ jobs: - name: Run DM unit tests run: npm run test:dm:unit + e2e-tests: + runs-on: ubuntu-latest + timeout-minutes: 35 + strategy: + fail-fast: false + matrix: + node-version: [22] + project: [e2e, e2e-firefox] + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + + - name: Cache npm directory + uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ matrix.node-version }}-npm-${{ hashFiles('package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-${{ matrix.node-version }}-npm- + + - name: Cache node_modules + id: node-modules-cache + uses: actions/cache@v4 + with: + path: node_modules + key: ${{ runner.os }}-node-${{ matrix.node-version }}-modules-${{ hashFiles('package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-${{ matrix.node-version }}-modules- + + - name: Install dependencies + if: steps.node-modules-cache.outputs.cache-hit != 'true' + run: npm ci + + - name: Build app + run: npm run build + + - name: Install Playwright browsers + run: npx playwright install --with-deps chromium firefox + + - name: Run deterministic E2E suite (${{ matrix.project }}) + run: npx playwright test tests/e2e --project=${{ matrix.project }} + dm-integration-tests: runs-on: ubuntu-latest timeout-minutes: 30 diff --git a/AGENTS.md b/AGENTS.md index 7db688cb..f75a0f61 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -366,6 +366,11 @@ Or set `localStorage.__bitvidTestRelays__` to a JSON array of relay URLs. | `waitForSelector(sel, ms)` | `Promise` | Wait for a DOM element | | `getRelayHealth()` | `{ relays, unreachable, backoff }` | Relay connection status | | `applyRelayOverrides(urls)` | `boolean` | Redirect relay connections | +| `setTestRelays(urls)` | `{ ok, relays }` | Align relayManager + nostrClient to a deterministic relay set | +| `setSignerDecryptBehavior(mode, opts?)` | `{ ok, mode, ... }` | Force decrypt behavior (`passthrough`, `timeout`, `error`, `delay`) for signer-based list sync tests | +| `getListSyncEvents()` | `Array<{ source, at, detail }>` | Read captured sync timeline (`bitvid:auth-loading-state` + `userBlocks` status) | +| `clearListSyncEvents()` | `void` | Reset captured sync events between assertions | +| `waitForListSyncEvent(criteria, ms?)` | `Promise` | Wait for sync milestones (`status`, `reason`, `source`) | | `nostrClient` | `NostrClient` | Direct access for advanced use | ### Mock Relay (`scripts/agent/simple-relay.mjs`) @@ -406,6 +411,9 @@ test("agent can seed and view videos", async ({ page, gotoApp, loginAs, seedEven | `clearRelay()` | `() => Promise` | Wipe all relay events | | `gotoApp(path?)` | `(string?) => Promise` | Navigate with test mode + relay overrides | | `loginAs(page)` | `(Page) => Promise` | Login with deterministic test key | +| `setTestRelays(page, relays)` | `(Page, string[]) => Promise<{ok, relays}>` | Force relay alignment through harness + relayManager | +| `setDecryptBehavior(page, mode, opts?)` | `(Page, mode, opts?) => Promise` | Force signer decrypt behavior (`passthrough`, `timeout`, `error`, `delay`) | +| `startDiagnostics(page, opts?)` | `(Page, opts?) => Promise<{stop()}>` | Capture console/page errors and list-sync telemetry for assertions | | `testPubkey` | `string` | Hex pubkey of the test key | | `relayUrl` | `string` | WebSocket URL of the mock relay | @@ -418,6 +426,8 @@ Use these for stable element targeting: | `[data-testid="login-button"]` | Header login button | | `[data-testid="upload-button"]` | Header upload button (hidden until logged in) | | `[data-testid="profile-button"]` | Header profile button (hidden until logged in) | +| `[data-testid="profile-permission-prompt"]` | Profile list-sync permission CTA container | +| `[data-testid="profile-permission-prompt-button"]` | Profile list-sync permission/retry CTA button | | `[data-testid="search-input"]` | Header search field | | `[data-testid="login-modal"]` | Login modal container | | `[data-testid="login-provider-button"]` | Login provider option buttons | @@ -428,6 +438,12 @@ Use these for stable element targeting: | `[data-testid="upload-url"]` | Video URL input | | `[data-testid="upload-magnet"]` | Magnet link input | | `[data-testid="upload-submit"]` | Publish button | +| `[data-testid="hashtags-sync-status"]` | Profile hashtag sync status message | +| `[data-testid="subscriptions-sync-status"]` | Profile subscriptions sync status message | +| `[data-testid="blocked-refresh-button"]` | Profile blocked creators refresh button | +| `[data-testid="blocked-sync-status"]` | Profile blocked creators sync status message | +| `[data-testid="blocked-list"]` | Blocked creators list container | +| `[data-testid="blocked-empty-state"]` | Blocked creators empty state | | `[data-testid="video-modal"]` | Video player modal | | `[data-testid="video-card"]` | Individual video card in the feed | | `[data-testid="video-list"]` | Video feed grid container | @@ -440,6 +456,8 @@ Use these for stable element targeting: | `scripts/agent/simple-relay.mjs` | Mock relay with HTTP seeding API | | `tests/e2e/helpers/bitvidTestFixture.ts` | Reusable Playwright fixture | | `tests/e2e/agent-testability.spec.ts` | Infrastructure validation tests | +| `scripts/playwright/run-extension-persistent.mjs` | Dedicated persistent-context launcher for extension smoke tests | +| `docs/testing/playwright-integration-recommendations-2026-02-22.md` | Playwright/extension integration recommendations and follow-ups | --- diff --git a/README.md b/README.md index 4aa69277..659ab279 100644 --- a/README.md +++ b/README.md @@ -213,7 +213,13 @@ For detailed architecture and system documentation, see the [Documentation Index - **Run load tests**: `npm run test:load` - **Run DM unit tests**: `npm run test:dm:unit` - **Run DM integration tests**: `npm run test:dm:integration` -- **Run headless E2E tests**: `npm run test:e2e` +- **Run headless E2E tests (Chromium + Firefox)**: `npm run test:e2e` +- **Run E2E tests (Chromium only)**: `npm run test:e2e:chromium` +- **Run E2E tests (Firefox only)**: `npm run test:e2e:firefox` +- **Run deterministic E2E matrix**: `npm run test:e2e:deterministic` +- **Run NIP-07 extension smoke (opt-in)**: `PLAYWRIGHT_EXTENSION_PATH=/abs/path/to/extension npm run test:e2e:extension` + - Uses persistent-context launcher: `scripts/playwright/run-extension-persistent.mjs` + - Optional profile dir: `PLAYWRIGHT_EXTENSION_USER_DATA_DIR=/abs/path/to/profile` - **Run visual regression tests**: `npm run test:visual` - **Update visual baselines**: `npm run test:visual:update` - **Run design system audit**: `npm run audit` (Generates remediation report) @@ -572,7 +578,11 @@ Before pushing, run `npm run build` locally so the Tailwind bundle regenerates. - **Direct Messages**: Run `npm run test:dm:unit` and `npm run test:dm:integration` for DM flows. -- **End-to-End**: Run `npm run test:e2e` for headless Playwright journeys. +- **End-to-End**: + - `npm run test:e2e` runs deterministic Playwright journeys on Chromium + Firefox. + - `npm run test:e2e:chromium` / `npm run test:e2e:firefox` runs a single browser target. + - `npm run test:e2e:extension` runs the opt-in Chromium extension suite (set `PLAYWRIGHT_EXTENSION_PATH` and optionally `PLAYWRIGHT_ENABLE_EXTENSION_E2E=1`). + - Recommendations/roadmap: `docs/testing/playwright-integration-recommendations-2026-02-22.md` ### Manual QA checklist diff --git a/components/profile-modal.html b/components/profile-modal.html index 4ecaef64..869f127a 100644 --- a/components/profile-modal.html +++ b/components/profile-modal.html @@ -383,16 +383,19 @@ >