Core Concepts
Core Concepts
Understanding these concepts will help you write effective automation scripts.
Steps
A step is a single unit of work in your automation script.
.step('Click the button', async (ctx) => { await ctx.page.click('button.submit');})Each step:
- Has a name for identification and logging
- Receives a context (
ctx) with page access and utilities - Can be configured with options like timeout and retries
- Is executed sequentially
Step Options
.step('Slow operation', async (ctx) => { // ...}, { timeout: 30000, // Custom timeout critical: true, // Fail script if this fails retry: { times: 3, // Retry up to 3 times delay: 1000, // Wait 1 second between retries backoff: 'exponential' }})Checkpoints
A checkpoint groups related steps together.
.checkpoint('Login Flow', { required: true, maxRetries: 2 }) .step('Enter username', ...) .step('Enter password', ...) .step('Click login', ...).endCheckpoint()Checkpoints provide:
- Logical grouping - Organize related steps
- Checkpoint-level retries - Retry all steps if any fail
- Required vs optional - Required checkpoints fail the script if they fail
- Clean failure boundaries - Easier debugging and reporting
Context
The context (ctx) is passed to every step and provides:
.step('Example', async (ctx) => { // Page access await ctx.page.goto('https://example.com');
// Logging ctx.log('Something happened');
// Data access ctx.data.myValue = 'stored'; console.log(ctx.data.existingValue);
// Screenshots const path = await ctx.screenshot('my-screenshot');
// Configuration access console.log(ctx.config.headless);})Data
Data is shared state that persists across steps.
Stepwright.create<{ username: string; token?: string }>('My Script') .data({ username: 'testuser' })
.step('Login', async (ctx) => { // Read initial data await ctx.page.fill('#user', ctx.data.username);
// Store new data ctx.data.token = await getToken(); })
.step('Use token', async (ctx) => { // Access previously stored data console.log('Token:', ctx.data.token); })Data is:
- Type-safe - Define your data shape with TypeScript
- Mutable - Steps can read and write
- Included in results - Available after script completes
Configuration
Configuration controls script behavior:
.config({ // Browser headless: true, defaultTimeout: 30000,
// Artifacts screenshotOnFailure: true, domOnFailure: true, artifactDir: './artifacts',
// Reporting verbose: true,})See Configuration Reference for all options.
Failure Cases
When a script fails, Stepwright can generate a failure case:
import { generateFailureCase } from '@korvol/stepwright';
const result = await script.run();
if (!result.success && result.failedStep) { const failureCase = generateFailureCase(result, { scriptInfo: { name: 'My Script', path: 'scripts/my-script.ts', }, }); // Save to file or database for Fixwright}A failure case contains:
- Script information
- Error details and stack trace
- Source code location
- Artifact paths (screenshots, DOM, console logs)
Fixwright Integration
Fixwright consumes failure cases and attempts to fix them:
import { FixWright } from '@korvol/fixwright';
const fixwright = new FixWright({ ai: { apiKey: process.env.ANTHROPIC_API_KEY! },});
fixwright.useFileSource('./failure-cases');
fixwright.on('attempt:success', (attempt) => { console.log('Fix found:', attempt.proposedFix);});
await fixwright.start();The fix loop:
- Receives a failure case
- Analyzes with Claude AI
- Proposes a code fix
- Validates by re-running the script
- Creates a PR if successful
Next Steps
- Stepwright Overview - Deep dive into Stepwright
- Fixwright Overview - Learn about AI fixing
- Guides - Practical how-to guides