Fluent API
Chain steps together for readable, self-documenting scripts
Stepwright is a fluent API wrapper for Playwright that makes browser automation scripts more readable, maintainable, and resilient.
While Playwright is a powerful browser automation library, complex scripts can become difficult to read and maintain. Stepwright addresses this with:
Fluent API
Chain steps together for readable, self-documenting scripts
Checkpoints
Group related steps with automatic retry on failure
Data Management
Type-safe data passing between steps
Artifact Capture
Automatic screenshots and DOM capture on failure
import { Stepwright } from '@korvol/stepwright';
const script = Stepwright.create('Login Flow') .config({ headless: false, screenshotOnFailure: true, })
.checkpoint('Login') .step('Navigate to login', async (ctx) => { await ctx.page.goto('https://app.example.com/login'); }) .step('Enter credentials', async (ctx) => { await ctx.page.fill('#email', 'user@example.com'); await ctx.page.fill('#password', 'password123'); }) .step('Submit form', async (ctx) => { await ctx.page.click('button[type="submit"]'); await ctx.page.waitForURL('**/dashboard'); }) .endCheckpoint()
.checkpoint('Verify Dashboard') .step('Check welcome message', async (ctx) => { const welcome = ctx.page.locator('h1'); await expect(welcome).toContainText('Welcome'); }) .endCheckpoint();
const result = await script.run();console.log('Success:', result.success);Chain methods together to build readable scripts:
Stepwright.create('My Script') .config({ headless: true }) .data({ userId: '123' }) .checkpoint('Setup') .step('Step 1', ...) .step('Step 2', ...) .endCheckpoint() .run();Each step runs sequentially with full error handling:
Group related steps into checkpoints for intelligent retry:
.checkpoint('Login', { maxRetries: 2 }) .step('Fill form', ...) .step('Submit', ...).endCheckpoint()If any step in a checkpoint fails, the entire checkpoint retries from the beginning.
Pass data between steps with full TypeScript support:
interface MyData { username: string; token?: string;}
Stepwright.create<MyData>('My Script') .data({ username: 'testuser' }) .step('Get token', async (ctx) => { ctx.data.token = await fetchToken(); });┌─────────────────────────────────────────────────────────────────┐│ Stepwright │├─────────────────────────────────────────────────────────────────┤│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ Config │ │ Data │ │ Steps │ │Reporters │ ││ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │├─────────────────────────────────────────────────────────────────┤│ TaskQueue (Execution) │├─────────────────────────────────────────────────────────────────┤│ ┌─────────────────┐ ┌─────────────────────────────────┐ ││ │ Checkpoints │ │ Background Tasks │ ││ └─────────────────┘ └─────────────────────────────────┘ │├─────────────────────────────────────────────────────────────────┤│ Playwright (Browser) │└─────────────────────────────────────────────────────────────────┘Use Stepwright when:
Consider vanilla Playwright when: