Skip to content

test(e2e): add Playwright E2E suite for 17 widget examples#684

Open
vinzenzLIFI wants to merge 22 commits into
mainfrom
test/emb-331-create-playwright-test-suite
Open

test(e2e): add Playwright E2E suite for 17 widget examples#684
vinzenzLIFI wants to merge 22 commits into
mainfrom
test/emb-331-create-playwright-test-suite

Conversation

@vinzenzLIFI
Copy link
Copy Markdown

@vinzenzLIFI vinzenzLIFI commented Apr 2, 2026

Which Linear task is linked to this PR?

EMB-331 — CI: Playwright E2E suite for widget examples

Why was it implemented this way?

Adds a full Playwright E2E suite that verifies all 17 active widget example apps still render and behave correctly when packages or example code changes.

What this adds

Test suite (e2e/) with a Component Object Model structure:

  • tests/components/ — reusable component objects (WidgetExchange, SettingsView, TokenSelectorView, PlaygroundSidebar)
  • tests/fixtures/base.fixture.ts — extended test fixture with widget helpers and waitForTokens()
  • tests/profiles/ — specs per profile (standard/routed, iframe, nft)
  • tests/playground/ — smoke tests for the widget playground

4 example profiles, each with its own spec:

Profile Examples Assertions
standard vite, connectkit, privy, privy-ethers, rainbowkit, reown, svelte, zustand-widget-config, vue, nextjs, nextjs15, remix, react-router-7 Widget root, Exchange heading, From/To buttons, Settings flow, token selector end-to-end
routed tanstack-router Same as standard, navigates to /widget first
iframe vite-iframe, vite-iframe-wagmi iframe present, widget root inside frame, Exchange heading, Settings button
nft nft-checkout Widget root, Checkout heading, Pay with section

Local test scripts — full build → serve → test → kill cycle:

pnpm test:example vite          # single example
pnpm test:examples              # all 17 sequentially

CI workflow (e2e-examples.yml) — triggers on every PR to main:

  • detect-changes job computes which examples to test: isolated examples/<name>/ change → that example only; shared package / lockfile / e2e/ change → all 17
  • One matrix job per affected example (fail-fast: false)
  • On failure: Playwright report uploaded as artifact + sticky PR comment listing which examples failed (via marocchino/sticky-pull-request-comment)

Rolldown rc.17 fixvite@8.0.10 introduced a Rolldown regression that causes a circular chunk dependency at runtime (Class extends value undefined) in any example using @wagmi/connectors. Added build.rolldownOptions.output.strictExecutionOrder: true to 8 affected examples. Same fix already applied to widget-embedded / widget-playground-vite in #721. Will be removed once the upstream fix lands in Rolldown.

Known broken examples (not tested)

Example Issue Ticket
dynamic vite-plugin-env-compatible doesn't shim process globally — Dynamic SDK crashes at runtime EMB-349
nuxt veaury's React bridge fails in Nuxt SSR production build (R is not a function) EMB-350
deposit-flow Widget's own error boundary fires at runtime — root never mounts EMB-351

Flip status: 'broken' → 'active' in e2e/examples.config.ts to include them once fixed.

Selector strategy

Tests use ARIA roles and visible text rather than data-testid attributes — the widget is a library and data-testid would need to be stripped from production builds (not yet solved). Widget root uses a prefix selector [id^="widget-app-expanded-container"] because the full ID includes a React useId() suffix that varies per build.

Visual showcase (Screenshots or Videos)

N/A — CI workflow and test suite, no UI changes.

Checklist before requesting a review

  • I have performed a self-review and testing of my code.
  • This pull request is focused and addresses a single problem.
  • If this PR modifies the Widget API or adds new features that require documentation, I have updated the documentation in the public-docs repository.

Linear

@vinzenzLIFI vinzenzLIFI force-pushed the test/emb-331-create-playwright-test-suite branch from afedcc4 to 294e07c Compare April 14, 2026 08:39
@vinzenzLIFI vinzenzLIFI force-pushed the test/emb-331-create-playwright-test-suite branch from 294e07c to e6456d3 Compare May 5, 2026 15:28
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

E2E Examples — failures

The following example(s) failed:

  • connectkit
  • vite

See the workflow run for Playwright reports and logs.

@vinzenzLIFI vinzenzLIFI changed the title test(smoke): setup playwright test suite test(e2e): add Playwright E2E suite for 17 widget examples May 7, 2026
@vinzenzLIFI vinzenzLIFI marked this pull request as ready for review May 7, 2026 11:59
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

E2E Examples — all passed

All examples passed in the latest run.

await page.goto('/')
})

