Stable identifier for the
@taprun/from-playwrightadapter. Every plan compiled from a Playwright source carriescompiled_bymetadata so consumers can dereference the producer.
Part of the Capture plane — one of Tap’s three primitive planes (Capture / Replay / Verify). Bumped to v1.0 for the v2 schema break (see Migration guide).
Convert Playwright tests into local-first bare v2 Plans, no rewrite. Maps the deterministic page-level APIs (page.goto, .click, .fill, .type, .press, .waitForSelector, .waitForTimeout) to the 11-op v2 closure. Lifecycle calls (browser.launch / close) silently dropped. Anything outside the deterministic surface either throws under strict: true or becomes a typed op:eval with the original line preserved as a comment for human follow-up — never free-form JS.
npm install @taprun/from-playwright@^1 @taprun/spec@^1
A read tap:
{
"id": { "site": "github", "name": "trending" },
"observe": [
{ "op": "nav", "url": "https://github.com/trending" },
{ "op": "wait", "selector": "article.Box-row" }
],
"return": "$.observe[1]"
}
A write tap (login flow):
{
"id": { "site": "example", "name": "login" },
"args": { "password": { "type": "string", "required": true } },
"key": "$.args.password",
"observe": [
{ "op": "nav", "url": "https://app.example.com/login" }
],
"act": [
{ "op": "input", "kind": "fill", "target": "#email", "value": "alice@example.com" },
{ "op": "input", "kind": "fill", "target": "#password", "value": "" },
{ "op": "input", "kind": "click", "target": "button[type='submit']" }
],
"confirm": [
{ "op": "wait", "selector": ".dashboard", "timeout_ms": 5000 }
],
"return": "$.confirm[0]"
}
The output is a bare Plan — no @context, no W3C wrapper, no body. The discriminated union (read vs write) is encoded at the type level: a write tap that omits key fails compilation in @taprun/spec.
Plan reference@taprun/from-puppeteer@taprun/from-stagehand — deprecated; see migration guide for alternative