@andwhy/e2e-pipeline 0.13.2 → 0.14.1

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.
@@ -0,0 +1,547 @@
1
+ ---
2
+ name: playwright-test-pipeline
3
+ description: Guides the full workflow for creating and maintaining Playwright
4
+ end-to-end tests with the planner/generator/healer agents — setup check,
5
+ Plan → Generate → Heal, local runs, Checkly preview validation, and
6
+ deployment. Use when the user wants to create, extend, or fix e2e/Playwright
7
+ tests, asks to "test" a page/feature/flow, or asks how the test pipeline
8
+ works.
9
+ metadata:
10
+ version: "0.14.1"
11
+ ---
12
+
13
+ # Playwright Test Pipeline
14
+
15
+ You are guiding a person through this project's test pipeline. They may not
16
+ know it exists — narrate briefly at each phase, and pause at the marked
17
+ decision points. The delegation rules, the project test rules, and the exact
18
+ prompt templates for the agents are all in this skill; follow them, do not
19
+ improvise your own prompts to the agents.
20
+
21
+ Setup and workflow docs (for humans): https://app.notion.com/p/31ff837b6270805d8922c4a7c7beb6b0
22
+
23
+ ## Delegation rules (always)
24
+
25
+ - When the user says "Use the playwright-test-planner/generator/healer agent",
26
+ or the pipeline reaches a step owned by one of them, delegate via the
27
+ **Agent** tool with the matching `subagent_type`. The agents ship with the
28
+ `e2e-pipeline` plugin and register under their namespaced names:
29
+ `e2e-pipeline:playwright-test-planner`, `e2e-pipeline:playwright-test-generator`,
30
+ `e2e-pipeline:playwright-test-healer` (the plain name also resolves when it
31
+ is unique in the session).
32
+ - **Never call the `playwright-test` MCP tools directly** from the
33
+ orchestrating session. They belong to the agents.
34
+ - **Do not implement Playwright specs in the orchestrating turn.** Writing or
35
+ editing `*.spec.js` / `*.spec.ts` test bodies yourself bypasses replay, the
36
+ generator's MCP tools, and the project rules. Generation goes through the
37
+ generator; failing tests go through the healer.
38
+ - **Plans:** read `tests/e2e/<feature>/<name>.plan.md` yourself and pass its
39
+ contents in the Agent prompt. **Never ask the user to paste the plan** into
40
+ chat.
41
+
42
+ | Trigger phrase in user prompt | `subagent_type` | Purpose |
43
+ | ---------------------------------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
44
+ | "Use the playwright-test-planner agent to …" | `e2e-pipeline:playwright-test-planner` | Explores the live site, discovers real selectors/DOM, writes a `tests/e2e/<name>.plan.md` |
45
+ | "Use the playwright-test-generator agent to …" | `e2e-pipeline:playwright-test-generator` | Reads a plan, replays steps in a browser, writes or extends `tests/e2e/<group>.spec.js` or `.spec.ts` (**Project test rules** §7–8) |
46
+ | "Use the playwright-test-healer agent to …" | `e2e-pipeline:playwright-test-healer` | Runs tests, debugs failures, fixes code, re-runs until green |
47
+
48
+ ## Phase 0 — Setup (always first)
49
+
50
+ Verify, in order:
51
+
52
+ 1. The three agents are available in this session. A repo is in one of two
53
+ states, and both are fine:
54
+ - **Plugin:** the agents are listed for the Agent tool as
55
+ `e2e-pipeline:playwright-test-planner`,
56
+ `e2e-pipeline:playwright-test-generator` and
57
+ `e2e-pipeline:playwright-test-healer`. They come from the `e2e-pipeline`
58
+ plugin, which the repo enables through `.claude/settings.json`
59
+ (`enabledPlugins` → `e2e-pipeline@andwhy`).
60
+ - **Original flow (repo scaffolded before 0.14.0):** the agents are files
61
+ under `.claude/agents/playwright-test-*.md` and are listed by their plain
62
+ names `playwright-test-planner`, `playwright-test-generator`,
63
+ `playwright-test-healer`. Use those names for `subagent_type` wherever
64
+ this skill writes the `e2e-pipeline:` form. Do not suggest migrating to
65
+ the plugin unless the user asks; the repo works as it is.
66
+ 2. `.mcp.json` at project root defines the `playwright-test` server, pointed
67
+ at `playwright.mcp.config.{ts,mjs}` (which must exist — it lets the MCP run
68
+ seeds that `testIgnore` hides from normal runs)
69
+ 3. A `playwright.config.{ts,mjs}` and `checkly.config.{ts,mjs}` exist
70
+
71
+ ### If the agents are missing but the repo is otherwise set up
72
+
73
+ Check `.claude/settings.json` for the `e2e-pipeline@andwhy` entry.
74
+
75
+ - **Entry present, agents absent:** the plugin has not loaded in this
76
+ session. On a developer machine that means the session started before the
77
+ settings were committed or the folder was trusted — the plugin installs at
78
+ the next session start, so tell the user to restart and re-ask. In a
79
+ claude.ai/code cloud session the repo's plugin settings are not loaded at
80
+ all; say so plainly and stop — do not run the scaffold again, it will not
81
+ help, and do not improvise (see the hard stop below).
82
+ - **Entry absent, repo copies present** (`.claude/agents/playwright-test-*.md`
83
+ exist): original flow, nothing is missing — continue with the plain agent
84
+ names. Migrating to the plugin is the user's decision; when they ask, the
85
+ scaffold with `--force` as below writes the plugin entry and removes the
86
+ copies, which would otherwise shadow the plugin's agents.
87
+ - **Entry absent, no repo copies:** the pipeline is not installed here. Run
88
+ the scaffold as below.
89
+
90
+ ### If anything is missing, install it — do not just bounce the user
91
+
92
+ Say what is missing, then offer to run the scaffold. Do not run it without
93
+ agreement: it installs dependencies and writes files.
94
+
95
+ **Always pass `--format` explicitly.** Without it the CLI opens an interactive
96
+ prompt, and in a non-interactive shell that prompt resolves empty and the CLI
97
+ exits silently having done nothing — it looks like it worked. Pick the format
98
+ from the repo: `ts` when there is a `tsconfig.json`, otherwise `mjs`.
99
+
100
+ ```bash
101
+ pnpm dlx @andwhy/e2e-pipeline init --format ts # or --format mjs
102
+ ```
103
+
104
+ Add `--force` only when updating an existing install. It regenerates the
105
+ package-owned files (`.mcp.json`, `playwright.mcp.config.*`), removes
106
+ pre-plugin copies of the agents, rules and skill from `.claude/`, and never
107
+ touches the configs or the workflows. Add `--update-workflows` as well when
108
+ the repo still carries the full-length workflows from before 0.14.0: it
109
+ replaces them with the short callers of the pipeline's reusable workflows
110
+ and removes the prompt and script copies only those old workflows read.
111
+
112
+ Then read the output back to the user: what was created, what was skipped,
113
+ what was removed, and any warning it printed (it flags workflows from
114
+ before 0.14.0 and names the flag that replaces them; have the user review
115
+ that diff, since a repo customization becomes a `with:` input in the
116
+ caller).
117
+ Docs: https://app.notion.com/p/31ff837b6270805d8922c4a7c7beb6b0
118
+
119
+ **After a mid-session install, a restart is required — this is a hard stop.**
120
+ Claude Code installs plugins and registers subagents and `.mcp.json` servers
121
+ at session start, so the planner/generator/healer and the `playwright-test`
122
+ browser tools do not exist in the session that just scaffolded them. Do NOT
123
+ work around this: no inlining an agent definition into a general-purpose
124
+ agent, no hand-writing plans or specs from source code — without the browser
125
+ tools that produces unverified selectors, which is exactly what this pipeline
126
+ exists to prevent. Finish Phase 0 (configs, reachable URL), then tell the
127
+ user to restart the session and re-ask; Phase 0 will pass and planning starts
128
+ for real.
129
+
130
+ ### Then finish the configuration before planning
131
+
132
+ The scaffold writes templates, not a working setup. Walk these with the user:
133
+
134
+ 1. `playwright.config` — `baseURL` for local runs.
135
+ 2. `checkly.config` — real `projectName` and `logicalId`, the production
136
+ domain(s) in `environmentVariables`, `testCommand` (see Phase 5), and the
137
+ check-suite `name` — that is what teammates see in the Checkly dashboard
138
+ and in alerts. **Ask the user what to call it** unless the repo makes it
139
+ obvious (a single clear brand or product name); do not silently invent
140
+ one. Also set
141
+ `installCommand: "pnpm install --ignore-scripts"` — Checkly's runner gets a
142
+ bundle of test files, not the repo, so a project postinstall (codegen etc.)
143
+ fails there on missing files. Placeholder values (`my-app`, `example.com`)
144
+ left in place will block Phase 4; local work is unaffected.
145
+ 3. A reachable URL for the planner: a running dev server or a deployed
146
+ environment. **Confirm this before Phase 1** — the planner explores a live
147
+ page, and pointing it at an empty or unreachable app produces a plan that
148
+ asserts nothing useful.
149
+ 4. **Repository secrets for the workflows**: if the scaffold just created
150
+ `.github/workflows/`, tell the user now — not at merge time — to add the
151
+ repository secrets (GitHub → Settings → Secrets and variables → Actions).
152
+ You cannot add them; a person must. Without them the first PR push and the
153
+ first merge fail CI in ways that look like pipeline bugs.
154
+ - `CHECKLY_API_KEY` — 1Password ("Checkly") first; else Checkly → User
155
+ Settings → API keys. The key is shown once, at creation — tell the user
156
+ to save it to 1Password immediately.
157
+ - `CHECKLY_ACCOUNT_ID` — Checkly → Account Settings → General; also in
158
+ 1Password.
159
+ - `VERCEL_AUTOMATION_BYPASS_SECRET` — Vercel → project → Settings →
160
+ Deployment Protection → Protection Bypass for Automation. Per project —
161
+ never copied from another repo.
162
+ - `SLACK_WEBHOOK_URL` — the **org-shared** e2e-channel webhook: paste the
163
+ value from 1Password ("e2e Slack webhook"). Same value in every repo;
164
+ do not walk the user through creating a Slack app or webhook — routing
165
+ to the project channel happens via a Slack rule in Phase 5.
166
+ - `ANTHROPIC_API_KEY` usually needs **no action**: it is an
167
+ organization-level secret inherited by every repo — do not walk the
168
+ user through adding it up front. But it can fail to reach a repo
169
+ (org-secret scoping, or a stale stored value): if a heal run's agent
170
+ step fails to authenticate, have the user add a repository-level
171
+ `ANTHROPIC_API_KEY` — a repo secret with the same name overrides the
172
+ organization one.
173
+ 5. **Existing tests under `tests/`** (unit, a11y — the scaffold lists them as
174
+ "outside tests/e2e"): leave `testDir` at `./tests/e2e` and give that suite
175
+ its own Playwright project with its own `testDir` if it should run under
176
+ Playwright at all. **Never widen `testDir` to `./tests`** — that runs the
177
+ other suite in every browser project and mixes the suites. Checkly is
178
+ pinned to `tests/e2e` by `testCommand` either way.
179
+
180
+ ## Project test rules
181
+
182
+ These rules apply to **all** agents (generator, healer, and orchestrator).
183
+ Include them verbatim in every Agent prompt to the generator or healer.
184
+
185
+ 1. Every logical step MUST have a numbered comment above it
186
+ (e.g. `// 1. Navigate to the homepage`). Preserve existing step comments
187
+ when editing. Add them if missing.
188
+
189
+ 2. Never hardcode domains. Use `page.goto("/")` and derive the origin from the
190
+ live page URL.
191
+
192
+ 3. Every `test.describe` block MUST include a `beforeEach` that runs shared preview setup
193
+ from `tests/e2e/helpers/preview-consent-setup.js` or `.ts` (`prepareVercelPreviewPage`, and when tests
194
+ start after consent, `gotoPathAndAcceptCookies(page, baseURL, path)` with the correct
195
+ relative path). The scaffold ships `prepareVercelPreviewPage` — it exchanges
196
+ `VERCEL_AUTOMATION_BYPASS_SECRET` for Vercel's deployment-protection bypass cookie on the
197
+ first navigation and is a plain `goto` when the variable is unset. Extend the file with
198
+ project consent logic; do not reinvent it. The helper file extension must match rule 7.
199
+
200
+ 4. Never hardcode a single locale's URL pattern. Use a locale config map keyed
201
+ by bare hostname and resolve at runtime. Preview hosts (`*.vercel.app`) are
202
+ never in the map and must fall back to the primary production domain's
203
+ config (overridable via `PREVIEW_LOCALE_HOST`) — an exact-match-only lookup
204
+ skips the whole suite on every PR run.
205
+
206
+ 5. After all tests pass locally, verify with
207
+ `BASE_URL=<dev-url> pnpm playwright test` via the terminal tool. If failures
208
+ occur, fix and re-run until green.
209
+
210
+ **Local runs always pin `BASE_URL` on the command line** to the dev server
211
+ confirmed during setup (usually `http://localhost:3000`) — never rely on the
212
+ ambient environment. Repos commonly export `BASE_URL` for the app's own
213
+ purposes, pointed at the deployed site; an unpinned run silently targets
214
+ production, which does not contain the working tree's changes (the feature
215
+ under test, any `data-testid` additions). Deployed URLs enter the pipeline
216
+ only at preview validation and Checkly, always passed explicitly.
217
+
218
+ 6. **Test root:** Paths in this skill assume the default `tests/e2e/`, which keeps e2e specs
219
+ clear of unit tests in the same repo. **The repo wins over this default.** Check
220
+ `playwright.config.{ts,mjs}` for `testDir` and list existing `*.spec.*`; if the **e2e**
221
+ specs already live somewhere else (`tests/` flat, `e2e/`, `src/__tests__/`), write there
222
+ instead and read every `tests/e2e/…` path below as that directory. Never split a suite
223
+ across two roots. A non-e2e suite under `tests/` (unit, a11y) is **not** that signal:
224
+ leave `testDir` on the e2e root and give that suite its own Playwright project with its
225
+ own `testDir` — never widen `testDir` to cover both, which runs the other suite in every
226
+ browser project.
227
+
228
+ 7. **Spec language (generators only):** Repositories differ — some teams use **JavaScript**
229
+ for Playwright tests (`.spec.js`), others use **TypeScript** (`.spec.ts`). List
230
+ `tests/e2e/**/*.spec.*` and match the prevailing extension. If there are no specs yet, default
231
+ to `.spec.js` unless the project README or the user specifies TypeScript for tests. Helpers
232
+ and seeds must use the same language as specs. Do not add `.spec.ts` in a repo that already
233
+ uses `.spec.js` everywhere (and vice versa).
234
+
235
+ 8. **Feature groups (target layout):** Prefer **one spec file per feature group** (e.g.
236
+ `tests/e2e/map/map.spec.js`) with a single `test.describe('<Group name>', …)` and **multiple**
237
+ `test()` blocks — one per plan scenario — sharing one `beforeEach`. Do not default to one
238
+ file per scenario unless scenarios are unrelated. Prefer **lean** tests: assert user-visible
239
+ outcomes and regressions, not every intermediate DOM detail from the plan. Numbered
240
+ comments on **main** user steps only.
241
+
242
+ ## Phase 1 — Plan
243
+
244
+ Trigger when: user wants to create tests for a new feature, page, or user flow.
245
+
246
+ 1. Ask, if not already clear: which page/flow, which URL, and whether the
247
+ suite targets multiple domains (check `checkly.config` for the list).
248
+ 2. Use the **Agent** tool with `subagent_type: "e2e-pipeline:playwright-test-planner"`,
249
+ passing the URL and user flow description in the `prompt` (template below).
250
+ 3. The planner saves output to `tests/e2e/<feature>/<name>.plan.md`.
251
+ 4. **Decision point:** present the saved plan scenario-by-scenario and ask
252
+ what to keep, drop, or adjust. Do not generate before the user responds.
253
+
254
+ Prompt to forward:
255
+
256
+ ```
257
+ Create a test plan for: <FEATURE NAME>
258
+
259
+ Navigate to <URL> and explore the following user flow:
260
+ <USER'S FLOW STEPS>
261
+
262
+ While exploring, verify:
263
+ - Actual selectors (see **Locator strategy** under *Robustness patterns* below)
264
+ - Whether cookie consent or login gates appear
265
+ - DOM structure of key interactive elements
266
+ - If the suite targets **multiple domains**, explore **each** domain the tests will run against
267
+ (see *Multi-domain / multi-locale testing* — the plan must reflect every distinct host or market)
268
+
269
+ Generate a seed file at tests/e2e/<feature>/seed.spec.js or seed.spec.ts (same extension as
270
+ the rest of this repo's specs — see Project test rules §7) that handles the common setup
271
+ (navigation, cookie/auth consent, waiting for key elements) discovered during exploration.
272
+
273
+ Save the plan to tests/e2e/<feature>/<name>.plan.md using planner_save_plan.
274
+ All URLs must use relative paths — never localhost or absolute domains.
275
+ ```
276
+
277
+ ## Phase 2 — Generate
278
+
279
+ Trigger when: a `tests/e2e/<name>.plan.md` exists and the user wants generated test code.
280
+
281
+ **You (the orchestrating agent) own this step end-to-end.** The human does **not** need to
282
+ invoke the generator separately for each scenario or plan section — you chain **Agent** calls
283
+ to `playwright-test-generator` until the feature group is implemented (see **Important rules**).
284
+
285
+ 1. Read `tests/e2e/<feature>/<name>.plan.md` yourself to get the full plan content; never ask the user to paste it.
286
+ 2. Use the **Agent** tool with `subagent_type: "e2e-pipeline:playwright-test-generator"` — **once per scenario**
287
+ if building incrementally, **or** pass the **full plan** and all scenarios for the group in one
288
+ prompt if the generator can emit the whole file (**Project test rules** §8)
289
+ 3. Pass the **plan content** in the `prompt` (the generator subagent cannot read arbitrary paths from disk)
290
+ 4. Include the **project test rules** above in the prompt
291
+ 5. If the plan contains a "Recommended data-testid additions" table, include it verbatim — the generator adds those attributes before replaying steps
292
+ 6. Target **one spec file per feature group** (e.g. `tests/e2e/map/map.spec.js`) with a shared
293
+ `test.describe` and **multiple** `test()` blocks — merge with `edit` between runs if needed
294
+ 7. Tell the user which spec file is being written and when each scenario lands.
295
+
296
+ Prompt to forward (example — adjust per repo):
297
+
298
+ ```
299
+ Implement tests from the plan for this feature group. Target layout: one file, one describe, multiple tests (see project test rules §8).
300
+
301
+ - Group / describe: "<TOP-LEVEL PLAN HEADING e.g. Map>"
302
+ - File: tests/e2e/<feature>/<group>.spec.js (or `.spec.ts` per project)
303
+ - Seed: <SEED FILE PATH FROM PLAN>
304
+ - Viewport: <WIDTH>x<HEIGHT>
305
+
306
+ <plan>
307
+ <PASTE full plan OR the scenario block(s) you are implementing this run>
308
+ </plan>
309
+
310
+ If recommended data-testid additions exist, add them to source components before replaying steps.
311
+
312
+ After the spec is written or updated, run
313
+ BASE_URL=<dev-url> pnpm playwright test tests/e2e/<feature>/ (pin the dev server per rule 5).
314
+
315
+ ## Project test rules (follow these strictly)
316
+
317
+ <COPY the Project test rules section above into this prompt>
318
+ ```
319
+
320
+ ## Phase 3 — Run and heal
321
+
322
+ 1. Run `BASE_URL=<dev-url> pnpm playwright test tests/e2e/<feature>/`, pinning
323
+ the dev server confirmed in Phase 0. Phases 1–3 always target local: the
324
+ working tree's changes (the feature, any `data-testid` additions) exist
325
+ nowhere else, and an ambient `BASE_URL` export would silently point the run
326
+ at the deployed site. Deployed URLs enter only at Phase 4, always explicit.
327
+ 2. Green → Phase 4. Red → use the **Agent** tool with
328
+ `subagent_type: "e2e-pipeline:playwright-test-healer"`, passing the test file path and
329
+ the project test rules (template below). If the healer marks anything
330
+ `test.fixme()`, surface it explicitly — the user decides whether that is
331
+ acceptable.
332
+
333
+ Prompt to forward (always include the rules block):
334
+
335
+ ```
336
+ Run and fix the tests in tests/e2e/<name>.spec.js (or `.ts` per project)
337
+
338
+ If any tests fail:
339
+
340
+ - Debug each failure
341
+ - Examine the page state, selectors, and assertions
342
+ - Fix the test code
343
+ - Re-run until all tests pass locally
344
+
345
+ ## Project test rules (follow these strictly)
346
+
347
+ <COPY the Project test rules section above into this prompt>
348
+ ```
349
+
350
+ ## Important rules
351
+
352
+ - **Always delegate via the Agent tool.** Never call `playwright-test/*` tools directly.
353
+ - **Always plan before generating.** Use the planner to discover real selectors first.
354
+ - **Always read the plan file** before passing to the generator. The generator runs in
355
+ isolation — include the plan or scenario steps in the prompt.
356
+ - **You implement the full generate phase.** After plan approval, **you** invoke the
357
+ generator subagent **as many times as needed** (typically once per scenario, sequentially)
358
+ or supply the full multi-scenario prompt — **without** asking the user to run the generator
359
+ for each plan section. A single user request such as "Implement the tests from this plan" is enough.
360
+ - **Run generator subagent calls sequentially.** Never parallel — the MCP browser server is shared.
361
+ - **Do not interrupt.** Sending a message while a generator is running aborts it.
362
+ Wait for completion before proceeding.
363
+ - **data-testid additions are owned by the generator.** When the plan includes a
364
+ "Recommended data-testid additions" table, the generator subagent adds those
365
+ attributes to source components before replaying steps. The orchestrator must
366
+ forward the table verbatim in the generator prompt and must NOT edit source
367
+ components itself.
368
+ - **Present the plan for review** after planning. Unless the user narrows scope, **proceed
369
+ to generate all scenarios** for the agreed feature group (see **Project test rules** §8).
370
+ - **Generator and healer self-verify locally** with
371
+ `BASE_URL=<dev-url> pnpm playwright test` (pinned per **Project test rules** §5).
372
+ Cloud validation via `checkly pw-test` is a separate human step after pushing.
373
+ Only invoke the healer if a generated test fails locally.
374
+ - **Base URL**: local runs pin `BASE_URL=<dev-url>` on the command (**Project
375
+ test rules** §5); the config's localhost fallback is a safety net, not a
376
+ guarantee, because an exported `BASE_URL` overrides it silently.
377
+ - **Plan files** are saved at `tests/e2e/<feature>/<name>.plan.md`.
378
+ - **Test files** follow **Project test rules** §7–8 — typically `tests/e2e/<feature>/<group>.spec.js`
379
+ or `.spec.ts` with one `describe` and multiple tests.
380
+
381
+ ## Phase 4 — Preview validation (before merge)
382
+
383
+ 1. Auth check (first authenticated command in the pipeline): run
384
+ `pnpm checkly whoami`. If not logged in, have the user run
385
+ `pnpm checkly login` — it opens a browser flow, and the shared team
386
+ credentials are in 1Password (search "Checkly"). Local Playwright runs
387
+ never need this, and CI does not either — it uses the `CHECKLY_API_KEY` /
388
+ `CHECKLY_ACCOUNT_ID` repository secrets.
389
+ 2. **Decision point:** ask for the preview deployment URL, and settle how
390
+ Checkly's runners get through Vercel deployment protection. Preferred: the
391
+ project's automation bypass secret (Vercel project settings → Deployment
392
+ Protection; value in 1Password) — the scaffolded helper exchanges it for
393
+ Vercel's bypass cookie on first navigation. Fallback when the project has
394
+ no secret: a share link ("Anyone with the link") as the preview URL.
395
+ 3. Run: `pnpm checkly pw-test --env BASE_URL="<preview-url>" --env VERCEL_AUTOMATION_BYPASS_SECRET="<secret>" -- tests/e2e/<feature>/`
396
+ (omit the second `--env` on the share-link fallback). Never write the
397
+ secret into `checkly.config` — deployed monitors run against production
398
+ and do not need it.
399
+ 4. Failures here but not locally are usually cloud-environment issues
400
+ (timeouts, consent gates) — heal with that framing, then re-run.
401
+
402
+ The user can skip this phase; note that cloud behavior then goes unverified
403
+ until after merge.
404
+
405
+ ## Phase 5 — Merge and deployment
406
+
407
+ The scaffold ships three workflows (seeded once — existing ones are never
408
+ overwritten, except by an explicit `init --update-workflows`). Each is a
409
+ short caller of the matching reusable workflow in the pipeline repository,
410
+ so pipeline releases update the behavior without a change in the repo:
411
+
412
+ - `.github/workflows/pr-playwright-tests.yml` — runs the suite against the
413
+ PR's own Vercel preview on every push (`deployment_status` trigger, so the
414
+ preview is already live and contains the PR's changes), and comments the
415
+ result on the PR.
416
+ - `.github/workflows/checkly-deploy.yml` — when a **production deployment
417
+ succeeds** (`deployment_status` trigger), deploys the checks as Checkly
418
+ monitors. Not on merge: monitors must match what production serves, and a
419
+ merge that adds tests for new `data-testid`s would go red until the release
420
+ carrying them is live — with gated releases that gap can be days. A
421
+ `workflow_dispatch` fallback allows manual runs.
422
+ - `.github/workflows/checkly-heal.yml` — a failing deployed monitor
423
+ dispatches here (via the webhook alert channel below). An agent triages
424
+ first: a production regression or anything needing a behavioral app change
425
+ alerts Slack immediately; a stale test gets fixed and a flaky test gets
426
+ hardened — including behavior-neutral test hooks (`data-testid`) in app
427
+ source when the robust fix needs them — and opened as a PR that a human
428
+ must review. Test-only fixes are verified against production and on
429
+ Checkly's infrastructure; app-side hooks are validated by the PR's own
430
+ preview run (pr-playwright-tests). Inert until the webhook exists.
431
+
432
+ **Before the first merge, the repo needs secrets** (values in 1Password):
433
+ `CHECKLY_API_KEY` and `CHECKLY_ACCOUNT_ID` for the deploy and auto-heal,
434
+ `VERCEL_AUTOMATION_BYPASS_SECRET` for the PR run through deployment
435
+ protection, `SLACK_WEBHOOK_URL` for auto-heal notifications
436
+ (`ANTHROPIC_API_KEY` is inherited from the organization — nothing to add
437
+ unless a heal run fails to authenticate; then a repo-level secret of the
438
+ same name overrides it, see Phase 0).
439
+ If the scaffold just created the workflows, say so explicitly and list the
440
+ secrets — a merge without them fails CI and looks like a pipeline bug.
441
+
442
+ After merge, monitors update once the production deployment goes live — the
443
+ user verifies in the Checkly dashboard (https://app.checklyhq.com/); nothing
444
+ to run by hand. Manual fallback if a repo deleted the deploy workflow:
445
+ `pnpm checkly test --record`, then `pnpm checkly deploy` (requires the
446
+ Phase 4 login).
447
+
448
+ **Alert notifications are not automatic — walk the user through the
449
+ auto-heal webhook.** A failing monitor only shows in the Checkly dashboard
450
+ until an alert channel exists. The alert channel for these suites is a
451
+ **webhook into the auto-heal workflow**, not a direct Slack channel: the
452
+ team's Slack message is written by the pipeline *after* triage (regression
453
+ vs. stale test), so it carries a diagnosis and, for stale tests, the fix PR.
454
+ Set up once per project:
455
+
456
+ 1. Confirm the `SLACK_WEBHOOK_URL` repository secret from Phase 0 exists —
457
+ the workflow escalates nothing without it. (`ANTHROPIC_API_KEY` comes
458
+ from the organization automatically — but if the dry run in step 6 ends
459
+ agent-failed with an authentication error, override it with a repo-level
460
+ secret of the same name, per Phase 0.)
461
+ 2. The shared `GH_DISPATCH_TOKEN` secret exists in Checkly and covers this
462
+ repo. This is **one-time organization setup, not yours to perform**: the
463
+ token (`checkly-heal-dispatch`, a fine-grained PAT) is created once and
464
+ maintained by its owner, named in 1Password — see "One-time organization
465
+ setup" in the usage guide
466
+ (https://app.notion.com/p/32df837b627080748719c0f94a3aeaaf). Your only
467
+ per-project concern: if this repo is not yet on the token's repository
468
+ list, the webhook channel's test (step 3) fails with a 404 — then ask
469
+ the token owner to widen it (a one-minute edit on their side; the token
470
+ value doesn't change). Do not walk the user through creating a PAT or a
471
+ Checkly secret.
472
+ 3. Checkly → Alert channels → "Add more channels" → **Webhook**:
473
+ - Method `POST`, URL
474
+ `https://api.github.com/repos/<org>/<repo>/dispatches`
475
+ - Headers: `Authorization: Bearer {{GH_DISPATCH_TOKEN}}` and
476
+ `Accept: application/vnd.github+json`
477
+ - Body (Checkly's editor lists the available variables — confirm the
478
+ names there):
479
+
480
+ ```json
481
+ {
482
+ "event_type": "checkly-alert",
483
+ "client_payload": {
484
+ "check_name": "{{CHECK_NAME}}",
485
+ "check_id": "{{CHECK_ID}}",
486
+ "result_id": "{{CHECK_RESULT_ID}}",
487
+ "result_link": "{{RESULT_LINK}}",
488
+ "alert_type": "{{ALERT_TYPE}}"
489
+ }
490
+ }
491
+ ```
492
+
493
+ - Notify on **failure**; enable **reminders** while a check stays failing
494
+ — a reminder re-fires the webhook, the workflow dedupes repeats, and a
495
+ lost first delivery gets retried by the next one. Recovery/degraded
496
+ notifications are ignored by the workflow either way.
497
+ 4. Subscriptions: **only the current check**, and **uncheck** "Automatically
498
+ subscribe newly created checks to this alert channel".
499
+ 5. **Do not also subscribe a Slack alert channel to these suites.** The
500
+ pipeline is the single alert path; a parallel raw Checkly alert double-pings
501
+ the channel and trains people to ignore one of them.
502
+ 6. **One Slack Workflow Builder rule** routes this project's messages from
503
+ the shared e2e channel to the project channel. All notifications post to
504
+ the e2e channel tagged `[e2e:<repo-name>]`; the rule matches the **full
505
+ bracketed tag** — never a short name like `gbk`, which collides with
506
+ other text — and sends the message to the project channel. The sent
507
+ message's template is just the message-text variable (plus the
508
+ link-to-original variable when available, so threads happen on the
509
+ original) — no static prefix text. Have the user add a **second
510
+ manager** to the rule and record it in the rule registry in the e2e
511
+ channel's canvas.
512
+ 7. Dry run: GitHub → Actions → "Checkly auto-heal" → Run workflow, with the
513
+ suite's check name. Confirm the run completes and the message shows up in
514
+ the e2e channel and, via the rule, in the project channel (a passing
515
+ check should end as "not reproducible" — summary only, no message — so a
516
+ real dry run is easiest right after any genuine failure).
517
+
518
+ What the user should expect afterwards: a failing monitor produces either a
519
+ `checkly-heal` PR plus a Slack note (stale or flaky test — **review
520
+ required, the PR is never merged automatically**; PRs carrying app-side test
521
+ hooks say so and point at their preview run for validation), or a Slack
522
+ escalation (regression, fix needs a behavioral app change, agent failed). A
523
+ transient blip that doesn't reproduce stays silent by design.
524
+
525
+ ## Checkly auto-heal (CI, not this session)
526
+
527
+ Failing deployed monitors are handled by `.github/workflows/checkly-heal.yml`:
528
+ it triages first (production regression → Slack alert; stale test → fix; flaky
529
+ test → harden), may add behavior-neutral test hooks (`data-testid`) to app
530
+ source when the robust fix needs them, and opens a `checkly-heal` PR a human
531
+ must review — app-side hooks are validated by the PR's own preview run. The
532
+ repo's workflow file is a short caller; the triage logic, the agent prompt
533
+ and the healer methodology come from the pipeline's reusable workflow and
534
+ the published package, not from this repo or this plugin. If a user asks
535
+ about a `checkly-heal` PR, that workflow authored it; reviewing one means
536
+ verifying the updated test still describes correct production behavior, not
537
+ that it merely passes.
538
+
539
+ ## Conventions to uphold
540
+
541
+ The generator and healer enforce spec-level rules themselves. At the pipeline
542
+ level, additionally keep to:
543
+
544
+ - One spec file per feature group; one `describe`, multiple `test()` blocks
545
+ - Commit specs, plans, seeds, **and** any `data-testid` source edits together
546
+ - Never commit with locally failing tests — heal first or `test.fixme()` with
547
+ the user's sign-off
@@ -13,9 +13,16 @@ team. You never push, never open PRs, never send notifications.
13
13
  - `.checkly-heal/result.json` — the raw Checkly check result when the API call
14
14
  succeeded: error message, failing test and step, stack trace. May be absent;
15
15
  proceed without it if so.
16
- - `.claude/agents/playwright-test-healer.md` — debugging practice and
17
- robustness rules. Follow its methodology. The overrides below take
18
- precedence over anything it says.
16
+ - `.checkly-heal/healer.md` — the `playwright-test-healer` agent definition:
17
+ debugging practice and robustness rules. The workflow copies it here from
18
+ the published pipeline package. Follow its methodology; ignore its
19
+ frontmatter (`tools:` names browser tools this run does not have — use
20
+ `pnpm playwright test` and the trace output instead). The overrides below
21
+ take precedence over anything it says. If the file is absent (a workflow
22
+ from before 0.14.0 that never wrote it), apply the same principles from
23
+ your own knowledge: resilient locators, root causes over timeouts, minimal
24
+ edits — and say in the outcome details that the methodology file was
25
+ missing.
19
26
 
20
27
  ## Overrides for this run
21
28
 
@@ -1,14 +1,16 @@
1
1
  name: Deploy Checkly checks
2
2
 
3
- # Deploys the e2e suite as Checkly monitors when PRODUCTION deploys — not on
4
- # merge. Monitors must match what production serves: a merge that adds tests
5
- # for new data-testids goes red until the app deploy carrying those testids is
6
- # live, and with gated releases that gap can be days. `deployment_status`
7
- # fires when Vercel finishes the production deployment, so monitors update at
8
- # the exact moment the code they were recorded against is reachable.
9
- # `checkly deploy` is idempotent, so redeploying on every production deploy
10
- # is harmless.
11
- # Needs repo secrets: CHECKLY_API_KEY, CHECKLY_ACCOUNT_ID (1Password, "Checkly").
3
+ # Deploys the e2e suite as Checkly monitors when a PRODUCTION deployment
4
+ # succeeds (not on merge — monitors must match what production serves).
5
+ # The work happens in the pipeline's reusable workflow, so a pipeline
6
+ # release updates it without a change here. This file owns the triggers.
7
+ # Needs repo secrets CHECKLY_API_KEY, CHECKLY_ACCOUNT_ID (1Password, "Checkly").
8
+ # Alternative trigger, if the repo prefers deploying on merge: replace
9
+ # deployment_status with
10
+ # push:
11
+ # branches: [main]
12
+ # paths: ["tests/e2e/**", "playwright.config.*", "checkly.config.*"]
13
+ # The reusable workflow deploys on any non-deployment_status event.
12
14
  on:
13
15
  deployment_status:
14
16
  workflow_dispatch:
@@ -19,46 +21,11 @@ concurrency:
19
21
 
20
22
  jobs:
21
23
  deploy:
22
- if: >-
23
- github.event_name == 'workflow_dispatch' ||
24
- (github.event.deployment_status.state == 'success' &&
25
- github.event.deployment.environment == 'Production')
26
- runs-on: ubuntu-latest
27
- timeout-minutes: 8
28
-
29
- steps:
30
- - name: Check out the deployed ref
31
- uses: actions/checkout@v5
32
- with:
33
- ref: ${{ github.event.deployment.ref || github.ref }}
34
-
35
- - name: Set up pnpm
36
- uses: pnpm/action-setup@v4
37
-
38
- - name: Set up Node
39
- uses: actions/setup-node@v5
40
- with:
41
- node-version: 22
42
- cache: pnpm
43
-
44
- # --ignore-scripts: only the tests are bundled; project postinstall
45
- # hooks are not needed and may want CMS tokens CI does not have.
46
- - name: Install dependencies
47
- run: pnpm install --frozen-lockfile --ignore-scripts
48
-
49
- # --force skips the interactive confirmation prompt.
50
- - name: Deploy checks to Checkly
51
- env:
52
- CHECKLY_API_KEY: ${{ secrets.CHECKLY_API_KEY }}
53
- CHECKLY_ACCOUNT_ID: ${{ secrets.CHECKLY_ACCOUNT_ID }}
54
- run: pnpm exec checkly deploy --force
55
-
56
- - name: Write result to job summary
57
- if: always()
58
- run: |
59
- {
60
- echo "## Checkly deploy"
61
- echo ""
62
- echo "- Ref: \`${{ github.event.deployment.ref || github.ref }}\`"
63
- echo "- Triggered by a successful production deployment"
64
- } >> "$GITHUB_STEP_SUMMARY"
24
+ uses: why-agency/why-e2e-pipeline/.github/workflows/reusable-checkly-deploy.yml@main
25
+ # Per-repo settings, defaults shown. Uncomment to change.
26
+ # with:
27
+ # node_version: "22"
28
+ # pnpm_version: ""
29
+ # install_command: pnpm install --frozen-lockfile --ignore-scripts
30
+ # validate_before_deploy: false # `checkly test` before deploying
31
+ secrets: inherit