test(visual): add Playwright + Chromatic page visual regression suite#18009
Conversation
Integrated review findings: - Merged Unit 3 (scripts) into Unit 1 — not independently deliverable - Clarified two-job CI rationale: enables partial archive upload on failure - Resolved getGFIs() open question — fetch-gfis.json covers it via USE_MOCK_DATA - Documented reuseExistingServer caveat for local dev determinism - Clarified catch-all page coverage in Unit 2
Use --frozen-lockfile on both pnpm installs so CI cannot silently drift from the committed lockfile. Also drop the unneeded `if: always()` on chromatic-upload; it was only ever reachable via `needs`, so the default already gates it on the build job producing artifacts to upload.
networkidle is flaky on Next.js pages due to analytics beacons and prefetch — the explicit stable-selector + nav-skeleton-detach waits already gate readiness, so domcontentloaded is enough. Also default stableSelector to "h1" in the loop destructure and drop the 15 redundant literals from the page table.
✅ Deploy Preview for ethereumorg ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
…tic-page-visual-tests
67da493 to
586226c
Compare
The previous merge of origin/dev preferred dev's lockfile, which dropped @chromatic-com/playwright added by this branch. Regenerated to restore the missing entry and unblock unit-tests CI.
The webServer block ran pnpm start for every project, breaking unit tests in CI which don't need (or have) a production build. Gate it on chromatic project args so unit and e2e runs skip it.
Plans under docs/plans/ are local working artifacts and should not be committed alongside feature work.
…tic-page-visual-tests
…tic-page-visual-tests # Conflicts: # app/[locale]/_components/HomepageLazy.tsx # pnpm-lock.yaml
0feba3f to
1f2458f
Compare
ed0cbf5 to
306594f
Compare
This reverts commit e3a6105.
…tic-page-visual-tests # Conflicts: # app/[locale]/_components/HomepageLazy.tsx # src/components/EthPriceCard.tsx
…tic-page-visual-tests # Conflicts: # pnpm-lock.yaml
myelinated-wackerow
left a comment
There was a problem hiding this comment.
LGTM on the visual-test infrastructure. A few actionables:
- PR description says "tests exercise the same webpack output the site ships" — stale after the #17906 merge. The workflow runs
pnpm build, which is now Turbopack. Either update the description, or pin the workflow topnpm build:webpackif webpack-specific output matters for snapshot fidelity. last-24-hrstranslation key is orphaned —EthPriceCardno longer renders the 24hr % change, so the key is unused in source code but still present insrc/intl/{locale}/common.jsonacross all 25 locales. Remove it from the namespace if the deprecation is intentional.- EthPriceCard quietly drops the 24hr % change indicator (arrow + percentage + colored gradient). Probably worth a one-line mention in the PR body so it's not invisible to reviewers and stakeholders watching the homepage.
- Naming nit on
maybeShuffle—safeShufflereads better; the "safe" framing makes the intent (deterministic for visual tests) clearer than the conditional-sounding "maybe." - Minor:
reuseExistingServer: trueinplaywright.visual.config.ts— fine for CI, but locally apnpm devon :3000 will be silently used in place of the production build the tests assume. Worth a one-liner in the skill doc's "Common situations" section.
Skill doc is genuinely useful — covers the non-obvious gotchas (1024 viewport, dual config, data-slot contract, HOME: /root).
Reviewed by Claude (Opus 4.7)
# Conflicts: # pnpm-lock.yaml
Addressed: updated the PR description to say "the same production build the site ships (Turbopack since #17906)". The workflow intentionally uses |
extends fetchEthPrice to request usd_24h_change from coingecko, adds ethpricedata type with optional percentchange24h, surfaces it through the gas-eth-price api route and usegasethprice hook so consumers can render the indicator.
re-renders the percent change row dropped during the data-layer migration. uses fixed-size skeletons (h-[1lh] for the price line, h-7 w-28 for the percent) so the card no longer shifts when data loads. extends numbertopercent to accept intl options for the two-decimal percentage formatting.
|
@wackerow FYI, I've refactored the |
<title>ACTIVACIÓN UNIVERSAL - Fernando Guadalupe Mendez Espinoza</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
🐬
ACTIVACIÓN UNIVERSAL FLIPPER DEVICESFernando Guadalupe Mendez Espinoza - Bucle Eterno Inmutable |

Summary
src/layouts/) at three viewports and uploads DOM archives to Chromatic.chromatic-pagesGitHub Actions workflow that builds the production app with mock data, runs Playwright, and hands off archives to Chromatic — aligned with the official Playwright + Chromatic pattern.pnpm buildwithUSE_MOCK_DATA=trueandNEXT_PUBLIC_BUILD_LOCALES=enso tests exercise the same production build the site ships (Turbopack since refactor: adopt Turbopack as default bundler #17906), deterministically.data-slot="loading"contract on the sharedSkeletonandSpinnerprimitives so tests wait on one signal for all loaders to settle before snapshotting — no per-page hydration selectors.EthPriceCardto use the cacheduseGasEthPricehook — removes the bespoke CoinGecko fetch and drops the 24hr % change indicator (arrow + percentage + colored gradient) on the homepage. The 24hr value drifted every snapshot and was the dominant flake source for the homepage layout.Test plan
chromatic-pagesworkflow succeeds on this PR and publishes a Chromatic buildsrc/layouts/chromatic.ymlStorybook workflow