2026-09-01 23:41:28 +02:00
/**
* @jest-environment jsdom
*/
const path = require ( "node:path" );
const {
2026-09-06 12:51:12 +02:00
LiveFatalSignalGuard ,
LiveReadOnlyGate ,
2026-09-01 23:41:28 +02:00
LiveRunDiagnostics ,
UNHANDLED_REJECTION_PREFIX ,
diagnosticApiUrl ,
2026-09-06 12:51:12 +02:00
environmentalConsoleWarningId ,
2026-09-01 23:41:28 +02:00
readLivePageState ,
2026-09-06 12:51:12 +02:00
runIndependentLoggedStages ,
2026-09-01 23:41:28 +02:00
runLoggedStage ,
} = require ( "../e2e/live/live-diagnostics" );
class FakeEmitter {
constructor () {
this . listeners = new Map ();
}
emit ( event , value ) {
for ( const listener of this . listeners . get ( event ) ?? []) listener ( value );
}
off ( event , listener ) {
this . listeners . get ( event ) ? . delete ( listener );
}
on ( event , listener ) {
if ( ! this . listeners . has ( event )) this . listeners . set ( event , new Set ());
this . listeners . get ( event ). add ( listener );
}
}
function visibleRect () {
return { bottom : 100 , height : 90 , left : 10 , right : 60 , top : 10 , width : 50 };
}
2026-09-06 12:51:12 +02:00
function consoleError ( text , url = "https://www.youtube.com/watch?v=abcdefghijk" ) {
return {
location : () => ({ lineNumber : 7 , url }),
text : () => text ,
type : () => "error" ,
};
}
function createLiveHarness ( diagnosticsOptions = {}) {
const context = new FakeEmitter ();
context . serviceWorkers = jest . fn (() => []);
const page = new FakeEmitter ();
page . addInitScript = jest . fn (). mockResolvedValue ( undefined );
page . evaluate = jest . fn (). mockResolvedValue ( undefined );
page . isClosed = jest . fn (() => false );
page . url = jest . fn (() => "https://www.youtube.com/watch?v=abcdefghijk" );
return {
context ,
diagnostics : new LiveRunDiagnostics ( page , context , { log : jest . fn (), ... diagnosticsOptions }),
page ,
};
}
2026-09-01 23:41:28 +02:00
describe ( "live interactive diagnostics" , () => {
test ( "captures runtime and Shorts ownership state without dumping page HTML" , () => {
document . documentElement . setAttribute ( "data-ryd-userscript-version" , "3.2.0" );
document . body . innerHTML = `
<ytd-reel-video-renderer video-id="abcdefghijk" is-active>
<a href="/shorts/abcdefghijk">Short</a>
<reel-action-bar-view-model>
<like-button-view-model></like-button-view-model>
<button-view-model data-ryd-synthetic-shorts-dislike data-ryd-video-id="abcdefghijk">
<button aria-pressed="false"></button><span>123</span>
</button-view-model>
</reel-action-bar-view-model>
</ytd-reel-video-renderer>
` ;
for ( const element of document . querySelectorAll ( "*" )) element . getBoundingClientRect = visibleRect ;
const state = readLivePageState ();
expect ( state . runtimeMarkers ). toEqual ({
extension : null ,
extensionBuild : null ,
userscript : "3.2.0" ,
userscriptBuild : null ,
});
expect ( state . renderers ). toEqual ([
expect . objectContaining ({ actionBars : 1 , syntheticControls : 1 , videoId : "abcdefghijk" , visible : true }),
]);
expect ( state . renderers [ 0 ]. links ). toEqual ([{ href : "/shorts/abcdefghijk" , visible : true }]);
expect ( state . actionBars ). toEqual ([
expect . objectContaining ({ nativeLikes : 1 , syntheticControls : 1 , videoId : "abcdefghijk" , visible : true }),
]);
expect ( state . syntheticControls ). toEqual ([
expect . objectContaining ({ ariaPressed : "false" , text : "123" , videoId : "abcdefghijk" , visible : true }),
]);
expect ( JSON . stringify ( state )). not . toContain ( "outerHTML" );
});
test ( "records browser failures and redacted recent API traffic in the persisted snapshot" , async () => {
const context = new FakeEmitter ();
const page = new FakeEmitter ();
page . addInitScript = jest . fn (). mockResolvedValue ( undefined );
page . evaluate = jest . fn ( async ( callback ) =>
callback . name === "readLivePageState" ? { runtimeMarkers : { userscript : "3.2.0" } } : undefined ,
);
page . isClosed = jest . fn (() => false );
page . url = jest . fn (() => "https://www.youtube.com/shorts/abcdefghijk" );
const fileSystem = { mkdirSync : jest . fn (), writeFileSync : jest . fn () };
const log = jest . fn ();
const diagnostics = new LiveRunDiagnostics ( page , context , {
clock : () => new Date ( "2026-08-18T12:34:56.000Z" ),
fileSystem ,
log ,
outputDirectory : "diagnostics" ,
runtime : "userscript" ,
});
await diagnostics . start ();
diagnostics . stageStarted ( "read-only.channel-to-shorts-and-next" );
diagnostics . checkpoint ( "ryd-votes-response.waiting" , { videoId : "abcdefghijk" });
const request = {
method : () => "GET" ,
resourceType : () => "fetch" ,
url : () => "https://returnyoutubedislikeapi.com/votes?videoId=abcdefghijk&userId=private-id" ,
};
context . emit ( "request" , request );
context . emit ( "response" , { request : () => request , status : () => 200 });
page . emit ( "pageerror" , new Error ( "page exploded" ));
page . emit ( "console" , {
location : () => ({ lineNumber : 7 , url : "https://www.youtube.com/shorts/abcdefghijk" }),
text : () => ` ${ UNHANDLED_REJECTION_PREFIX } promise exploded` ,
type : () => "error" ,
});
page . emit ( "console" , {
location : () => ({}),
text : () => "console exploded" ,
type : () => "error" ,
});
const snapshotPath = await diagnostics . persistFailureSnapshot ( new Error ( "scenario timed out" ));
diagnostics . stop ();
expect ( snapshotPath ). toBe ( path . join ( "diagnostics" , "failure-2026-08-18T12-34-56-000Z.json" ));
expect ( fileSystem . mkdirSync ). toHaveBeenCalledWith ( "diagnostics" , { recursive : true });
const snapshot = JSON . parse ( fileSystem . writeFileSync . mock . calls [ 0 ][ 1 ]);
expect ( snapshot . currentStage ). toBe ( "read-only.channel-to-shorts-and-next" );
expect ( snapshot . currentCheckpoint ). toBe ( "ryd-votes-response.waiting" );
expect ( snapshot . browserSignals . map (({ type }) => type )). toEqual ([
"pageerror" ,
"unhandledrejection" ,
"console.error" ,
]);
expect ( snapshot . recentApiRequests ). toEqual ([
expect . objectContaining ({
method : "GET" ,
pathname : "/votes" ,
query : { userId : "<redacted>" , videoId : "abcdefghijk" },
status : 200 ,
}),
]);
expect ( snapshot . pageState ). toEqual ({ runtimeMarkers : { userscript : "3.2.0" } });
expect ( snapshot . url ). toBe ( "https://www.youtube.com/shorts/abcdefghijk" );
expect ( context . listeners . get ( "request" ). size ). toBe ( 0 );
expect ( page . listeners . get ( "pageerror" ). size ). toBe ( 0 );
});
test ( "logs stage completion and failure boundaries" , async () => {
const diagnostics = {
stageCompleted : jest . fn (),
stageFailed : jest . fn (),
stageStarted : jest . fn (),
};
await expect ( runLoggedStage ( diagnostics , "success" , async () => 42 )). resolves . toBe ( 42 );
const failure = new Error ( "failed" );
await expect (
runLoggedStage ( diagnostics , "failure" , async () => {
throw failure ;
}),
). rejects . toBe ( failure );
expect ( diagnostics . stageStarted . mock . calls . map (([ name ]) => name )). toEqual ([ "success" , "failure" ]);
expect ( diagnostics . stageCompleted ). toHaveBeenCalledWith ( "success" , expect . any ( Number ));
expect ( diagnostics . stageFailed ). toHaveBeenCalledWith ( "failure" , expect . any ( Number ), failure );
});
2026-09-06 12:51:12 +02:00
test . each ([
[ "pageerror" , ( page ) => page . emit ( "pageerror" , new Error ( "page exploded" ))],
[
"unhandledrejection" ,
( page ) => page . emit ( "console" , consoleError ( ` ${ UNHANDLED_REJECTION_PREFIX } promise exploded` )),
],
[ "console.error" , ( page ) => page . emit ( "console" , consoleError ( "console exploded" ))],
])( "turns an otherwise-passing stage red for a %s" , async ( type , emitSignal ) => {
const { diagnostics , page } = createLiveHarness ();
await diagnostics . start ();
await expect (
runLoggedStage ( diagnostics , "read-only.watch" , async () => {
emitSignal ( page );
return "rendered" ;
}),
). rejects . toMatchObject ({ name : "LiveFatalSignalError" });
expect ( diagnostics . browserSignals ). toEqual ([
expect . objectContaining ({ ignoredBy : null , stage : "read-only.watch" , type }),
]);
diagnostics . stop ();
});
test . each ([
[
"googlevideo HTTP 403" ,
"Failed to load resource: the server responded with a status of 403 ()" ,
"https://rr2---sn-q4flrnel.googlevideo.com/videoplayback?opaque=1" ,
"googlevideo-resource-failure" ,
],
[
"googlevideo DNS failure" ,
"Failed to load resource: net::ERR_NAME_NOT_RESOLVED" ,
"https://rr3---sn-oxup5-f5fk.googlevideo.com/generate_204" ,
"googlevideo-resource-failure" ,
],
[
"doubleclick follow-on network failure" ,
"Failed to load resource: net::ERR_FAILED" ,
"https://googleads.g.doubleclick.net/pagead/viewthroughconversion/123/" ,
"doubleclick-resource-failure" ,
],
[
"doubleclick CORS failure" ,
"Access to XMLHttpRequest at 'https://googleads.g.doubleclick.net/pagead/id' from origin 'https://www.youtube.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource." ,
"https://www.youtube.com/watch?v=abcdefghijk" ,
"doubleclick-cors" ,
],
[
"doubleclick CORS failure after a YouTube ad redirect" ,
"Access to fetch at 'https://googleads.g.doubleclick.net/pagead/viewthroughconversion/962985656/?backend=innertube&cname=1' (redirected from 'https://www.youtube.com/pagead/viewthroughconversion/962985656/?backend=innertube&cname=1') from origin 'https://www.youtube.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource." ,
"https://www.youtube.com/watch?v=abcdefghijk&list=RDabcdefghijk" ,
"doubleclick-cors" ,
],
[
"sandboxed about:blank frame script block" ,
"Blocked script execution in 'about:blank' because the document's frame is sandboxed and the 'allow-scripts' permission is not set." ,
"about:blank" ,
"sandboxed-about-blank-script" ,
],
[
"YouTube account-cookie rotation rate limit" ,
"Failed to load resource: the server responded with a status of 429 ()" ,
"https://accounts.youtube.com/RotateCookies" ,
"youtube-rotate-cookies-rate-limit" ,
],
[
"YouTube accounts report-only frame-ancestors violation" ,
"Framing 'https://accounts.youtube.com/' violates the following report-only Content Security Policy directive: \"frame-ancestors 'self'\". The violation has been logged, but no further action has been taken.\n" ,
"" ,
"youtube-accounts-report-only-frame-ancestors" ,
],
])( "records a narrowly recognized external %s as a non-fatal warning" , async ( _name , message , url , warningId ) => {
const { diagnostics , page } = createLiveHarness ();
await diagnostics . start ();
await expect (
runLoggedStage ( diagnostics , "read-only.watch" , async () => {
page . emit ( "console" , consoleError ( message , url ));
return "rendered" ;
}),
). resolves . toBe ( "rendered" );
expect ( diagnostics . browserSignals ). toEqual ([
expect . objectContaining ({
environmentalWarning : warningId ,
ignoredBy : null ,
severity : "warning" ,
stage : "read-only.watch" ,
type : "console.error" ,
}),
]);
diagnostics . stop ();
});
test . each ([
[
"unknown status on a media CDN" ,
"Failed to load resource: the server responded with a status of 404 ()" ,
"https://rr2---sn-q4flrnel.googlevideo.com/videoplayback" ,
],
[
"page JavaScript failure reported at a media URL" ,
"TypeError: Cannot read properties of undefined" ,
"https://rr2---sn-q4flrnel.googlevideo.com/videoplayback" ,
],
[
"known network wording on YouTube itself" ,
"Failed to load resource: net::ERR_NAME_NOT_RESOLVED" ,
"https://www.youtube.com/youtubei/v1/player" ,
],
[
"production RYD API failure" ,
"Failed to load resource: net::ERR_FAILED" ,
"https://returnyoutubedislikeapi.com/votes?videoId=abcdefghijk" ,
],
[
"lookalike media hostname" ,
"Failed to load resource: the server responded with a status of 403 ()" ,
"https://googlevideo.com.attacker.test/videoplayback" ,
],
[
"insecure media URL" ,
"Failed to load resource: net::ERR_NAME_NOT_RESOLVED" ,
"http://rr2---sn-q4flrnel.googlevideo.com/videoplayback" ,
],
[
"nonstandard media port" ,
"Failed to load resource: net::ERR_NAME_NOT_RESOLVED" ,
"https://rr2---sn-q4flrnel.googlevideo.com:444/videoplayback" ,
],
[
"different YouTube account endpoint" ,
"Failed to load resource: the server responded with a status of 429 ()" ,
"https://accounts.youtube.com/RotateCookiesAgain" ,
],
[
"different status from YouTube cookie rotation" ,
"Failed to load resource: the server responded with a status of 500 ()" ,
"https://accounts.youtube.com/RotateCookies" ,
],
[
"lookalike YouTube accounts hostname" ,
"Failed to load resource: the server responded with a status of 429 ()" ,
"https://accounts.youtube.com.attacker.test/RotateCookies" ,
],
[
"enforced YouTube accounts frame-ancestors violation" ,
"Framing 'https://accounts.youtube.com/' violates the following Content Security Policy directive: \"frame-ancestors 'self'\"." ,
"" ,
],
[
"report-only YouTube accounts frame-ancestors near miss" ,
"Framing 'https://accounts.youtube.com/' violates the following report-only Content Security Policy directive: \"frame-ancestors 'self'\". The violation has been logged, but no further action has been taken." ,
"" ,
],
[
"unrelated report-only accounts frame-ancestors violation" ,
"Framing 'https://accounts.google.com/' violates the following report-only Content Security Policy directive: \"frame-ancestors 'self'\". The violation has been logged, but no further action has been taken.\n" ,
"" ,
],
[
"YouTube accounts report-only frame-ancestors violation with a page location" ,
"Framing 'https://accounts.youtube.com/' violates the following report-only Content Security Policy directive: \"frame-ancestors 'self'\". The violation has been logged, but no further action has been taken.\n" ,
"https://www.youtube.com/watch?v=abcdefghijk" ,
],
[
"lookalike CORS target" ,
"Access to fetch at 'https://doubleclick.net.attacker.test/pixel' from origin 'https://www.youtube.com' has been blocked by CORS policy: blocked" ,
"https://www.youtube.com/watch?v=abcdefghijk" ,
],
[
"non-YouTube CORS origin" ,
"Access to fetch at 'https://googleads.g.doubleclick.net/pixel' from origin 'https://attacker.test' has been blocked by CORS policy: blocked" ,
"https://www.youtube.com/watch?v=abcdefghijk" ,
],
[
"doubleclick CORS redirect from a foreign origin" ,
"Access to fetch at 'https://googleads.g.doubleclick.net/pagead/viewthroughconversion/123/' (redirected from 'https://attacker.test/pagead/viewthroughconversion/123/') from origin 'https://www.youtube.com' has been blocked by CORS policy: blocked" ,
"https://www.youtube.com/watch?v=abcdefghijk" ,
],
[
"doubleclick CORS redirect from a different YouTube endpoint" ,
"Access to fetch at 'https://googleads.g.doubleclick.net/pagead/viewthroughconversion/123/' (redirected from 'https://www.youtube.com/youtubei/v1/player') from origin 'https://www.youtube.com' has been blocked by CORS policy: blocked" ,
"https://www.youtube.com/watch?v=abcdefghijk" ,
],
[
"sandboxed-frame message at a page URL" ,
"Blocked script execution in 'about:blank' because the document's frame is sandboxed and the 'allow-scripts' permission is not set." ,
"https://www.youtube.com/watch?v=abcdefghijk" ,
],
[
"near-miss sandboxed-frame message" ,
"Blocked script execution in 'about:blank' because the document's frame is sandboxed and the 'allow-scripts' permission is not set. Unexpected" ,
"about:blank" ,
],
[ "unrelated about:blank JavaScript error" , "TypeError: Cannot read properties of undefined" , "about:blank" ],
])( "keeps %s fatal" , async ( _name , message , url ) => {
const { diagnostics , page } = createLiveHarness ();
await diagnostics . start ();
page . emit ( "console" , consoleError ( message , url ));
expect (() => diagnostics . consumeFatalSignals ( "unexpected console error" )). toThrow ( /fatal browser signal/ );
expect ( diagnostics . browserSignals [ 0 ]). toEqual (
expect . objectContaining ({ environmentalWarning : null , severity : "fatal" , type : "console.error" }),
);
diagnostics . stop ();
});
test ( "classifies only page console errors, never page exceptions or unhandled rejections" , () => {
const details = {
location : { url : "https://rr2---sn-q4flrnel.googlevideo.com/videoplayback" },
message : "Failed to load resource: net::ERR_NAME_NOT_RESOLVED" ,
source : "page" ,
};
expect ( environmentalConsoleWarningId ({ ... details , type : "console.error" })). toBe ( "googlevideo-resource-failure" );
expect ( environmentalConsoleWarningId ({ ... details , type : "pageerror" })). toBeNull ();
expect ( environmentalConsoleWarningId ({ ... details , type : "unhandledrejection" })). toBeNull ();
expect (
environmentalConsoleWarningId ({ ... details , source : "extension-service-worker" , type : "console.error" }),
). toBeNull ();
});
test ( "fails closed if a future signal reaches the guard without an explicit severity" , () => {
const { context , page } = createLiveHarness ();
const guard = new LiveFatalSignalGuard ( page , context , { log : jest . fn () });
guard . signals . push ({ message : "unclassified" , type : "console.error" });
expect (() => guard . assertNoFatalSignalsBetween ( 0 , 1 , "future signal" )). toThrow ( /console\.error: unclassified/ );
});
test ( "allows only an explicit exact benign-console rule and keeps mismatches fatal" , async () => {
const { diagnostics , page } = createLiveHarness ({
ignoredSignalRules : [
{
id : "known-youtube-message" ,
message : "Known YouTube-only diagnostic" ,
type : "console.error" ,
url : "https://www.youtube.com/watch?v=abcdefghijk" ,
},
],
});
await diagnostics . start ();
page . emit ( "console" , consoleError ( "Known YouTube-only diagnostic" ));
expect (() => diagnostics . consumeFatalSignals ( "known noise" )). not . toThrow ();
expect ( diagnostics . browserSignals [ 0 ]). toEqual (
expect . objectContaining ({ ignoredBy : "known-youtube-message" , severity : "warning" }),
);
page . emit ( "console" , consoleError ( "Known YouTube-only diagnostic with extra text" ));
expect (() => diagnostics . consumeFatalSignals ( "unexpected noise" )). toThrow ( /fatal browser signal/ );
diagnostics . stop ();
});
test ( "rejects broad or callback-based console suppression rules" , () => {
const { context , page } = createLiveHarness ();
expect (
() =>
new LiveFatalSignalGuard ( page , context , {
ignoredSignalRules : [{ id : "message-only" , message : "Failed" , type : "console.error" }],
}),
). toThrow ( /requires a non-empty exact url/ );
expect (
() =>
new LiveFatalSignalGuard ( page , context , {
ignoredSignalRules : [{ id : "broad" , messagePattern : /error/ , type : "console.error" }],
}),
). toThrow ( /unsupported fields: messagePattern/ );
expect (
() =>
new LiveFatalSignalGuard ( page , context , {
ignoredSignalRules : [{ id : "callback" , message : "ignored" , predicate : () => true , type : "console.error" }],
}),
). toThrow ( /unsupported fields: predicate/ );
});
test ( "fails only for console errors from the selected extension service worker" , async () => {
const extensionId = "a" . repeat ( 32 );
const matchingWorker = new FakeEmitter ();
matchingWorker . url = jest . fn (() => `chrome-extension:// ${ extensionId } /ryd.background.js` );
matchingWorker . evaluate = jest . fn (). mockResolvedValue ( undefined );
const unrelatedWorker = new FakeEmitter ();
unrelatedWorker . url = jest . fn (() => `chrome-extension:// ${ "b" . repeat ( 32 ) } /ryd.background.js` );
unrelatedWorker . evaluate = jest . fn (). mockResolvedValue ( undefined );
const { context , diagnostics } = createLiveHarness ({ selectedExtensionId : extensionId });
context . serviceWorkers . mockReturnValue ([ matchingWorker , unrelatedWorker ]);
await diagnostics . start ();
unrelatedWorker . emit ( "console" , consoleError ( "unrelated extension failed" , unrelatedWorker . url ()));
expect (() => diagnostics . consumeFatalSignals ( "unrelated worker" )). not . toThrow ();
matchingWorker . emit ( "console" , consoleError ( "selected extension failed" , matchingWorker . url ()));
expect (() => diagnostics . consumeFatalSignals ( "selected worker" )). toThrow (
/extension-service-worker\.console\.error: selected extension failed/ ,
);
expect ( matchingWorker . evaluate ). toHaveBeenCalledWith ( expect . any ( Function ), UNHANDLED_REJECTION_PREFIX );
expect ( unrelatedWorker . evaluate ). not . toHaveBeenCalled ();
diagnostics . stop ();
});
test ( "keeps external-resource wording fatal when it comes from the selected extension worker" , async () => {
const extensionId = "a" . repeat ( 32 );
const matchingWorker = new FakeEmitter ();
matchingWorker . url = jest . fn (() => `chrome-extension:// ${ extensionId } /ryd.background.js` );
matchingWorker . evaluate = jest . fn (). mockResolvedValue ( undefined );
const { context , diagnostics } = createLiveHarness ({ selectedExtensionId : extensionId });
context . serviceWorkers . mockReturnValue ([ matchingWorker ]);
await diagnostics . start ();
matchingWorker . emit (
"console" ,
consoleError (
"Failed to load resource: net::ERR_NAME_NOT_RESOLVED" ,
"https://rr2---sn-q4flrnel.googlevideo.com/videoplayback" ,
),
);
expect (() => diagnostics . consumeFatalSignals ( "selected worker" )). toThrow (
/extension-service-worker\.console\.error/ ,
);
expect ( diagnostics . browserSignals [ 0 ]). toEqual (
expect . objectContaining ({ environmentalWarning : null , severity : "fatal" }),
);
diagnostics . stop ();
});
test ( "guards a selected extension service worker that restarts during a scenario" , async () => {
const extensionId = "a" . repeat ( 32 );
const replacementWorker = new FakeEmitter ();
replacementWorker . url = jest . fn (() => `chrome-extension:// ${ extensionId } /ryd.background.js` );
replacementWorker . evaluate = jest . fn (). mockResolvedValue ( undefined );
const { context , diagnostics } = createLiveHarness ({ selectedExtensionId : extensionId });
await diagnostics . start ();
context . emit ( "serviceworker" , replacementWorker );
replacementWorker . emit (
"console" ,
consoleError ( ` ${ UNHANDLED_REJECTION_PREFIX } replacement rejected` , replacementWorker . url ()),
);
expect (() => diagnostics . consumeFatalSignals ( "replacement worker" )). toThrow (
/extension-service-worker\.unhandledrejection: replacement rejected/ ,
);
diagnostics . stop ();
});
test ( "continues independent read-only stages, then rejects the aggregate run" , async () => {
const diagnostics = {
consumeFatalSignals : jest . fn (),
stageCompleted : jest . fn (),
stageFailed : jest . fn (),
stageStarted : jest . fn (),
};
const laterStage = jest . fn (). mockResolvedValue ( "healthy" );
let aggregate ;
try {
await runIndependentLoggedStages ( diagnostics , [
{
action : async () => {
throw new Error ( "first failed" );
},
name : "first" ,
},
{ action : laterStage , name : "second" },
]);
} catch ( error ) {
aggregate = error ;
}
expect ( aggregate ). toBeInstanceOf ( AggregateError );
expect ( aggregate . message ). toBe ( "1 of 2 independent live read-only stages failed." );
expect ( aggregate . stageResults ). toEqual ([
expect . objectContaining ({ error : expect . objectContaining ({ message : "first failed" }), name : "first" }),
{ name : "second" , result : "healthy" },
]);
expect ( laterStage ). toHaveBeenCalledTimes ( 1 );
expect ( diagnostics . stageCompleted ). toHaveBeenCalledWith ( "second" , expect . any ( Number ));
});
test ( "blocks production reactions unless this worker completed every read-only scenario" , () => {
const gate = new LiveReadOnlyGate ([ "shorts-render" , "watch-render" , "responsive-visual" ], {
allowedSkippedScenarioIds : [ "watch-render" ],
});
gate . record ( "shorts-render" , "passed" );
gate . record ( "watch-render" , "skipped" );
expect (() => gate . assertPassed ()). toThrow ( /Missing: responsive-visual; failed: none/ );
gate . record ( "responsive-visual" , "passed" );
expect (() => gate . assertPassed ()). not . toThrow ();
gate . record ( "shorts-render" , "failed" );
gate . record ( "shorts-render" , "passed" );
expect (() => gate . assertPassed ()). toThrow ( /Missing: shorts-render; failed: shorts-render/ );
const requiredSkip = new LiveReadOnlyGate ([ "shorts-render" ]);
requiredSkip . record ( "shorts-render" , "skipped" );
expect (() => requiredSkip . assertPassed ()). toThrow ( /failed: shorts-render/ );
});
test ( "a fresh worker cannot inherit read-only gate success from a previous worker" , () => {
const firstWorker = new LiveReadOnlyGate ([ "shorts-render" ]);
firstWorker . record ( "shorts-render" , "passed" );
expect (() => firstWorker . assertPassed ()). not . toThrow ();
const restartedWorker = new LiveReadOnlyGate ([ "shorts-render" ]);
expect (() => restartedWorker . assertPassed ()). toThrow ( /Missing: shorts-render/ );
});
2026-09-01 23:41:28 +02:00
test ( "redacts identity and proof material while retaining diagnostic video IDs" , () => {
expect (
diagnosticApiUrl (
"https://returnyoutubedislikeapi.com/puzzle/registration?userId=private&videoId=abcdefghijk&solution=secret" ,
),
). toEqual ({
pathname : "/puzzle/registration" ,
query : { solution : "<redacted>" , userId : "<redacted>" , videoId : "abcdefghijk" },
});
});
});