You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The e2e test frame: a lazy <webjs-frame src> self-loads on viewport entry, sending x-webjs-frame (test/e2e/e2e.test.mjs:2600) is intermittently red. It failed once on PR #810 on a docs-only commit that cannot touch the blog runtime, then passed on re-run with no code change. The framework behaviour is CORRECT here (all functional assertions pass); the flake is in the TEST'S response-body capture.
The failing assertion is line 2654: assert.ok(frameResponses.length >= 1, 'captured the deferred self-load response'). Every assertion before it passes, so the lazy self-load fired, the x-webjs-frame: deferred request was sent, and the content swapped in. Only the response-BODY capture failed.
Root cause: the response handler reads the body asynchronously and swallows failures:
loadFrame (packages/core/src/router-client.js) does fetch() then reads the body to apply the subtree, so the browser can free the response body before the handler's await resp.text() resolves. Puppeteer then throws ("Could not load body for this request"), the silent catch eats it, frameResponses stays empty, and line 2654 fails. The swallowing catch is what turns a transient capture race into an intermittent CI red instead of a loud, obvious failure.
Design / approach
Make the response-body capture robust and non-silent:
Prefer capturing the body EAGERLY at response time in a way that does not race the browser freeing it (e.g. buffer it immediately, or intercept via the request-scoped capture the harness already uses elsewhere), rather than an await resp.text() that can lose the body.
Remove the swallowing catch (or narrow it and record the failure) so a genuine capture failure is a clear assertion, not an empty array.
Alternatively, assert the subtree-render optimization (Add src-driven frame self-loading and server-scoped frame render #253: the response is the <webjs-frame id="deferred"> subtree, not a full document) via a mechanism that does not depend on re-reading a consumed fetch body, since the functional DOM assertions already prove the self-load worked.
Keep the functional assertions (request sent, content swapped, subtree-only) intact; only the body-capture path is fragile.
Implementation notes (for the implementing agent)
Where: test/e2e/e2e.test.mjs, the test at L2600 (the onResp handler L2612-2616 and the L2654 assertion). Look at how other frame/stream tests in the same file capture bodies for a non-racy pattern to reuse.
Landmine: the framework is NOT at fault. loadFrame reading the fetch body is correct; do not "fix" the runtime. This is purely a test-harness reliability fix.
Landmine: a swallowing catch { /* ignore */ } around an async body read is the anti-pattern; any replacement must make a real capture failure LOUD (so the test never again goes red without a diagnosable reason).
Problem
The e2e test
frame: a lazy <webjs-frame src> self-loads on viewport entry, sending x-webjs-frame(test/e2e/e2e.test.mjs:2600) is intermittently red. It failed once on PR #810 on a docs-only commit that cannot touch the blog runtime, then passed on re-run with no code change. The framework behaviour is CORRECT here (all functional assertions pass); the flake is in the TEST'S response-body capture.The failing assertion is line 2654:
assert.ok(frameResponses.length >= 1, 'captured the deferred self-load response'). Every assertion before it passes, so the lazy self-load fired, thex-webjs-frame: deferredrequest was sent, and the content swapped in. Only the response-BODY capture failed.Root cause: the
responsehandler reads the body asynchronously and swallows failures:loadFrame(packages/core/src/router-client.js) doesfetch()then reads the body to apply the subtree, so the browser can free the response body before the handler'sawait resp.text()resolves. Puppeteer then throws ("Could not load body for this request"), the silentcatcheats it,frameResponsesstays empty, and line 2654 fails. The swallowing catch is what turns a transient capture race into an intermittent CI red instead of a loud, obvious failure.Design / approach
Make the response-body capture robust and non-silent:
await resp.text()that can lose the body.catch(or narrow it and record the failure) so a genuine capture failure is a clear assertion, not an empty array.<webjs-frame id="deferred">subtree, not a full document) via a mechanism that does not depend on re-reading a consumedfetchbody, since the functional DOM assertions already prove the self-load worked.Keep the functional assertions (request sent, content swapped, subtree-only) intact; only the body-capture path is fragile.
Implementation notes (for the implementing agent)
test/e2e/e2e.test.mjs, the test at L2600 (theonResphandler L2612-2616 and the L2654 assertion). Look at how other frame/stream tests in the same file capture bodies for a non-racy pattern to reuse.loadFramereading the fetch body is correct; do not "fix" the runtime. This is purely a test-harness reliability fix.catch { /* ignore */ }around an async body read is the anti-pattern; any replacement must make a real capture failure LOUD (so the test never again goes red without a diagnosable reason).x-webjs-frame: deferredrequest + content swap).Acceptance criteria
await resp.text()that can lose the body).catchis removed or narrowed so a real capture failure fails loudly with a diagnosable message.<webjs-frame id="deferred">body, no full-document shell) are preserved.