Skip to content

Recipes (Jest)

Every Vitest recipe has a Jest equivalent in apps/jest-example. The generated output is identical across frameworks — only the test code differs.

You use native describe / it and the story object: call story.init() at the start of each test (no task argument; Jest gets the test name from expect.getState()), then story.given, story.when, story.then (and story.and, story.but). Jest also exports top-level given, when, then, and, but helpers.

Vitest Jest
Init story.init(task) story.init()
Import import { story } from 'executable-stories-vitest' import { story } from 'executable-stories-jest'
Setup none setupFilesAfterEnv: ['executable-stories-jest/setup']
Top-level helpers not exported (no then) given, when, then, and, but exported
### User logs in successfully
- **Given** the user account exists
- **And** the user is on the login page
- **And** the account is active
- **When** the user submits valid credentials
- **Then** the user should see the dashboard
import { expect } from '@jest/globals';
import { story } from 'executable-stories-jest';
describe('Login', () => {
it('User logs in successfully', () => {
story.init();
story.given('the user account exists');
story.given('the user is on the login page');
story.given('the account is active');
story.when('the user submits valid credentials');
story.then('the user should see the dashboard');
expect(true).toBe(true); // or real assertions
});
});

Example: Login blocked for suspended user (with But)

Section titled “Example: Login blocked for suspended user (with But)”
import { story } from 'executable-stories-jest';
describe('Login', () => {
it('Login blocked for suspended user', () => {
story.init();
story.given('the user account exists');
story.given('the account is suspended');
story.when('the user submits valid credentials');
story.then('the user should see an error message');
story.but('the user should not be logged in');
});
});

Example: Bulk user creation (with doc.table)

Section titled “Example: Bulk user creation (with doc.table)”
import { story } from 'executable-stories-jest';
describe('Users', () => {
it('Bulk user creation', () => {
story.init();
story.given('the following users exist');
story.table({
label: 'Users',
columns: ['email', 'role', 'status'],
rows: [
['[email protected]', 'admin', 'active'],
['[email protected]', 'user', 'active'],
['[email protected]', 'user', 'locked'],
],
});
story.when('the admin opens the user list');
story.then('the user list should include');
story.table({
label: 'Expected',
columns: ['email', 'role', 'status'],
rows: [
['[email protected]', 'admin', 'active'],
['[email protected]', 'user', 'active'],
['[email protected]', 'user', 'locked'],
],
});
});
});

The same 32 scenarios as Vitest recipes are in apps/jest-example/src/replicate.story.test.ts. Generated docs: apps/jest-example/src/replicate.story.docs.md.

Scenario Pattern See Vitest recipe
User logs in successfully Multiple Given, single When, single Then Link
User updates profile details Single Given, multiple When, single Then Link
Checkout calculates totals Single Given, single When, multiple Then Link
Password reset flow Multiple Given/When/Then Link
Login blocked for suspended user Use of But Link
Login works (tags) Story tags Link
Login errors (outline) Scenario outline with loop Link
Many login attempts (outline) Scenario outline, multiple outcomes Link
Bulk user creation doc.table Link
Create users from table Scenario outline with doc.table Link
Calculate shipping options DataTable, multiple Then Link
Shipping eligibility Scenario outline by country Link
Tax calculation by region Scenario outline with multiple rows Link
API accepts JSON payload doc.json (DocString) Link
Post JSON payload (outline) Scenario outline with doc.json Link
Import XML invoice doc.code (XML) Link
Import users + welcome email doc.table + doc.code Link
Render markdown doc.code (markdown) Link
Change email address Shared background Link
Change password Shared background, different When/Then Link
Eligible customer gets discount Rule block, positive path Link
Ineligible customer no discount Rule block, negative path Link
Two step checkout Multiple When groups Link
Payment declined Negative path with But Link
Guest checkout allowed doc.note for But Link
Logout clears session Repeated Then steps Link
Document status changes Explicit state transition Link
Update preferences DataTable as key-value pairs Link
Configure feature flags Complex DataTable Link
Create order Background and tags Link
Search results show highlights And after Then Link
Report shows fields in order And in middle of Then Link

Jest story & doc API — steps and doc usage.