@hiver/skills 1.0.7 → 1.0.9
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/README.md +1 -1
- package/collections/common/skills/discuss-problem/SKILL.md +4 -0
- package/collections/extension/agents/build-feature.md +2 -1
- package/collections/extension/agents/build-milestone.md +2 -1
- package/collections/extension/skills/build-component/SKILL.md +75 -1
- package/collections/extension/skills/build-component/palette/colors.md +76 -0
- package/collections/extension/skills/build-component/references/v2-components.md +100 -0
- package/collections/extension/skills/build-component/references/v2-usage-examples.md +23 -0
- package/collections/extension/skills/build-component/typography/variants.md +27 -14
- package/collections/mobile/skills/version-bump-up/SKILL.md +66 -0
- package/collections/qa-skills/README.md +103 -0
- package/collections/qa-skills/qa-suite-guide.html +760 -0
- package/collections/qa-skills/skills/hiver-explore/SKILL.md +413 -0
- package/collections/qa-skills/skills/hiver-explore/references/spec-template.md +204 -0
- package/collections/qa-skills/skills/playwright-gen/SKILL.md +280 -0
- package/collections/qa-skills/skills/playwright-gen/references/codegen-conventions.md +100 -0
- package/collections/qa-skills/skills/playwright-gen/references/step-mapping.md +137 -0
- package/collections/qa-skills/skills/qa-api-author/SKILL.md +204 -0
- package/collections/qa-skills/skills/qa-api-author/references/api-areas.md +112 -0
- package/collections/qa-skills/skills/qa-api-run/SKILL.md +178 -0
- package/collections/qa-skills/skills/qa-bugs/SKILL.md +82 -0
- package/collections/qa-skills/skills/qa-eval/SKILL.md +123 -0
- package/collections/qa-skills/skills/qa-eval/references/deterministic-checks.md +89 -0
- package/collections/qa-skills/skills/qa-kit/SKILL.md +228 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/INDEX.md +31 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/INDEX.md +90 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/account-security.md +44 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/apps-integrations.md +43 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/automate-workflows.md +65 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/collaborate.md +36 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/customer-relationships.md +20 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/getting-started.md +31 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/hiver-ai.md +79 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/multichannel-support.md +82 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/reporting-analytics.md +35 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/self-service.md +23 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/sla-policies.md +30 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/troubleshooting.md +27 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/INDEX.md +45 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/account-security.md +13 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/apps-integrations.md +15 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/automate-workflows.md +26 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/collaborate.md +11 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/customer-relationships.md +9 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/getting-started.md +21 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/hiver-ai.md +13 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/identity-access.md +23 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/multichannel-support.md +47 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/reporting-analytics.md +13 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/self-service.md +11 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/sla-policies.md +12 -0
- package/collections/qa-skills/skills/qa-kit/references/clickup-ticket.md +163 -0
- package/collections/qa-skills/skills/qa-kit/references/eval.md +117 -0
- package/collections/qa-skills/skills/qa-kit/references/flow-capture.md +147 -0
- package/collections/qa-skills/skills/qa-kit/references/handoff-contract.md +159 -0
- package/collections/qa-skills/skills/qa-kit/references/hiver-context.md +99 -0
- package/collections/qa-skills/skills/qa-kit/references/tracker-format.md +123 -0
- package/collections/qa-skills/skills/qa-kit/references/triage-guide.md +105 -0
- package/collections/qa-skills/skills/qa-ui-author/SKILL.md +208 -0
- package/collections/qa-skills/skills/qa-ui-author/references/test-areas.md +132 -0
- package/collections/qa-skills/skills/qa-ui-run/SKILL.md +183 -0
- package/collections/web/agents/build-feature.md +2 -2
- package/collections/web/agents/build-milestone.md +2 -2
- package/collections/web/skills/build-component/SKILL.md +54 -13
- package/collections/web/skills/build-component/palette/colors.md +76 -0
- package/collections/web/skills/build-component/references/v2-components.md +100 -0
- package/collections/web/skills/build-component/references/v2-usage-examples.md +23 -0
- package/collections/web/skills/build-component/typography/variants.md +27 -14
- package/package.json +1 -1
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: playwright-gen
|
|
3
|
+
description: Hiver Playwright automation — maps confirmed passing test cases onto the existing page objects in the poc-playwright / playwright-hig-automation repo, generates a runnable spec file in the repo house style, runs it, writes results back to the tracker, and opens a PR. Reuses methods, never invents selectors. Trigger on playwright-gen, generate automation, automate these test cases, write playwright tests, run the automation.
|
|
4
|
+
---
|
|
5
|
+
# playwright-gen — Tracker → Running Playwright Tests
|
|
6
|
+
|
|
7
|
+
You are the **automation track**. Your input is a set of *confirmed* test cases (the qa-ui-run/qa-api-run
|
|
8
|
+
tracker). Your output is a **real, runnable `.spec.ts` file** in the Playwright repo, executed, with
|
|
9
|
+
pass/fail written back into the tracker. This is the step that removes the manual work of hand-writing
|
|
10
|
+
automation.
|
|
11
|
+
|
|
12
|
+
**Your prime directive: REUSE, never hallucinate.** The repo already has proven page objects with
|
|
13
|
+
selectors that survive Hiver's quirks. You map English test steps onto *existing methods*. If a step
|
|
14
|
+
needs a method that doesn't exist, you FLAG it (or generate a small, clearly-marked addition when the
|
|
15
|
+
user approves) — you never invent a raw selector inline, because untested selectors are exactly what
|
|
16
|
+
makes generated tests fail on a live demo.
|
|
17
|
+
|
|
18
|
+
**Read before doing anything:**
|
|
19
|
+
- `references/codegen-conventions.md` — the repo's house rules (getter locators, allure steps,
|
|
20
|
+
two-tier assertions, JSDoc, `authedPage`, path aliases). Generated code MUST match these.
|
|
21
|
+
- `references/step-mapping.md` — how to translate a tracker row into page-object calls, the
|
|
22
|
+
automatable/skip filter, the missing-method policy, and multi-persona handling.
|
|
23
|
+
- `../qa-kit/references/hiver-context.md` — Hiver concepts.
|
|
24
|
+
- `../qa-kit/references/tracker-format.md` — the tracker schema you
|
|
25
|
+
read from and write back into (the `Initial Behaviour – Testing 1` + `Status` columns).
|
|
26
|
+
|
|
27
|
+
> The `../qa-kit/references/…` paths point at the **qa-kit** skill installed alongside this one.
|
|
28
|
+
> Use relative `references/…` for this skill's own files.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Pipeline contract (Phase 1)
|
|
33
|
+
|
|
34
|
+
This skill runs inside the file-based pipeline. Read
|
|
35
|
+
`../qa-kit/references/handoff-contract.md` (§6 per-agent map) and
|
|
36
|
+
`../qa-kit/references/eval.md` before starting.
|
|
37
|
+
|
|
38
|
+
- **On start:** read `qa-output/.current-run` → `$RUN_DIR`, then read `$RUN_DIR/handoff.json`.
|
|
39
|
+
Everything in its cargo is already known — do NOT re-ask the user for it. Open your action log at
|
|
40
|
+
`$RUN_DIR/logs/playwright-gen.jsonl` and append one line per meaningful action.
|
|
41
|
+
- **During:** the generated specs live in the POC repo (`specs/…`) by design; write the *pipeline*
|
|
42
|
+
artefacts — tracker.xlsx results and the Allure report path — into `$RUN_DIR`, and append actions
|
|
43
|
+
to the log.
|
|
44
|
+
- **On finish:** write a step record `$RUN_DIR/steps/playwright-gen-run.json` per `eval.md` (leave
|
|
45
|
+
`verdict: null` — only qa-eval fills it). playwright-gen is **terminal** — it opens a PR rather than
|
|
46
|
+
handing off, so it writes no downstream `handoff.json`.
|
|
47
|
+
- **Note (later phase):** the 3-attempt self-heal loop is a behaviour enhancement tracked separately — do not implement it as part of Phase 1 wiring.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## The workflow
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
qa-ui-run (browser first pass) you can also start here directly
|
|
55
|
+
│ Phase 7 handoff │ (point at an existing tracker)
|
|
56
|
+
▼ ▼
|
|
57
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
58
|
+
│ playwright-gen │
|
|
59
|
+
│ 0 intake → 1 catalog → 2 select+plan(GATE) → 3 map → │
|
|
60
|
+
│ 4 emit spec → 5 run → 6 write results back → 7 handoff │
|
|
61
|
+
└──────────────────────────────────────────────────────────────┘
|
|
62
|
+
▼
|
|
63
|
+
specs/<feature>.spec.ts + Allure report + updated tracker
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Semi-auto: there are **two confirmation gates** — after the selection plan (Phase 2) and before the
|
|
67
|
+
run if anything destructive/new was generated (Phase 4). Everything else flows automatically.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## PHASE 0 — Intake
|
|
72
|
+
|
|
73
|
+
**If invoked by `qa-ui-run`/`qa-kit`:** read the handoff block from the conversation (see the contract at
|
|
74
|
+
the bottom). Do NOT re-ask for the feature, product, effort, or the cases — they're already here.
|
|
75
|
+
|
|
76
|
+
**If invoked directly:** collect the minimum below.
|
|
77
|
+
|
|
78
|
+
| Input | Required | If missing |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| The test cases | YES | Either the **confirmed cases in the conversation** (preferred — most reliable) OR a path to the `TestTracker_*.xlsx`. If only the xlsx, parse it (see `step-mapping.md` §Reading the tracker). |
|
|
81
|
+
| Feature name / slug | YES | Derive a kebab-case slug for the filename, e.g. `Hiver Notes` → `hiverNotes`. Match the repo's existing naming (`specs/hiverNotes.spec.ts`). |
|
|
82
|
+
| Repo root | YES | Auto-detect: the dir containing `playwright.config.ts` + `pages/` + `fixtures/auth.fixture.ts`. Default to the poc-playwright / playwright-hig-automation repo. Confirm in one line. |
|
|
83
|
+
| Product: HIG / Omni / Both | From handoff | Only affects env/personas; carry it through. |
|
|
84
|
+
| Effort level | From handoff | Controls how many cases you attempt (mirror qa-ui-run sizing). |
|
|
85
|
+
|
|
86
|
+
Open with one line: *"I'll build a method catalog from the repo, pick the automatable cases, generate
|
|
87
|
+
`specs/<slug>.spec.ts` reusing existing page objects, run it, and write results back to the tracker."*
|
|
88
|
+
|
|
89
|
+
A browser-first-pass "passed" status is **not** a hard precondition. If there was no live env, don't
|
|
90
|
+
block — just confirm with the QA that the feature is stable enough to automate (*"Is the build stable
|
|
91
|
+
and do you want automation now?"*). On yes, generate the specs and **gate them to self-skip cleanly**
|
|
92
|
+
(an env `*_READY` flag + the tier-gate detector) until the env/build is available, rather than
|
|
93
|
+
stalling on the missing browser pass. Mark selectors you couldn't verify against a live DOM as
|
|
94
|
+
`// UNVERIFIED` so they're easy to confirm once the build exists.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## PHASE 1 — Build the Method Catalog (the key to reuse)
|
|
99
|
+
|
|
100
|
+
Before writing a single line, learn what the repo already gives you. Read, in the repo root:
|
|
101
|
+
|
|
102
|
+
1. `fixtures/auth.fixture.ts` — the fixtures available (`authedPage`, `personaContext(name, idx)`).
|
|
103
|
+
2. `pages/*.page.ts` for the feature under test **and any obviously-related page** — extract the
|
|
104
|
+
**public getters** and **public async methods** with their signatures. These are your vocabulary.
|
|
105
|
+
3. One existing spec for the same/adjacent feature (e.g. `specs/hiverNotes.spec.ts`) — as the golden
|
|
106
|
+
template for structure, imports, and idiom.
|
|
107
|
+
4. `utils/env.ts` (`mustEnv`/`getEnv`), `utils/wait-helpers.ts`, and `CLAUDE.md` (conventions +
|
|
108
|
+
`knowledgebase-claude/HIVER-QUIRKS.md` pointers).
|
|
109
|
+
|
|
110
|
+
Produce a **Method Catalog** — a compact list of what's callable, e.g.:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
Page object: HiverNotesPage (pages/hiver-notes.page.ts)
|
|
114
|
+
actions: addNote(text) · editNote(text) · pinNote() · unpinNote() · replyToNote(text)
|
|
115
|
+
deleteNote() · openFirstSmConversation() · navigateToConversation(subject)
|
|
116
|
+
asserts: verifyNotePresent(text) · verifyNoteEdited(text) · expectNotePinned(text)
|
|
117
|
+
expectEmptyNoteSaveBlocked() · countNotesContaining(text) → number
|
|
118
|
+
Fixtures: authedPage (Tony) · personaContext('steve'|'thor', workerIndex)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
This catalog is what makes generated tests pass — every step you emit must resolve to something here.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## PHASE 2 — Select Automatable Cases & Plan (GATE 1)
|
|
126
|
+
|
|
127
|
+
Go through every case in the tracker and classify it using `step-mapping.md` §The automatable filter:
|
|
128
|
+
|
|
129
|
+
| Bucket | Meaning |
|
|
130
|
+
|---|---|
|
|
131
|
+
| **Automatable** | Single-account, UI/happy-path/validation, every step maps to a catalog method. |
|
|
132
|
+
| **Needs new method** | Automatable in principle, but one or more steps have no matching page-object method. |
|
|
133
|
+
| **Manual-only** | Skip — matches qa-ui-run's skip rules: two simultaneous accounts (unless multi-persona is explicitly in scope), network-inspection assertions, backend-failure simulation, or anything the tracker already marked `⏭️ Skipped`. (Only internal Gainsight event-tracking is excluded — a customer-facing analytics dashboard/report IS automatable UI.) |
|
|
134
|
+
|
|
135
|
+
Print the **Automation Plan** and WAIT for confirmation:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
Automation Plan — [Feature] (repo: [root], file: specs/[slug].spec.ts)
|
|
139
|
+
Automatable now: [n] — [TC IDs]
|
|
140
|
+
Needs new method: [n] — [TC IDs] → [the missing capability per case]
|
|
141
|
+
Manual-only (skip): [n] — [TC IDs] → [reason, e.g. "requires network inspection"]
|
|
142
|
+
Plan: generate [n] tests reusing [PageObject]. For "needs new method" cases I will:
|
|
143
|
+
[ (a) generate a small page-object method — I'll show the diff first, OR
|
|
144
|
+
(b) skip and note it, your call ].
|
|
145
|
+
Run headed or headless? (headed recommended for the demo)
|
|
146
|
+
Go?
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Never silently drop a case — every case lands in exactly one bucket and is named.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## PHASE 3 — Map Steps → Method Calls
|
|
154
|
+
|
|
155
|
+
For each automatable case, translate its **Test Steps** + **Expected Result** into page-object calls,
|
|
156
|
+
following `step-mapping.md`. Rules of thumb:
|
|
157
|
+
|
|
158
|
+
- One tracker case → one `test(...)`. One user-visible step-group → one `allure.step(...)` (3–7 total).
|
|
159
|
+
- Pre-conditions → setup calls (`openFirstSmConversation()`, personas, env reads).
|
|
160
|
+
- Expected-result lines → assertions: single facts via `expect()` in the spec; compound/domain checks
|
|
161
|
+
via the page object's `expect*`/`verify*` methods.
|
|
162
|
+
- Use unique run tags for created data: `const tag = Date.now().toString().slice(-6)`.
|
|
163
|
+
- For a **"needs new method"** case the user approved: add the smallest possible method to the page
|
|
164
|
+
object, reusing existing getters/patterns, and mark it with a `// [playwright-gen] generated for TC-xx`
|
|
165
|
+
comment. Show the diff before writing. If not approved, emit the test body with a
|
|
166
|
+
`test.fixme(...)` and a `// TODO: needs HiverNotesPage.<method>` note so nothing is lost.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## PHASE 4 — Emit the Spec File
|
|
171
|
+
|
|
172
|
+
Write `specs/[slug].spec.ts` following `references/codegen-conventions.md` exactly:
|
|
173
|
+
|
|
174
|
+
- Imports from the repo's path aliases / relative fixture path (match the golden template).
|
|
175
|
+
- `test.describe('[Feature]', ...)` with a per-test `test.setTimeout()` sized to the flow.
|
|
176
|
+
- Each test: JSDoc block (`@description`/`@steps`/`@expects`) **above** + matching
|
|
177
|
+
`allure.description()` + `allure.label('feature', '[Feature]')` + `allure.step()` calls inside.
|
|
178
|
+
- `authedPage` for single-persona; `personaContext(...)` in a `try/finally` for multi-persona.
|
|
179
|
+
|
|
180
|
+
After writing, run a quick sanity check and (GATE 2, only if you generated new page-object methods)
|
|
181
|
+
confirm the diff is acceptable:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
npx tsc --noEmit # or: npm run typecheck
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Fix any type errors before running. Report the file path.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## PHASE 5 — Run
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# headed for the demo (browser visibly drives Hiver); drop --headed for CI
|
|
195
|
+
npx playwright test specs/[slug].spec.ts --headed
|
|
196
|
+
# a single case: npx playwright test specs/[slug].spec.ts -g "case title"
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Prereqs the repo owns (verify, don't re-implement): profile seeded (`npm run auth:all` done),
|
|
200
|
+
extension staged, `.env` has the persona password. If the run bounces to Google sign-in or "Hiver
|
|
201
|
+
topbar not visible", that's an environment/auth issue (see `CLAUDE.md` → HIVER-QUIRKS) — surface it,
|
|
202
|
+
don't rewrite the test to work around it.
|
|
203
|
+
|
|
204
|
+
Capture per-test outcome: passed / failed (+ the failing assertion or timeout) / skipped.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## PHASE 6 — Write Results Back + Report
|
|
209
|
+
|
|
210
|
+
1. **Update the tracker** (`tracker-format.md` schema): for each executed case set
|
|
211
|
+
`Initial Behaviour – Testing 1` to `✅ As Expected` / `❌ Different — <detail>` / `⏭️ Skipped — <reason>`
|
|
212
|
+
and `Status` to `Pass` / `Fail` / `Not Tested`. Use openpyxl (see `step-mapping.md` §Writing results back).
|
|
213
|
+
If the cases live only in-conversation, produce the updated tracker instead.
|
|
214
|
+
2. **Allure report**: `npm run allure:generate && npm run allure:open` (or `npm run allure:serve`).
|
|
215
|
+
3. Print the summary:
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
Automation Run — [Feature] (specs/[slug].spec.ts)
|
|
219
|
+
Generated: [n] tests Ran: [n]
|
|
220
|
+
✅ Passed: [n] — [IDs]
|
|
221
|
+
❌ Failed: [n] — [IDs] → [one-line cause each]
|
|
222
|
+
⏭️ Skipped: [n] — [IDs]
|
|
223
|
+
New page-object methods added: [list or none]
|
|
224
|
+
Report: [allure path] Tracker updated: [path]
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
For any ❌: say whether it looks like a **product bug** (hand back to qa-ui-run → `clickup-ticket.md`) or a
|
|
228
|
+
**test/selector issue** (offer to adjust the generated test and re-run just that case).
|
|
229
|
+
|
|
230
|
+
> **Step record (Phase-2).** After finishing this phase, write `$RUN_DIR/steps/playwright-gen-run.json` per `eval.md`:
|
|
231
|
+
> `input` = passing cases, `output` = `{ "artifact": "<spec file paths + tracker results + Allure path>", "summary": "<n specs generated / passed / failed>" }`,
|
|
232
|
+
> `self_check` = `{ "passed": <bool>, "notes": "spec compiles+ran, no hallucinated page-object methods, results written back to tracker" }`, `verdict: null`
|
|
233
|
+
> (only qa-eval fills `verdict`). Append the same to `$RUN_DIR/logs/playwright-gen.jsonl`.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## PHASE 7 — Handoff / Next Steps
|
|
238
|
+
|
|
239
|
+
- Offer to run the other track's cases, add more cases (bump effort), or wire the spec into CI.
|
|
240
|
+
- If this was invoked by `qa-kit`/`qa-ui-run`, report the artefacts produced (spec file, Allure report,
|
|
241
|
+
updated tracker) back up so the orchestrator can close out.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Handoff contract (what qa-ui-run prints before invoking you)
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
=== PLAYWRIGHT-GEN HANDOFF (from qa-ui-run) ===
|
|
249
|
+
Feature: [name] Slug: [kebab]
|
|
250
|
+
Product: HIG / Omni / Both
|
|
251
|
+
Effort level: smoke / standard / exhaustive
|
|
252
|
+
Repo root: [abs path to poc-playwright/playwright-hig-automation]
|
|
253
|
+
Tracker: [path to TestTracker_*.xlsx OR "cases in conversation"]
|
|
254
|
+
Automatable cases: [TC IDs qa-ui-run marked single-account / non-failure-sim / passed]
|
|
255
|
+
Skip (manual): [TC IDs + reason]
|
|
256
|
+
Existing page objects: [e.g. HiverNotesPage @ pages/hiver-notes.page.ts]
|
|
257
|
+
Live observations: [selectors/timing from qa-ui-run browser pass, if any]
|
|
258
|
+
=== END HANDOFF ===
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
If a field is missing, fill it in Phase 0/1 — don't stall.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Notes
|
|
266
|
+
|
|
267
|
+
- You are the ONLY skill that writes into the Playwright repo. Keep changes surgical: one spec file,
|
|
268
|
+
plus small clearly-marked page-object additions when approved. Never refactor existing page objects.
|
|
269
|
+
- Don't duplicate triage or test-case authoring — that's `qa-kit`/`qa-ui-run`. You consume their output.
|
|
270
|
+
- Prefer reusing a method over adding one. Prefer skipping-with-a-note over an invented selector.
|
|
271
|
+
- The repo is the source of truth for *how* to drive Hiver; the tracker is the source of truth for
|
|
272
|
+
*what* to verify. Your job is to connect them.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Finish — grade the run.
|
|
277
|
+
|
|
278
|
+
When the track is done (bugs filed, and any playwright-gen automation complete), invoke `qa-eval`
|
|
279
|
+
(Skill tool, `skill: qa-eval`) on this run. Safe to re-run; in a mixed run the last invocation
|
|
280
|
+
produces the complete report. Do not block on its result.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Codegen Conventions — match the repo's house style exactly
|
|
2
|
+
|
|
3
|
+
Generated specs must be indistinguishable from hand-written ones in the `poc-playwright` /
|
|
4
|
+
`playwright-hig-automation` repo. These rules are distilled from that repo's `CLAUDE.md`. When the
|
|
5
|
+
repo's `CLAUDE.md` and this file disagree, **the repo wins** — re-read it in Phase 1.
|
|
6
|
+
|
|
7
|
+
## The golden template
|
|
8
|
+
|
|
9
|
+
Study `specs/hiverNotes.spec.ts` before generating — it is the reference for imports, structure, and
|
|
10
|
+
idiom. A generated single-persona test should look like this:
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
/**
|
|
14
|
+
* @description One-sentence summary of what this test verifies and why.
|
|
15
|
+
* @steps
|
|
16
|
+
* 1. First user-visible action
|
|
17
|
+
* 2. Second user-visible action
|
|
18
|
+
* 3. Verification
|
|
19
|
+
* @expects
|
|
20
|
+
* - Concrete observable outcome 1
|
|
21
|
+
* - Concrete observable outcome 2
|
|
22
|
+
*/
|
|
23
|
+
import { allure } from 'allure-playwright'
|
|
24
|
+
import { test, expect } from '../fixtures/auth.fixture'
|
|
25
|
+
import { HiverNotesPage } from '../pages/hiver-notes.page'
|
|
26
|
+
|
|
27
|
+
test.describe('Hiver Notes', () => {
|
|
28
|
+
test.setTimeout(120_000)
|
|
29
|
+
|
|
30
|
+
test('descriptive name — maps to the tracker case title', async ({ authedPage }) => {
|
|
31
|
+
allure.description('Full intent — what + why.')
|
|
32
|
+
allure.label('feature', 'Hiver Notes')
|
|
33
|
+
|
|
34
|
+
const tag = Date.now().toString().slice(-6) // unique run data
|
|
35
|
+
const noteText = `note ${tag}`
|
|
36
|
+
const notes = new HiverNotesPage(authedPage)
|
|
37
|
+
|
|
38
|
+
await allure.step('Open first SM conversation', async () => {
|
|
39
|
+
await notes.openFirstSmConversation()
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
await allure.step('Add a note', async () => {
|
|
43
|
+
await notes.addNote(noteText)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
await allure.step('Verify the note is saved', async () => {
|
|
47
|
+
await notes.verifyNotePresent(noteText)
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Hard rules
|
|
54
|
+
|
|
55
|
+
1. **Imports** — `test`/`expect`/`personaContext` come from the fixture, not `@playwright/test`:
|
|
56
|
+
`import { test, expect, personaContext } from '../fixtures/auth.fixture'`. Page objects via the
|
|
57
|
+
repo's path aliases (`@pages/…`) or relative (`../pages/…`) — match the golden template's choice.
|
|
58
|
+
2. **Fixtures** — single persona → `async ({ authedPage })`. Multi-persona → get the second persona
|
|
59
|
+
from `personaContext('steve', 1)` and ALWAYS clean up in `finally { await cleanup() }`.
|
|
60
|
+
3. **JSDoc above every test** with `@description` / `@steps` / `@expects`, AND matching
|
|
61
|
+
`allure.description()` + `allure.label('feature', '<Feature>')` inside. They must not contradict.
|
|
62
|
+
4. **Allure steps** — one per user-visible outcome, aim for **3–7 per test**. Never wrap every click.
|
|
63
|
+
Step labels should read like the tracker's Test Steps.
|
|
64
|
+
5. **Assertions — two tiers**:
|
|
65
|
+
- single fact → `expect()` in the spec (`await expect(notes.noteText).toHaveText('hi')`),
|
|
66
|
+
- compound/domain-meaningful → an `expect*`/`verify*` method on the page object.
|
|
67
|
+
6. **Locators** — you generally don't write locators; you call page-object methods. If you must add a
|
|
68
|
+
locator to a page object, use the **public getter** pattern (`get x(): Locator { return this.page.locator(...) }`),
|
|
69
|
+
never a `private readonly` field in the constructor.
|
|
70
|
+
7. **Variable names — full, no short aliases** (ESLint `id-length` min 3). `const sendActions = …`,
|
|
71
|
+
not `const sa = …`. Allowed short names: `i`, `j`, `e`, `r`, `t`, `el`, `id`, `_`.
|
|
72
|
+
8. **Timeouts** — set a realistic `test.setTimeout()` per test (Hiver flows are slow; existing specs
|
|
73
|
+
use 120k–600k). Prefer `test.setTimeout()` inside each test over relying on describe-level config
|
|
74
|
+
(the repo notes `-g` filtering makes describe-level timeouts unreliable in PW 1.59.1).
|
|
75
|
+
9. **Unique data** — anything created (notes, subjects, tags) gets a `Date.now().toString().slice(-6)`
|
|
76
|
+
suffix so re-runs don't collide. Keep it short — Hiver truncates some fields (~28 chars for notes).
|
|
77
|
+
10. **No invented selectors in the spec.** Selectors live in page objects only. A spec that contains
|
|
78
|
+
`page.locator('...')` for feature UI is a smell — move it to (or reuse from) the page object.
|
|
79
|
+
|
|
80
|
+
## Multi-persona shape (only when the case genuinely needs two accounts)
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const { page: stevePage, cleanup } = await personaContext('steve', 1)
|
|
84
|
+
try {
|
|
85
|
+
const steveNotes = new HiverNotesPage(stevePage)
|
|
86
|
+
// ... drive steve alongside authedPage (tony) ...
|
|
87
|
+
} finally {
|
|
88
|
+
await cleanup() // closes context + deletes temp profile — never skip
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Cross-persona sync is slow (30–90s) and thread IDs are non-portable across Gmail accounts — see the
|
|
93
|
+
repo's HIVER-QUIRKS. Only generate multi-persona tests when the tracker case is explicitly cross-user
|
|
94
|
+
AND the user opted into it; otherwise it's a "manual-only" case.
|
|
95
|
+
|
|
96
|
+
## What "done" looks like
|
|
97
|
+
|
|
98
|
+
- `npm run typecheck` passes on the new file.
|
|
99
|
+
- `npm run lint` has no new errors (id-length, unused imports).
|
|
100
|
+
- The file reads like the golden template — a reviewer can't tell it was generated.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Step Mapping — tracker row → Playwright calls
|
|
2
|
+
|
|
3
|
+
This is the translation logic: how a single tracker case becomes a `test()`, which cases you attempt,
|
|
4
|
+
what to do when a method is missing, and how to read/write the tracker file.
|
|
5
|
+
|
|
6
|
+
## The automatable filter
|
|
7
|
+
|
|
8
|
+
Classify EVERY case into exactly one bucket. Mirror qa-ui-run's skip rules so the two tracks agree.
|
|
9
|
+
|
|
10
|
+
**Automatable** — attempt it — when ALL hold:
|
|
11
|
+
- Single account (only `authedPage`/Tony needed), OR multi-persona explicitly in scope.
|
|
12
|
+
- It's a UI happy-path, validation, or configuration flow.
|
|
13
|
+
- Every Test Step maps to a method in the Phase-1 catalog (or one the user approves adding).
|
|
14
|
+
- No dependence on inspecting analytics/network or simulating a backend failure.
|
|
15
|
+
|
|
16
|
+
**Needs new method** — automatable but a step has no matching page-object method. List the missing
|
|
17
|
+
capability precisely (e.g. *"TC-07 needs `HiverNotesPage.filterByAuthor(name)` — no equivalent getter"*).
|
|
18
|
+
|
|
19
|
+
**Manual-only** — skip, and record the reason in the tracker's Testing-1 column as `⏭️ Skipped — <reason>`:
|
|
20
|
+
- Two simultaneous accounts when multi-persona wasn't opted into → *"requires multi-account setup"*.
|
|
21
|
+
- Any network-inspection assertion → *"requires network inspection"*. (Only internal Gainsight event-tracking is out of scope — a customer-facing analytics dashboard/report IS automatable UI: reading rendered metrics/charts and checking they reconcile is normal verification.)
|
|
22
|
+
- Backend/API failure simulation → *"requires API error simulation"*.
|
|
23
|
+
- Anything the tracker already marked `⏭️ Skipped` in the browser pass.
|
|
24
|
+
|
|
25
|
+
Never silently drop a case. If unsure, put it in "needs new method" and ask.
|
|
26
|
+
|
|
27
|
+
## Mapping the fields
|
|
28
|
+
|
|
29
|
+
| Tracker field | Becomes |
|
|
30
|
+
|---|---|
|
|
31
|
+
| **Test Case** (title) | the `test('…')` name + `@description` + `allure.description()` |
|
|
32
|
+
| **Pre-conditions** | setup `allure.step` — `openFirstSmConversation()`, persona init, `mustEnv()` reads. `SM:`/`Extension:` notes are context, not code. |
|
|
33
|
+
| **Test Data** | `const` values at the top of the test, tagged unique where created. |
|
|
34
|
+
| **Test Steps** (numbered) | grouped into 3–7 `allure.step()` blocks of page-object calls, in order. |
|
|
35
|
+
| **Expected Result** (numbered) | assertions — `expect()` for single facts, `expect*`/`verify*` page-object methods for compound checks. Put them in the step whose outcome they verify, or a final "Verify …" step. |
|
|
36
|
+
| **Priority** | ordering only (P0 first). Doesn't change the code. |
|
|
37
|
+
|
|
38
|
+
### Worked example
|
|
39
|
+
|
|
40
|
+
Tracker row:
|
|
41
|
+
```
|
|
42
|
+
TC: A-02 · "Verify a saved note appears in the activity panel"
|
|
43
|
+
Pre: Logged in as Tony · SM: sdf · Extension v7.5.40
|
|
44
|
+
Steps: 1. Open first SM conversation 2. Click Add a note 3. Type text 4. Save
|
|
45
|
+
Expected: 1. Editor opens 2. Note appears in the activity panel with the typed text
|
|
46
|
+
```
|
|
47
|
+
Maps to (reusing `addNote` which already encapsulates click→type→save):
|
|
48
|
+
```typescript
|
|
49
|
+
test('A-02: a saved note appears in the activity panel', async ({ authedPage }) => {
|
|
50
|
+
test.setTimeout(120_000)
|
|
51
|
+
allure.description('Verify a saved note appears in the activity panel with the typed text.')
|
|
52
|
+
allure.label('feature', 'Hiver Notes')
|
|
53
|
+
|
|
54
|
+
const tag = Date.now().toString().slice(-6)
|
|
55
|
+
const noteText = `panel-check ${tag}`
|
|
56
|
+
const notes = new HiverNotesPage(authedPage)
|
|
57
|
+
|
|
58
|
+
await allure.step('Open first SM conversation', async () => {
|
|
59
|
+
await notes.openFirstSmConversation()
|
|
60
|
+
})
|
|
61
|
+
await allure.step('Add a note', async () => {
|
|
62
|
+
await notes.addNote(noteText)
|
|
63
|
+
})
|
|
64
|
+
await allure.step('Verify the note appears in the activity panel', async () => {
|
|
65
|
+
await notes.verifyNotePresent(noteText)
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
Note how four literal UI steps collapsed into the existing `addNote()` — prefer the coarse existing
|
|
70
|
+
method over re-implementing click/type/save. That's what keeps generated tests green.
|
|
71
|
+
|
|
72
|
+
## Missing-method policy
|
|
73
|
+
|
|
74
|
+
When a case is "needs new method" and the user approved generating it:
|
|
75
|
+
- Add the **smallest** method to the relevant `pages/*.page.ts`, reusing existing getters and the
|
|
76
|
+
`dismissMuiOverlays()`/`waitForRightPanel()` helpers from `BasePage`.
|
|
77
|
+
- Follow the getter-locator pattern; give it a clear name (`verb + object`).
|
|
78
|
+
- Mark it: `// [playwright-gen] added for TC-07 — filter notes by author`.
|
|
79
|
+
- Show the diff before writing. Re-run `npm run typecheck`.
|
|
80
|
+
|
|
81
|
+
When NOT approved: emit the test with `test.fixme('TC-07 — needs HiverNotesPage.filterByAuthor')`
|
|
82
|
+
so the intent is captured in the file and shows as skipped, not lost.
|
|
83
|
+
|
|
84
|
+
Never write a raw feature selector inline in the spec as a shortcut — untested selectors are the #1
|
|
85
|
+
cause of a generated test failing on stage.
|
|
86
|
+
|
|
87
|
+
## Reading the tracker (when input is an .xlsx, not in-conversation cases)
|
|
88
|
+
|
|
89
|
+
Prefer the confirmed cases already in the conversation. If you must parse the file, use openpyxl:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
# needs a python with openpyxl. If none: python3 -m venv ~/.qa-venv && ~/.qa-venv/bin/pip install openpyxl
|
|
93
|
+
from openpyxl import load_workbook
|
|
94
|
+
wb = load_workbook("TestTracker_HiverNotes_2026-07-09.xlsx")
|
|
95
|
+
ws = wb["Test Cases"]
|
|
96
|
+
headers = [c.value for c in ws[1]] # row 1 = header (frozen)
|
|
97
|
+
col = {h: i for i, h in enumerate(headers)}
|
|
98
|
+
for row in ws.iter_rows(min_row=2, values_only=True):
|
|
99
|
+
if row[col["TC ID"]] is None: # skip merged section-header rows
|
|
100
|
+
continue
|
|
101
|
+
tc = {h: row[col[h]] for h in headers}
|
|
102
|
+
# tc["Test Case"], tc["Test Steps"], tc["Expected Result"], tc["Priority"], ...
|
|
103
|
+
```
|
|
104
|
+
Section-header rows are merged and have no TC ID — skip them. Steps/Expected are newline-separated
|
|
105
|
+
within one cell.
|
|
106
|
+
|
|
107
|
+
## Writing results back
|
|
108
|
+
|
|
109
|
+
After the run, set two columns per executed case and save the workbook:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
TESTING1 = col["Initial Behaviour – Testing 1"] # yellow column
|
|
113
|
+
STATUS = col["Status"]
|
|
114
|
+
# map a case id → outcome from the playwright run
|
|
115
|
+
for row in ws.iter_rows(min_row=2):
|
|
116
|
+
tc_id = row[col["TC ID"]].value
|
|
117
|
+
if tc_id in results:
|
|
118
|
+
r = results[tc_id] # {'testing1': '✅ As Expected', 'status': 'Pass'}
|
|
119
|
+
row[TESTING1].value = r["testing1"]
|
|
120
|
+
row[STATUS].value = r["status"]
|
|
121
|
+
wb.save(path)
|
|
122
|
+
```
|
|
123
|
+
Values must match the schema: Testing-1 uses `✅ As Expected` / `❌ Different — <detail>` /
|
|
124
|
+
`⚠️ Partial — <detail>` / `⏭️ Skipped — <reason>`; Status uses `Pass` / `Fail` / `Bug` / `Blocked` /
|
|
125
|
+
`Not Tested`. Don't touch the "Testing 2" column — that's the QA engineer's manual pass.
|
|
126
|
+
|
|
127
|
+
## Parsing the Playwright run
|
|
128
|
+
|
|
129
|
+
Get machine-readable results with the JSON reporter, then map test titles → TC IDs (put the TC ID at
|
|
130
|
+
the start of each test title so this is trivial):
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npx playwright test specs/hiverNotes.spec.ts --reporter=json > run.json
|
|
134
|
+
```
|
|
135
|
+
`suites[].specs[].tests[].results[].status` gives `passed` / `failed` / `skipped` / `timedOut`. A
|
|
136
|
+
`failed`/`timedOut` → `❌ Different` + `Fail`; grab the error message for the detail. `skipped` (from
|
|
137
|
+
`test.fixme`) → `⏭️ Skipped`. Keep the Allure reporter too (config already has it) for the visual report.
|