| name | open-testing-convert-testersai-recorder |
| description | Convert Testers.AI Recorder output (JSON with `test_steps[]` AND parallel `recordedActions[]` where `recordedActions[i].naturalStep === test_steps[i]`) to and from Selenium, Playwright, Cypress, Appium, Cucumber, Eggplant (SenseTalk), OpenTest.AI, and Testers.AI Dynamic. Handles browser-captured flows with deterministic selector hints (CSS/XPath/accessibility), recorded input values, and AI-collapsed assertion steps. Use whenever the user wants to migrate a Recorder suite, replay a recorded flow in code, or round-trip through another framework. MANDATORY TRIGGERS — "convert Recorder", "Testers.AI Recorder to <target>", "recorded actions to code", "migrate recorded test", "replay recorded flow", "convert recorded browser test", "Testers.AI capture to Selenium", "recorded test to Playwright", any mention of Testers.AI Recorder alongside any supported target. |
| license | MIT |
| metadata | {"family":"open-testing-convert","source":"testersai-recorder","orchestrator":"open-testing-convert","targets":["selenium","playwright","cypress","appium","cucumber","eggplant","opentestai","testersai-dynamic"]} |
Convert — Testers.AI Recorder
Converts Testers.AI Recorder captures to any supported target, and builds Recorder-format output from any source. Defers orchestration, cross-framework rules, and target semantics to the open-testing-convert master skill.
When to use
Trigger when:
- The user references a Testers.AI Recorder capture,
recordedActions, a browser-captured flow, a .recorder.json file, or the Testers.AI Recorder product.
- The user uploads JSON whose test-case objects contain both
test_steps[] and recordedActions[] (the Recorder's signature shape).
- Entries in
recordedActions[] have an action (navigate/click/input/select/check/hover/keypress/upload/ai_assert/screenshot) and a naturalStep field that matches the parallel test_steps[] entry verbatim.
selectorHints appears on recordedActions[] entries — this is the Recorder's unique selector vocabulary: {role, name}, {label}, {text}, {testId}, {css}, {xpath}, {placeholder}, {altText}, {title}, {accessibilityId} (mobile), {frameSelector} (iframes).
- The user asks to replay a recorded flow or convert recorded actions into test code.
How to use
- Read the master orchestrator first. Open
../open-testing-convert/SKILL.md.
- Read the Recorder target primer.
../open-testing-convert/reference/targets/testersai-recorder.md documents the emission shape (especially the 1:1 invariant between test_steps[i] and recordedActions[i].naturalStep).
- Verify the 1:1 invariant before extracting. If
test_steps.length !== recordedActions.length or any recordedActions[i].naturalStep !== test_steps[i], flag the file as potentially corrupted and emit a repair suggestion before proceeding.
- Read the relevant target primer for where you're going:
../open-testing-convert/reference/targets/opentestai.md
../open-testing-convert/reference/targets/testersai-dynamic.md
../open-testing-convert/reference/targets/eggplant.md
- For code targets, consult the per-source profile (
../open-testing-convert-selenium/reference/source-profile.md, etc.) for the target's canonical shape.
- Read this skill's reference files:
reference/source-profile.md — the Recorder schema, selector-hint vocabulary, 1:1 invariant details, mobile/iframe/shadow-DOM variants.
reference/extraction.md — how to turn recordedActions[] + test_steps[] into canonical intent (authoritative selector source: selectorHints; NL step is descriptive not authoritative).
reference/mappings.md — per-target cookbook.
- Read shared references as needed:
open-testing-convert/reference/shared/{locator-mapping,wait-strategies,assertion-mapping,lifecycle-mapping}.md.
- Emit per target Emission Checklist. Preamble must call out: count of tests, count of actions, count of
ai_assert entries (which require AI runtime or a locator inference on replay), any dropped/unsupported actions, iframe / shadow DOM / alert handling used.
The 1:1 invariant — core of this format
Recorder's distinctive property:
recordedActions.length === test_steps.length
recordedActions[i].naturalStep === test_steps[i] for all i
This invariant is load-bearing:
- The NL array is the human-readable view; the action array is the machine-executable view.
- Changes to either must be mirrored. Round-trip tools that edit one side without the other break replay.
- When converting to Recorder, we rebuild BOTH arrays from canonical intent, asserting the invariant holds before emitting.
selectorHints — authoritative selectors
Unlike OpenTest.AI (which leaves selector resolution to runtime) and Dynamic (which uses hints[] as probabilistic guidance), Recorder captures the actual selector observed at record time. Hints are authoritative for replay:
{
"action": "click",
"naturalStep": "Click the 'Sign in' button.",
"selectorHints": {
"role": "button",
"name": "Sign in",
"css": "button[data-test='signin']",
"xpath": "/html/body/div[2]/main/form/button[1]",
"testId": "signin-btn"
}
}
Use the strongest hint available (preference order: testId → role+name → label → text → css → xpath) when converting to code targets.
ai_assert — the one exception
ai_assert actions have selectorHints: null (or absent). These encode assertions that the recorder couldn't pin to a DOM element — "Verify the page shows 'Welcome'" is an LLM-interpreted check at replay time. When converting to non-AI targets (Selenium, Playwright, Cypress), the extractor pattern-matches the NL step against the OpenTest.AI assertion catalogue to generate a concrete assertion.
Scope
- Recorder exports for web (
.recorder.json, .recording.json, or inline JSON).
- Mobile recorder exports (with
platform: "android" | "ios" and accessibilityId selector hints).
- Single-test and multi-test files.
- Iframe-scoped actions (
frameSelector on selector hints).
- Shadow-DOM scoped actions (
shadowRootPath on selector hints).
- Alerts, confirmation dialogs, and file-upload actions.
ai_assert steps (collapsed to target-native assertions).
- Network-capture augmentation (when present as
networkContext[]) — used only as extraction hints; rarely round-tripped.
Out of scope
- Eggplant image recorder exports (use
open-testing-convert-eggplant).
- Cypress cy.recorder / Playwright codegen outputs — those have different envelopes; trigger their native source skill.
- Session replay services (Sentry, LogRocket). These are observability traces, not executable tests.
Quick reference: action → canonical
recordedActions[i].action | Canonical kind | Notes |
|---|
navigate | navigate | url on action |
click | click | selectorHints → locator |
dblclick | click with count: 2 | |
rightclick | click with button: "right" | |
input | input | value on action |
select | select | option on action |
check / uncheck | check / uncheck | |
hover | hover | |
keypress | keypress | key on action |
upload | upload | files[] on action |
screenshot | screenshot | |
ai_assert | assert | Pattern-match naturalStep for assertion_kind |
wait | wait_for | Typically time or element_visible |
drag | drag | source + target locator |
tap (mobile) | tap | Mobile-only |
swipe (mobile) | swipe | direction + from/to |
See reference/mappings.md for the full per-target cookbook.