cursedbelt 5.99.1 → 5.99.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/react/engagement/beaconClient.d.ts.map +1 -1
- package/dist/react/engagement/beaconClient.js +24 -3
- package/dist/react/engagement/beaconClient.js.map +1 -1
- package/dist/testing/designBaseline.d.ts +1 -0
- package/dist/testing/designBaseline.d.ts.map +1 -1
- package/dist/testing/designBaseline.js +13 -1
- package/dist/testing/designBaseline.js.map +1 -1
- package/package.json +2 -2
- package/src/react/engagement/beaconClient.spec.ts +25 -14
- package/src/react/engagement/beaconClient.ts +25 -3
- package/src/testing/designBaseline.spec.ts +34 -0
- package/src/testing/designBaseline.ts +16 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beaconClient.d.ts","sourceRoot":"","sources":["../../../src/react/engagement/beaconClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAEhD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAaD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAYD,8DAA8D;AAC9D,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;
|
|
1
|
+
{"version":3,"file":"beaconClient.d.ts","sourceRoot":"","sources":["../../../src/react/engagement/beaconClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAEhD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAaD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAYD,8DAA8D;AAC9D,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AA6CD;;;;;GAKG;AACH,wBAAsB,WAAW,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,OAAO,CAAC,CAgClB;AAED,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC9D;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBtG;AAED,8DAA8D;AAC9D,MAAM,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC;AAIpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,kBAAuB,GAAG,UAAU,CAehF"}
|
|
@@ -97,6 +97,23 @@ export function resetEngagementBeacon() {
|
|
|
97
97
|
lastReported = null;
|
|
98
98
|
sessionAnswer = null;
|
|
99
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Read an answer to its end, and drop it.
|
|
102
|
+
*
|
|
103
|
+
* 🔴 Chromium reports a fetch whose body nobody reads as STILL LOADING, so Playwright's
|
|
104
|
+
* `networkidle` never comes on a page that fired the beacon. flix's desktop design audit waited
|
|
105
|
+
* out its 15 s cap at every place it visited — 60 s of a 98 s gate (forge task 3884); the resume
|
|
106
|
+
* client learned the same thing in task 2574 (`deep-link/resume.ts`). Every answer this file
|
|
107
|
+
* receives — the probe's refusal, the recorder's reply — is read through here.
|
|
108
|
+
*/
|
|
109
|
+
async function drain(res) {
|
|
110
|
+
try {
|
|
111
|
+
await res.text();
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// The request was made; an answer that cannot be read changes nothing it reports.
|
|
115
|
+
}
|
|
116
|
+
}
|
|
100
117
|
/**
|
|
101
118
|
* Is there a session? Silent, cached, and false on any doubt.
|
|
102
119
|
*
|
|
@@ -113,8 +130,10 @@ async function hasSession(options) {
|
|
|
113
130
|
const res = await doFetch(options.sessionPath ?? SESSION_PATH, {
|
|
114
131
|
credentials: "same-origin",
|
|
115
132
|
});
|
|
116
|
-
if (!res.ok)
|
|
133
|
+
if (!res.ok) {
|
|
134
|
+
await drain(res);
|
|
117
135
|
return false;
|
|
136
|
+
}
|
|
118
137
|
const body = (await res.json());
|
|
119
138
|
return body?.authenticated === true;
|
|
120
139
|
}
|
|
@@ -147,7 +166,7 @@ export async function reportPlace(place, options = {}) {
|
|
|
147
166
|
return false;
|
|
148
167
|
lastReported = place;
|
|
149
168
|
try {
|
|
150
|
-
await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/view`, {
|
|
169
|
+
const res = await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/view`, {
|
|
151
170
|
method: "POST",
|
|
152
171
|
headers: { "content-type": "application/json" },
|
|
153
172
|
// Same-origin credentials: the session cookie is the only identity
|
|
@@ -156,6 +175,7 @@ export async function reportPlace(place, options = {}) {
|
|
|
156
175
|
body: JSON.stringify({ place }),
|
|
157
176
|
keepalive: true,
|
|
158
177
|
});
|
|
178
|
+
await drain(res);
|
|
159
179
|
return true;
|
|
160
180
|
}
|
|
161
181
|
catch {
|
|
@@ -195,13 +215,14 @@ export async function reportAction(action, options = {}) {
|
|
|
195
215
|
}
|
|
196
216
|
const place = options.place ?? (typeof window === "undefined" ? "/" : currentLocationPlace());
|
|
197
217
|
try {
|
|
198
|
-
await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/action`, {
|
|
218
|
+
const res = await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/action`, {
|
|
199
219
|
method: "POST",
|
|
200
220
|
headers: { "content-type": "application/json" },
|
|
201
221
|
credentials: "same-origin",
|
|
202
222
|
body: JSON.stringify({ place, action }),
|
|
203
223
|
keepalive: true,
|
|
204
224
|
});
|
|
225
|
+
await drain(res);
|
|
205
226
|
return true;
|
|
206
227
|
}
|
|
207
228
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beaconClient.js","sourceRoot":"","sources":["../../../src/react/engagement/beaconClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAmBhD;;;;;;;;GAQG;AACH,IAAI,YAAY,GAAkB,IAAI,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB;IACnC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;IACnD,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;AACjC,CAAC;AAED;;;;;;;GAOG;AACH,IAAI,aAAa,GAA4B,IAAI,CAAC;AAElD,8DAA8D;AAC9D,MAAM,UAAU,qBAAqB;IACpC,YAAY,GAAG,IAAI,CAAC;IACpB,aAAa,GAAG,IAAI,CAAC;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,UAAU,CAAC,OAA2B;IACpD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC;IACtD,IAAI,OAAO,OAAO,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,WAAW,IAAI,YAAY,EAAE;YAC9D,WAAW,EAAE,aAAa;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"beaconClient.js","sourceRoot":"","sources":["../../../src/react/engagement/beaconClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -44,6 +44,7 @@ export declare function designLedger(baselinePath: string): {
|
|
|
44
44
|
audit(page: ResizablePage, route: string, options?: AuditDesignOptions & {
|
|
45
45
|
widths?: readonly number[];
|
|
46
46
|
schemes?: readonly ColorScheme[];
|
|
47
|
+
blankWaitMs?: number;
|
|
47
48
|
}): Promise<void>;
|
|
48
49
|
/**
|
|
49
50
|
* The Apple pass (forge task apple-device-testing, `appleWalk.ts`): the page, already open in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"designBaseline.d.ts","sourceRoot":"","sources":["../../src/testing/designBaseline.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAA4B,MAAM,gBAAgB,CAAC;AAClG,OAAO,EACL,KAAK,kBAAkB,EAGvB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,cAAc,EAEpB,MAAM,kBAAkB,CAAC;AAE1B,2EAA2E;AAC3E,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,eAAe,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,YAAY,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC1D;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"designBaseline.d.ts","sourceRoot":"","sources":["../../src/testing/designBaseline.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAA4B,MAAM,gBAAgB,CAAC;AAClG,OAAO,EACL,KAAK,kBAAkB,EAGvB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,cAAc,EAEpB,MAAM,kBAAkB,CAAC;AAE1B,2EAA2E;AAC3E,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,eAAe,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,YAAY,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC1D;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AA0C3C,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,sBAAuB,CAAC;AAIrD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAOD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAYvE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,MAAM,CAG3E;AAED,MAAM,WAAW,qBAAqB;IACpC,uFAAuF;IACvF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,iGAAiG;IACjG,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,iGAAiG;AACjG,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,EAAE,EAAE,QAAQ,EAAE,mBAAmB,EAAE,GAAG,qBAAqB,CAc1H;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM;IAkC7C;;;;OAIG;gBAEK,aAAa,SACZ,MAAM,YACJ,kBAAkB,GAAG;QAAE,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACnH,OAAO,CAAC,IAAI,CAAC;IAehB;;;;;OAKG;qBACoB,SAAS,SAAS,MAAM,UAAU,WAAW,YAAW,iBAAiB,GAAQ,OAAO,CAAC,IAAI,CAAC;kBAMvG,MAAM,cAAc,eAAe,EAAE,GAAG,IAAI;IAG1D;;;OAGG;cACO,MAAM;aAMP,mBAAmB,EAAE;iBAUlB,MAAM,GAAG,SAAS,GAAiC,qBAAqB;EAkCvF"}
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
21
21
|
import { auditApple, settleInPage } from './appleWalk.js';
|
|
22
22
|
import { auditDesign, DESIGN_RULES, formatDesignViolations, } from './designAudit.js';
|
|
23
|
+
/** How long a width that reads no visible text is given to paint before the audit calls it blank. */
|
|
24
|
+
const BLANK_WAIT_MS = 10_000;
|
|
23
25
|
/** The color-scheme store's key (cursedbelt-core `COLOR_SCHEME_STORAGE_KEY`), said here so the
|
|
24
26
|
* ledger stays free of a runtime import from the React half. */
|
|
25
27
|
const SCHEME_KEY = 'cwip.colorScheme';
|
|
@@ -107,7 +109,17 @@ export function designLedger(baselinePath) {
|
|
|
107
109
|
// Wait for the page to settle (`settleInPage` says what that means and why).
|
|
108
110
|
await page.evaluate(settleInPage, undefined);
|
|
109
111
|
const label = `${route}@${width}${scheme ? `:${scheme}` : ''}`;
|
|
110
|
-
|
|
112
|
+
let { violations, census } = await auditDesign(page, { ...options, route, width });
|
|
113
|
+
// A width change can hide what was on screen (a pane the CSS drops at this width) before the
|
|
114
|
+
// code that mounts its replacement runs, and a loaded machine stretches that gap past
|
|
115
|
+
// `settleInPage`'s calm: vault's entry read blank at 390 under the ship's three gates at once
|
|
116
|
+
// (forge task 3890). So a blank census is settled and read again until the deadline.
|
|
117
|
+
const deadline = Date.now() + (options.blankWaitMs ?? BLANK_WAIT_MS);
|
|
118
|
+
while (census.textNodes === 0 && Date.now() < deadline) {
|
|
119
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
120
|
+
await page.evaluate(settleInPage, undefined);
|
|
121
|
+
({ violations, census } = await auditDesign(page, { ...options, route, width }));
|
|
122
|
+
}
|
|
111
123
|
// A sweep that read no text audited nothing, and an empty finding list from it would
|
|
112
124
|
// read as a clean page — the false green the touch-target sweep was once caught in.
|
|
113
125
|
if (census.textNodes === 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"designBaseline.js","sourceRoot":"","sources":["../../src/testing/designBaseline.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"designBaseline.js","sourceRoot":"","sources":["../../src/testing/designBaseline.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursedbelt",
|
|
3
|
-
"version": "5.99.
|
|
3
|
+
"version": "5.99.3",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "The React design system of the cursedbelt split — components, styles, theme. cursedbelt-core below it; server tier in cursedbelt-server.",
|
|
@@ -965,7 +965,7 @@
|
|
|
965
965
|
"@vidstack/react": "1.15.6",
|
|
966
966
|
"@vitejs/plugin-react": "^5.2.0",
|
|
967
967
|
"cursedbelt-server": "^4.43.1",
|
|
968
|
-
"cursedops": "^0.
|
|
968
|
+
"cursedops": "^0.22.0",
|
|
969
969
|
"diff": "^9.0.0",
|
|
970
970
|
"emoji-mart": "^5.6.0",
|
|
971
971
|
"hls.js": "^1.5.0",
|
|
@@ -15,21 +15,19 @@
|
|
|
15
15
|
import { beforeEach, describe, expect, test } from "bun:test";
|
|
16
16
|
import { reportAction, reportPlace, resetEngagementBeacon, SESSION_PATH } from "./beaconClient.js";
|
|
17
17
|
|
|
18
|
-
/** A `fetch` that records every call and answers from a script. */
|
|
18
|
+
/** A `fetch` that records every call, and every answer it handed out, and answers from a script. */
|
|
19
19
|
function recordingFetch(answers: Record<string, { status?: number; body?: unknown }>) {
|
|
20
20
|
const calls: string[] = [];
|
|
21
|
+
const responses: Response[] = [];
|
|
21
22
|
const impl = (async (input: string) => {
|
|
22
23
|
const url = String(input);
|
|
23
24
|
calls.push(url);
|
|
24
25
|
const answer = answers[url] ?? { status: 404 };
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
status,
|
|
29
|
-
json: async () => answer.body ?? {},
|
|
30
|
-
};
|
|
26
|
+
const response = new Response(JSON.stringify(answer.body ?? {}), { status: answer.status ?? 200 });
|
|
27
|
+
responses.push(response);
|
|
28
|
+
return response;
|
|
31
29
|
}) as unknown as typeof fetch;
|
|
32
|
-
return { impl, calls };
|
|
30
|
+
return { impl, calls, responses };
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
const SIGNED_IN = { body: { authenticated: true } };
|
|
@@ -116,18 +114,31 @@ describe("the probe fails CLOSED", () => {
|
|
|
116
114
|
const impl = (async (input: string) => {
|
|
117
115
|
if (answer === null) throw new Error("network down");
|
|
118
116
|
const status = (answer as { status?: number }).status ?? 200;
|
|
119
|
-
return {
|
|
120
|
-
ok: status >= 200 && status < 300,
|
|
121
|
-
status,
|
|
122
|
-
json: async () => (answer as { body?: unknown }).body ?? {},
|
|
123
|
-
_url: input,
|
|
124
|
-
};
|
|
117
|
+
return new Response(JSON.stringify((answer as { body?: unknown }).body ?? {}), { status, headers: { "x-url": input } });
|
|
125
118
|
}) as unknown as typeof fetch;
|
|
126
119
|
|
|
127
120
|
expect(await reportPlace("/#/hub", { fetchImpl: impl })).toBe(false);
|
|
128
121
|
});
|
|
129
122
|
});
|
|
130
123
|
|
|
124
|
+
describe("every answer is read to its end (forge task 3884)", () => {
|
|
125
|
+
// Chromium reports a fetch whose body nobody reads as still loading, so Playwright's
|
|
126
|
+
// `networkidle` never came on a page that fired the beacon: flix's desktop audit waited out a
|
|
127
|
+
// 15 s cap at every place — 60 s of its 98 s gate.
|
|
128
|
+
test.each([
|
|
129
|
+
["a signed-in view", { [SESSION_PATH]: SIGNED_IN, "/api/engagement/view": { status: 204 } }],
|
|
130
|
+
["the recorder refuses", { [SESSION_PATH]: SIGNED_IN, "/api/engagement/view": { status: 404 } }],
|
|
131
|
+
["the probe refuses", { [SESSION_PATH]: { status: 500 } }],
|
|
132
|
+
["signed out", { [SESSION_PATH]: SIGNED_OUT }],
|
|
133
|
+
])("%s — no response is left unread", async (_name, answers) => {
|
|
134
|
+
const { impl, responses } = recordingFetch(answers);
|
|
135
|
+
await reportPlace("/#/hub", { fetchImpl: impl });
|
|
136
|
+
await reportAction("search", { fetchImpl: impl, place: "/#/hub" });
|
|
137
|
+
expect(responses.length).toBeGreaterThan(0);
|
|
138
|
+
expect(responses.map((r) => r.bodyUsed)).toEqual(responses.map(() => true));
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
131
142
|
describe("a caller that already knows may skip the probe", () => {
|
|
132
143
|
test("assumeSignedIn reports with no second answer to the same question", async () => {
|
|
133
144
|
const { impl, calls } = recordingFetch({ "/api/engagement/view": { status: 200 } });
|
|
@@ -121,6 +121,23 @@ export function resetEngagementBeacon(): void {
|
|
|
121
121
|
sessionAnswer = null;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Read an answer to its end, and drop it.
|
|
126
|
+
*
|
|
127
|
+
* 🔴 Chromium reports a fetch whose body nobody reads as STILL LOADING, so Playwright's
|
|
128
|
+
* `networkidle` never comes on a page that fired the beacon. flix's desktop design audit waited
|
|
129
|
+
* out its 15 s cap at every place it visited — 60 s of a 98 s gate (forge task 3884); the resume
|
|
130
|
+
* client learned the same thing in task 2574 (`deep-link/resume.ts`). Every answer this file
|
|
131
|
+
* receives — the probe's refusal, the recorder's reply — is read through here.
|
|
132
|
+
*/
|
|
133
|
+
async function drain(res: Response): Promise<void> {
|
|
134
|
+
try {
|
|
135
|
+
await res.text();
|
|
136
|
+
} catch {
|
|
137
|
+
// The request was made; an answer that cannot be read changes nothing it reports.
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
124
141
|
/**
|
|
125
142
|
* Is there a session? Silent, cached, and false on any doubt.
|
|
126
143
|
*
|
|
@@ -136,7 +153,10 @@ async function hasSession(options: ReportPlaceOptions): Promise<boolean> {
|
|
|
136
153
|
const res = await doFetch(options.sessionPath ?? SESSION_PATH, {
|
|
137
154
|
credentials: "same-origin",
|
|
138
155
|
});
|
|
139
|
-
if (!res.ok)
|
|
156
|
+
if (!res.ok) {
|
|
157
|
+
await drain(res);
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
140
160
|
const body = (await res.json()) as { authenticated?: unknown } | null;
|
|
141
161
|
return body?.authenticated === true;
|
|
142
162
|
} catch {
|
|
@@ -170,7 +190,7 @@ export async function reportPlace(
|
|
|
170
190
|
if (place === lastReported) return false;
|
|
171
191
|
lastReported = place;
|
|
172
192
|
try {
|
|
173
|
-
await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/view`, {
|
|
193
|
+
const res = await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/view`, {
|
|
174
194
|
method: "POST",
|
|
175
195
|
headers: { "content-type": "application/json" },
|
|
176
196
|
// Same-origin credentials: the session cookie is the only identity
|
|
@@ -179,6 +199,7 @@ export async function reportPlace(
|
|
|
179
199
|
body: JSON.stringify({ place }),
|
|
180
200
|
keepalive: true,
|
|
181
201
|
});
|
|
202
|
+
await drain(res);
|
|
182
203
|
return true;
|
|
183
204
|
} catch {
|
|
184
205
|
// See the header: telemetry never becomes the user's problem.
|
|
@@ -223,13 +244,14 @@ export async function reportAction(action: string, options: ReportActionOptions
|
|
|
223
244
|
}
|
|
224
245
|
const place = options.place ?? (typeof window === "undefined" ? "/" : currentLocationPlace());
|
|
225
246
|
try {
|
|
226
|
-
await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/action`, {
|
|
247
|
+
const res = await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/action`, {
|
|
227
248
|
method: "POST",
|
|
228
249
|
headers: { "content-type": "application/json" },
|
|
229
250
|
credentials: "same-origin",
|
|
230
251
|
body: JSON.stringify({ place, action }),
|
|
231
252
|
keepalive: true,
|
|
232
253
|
});
|
|
254
|
+
await drain(res);
|
|
233
255
|
return true;
|
|
234
256
|
} catch {
|
|
235
257
|
return false;
|
|
@@ -88,3 +88,37 @@ test('detail() prints every recorded finding with its route, and nothing for a c
|
|
|
88
88
|
expect(ledger.detail()).toContain('home@iphone-se-3rd-gen');
|
|
89
89
|
expect(ledger.detail()).toContain('button "Pin"');
|
|
90
90
|
});
|
|
91
|
+
|
|
92
|
+
describe('a width that reads blank is given its moment to paint (forge task 3890)', () => {
|
|
93
|
+
/** A page whose probe reads no text for its first `blankReads` audits, then one LAY-13. */
|
|
94
|
+
const pageBlankFor = (blankReads: number) => {
|
|
95
|
+
let probes = 0;
|
|
96
|
+
return {
|
|
97
|
+
probes: () => probes,
|
|
98
|
+
setViewportSize: async () => {},
|
|
99
|
+
viewportSize: () => ({ width: 1280, height: 900 }),
|
|
100
|
+
evaluate: async <R, A>(_fn: (arg: A) => R | Promise<R>, arg: A): Promise<R> => {
|
|
101
|
+
if (!(arg && typeof arg === 'object' && 'rules' in arg)) return undefined as R; // settleInPage
|
|
102
|
+
probes++;
|
|
103
|
+
const textNodes = probes > blankReads ? 12 : 0;
|
|
104
|
+
return { violations: textNodes ? [v('LAY-13')] : [], census: { textNodes, targets: 0, controlRows: 0, tableCells: 0, contrastChecked: 0, coarse: false, innerWidth: 390 } } as R;
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
test('🔴 a pane the resize hid, whose replacement paints a moment later, is audited once it has', async () => {
|
|
110
|
+
const page = pageBlankFor(2);
|
|
111
|
+
const ledger = designLedger(tmp());
|
|
112
|
+
await ledger.audit(page, 'entry', { widths: [390] });
|
|
113
|
+
expect(page.probes()).toBe(3);
|
|
114
|
+
expect(ledger.detail()).toContain('entry@390');
|
|
115
|
+
expect(ledger.detail()).toContain('LAY-13');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('🔴 a page still blank at the deadline is refused — no empty finding list reads as clean', async () => {
|
|
119
|
+
const page = pageBlankFor(Number.POSITIVE_INFINITY);
|
|
120
|
+
const ledger = designLedger(tmp());
|
|
121
|
+
await expect(ledger.audit(page, 'entry', { widths: [390], blankWaitMs: 300 })).rejects.toThrow('entry@390 rendered no visible text');
|
|
122
|
+
expect(page.probes()).toBeGreaterThan(1);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
@@ -38,6 +38,9 @@ export interface ResizablePage extends EvaluatingPage {
|
|
|
38
38
|
|
|
39
39
|
export type ColorScheme = 'light' | 'dark';
|
|
40
40
|
|
|
41
|
+
/** How long a width that reads no visible text is given to paint before the audit calls it blank. */
|
|
42
|
+
const BLANK_WAIT_MS = 10_000;
|
|
43
|
+
|
|
41
44
|
/** The color-scheme store's key (cursedbelt-core `COLOR_SCHEME_STORAGE_KEY`), said here so the
|
|
42
45
|
* ledger stays free of a runtime import from the React half. */
|
|
43
46
|
const SCHEME_KEY = 'cwip.colorScheme';
|
|
@@ -146,7 +149,7 @@ export function designLedger(baselinePath: string) {
|
|
|
146
149
|
page: ResizablePage,
|
|
147
150
|
route: string,
|
|
148
151
|
scheme: ColorScheme | null,
|
|
149
|
-
options: AuditDesignOptions & { widths?: readonly number[] },
|
|
152
|
+
options: AuditDesignOptions & { widths?: readonly number[]; blankWaitMs?: number },
|
|
150
153
|
): Promise<void> {
|
|
151
154
|
const original = page.viewportSize();
|
|
152
155
|
for (const width of options.widths ?? APP_AUDIT_WIDTHS) {
|
|
@@ -154,7 +157,17 @@ export function designLedger(baselinePath: string) {
|
|
|
154
157
|
// Wait for the page to settle (`settleInPage` says what that means and why).
|
|
155
158
|
await page.evaluate(settleInPage, undefined);
|
|
156
159
|
const label = `${route}@${width}${scheme ? `:${scheme}` : ''}`;
|
|
157
|
-
|
|
160
|
+
let { violations, census } = await auditDesign(page, { ...options, route, width });
|
|
161
|
+
// A width change can hide what was on screen (a pane the CSS drops at this width) before the
|
|
162
|
+
// code that mounts its replacement runs, and a loaded machine stretches that gap past
|
|
163
|
+
// `settleInPage`'s calm: vault's entry read blank at 390 under the ship's three gates at once
|
|
164
|
+
// (forge task 3890). So a blank census is settled and read again until the deadline.
|
|
165
|
+
const deadline = Date.now() + (options.blankWaitMs ?? BLANK_WAIT_MS);
|
|
166
|
+
while (census.textNodes === 0 && Date.now() < deadline) {
|
|
167
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
168
|
+
await page.evaluate(settleInPage, undefined);
|
|
169
|
+
({ violations, census } = await auditDesign(page, { ...options, route, width }));
|
|
170
|
+
}
|
|
158
171
|
// A sweep that read no text audited nothing, and an empty finding list from it would
|
|
159
172
|
// read as a clean page — the false green the touch-target sweep was once caught in.
|
|
160
173
|
if (census.textNodes === 0) throw new Error(`design audit: ${label} rendered no visible text — nothing was audited`);
|
|
@@ -171,7 +184,7 @@ export function designLedger(baselinePath: string) {
|
|
|
171
184
|
async audit(
|
|
172
185
|
page: ResizablePage,
|
|
173
186
|
route: string,
|
|
174
|
-
options: AuditDesignOptions & { widths?: readonly number[]; schemes?: readonly ColorScheme[] } = {},
|
|
187
|
+
options: AuditDesignOptions & { widths?: readonly number[]; schemes?: readonly ColorScheme[]; blankWaitMs?: number } = {},
|
|
175
188
|
): Promise<void> {
|
|
176
189
|
const original = page.viewportSize();
|
|
177
190
|
// No `schemes`: the page is audited in whatever scheme it opened in, under the labels
|