test-casebook 1.0.0 → 1.0.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.
- package/.claude/skills/test-task/SKILL.md +39 -32
- package/AGENTS.md +2 -0
- package/package.json +1 -1
|
@@ -1,50 +1,57 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: test-task
|
|
3
|
-
description: Use when a project manager wants to turn a story into
|
|
3
|
+
description: Use when a project manager wants to turn a story into test tasks in Jira before development — reads the whole story, interviews the PM one question at a time to close gaps (personas, gated capabilities and their forbidden side, regression surface, edge cases), then creates one Jira sub-task per team (front / back / mobile) carrying the behavioural test contract that team's developer will execute. Triggers on "turn this story into a test task", "crée la tâche test", "découper une tâche test", "plan the tests for STK-xxxx", or a linked/pasted story.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# test-task — story →
|
|
6
|
+
# test-task — story → test sub-tasks in Jira
|
|
7
7
|
|
|
8
|
-
You help a **project manager** turn one story into
|
|
8
|
+
You help a **project manager** turn one story into **test tasks in Jira** — one **sub-task per team** (front / back / mobile), each carrying the behavioural contract its developer will hand to the `test-casebook` skill. You write **intent, never code** (no PHPUnit, no Vitest, no Flutter) — *what* must be true per actor, not *how* to test it. Each team then executes its own sub-task.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
You close the two holes a story alone leaves: **which actor** performs each action (permissions / multi-role) and **regressions** in adjacent areas.
|
|
11
|
+
|
|
12
|
+
> Runs in Claude Code (with the Atlassian/Jira tools) or as a **Claude Desktop project** with the Jira connector enabled. In Desktop you have no repo access — you rely on the story plus the PM interview, not on reading code.
|
|
11
13
|
|
|
12
14
|
## Do this, in order
|
|
13
15
|
|
|
14
|
-
1. **Get the story.**
|
|
15
|
-
2. **
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- **
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
26
|
-
|
|
27
|
-
- Note per case whether it's front, back, or both, so each developer sees their slice.
|
|
28
|
-
5. **Confirm with the PM**, then save `test-task.md`. This one file goes to both developers.
|
|
29
|
-
|
|
30
|
-
## Shape of `test-task.md`
|
|
16
|
+
1. **Get the whole story.** Given an issue key, fetch it via the Jira tool (description, acceptance criteria, epic, links, components). Read all of it.
|
|
17
|
+
2. **Interview the PM to close gaps — one question at a time**, highest-value ambiguity first (never a wall of questions):
|
|
18
|
+
- which **personas** are in play — each a role set + scope (global / per-tenant-or-BU / resource-owner);
|
|
19
|
+
- for every capability the story adds or touches, **who may and who must not** — always pin the **forbidden** side explicitly;
|
|
20
|
+
- which **adjacent areas** this story could break (the regression surface);
|
|
21
|
+
- edge cases, empty / error states, boundaries the criteria skip.
|
|
22
|
+
3. **Decide the teams** the story touches (front / back / mobile) — usually not all three.
|
|
23
|
+
4. **Build one internal matrix** `persona × scenario → expected observable outcome` (allowed / refused), then **split it into one sub-task per team**. Deriving all sub-tasks from the *same* matrix is what keeps front and back from drifting on what a persona is or what's expected.
|
|
24
|
+
5. **Create the Jira sub-tasks** (issue type **Sub-task** unless the project uses a custom one — confirm against the project's issue types), each **linked to the parent story**:
|
|
25
|
+
- **label = the team** (`front` / `back` / `mobile`);
|
|
26
|
+
- **assignee = the specific developer** — ask the PM who takes each team; if unknown, leave it unassigned (never guess);
|
|
27
|
+
- each sub-task **self-contained**: it restates the personas and the expected outcomes for *its* layer, so the developer needn't read the sibling sub-tasks.
|
|
28
|
+
6. **Confirm the plan with the PM** before creating anything in Jira, then create the sub-tasks.
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
## What each sub-task contains
|
|
31
|
+
|
|
32
|
+
Behavioural cases, expressed as outcomes — never "has permission X":
|
|
34
33
|
|
|
34
|
+
- **Dense on the refused cells** — for every gated capability, at least one persona that must be **denied**.
|
|
35
|
+
- **State the layer's observable outcome** — back sub-task: API result (e.g. `member-simple → POST /merge-requests → 403`); front sub-task: UI result (e.g. create control absent — name the `data-test-*` hook where known).
|
|
36
|
+
- **Both layers must agree** — the same persona/scenario appears in the front *and* back sub-task with matching intent; a front/back disagreement at execution time is the bug this is meant to surface.
|
|
37
|
+
- **Expected comes from intent** (this contract), never to be recomputed downstream from the app's own check.
|
|
38
|
+
- **Regression surface** — list the adjacent flows to re-verify because this story touches them.
|
|
39
|
+
|
|
40
|
+
Example (front sub-task body):
|
|
41
|
+
|
|
42
|
+
```md
|
|
35
43
|
## Personas
|
|
36
44
|
- member-simple: role "member" on BU-1
|
|
37
|
-
- bu-admin-multi:
|
|
45
|
+
- bu-admin-multi: "bu-admin" on BU-1 + "member" on BU-2
|
|
38
46
|
|
|
39
|
-
##
|
|
40
|
-
- [ ] bu-admin-multi →
|
|
41
|
-
- [ ] member-simple →
|
|
47
|
+
## Create a merge request (front)
|
|
48
|
+
- [ ] bu-admin-multi → create control visible + usable (data-test: mr-create)
|
|
49
|
+
- [ ] member-simple → create control ABSENT (data-test: mr-create) ← refused cell
|
|
42
50
|
|
|
43
|
-
## Regression
|
|
44
|
-
- [ ] MR list still
|
|
45
|
-
- [ ] existing MR detail actions unchanged for bu-admin-multi
|
|
51
|
+
## Regression (this story touches MR permissions)
|
|
52
|
+
- [ ] MR list still renders for member-simple
|
|
46
53
|
```
|
|
47
54
|
|
|
48
|
-
## Prerequisite
|
|
55
|
+
## Prerequisite — flag it, don't paper over it
|
|
49
56
|
|
|
50
|
-
The refused/allowed cells are only real if each developer can **instantiate the personas** (a factory / token minter). If
|
|
57
|
+
The refused/allowed cells are only real if each developer can **instantiate the personas** (a factory / token minter). If a team has none, say so in its sub-task so it's built before the cells are trusted — see the persona matrix in `AGENTS.md` (Step 5.2).
|
package/AGENTS.md
CHANGED
|
@@ -229,6 +229,8 @@ Type every stub / handler to the real signature (Pass B step 3) — a stub that
|
|
|
229
229
|
- treat third-party components and the framework runtime as trusted boundaries — assert on **your** inputs to them and **your** handling of their outputs, not their internals;
|
|
230
230
|
- exclude framework / vendor / generated code from coverage (`coverage.exclude`) so the 90% measures only the code you wrote.
|
|
231
231
|
|
|
232
|
+
**Some effects aren't observable at unit level — send them to E2E, don't fake them.** A headless DOM (jsdom / happy-dom) does not compute layout or fully apply styling: CSS custom properties injected via `v-bind()` / `useCssVars`, values from real stylesheets, geometry, and paint are not serialized. If a case's only observable effect is one of these (e.g. a `fontSize` prop that just feeds a CSS variable), it **cannot** be asserted in a unit test. Do not select on a rendered style that the runner never produced, and do not invent a passing assertion. Cover the prop's *render* branches at unit level, assert the visual effect in **E2E**, and leave a one-line note on the skipped unit assertion per Step 5.0 — the same honesty rule as a genuinely unreachable path.
|
|
233
|
+
|
|
232
234
|
### Step 5.2 — Permission-gated units: the persona matrix
|
|
233
235
|
|
|
234
236
|
When a unit's behaviour depends on **who** the current user is — a role, a permission, an ownership / tenant / scope check — one happy-path user is not a test. This is the single biggest source of escaped bugs, because a harness that always authenticates as the same user (or only ever mints single-role users) never exercises the other actors. Apply this whenever Step 5.0 flagged an authorization gate.
|