test: rewrite to e2e#2370
Draft
bjohansebas wants to merge 24 commits into
Draft
Conversation
|
bjohansebas
force-pushed
the
hot-e2e-tests
branch
from
July 25, 2026 03:17
b9ec067 to
f8bb9c6
Compare
bjohansebas
force-pushed
the
hot-middleware
branch
from
July 25, 2026 22:09
b74c265 to
11f24ab
Compare
bjohansebas
force-pushed
the
hot-e2e-tests
branch
from
July 25, 2026 22:52
f8bb9c6 to
d029233
Compare
… the console The hot client, overlay, and building indicator are now exercised end to end in headless Chrome (puppeteer 22, the last CJS release jest can require) against a real webpack watcher: updates applied without reload, the full-reload fallback, reconnect with catch-up sync after a server restart, disconnect() semantics, overlay lifecycle (Escape on the host page, HTML-in-error-message escaping, warnings, pagination), the building badge, multi-compiler ?name= filtering with per-bundle overlay slots, and the custom publish/subscribe API. Console behavior is snapshotted from the real browser console: the full info-level update cycle, logging=none/warn/error gates, and the per-bundle dedup where a sibling's clean rebuild does not re-log another bundle's unchanged warning while its own rebuild does. Each multi-compiler compilation gets its own context dir so editing one entry cannot invalidate the sibling's watcher and shuffle event order. The jsdom suites stay, slimmed to what a browser cannot exercise deterministically: process-update internals, shared state between bundled copies, option parsing, and protocol edges. The review of the new tests also surfaced a real client bug, now fixed: an EventSource error event queued behind disconnect() re-armed the reconnect timer on the orphaned wrapper — close() is now final. e2e runs serially through the new test:e2e script (four concurrent Chrome instances plus watchers starved the rest of the suite), and CI shards every test job 4x with jest --shard, uploading per-shard coverage that a final job aggregates for codecov, mirroring webpack-dev-server's setup. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d unit tests A logging=log e2e run now snapshots the collapsed "Updated modules:" group and its per-module entries straight from the browser console (puppeteer surfaces group frames as console events). The jsdom equivalents — the process-update logging describe and the building-message log test, whose output already appears verbatim in the info-level e2e snapshot — are removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eir console The inactivity watchdog is now exercised against a genuinely silent SSE connection (a server heartbeat far beyond the client timeout): the second connect proves it fires on pure silence and the third that it re-arms after a reconnect. Manual recovery gets its own test — disconnect() followed by setOptionsAndConnect() opens a fresh connection that still delivers updates. Both, plus the server-restart catch-up test, snapshot their console sequence; browser network-error noise is filtered out of the snapshots since its volume depends on reconnect timing. The fake-timer equivalents in the jsdom suite are removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d copies The multi-compiler helper already produces what the jsdom suite could only simulate: two genuinely separate bundled copies of the indicator module on one page. Each bundle now exposes its copy as a global and the tests drive both from the browser — a second copy adopts the same badge instead of stacking one, per-source counting spans copies, hiding an unknown source is ignored, and a leaner state shape left by an older package version gets its missing fields filled (planted via evaluateOnNewDocument before the bundles load). The jsdom indicator suite is removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e jsdom suite The subscribe/subscribeAll contract, the ?name= filter, per-source badge counting, the shared SSE connection between bundled clients (asserted explicitly in the multi-compiler console snapshot: one "connected" for two clients), the dev-server-shaped overlay option, and the warnings filter function — parsed from the entry query and applied against two real warning-producing modules — now all run in Chrome. The warnings overlay test also covers clearing on a recovered build, and the pagination test snapshots the two-error console output that the deleted jsdom snapshot used to document. client.test.js keeps only what the browser cannot pin deterministically: problem-type transitions, the multi-bundle problem union, option forwarding to the overlay factory, dynamicPublicPath URL building, and protocol edges. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Breaking both bundles shows the union of their problems in the shared overlay — paginated one per page, in whichever order the compilers finished. The two jsdom equivalents are removed: the union test, and no-apply-on-errored-builds, which the multi-compiler console snapshot already documents (no "Checking for updates" follows a bundle's error report). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
webpack's invalid hook sometimes reports the watched directory instead of the changed file under the polling watcher, so the "bundle rebuilding (…)" line alternated between the file and the fixture dir and flaked the snapshots. The normalizer now collapses both forms to "(<fixture> changed)". Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The bundles' real hot clients call indicator.hide("a")/hide("b") when
their connect-time syncs arrive — the same source names these tests
register — so a late sync could wipe a source mid-test. progress=false
keeps the client away from the indicator entirely.
bjohansebas
force-pushed
the
hot-e2e-tests
branch
from
July 25, 2026 22:53
d029233 to
0a5c6e5
Compare
test/fixtures/js3 was compiled output (a misdirected copy of the dev-server-false test's dist, whose real destination under test/outputs is gitignored) swept up by a bulk git add. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
--testPathIgnorePatterns is variadic, so a positional file after `npm run test:only --` was consumed as another ignore pattern — silently excluding the very file being targeted (the = form appends all the same). The exclusion now lives in jest.config.js and lifts itself when a test/e2e path is requested explicitly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…copies Same pattern as the indicator: each compilation exposes its own bundled copy of the overlay module and the tests drive both from the browser — a second copy adopts the shared iframe instead of stacking one, both sources paginate together in the union, either copy can dismiss what the other rendered, errors from one copy outrank another's warnings until the erroring source recovers, clearing an unreported source does not rebuild the card another copy is showing, and a leaner state shape left by an older package version gets its missing fields filled. The jsdom equivalents are removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Backdrop click, close (×) button, and click-inside-stays-open now run against real mouse events in the overlay iframe — the backdrop case clicks the frame's top-left corner away from the centered card, and the close-button pass rides the catch-up sync that re-shows the overlay after a reload. The jsdom dismiss describe is removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The one-error-one-warning-one-* fixture configs build into test/fixtures/js3 by design, so every logging run recreates it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…pack 5.109 Runtime-error accumulation (two errors paging "1 / 2" ↔ "2 / 2") and unhandled promise rejections now run against real page errors — the rejection fixture rejects from the page's own script so the event carries the real reason. Their jsdom equivalents are removed. The branch also settles on webpack 5.109: the lockfile catches up with the already-bumped range, and the assertions and console snapshots adopt 5.109's parse-error format (numbered code-frame gutter, caret line, and the "File was parsed as module type" note) instead of normalizing it away. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…logger webpack/lib/logging/runtime.js pulls tapable into the client bundle, and tapable compiles its hooks with new Function — an EvalError under a require-trusted-types-for 'script' CSP that killed the client's logging and surfaced spurious runtime errors in the overlay. The replacement is a level-gated console logger with byte-identical output (same prefix merging, same level gates, groups from the "log" level up), verified against the existing console snapshots. It also drops tapable and webpack's logging machinery from the bundle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The page is served with require-trusted-types-for 'script' and a trusted-types allowlist holding only the configured policy name — under real Chrome enforcement, which jsdom cannot do, the overlay only renders if every HTML write went through that policy (including inside the about:blank iframe, which inherits the page's CSP). The jsdom trusted-types test is removed; the helper gained a pageHeaders option. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…time Under a require-trusted-types-for 'script' CSP, tapable — bundled through webpack's logging runtime — cannot compile its hooks: the first log call throws an EvalError from new Function, killing whatever listener happened to log (and with it the update flow). The logger methods are now guarded, so webpack's logging runtime stays the engine and enforcement just turns logging off. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…blish Two browser pages connected to the same server both apply a single edit — broadcast proven end to end. The unit variant also stops passing vacuously: it now publishes while both SSE clients are attached instead of only observing the per-client connect-time sync. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
waitForFunction's default requestAnimationFrame polling never fires on a hidden document, so the backgrounded first tab of the broadcast test hung on a wait for text it had already rendered. Also settle the connections before editing so both pages receive the broadcast rather than a catch-up sync. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… browser invalidate() with unchanged sources rebuilds and reaches the page as a building event followed by a no-op sync — the client neither re-renders nor reloads (a built here would 404 on the never-emitted manifest). close() ends the SSE stream under a connected page: the client falls into its reconnect loop against an endpoint that no longer speaks SSE and the page keeps running untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ntime filter Arrow keys page through problems with real keyboard events (the frame holds focus after the pager click), paginate=false shows the full problem list with no counter, and a runtime filter configured by a later bundled copy is honored by the window listeners the first copy attached — proven non-vacuously by first catching an error through copy A, then watching copy B's rejecting filter keep the overlay away. The three jsdom equivalents are removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The accent-bar colors are asserted (both hues, including the error-to-warning flip) by the shared-state e2e, and the default pagination counter by the pagination e2e. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…om describe The pagination e2e now clamps at the last page under real clicks and key presses, and a shared-state test drives a bundled copy through the page-index semantics: a re-publish of the same problems keeps the page the user navigated to, a different set starts back at page one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Problem replacement is asserted by the page-retention e2e (a new set swaps the rendered content), and the overlay API shape is exercised by every shared-state test driving real bundled copies. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
What kind of change does this PR introduce?
Did you add tests for your changes?
Does this PR introduce a breaking change?
If relevant, what needs to be documented once your changes are merged or what have you already documented?
Use of AI