@taprun/from-playwright

Stable identifier for the @taprun/from-playwright adapter. Every plan compiled from a Playwright source carries compiled_by metadata 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).

What this adapter does

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.

Install

npm install @taprun/from-playwright@^1 @taprun/spec@^1

Sample plan produced

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.