@roopesh.yadava/qa-pack 1.0.3

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,234 @@
1
+ ---
2
+ name: ui-test-figma
3
+ description: >
4
+ Compares a live web application page against a Figma design to detect UI inconsistencies.
5
+ Uses Playwright CLI for zero-token screenshots and targeted browser_evaluate for CSS — never
6
+ browser_snapshot. Figma MCP preferred; browser fallback automatic. OTP always 999999.
7
+ Can be called standalone or from manual-testing (Step 1 of Manual branch).
8
+ Trigger: "compare with application", "ui test", "check design", "test this page against figma",
9
+ "run ui check", or a Figma link with a comparison request.
10
+ compatibility: >
11
+ Playwright CLI (npx playwright) must be available — already installed in this project.
12
+ Playwright MCP is used only for interactive login. All screenshots use CLI.
13
+ Figma MCP is optional — browser fallback fires automatically on any error.
14
+ user-invocable: true
15
+ ---
16
+
17
+ # UI Test Figma Skill
18
+
19
+ Compares a live app page against a Figma design. Uses **Playwright CLI** for all screenshots
20
+ (zero response tokens) and targeted `browser_evaluate` for CSS — never `browser_snapshot`.
21
+
22
+ ## Token Budget Rules
23
+
24
+ | Operation | USE | NEVER USE |
25
+ |-----------|-----|-----------|
26
+ | Screenshots | `npx playwright screenshot --full-page URL file.png` | `browser_screenshot()` (returns base64) |
27
+ | DOM reading | `browser_evaluate` with targeted selectors | `browser_snapshot()` (returns full tree) |
28
+ | Login flow | Playwright MCP `browser_fill` / `browser_click` | — |
29
+ | Session save | `browser_evaluate` → write `.playwright-session.json` | — |
30
+
31
+ ## Token Tracking
32
+
33
+ Silent background task — follow the **Token Tracking** pattern in `SKILLS_CONTEXT.md`.
34
+ Never show tracking output to user. Checkpoints: `start` → `login` → `comparison` → `end + report + session`.
35
+ Use `CARD_ID` if called from pipeline, else `"ui-test"`.
36
+
37
+ ---
38
+
39
+ ## Step 0 — Pre-flight: Collect Inputs One by One
40
+
41
+ Ask questions **one at a time**. Wait for the answer to each before asking the next.
42
+
43
+ **Question 1 — Figma URL:**
44
+ > Please share the **Figma design link** for the page you want to compare.
45
+ > It should look like: `https://www.figma.com/design/<FILE_KEY>/...?node-id=<NODE_ID>`
46
+ > Tip: In Figma, right-click the frame → **Copy link** to get a link that includes the `node-id`.
47
+
48
+ Validate it has a recognisable Figma domain and a `node-id` param. If missing:
49
+ > "Please right-click the frame in Figma → **Copy link** — that version includes the `node-id`."
50
+
51
+ **Question 2 — App URL:**
52
+ > Got it! Now paste the **full URL of the exact page** you want to test.
53
+
54
+ Store as `TARGET_URL`. Extract base origin as `BASE_URL`.
55
+
56
+ **Question 3 — Check if already logged in:**
57
+
58
+ First, check for a saved session file:
59
+ ```bash
60
+ ls .playwright-session.json 2>/dev/null && echo "SESSION_EXISTS" || echo "NO_SESSION"
61
+ ```
62
+
63
+ **If `.playwright-session.json` exists:**
64
+ - Set `SESSION_FILE = .playwright-session.json`
65
+ - Skip login entirely — proceed directly to Step 1b
66
+ - If a screenshot taken with `--storage-state` redirects to the login page, the session has expired: delete the file and fall through to the login flow below
67
+
68
+ **If no session file:**
69
+ Navigate to `BASE_URL` via `browser_navigate` and take a `browser_snapshot`.
70
+ - **Dashboard/home page** → session active, skip to Step 1b.
71
+ - **Login form** → ask for email, then password.
72
+
73
+ Once inputs collected: `"Got everything. Logging in and starting the comparison now..."`
74
+
75
+ **Parse the Figma URL:**
76
+ - `FILE_KEY` — alphanumeric segment after `/design/` or `/file/`
77
+ - `NODE_ID` — value of `node-id` query param (normalize `-` to `:`, e.g. `123-456` → `123:456`)
78
+
79
+ ---
80
+
81
+ ## Critical Rules
82
+
83
+ - Never ask the user to take a screenshot manually — Playwright handles all captures.
84
+ - If Figma MCP fails for any reason, **immediately** open Figma in a new browser tab (Method B). No pause, no asking user.
85
+ - Always wait for `networkidle` before any screenshot.
86
+
87
+ ---
88
+
89
+ ## Step 1 — Login to the Application
90
+
91
+ **Skip if session check in Step 0 Q3 confirmed already logged in.**
92
+
93
+ Use `browser_snapshot` to read field selectors, then:
94
+ 1. `browser_wait_for(state: "networkidle")`
95
+ 2. `browser_snapshot()` — read actual input selectors
96
+ 3. `browser_fill` email, password
97
+ 4. `browser_click` Login button
98
+ 5. `browser_wait_for(state: "networkidle")`
99
+ 6. `browser_snapshot()` — check for OTP screen
100
+
101
+ **If OTP screen appears** (6-box PIN):
102
+ 7. `browser_click` first OTP box
103
+ 8. `browser_type(text: "999999")` — always this value, auto-advances
104
+ 9. `browser_click` Verify button
105
+ 10. `browser_wait_for(state: "networkidle")`
106
+ 11. `browser_snapshot()` — confirm past OTP
107
+
108
+ Confirm login: dashboard/main nav → proceed. Still on login page → stop with error.
109
+
110
+ Run `login` token checkpoint.
111
+
112
+ ---
113
+
114
+ ## Step 1b — Navigate to Target Page and Capture
115
+
116
+ **1. Save authenticated session to disk:**
117
+ ```javascript
118
+ browser_evaluate({
119
+ expression: `JSON.stringify({
120
+ localStorage: Object.fromEntries(Object.entries(localStorage)),
121
+ sessionStorage: Object.fromEntries(Object.entries(sessionStorage)),
122
+ cookies: document.cookie
123
+ })`
124
+ })
125
+ ```
126
+ Write result to `.playwright-session.json`.
127
+
128
+ **2. Take full-page screenshot via Playwright CLI:**
129
+ ```bash
130
+ mkdir -p outputs/screenshots
131
+ npx playwright screenshot \
132
+ --storage-state .playwright-session.json \
133
+ --browser chromium \
134
+ --full-page \
135
+ --viewport-size "1920,1080" \
136
+ --wait-for-timeout 3000 \
137
+ "TARGET_URL" \
138
+ outputs/screenshots/app-capture.png
139
+ ```
140
+ If `.playwright-session.json` does not exist, omit the `--storage-state` flag.
141
+ Store as `APP_SCREENSHOT = outputs/screenshots/app-capture.png`.
142
+
143
+ **3. Extract computed CSS via `browser_evaluate`:**
144
+
145
+ Load `.claude/skills/ui-test-figma/COMPARISON_PATTERNS.md` now — use the
146
+ **CSS Extraction JS** block from that file to run `browser_evaluate`.
147
+ Store result as `APP_CSS`.
148
+
149
+ ---
150
+
151
+ ## Step 2 — Fetch Figma Design
152
+
153
+ Try Method A first. On **any** error, immediately use Method B.
154
+
155
+ #### Method A — Figma MCP (preferred)
156
+ ```
157
+ get_design_context(fileKey: FILE_KEY, nodeId: NODE_ID)
158
+ ```
159
+ On success, extract all text layers, layout structure, design tokens.
160
+ Tag each text element: `STATIC`, `DYNAMIC`, or `PATTERN` (rules in COMPARISON_PATTERNS.md).
161
+ Mark source as `[Source: Figma MCP]`.
162
+
163
+ #### Method B — Playwright CLI Fallback (automatic, zero response tokens)
164
+ ```bash
165
+ mkdir -p outputs/screenshots
166
+ npx playwright screenshot \
167
+ --browser chromium \
168
+ --full-page \
169
+ --viewport-size "1920,1080" \
170
+ --wait-for-timeout 15000 \
171
+ "<Figma URL from user>" \
172
+ outputs/screenshots/figma-design.png
173
+ ```
174
+ If screenshot shows Figma login page:
175
+ > "You're not logged into Figma. Please log into figma.com in your browser, then confirm to retry."
176
+
177
+ Store `FIGMA_SCREENSHOT = outputs/screenshots/figma-design.png`.
178
+ Mark source as `[Source: Playwright CLI Screenshot]`.
179
+
180
+ ---
181
+
182
+ ## Step 3 — Intelligent Comparison
183
+
184
+ **Load `.claude/skills/ui-test-figma/COMPARISON_PATTERNS.md` now.**
185
+
186
+ Use the following from that file:
187
+ - **Tag Classification Rules** — classify Figma elements as STATIC / DYNAMIC / PATTERN
188
+ - **CSS Comparison Rules** — compare design tokens vs computed styles
189
+ - **Visual Comparison Checklist** (Method B) — 13-point structured check
190
+
191
+ Run `comparison` token checkpoint after comparison is complete.
192
+
193
+ ---
194
+
195
+ ## Step 4 — Generate Report
196
+
197
+ Use the **Report Template** from `COMPARISON_PATTERNS.md`.
198
+
199
+ ### Step 4b — Save Report to outputs/
200
+
201
+ ```bash
202
+ ls outputs/ 2>/dev/null && echo "EXISTS" || echo "MISSING"
203
+ ```
204
+
205
+ If `outputs/` exists:
206
+ 1. Derive `URL_SLUG` from `TARGET_URL` (drop UUID segments, last 2 meaningful segments, lowercase)
207
+ 2. Build filename: `ui-bugs-{URL_SLUG}-{YYYYMMDD-HHmmss}.md`
208
+ 3. Write full report to `outputs/{filename}`.
209
+ 4. Tell user: `"Report saved to outputs/{filename}."`
210
+
211
+ ---
212
+
213
+ ## Step 5 — Jira Bug Logging (optional)
214
+
215
+ Ask:
216
+ > "Would you like me to log the failures as comments on a Jira card?
217
+ > If yes, share the **Jira card link** and the **assignee name**."
218
+
219
+ If yes:
220
+ 1. Extract issue key from URL. Use `getJiraIssue` to confirm card exists.
221
+ 2. Use `lookupJiraAccountId` for the assignee name.
222
+ - One match → use directly. Multiple → list and ask. None → ask for email.
223
+ 3. Use `addCommentToJiraIssue` with the **Jira Comment Template** from `COMPARISON_PATTERNS.md`.
224
+ Do NOT assign the card — only tag the assignee in the comment.
225
+
226
+ After posting:
227
+ ```
228
+ JIRA UPDATED
229
+ ✅ Comment posted — [N] failure(s) logged
230
+ ✅ Tagged : [Full Name]
231
+ Card : [Jira URL]
232
+ ```
233
+
234
+ Run `end + report + session` token close-out.
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@roopesh.yadava/qa-pack",
3
+ "version": "1.0.3",
4
+ "description": "AI-powered QA agent skills for Claude Code — manual testing, BDD automation, accessibility, UI/Figma diff, bug reporting",
5
+ "scripts": {
6
+ "postinstall": "node bin/postinstall.js"
7
+ },
8
+ "files": [
9
+ "bin/",
10
+ "claude/",
11
+ "templates/"
12
+ ],
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/Roopesh519/qa-pack.git"
19
+ },
20
+ "keywords": [
21
+ "qa",
22
+ "testing",
23
+ "claude",
24
+ "playwright",
25
+ "cucumber",
26
+ "bdd"
27
+ ],
28
+ "license": "MIT"
29
+ }
@@ -0,0 +1,41 @@
1
+ # QA Agent — Project Configuration
2
+
3
+ <!-- Fill in the sections marked TODO before committing. -->
4
+
5
+ ## Project
6
+
7
+ - **Jira Project Key**: `TODO: e.g. PROJ`
8
+ - **App URL**: `TODO: e.g. https://app.example.com`
9
+ - **Login URL**: `TODO: e.g. https://app.example.com/login` (or same as App URL)
10
+ - **Environment**: `TODO: staging | dev | prod`
11
+ - **Auth Method**: `TODO: form_login | SSO | token | none`
12
+ - **OTP Required**: `TODO: yes (always use 999999) | no`
13
+
14
+ ## Test credentials (dev/staging only — use env vars in CI)
15
+
16
+ - **Username**: `TODO`
17
+ - **Password**: `TODO`
18
+
19
+ ---
20
+
21
+ ## QA Skills available
22
+
23
+ This project has the full QA agent skill pack installed. Invoke any skill from Claude Code:
24
+
25
+ | What you want | How to trigger |
26
+ |---|---|
27
+ | Full QA on a Jira card | `run qa PROJ-123` |
28
+ | Manual testing only | `manual test PROJ-123` |
29
+ | Write BDD automation | `automate PROJ-123` |
30
+ | Accessibility audit | `accessibility test PROJ-123` |
31
+ | UI vs Figma diff | `ui test PROJ-123` |
32
+ | File a bug | `file a bug` |
33
+ | Write acceptance criteria | `/write-acceptance-criteria PROJ-123` |
34
+ | Clean up outputs | `delete files` |
35
+
36
+ ## Conventions
37
+
38
+ - Test files live in `test/` — feature files in `test/features/`, step definitions in `test/step-definations/`
39
+ - BDD runner: CucumberJS with `cucumber.cjs` config
40
+ - Screenshots and reports go to `outputs/` (gitignored)
41
+ - Product context (persistent QA memory) lives in `.claude/skills/qa-agent/product_context/{PROJECT_KEY}/context.md`
@@ -0,0 +1,7 @@
1
+ // Root Cucumber config — used for dry-run and ad-hoc runs
2
+ module.exports = {
3
+ default: {
4
+ import: ['test/step-definations/**/*.cjs'],
5
+ format: ['progress'],
6
+ },
7
+ };
@@ -0,0 +1,18 @@
1
+ {
2
+ "mcpServers": {
3
+ "playwright": {
4
+ "type": "stdio",
5
+ "command": "npx",
6
+ "args": [
7
+ "@playwright/mcp@latest",
8
+ "--browser",
9
+ "chromium",
10
+ "--caps",
11
+ "vision",
12
+ "--viewport-size",
13
+ "1920x1080"
14
+ ],
15
+ "env": {}
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npx playwright *)",
5
+ "Bash(npx cucumber-js *)",
6
+ "Bash(echo \"Exit: $?\")",
7
+ "Bash(playwright --version)",
8
+ "mcp__claude_ai_Atlassian__getAccessibleAtlassianResources",
9
+ "mcp__claude_ai_Atlassian__getJiraIssue",
10
+ "mcp__claude_ai_Atlassian__createJiraIssue",
11
+ "mcp__claude_ai_Atlassian__createIssueLink",
12
+ "mcp__claude_ai_Atlassian__addCommentToJiraIssue"
13
+ ]
14
+ },
15
+ "enableAllProjectMcpServers": true,
16
+ "enabledMcpjsonServers": [
17
+ "playwright"
18
+ ]
19
+ }