feat(scenario): dump page screenshot and HTML to run files on step failure
Captures a full-page screenshot and the current page HTML whenever a scenario or snippet step fails, and uploads both as run artifacts so failures can be diagnosed from the run's file list. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
69d16c9a94
commit
47529b2c1e
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "liqa",
|
"name": "liqa",
|
||||||
"version": "1.11.0",
|
"version": "1.12.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"server",
|
"server",
|
||||||
|
|||||||
@@ -515,6 +515,8 @@ export class ScenarioSchedulerService implements OnModuleInit {
|
|||||||
`Step ${(stepRun.scenarioStep as ScenarioStepEntity | undefined)?.order ?? "?"} failed: ${description}`,
|
`Step ${(stepRun.scenarioStep as ScenarioStepEntity | undefined)?.order ?? "?"} failed: ${description}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await this.dumpPageOnFailure(stepRun);
|
||||||
|
|
||||||
// Cancel all remaining waiting/pending step runs in this run
|
// Cancel all remaining waiting/pending step runs in this run
|
||||||
await this.runStepRepo
|
await this.runStepRepo
|
||||||
.createQueryBuilder()
|
.createQueryBuilder()
|
||||||
@@ -534,4 +536,51 @@ export class ScenarioSchedulerService implements OnModuleInit {
|
|||||||
await this.runRepo.update(stepRun.runId, { status: "fail" });
|
await this.runRepo.update(stepRun.runId, { status: "fail" });
|
||||||
this.logger.log(`Run #${stepRun.runId} → fail`);
|
this.logger.log(`Run #${stepRun.runId} → fail`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Page dump on failure ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
private async dumpPageOnFailure(
|
||||||
|
stepRun: ScenarioRunStepEntity,
|
||||||
|
): Promise<void> {
|
||||||
|
const handle = this.runBrowsers.get(stepRun.runId);
|
||||||
|
if (!handle) return; // no browser was ever opened for this run (e.g. setup error)
|
||||||
|
|
||||||
|
const step = stepRun.scenarioStep as ScenarioStepEntity | undefined;
|
||||||
|
const namePrefix = `step-${step?.order ?? stepRun.id}-failure`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const screenshot = await handle.page.screenshot({ fullPage: true });
|
||||||
|
await this.fileStorageService.createAndSaveRunArtifact(
|
||||||
|
stepRun.runId,
|
||||||
|
screenshot,
|
||||||
|
`${namePrefix}.png`,
|
||||||
|
"image/png",
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.warn(
|
||||||
|
`StepRun #${stepRun.id}: failed to capture failure screenshot — ${(err as Error).message}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const html = await handle.page.content();
|
||||||
|
await this.fileStorageService.createAndSaveRunArtifact(
|
||||||
|
stepRun.runId,
|
||||||
|
Buffer.from(html, "utf-8"),
|
||||||
|
`${namePrefix}.html`,
|
||||||
|
"text/html",
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.warn(
|
||||||
|
`StepRun #${stepRun.id}: failed to capture failure page HTML — ${(err as Error).message}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.persistLog(
|
||||||
|
stepRun.runId,
|
||||||
|
stepRun.id,
|
||||||
|
"log",
|
||||||
|
`Step ${step?.order ?? "?"} failed: page dump uploaded to run files`,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user