Skip to content

Harden landing e2e gate and migrate to vinext - #631

Merged
owjs3901 merged 5 commits into
mainfrom
owjs3901/landing-vinext-migration
Aug 23, 2026
Merged

Harden landing e2e gate and migrate to vinext#631
owjs3901 merged 5 commits into
mainfrom
owjs3901/landing-vinext-migration

Conversation

@owjs3901

@owjs3901 owjs3901 commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Summary

This lands the migration in the required two phases:

  1. Harden the landing Playwright suite into a deterministic acceptance gate (d0e1ad87).
  2. Migrate apps/landing from Next.js to vinext while keeping the Phase-1 assertions and snapshot pixels unchanged in the migration commit (e51124fd).

A follow-up removes the standalone export copier/postprocessor and makes CI/CD consume vinext's native client output directly (293f017b). The app exports every existing URL to apps/landing/dist/client, keeps MDX and dynamic component routes, and preserves the DEVUP_SINGLE_CSS=1 build path through @devup-ui/vite-plugin.

After merging the latest main, the gate also covers the new custom-shorthands documentation route and uses explicit Linux/Windows screenshot baselines while retaining the 1% threshold (90f7a5d1).

Phase 1: trustworthy gate

Coverage grew from 13 specs / 108 tests to 15 specs / 128 tests. The gate now:

  • derives and asserts the complete 63-route static-export manifest, including route groups, 27 generated component pages, and MDX docs;
  • exercises every route in light/dark themes at desktop/mobile widths;
  • validates metadata, canonical/OG/favicon references, local HTML/CSS assets, and real 404 responses;
  • fails on console errors, HTTP failures, or missing assets;
  • covers landmarks and heading order, first-paint theme/no-FOUC behavior, client navigation, Lenis scrolling, anchor navigation, header scroll state, and mobile body scroll locking;
  • strengthens the zero-runtime contract around static CSS delivery, short compiled class names, stable style-tag counts, and absence of runtime/inline style injection;
  • tightens screenshot tolerance from 15% to 1% and separates Linux/Windows baselines so OS font rasterization cannot make CI flaky.

The two documented flakes were fixed at their causes: tests now wait for required font weights, decoded images, stable document height, and finite animations; GitHub data is deterministic; image layout space is reserved; and hover polling re-aims the pointer while asserting the element is actually :hover.

Repeated pre-migration evidence:

  • default build: 128/128 passed three consecutive times;
  • single-CSS build: 128/128 passed.

Latest direct-output acceptance after merging current main:

  • default vinext build: 128/128 passed, zero retries (2.1m);
  • single-CSS vinext build: 128/128 passed, zero retries (2.2m).

Phase 2: vinext port

  • replaces the Next build/plugin/MDX toolchain with vinext beta 8, Vite 8, @mdx-js/rollup, RSC packages, and @devup-ui/vite-plugin;
  • makes dist/client deployment-ready at generation time: the Vite config removes dead Devup CSS proxy dependencies from the RSC manifest, while the root layout installs the static-host .rsc transport;
  • points the local server, route manifest checks, normal/single-CSS acceptance runs, and GitHub Pages upload directly at apps/landing/dist/client;
  • removes export-static.mjs, the out copy, HTML mutation, and the redundant _not-found.html alias; GitHub Pages uses vinext's native 404.html;
  • excludes the separately copied Storybook HTML from the landing route manifest while keeping Storybook in the deployed artifact;
  • keeps route-driven search/menu state hydration-safe without vinext's static useSearchParams bailout;
  • converts demo discovery to import.meta.glob and narrows syntax-highlighter imports;
  • disables automatic full-RSC route prefetch for this static artifact shape so the landing page does not eagerly decode every visible route;
  • passes vinext check at 100% compatibility and TypeScript from a clean generated-output state.

Measurements

Measured on the same Windows machine from clean generated output. Browser transfer values are raw local response bodies after networkidle, with GitHub/GTM made deterministic in both runs. Artifact table rows exclude the separately built Storybook directory because it is the same CI input in both pipelines.

Metric Next.js baseline vinext Delta
Clean build time 32.232s 20.100s -37.6%
Total export bytes 33,171,227 40,741,459 +22.8%
Export JS bytes 782,664 650,438 -16.9%
Export CSS bytes 51,493 60,523 +17.5%
Export file count 504 368 -27.0%
Landing browser JS 638,146 517,519 -18.9%
Landing browser CSS 32,025 29,230 -8.7%
Landing requests 77 91 +18.2%

The main tradeoff is explicit: vinext's static export stores full RSC artifacts alongside HTML, so total export size rises even though build time, shipped JS, shipped CSS, and file count improve. The native single-CSS landing output is 23,913,771 bytes across 266 files (644,530 JS bytes and 35,603 CSS bytes). With the CI-built Storybook included, the deployable single-CSS artifact is 32,040,909 bytes across 409 files.

Verification

  • bun run lint
  • bunx tsc --noEmit -p apps/landing/tsconfig.json
  • bunx vinext check (100%)
  • default direct-output E2E: 128 passed
  • DEVUP_SINGLE_CSS=1 direct-output E2E: 128 passed
  • deployment structure: 64 landing HTML files with static RSC transport, zero dead Devup CSS proxy references, native 404.html, and Storybook present
  • required pre-commit hook: Rust tests/coverage plus 5,128 Bun tests (all passed; JS/TS coverage 100%)

@owjs3901
owjs3901 force-pushed the owjs3901/landing-vinext-migration branch from 921fcb0 to 90f7a5d Compare August 23, 2026 15:34
@github-actions

Copy link
Copy Markdown
Contributor

Changepacks

@devup-ui/wasm@1.0.75 → 1.0.76 - bindings/devup-ui-wasm/package.json

Patch

  • Add plugin-configured custom shorthands with generated TypeScript completion

@devup-ui/bun-plugin@1.0.12 → 1.0.13 - packages/bun-plugin/package.json

Patch

  • Add plugin-configured custom shorthands with generated TypeScript completion

@devup-ui/components@0.1.50 → 0.1.51 - packages/components/package.json

Patch

  • Auto-update: depends on '@devup-ui/react' via a local workspace dependency

@devup-ui/next-plugin@1.0.80 → 1.0.81 - packages/next-plugin/package.json

Patch

  • Add plugin-configured custom shorthands with generated TypeScript completion

@devup-ui/plugin-utils@1.0.10 → 1.0.11 - packages/plugin-utils/package.json

Patch

  • Add plugin-configured custom shorthands with generated TypeScript completion

@devup-ui/react@1.0.37 → 1.0.38 - packages/react/package.json

Patch

  • Add plugin-configured custom shorthands with generated TypeScript completion

@devup-ui/reset-css@1.0.24 → 1.0.25 - packages/reset-css/package.json

Patch

  • Auto-update: depends on '@devup-ui/react' via a local workspace dependency

@devup-ui/rsbuild-plugin@1.0.58 → 1.0.59 - packages/rsbuild-plugin/package.json

Patch

  • Add plugin-configured custom shorthands with generated TypeScript completion

@devup-ui/vite-plugin@1.0.64 → 1.0.65 - packages/vite-plugin/package.json

Patch

  • Add plugin-configured custom shorthands with generated TypeScript completion

@devup-ui/webpack-plugin@1.0.63 → 1.0.64 - packages/webpack-plugin/package.json

Patch

  • Add plugin-configured custom shorthands with generated TypeScript completion

@codecov

codecov Bot commented Aug 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@owjs3901
owjs3901 merged commit 7be63c1 into main Aug 23, 2026
3 checks passed
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.

1 participant