From 15f4a86d423526a0616b0124908db0eee9a05737 Mon Sep 17 00:00:00 2001 From: Pinky <5f5ab050ec58ae208332edd544ebf705221e24c1b86d82a6ca07038a7a8f6ac9@buzz.block.builderlab.xyz> Date: Tue, 29 Sep 2026 18:51:08 -0600 Subject: [PATCH 1/2] test(browser): count live retries from the post-update presence route The healthy-route journey took its global-request baseline while a startup presence renewal could still be pending. The first roster's access update renews the activity observer at once, but presence re-observes only after its read gate, about five seconds later. When presence had already observed before that update, the renewal landed inside the Retry window and was counted as a replaced route (WebKit, run 36648483268, live.spec.mjs:105). Wait until the newest presence route follows the newest observer route and has reached EOSE before recording the baseline. The exact global-request assertion is unchanged. Signed-off-by: Pinky <5f5ab050ec58ae208332edd544ebf705221e24c1b86d82a6ca07038a7a8f6ac9@buzz.block.builderlab.xyz> --- tests/browser/live.spec.mjs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/browser/live.spec.mjs b/tests/browser/live.spec.mjs index db0c9cf6c..1792b264a 100644 --- a/tests/browser/live.spec.mjs +++ b/tests/browser/live.spec.mjs @@ -52,6 +52,24 @@ test("production WS → broker → mounted UI delivers messages and retries a pa await page .getByRole("textbox", { name: "Message #Alpha", exact: true }) .fill("Keep my draft"); + // An access update renews the activity observer at once, but presence + // re-observes only after its read gate. Count from that post-update route. + const newest = (kind) => + app.relay.requests.findLastIndex(({ filters }) => + filters.some((filter) => filter.kinds.includes(kind)), + ); + await expect + .poll(() => { + const presence = newest(20001); + return ( + presence > newest(24200) && + app.report.wireFrames.some( + (frame) => + frame[0] === "EOSE" && frame[1] === app.relay.requests[presence].id, + ) + ); + }) + .toBe(true); const socketCount = app.relay.sockets.length; const globalRequests = app.relay.requests.filter(({ filters }) => filters.every((filter) => !filter["#h"]), From d2aed7216a42bc2279bd389ec6f592e1712e158b Mon Sep 17 00:00:00 2001 From: Pinky <5f5ab050ec58ae208332edd544ebf705221e24c1b86d82a6ca07038a7a8f6ac9@buzz.block.builderlab.xyz> Date: Tue, 29 Sep 2026 20:47:32 -0600 Subject: [PATCH 2/2] test(browser): count live retries once the page handles startup controls The previous barrier compared the newest recorded presence and observer REQs. Retired REQs stay in that history, and the post-roster observer generation can wait in the browser behind a startup /stream-observer control, so the startup pair could satisfy it before either renewal reached the wire. Count /stream-observer and /stream-presence-authors fetches in the page. Each settles, and any control it was holding is sent, in one microtask checkpoint, so a page read of zero means every control has been applied by the broker and none is queued. Record the baseline only then, with live observer and presence routes that reached EOSE on the open primary socket. The exact global-request assertion is unchanged. Signed-off-by: Pinky <5f5ab050ec58ae208332edd544ebf705221e24c1b86d82a6ca07038a7a8f6ac9@buzz.block.builderlab.xyz> --- tests/browser/live.spec.mjs | 53 ++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/tests/browser/live.spec.mjs b/tests/browser/live.spec.mjs index 1792b264a..03da9d654 100644 --- a/tests/browser/live.spec.mjs +++ b/tests/browser/live.spec.mjs @@ -43,6 +43,23 @@ test("production WS → broker → mounted UI delivers messages and retries a pa page, app, }) => { + // The first roster renews the activity observer and retires presence, which + // re-subscribes after its read gate. Either control may wait behind one in + // flight until that fetch's own continuation sends it, so count controls in + // the page: settlement and any resend fall in one microtask checkpoint. + await page.addInitScript(() => { + const native = window.fetch; + window.liveControls = 0; + window.fetch = (input, init) => { + const result = native(input, init); + if (/\/stream-(observer|presence-authors)$/.test(String(input))) { + const settled = () => window.liveControls--; + window.liveControls++; + result.then(settled, settled); + } + return result; + }; + }); await ready(page, app); const live = app.append("primary", "alpha", "Policy-realistic live delivery"); await expect( @@ -52,23 +69,29 @@ test("production WS → broker → mounted UI delivers messages and retries a pa await page .getByRole("textbox", { name: "Message #Alpha", exact: true }) .fill("Keep my draft"); - // An access update renews the activity observer at once, but presence - // re-observes only after its read gate. Count from that post-update route. - const newest = (kind) => - app.relay.requests.findLastIndex(({ filters }) => - filters.some((filter) => filter.kinds.includes(kind)), + const established = (kind) => + app.relay.sockets.some( + ({ community, readyState, routes }) => + community === "primary" && + readyState === 1 && + [...routes].some( + ([id, filters]) => + filters.some((filter) => filter.kinds.includes(kind)) && + app.report.wireFrames.some( + (frame) => frame[0] === "EOSE" && frame[1] === id, + ), + ), ); + // The broker applies each control before it responds. Once the page has + // handled every response, live observer and presence routes that reached + // EOSE belong to the latest generations. await expect - .poll(() => { - const presence = newest(20001); - return ( - presence > newest(24200) && - app.report.wireFrames.some( - (frame) => - frame[0] === "EOSE" && frame[1] === app.relay.requests[presence].id, - ) - ); - }) + .poll( + async () => + !(await page.evaluate(() => window.liveControls)) && + established(24200) && + established(20001), + ) .toBe(true); const socketCount = app.relay.sockets.length; const globalRequests = app.relay.requests.filter(({ filters }) =>