Docs Playwright Migration Guide

Migrating from Playwright to Mockarty

You already write browser tests in Playwright. Mockarty gives you the same
end-to-end power — record → get ready code → edit → run in a real browser →
read the report
— but with two things Playwright alone doesn’t give you:

  1. You don’t need the Playwright inspector or codegen CLI. Record a flow
    right in your browser with the Mockarty Capture extension, then get a
    ready-to-commit test in your language — TypeScript (Playwright-compatible),
    Go, Python, or Java.
  2. The run is unified with the rest of your testing. The same browser test
    lands in the same report as your API, load, fuzz, and contract runs, with
    per-step screenshots, video, a time-travel trace, and visual regression.

TL;DR

You do this in Playwright You do this in Mockarty
npx playwright codegen opens a browser + inspector Click Record in the Mockarty Capture extension, drive your app normally
Copy the generated *.spec.ts out of the inspector The recording is saved as a UI test; export it as .spec.ts, Go, Python, or Java
npx playwright test (needs Node + browsers on every machine) Run it on a browser-runner — one shared runner replays for the whole team; nothing to install locally
Trace viewer via playwright show-trace Same trace, plus video + per-step screenshots, in the run report — no CLI
Results live in playwright-report/ Results live in your test report alongside API/load/fuzz/contract runs

Nothing about your Playwright knowledge is thrown away: Mockarty records
Playwright-style locators (#id, [data-testid='x'], role=button[name='x'],
text="Sign in") and the exported TypeScript is a plain @playwright/test
file you can run with your existing Playwright install if you want to.

The workflow

1. Record (no inspector)

Install the Mockarty Capture Chrome extension, open Record UI, and use
your app. The extension captures clicks, typing, navigation, selects, key
presses, drag-and-drop, and file uploads, choosing a stable locator for each
(text → role → data-testid → id → CSS, in that priority). Assertions can be
added as you go.

You can also record without the extension — start a live session over the API
and drive it (see Browser & Mobile UI Testing).

2. Get ready code in your language

Every recording is a UI test. Export it in the format you want:

# CLI
mockarty ui list
mockarty ui export <ui-test-id> --lang playwright   # .spec.ts
mockarty ui export <ui-test-id> --lang go           # Go SDK
mockarty ui export <ui-test-id> --lang python       # Python SDK
mockarty ui export <ui-test-id> --lang java         # Java SDK

The same is available over REST
(GET /api/v1/ui-tests/{id}/export?format=playwright|go|python|java|appium)
and from the AI agent (the ui_test_export tool).

Playwright TypeScript — a plain @playwright/test file, runnable as-is:

import { test, expect } from '@playwright/test';

test('Login flow', async ({ page }) => {
  await page.goto('https://app.example.com/login');
  await page.locator('#email').fill('user@example.com');
  await page.locator('#pw').fill('secret');
  await page.locator('#login').click();
  await expect(page.locator('#welcome')).toContainText('Welcome');
});

Or the same flow as SDK code you commit next to your other tests — here in
Python:

from mockarty import UITest


def login_flow() -> UITest:
    """Mockarty UI test generated from a recording."""
    return (
        UITest("Login flow")
        .navigate("https://app.example.com/login")
        .fill("#email", "user@example.com")
        .fill("#pw", "secret")
        .click("#login")
        .assert_text("#welcome", "Welcome")
    )

Go and Java produce the same flow with an idiomatic builder
(mockarty.NewUITest(...), UITestBuilder.named(...)).

3. Edit and copy into your codebase

The exported code is the source of truth — edit the steps directly (rename,
reorder, tighten a locator, add an assertion) and commit it next to your app.
No inspector round-trip: the SDK builder reconstructs exactly the same recorded
step list that Mockarty runs, so what you commit is what executes.

4. Run it — in a real browser, no local install

Save and run the test through the SDK; it executes on a browser-runner
(real Chromium, Firefox, or WebKit, driven by Playwright), and the result flows
into your report:

from mockarty import MockartyClient

client = MockartyClient(base_url="http://localhost:5770", api_key="mk_...")

saved = client.ui_tests.create(login_flow())
run = client.ui_tests.run(saved["id"])                 # dispatch to a runner
result = client.ui_tests.wait_for_run(run["taskId"])   # poll to a verdict
print(result["status"])                                # passed | failed | broken

You don’t install Node or browsers on every laptop and CI agent — one
browser-runner replays for the whole team. See
Run UI tests in your own browser to stand one up (it’s a
single binary, or the mcr.microsoft.com/playwright-based container image).

Locator mapping

Mockarty records the same locator families Playwright uses, so there is nothing
to translate:

Playwright Mockarty recorded locator
page.locator('#id') #id (css)
page.getByTestId('x') [data-testid='x']
page.getByRole('button', { name: 'Save' }) role=button[name='Save']
page.getByText('Sign in') text="Sign in"
page.getByPlaceholder('Email') placeholder locator
structural CSS path structural CSS path

If a locator drifts, Mockarty’s replay self-heals using the alternate
locators captured for the same element and reports which one it fell back to —
so a renamed class doesn’t silently red your whole suite.

Action & assertion mapping

Playwright Mockarty step
page.goto(url) navigate
.click() / .dblclick() click / doubleClick
.fill(v) / .type(v) fill / type
.selectOption(v) select
.check() / .uncheck() check / uncheck
.hover() hover
.press(key) press
.setInputFiles(f) upload / setInputFiles
.dragTo(target) dragAndDrop
expect(l).toContainText(t) assertText
expect(l).toBeVisible() / toBeHidden() assertVisible / assertHidden
expect(l).toHaveValue(v) assertValue
expect(l).toHaveCount(n) assertCount
expect(page).toHaveURL(u) assertURL
expect(page).toHaveTitle(t) assertTitle
expect(l).toBeEnabled() / toBeDisabled() assertEnabled / assertDisabled
expect(l).toBeChecked() assertChecked
expect(l).toHaveScreenshot() visual checkpoint (see below)

Config & fixtures → environment variables

Playwright’s use: { baseURL } and fixtures that inject data become
environment variables on the run. Reference {{name}} in a navigate URL or
a fill value, and pass values at run time:

run = client.ui_tests.run(saved["id"], {
    "envVars": {"BASE_URL": "https://staging.example.com"},
    "browser": "firefox",          # chromium | firefox | webkit
    "viewport": "1280x800",
})

baseURL → an env var you substitute; projects: [{ browserName }] → the
browser option per run; viewport → the viewport option. Storage-state
(logged-in cookies) is supported too — save an authenticated state once and
replay from it (the “log in once, run for a month” flow).

What Playwright has that maps 1:1

  • Trace — RecordTrace per run produces a trace.zip you open with
    playwright show-trace, offered as a download in the report.
  • Video — RecordVideo records the whole replay.
  • Screenshots — per-step, on failure or every step (screenshotMode).
  • Visual regression — a per-step or whole-run screenshot diff against a
    baseline (toHaveScreenshot()’s equivalent), with inline approve in the
    report.
  • Cross-browser — run the same test on Chromium, Firefox, and WebKit.

Why not just keep running Playwright?

Keep it if it works for you — the exported .spec.ts runs on your existing
Playwright install unchanged. You reach for Mockarty when you want: recording
without the inspector, tests in Go/Python/Java (not only TypeScript), a shared
runner instead of Node-on-every-machine, and one report for browser + API +
load + fuzz + contract tests instead of a separate playwright-report/ silo.