tamash-playwright 0.10.0 → 0.11.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +11 -3
- package/CHANGELOG.md +53 -0
- package/README.md +18 -4
- package/RELEASE-TESTING.md +137 -0
- package/dist/bindings/locator.binding.d.ts +4 -0
- package/dist/bindings/locator.binding.d.ts.map +1 -1
- package/dist/bindings/locator.binding.js +176 -4
- package/dist/bindings/locator.binding.js.map +1 -1
- package/dist/cli/doctor.js +2 -2
- package/dist/cli/doctor.js.map +1 -1
- package/dist/healer/durable-locator.d.ts +3 -1
- package/dist/healer/durable-locator.d.ts.map +1 -1
- package/dist/healer/durable-locator.js +117 -0
- package/dist/healer/durable-locator.js.map +1 -1
- package/dist/healer/index.d.ts.map +1 -1
- package/dist/healer/index.js +2 -22
- package/dist/healer/index.js.map +1 -1
- package/dist/healer/providers/index.d.ts.map +1 -1
- package/dist/healer/providers/index.js +7 -1
- package/dist/healer/providers/index.js.map +1 -1
- package/dist/healer/providers/tamash-rule-based.d.ts +3 -0
- package/dist/healer/providers/tamash-rule-based.d.ts.map +1 -0
- package/dist/healer/providers/tamash-rule-based.js +67 -0
- package/dist/healer/providers/tamash-rule-based.js.map +1 -0
- package/package.json +5 -2
- package/usage.md +16 -4
- package/dist/healer/providers/claude-cli.d.ts +0 -3
- package/dist/healer/providers/claude-cli.d.ts.map +0 -1
- package/dist/healer/providers/claude-cli.js +0 -122
- package/dist/healer/providers/claude-cli.js.map +0 -1
- package/dist/healer/providers/copilot-cli.d.ts +0 -3
- package/dist/healer/providers/copilot-cli.d.ts.map +0 -1
- package/dist/healer/providers/copilot-cli.js +0 -115
- package/dist/healer/providers/copilot-cli.js.map +0 -1
package/.env.example
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Master on/off switch for self-healing. Unset or anything other than false/0 leaves it on.
|
|
2
2
|
HEALER_ENABLED=true
|
|
3
3
|
|
|
4
|
-
# Which AI provider backs self-healing: ollama | openai | anthropic | gemini | claude-subscription | copilot-subscription
|
|
4
|
+
# Which AI provider backs self-healing: ollama | openai | anthropic | gemini | claude-subscription | copilot-subscription | tamash
|
|
5
5
|
# Unset, unknown, or a provider whose key/model below is missing disables self-healing —
|
|
6
6
|
# a failed action just fails normally, since there's no AI model configured to recover it.
|
|
7
7
|
# claude-subscription/copilot-subscription don't need an API key at all — they use an existing
|
|
8
|
-
# Claude/GitHub Copilot subscription login instead.
|
|
9
|
-
# for setup.
|
|
8
|
+
# Claude/GitHub Copilot subscription login instead. tamash needs neither a key nor a subscription —
|
|
9
|
+
# it's not an AI provider at all. See the sections near the bottom of this file for setup.
|
|
10
10
|
HEALER_PROVIDER=ollama
|
|
11
11
|
|
|
12
12
|
# --- Ollama Cloud (https://ollama.com) ---
|
|
@@ -45,3 +45,11 @@ OLLAMA_API_KEY=
|
|
|
45
45
|
# account PAT fallback (COPILOT_GITHUB_TOKEN) if it doesn't.
|
|
46
46
|
# In other CI systems: set GITHUB_TOKEN (or COPILOT_GITHUB_TOKEN) to a PAT with "Copilot Requests".
|
|
47
47
|
# COPILOT_SUBSCRIPTION_MODEL=mai-code-1-flash-picker
|
|
48
|
+
|
|
49
|
+
# --- tamash: rule-based healing, no AI at all ---
|
|
50
|
+
# No API key, no subscription, no network call, no tokens. Resolves a broken locator by
|
|
51
|
+
# text-matching its description against the page's own accessibility tree, then reusing the same
|
|
52
|
+
# structural widening the AI-backed providers use. Declines rather than guesses on any ambiguity —
|
|
53
|
+
# no vision fallback, no action-recovery tactics. A fast, free, deterministic first line of
|
|
54
|
+
# defense, not a full replacement for an AI provider. Just set:
|
|
55
|
+
# HEALER_PROVIDER=tamash
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,59 @@
|
|
|
3
3
|
All notable changes to this project are documented here. Format loosely follows
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/); dates are when each version was published.
|
|
5
5
|
|
|
6
|
+
## [0.11.0] - 2026-08-28
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- **The published package was silently carrying stale, orphaned compiled output.** `npm run build`
|
|
11
|
+
(plain `tsc`, no `--build`/incremental mode) never deletes `dist/` output for a source file that
|
|
12
|
+
was later removed — found in the `0.11.0-beta.1` publish itself: `dist/healer/providers/
|
|
13
|
+
claude-cli.js`/`copilot-cli.js` shipped in the tarball with no corresponding source file
|
|
14
|
+
anywhere in the repo (from an abandoned, never-committed, never-wired-up piece of past work) —
|
|
15
|
+
dead code nothing actually imports, but real, needless bloat in every install. Fixed by cleaning
|
|
16
|
+
`dist/` automatically before every build (`prebuild` script), verified by confirming a full
|
|
17
|
+
rebuild no longer produces those two files.
|
|
18
|
+
|
|
19
|
+
- **A popup/new tab opened via `context.waitForEvent('page')`, `page.on('popup', ...)`, or
|
|
20
|
+
`page.waitForEvent('popup')` was never healing-aware.** `bindContext`/`bindPageActions` already
|
|
21
|
+
made `context.newPage()`/`context.pages()`/`context.on('page', ...)` heal correctly, but these
|
|
22
|
+
three — including `context.waitForEvent('page')`, the pattern most commonly taught for popup
|
|
23
|
+
handling — fell through to a raw, unwrapped Playwright page. A broken locator inside the
|
|
24
|
+
resulting page just threw a plain timeout, with no `[self-healer]` line at all: healing was never
|
|
25
|
+
attempted, not just unsuccessful. Found while building the first-ever test for popup healing
|
|
26
|
+
(previously implemented with zero coverage); fixed by extending both bindings to wrap whatever
|
|
27
|
+
page these three hand back, the same way `newPage()` already did.
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- **A new `tamash` heal provider — rule-based healing, no AI at all.** `HEALER_PROVIDER=tamash`
|
|
32
|
+
needs no API key, no subscription, and makes no network call: it resolves a broken locator by
|
|
33
|
+
text-matching the same description an AI provider would receive (`.describe()`, or a decoded
|
|
34
|
+
variable name — see below) against the already-captured accessibility snapshot, then reuses the
|
|
35
|
+
exact same structural widening (`near`/`adjacent`) the AI-backed path already uses once it finds
|
|
36
|
+
the right anchor — same output shape, same downstream code, zero duplicated logic. It shares the
|
|
37
|
+
same non-negotiable discipline as every text-matching step in this package: zero or more than one
|
|
38
|
+
match, at any point, means it declines rather than guesses — verified with a dedicated permanent
|
|
39
|
+
e2e suite covering direct matches, widened matches, and every decline path (including the known,
|
|
40
|
+
accepted limitation that a misleading type hint can't be second-guessed against). Genuinely a
|
|
41
|
+
different tool than the AI providers, not a free replacement for one: no vision fallback (nothing
|
|
42
|
+
to reason over a screenshot with) and no action-recovery tactics (those require understanding
|
|
43
|
+
*why* an action failed, which is inference this provider deliberately doesn't attempt) — a fast,
|
|
44
|
+
free, fully deterministic first line of defense, best suited to well-`.describe()`d,
|
|
45
|
+
Page-Object-style suites.
|
|
46
|
+
- **Undescribed, POM-style locator variables now get a real description automatically.** When
|
|
47
|
+
`.describe()` was never called, the healer already fell back to the locator's own variable/
|
|
48
|
+
property name (`txtEmployeeId`) as its best guess at intent — now that raw identifier is decoded
|
|
49
|
+
into the same kind of human-readable phrase `.describe()` would give: `txtEmployeeId` becomes
|
|
50
|
+
"Employee Id (textbox)", `submitButton` becomes "Submit (button)", recognizing both prefix-style
|
|
51
|
+
(`btnSubmit`) and suffix-style (`submitBtn`) naming, camelCase/snake_case/kebab-case, and correct
|
|
52
|
+
acronym boundaries (`employeeIDNumber` → "Employee ID Number"). Falls back to the raw identifier,
|
|
53
|
+
exactly as before, whenever nothing meaningful survives decoding (a placeholder name like `el1`,
|
|
54
|
+
or a bare affix with nothing else) — never a guess dressed up as a real description. Verified
|
|
55
|
+
live against a real, unpublished build in both sample repos (a real `copilot-subscription` call,
|
|
56
|
+
and — after finding and fixing a genuinely stale API key along the way — a real `ollama` call),
|
|
57
|
+
confirming the decoded description actually reaches the configured AI provider unchanged.
|
|
58
|
+
|
|
6
59
|
## [0.10.0] - 2026-08-27
|
|
7
60
|
|
|
8
61
|
### Fixed
|
package/README.md
CHANGED
|
@@ -14,6 +14,8 @@ Websites change often. A button gets renamed or moved, and your test can't find
|
|
|
14
14
|
|
|
15
15
|
**Looking for the complete reference** — caching, `apply-heals`, sharded-CI and PR automation, every env var and CLI flag? See [usage.md](usage.md).
|
|
16
16
|
|
|
17
|
+
**Want to know what's actually been verified, not just claimed?** Every release's [CHANGELOG.md](CHANGELOG.md) entry says what changed; [RELEASE-TESTING.md](RELEASE-TESTING.md) says how it was actually tested before it shipped — what ran locally, what ran in CI, and any real issue testing itself turned up along the way.
|
|
18
|
+
|
|
17
19
|
Here are the detailed steps to use this package.
|
|
18
20
|
|
|
19
21
|
## Step 1: Install it
|
|
@@ -30,7 +32,7 @@ npm install -D @playwright/test
|
|
|
30
32
|
|
|
31
33
|
## Step 2: Connect an AI model
|
|
32
34
|
|
|
33
|
-
`tamash-playwright` needs an AI model to decide where a broken element actually went. Pick one of Ollama, OpenAI, Anthropic (Claude), or Google Gemini, and give it an API key — or, if you don't have an API key but do have a Claude or GitHub Copilot subscription, use that instead (see below).
|
|
35
|
+
`tamash-playwright` needs an AI model to decide where a broken element actually went. Pick one of Ollama, OpenAI, Anthropic (Claude), or Google Gemini, and give it an API key — or, if you don't have an API key but do have a Claude or GitHub Copilot subscription, use that instead (see below). There's also a zero-dependency, zero-cost option (`tamash`) that needs no AI at all — see [Rule-based healing, no AI required](#rule-based-healing-no-ai-required) below.
|
|
34
36
|
|
|
35
37
|
Create a file named `.env` in your project folder:
|
|
36
38
|
|
|
@@ -38,7 +40,7 @@ Create a file named `.env` in your project folder:
|
|
|
38
40
|
# Master on/off switch. Leave this as true, or remove the line entirely.
|
|
39
41
|
HEALER_ENABLED=true
|
|
40
42
|
|
|
41
|
-
# Pick one: ollama | openai | anthropic | gemini | claude-subscription | copilot-subscription
|
|
43
|
+
# Pick one: ollama | openai | anthropic | gemini | claude-subscription | copilot-subscription | tamash
|
|
42
44
|
HEALER_PROVIDER=ollama
|
|
43
45
|
|
|
44
46
|
# --- Ollama Cloud (https://ollama.com) ---
|
|
@@ -162,6 +164,16 @@ A no-op if `copilot-subscription` was never used, so it's safe to add unconditio
|
|
|
162
164
|
|
|
163
165
|
**One thing worth knowing**: only Claude and Copilot support this "subscription, no API key, works in CI too" combination — a ChatGPT or Google AI subscription can back local runs the same way (via those vendors' own CLIs), but neither vendor currently offers a way to use that subscription unattended in CI, so CI there still needs a plain API key (the existing `openai`/`gemini` providers above).
|
|
164
166
|
|
|
167
|
+
### Rule-based healing, no AI required
|
|
168
|
+
|
|
169
|
+
```sh
|
|
170
|
+
HEALER_PROVIDER=tamash
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
No API key, no subscription, no network call, no tokens — `tamash` resolves a broken locator by searching the page's accessibility tree for the same text your `.describe()` (or a named locator variable — see the tip below) already gives it, then applying the same structural widening logic (`near`/`adjacent`) the AI-backed providers use once it finds the right anchor. `doctor` always reports it connected, since there's nothing external for it to fail to reach.
|
|
174
|
+
|
|
175
|
+
Worth being upfront about what this trades away, since it's a real, honest tradeoff, not a strictly-better free option: it never guesses. If the description doesn't closely match text actually on the page (a paraphrase, or a raw CSS/XPath selector with no human-readable text at all), or if two equally-plausible elements sit near the same anchor, it declines rather than pick — exactly the cases where an AI's real reasoning gets a heal that a text search can't. It also can't do the screenshot-based vision fallback (there's no model to look at an image with) or action-recovery tactics like scroll/force/wait (those need to understand *why* an action failed, which is inference this provider deliberately doesn't attempt). Use it when you want a fast, free, fully deterministic first line of defense — especially for well-`.describe()`d, Page-Object-style suites, where its success rate is genuinely close to an AI's — and fall back to one of the AI providers above for anything it can't resolve.
|
|
176
|
+
|
|
165
177
|
### Important: set `actionTimeout` in your `playwright.config.ts`
|
|
166
178
|
|
|
167
179
|
By default, Playwright lets a broken locator retry silently for your *entire* test timeout before it ever throws an error — which means self-healing never gets a turn at all, since it only kicks in once an action actually fails. Set `actionTimeout` to something well below your test timeout so a broken locator fails fast, leaving real time for healing to run:
|
|
@@ -250,6 +262,8 @@ test('login test using CSS Selectors', async ({ page }) => {
|
|
|
250
262
|
|
|
251
263
|
This step is optional, but recommended — without it, the healer has to guess purely from a broken CSS selector, which gives it a lot less to work with.
|
|
252
264
|
|
|
265
|
+
If you skip `.describe()` but still name your locator variables descriptively (`txtEmployeeId`, `submitButton`, `this.chkAgree = ...`) — the common Page Object style — the healer automatically decodes that name into the same kind of description `.describe()` would give: `txtEmployeeId` becomes "Employee Id (textbox)", `submitButton` becomes "Submit (button)". This happens for free, with no code change; `.describe()` still always wins when both are present.
|
|
266
|
+
|
|
253
267
|
## Local vs CI, at a glance
|
|
254
268
|
|
|
255
269
|
Everything below applies identically in both places — same package, same behavior — but a few things are worth knowing up front before you get to the details:
|
|
@@ -259,7 +273,7 @@ Everything below applies identically in both places — same package, same behav
|
|
|
259
273
|
| **Healing** | Runs automatically on every `npx playwright test`, using the `.env` file from Step 2. | Runs automatically the same way — set the same variables as CI secrets/environment variables on your test job instead of a `.env` file (there's a real example in [Running `apply-heals` in CI](#running-apply-heals-in-ci-sharded-or-not)). |
|
|
260
274
|
| **Caching** ([below](#not-paying-for-the-same-heal-twice)) | Persists on disk across every run — a real, ongoing saving the longer you keep working. | Only helps *within* one run — most runners start from a fresh checkout each time, so it doesn't carry over between separate CI runs. `apply-heals` landing the real fix is what actually stops repeat AI calls in CI, not the cache. |
|
|
261
275
|
| **`apply-heals`** ([below](#making-a-heal-permanent-apply-heals)) | Run manually whenever you want, preview with `--dry-run`, review the diff yourself, commit when ready. | Runs automatically after your test job and opens a PR for review — nothing ever auto-commits to your branch. |
|
|
262
|
-
| **Provider choice** | Any provider works, including `claude-subscription`/`copilot-subscription` off a personal subscription with no API key. | Only `ollama`/`openai`/`anthropic`/`gemini` (a real API key), `claude-subscription` (a `CLAUDE_CODE_OAUTH_TOKEN`), or `copilot-subscription` on GitHub Actions actually run unattended — a `claude-subscription`/`copilot-subscription` config that relies on a local interactive login won't authenticate in CI. See [above](#using-your-claude-or-github-copilot-subscription-instead-of-an-api-key). |
|
|
276
|
+
| **Provider choice** | Any provider works, including `claude-subscription`/`copilot-subscription` off a personal subscription with no API key. | Only `ollama`/`openai`/`anthropic`/`gemini` (a real API key), `claude-subscription` (a `CLAUDE_CODE_OAUTH_TOKEN`), or `copilot-subscription` on GitHub Actions actually run unattended — a `claude-subscription`/`copilot-subscription` config that relies on a local interactive login won't authenticate in CI. See [above](#using-your-claude-or-github-copilot-subscription-instead-of-an-api-key). `tamash` (see [Rule-based healing, no AI required](#rule-based-healing-no-ai-required)) needs no credentials at all, so it always runs unattended, anywhere — trading the AI providers' broader success rate for that simplicity. |
|
|
263
277
|
|
|
264
278
|
## What else it heals — no extra setup needed
|
|
265
279
|
|
|
@@ -289,7 +303,7 @@ Not every healed selector is equally durable. One with a real id, test id, or ac
|
|
|
289
303
|
|
|
290
304
|
## When text alone isn't enough: vision fallback
|
|
291
305
|
|
|
292
|
-
Sometimes an element has nothing useful to match on by text — an icon-only button with no label, or several visually distinct elements that all look identical in the accessibility tree. If your configured model supports image input (e.g. `gpt-4o`, `claude-haiku-4-5`, `gemini-3.6-flash` — and this applies to `claude-subscription`/`copilot-subscription` too, e.g. `CLAUDE_SUBSCRIPTION_MODEL=haiku`, or a vision-capable Copilot model), `tamash-playwright` automatically falls back to a screenshot-based search after the normal text-based attempt fails — no separate setup, it just uses the same provider from Step 2. Run `npx tamash-playwright doctor` to check whether your configured model is expected to support this.
|
|
306
|
+
Sometimes an element has nothing useful to match on by text — an icon-only button with no label, or several visually distinct elements that all look identical in the accessibility tree. If your configured model supports image input (e.g. `gpt-4o`, `claude-haiku-4-5`, `gemini-3.6-flash` — and this applies to `claude-subscription`/`copilot-subscription` too, e.g. `CLAUDE_SUBSCRIPTION_MODEL=haiku`, or a vision-capable Copilot model), `tamash-playwright` automatically falls back to a screenshot-based search after the normal text-based attempt fails — no separate setup, it just uses the same provider from Step 2. Run `npx tamash-playwright doctor` to check whether your configured model is expected to support this. (`tamash` never does — there's no model to reason over an image with.)
|
|
293
307
|
|
|
294
308
|
## Not paying for the same heal twice
|
|
295
309
|
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Release testing record
|
|
2
|
+
|
|
3
|
+
This is the trust layer: an honest, current account of what's actually been verified for every
|
|
4
|
+
feature users depend on — not a claim that it works, evidence for how we know. A status here
|
|
5
|
+
reflects something that was genuinely run and observed. Where something hasn't been checked, or
|
|
6
|
+
was checked before but not re-verified recently, that's stated plainly rather than rounded up to
|
|
7
|
+
look complete. A gap shown here is more useful than a gap hidden.
|
|
8
|
+
|
|
9
|
+
**Status legend**: ✅ Verified (automated test exists and passes) · 🔎 Verified manually, no
|
|
10
|
+
permanent automated test yet · ⚠️ Verified previously, not re-checked this release · ❌ Not
|
|
11
|
+
currently covered · N/A not applicable to that column.
|
|
12
|
+
|
|
13
|
+
## Feature coverage
|
|
14
|
+
|
|
15
|
+
| Feature | Description | Tested locally | Tested in CI |
|
|
16
|
+
|---|---|---|---|
|
|
17
|
+
| Core action healing (click/fill/check/selectOption/etc.) | Any wrapped Playwright action retries against a healed locator on failure. | ✅ Extensive unit + e2e coverage (many repro specs) | ✅ Every CI run exercises this against the sample repos' own broken locators |
|
|
18
|
+
| `.describe()` context | Human-readable label chained onto a locator, used as the AI's primary description. | ✅ Used throughout the test suite | ✅ Both sample repos' tests use it |
|
|
19
|
+
| Automatic variable-name description fallback | `extractVariableName` (raw identifier) + `decodeVariableName` (decoded phrase + type hint) when `.describe()` isn't called. | ✅ 10+10 unit tests, permanent e2e spec | ❌ Not yet — this release's beta hasn't been pushed to either sample repo's CI yet |
|
|
20
|
+
| Search-scoped snapshots | Sends a narrower excerpt of the accessibility tree when the description matches exactly one node, instead of the full page. | ✅ Live-verified (measured token reduction across several real cases) | 🔎 Silently exercised on every CI heal (it's the default first path), but no dedicated CI assertion checks it specifically |
|
|
21
|
+
| `near` strategy (nameless field via label) | Resolves an unlabeled field by climbing to a shared ancestor and finding the one plausible-role sibling. | ✅ e2e (`aic-form-healing`, `employee-id-healing`) | ✅ Indirectly — the sample repos' own Employee Id field is exactly this shape |
|
|
22
|
+
| `adjacent` strategy (same-row disambiguation) | Precise sibling match when `near`'s ancestor search would find more than one same-role candidate. | ✅ e2e (`adjacent-sibling-healing`) + unit | ❌ No sample test currently has this shape |
|
|
23
|
+
| `scoped` / `containing` strategies | Landmark-scoped role/name, and container-identified-by-contents. | ✅ Unit-tested (source-code generation for all 9 strategies, `applyHeals.test.js`) | ❌ No live e2e resolution test, no CI case |
|
|
24
|
+
| `tamash` rule-based provider | Zero-AI healing via text match + the same structural widening. | ✅ 19 unit tests + permanent e2e (4/4 live) | ❌ Not yet — pending, see above |
|
|
25
|
+
| Vision fallback (screenshot-based) | Used when text/ref healing fails and the model supports image input. | ✅ e2e (`vision-fallback-repro`) | ❌ No sample test currently forces this path (no accessible-name-less broken element in CI's own tests) |
|
|
26
|
+
| Action recovery (scroll/force/wait/dispatch) | Second-order fallback when a healed locator still can't complete the original action. | ⚠️ Repro spec exists but requires `HEALER_ACTION_RECOVERY_ENABLED=true`, which is unset by default — not currently passing out of the box locally either | N/A — opt-in, disabled by default, not set in either CI workflow |
|
|
27
|
+
| iframe healing | Locators inside `<iframe>`s heal the same way, scoped to the correct document. | ✅ e2e (`iframe-ref-repro`) | ❌ No CI sample test uses an iframe |
|
|
28
|
+
| Popup / new-tab healing (`bindContext`/`bindPageActions`) | A page opened via `context.newPage()`, `page.on('popup', ...)`, or `context.waitForEvent('page')`/`page.waitForEvent('popup')` is healing-aware too. | ✅ Permanent e2e (`popup-newtab-healing.e2e.spec.ts`, real orangehrm.com popup, all 3 obtaining patterns) — but this closed a real gap, not just added a test; see below | ❌ Not covered |
|
|
29
|
+
| Full attempt-history logging (`attempts[]`) | Every cache/text/vision/action-recovery attempt recorded, not just the last. | ✅ Unit + e2e | ✅ Visible in every CI console log |
|
|
30
|
+
| Heal caching (`heals.jsonl`) | A previously-confirmed selector is retried before a fresh AI call. | ✅ Unit (`healLog.test.js`) + e2e-observed | ✅ Uploaded as a CI artifact every run, consumed by `apply-heals` |
|
|
31
|
+
| `apply-heals` (permanent fix + PR automation) | Turns a runtime heal into a committed source change; opens a PR in CI. | ✅ Unit (46 tests, all 9 strategies) | ✅ Dedicated CI job, runs every push |
|
|
32
|
+
| `doctor` CLI | Pre-flight checks: provider connectivity, `actionTimeout`, vision capability, missing `.describe()`, inline locators. | ✅ Run live against every provider including `tamash` this session | ❌ Not run as part of either CI workflow |
|
|
33
|
+
| `getDurable()` | Resolves any locator (e.g. `aria-ref=...`) to a durable, reusable equivalent. | ✅ e2e (`get-durable-*-repro`, 4 specs incl. concurrency) | ❌ No CI sample test calls it directly |
|
|
34
|
+
| Provider: `ollama` | API-key provider, Ollama Cloud. | ✅ Verified this session (live calls, real token counts) | ❌ Neither CI workflow currently uses it |
|
|
35
|
+
| Provider: `openai` | API-key provider. | ✅ Re-verified live this release (`doctor` connectivity, real key) | ❌ Not used in either CI workflow |
|
|
36
|
+
| Provider: `anthropic` | API-key provider. | ✅ Re-verified live this release (`doctor` connectivity, real key) | ❌ Not used in either CI workflow |
|
|
37
|
+
| Provider: `gemini` | API-key provider. | ⚠️ Key authenticates and the model responds correctly (verified with a raw request, real `200 OK`), but `gemini-3.6-flash` took 50+ seconds to answer a trivial prompt — far beyond `doctor`'s 15s timeout and this repo's real `actionTimeout: 8000`ms, so it fails both `doctor` and real healing as currently configured, despite the key itself being valid | ❌ Not used in either CI workflow |
|
|
38
|
+
| Provider: `claude-subscription` | No API key — uses a Claude subscription. | ✅ Verified this session | ✅ The Playwright sample repo's CI uses this as its default provider |
|
|
39
|
+
| Provider: `copilot-subscription` | No API key — uses a GitHub Copilot subscription. | ✅ Verified this session | ✅ The Cucumber sample repo's CI uses this as its default provider |
|
|
40
|
+
| Provider: `tamash` (no AI) | Zero-dependency rule-based healing. | ✅ Verified this session, both sample repos | ❌ Not yet — pending |
|
|
41
|
+
| Non-`@playwright/test` runner support (`bindPageActions`/`bindContext`) | Manual binding for Cucumber, Jest, or a plain script. | ✅ Live-verified via the Cucumber sample repo, this session | ✅ The Cucumber sample repo's entire CI run *is* this |
|
|
42
|
+
| `waitFor()`/`dragTo`/`drop`/`expect()` exclusions | Deliberately never healed — state checks and two-sided actions can't be safely guessed at. | ✅ e2e (`wait-for-not-healed`) | ❌ No CI sample test currently exercises these specifically |
|
|
43
|
+
|
|
44
|
+
**What this table makes plain, on purpose**: CI coverage today is real but narrow — it's two
|
|
45
|
+
sample repos each running a small, fixed set of tests against one specific provider each
|
|
46
|
+
(`claude-subscription`, `copilot-subscription`). It genuinely proves core healing, `.describe()`,
|
|
47
|
+
`near`-shaped widening, caching, and `apply-heals` work end-to-end in a real unattended pipeline.
|
|
48
|
+
It does **not** currently exercise `adjacent`, `scoped`/`containing`, vision, action-recovery,
|
|
49
|
+
iframes, popups, or four of the seven providers at all. Those are covered by local automated
|
|
50
|
+
tests (mostly thorough) or, for a few cells, not covered by any permanent test yet. Closing that
|
|
51
|
+
CI gap — not just adding more local tests — is the honest next step this table points to.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Per-release notes
|
|
56
|
+
|
|
57
|
+
The table above is the current, living state. This section keeps a short history of what changed
|
|
58
|
+
release to release, and anything worth remembering that testing itself turned up — including real
|
|
59
|
+
mistakes, not just successes.
|
|
60
|
+
|
|
61
|
+
### [0.11.0-beta.1 → beta.2] — 2026-08-28
|
|
62
|
+
|
|
63
|
+
**Added this release**: the `tamash` provider, the automatic variable-name description enrichment,
|
|
64
|
+
and — found while closing the popup/new-tab coverage gap this document itself surfaced — two real,
|
|
65
|
+
previously-unknown bugs in `bindContext`/`bindPageActions` fixed the same day they were found.
|
|
66
|
+
|
|
67
|
+
**The popup/new-tab bug, in detail**: the coverage table above previously flagged "implemented, but
|
|
68
|
+
no dedicated test found anywhere in this repo" for popup healing. Building that test (against a
|
|
69
|
+
real popup on orangehrm.com, opened from the OrangeHRM login page's own footer link) found the
|
|
70
|
+
"no test" gap was hiding a real functional gap: `context.waitForEvent('page')` — the idiomatic,
|
|
71
|
+
commonly-taught pattern for popup handling — silently returned Playwright's raw, non-healing page.
|
|
72
|
+
Confirmed live before the fix: a deliberately broken locator inside the resulting page threw a
|
|
73
|
+
plain Playwright timeout with no `[self-healer]` console line at all — healing was never even
|
|
74
|
+
attempted, not just unsuccessful. The same gap existed on the `Page` side too:
|
|
75
|
+
`page.on('popup', handler)` and `page.waitForEvent('popup')` both handed back raw, unwrapped pages,
|
|
76
|
+
for the identical reason — neither `bindContext` nor `bindPageActions`'s underlying Proxy had any
|
|
77
|
+
interception for these three methods, only for `newPage()`/`pages()`/`on('page', ...)`. Fixed by
|
|
78
|
+
extending both Proxies to wrap whatever page `waitForEvent`/`on`/`once` hand back, the same way
|
|
79
|
+
`newPage()` already did. One implementation bug was caught and fixed along the way, live: the first
|
|
80
|
+
attempt extracted the target method into an intermediate `const` before calling it
|
|
81
|
+
(`const m = obj[prop]; m(...)`), which detaches `this` from the real object — confirmed by a real
|
|
82
|
+
`Cannot read properties of undefined` thrown from inside Playwright's own internals — fixed by
|
|
83
|
+
keeping it a single inline `obj[prop](...)` call expression instead, preserving `this` the same way
|
|
84
|
+
this file's own `ACTIONS` block already does it one function up.
|
|
85
|
+
|
|
86
|
+
All three patterns (`context.waitForEvent('page')`, `page.on('popup', ...)`,
|
|
87
|
+
`page.waitForEvent('popup')`) were verified live, individually, against a real popup before being
|
|
88
|
+
folded into the permanent e2e spec — not just reasoned about from reading the fix. The permanent
|
|
89
|
+
spec itself hit one more real thing worth recording: orangehrm.com runs a genuine third-party
|
|
90
|
+
Cookiebot consent banner that appears intermittently (3 of 4 early runs) and, when present, covers
|
|
91
|
+
enough of the page that the target field is effectively invisible to the healer — not a
|
|
92
|
+
tamash-playwright bug, a real environmental precondition, handled in the test the same way any real
|
|
93
|
+
suite would (dismiss it if present, don't fail if it never appeared). Stable across 6 repeat runs
|
|
94
|
+
after that fix.
|
|
95
|
+
|
|
96
|
+
**Found in the beta.1 publish itself, fixed as beta.2**: the actual published `beta.1` tarball
|
|
97
|
+
contained `dist/healer/providers/claude-cli.js`/`copilot-cli.js` — compiled output with no
|
|
98
|
+
corresponding source file anywhere in the repo, from an abandoned, never-committed, never-wired-up
|
|
99
|
+
piece of past work. Root cause: plain `tsc` (no `--build`/incremental mode) never deletes `dist/`
|
|
100
|
+
output for a source file removed since the last build, so this stale output silently survived
|
|
101
|
+
every rebuild since whenever it was first compiled. Fixed by cleaning `dist/` automatically before
|
|
102
|
+
every build; verified by confirming a full rebuild no longer produces either file, before
|
|
103
|
+
re-publishing as `beta.2`. Recorded here specifically because it was caught only by inspecting the
|
|
104
|
+
real, already-published tarball's own file listing after publishing — a reminder that "the build
|
|
105
|
+
succeeded and tests passed" doesn't guarantee the published artifact itself is clean.
|
|
106
|
+
|
|
107
|
+
**Regression check**: full existing e2e suite re-run against the published 0.10.0 baseline (not
|
|
108
|
+
just "did it pass," but "does the same thing fail on the untouched published package too"). The
|
|
109
|
+
only failures that reproduced identically on the untouched baseline were 3 known, pre-existing
|
|
110
|
+
investigation scripts, unrelated to this release. Everything else that failed in one run passed
|
|
111
|
+
cleanly in a repeat run with a *different* test failing each time — the signature of parallel-load
|
|
112
|
+
contention against a live AI provider under `fullyParallel: true`, not a deterministic regression.
|
|
113
|
+
|
|
114
|
+
**Real issues testing itself caught, not just successes**:
|
|
115
|
+
- Building `decodeVariableName`'s unit tests surfaced two real bugs before anything was run for
|
|
116
|
+
real: a snake_case prefix boundary that wasn't recognized, and a bare-affix-word case
|
|
117
|
+
(`txt`/`button` alone) the meaningless-word guard didn't yet catch. A third (`submitBtn`, a
|
|
118
|
+
short-suffix style) was caught by a follow-up spot-check script.
|
|
119
|
+
- Building `tamash`'s permanent e2e spec surfaced a real test-isolation bug (not a feature bug):
|
|
120
|
+
`heals.jsonl` is keyed by file:line, not by provider, so a second run of the same spec resolved
|
|
121
|
+
via `provider:'cache'` before `tamash` ever got a turn — looked like a regression, wasn't. Fixed
|
|
122
|
+
by clearing the cache in the spec's own `beforeAll`, documented in `TESTING.md` so it isn't
|
|
123
|
+
rediscovered the hard way.
|
|
124
|
+
- Live-verifying the description enrichment against a real `ollama` call (Cucumber sample repo)
|
|
125
|
+
hit a genuinely stale API key (`401 Unauthorized`) — an environment problem, not a code problem.
|
|
126
|
+
Confirmed by re-testing after the key was updated: a real fresh call succeeded with real token
|
|
127
|
+
usage and the correctly-decoded description.
|
|
128
|
+
- Re-verifying `openai`/`anthropic`/`gemini` with freshly-issued keys turned up a real, current
|
|
129
|
+
Gemini issue unrelated to anything in this release: `gemini-2.5-flash` (this project's configured
|
|
130
|
+
default) is deprecated for new API keys — a raw request against the real endpoint returned
|
|
131
|
+
Google's own `404`, naming `gemini-3.6-flash` as the replacement. Switching to it authenticates
|
|
132
|
+
and responds correctly, but takes 50+ seconds for a trivial prompt (its response includes a
|
|
133
|
+
`thought_signature` field — extended internal reasoning by default, the same class of problem
|
|
134
|
+
already fixed once for `claude-subscription`'s `effort`/`thinking` settings). Root-caused via a
|
|
135
|
+
raw request outside the package's own code, isolating "bad key" from "deprecated model" from
|
|
136
|
+
"model too slow for the configured timeout" as three genuinely distinct possibilities before
|
|
137
|
+
concluding which one it actually was.
|
|
@@ -2,6 +2,10 @@ import type { BrowserContext, Frame, FrameLocator, Locator, Page } from '@playwr
|
|
|
2
2
|
type BindingKind = 'locator' | 'page' | 'frame' | 'frameLocator';
|
|
3
3
|
export declare function resolveCallerLocation(callSite: Error): string | undefined;
|
|
4
4
|
export declare function extractVariableName(sourceLocation: string): string | undefined;
|
|
5
|
+
export declare function decodeVariableName(raw: string): {
|
|
6
|
+
name: string;
|
|
7
|
+
typeHint?: string;
|
|
8
|
+
} | undefined;
|
|
5
9
|
export declare function bindTargetActions<T extends Locator | Page | Frame | FrameLocator>(target: T, kind?: BindingKind, description?: string, frameScope?: FrameLocator, selector?: string, callSite?: Error): T;
|
|
6
10
|
export declare function bindLocatorActions(locator: Locator): Locator;
|
|
7
11
|
export declare function bindPageActions(page: Page): Page;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locator.binding.d.ts","sourceRoot":"","sources":["../../src/bindings/locator.binding.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AA2E3F,KAAK,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,cAAc,CAAC;AA4CjE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAiCzE;AAWD,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA4B9E;AAmDD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,YAAY,EAC/E,MAAM,EAAE,CAAC,EACT,IAAI,GAAE,WAAuB,EAC7B,WAAW,CAAC,EAAE,MAAM,EAKpB,UAAU,CAAC,EAAE,YAAY,EAMzB,QAAQ,CAAC,EAAE,MAAM,EAKjB,QAAQ,CAAC,EAAE,KAAK,GACf,CAAC,
|
|
1
|
+
{"version":3,"file":"locator.binding.d.ts","sourceRoot":"","sources":["../../src/bindings/locator.binding.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AA2E3F,KAAK,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,cAAc,CAAC;AA4CjE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAiCzE;AAWD,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA4B9E;AAsFD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CA0C/F;AAmDD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,YAAY,EAC/E,MAAM,EAAE,CAAC,EACT,IAAI,GAAE,WAAuB,EAC7B,WAAW,CAAC,EAAE,MAAM,EAKpB,UAAU,CAAC,EAAE,YAAY,EAMzB,QAAQ,CAAC,EAAE,MAAM,EAKjB,QAAQ,CAAC,EAAE,KAAK,GACf,CAAC,CAuMH;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAE5D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAEhD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAEpD;AAgBD,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,CA6CnE"}
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.resolveCallerLocation = resolveCallerLocation;
|
|
7
7
|
exports.extractVariableName = extractVariableName;
|
|
8
|
+
exports.decodeVariableName = decodeVariableName;
|
|
8
9
|
exports.bindTargetActions = bindTargetActions;
|
|
9
10
|
exports.bindLocatorActions = bindLocatorActions;
|
|
10
11
|
exports.bindPageActions = bindPageActions;
|
|
@@ -193,6 +194,121 @@ function extractVariableName(sourceLocation) {
|
|
|
193
194
|
return undefined;
|
|
194
195
|
}
|
|
195
196
|
}
|
|
197
|
+
// Hungarian-notation-style prefixes teams commonly put on a locator variable to hint at its
|
|
198
|
+
// expected role -- `txtUserName`, `btnSubmit`. Checked case-insensitively, but only recognized
|
|
199
|
+
// when immediately followed by an uppercase letter (the start of the rest of the identifier), so
|
|
200
|
+
// an ordinary English word that happens to start the same way (`imgur`, `chunk`) never matches.
|
|
201
|
+
const TYPE_PREFIXES = [
|
|
202
|
+
{ prefix: 'txt', type: 'textbox' },
|
|
203
|
+
{ prefix: 'btn', type: 'button' },
|
|
204
|
+
{ prefix: 'chk', type: 'checkbox' },
|
|
205
|
+
{ prefix: 'cb', type: 'checkbox' },
|
|
206
|
+
{ prefix: 'rdo', type: 'radio button' },
|
|
207
|
+
{ prefix: 'ddl', type: 'dropdown' },
|
|
208
|
+
{ prefix: 'lnk', type: 'link' },
|
|
209
|
+
{ prefix: 'img', type: 'image' },
|
|
210
|
+
{ prefix: 'lbl', type: 'label' },
|
|
211
|
+
];
|
|
212
|
+
// The suffix-style equivalent -- `submitButton`, `emailInput`, `agreeCheckbox` -- at least as
|
|
213
|
+
// common in real codebases as the prefix style above. Longest suffix first, so e.g. `radiobutton`
|
|
214
|
+
// is preferred over the shorter `button` it would otherwise also match.
|
|
215
|
+
const TYPE_SUFFIXES = [
|
|
216
|
+
{ suffix: 'radiobutton', type: 'radio button' },
|
|
217
|
+
{ suffix: 'checkbox', type: 'checkbox' },
|
|
218
|
+
{ suffix: 'textarea', type: 'textarea' },
|
|
219
|
+
{ suffix: 'textbox', type: 'textbox' },
|
|
220
|
+
{ suffix: 'textfield', type: 'textbox' },
|
|
221
|
+
{ suffix: 'dropdown', type: 'dropdown' },
|
|
222
|
+
{ suffix: 'combobox', type: 'dropdown' },
|
|
223
|
+
{ suffix: 'button', type: 'button' },
|
|
224
|
+
{ suffix: 'select', type: 'dropdown' },
|
|
225
|
+
{ suffix: 'input', type: 'textbox' },
|
|
226
|
+
{ suffix: 'field', type: 'textbox' },
|
|
227
|
+
{ suffix: 'radio', type: 'radio button' },
|
|
228
|
+
{ suffix: 'link', type: 'link' },
|
|
229
|
+
{ suffix: 'image', type: 'image' },
|
|
230
|
+
{ suffix: 'label', type: 'label' },
|
|
231
|
+
// Short forms mirroring TYPE_PREFIXES -- "submitBtn"/"agreeChk"/"countryDdl" are just as common
|
|
232
|
+
// in the wild as the prefix-first style ("btnSubmit"/"chkAgree"/"ddlCountry").
|
|
233
|
+
{ suffix: 'btn', type: 'button' },
|
|
234
|
+
{ suffix: 'chk', type: 'checkbox' },
|
|
235
|
+
{ suffix: 'cb', type: 'checkbox' },
|
|
236
|
+
{ suffix: 'rdo', type: 'radio button' },
|
|
237
|
+
{ suffix: 'ddl', type: 'dropdown' },
|
|
238
|
+
{ suffix: 'lnk', type: 'link' },
|
|
239
|
+
{ suffix: 'img', type: 'image' },
|
|
240
|
+
{ suffix: 'lbl', type: 'label' },
|
|
241
|
+
];
|
|
242
|
+
// Identifiers that carry no real meaning even after decoding -- generic placeholder names a
|
|
243
|
+
// person reaches for when they didn't have (or didn't bother writing) a descriptive one. Decoding
|
|
244
|
+
// something like `el1` into "El" would be worse than no signal at all: a confident-looking but
|
|
245
|
+
// empty description that could mislead the AI, so this is deliberately conservative -- it only
|
|
246
|
+
// blocks the *whole* result, and only when every surviving word is on this list.
|
|
247
|
+
const MEANINGLESS_WORDS = new Set([
|
|
248
|
+
'el', 'elem', 'element', 'obj', 'val', 'value', 'loc', 'locator', 'ctrl', 'control',
|
|
249
|
+
'item', 'temp', 'tmp', 'thing', 'x', 'y', 'a', 'b', 'field', 'box', 'node',
|
|
250
|
+
]);
|
|
251
|
+
// A bare affix on its own ("txt", "button", with nothing else) isn't a meaningful name either --
|
|
252
|
+
// it only became one once combined with the rest of an identifier. Folded into the same
|
|
253
|
+
// meaningless-word check below rather than duplicated as its own list.
|
|
254
|
+
const AFFIX_WORDS = new Set([
|
|
255
|
+
...TYPE_PREFIXES.map(({ prefix }) => prefix),
|
|
256
|
+
...TYPE_SUFFIXES.map(({ suffix }) => suffix),
|
|
257
|
+
]);
|
|
258
|
+
function splitIdentifierIntoWords(identifier) {
|
|
259
|
+
return identifier
|
|
260
|
+
.replace(/[_-]+/g, ' ')
|
|
261
|
+
// lower/digit -> upper boundary: "userName" -> "user Name"
|
|
262
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
263
|
+
// acronym -> word boundary: "IDNumber" -> "ID Number"
|
|
264
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
|
|
265
|
+
.trim()
|
|
266
|
+
.split(/\s+/)
|
|
267
|
+
.filter(Boolean);
|
|
268
|
+
}
|
|
269
|
+
// Third-tier-of-the-third-tier: what extractVariableName() below hands back is a raw identifier
|
|
270
|
+
// ("txtUserName", "submitButton") -- legible enough to an AI on its own, but it's also a free type
|
|
271
|
+
// hint (the prefix/suffix) that would otherwise just be thrown away, and a cleaner phrase is a
|
|
272
|
+
// meaningfully better anchor for anything doing plain text matching against the ARIA snapshot
|
|
273
|
+
// (an AI or, eventually, a rule-based pre-check) than a smashed-together identifier is. Returns
|
|
274
|
+
// undefined -- not a best-effort guess -- when nothing meaningful survives decoding, so a caller
|
|
275
|
+
// can fall back to the raw identifier exactly as before rather than trust an empty result.
|
|
276
|
+
function decodeVariableName(raw) {
|
|
277
|
+
if (!raw) {
|
|
278
|
+
return undefined;
|
|
279
|
+
}
|
|
280
|
+
const lower = raw.toLowerCase();
|
|
281
|
+
let remainder = raw;
|
|
282
|
+
let typeHint;
|
|
283
|
+
const prefixMatch = TYPE_PREFIXES.find(
|
|
284
|
+
// Boundary after the prefix must be either the start of a new camelCase word (an uppercase
|
|
285
|
+
// letter -- so "imgur" isn't misread as "img" + "ur") or an explicit separator (snake_case /
|
|
286
|
+
// kebab-case: "txt_user_name", "txt-user-name").
|
|
287
|
+
({ prefix }) => lower.startsWith(prefix) && raw.length > prefix.length && /[A-Z_-]/.test(raw[prefix.length]));
|
|
288
|
+
if (prefixMatch) {
|
|
289
|
+
remainder = raw.slice(prefixMatch.prefix.length);
|
|
290
|
+
typeHint = prefixMatch.type;
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
const suffixMatch = TYPE_SUFFIXES.find(({ suffix }) => lower.endsWith(suffix) && raw.length > suffix.length);
|
|
294
|
+
if (suffixMatch) {
|
|
295
|
+
remainder = raw.slice(0, raw.length - suffixMatch.suffix.length);
|
|
296
|
+
typeHint = suffixMatch.type;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const words = splitIdentifierIntoWords(remainder);
|
|
300
|
+
if (words.length === 0) {
|
|
301
|
+
return undefined;
|
|
302
|
+
}
|
|
303
|
+
if (words.every((w) => {
|
|
304
|
+
const bare = w.toLowerCase().replace(/\d+$/, '');
|
|
305
|
+
return MEANINGLESS_WORDS.has(bare) || AFFIX_WORDS.has(bare);
|
|
306
|
+
})) {
|
|
307
|
+
return undefined;
|
|
308
|
+
}
|
|
309
|
+
const name = words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
310
|
+
return { name, typeHint };
|
|
311
|
+
}
|
|
196
312
|
// The naive `line.search(/=(?!=)/)` this replaced had a real false-positive: a CSS attribute
|
|
197
313
|
// selector like `input[name="wrongname"]` contains a completely unrelated `=` inside the string
|
|
198
314
|
// literal, which got misread as an assignment and produced garbage ("name" extracted instead of
|
|
@@ -367,7 +483,16 @@ callSite) {
|
|
|
367
483
|
}
|
|
368
484
|
else {
|
|
369
485
|
const variableName = resolvedSourceLocation ? extractVariableName(resolvedSourceLocation) : undefined;
|
|
370
|
-
|
|
486
|
+
// decodeVariableName upgrades "txtUserName" to "User Name (textbox)" when it can;
|
|
487
|
+
// falls back to the raw identifier itself when nothing meaningful survives
|
|
488
|
+
// decoding, so this is never worse than what extractVariableName alone gave us.
|
|
489
|
+
const decoded = variableName ? decodeVariableName(variableName) : undefined;
|
|
490
|
+
const variableDescription = decoded
|
|
491
|
+
? decoded.typeHint
|
|
492
|
+
? `${decoded.name} (${decoded.typeHint})`
|
|
493
|
+
: decoded.name
|
|
494
|
+
: variableName;
|
|
495
|
+
effectiveDescription = variableDescription ?? description ?? selector ?? `${kind} action ${String(prop)}`;
|
|
371
496
|
}
|
|
372
497
|
const healing = await (0, healer_1.healActionFailure)({
|
|
373
498
|
action: String(prop),
|
|
@@ -392,6 +517,40 @@ callSite) {
|
|
|
392
517
|
}
|
|
393
518
|
};
|
|
394
519
|
}
|
|
520
|
+
// A popup is just as much "what the test did" as the page that opened it, but it's
|
|
521
|
+
// obtained via a Page-level event (`page.on('popup', ...)`/`page.waitForEvent('popup')`),
|
|
522
|
+
// not through anything the ACTIONS/factory branches above already cover. Only `Page`
|
|
523
|
+
// objects fire this event (a Locator/Frame/FrameLocator never does), so this is gated to
|
|
524
|
+
// `kind === 'page'` specifically, mirroring how `frameLocator`/`getDurable` above are
|
|
525
|
+
// gated to their own kinds. Same reasoning as bindContext's own `on`/`once`/`newPage`
|
|
526
|
+
// interception just below it in this file: rewrapping the *value handed back to the
|
|
527
|
+
// caller*, since a plain `context.on('page', ...)`-style listener attached to the raw
|
|
528
|
+
// target would never reach code holding only this Proxy.
|
|
529
|
+
if (kind === 'page' && (prop === 'on' || prop === 'once')) {
|
|
530
|
+
return (event, handler) => {
|
|
531
|
+
if (event === 'popup') {
|
|
532
|
+
const wrappedHandler = (popup) => handler(bindTargetActions(popup, 'page'));
|
|
533
|
+
return targetObject[prop](event, wrappedHandler);
|
|
534
|
+
}
|
|
535
|
+
return targetObject[prop](event, handler);
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
if (kind === 'page' && prop === 'waitForEvent') {
|
|
539
|
+
return async (...args) => {
|
|
540
|
+
// Deliberately NOT extracted into an intermediate `const` first — `const m =
|
|
541
|
+
// targetObject[prop]; m(...args)` detaches the call from `targetObject`, so `this`
|
|
542
|
+
// inside Playwright's own implementation becomes undefined (confirmed live: threw
|
|
543
|
+
// "Cannot read properties of undefined" before this was written as a single inline
|
|
544
|
+
// expression instead). `(targetObject[prop] as Fn)(...args)` stays a real method call
|
|
545
|
+
// — the `as` cast is erased at runtime, leaving a plain `obj[prop](...)` expression,
|
|
546
|
+
// which JS's own call semantics still bind to `targetObject`.
|
|
547
|
+
const result = await targetObject[prop](...args);
|
|
548
|
+
if (args[0] === 'popup' && result) {
|
|
549
|
+
return bindTargetActions(result, 'page');
|
|
550
|
+
}
|
|
551
|
+
return result;
|
|
552
|
+
};
|
|
553
|
+
}
|
|
395
554
|
}
|
|
396
555
|
const value = Reflect.get(target, prop, receiver);
|
|
397
556
|
return typeof value === 'function' ? value.bind(target) : value;
|
|
@@ -416,9 +575,13 @@ function bindFrameActions(frame) {
|
|
|
416
575
|
// listening via `context.on('page', ...)` and discarding the result would never reach the test:
|
|
417
576
|
// `const popup = await context.newPage()` returns Playwright's own raw object directly, bypassing
|
|
418
577
|
// any side-effecting listener entirely. So this wraps the *methods that hand pages back to the
|
|
419
|
-
// caller* instead — newPage(), pages(),
|
|
420
|
-
// whatever it's called with is the wrapped page, not the raw one)
|
|
421
|
-
//
|
|
578
|
+
// caller* instead — newPage(), pages(), on('page'/'popup', handler) (rewriting the handler so
|
|
579
|
+
// whatever it's called with is the wrapped page, not the raw one), and waitForEvent('page') (the
|
|
580
|
+
// idiomatic `const popup = await context.waitForEvent('page')` pattern — confirmed live to
|
|
581
|
+
// silently return a raw, non-healing page before this was added: no [self-healer] line at all on
|
|
582
|
+
// a deliberately broken locator inside the resulting page, just a plain Playwright timeout) —
|
|
583
|
+
// together this is what actually gets the healing-aware Proxy into the test's hands regardless of
|
|
584
|
+
// how it obtained the new page.
|
|
422
585
|
function bindContext(context) {
|
|
423
586
|
if (knownProxies.has(context)) {
|
|
424
587
|
return context;
|
|
@@ -443,6 +606,15 @@ function bindContext(context) {
|
|
|
443
606
|
return target[prop](event, handler);
|
|
444
607
|
};
|
|
445
608
|
}
|
|
609
|
+
if (prop === 'waitForEvent') {
|
|
610
|
+
return async (...args) => {
|
|
611
|
+
const result = await target.waitForEvent(...args);
|
|
612
|
+
if ((args[0] === 'page' || args[0] === 'popup') && result) {
|
|
613
|
+
return bindPageActions(result);
|
|
614
|
+
}
|
|
615
|
+
return result;
|
|
616
|
+
};
|
|
617
|
+
}
|
|
446
618
|
const value = Reflect.get(target, prop, receiver);
|
|
447
619
|
return typeof value === 'function' ? value.bind(target) : value;
|
|
448
620
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locator.binding.js","sourceRoot":"","sources":["../../src/bindings/locator.binding.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"locator.binding.js","sourceRoot":"","sources":["../../src/bindings/locator.binding.ts"],"names":[],"mappings":"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"}
|