Skip to content

feat(e2e-web): shared Playwright E2E suite for web SDK implementations [NT-3466]#319

Draft
David Nalchevanidze (nalchevanidze) wants to merge 65 commits into
mainfrom
NT-3466-shared
Draft

feat(e2e-web): shared Playwright E2E suite for web SDK implementations [NT-3466]#319
David Nalchevanidze (nalchevanidze) wants to merge 65 commits into
mainfrom
NT-3466-shared

Conversation

@nalchevanidze

Copy link
Copy Markdown
Contributor

Summary

  • Add implementations/e2e-web — standalone Playwright package with all 9 shared web E2E specs
  • Both web-sdk_react and web-sdk_angular delegate to it; no duplicated spec files
  • Each implementation passes BASE_URL and PUBLIC_OPTIMIZATION_ENABLE_PREVIEW_PANEL so the same specs work against both
  • Align Angular UI text with React ("Auto Observed Entries", "Manually Observed Entries", "Accept Consent") to eliminate per-implementation forks
  • Fix deterministic audience resolution by clearing cookies in beforeEach for variant display specs

Test plan

  • pnpm --dir implementations/web-sdk_angular test:e2e → 78 passed
  • pnpm --dir implementations/web-sdk_react test:e2e → 72 passed, 6 skipped (preview panel disabled in React)

🤖 Generated with Claude Code

- Add playwright.config.mjs with webServer readiness gate, workers=1,
  and per-assertion timeout to fix headless vs UI mode parity
- Add e2e/ with all specs copied from web-sdk_react as a starting point
- Update serve:app to use ng serve via PM2 with log-based readiness wait
- Add test:e2e:setup shared between headless and UI commands
- Add allowedCommonJsDependencies for lodash to suppress build warning

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Align heading selectors with Angular template text ('Auto-observed', 'Manually-observed')
- Use data-testid instead of role+name for consent button ('Grant' vs 'Accept Consent')
- Normalize page event URL to pathname in tracking log so navigation spec matches React behavior
- Count all non-null stream events for rawEventsCount so identify events are included

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…T-3466]

Move all E2E specs into a new e2e-web package so React and Angular run the
same tests without duplication. Each implementation delegates to e2e-web
via BASE_URL and PUBLIC_OPTIMIZATION_ENABLE_PREVIEW_PANEL env vars.

Align Angular UI text with React (heading names, consent button label) so a
single spec set covers both implementations without per-implementation forks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ience resolution [NT-3466]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new package is not an implementation of its own, so maybe we should consider moving it to /lib from project root.

If this is not yet intended to be ready, please set it as a draft.

e2e-web scripts no longer hardcode BASE_URL or implementation-specific
env vars — each implementation passes them when delegating.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ferences [NT-3466]

Use storageState to give each test a fresh context (no cookies, no localStorage)
so SDK profile state from previous tests cannot affect audience resolution.

Add baseline fallbacks for visitor-type and A/B/C entries that resolve
differently across browsers due to fingerprint-based audience classification.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Env vars are passed by parent implementation scripts, not loaded from a local .env.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All env vars are passed by parent callers, no local .env needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…[NT-3466]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ives [NT-3466]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…to E2E_BASE_URL [NT-3466]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…3466]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nalchevanidze David Nalchevanidze (nalchevanidze) marked this pull request as draft June 16, 2026 13:28
… E2E scripts [NT-3466]

- Switch Angular from ng serve (watch mode) to ng build + http-server (static) on port 3000
- Both implementations now share port 3000, removing the need for E2E_BASE_URL
- Rename E2E_BASE_URL back to BASE_URL in playwright.config.mjs
- Remove set -a / . ./.env / set +a from test:e2e and test:e2e:ui scripts
- Remove curl wait loop from Angular serve script (moved to test:e2e:setup)
- Remove E2E_BASE_URL from Angular .env.example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…E jobs [NT-3466]

