Skip to content

Artifacts

Artifacts

Stepwright can capture various artifacts during script execution for debugging and analysis. These artifacts are essential for Fixwright to analyze failures.

Automatic Capture on Failure

Configuration

Enable automatic artifact capture:

Stepwright.create('My Script')
.config({
screenshotOnFailure: true, // Capture screenshot when step fails
domOnFailure: true, // Capture DOM when step fails
artifactDir: './artifacts', // Output directory
})

What Gets Captured

When a step fails, Stepwright automatically captures:

ArtifactDescription
ScreenshotFull page screenshot (PNG)
DOMHTML snapshot of the page
Console logsBrowser console messages
URLCurrent page URL
TitleCurrent page title

Accessing Artifacts

Artifacts are available in the result:

const result = await script.run();
if (!result.success && result.failedStep) {
const { artifacts } = result.failedStep;
console.log('Screenshot:', artifacts.screenshot);
console.log('DOM:', artifacts.dom);
console.log('Console logs:', artifacts.console);
console.log('URL:', artifacts.url);
console.log('Title:', artifacts.title);
}

Manual Capture

Screenshots

Capture screenshots at any point:

.step('Take screenshot', async (ctx) => {
// Capture current state
const path = await ctx.screenshot('after-login');
console.log('Screenshot saved to:', path);
})

Screenshot names are automatically prefixed with step information:

artifacts/
├── step-001-Navigate-after-login.png
├── step-002-FillForm-form-complete.png
└── step-003-Submit-failure.png

DOM Snapshots

Get the current DOM as a string:

.step('Capture DOM', async (ctx) => {
// Get full page DOM
const fullDom = await ctx.getDOM();
// Get specific element DOM
const formDom = await ctx.getDOM('#signup-form');
console.log('Form HTML:', formDom);
})

Console Logs

Collect console messages:

import { ConsoleCollector } from '@korvol/stepwright';
// Manual collection
const collector = new ConsoleCollector();
collector.start(page);
// ... run steps ...
const logs = collector.stop();
console.log('Console messages:', logs);

Video Recording

Enable Video

Record video of the entire script execution:

.config({
video: {
enabled: true,
dir: './videos',
size: { width: 1280, height: 720 },
},
})

Or use the shorthand:

.video(true)

Access Video Path

const result = await script.run();
if (result.video) {
console.log('Video saved to:', result.video);
}

Artifact Directory Structure

Default structure:

.stepwright/artifacts/
├── run-2024-01-15T10-30-00/
│ ├── step-001-Navigate.png
│ ├── step-001-Navigate.html
│ ├── step-002-Login-failure.png
│ ├── step-002-Login-failure.html
│ ├── step-002-Login-console.log
│ └── video.webm

Custom Directory

.config({
artifactDir: './my-custom-artifacts',
})

Capture Functions

Low-Level API

For advanced use cases, use the capture functions directly:

import {
captureScreenshot,
captureDOM,
ConsoleCollector,
} from '@korvol/stepwright';
// Capture screenshot
const screenshotPath = await captureScreenshot(page, {
dir: './artifacts',
baseName: 'my-screenshot',
});
// Capture DOM
const domPath = await captureDOM(page, {
dir: './artifacts',
baseName: 'my-dom',
selector: '#specific-element', // Optional
});
// Collect console logs
const collector = new ConsoleCollector();
collector.start(page);
// ... interact with page ...
const logPath = collector.saveToFile('./artifacts/console.log');

Capture Options

interface CaptureOptions {
/** Directory to save artifacts */
dir: string;
/** Base name for artifact files */
baseName: string;
/** Specific selector to capture (DOM only) */
selector?: string;
/** Full page screenshot */
fullPage?: boolean;
}

Failure Cases

Generating Failure Cases

Failure cases bundle all artifacts for Fixwright:

import { generateFailureCase } from '@korvol/stepwright';
const result = await script.run();
if (!result.success && result.failedStep) {
const failureCase = generateFailureCase(result, {
scriptInfo: {
name: 'Login Test',
path: 'scripts/login.ts',
},
repository: {
url: 'https://github.com/org/repo',
branch: 'main',
},
});
// Save for Fixwright
await fs.writeFile(
'./failure-cases/login-failure.json',
JSON.stringify(failureCase, null, 2)
);
}

Failure Case Structure

interface FailureCase {
id: string;
status: 'pending' | 'processing' | 'fixed' | 'unfixable';
timestamp: string;
script: {
name: string;
path: string;
repository?: {
url: string;
branch: string;
};
};
failure: {
step: string;
checkpoint?: string;
error: {
message: string;
stack?: string;
};
artifacts: {
screenshot?: string;
dom?: string;
console?: string;
};
url?: string;
title?: string;
};
sourceCode?: {
content: string;
lineNumber: number;
context: string[];
};
}

Best Practices

Always Enable on Failure Capture

// Always enable in production scripts
.config({
screenshotOnFailure: true,
domOnFailure: true,
})

Clean Up Old Artifacts

// Add to CI cleanup
import { rm } from 'fs/promises';
await rm('.stepwright/artifacts', { recursive: true, force: true });

Include Context in Names

.step('Verify dashboard', async (ctx) => {
// Include relevant context in screenshot names
await ctx.screenshot(`user-${ctx.data.userId}-dashboard`);
})

Don’t Capture Sensitive Data

// Clear sensitive fields before capturing
.step('Login', async (ctx) => {
await ctx.page.fill('#password', ctx.data.password);
// Clear password before any screenshots
await ctx.page.fill('#password', '********');
await ctx.screenshot('login-form');
})

Next Steps