Skip to content

Record from clicks

The blank page is the hardest part of authoring tests. Record-from-clicks removes it: record yourself clicking through a flow, and Tripwire turns that recorded trace into a plain-English Tripwire suite you can run, edit, and check into the suite repo.

The idea

A recorder — Playwright codegen, a browser extension, or a devtools hook — emits an ordered list of low-level actions. Tripwire's record engine humanizes them into a Tripwire suite: each interaction becomes a natural-language step, and each recorded assertion becomes an expect entry.

json
[
  { "type": "goto",   "url": "/login" },
  { "type": "fill",   "selector": "#email", "value": "a@b.test" },
  { "type": "fill",   "selector": "#password", "value": "hunter2" },
  { "type": "click",  "selector": "button[type=submit]" },
  { "type": "assert", "text": "Welcome back" },
  { "type": "assert", "url": "/account" }
]

becomes:

yaml
suite: "Recorded flow"
id: recorded-flow
base_url: https://app.example.com
cases:
  - id: recorded-flow
    title: "Recorded flow"
    tags: [recorded]
    steps:
      - { id: s1, do: "Go to /login" }
      - { id: s2, do: "Type 'a@b.test' into the email field" }
      - { id: s3, do: "Type 'hunter2' into the password field" }
      - { id: s4, do: "Click the submit button" }
    expect:
      - { id: a1, assert: "the text 'Welcome back' is visible",
          check: { kind: visible_text, contains: "Welcome back" } }
      - { id: a2, assert: "the URL path is /account",
          check: { kind: url, path_is: "/account" } }

How the conversion works

  • Step typesgoto, fill, click, select, press, check, upload — become plain-English steps. Tripwire derives a human label for each target from its selector (#email → "the email field", button[type=submit] → "the submit button").
  • assert actions become expectations: an assert with url → a url check, an assert with text → a visible_text check. Recorded flows therefore arrive with deterministic checks already wired up.
  • Humanizing the language is optional and additive: with an Anthropic client, Claude rewrites the literal steps into natural tester language (same count, same order, concrete values preserved). Without a client — or if the call fails — a deterministic fallback maps each action to English directly. The structure and expectations are always deterministic.

The result is canonical Tripwire YAML (via the same serializer the generator uses), so a recorded suite drops straight into the suite repo and runs like any other.

One-click recorder

The dashboard's Record tab is a true recorder: click it, a real browser opens at your app, you click and type through the flow you care about, then hit Stop — Tripwire captures every action and converts it to a plain-English suite. No JSON, no Playwright knowledge.

Under the hood (backend/app/engine/recorder.py) a session owns a headed Chromium, injects a recorder script that reports each click / input / select / navigation, and on stop hands the trace to the same pure converter below. Endpoints: /record/start/record/sessions/{id}/record/stop.

Convert a trace you already have

The conversion core is a pure, unit-tested engine capability (backend/app/engine/record.pyactions_to_suite, action_to_step, action_to_expect; no browser, no model required) exposed at POST /record/convert. Feed it a recorded action trace (e.g. adapted from Playwright codegen) and get back ready-to-run YAML.

Record vs. generate

URL → generateRecord from clicks
InputA URLA recorded interaction trace
CoverageThe flows it can infer from the pageExactly the flow you performed
Best for"I have an app, zero tests""I know the exact journey I care about"

Use generate for breadth, record for the precise flow you just clicked through. Both emit the same Tripwire YAML.

Related: URL → test generation · Writing Tests

Tripwire — AI-native, self-healing E2E testing. Terms · Privacy · Legal Notice