Skip to main content

Write a spec by hand

The recording-based and scenario-based paths handle most situations. But sometimes you want to write the spec yourself — to model a complex multi-step flow precisely, to document an existing manual test, or simply to understand the format deeply before trusting the AI to fill it in.

This guide walks you through writing a spec file from scratch, validating it, and then handing it to the Generator to produce the runnable TypeScript.


The spec format

A spec is a plain Markdown file in tests/specs/<feature>/. It has two parts: a YAML frontmatter block and a body with three named sections.

For the full format reference, see Specs: the English description of a test.

Frontmatter

---
id: FEATURE-AREA-SHORT-DESCRIPTION-001
feature: project
title: 'Case: Short human-readable title'
priority: high
tags: [happy-path, feature-tag]
fixture: featurePageFixture
data:
- data.key_reference
---
FieldWhat to put here
idUnique ID in SCREAMING-KEBAB form. Use the feature area as a prefix.
featureThe PACE feature area (project, estimates, deliverables, …).
titleA short label shown in test reports.
priorityhigh, medium, or low. High-priority tests run in the smoke suite.
fixtureThe Playwright fixture that logs in and navigates to the right page. Check tests/e2e/fixtures/ for available fixtures.
dataDotted keys into tests/data/*.jsonc. Run pnpm run test:validate-data to confirm the keys exist.

Body sections

After the frontmatter, add three sections exactly as shown:

## Background

One or two sentences explaining what this test is proving and any assumptions about
the starting state (e.g. "the project already exists", "the user is logged in as a
project manager").

## Steps

1. Navigate to the Deliverables tab on project 5192
- intent: "Start on the correct tab so subsequent actions land on the right grid."
- method: `projectPage.openDeliverables(data.project_number)`
2. Click the '+New Deliverable' button
- intent: "Open the create-deliverable form."
- method: `deliverableGrid.clickNew()`
3. Fill in the deliverable number and name
- intent: "Provide the minimum required fields to enable save."
- method: `deliverableForm.fill({ number: data.deliverable.number, name: data.deliverable.name })`
4. Click 'Create and go to deliverables'
- intent: "Submit the form and return to the grid."
- method: `deliverableForm.submit()`
5. Assert the new row appears with status 'Draft'
- intent: "Confirm the server accepted the record and the UI reflects the initial status."
- method: `deliverableGrid.expectRowWithStatus(data.deliverable.name, 'Draft')`

## Expected

The deliverables grid shows the newly created row. The Status column reads 'Draft'.

Key rules for Steps:

  • One logical action or assertion per numbered item.
  • Every step must have an intent: (the why) and a method: (the page-object calls to execute).
  • If the page-object method does not exist yet, annotate it: method: [NEW: DeliverableGrid.expectRowWithStatus()]. The Generator will write the method for you.

Validate the spec

Before generating a test, run the spec validator to catch schema errors early:

pnpm run test:validate-spec

The validator checks every file in tests/specs/ against the Zod schema. It reports missing fields, wrong types, and malformed step syntax. Fix all errors before proceeding — the Generator will fail on an invalid spec.


Generate the TypeScript

Once the spec is valid, hand it to the Generator:

/generate-test

The AI will prompt you for (or infer from context) the path to your spec file. The Generator reads the spec, translates each method: line into TypeScript, writes any [NEW: …] page-object methods, and smoke-runs the result.

For the full command reference, see /generate-test.


Review and commit

After generation:

  1. Read the produced .spec.ts file in tests/e2e/<feature>/ — verify the selectors and assertions look correct.
  2. Run the test:
    pnpm run test --grep "<your spec title or id>"
  3. If the test is green, commit the spec and the generated file:
    git add tests/specs/<feature>/<name>.md \
    tests/e2e/<feature>/<name>.spec.ts
    git commit -m "test: add <description> e2e test"

Remember: edit the spec, not the generated TypeScript. If you need to change what the test does, update tests/specs/…/<name>.md and re-run /generate-test. Hand-edits to the .spec.ts file will be overwritten the next time the Generator runs.