feat: add OpenRouter audit generation pipeline
This commit is contained in:
@@ -360,7 +360,8 @@ test("website enrichment action prepares Chromium AL2023 shared libraries for Co
|
||||
);
|
||||
|
||||
const executableIndex = actionSource.indexOf(
|
||||
"const executablePath = await resolveChromiumExecutablePath(",
|
||||
"resolveChromiumExecutablePath(",
|
||||
actionSource.indexOf("export const processLeadEnrichment"),
|
||||
);
|
||||
const launchIndex = actionSource.indexOf("chromium.launch({");
|
||||
const hasSetupIndex = Math.max(
|
||||
@@ -381,7 +382,7 @@ test("processLeadEnrichment wraps Playwright bootstrap in protected try/catch",
|
||||
assert.equal(
|
||||
hasPattern(
|
||||
actionSource,
|
||||
/try\s*\{[\s\S]*?const \{ playwrightCore, serverlessChromium \}\s*=\s*await loadPlaywrightModules\(\);[\s\S]*?const executablePath = await resolveChromiumExecutablePath\(\s*serverlessChromium,\s*\);[\s\S]*?browser = await playwrightCore\.chromium\.launch\([\s\S]*?executablePath,[\s\S]*?desktopContext = await browser\.newContext\([\s\S]*?mobileContext = await browser\.newContext\(/,
|
||||
/try\s*\{[\s\S]*?const \{ playwrightCore, serverlessChromium \}\s*=[\s\S]*?loadPlaywrightModules\(\)[\s\S]*?const executablePath = await withActionTimeout\([\s\S]*?resolveChromiumExecutablePath\(\s*serverlessChromium\s*\)[\s\S]*?browser = await withActionTimeout\([\s\S]*?playwrightCore\.chromium\.launch\([\s\S]*?executablePath,[\s\S]*?desktopContext = await withActionTimeout\([\s\S]*?browser\.newContext\([\s\S]*?mobileContext = await withActionTimeout\([\s\S]*?browser\.newContext\(/,
|
||||
),
|
||||
true,
|
||||
"Playwright runtime bootstrap should use resolveChromiumExecutablePath() inside the action's try/catch-protected block",
|
||||
@@ -558,6 +559,77 @@ test("website enrichment enforces TASK-8 crawler limits and runtime timeboxes",
|
||||
);
|
||||
});
|
||||
|
||||
test("website enrichment guards long browser work before Convex action runtime aborts", () => {
|
||||
assert.equal(
|
||||
hasPattern(actionSource, /DEFAULT_ACTION_BUDGET_MS\s*=\s*120_000/),
|
||||
true,
|
||||
"Action should keep an overall runtime budget below the observed Convex abort window.",
|
||||
);
|
||||
assert.equal(
|
||||
hasPattern(actionSource, /TASK8_ACTION_BUDGET_MS/),
|
||||
true,
|
||||
"Action runtime budget should be configurable for manual tuning.",
|
||||
);
|
||||
assert.equal(
|
||||
hasPattern(actionSource, /function actionBudgetMs\(\)/),
|
||||
true,
|
||||
"Action should resolve a bounded runtime budget.",
|
||||
);
|
||||
assert.equal(
|
||||
hasPattern(actionSource, /function remainingActionBudgetMs\(/),
|
||||
true,
|
||||
"Action should calculate remaining runtime before long awaits.",
|
||||
);
|
||||
assert.equal(
|
||||
hasPattern(actionSource, /async function withActionTimeout/),
|
||||
true,
|
||||
"Action should wrap long promises so JS catch runs before Convex kills the runtime.",
|
||||
);
|
||||
|
||||
const processBody = extractExportSource(actionSource, "processLeadEnrichment");
|
||||
assert.equal(
|
||||
hasPattern(processBody, /const actionStartedAt = Date\.now\(\)/),
|
||||
true,
|
||||
"processLeadEnrichment should track action start time.",
|
||||
);
|
||||
assert.equal(
|
||||
hasPattern(processBody, /const actionBudget = actionBudgetMs\(\)/),
|
||||
true,
|
||||
"processLeadEnrichment should resolve the action budget once.",
|
||||
);
|
||||
|
||||
const guardedPatterns = [
|
||||
/withActionTimeout\([\s\S]*loadPlaywrightModules\(\)/,
|
||||
/withActionTimeout\([\s\S]*resolveChromiumExecutablePath\(/,
|
||||
/withActionTimeout\([\s\S]*prepareChromiumSharedLibraries\(/,
|
||||
/withActionTimeout\([\s\S]*playwrightCore\.chromium\.launch\(/,
|
||||
/withActionTimeout\([\s\S]*crawlPage\(\s*desktopContext,\s*rootUrl/,
|
||||
/withActionTimeout\([\s\S]*captureHomepageScreenshot\(/,
|
||||
];
|
||||
|
||||
for (const pattern of guardedPatterns) {
|
||||
assert.equal(
|
||||
hasPattern(processBody, pattern),
|
||||
true,
|
||||
`Expected long await to be guarded by withActionTimeout: ${pattern}`,
|
||||
);
|
||||
}
|
||||
|
||||
assert.equal(
|
||||
hasPattern(processBody, /Math\.min\(\s*timeoutMs,\s*remainingActionBudgetMs\(/),
|
||||
true,
|
||||
"Per-page crawl timeout should be capped by remaining action budget.",
|
||||
);
|
||||
assert.equal(
|
||||
hasPattern(
|
||||
processBody,
|
||||
/desktopContext\.request\.get\([\s\S]*timeout:\s*Math\.min\([\s\S]*remainingActionBudgetMs\(/,
|
||||
),
|
||||
true,
|
||||
"Internal link checks should cap request timeouts by remaining action budget.",
|
||||
);
|
||||
});
|
||||
|
||||
test("processLeadEnrichment schedules PageSpeed audit jobs after successful enrichment", () => {
|
||||
const processBody = extractExportSource(actionSource, "processLeadEnrichment");
|
||||
const persistIndex = processBody.indexOf(
|
||||
|
||||
Reference in New Issue
Block a user