- Add e2e-web install + playwright install steps to e2e-web-sdk_react CI job
- Add new e2e-web-sdk_angular CI job mirroring the React job structure
- Add e2e_web_sdk_angular path filter and output to the changes job
- Update e2e_web_sdk_react filter to also include implementations/e2e-web/**
- Fix artifact paths to point to implementations/e2e-web/ (where Playwright outputs reports)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…h, raise bundle budget [NT-3466]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…stency [NT-3466]

Matches web-sdk_react/.env.example which already has it false. Preview panel
tests in live-updates.spec.ts are guarded by isPreviewPanelEnabled and skip
when false, so there is no coverage loss.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
angular.json defines import.meta.env as a static empty object {}, so
PUBLIC_OPTIMIZATION_ENABLE_PREVIEW_PANEL is always undefined. The previous
!== 'false' check meant the preview panel was always enabled in Angular.
Switching to === 'true' makes it disabled by default, consistent with the
React implementation and correct for E2E.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ject [NT-3466]

process.env references in angular.json define are not evaluated at build time;
angular.json only accepts static string literals. The opt-in guard in app.config.ts
(=== 'true') is sufficient to keep preview panel off by default.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…stop [NT-3466]

When PM2 runs "pnpm --dir lib/mocks serve", killing the PM2 process kills the
shell but leaves the tsx child holding port 8000. On the next serve:mocks start,
the port is already bound and the mock server crashes with EADDRINUSE, causing
all API calls to fail and tests to hang. Running tsx directly makes PM2 own the
actual process and SIGTERM reaches it cleanly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…l health-check [NT-3466]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…00 [NT-3466]

- Switch trace from 'on-first-retry' to 'on' locally: with 0 retries no
  trace files are ever written, causing the UI trace viewer to flood the
  console with 404/500 errors and preventing tests from running in UI mode.
- Add a second webServer entry for port 8000 so Playwright polls and waits
  for the mocks server before dispatching tests. PM2 start returns immediately
  after forking the tsx process; without the readiness check the first API
  call races tsx startup and hangs until the 60s test timeout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ht to 1.61.0 [NT-3466]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…b [NT-3466]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cripts [NT-3466]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…estable by attribute

- Angular: revert label to plain event.value; add duration as separate column with CSS
- Angular: fix component_hover badge type from component_hover to hover (now styled purple)
- Angular + React: expose data-hover-duration-ms / data-view-duration-ms attributes on event rows
- E2E: read hover duration from attribute instead of parsing inner text

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tus value

The label column already says "Consent" so the value cell should show
just the boolean. Angular, React, and E2E updated consistently.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… testability

Simplifying the Angular label to plain event.value broke navigation-page-events.spec.ts
which was parsing 'URL: ' from innerText. Fix: expose data-page-url on page event rows
in Angular and React; read it by attribute in the test instead of parsing text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gular layout

Replace the flat <ul> with a <table> showing badge, value, and duration columns.
Badge types mapped consistently with Angular (view/comp/hover/page).
data-hover-duration-ms, data-view-duration-ms, data-page-url attributes preserved on <tr>.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… testid

The test was using data-ctfl-entry-id as hoverId, but the SDK emits a
different ID in hoverId. Restored the original approach: hover the entry,
wait for any hover event to appear, extract hoverId from its data-testid,
then use that to read data-hover-duration-ms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Angular layout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-events-count

events-count was only used as a UI-ready sentinel in the offline E2E test,
which already checks raw-events-count right after.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eader

Show count as a pill badge next to the Tracking heading in both Angular and React.
Text reads "N events" instead of "Raw Events: N". E2E parser updated to match.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rop parser

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ad of relative age

Drops the tick-based timeAgo interval in Angular. Both implementations now show
HH:MM:SS at the end of each row. Type badge stays first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…t last

- thead: Type / Value / Dur / Age / (count)
- Duration displayed as X.Xs instead of Xms
- Age: compact relative (0s, 2m) with 5s auto-refresh tick
- Count (×N) moved to last column

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wrap app in a 100vh flex column so nav stays fixed and the sidebar and
main content scroll independently — the sidebar no longer moves when
page content scrolls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…l/value/button grid)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After the Utilities grid refactor the element holds a plain number,
not 'Selected Optimizations: N'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…button / reset-button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Dev server (ng serve / rsbuild preview) keeps PUBLIC_OPTIMIZATION_ENABLE_PREVIEW_PANEL=false
from .env. E2E and E2E UI scripts build with the flag set to true via serve:app:e2e.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_PANEL is false

Angular: expose isPreviewPanelEnabled from import.meta.env and guard the row with @if.
React: guard with ENABLE_PREVIEW_PANEL build constant.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ad of template

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… attribute on content element

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ng for panel button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…enable in .env.example

- Replace import.meta.env.PUBLIC_OPTIMIZATION_ENABLE_PREVIEW_PANEL === 'true' checks in app.ts
  and control-panel/index.ts with config.previewPanel !== undefined from injected token
- Update .env.example to enable preview panel by default (true)
- Remove redundant sourceMap/define overrides from angular.json development config since
  .env already supplies the value at dev time

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ore angular.json define

- Add fromSdkConditionalState to utils.ts: accepts a reactive factory that returns
  an SdkObservable or undefined, re-subscribes when dependencies change, resets to
  undefined when factory returns undefined
- Simplify control-panel booleanFlag to use fromSdkConditionalState instead of
  inline effect + manual subscription management
- Restore sourceMap and define for PUBLIC_OPTIMIZATION_ENABLE_PREVIEW_PANEL in
  angular.json development config — needed for E2E builds that pass the flag via
  shell env prefix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gating

Preview panel is unconditionally enabled in the Angular reference implementation.
Remove PUBLIC_OPTIMIZATION_ENABLE_PREVIEW_PANEL env var, define block, isPreviewPanelEnabled
checks, and all related conditional logic from app.config.ts, app.ts, control-panel,
angular.json, package.json, env.d.ts, and .env.example.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants