tamash-playwright 0.8.0-beta.1 → 0.8.0

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 CHANGED
@@ -9,11 +9,6 @@ HEALER_ENABLED=true
9
9
  # for setup.
10
10
  HEALER_PROVIDER=ollama
11
11
 
12
- # Optional, off by default. If a locator gets healed but the action on it still fails (e.g. the
13
- # element is covered or needs scrolling into view), the AI can pick a recovery tactic (scroll,
14
- # force, wait, or dispatch the DOM event directly) instead of giving up immediately.
15
- # HEALER_ACTION_RECOVERY_ENABLED=true
16
-
17
12
  # --- Ollama Cloud (https://ollama.com) ---
18
13
  OLLAMA_MODEL=gpt-oss:120b
19
14
  OLLAMA_API_KEY=
@@ -34,16 +29,19 @@ OLLAMA_API_KEY=
34
29
  # GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai
35
30
 
36
31
  # --- Claude subscription (no API key — uses your existing Claude Pro/Max/Team/Enterprise subscription) ---
37
- # Requires: npm install @anthropic-ai/claude-agent-sdk
38
- # Locally: run `claude login` once no other setup needed.
32
+ # Requires: npm install -g @anthropic-ai/claude-code (the CLI, so `claude login` exists to run),
33
+ # and npm install @anthropic-ai/claude-agent-sdk (the SDK tamash-playwright actually calls).
34
+ # Locally: run `claude login` once.
39
35
  # In CI: run `claude setup-token` once to mint a 12-month token, then set it as a CI secret below.
40
36
  # CLAUDE_SUBSCRIPTION_MODEL=haiku
41
37
  # CLAUDE_CODE_OAUTH_TOKEN=
42
38
 
43
39
  # --- GitHub Copilot subscription (no API key — uses your existing Copilot subscription or free tier) ---
44
- # Requires: npm install @github/copilot-sdk, and the `copilot` CLI installed and authenticated.
45
- # Locally: sign in with the `copilot` CLI once — no other setup needed.
46
- # In GitHub Actions CI: no secret needed add `permissions: { copilot-requests: write }` to the
47
- # workflow job and the ambient GITHUB_TOKEN is used automatically.
48
- # In other CI systems: set GITHUB_TOKEN to a PAT with the "Copilot Requests" scope.
40
+ # Requires: npm install -g @github/copilot (the CLI, so `copilot` exists to sign in with),
41
+ # and npm install @github/copilot-sdk (the SDK tamash-playwright actually calls).
42
+ # Locally: sign in with the `copilot` CLI once.
43
+ # In GitHub Actions CI: add `permissions: { copilot-requests: write }` to the workflow job but
44
+ # only works if the repo's owning account/org has Copilot enabled; see README for the personal-
45
+ # account PAT fallback (COPILOT_GITHUB_TOKEN) if it doesn't.
46
+ # In other CI systems: set GITHUB_TOKEN (or COPILOT_GITHUB_TOKEN) to a PAT with "Copilot Requests".
49
47
  # COPILOT_SUBSCRIPTION_MODEL=mai-code-1-flash-picker
package/README.md CHANGED
@@ -41,9 +41,6 @@ HEALER_ENABLED=true
41
41
  # Pick one: ollama | openai | anthropic | gemini | claude-subscription | copilot-subscription
42
42
  HEALER_PROVIDER=ollama
43
43
 
44
- # Optional, off by default — see "Action recovery" below.
45
- # HEALER_ACTION_RECOVERY_ENABLED=true
46
-
47
44
  # --- Ollama Cloud (https://ollama.com) ---
48
45
  OLLAMA_MODEL=gpt-oss:120b
49
46
  OLLAMA_API_KEY=
@@ -95,8 +92,14 @@ If you don't have an API key issued to you but do have a personal Claude (Pro/Ma
95
92
  **Claude subscription** — works both locally and unattended in CI:
96
93
 
97
94
  ```sh
98
- npm install @anthropic-ai/claude-agent-sdk
99
- claude login # one-time, locally
95
+ npm install -g @anthropic-ai/claude-code # the CLI itself — needed so `claude login` exists to run.
96
+ # @anthropic-ai/claude-agent-sdk (below) bundles its own
97
+ # copy of the Claude Code binary too, but only for its own
98
+ # internal use — it exposes no `claude` command of its own,
99
+ # so this separate install is still required for the login
100
+ # step below.
101
+ npm install @anthropic-ai/claude-agent-sdk # the SDK — what tamash-playwright actually calls
102
+ claude login # one-time, locally
100
103
  ```
101
104
 
102
105
  ```sh
@@ -113,8 +116,10 @@ CLAUDE_CODE_OAUTH_TOKEN=the-token-you-copied
113
116
  **GitHub Copilot subscription** — works locally, and unattended in GitHub Actions specifically:
114
117
 
115
118
  ```sh
