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:
Andrii Arsenin
2026-09-16 15:52:32 +03:00
co-authored by Claude Sonnet 5
parent 69d16c9a94
commit 47529b2c1e
2 changed files with 50 additions and 1 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "liqa",
"version": "1.11.0",
"version": "1.12.0",
"private": true,
"workspaces": [
"server",
@@ -515,6 +515,8 @@ export class ScenarioSchedulerService implements OnModuleInit {
`Step ${(stepRun.scenarioStep as ScenarioStepEntity | undefined)?.order ?? "?"} failed: ${description}`,
);
await this.dumpPageOnFailure(stepRun);
// Cancel all remaining waiting/pending step runs in this run
await this.runStepRepo
.createQueryBuilder()
@@ -534,4 +536,51 @@ export class ScenarioSchedulerService implements OnModuleInit {
await this.runRepo.update(stepRun.runId, { status: "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`,
);
}
}