Files
buzz/desktop/tests/e2e/mock-subscription-readiness.spec.ts
Wes fe56d311a7 test(desktop): stabilize unread and audio release smoke fixtures (#7821)
## Summary
Repair the mock-backed desktop smoke fixtures blocking release PR #7817.
No application unread logic, styling, audio component, scheduler, or
release-tool changes.

- Require an exact channel-scoped kind-9 subscription before injecting
unread messages, including after navigation. The old readiness check
could accept a global-only, wrong-channel, or wrong-kind consumer. The
extracted predicate is used by the real mock bridge and has regression
coverage for those false positives and legacy behavior.
- Seed the 24 audio messages offscreen with distinct timestamps, then
open the channel with all cards in the load margin. Same-second random
event IDs previously reordered the settling timeline, causing different
visible cards to start loads. This was viewport churn, not a component
restart defect.
- Expose the existing real audio scheduler snapshot through the E2E
bridge. Assert 3 active / 21 queued before navigation and 0 active / 0
queued afterward. Preserve the peak-3 cap, exact 3 fetches /
cancellations / releases, zero object URLs, and existing unread/bold
assertions. No sleeps, retries, skipped tests, or relaxed limits were
added.

## Validation
- Before commit, all 30 tests in `channel-activity-popover.spec.ts`,
`channel-mute.spec.ts`, and `voice-note.spec.ts` passed five repetitions
with retries disabled: **150/150**. This was the working repair on base
`312cf674f`, before final formatting/cleanup, not the entire smoke
suite.
- At committed head `1b126afbe75c2a2afbdfe13744f0938fa584764e`, normal
pre-push hooks passed: **6,591/6,591 desktop unit tests**, desktop
checks, TypeScript typechecking, differential file-size gate, and
branch-skew check. Pre-commit Biome formatting passed; working tree is
clean.
- Independent sidebar and audio reviews found no substantive blocker.
Their formatting findings are resolved in this commit.
- Full repository `just ci`, native release packaging, and the entire
Playwright smoke suite were not run locally. GitHub CI is the remaining
broader gate; this PR is not a release certification.

## Release follow-up
After this repair is merged and required checks pass, regenerate #7817
through the desktop release tooling and validate the new candidate's
exact head. This PR does not merge or publish a release.

Originating discussion:
buzz://message?channel=3428ec3f-a58b-429b-afbc-dc6a77918ce8&id=3303565b14334696e9bbf433ef3ad1aea4307acc69834f7f685a412e81354493

Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
2026-09-23 01:07:00 +00:00

94 lines
3.1 KiB
TypeScript

import { expect, test } from "@playwright/test";
import { installMockBridge } from "../helpers/bridge";
test("mock socket REQs preserve exact readiness semantics", async ({
page,
}) => {
// Keep app-owned channel subscriptions out of the readiness result. The
// bridge is installed, but locked boot never mounts the channel consumers.
await installMockBridge(page, { identityLocked: true });
await page.goto("/");
await expect(page.getByTestId("keyring-locked")).toBeVisible();
const observed = await page.evaluate(async () => {
const invoke = window.__BUZZ_E2E_INVOKE_MOCK_COMMAND__;
const ready = window.__BUZZ_E2E_HAS_MOCK_LIVE_SUBSCRIPTION__;
if (!invoke || !ready) throw new Error("Mock socket bridge is unavailable");
const channel = "9a1657ac-f7aa-5db0-b632-d8bbeb6dfb50";
const owner = "deadbeef".repeat(8);
const frames: unknown[][] = [];
const id = await invoke("plugin:websocket|connect", {
onMessage: (batch: Array<{ type: string; data?: string }>) => {
for (const frame of batch) {
if (frame.type === "Text" && frame.data) {
frames.push(JSON.parse(frame.data));
}
}
},
});
const subId = "live-readiness-regression";
const check = (kind: number | undefined = 9, exactChannel = true) =>
ready({ channelName: "general", kind, exactChannel });
const send = (message: unknown[]) =>
invoke("plugin:websocket|send", {
id,
message: { type: "Text", data: JSON.stringify(message) },
});
const req = async (filters: Array<Record<string, unknown>>) => {
frames.length = 0;
await send(["REQ", subId, ...filters]);
if (!frames.some((frame) => frame[0] === "EOSE" && frame[1] === subId)) {
throw new Error(`REQ was not accepted: ${JSON.stringify(frames)}`);
}
return check();
};
try {
const before = check();
const splitGlobal = await req([
{ "#h": [channel], kinds: [30078] },
{ kinds: [9] },
]);
const splitOtherChannel = await req([
{ "#h": [channel], kinds: [30078] },
{ "#h": ["other"], kinds: [9] },
]);
const sameFilter = await req([{ "#h": [channel], kinds: [9] }]);
const emptyKinds = await req([
{ "#h": [channel], "#p": [owner], kinds: [] },
]);
const omittedKinds = await req([{ "#h": [channel], "#p": [owner] }]);
const globalOnly = await req([{ kinds: [9] }]);
const legacyGlobal = check(9, false);
await send(["CLOSE", subId]);
const afterClose = check();
return {
before,
splitGlobal,
splitOtherChannel,
sameFilter,
emptyKinds,
omittedKinds,
globalOnly,
legacyGlobal,
afterClose,
};
} finally {
await invoke("plugin:websocket|disconnect", { id });
}
});
expect(observed).toEqual({
before: false,
splitGlobal: false,
splitOtherChannel: false,
sameFilter: true,
emptyKinds: false,
omittedKinds: true,
globalOnly: false,
legacyGlobal: true,
afterClose: false,
});
});