Skip to main content

Bindings in a plain Playwright project

The first thing to adopt is the piece that works on its own: bindings and model-free healing for an existing Playwright project. One dependency, one import, no flow language, no compiler, and no model at record time or at run time. The full worked example, timed against a ten-minute budget in CI, is examples/plain-playwright/.

1. Add the dependency

npm install --save-dev @svatah/yam-playwright-test

2. Import test from it

import { test, expect } from "@svatah/yam-playwright-test";

test("sign in", async ({ page, bind }) => {
await page.goto("/login");
await (await bind("login.username-field", "the username field")).fill("me@example.com");
await (await bind("login.password-field", "the password field")).fill("hunter2");
await (await bind("login.sign-in-button", "the sign in button")).click();
await expect(page).toHaveURL(/dashboard/);
});

bind(id, phrase?) returns a Playwright Locator, so everything you already do with a locator still works. A project with its own fixtures extends this test instead of the one from @playwright/test.

3. Record once

YAM_MODE=record YAM_HEADED=1 npx playwright test

A browser opens and asks you to click each unbound element. What you clicked becomes a ranked bundle of candidates plus a structural fingerprint, written to bindings/login/username-field.yaml. Commit that directory: it is a reviewable file, not a database, and it records provenance.model: "human".

4. Run

npx playwright test

Run mode is the default. The resolver reads the store and tries the candidates in order until exactly one element matches. No model, no network beyond your own application.

5. Heal

YAM_MODE=heal npx playwright test

When a binding stops resolving, relocalization scores every element now on the page against the recorded fingerprint. A clear winner is used and the test is annotated healed, never passed. The repair is staged in .yam/heal-proposals.jsonl for a person to review; nothing is written to the store.

Settings

EnvironmentDefaultWhat it is
YAM_MODErunrun, record or heal
YAM_BINDINGSbindingswhere the store lives
YAM_OUT.yambind failures and heal proposals
YAM_PICKelement id to selector, for headless record in CI

Next: your first flow, which adds the flow language and the compiler on top of the same bindings.