test('widget root is visible', async ({ page }) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can all of these tests be moved into test.steps() ?

*/
export async function waitForTokens(page: Page): Promise<void> {
await page.waitForResponse(
(res) => res.url().includes('/v1/tokens') && res.status() === 200
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is it worth here to add timeout? e.g 10-15sec?

await page.waitForResponse( (res) => res.url().includes('/v1/tokens') && res.status() === 200, { timeout: 15_000 } )

effie-ms and others added 20 commits May 8, 2026 11:41
The smoke spec mixed playground-only tests with @example-tagged tests
intended for portability. Split it cleanly:

- Move playground tests to tests/playground/smoke.spec.ts and drop the
  @example tags
- Add testIgnore for tests/profiles/** so the playground config does
  not pick up the upcoming examples profile specs
- Start widget-playground-vite automatically via webServer; reuse an
  existing server locally
- Repoint the e2e smoketest script to tests/playground and remove the
  now-unused smoke:example passthrough at root and in e2e/

Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce a second Playwright config dedicated to the example apps in
examples/. Each active example becomes its own Playwright project with
a baseURL bound to its serve port and a profile spec that reflects how
the widget renders.

- e2e/examples.config.ts is the single source of truth: each entry
  declares package, port, build/serve commands, mountPath, and profile
- e2e/playwright.examples.config.ts generates one project per active
  example. No webServer block — the server lifecycle is owned by the
  caller (local scripts or CI) so the same suite runs uniformly in
  both contexts
- Three profile specs cover today's shapes:
    * widget-smoke — standard + routed (mountPath from project metadata)
    * iframe       — LiFiWidgetLight wrapping
    * nft          — NFT checkout subvariant
- Add e2e:examples / e2e:example scripts (passthrough at root, real
  invocation in e2e/) that take the new config explicitly so the
  default playground config stays untouched
- Ignore playwright-report-examples/ alongside playwright-report/

Co-authored-by: Cursor <cursoragent@cursor.com>
Add bash orchestrators that build a single example, start its preview
server on a known port, run its Playwright project, and tear the
server down — both for one-shot use and a sequential loop over every
active example.

- scripts/test-example.sh: build → serve → wait-for-ready → run
  Playwright with --project <name> against the new examples config →
  kill server. Mirrors the per-example metadata in
  e2e/examples.config.ts so local runs match CI exactly
- scripts/test-all-examples.sh: invokes the per-example script for
  every active entry sequentially; exit code surfaces the first
  failure
- Wire pnpm test:example <name> and pnpm test:examples at the root

Co-authored-by: Cursor <cursoragent@cursor.com>
Swap the old single-job examples-smoke-test workflow for one that
mirrors how local runs work and only tests what changed.

- detect-changes job computes which examples need testing: a change
  inside examples/<name>/ runs that example, while a change to
  packages/widget/**, packages/wallet-management/**,
  packages/widget-provider*/**, or e2e/** runs all 17 active
  examples
- Each selected example runs as its own matrix job (parallel,
  fail-fast: false) so one broken example does not mask the others
- Each job builds workspace packages, installs example deps, builds
  the example, starts its preview server with PORT honoured for
  remix/react-router-7, waits for readiness, then runs the matching
  Playwright project against the examples config

Drop the old examples-smoke-test.yml — the new workflow supersedes it
and the playground smoke path is now covered by the playground suite.

Co-authored-by: Cursor <cursoragent@cursor.com>
Rewrite e2e/README.md to describe the two coexisting suites and how
to run, extend, and debug them.

- Up-front summary table mapping each suite to its config and what it
  tests
- Prerequisite section calling out the workspace package build that
  must run before example tests, including the exact pnpm filter
  command CI uses (avoids stale dist artifacts on first runs)
- Per-profile assertion summary for standard / routed / iframe / nft
- Per-example build/serve notes covering the vite-build vs build
  distinction (MUI v7 props + @lifi/types mismatch), the PORT env var
  for remix and react-router-7, and Next.js / Nuxt defaults
- Known broken examples table linking to the EMB-349 / EMB-350 /
  EMB-351 tickets, with the unblocking criterion
- Stale-directory note pointing at the leftover examples/nextjs14*
  scaffolds that are intentionally not wired up
- Architecture, selector strategy, and CI sections kept

Drop the now-unused e2e/.env.test.example placeholder; the playground
config reads BASE_URL straight from the environment and the README
no longer references .env.test.

Co-authored-by: Cursor <cursoragent@cursor.com>
Regenerate pnpm-lock.yaml so it matches the e2e workspace as it has
been since e6456d3 (fix: duplicate node and ts dependencies for e2e
tests), which removed @types/node and typescript from
e2e/package.json without re-running pnpm install. The remaining diff
is peer-graph re-hoisting: @playwright/test now appears as a peer
qualifier on the resolved next 15.5.15 / 16.2.4 entries (next-app
examples consume both), and eventemitter3 floats from 5.0.1 to 5.0.4
within its declared range.

No package.json changes — purely the lockfile catching up so future
installs are reproducible.

Co-authored-by: Cursor <cursoragent@cursor.com>
… tests

Raise expect.timeout to 15s in playwright.examples.config.ts so widget
root assertions don't time out on slow CI runners.

Add webServer to playwright.config.ts so the playground dev server starts
automatically when running playground tests locally.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
--reporter=list on the CLI replaced all config reporters, preventing
the HTML report from being written. Dropping the flag lets the config's
html/json/list reporters all run. Also upgrades upload-artifact from
v4 (Node.js 20, deprecated) to v7 (Node.js 24).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
vinzenzLIFI and others added 2 commits May 11, 2026 09:10
Previously the comment was only posted on failure, leaving stale failure
info visible after a fix. Now the report job always runs (when examples
were tested) and updates the comment to either a pass or failure summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vinzenzLIFI vinzenzLIFI force-pushed the test/emb-331-create-playwright-test-suite branch from eee1eef to 2a91292 Compare May 11, 2026 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants