fix(e2e): make the runtime-error tests able to fail, drop a save race - #240
Conversation
The lottie and gist frontend tests attach their console/pageerror
listeners to the page `publishAndGetFrontendPage` returns -- after it has
already navigated. Playwright does not buffer those events for listeners
attached later, and `goto` resolves on `load`, which has already waited
for the async plugin scripts to load and execute. So any error thrown
during script evaluation was emitted and dropped before the listener
existed, `relevantErrors` was always empty, and
`expect(relevantErrors).toEqual([])` could not fail.
The lottie one is the regression test for the duplicate
`customElements.define` fix; as written it would not catch a
reintroduction. The helper now takes an `onPageReady` callback and hands
the page over before navigating.
typography's `setFontSetting` slept 1000ms for a save the settings page
debounces by exactly 1000ms and then fires without awaiting -- so the
sleep expired as the request went out, and the `page` fixture closes the
page at teardown, discarding anything still in flight. Losing that race
showed up in a later test as a font mismatch. It now waits on the POST.
gist asserted on `mockStats`, a plain object its route handlers mutate,
with a bare `expect` -- no retry, which is why a flat 1s sleep had to sit
in front of it. `expect.poll` ends as soon as the mock fires.
Also drops two `waitForLoadState('domcontentloaded')` calls that ran after
`goto` had already resolved on `load`, and the build step from the lint
job: `lint:js` is `biome check`, whose shared config excludes `**/build`,
and `lint:css` globs the SCSS sources -- neither reads build output.
Picks up @nk-crew/plugin-toolkit 0.6.0.
Not fixed, flagged instead: `ghostkit_typography` is never reset, so from
the second run on every editor boot enqueues a real fonts.googleapis.com
stylesheet, and test 4 silently depends on tests 1-3 having run. The
obvious reset through update_custom_typography merges rather than
replaces, so it needs a local run to get right.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8dea5e0891
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // is why a flat 1s sleep used to sit above this -- polling ends as soon | ||
| // as the mock has fired instead. | ||
| await expect.poll(() => mockStats.jsonRequests).toBeGreaterThan(0); | ||
| await expect.poll(() => mockStats.cssRequests).toBeGreaterThan(0); |
There was a problem hiding this comment.
Wait for the mocked stylesheet to finish loading
In the editor test, cssRequests is incremented before route.fulfill() completes, so this poll only proves that the stylesheet request started. The bundled gist-simple code inserts the mocked gist and can emit the errors under test from the stylesheet's later load callback; because the fixed delay was removed, runtimeErrors can be filtered before that callback runs, allowing asynchronous regressions to pass. Wait for the rendered mocked gist content (such as .gist-file) or another post-load signal before inspecting the error array.
Useful? React with 👍 / 👎.
Toolkit 0.6.0 plus the fixes that came out of profiling this suite. Two of these are tests that currently cannot fail — those matter more than the seconds.
The runtime-error tests never observe the errors they exist to catch
lottie-block.spec.jsandgist-block.spec.jsboth do:publishAndGetFrontendPagedoesnewPage()→goto(href). Playwright does not bufferconsoleorpageerrorfor listeners attached afterwards, andgotoresolves onload— which has already waited for theasyncplugin scripts to both load and execute (classes/class-assets.php:413-414). So an error thrown during script evaluation was emitted and dropped before the listener existed.relevantErrorswas therefore always[], andexpect(relevantErrors).toEqual([])always passed.The lottie one is the regression test for the duplicate
customElements.define('lottie-player', …)fix. As written it would not catch a reintroduction.The helper now takes an
onPageReadycallback and hands the page over before navigating.Heads up for review: these two assertions have never actually run. If either now goes red, that is a real finding, not a broken test — the whole point of the change is that they can fail again.
The typography save is a race it loses
setFontSettingslept 1000 ms for a save the settings page debounces by exactly 1000 ms (settings/pages/typography.js:28-31) and then fires without awaiting (:254-260). The sleep expired as the POST was going out, and thepagefixture closes the page at teardown, discarding anything in flight.When it lost, the symptom appeared in a different test —
Check fonts available on backend and frontend— as a mismatch againstEXPECTED_GOOGLE_FONTS_FAMILY. Classic intermittent-and-baffling.It now waits on the POST itself. No time saved; the 1000 ms is in the product.
The gist counters were asserted without retry
await expect(mockStats.jsonRequests).toBeGreaterThan(0)—mockStatsis a plain object the route handlers mutate, soawaiton a non-thenable buys nothing and the check ran once. That is precisely why a flat 1 s sleep had to sit in front of it.expect.pollretries and ends as soon as the mock fires.Both sleeps (editor and frontend) are gone. ~1.6 s.
Smaller
waitForLoadState('domcontentloaded')calls that ran aftergotohad resolved onload— strictly later, so no-ops.lintjob.lint:jsisbiome check, and the shared Biome config excludes**/build;lint:cssglobs the SCSS sources. Neither reads anything the build produces. 8–15 s per PR.@nk-crew/plugin-toolkit→0.6.0(toolkit#2): no tracing on tests that pass, andreportSlowTestsrestored so the next run prints its own slowest files.Lockfile touched surgically — four fields for that one package.
npm install --package-lock-onlyre-resolves the whole tree and, on a sibling repo, dropped two optional peers while flipping ~60 entries todev.Sleeps deliberately kept
console-errors.spec.js:100and the two inlottie-block.spec.jsare settle windows for the absence of a future event. There is no signal for "no error is coming", so a sleep is the correct tool.Flagged, not fixed
ghostkit_typographyis never reset. wp-env's database survivesenv:stop, so from the second run onward every editor boot enqueues a realfonts.googleapis.comstylesheet inside theloadgate — which is likely whyconsole-errors.spec.jshas to ignore/fonts\.gstatic\.com/iand/net::ERR_/i. Test 4 also silently depends on tests 1–3 having run, so--grepon it alone fails.I did not fix it: the obvious reset via
update_custom_typographymerges rather than replaces (classes/class-rest.php:1834-1856), so{}lands as[], and getting it right needs a local run.Also flagged:
publishAndGetFrontendPageandtrackRuntimeErrorsare copy-pasted across three spec files, which is why this fix had to be applied twice. Worth atests/e2e/utils/directory like the sibling plugins have.Not included
assets-loading.spec.jsboots the editor and publishes six times to produce content REST could create (est. 15–30 s). Detection is content-driven, so it should be equivalent — but it would stop the markup round-tripping through the editor's parse/serialize, and that wants a local run first.