test(perf): end J2's HTTP window at the accepted quiet sample

The post-terminal window read the ledger after waitForMockQuiet returned,
so a request arriving in between was counted although its completion was
never waited for. waitForMockQuiet now returns the ledger position its
accepted sample read; later requests are kept as evidence
(httpRequestsAfterSettledByRoute) instead of the counter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5.5 committed 2026-09-29 08:58:37 +02:00
1 parent b43ecc2870
commit b0bbd73bb1
4 files changed
+38 -12

No files matched your search

@@ -133,8 +133,8 @@ async function waitForQuiet(
*/
async function waitForMockQuiet(
ledger: JourneyMockRequestLedger
): Promise<void> {
await waitForJourneyQuiet({
): Promise<number> {
const { sample: quiet } = await waitForJourneyQuiet({
inFlight: (activity) => activity.inFlight,
pollMs: POLL_MS,
quietMs: QUIET_MS,
@@ -145,6 +145,11 @@ async function waitForMockQuiet(
timeoutError: () => new Error('open-source-journey-mock-not-quiet'),
timeoutMs: SETTLE_TIMEOUT_MS,
});
// The window ends at the ledger position this accepted sample read. A
// request that arrives after it was never seen in flight, so its
// response and follow-ups are not waited for; counting it would make
// the counter depend on when the ledger is read.
return quiet.requests;
}
/**
@@ -202,7 +207,7 @@ export async function measureOpenSourceJourney(
OPEN_SOURCE_JOURNEY_MAIN_IPC_STATE_KEY,
10_000
);
await waitForMockQuiet(ledger);
const settledAfterLedgerMark = await waitForMockQuiet(ledger);
// The journey starts at the renderer's click stamp, not when Playwright
// began its actionability checks, so a request that arrives in between
// stays before the click like it does for every other J2 counter. The
@@ -216,14 +221,20 @@ export async function measureOpenSourceJourney(
const beforeClick = sinceSpawn.filter(
(entry) => entry.epochMs < clickEpochMs
);
const afterClick = sinceSpawn.filter(
(entry) => entry.epochMs >= clickEpochMs
);
return {
http: {
afterSettleBeforeClick: beforeClick.filter(
(entry) => entry.sequence >= settledLedgerMark
).length,
afterSettled: afterClick.filter(
(entry) => entry.sequence >= settledAfterLedgerMark
),
beforeClick,
requests: sinceSpawn.filter(
(entry) => entry.epochMs >= clickEpochMs
requests: afterClick.filter(
(entry) => entry.sequence < settledAfterLedgerMark
),
},
ipc,
@@ -83,6 +83,9 @@ function measurement(
return {
http: {
afterSettleBeforeClick: 0,
afterSettled: [
request(3, '/player_api.php?action=get_vod_streams', 12_500),
],
beforeClick: [
request(0, '/player_api.php?action=get_account_info', 2_000),
],
@@ -129,6 +132,10 @@ test('maps the click-started probe, IPC window and mock ledger to exact counters
'/assets/marketing/poster/a': 1,
'/player_api.php?action=get_account_info': 1,
});
// Arrived after the post-terminal quiet sample: evidence, not counted.
assert.deepEqual(record.evidence['httpRequestsAfterSettledByRoute'], {
'/player_api.php?action=get_vod_streams': 1,
});
assert.deepEqual(record.evidence['httpRequestsBeforeClickByRoute'], {
'/player_api.php?action=get_account_info': 1,
});
@@ -50,6 +50,11 @@ export interface OpenSourceJourneyMeasurement {
readonly http: {
/** Mock requests after the app settled but before the click stamp. */
readonly afterSettleBeforeClick: number;
/**
* Requests after the post-terminal quiet sample; outside the window
* because their completion was not waited for.
*/
readonly afterSettled: readonly JourneyMockRequest[];
/** Mock requests from the spawn (J1 and settling) until the click. */
readonly beforeClick: readonly JourneyMockRequest[];
/** Mock requests from the click until the mock was quiet again. */
@@ -171,6 +176,9 @@ export function toOpenSourceIterationRecord(
httpRequestsBeforeClickByRoute: countJourneyMockRoutes(
http.beforeClick
),
httpRequestsAfterSettledByRoute: countJourneyMockRoutes(
http.afterSettled
),
httpRequestsByRoute: countJourneyMockRoutes(http.requests),
httpRequestsToFirstPage: requestsToFirstPage,
ipcCallsAfterFirstPage: ipc.callsAfterSentinel,