116
- npm install @github/copilot-sdk
117
- copilot # sign in once, locally
119
+ npm install -g @github/copilot # the CLI itself — needed so `copilot` exists to sign in with
120
+ npm install @github/copilot-sdk # the SDK — what tamash-playwright actually calls (wraps the CLI,
121
+ # doesn't replace it, so both installs above are required)
122
+ copilot # sign in once, locally
118
123
  ```
119
124
 
120
125
  ```sh
@@ -122,14 +127,25 @@ HEALER_PROVIDER=copilot-subscription
122
127
  COPILOT_SUBSCRIPTION_MODEL=mai-code-1-flash-picker
123
128
  ```
124
129
 
125
- In a GitHub Actions workflow, no secret is needed at all — just grant the job permission to use it:
130
+ In a GitHub Actions workflow, no secret is needed at all *if the repo's owning account/org has Copilot enabled* — just grant the job permission to use it:
126
131
 
127
132
  ```yaml
128
133
  permissions:
129
134
  copilot-requests: write
130
135
  ```
131
136
 
132
- Outside GitHub Actions, set `GITHUB_TOKEN` to a personal access token with the "Copilot Requests" scope instead.
137
+ **Gotcha, confirmed by real testing, not just docs**: this only works if Copilot is enabled for whoever *owns the repo* — an organization, if that's who the repo belongs to. A personal Copilot subscription on your own account does **not** carry over to a separate organization's repos, even one you administer yourself; organizations need their own Copilot enablement (Business/Enterprise plan, or an explicit org policy), which is a different thing from an individual plan. If the job fails with `Authorization error, you may need to run /login` despite the permission being set correctly, this is almost certainly why.
138
+
139
+ The fix: use a personal-account PAT instead of the ambient token, so the request explicitly carries your own subscription regardless of which org's repo the workflow runs in:
140
+
141
+ 1. Create a fine-grained personal access token: **Resource owner** = your personal account (not the org), **Repository access** = Public Repositories (read-only) is enough if the repo is public, **Account permissions → Copilot Requests** = Read.
142
+ 2. Add it as a repo secret — any name works, but `COPILOT_GITHUB_TOKEN` is worth using specifically, since that's the exact env var the Copilot SDK checks *ahead of* `GITHUB_TOKEN` in its own auth precedence:
143
+ ```yaml
144
+ env:
145
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
146
+ ```
147
+
148
+ Outside GitHub Actions entirely, the same PAT approach applies — set `GITHUB_TOKEN` (or `COPILOT_GITHUB_TOKEN`) to a personal access token with the "Copilot Requests" scope.
133
149
 
134
150
  **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).
135
151
 
@@ -160,10 +176,9 @@ It checks:
160
176
 
161
177
  1. **AI connectivity** — confirms `HEALER_ENABLED`/`HEALER_PROVIDER` are set correctly and actually calls your configured provider to make sure the API key and model work.
162
178
  2. **`actionTimeout` configuration** — checks your `playwright.config.ts` for an `actionTimeout` set well below your test `timeout` (see above); flags it if missing or too close to the test timeout, since that silently starves self-healing of any time to run.
163
- 3. **Action recovery status** — whether `HEALER_ACTION_RECOVERY_ENABLED` is on (see below).
164
- 4. **Vision capability** — whether your configured model is expected to support the screenshot-based fallback (see below), based on its name.
165
- 5. **Missing `.describe()` labels** — scans your test files (`tests/` by default, or pass `--dir <path>`) for locators that don't have a `.describe('...')` label, and flags the ones most worth fixing (raw CSS/XPath selectors first).
166
- 6. **Locators written directly in test files** — flags any locator defined inline in a test rather than inside a Page Object class, which is a Playwright best practice regardless of self-healing: it keeps tests readable and means a UI change only needs a fix in one place.
179
+ 3. **Vision capability** — whether your configured model is expected to support the screenshot-based fallback (see below), based on its name.
180
+ 4. **Missing `.describe()` labels** — scans your test files (`tests/` by default, or pass `--dir <path>`) for locators that don't have a `.describe('...')` label, and flags the ones most worth fixing (raw CSS/XPath selectors first).
181
+ 5. **Locators written directly in test files** — flags any locator defined inline in a test rather than inside a Page Object class, which is a Playwright best practice regardless of self-healing: it keeps tests readable and means a UI change only needs a fix in one place.
167
182
 
168
183
  If it finds issues, the fastest fix is to open the project in an AI coding assistant (Claude Code, Cursor, GitHub Copilot, etc.) and ask it to address what it flagged — add `.describe()` calls, or extract locators into Page Object classes. You can also add a standing rule to that assistant's instructions/skill file (e.g. `CLAUDE.md`, `.cursor/rules`, `.github/copilot-instructions.md`) so it follows both practices automatically on any new test code going forward.
169
184
 
@@ -263,10 +278,6 @@ Not every healed selector is equally durable. One with a real id, test id, or ac
263
278
 
264
279
  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`), `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 and API key from Step 2. Run `npx tamash-playwright doctor` to check whether your configured model is expected to support this.
265
280
 
266
- ## Action recovery (optional)
267
-
268
- Occasionally a locator heals correctly — the AI found the right element — but the *action* on it still fails, e.g. it's covered by an overlay or needs scrolling into view first. Set `HEALER_ACTION_RECOVERY_ENABLED=true` to let the AI pick a recovery tactic from a fixed, safe set (scroll into view, retry bypassing actionability checks, wait briefly and retry, or dispatch the DOM event directly) before giving up. It's off by default since it's a second, more speculative layer of intervention beyond selector healing — the AI only ever picks from that fixed menu, it never decides how to interact with the page on its own.
269
-
270
281
  ## Not paying for the same heal twice
271
282
 
272
283
  Once a locator heals successfully, `tamash-playwright` remembers the fix in `.tamash-playwright/heals.jsonl` — the same file `apply-heals` reads (see below). The next time that exact locator breaks the same way, it tries the previously-confirmed selector *first*, with no ARIA snapshot and no AI call. Only if that no longer works (the page changed again) does it fall through to a fresh snapshot-and-AI-call, exactly as before — so there's no correctness risk in trying the cached selector, only a cost/time saving when it still works.
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAuJA,wBAAsB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBlE"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AA8IA,wBAAsB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBlE"}
@@ -19,15 +19,6 @@ async function checkProviderConnectivity() {
19
19
  console.log(' Healing is currently OFF. Set HEALER_ENABLED=true (or remove the line) to turn it back on.');
20
20
  return;
21
21
  }
22
- console.log(`HEALER_ACTION_RECOVERY_ENABLED: ${process.env.HEALER_ACTION_RECOVERY_ENABLED ?? '(unset — defaults to false)'}`);
23
- if ((0, healer_1.isActionRecoveryEnabled)()) {
24
- console.log(' Action recovery is ON — if a locator heals but the action on it still fails, the AI may retry');
25
- console.log(' it (scroll into view, force, wait, or dispatch the DOM event directly) before giving up.');
26
- }
27
- else {
28
- console.log(' Action recovery is OFF (opt-in, off by default). Set HEALER_ACTION_RECOVERY_ENABLED=true to turn it on.');
29
- }
30
- console.log('');
31
22
  const providerName = process.env.HEALER_PROVIDER;
32
23
  if (!providerName) {
33
24
  console.log('[WARN] HEALER_PROVIDER is not set. No AI provider is configured, so self-healing will never');
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamash-playwright",
3
- "version": "0.8.0-beta.1",
3
+ "version": "0.8.0",
4
4
  "description": "Plug and Play Self-healing for Playwright and automatically recovers broken selectors using an AI model (Ollama, OpenAI, Anthropic, Gemini, or a Claude/GitHub Copilot subscription).",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/usage.md CHANGED
@@ -17,7 +17,6 @@ For a quicker, high-level overview see [README.md](README.md); this file is the
17
17
  - [Finding elements by structure](#when-theres-no-name-to-match-finding-elements-by-structure)
18
18
  - [When a fix needs a second look](#when-a-fix-needs-a-second-look)
19
19
  - [Vision fallback](#when-text-alone-isnt-enough-vision-fallback)
20
- - [Action recovery](#action-recovery-optional)
21
20
  - [Not paying for the same heal twice](#not-paying-for-the-same-heal-twice)
22
21
  - [Making a heal permanent: `apply-heals`](#making-a-heal-permanent-apply-heals)
23
22
  - [Proving a fix works: `verify-heals.cjs`](#proving-a-fix-actually-works-verify-healscjs)
@@ -55,9 +54,6 @@ HEALER_ENABLED=true
55
54
  # Pick one: ollama | openai | anthropic | gemini
56
55
  HEALER_PROVIDER=ollama
57
56
 
58
- # Optional, off by default — see "Action recovery" below.
59
- # HEALER_ACTION_RECOVERY_ENABLED=true
60
-
61
57
  # --- Ollama Cloud (https://ollama.com) ---
62
58
  OLLAMA_MODEL=gpt-oss:120b
63
59
  OLLAMA_API_KEY=
@@ -108,10 +104,9 @@ npx tamash-playwright doctor
108
104
  |---|-------|---------------|
109
105
  | 1 | AI connectivity | Confirms `HEALER_ENABLED`/`HEALER_PROVIDER` are set, and actually calls the provider to verify the key and model work. |
110
106
  | 2 | `actionTimeout` | Reads `playwright.config.ts`; flags a missing or too-close-to-`timeout` value. |
111
- | 3 | Action recovery | Reports whether `HEALER_ACTION_RECOVERY_ENABLED` is on. |
112
- | 4 | Vision capability | Checks by name whether your configured model is expected to support the screenshot fallback. |
113
- | 5 | Missing `.describe()` | Scans `tests/` (or `--dir <path>`) for locators without a label, raw CSS/XPath first. |
114
- | 6 | Inline locators | Flags locators written directly in test files rather than a Page Object class. |
107
+ | 3 | Vision capability | Checks by name whether your configured model is expected to support the screenshot fallback. |
108
+ | 4 | Missing `.describe()` | Scans `tests/` (or `--dir <path>`) for locators without a label, raw CSS/XPath first. |
109
+ | 5 | Inline locators | Flags locators written directly in test files rather than a Page Object class. |
115
110
 
116
111
  If it finds issues, the fastest fix is to open the project in an AI coding assistant and ask it to address what's flagged — add `.describe()` calls, or extract locators into Page Objects. A standing rule in that assistant's instructions file (`CLAUDE.md`, `.cursor/rules`, etc.) keeps it doing both automatically going forward.
117
112
 
@@ -208,12 +203,6 @@ If the retry doesn't resolve either, healing falls through to the vision fallbac
208
203
 
209
204
  Sometimes an element has nothing useful to match on by text — an icon-only button with no label, or several visually distinct elements that look identical in the accessibility tree. If your configured model supports image input (`gpt-4o`, `claude-haiku-4-5`, `gemini-3.6-flash`, …), `tamash-playwright` automatically falls back to a screenshot-based search after the normal text attempt fails — same provider, same key, no separate setup. Run `npx tamash-playwright doctor` to check whether your model is expected to support it.
210
205
 
211
- ## Action recovery (optional)
212
-
213
- Occasionally a locator heals correctly — the AI found the right element — but the *action* on it still fails: covered by an overlay, needs scrolling into view first. Set `HEALER_ACTION_RECOVERY_ENABLED=true` to let the AI pick a tactic from a fixed, safe menu (scroll into view, bypass actionability checks, wait and retry, or dispatch the DOM event directly) before giving up.
214
-
215
- Off by default — it's a second, more speculative layer beyond selector healing. The AI only ever picks from that fixed menu; it never decides how to interact with the page on its own.
216
-
217
206
  ## Not paying for the same heal twice
218
207
 
219
208
  Once a locator heals successfully, `tamash-playwright` remembers the fix in `.tamash-playwright/heals.jsonl`. The next time that exact locator breaks the same way, it tries the previously-confirmed selector *first* — no ARIA snapshot, no AI call. Only if that no longer works does it fall through to a fresh snapshot-and-AI-call, exactly as before.
@@ -512,7 +501,6 @@ The same detail prints to the console as it happens:
512
501
  |----------|---------|---------|
513
502
  | `HEALER_ENABLED` | `true` | Master on/off switch. Any value other than `false`/`0` leaves healing on. |
514
503
  | `HEALER_PROVIDER` | unset | `ollama` \| `openai` \| `anthropic` \| `gemini`. Unset or missing key/model still allows cache hits, just no fresh AI calls. |
515
- | `HEALER_ACTION_RECOVERY_ENABLED` | `false` | Opt-in second-layer recovery for actionability failures on an already-correctly-healed locator. |
516
504
  | `OLLAMA_MODEL` / `OLLAMA_API_KEY` | — | Ollama Cloud provider config. |
517
505
  | `OPENAI_MODEL` / `OPENAI_API_KEY` | — | OpenAI provider config. |
518
506
  | `ANTHROPIC_MODEL` / `ANTHROPIC_API_KEY` | — | Anthropic (Claude) provider config. |
@@ -522,7 +510,7 @@ The same detail prints to the console as it happens:
522
510
 
523
511
  | Command | Flags | What it does |
524
512
  |---------|-------|---------------|
525
- | `npx tamash-playwright doctor` | `--dir <path>` | Pre-flight checks: AI connectivity, `actionTimeout`, action recovery, vision capability, missing `.describe()`, inline locators. |
513
+ | `npx tamash-playwright doctor` | `--dir <path>` | Pre-flight checks: AI connectivity, `actionTimeout`, vision capability, missing `.describe()`, inline locators. |
526
514
  | `npx tamash-playwright apply-heals` | `--dry-run` | Preview fixes without writing anything (including `verify-heals.cjs` — see below). |
527
515
  | | `--logs-dir <path>` | Merge every `heals.jsonl` found under `<path>` (any nesting) instead of the local log — for sharded CI. |
528
516