test(e2e): add Playwright E2E suite for 17 widget examples#684
Conversation
afedcc4 to
294e07c
Compare
294e07c to
e6456d3
Compare
E2E Examples — failuresThe following example(s) failed:
See the workflow run for Playwright reports and logs. |
E2E Examples — failuresThe following example(s) failed:
See the workflow run for Playwright reports and logs. |
| await page.goto('/') | ||
| }) | ||
|
|
||
| test('widget root is visible', async ({ page }) => { |
There was a problem hiding this comment.
can all of these tests be moved into test.steps() ?
There was a problem hiding this comment.
I checked that. we would save execution time, you're right. But I think it is worth to have a separate test for each of the "steps". I will consider grouping into steps, if the anount of tests grows on and we are able to group them into steps semantically.
| */ | ||
| export async function waitForTokens(page: Page): Promise<void> { | ||
| await page.waitForResponse( | ||
| (res) => res.url().includes('/v1/tokens') && res.status() === 200 |
There was a problem hiding this comment.
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 } )
eee1eef to
2a91292
Compare
… is used for comparison
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>
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>
2a91292 to
e4591c9
Compare
|
Some tests will fail until #733 is merged |
| # Example directory mapping (name → examples/<dir>) | ||
| declare -A EXAMPLE_DIR | ||
| EXAMPLE_DIR=( | ||
| [vite]="vite" |
There was a problem hiding this comment.
@vinzenzLIFI I was wondering, is there a way to have the list of all examples in one place?
as I could understand, now if we add one more/remove example, we would need to update multiple lists?
There was a problem hiding this comment.
great idea. consolidated the list of all examples in a single JSON which is parsed in the workflow from now on.
…truth Add e2e/examples.json as the sole place to add, remove, or update example metadata. Previously, every change required edits in 5 locations (TS config, workflow bash arrays, two scripts, and docs). Now all consumers — Playwright config, CI workflow, and local scripts — read directly from the JSON. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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 andwaitForTokens()tests/profiles/— specs per profile (standard/routed, iframe, nft)tests/playground/— smoke tests for the widget playground4 example profiles, each with its own spec:
standardrouted/widgetfirstiframenftLocal test scripts — full build → serve → test → kill cycle:
CI workflow (
e2e-examples.yml) — triggers on every PR tomain:detect-changesjob computes which examples to test: isolatedexamples/<name>/change → that example only; shared package / lockfile /e2e/change → all 17fail-fast: false)marocchino/sticky-pull-request-comment)Rolldown rc.17 fix —
vite@8.0.10introduced a Rolldown regression that causes a circular chunk dependency at runtime (Class extends value undefined) in any example using@wagmi/connectors. Addedbuild.rolldownOptions.output.strictExecutionOrder: trueto 8 affected examples. Same fix already applied towidget-embedded/widget-playground-vitein #721. Will be removed once the upstream fix lands in Rolldown.Known broken examples (not tested)
dynamicvite-plugin-env-compatibledoesn't shimprocessglobally — Dynamic SDK crashes at runtimenuxtR is not a function)deposit-flowFlip
status: 'broken' → 'active'ine2e/examples.config.tsto include them once fixed.Selector strategy
Tests use ARIA roles and visible text rather than
data-testidattributes — the widget is a library anddata-testidwould 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 ReactuseId()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
Linear