feat(02-04): harness A24 — empirical Blob URL download verification (D-P2-01 closes P0-6)
Wire A24 into the Plan 01-13 Approach B UAT harness as the binding empirical gate for D-P2-01. A24 verifies end-to-end that SAVE_ARCHIVE → chrome.downloads. download receives a `blob:` URL prefix (NOT `data:application/zip;base64,`), closing audit P0-6 functionally. The Plan 02-02 unit tests pin the wire-format at the SW↔offscreen boundary; A24 pins it at the chrome.downloads platform boundary through a real Chrome instance. Strategy: chrome.downloads.onCreated listener captures the URL cross-realm. The plan's <action> block proposed a chrome.downloads.download monkey-patch installed in the harness page realm — but that intercepts only same-realm calls, missing the SW's call. The canonical cross-realm capture pattern is chrome.downloads.onCreated (fires for any download initiated by any extension realm, with the full DownloadItem including .url). Documented as a deviation from the plan's pseudo-code in SUMMARY.md (Rule 1 — bug fix vs the pseudo-code strategy; same A24 contract verified, correct mechanism). Files modified: - tests/uat/extension-page-harness.ts (+~150 lines): assertA24 + A24_* constants - tests/uat/lib/harness-page-driver.ts (+~30 lines): driveA24 page.evaluate wrapper - tests/uat/harness.test.ts (+~10 lines): import driveA24, append to drivers list Verification: - HEADLESS=1 npm run test:uat → 25/25 GREEN (24 baseline + A24) - capturedUrl observed: blob:chrome-extension://lpgnfoop.../... - npx vitest run → 171/171 GREEN (no regression) - Tier-1 FORBIDDEN_HOOK_STRINGS gate → 13/13 GREEN (12 strings preserved) - npx tsc --noEmit → clean Plan 02-04 scope: 1/3 tasks landed (A24); Tasks 2-3 add A25+A26+A27+A28 (latency, meta.json shape, multi-tab strict, REQ-archive-layout strict).
This commit is contained in:
@@ -89,6 +89,8 @@ import {
|
||||
driveA22,
|
||||
// Plan 01-14 — picker-narrowing constraint
|
||||
driveA23,
|
||||
// Plan 02-04 Task 1 — D-P2-01 empirical Blob URL verification
|
||||
driveA24,
|
||||
getManifestVersion,
|
||||
} from './lib/harness-page-driver';
|
||||
import {
|
||||
@@ -256,8 +258,8 @@ async function assertA0_GrepGate(): Promise<{
|
||||
* @returns Process exit code: 0 on 15/15 GREEN, 1 on any failure.
|
||||
*/
|
||||
async function main(): Promise<number> {
|
||||
process.stdout.write('\nMokosh Plan 01-13 + 01-14 — UAT harness orchestrator\n');
|
||||
process.stdout.write('Architecture: A0 pre-flight + extension-internal page driver (A1..A14, A23)\n');
|
||||
process.stdout.write('\nMokosh Plan 01-13 + 01-14 + 02-04 — UAT harness orchestrator\n');
|
||||
process.stdout.write('Architecture: A0 pre-flight + extension-internal page driver (A1..A14, A15..A17, A18..A22, A23, A24)\n');
|
||||
process.stdout.write('='.repeat(72) + '\n');
|
||||
|
||||
// A0 pre-flight (no Chrome launch needed; runs against built dist/).
|
||||
@@ -373,6 +375,15 @@ async function main(): Promise<number> {
|
||||
// Chrome ≥ 119 picker-narrowing semantics). Independent of A14 —
|
||||
// no new getDisplayMedia call, no new state change.
|
||||
{ name: 'A23', drive: driveA23 },
|
||||
// Plan 02-04 Task 1 A24: D-P2-01 empirical Blob URL verification.
|
||||
// Installs chrome.downloads.onCreated listener cross-realm, dispatches
|
||||
// SAVE_ARCHIVE, captures the download URL, asserts the `blob:` prefix
|
||||
// (closes audit P0-6 end-to-end through a real Chrome instance +
|
||||
// the offscreen mint round-trip + chrome.downloads platform call).
|
||||
// A24 does its OWN setupFreshRecording + SAVE because the listener
|
||||
// must be installed pre-dispatch. After A24 the recording stays alive
|
||||
// for any chained Plan 02-04 Tasks 2-3 assertions (Phase 2 closure).
|
||||
{ name: 'A24', drive: driveA24 },
|
||||
];
|
||||
|
||||
const buffers = { swConsole: handles.swConsole, offConsole: handles.offConsole };
|
||||
|
||||
Reference in New Issue
Block a user