claude-code-kit 0.7.0__py3-none-any.whl

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.
Files changed (209) hide show
  1. claude_code_kit-0.7.0.dist-info/METADATA +384 -0
  2. claude_code_kit-0.7.0.dist-info/RECORD +209 -0
  3. claude_code_kit-0.7.0.dist-info/WHEEL +4 -0
  4. claude_code_kit-0.7.0.dist-info/entry_points.txt +4 -0
  5. claude_code_kit-0.7.0.dist-info/licenses/LICENSE +21 -0
  6. claude_kit/__init__.py +10 -0
  7. claude_kit/__main__.py +8 -0
  8. claude_kit/_payload/agents/acceptance-reviewer.md +60 -0
  9. claude_kit/_payload/agents/auditor.md +76 -0
  10. claude_kit/_payload/agents/dependency-scanner.md +84 -0
  11. claude_kit/_payload/agents/developer.md +187 -0
  12. claude_kit/_payload/agents/devils-advocate.md +62 -0
  13. claude_kit/_payload/agents/devops-engineer.md +134 -0
  14. claude_kit/_payload/agents/e2e-tester.md +152 -0
  15. claude_kit/_payload/agents/em-reviewer.md +105 -0
  16. claude_kit/_payload/agents/incident-responder.md +64 -0
  17. claude_kit/_payload/agents/merge-reviewer.md +194 -0
  18. claude_kit/_payload/agents/observability-engineer.md +94 -0
  19. claude_kit/_payload/agents/orchestrator.md +551 -0
  20. claude_kit/_payload/agents/owasp-reviewer.md +76 -0
  21. claude_kit/_payload/agents/policy-validator.md +63 -0
  22. claude_kit/_payload/agents/pr-raiser.md +138 -0
  23. claude_kit/_payload/agents/risk-classifier.md +50 -0
  24. claude_kit/_payload/agents/sdlc-code-reviewer.md +196 -0
  25. claude_kit/_payload/agents/secret-scanner.md +70 -0
  26. claude_kit/_payload/agents/security-reviewer.md +80 -0
  27. claude_kit/_payload/agents/senior-backend-dev.md +199 -0
  28. claude_kit/_payload/agents/senior-frontend-dev.md +181 -0
  29. claude_kit/_payload/agents/senior-tester.md +206 -0
  30. claude_kit/_payload/agents/spec-doc-writer.md +331 -0
  31. claude_kit/_payload/agents/story-planner.md +56 -0
  32. claude_kit/_payload/agents/technical-architect.md +139 -0
  33. claude_kit/_payload/agents/tester.md +193 -0
  34. claude_kit/_payload/agents/ui-designer.md +73 -0
  35. claude_kit/_payload/agents/unit-tester.md +119 -0
  36. claude_kit/_payload/catalog/mcp.yaml +54 -0
  37. claude_kit/_payload/catalog/org.yaml +145 -0
  38. claude_kit/_payload/catalog/profiles.yaml +96 -0
  39. claude_kit/_payload/catalog/stacks.yaml +96 -0
  40. claude_kit/_payload/commands/init.md +36 -0
  41. claude_kit/_payload/commands/sdlc.md +18 -0
  42. claude_kit/_payload/commands/status.md +20 -0
  43. claude_kit/_payload/hooks/hooks.json +58 -0
  44. claude_kit/_payload/hooks/scripts/audit-log.sh +18 -0
  45. claude_kit/_payload/hooks/scripts/guard-secrets.sh +26 -0
  46. claude_kit/_payload/hooks/scripts/lint-fix.sh +38 -0
  47. claude_kit/_payload/hooks/scripts/load-continuity.sh +32 -0
  48. claude_kit/_payload/hooks/scripts/load-learnings.sh +40 -0
  49. claude_kit/_payload/hooks/scripts/type-check.sh +23 -0
  50. claude_kit/_payload/hooks/scripts/validate-frontmatter.sh +34 -0
  51. claude_kit/_payload/hooks/scripts/validate-settings.sh +21 -0
  52. claude_kit/_payload/hooks/scripts/warn-large-edits.sh +24 -0
  53. claude_kit/_payload/hooks/scripts/warn-missing-tests.sh +24 -0
  54. claude_kit/_payload/hooks/scripts/warn-sensitive-files.sh +30 -0
  55. claude_kit/_payload/hooks/scripts/warn-shared-modules.sh +33 -0
  56. claude_kit/_payload/rules/agent-guardrails.md +83 -0
  57. claude_kit/_payload/rules/agent-memory.md +106 -0
  58. claude_kit/_payload/rules/agent-resilience.md +61 -0
  59. claude_kit/_payload/rules/autonomy-levels.md +30 -0
  60. claude_kit/_payload/rules/code-organization.md +312 -0
  61. claude_kit/_payload/rules/continuity.md +84 -0
  62. claude_kit/_payload/rules/design-patterns.md +422 -0
  63. claude_kit/_payload/rules/devops-observability.md +57 -0
  64. claude_kit/_payload/rules/documentation.md +326 -0
  65. claude_kit/_payload/rules/evals.md +62 -0
  66. claude_kit/_payload/rules/frontend-best-practices.md +157 -0
  67. claude_kit/_payload/rules/goal-setting-and-monitoring.md +72 -0
  68. claude_kit/_payload/rules/human-in-the-loop.md +64 -0
  69. claude_kit/_payload/rules/linting-and-formatting.md +220 -0
  70. claude_kit/_payload/rules/mandatory-workflow.md +309 -0
  71. claude_kit/_payload/rules/model-tiers.md +34 -0
  72. claude_kit/_payload/rules/quality-gates.md +107 -0
  73. claude_kit/_payload/rules/rarv-cycle.md +31 -0
  74. claude_kit/_payload/rules/reasoning-techniques.md +62 -0
  75. claude_kit/_payload/rules/responsive-and-accessibility.md +353 -0
  76. claude_kit/_payload/rules/risk-classification.md +36 -0
  77. claude_kit/_payload/rules/testing.md +417 -0
  78. claude_kit/_payload/rules/tool-design.md +66 -0
  79. claude_kit/_payload/skills/_references/accessibility-checklist.md +160 -0
  80. claude_kit/_payload/skills/_references/orchestration-patterns.md +405 -0
  81. claude_kit/_payload/skills/_references/performance-checklist.md +153 -0
  82. claude_kit/_payload/skills/_references/security-checklist.md +134 -0
  83. claude_kit/_payload/skills/_references/testing-patterns.md +236 -0
  84. claude_kit/_payload/skills/accessibility-review/SKILL.md +56 -0
  85. claude_kit/_payload/skills/api-and-interface-design/SKILL.md +294 -0
  86. claude_kit/_payload/skills/api-integration/SKILL.md +348 -0
  87. claude_kit/_payload/skills/archive-sprint/SKILL.md +31 -0
  88. claude_kit/_payload/skills/backlog/SKILL.md +41 -0
  89. claude_kit/_payload/skills/backlog/item-template.md +20 -0
  90. claude_kit/_payload/skills/browser-testing-with-devtools/SKILL.md +302 -0
  91. claude_kit/_payload/skills/ci-cd-and-automation/SKILL.md +402 -0
  92. claude_kit/_payload/skills/code-review-and-quality/SKILL.md +347 -0
  93. claude_kit/_payload/skills/code-simplification/SKILL.md +331 -0
  94. claude_kit/_payload/skills/component-design/SKILL.md +171 -0
  95. claude_kit/_payload/skills/consolidate-learnings/SKILL.md +55 -0
  96. claude_kit/_payload/skills/context-engineering/SKILL.md +321 -0
  97. claude_kit/_payload/skills/debugging-and-error-recovery/SKILL.md +300 -0
  98. claude_kit/_payload/skills/decision/SKILL.md +46 -0
  99. claude_kit/_payload/skills/decision/adr-template.md +36 -0
  100. claude_kit/_payload/skills/deprecation-and-migration/SKILL.md +207 -0
  101. claude_kit/_payload/skills/documentation-and-adrs/SKILL.md +299 -0
  102. claude_kit/_payload/skills/doubt-driven-development/SKILL.md +243 -0
  103. claude_kit/_payload/skills/execute/SKILL.md +27 -0
  104. claude_kit/_payload/skills/frontend-ui-engineering/SKILL.md +328 -0
  105. claude_kit/_payload/skills/git-workflow-and-versioning/SKILL.md +300 -0
  106. claude_kit/_payload/skills/idea-refine/SKILL.md +178 -0
  107. claude_kit/_payload/skills/idea-refine/examples.md +238 -0
  108. claude_kit/_payload/skills/idea-refine/frameworks.md +99 -0
  109. claude_kit/_payload/skills/idea-refine/refinement-criteria.md +113 -0
  110. claude_kit/_payload/skills/idea-refine/scripts/idea-refine.sh +15 -0
  111. claude_kit/_payload/skills/incident-postmortem/SKILL.md +74 -0
  112. claude_kit/_payload/skills/incremental-implementation/SKILL.md +245 -0
  113. claude_kit/_payload/skills/interview-me/SKILL.md +221 -0
  114. claude_kit/_payload/skills/load-testing/SKILL.md +83 -0
  115. claude_kit/_payload/skills/manual-test/SKILL.md +516 -0
  116. claude_kit/_payload/skills/performance-optimization/SKILL.md +277 -0
  117. claude_kit/_payload/skills/planning-and-task-breakdown/SKILL.md +223 -0
  118. claude_kit/_payload/skills/playwright-verification/SKILL.md +205 -0
  119. claude_kit/_payload/skills/refresh-docs/SKILL.md +63 -0
  120. claude_kit/_payload/skills/remember/SKILL.md +96 -0
  121. claude_kit/_payload/skills/scope/SKILL.md +52 -0
  122. claude_kit/_payload/skills/scope/scope-template.md +82 -0
  123. claude_kit/_payload/skills/sdlc/SKILL.md +83 -0
  124. claude_kit/_payload/skills/security-and-hardening/SKILL.md +368 -0
  125. claude_kit/_payload/skills/security-verification/SKILL.md +209 -0
  126. claude_kit/_payload/skills/shipping-and-launch/SKILL.md +309 -0
  127. claude_kit/_payload/skills/smoke-test/SKILL.md +78 -0
  128. claude_kit/_payload/skills/source-driven-development/SKILL.md +195 -0
  129. claude_kit/_payload/skills/spec-driven-development/SKILL.md +200 -0
  130. claude_kit/_payload/skills/sprint/SKILL.md +67 -0
  131. claude_kit/_payload/skills/sprint/sprint-template.md +90 -0
  132. claude_kit/_payload/skills/test-driven-development/SKILL.md +383 -0
  133. claude_kit/_payload/skills/threat-model/SKILL.md +60 -0
  134. claude_kit/_payload/skills/triage/SKILL.md +87 -0
  135. claude_kit/_payload/skills/ui-ux-design/SKILL.md +71 -0
  136. claude_kit/_payload/skills/unit-test/SKILL.md +237 -0
  137. claude_kit/_payload/skills/using-agent-skills/SKILL.md +180 -0
  138. claude_kit/_payload/templates/CLAUDE.md +238 -0
  139. claude_kit/_payload/templates/CLAUDE.stack.md.tmpl +53 -0
  140. claude_kit/_payload/templates/CONTINUITY.template.md +35 -0
  141. claude_kit/_payload/templates/README.claude-sdlc.md.tmpl +219 -0
  142. claude_kit/_payload/templates/agent-memory/MEMORY.md +30 -0
  143. claude_kit/_payload/templates/agent-memory/api/.gitkeep +0 -0
  144. claude_kit/_payload/templates/agent-memory/architecture/.gitkeep +0 -0
  145. claude_kit/_payload/templates/agent-memory/debugging/.gitkeep +0 -0
  146. claude_kit/_payload/templates/agent-memory/gotchas/.gitkeep +0 -0
  147. claude_kit/_payload/templates/agent-memory/patterns/.gitkeep +0 -0
  148. claude_kit/_payload/templates/agent-memory/performance/.gitkeep +0 -0
  149. claude_kit/_payload/templates/artifacts/adr.md +18 -0
  150. claude_kit/_payload/templates/artifacts/feature-spec.md +29 -0
  151. claude_kit/_payload/templates/artifacts/release-plan.md +23 -0
  152. claude_kit/_payload/templates/artifacts/runbook.md +24 -0
  153. claude_kit/_payload/templates/artifacts/security-review.md +23 -0
  154. claude_kit/_payload/templates/artifacts/test-plan.md +22 -0
  155. claude_kit/_payload/templates/org/README.md +53 -0
  156. claude_kit/_payload/templates/org/agents/data-workflow-agent.md +59 -0
  157. claude_kit/_payload/templates/org/agents/founder-prototype-agent.md +61 -0
  158. claude_kit/_payload/templates/org/agents/internal-tools-builder.md +63 -0
  159. claude_kit/_payload/templates/org/agents/pm-copilot.md +60 -0
  160. claude_kit/_payload/templates/org/agents/support-ticket-engineer.md +63 -0
  161. claude_kit/_payload/templates/org/packs/devops-and-release/README.md +46 -0
  162. claude_kit/_payload/templates/org/packs/devops-and-release/pack.yaml +32 -0
  163. claude_kit/_payload/templates/org/packs/engineering-core/README.md +46 -0
  164. claude_kit/_payload/templates/org/packs/engineering-core/pack.yaml +44 -0
  165. claude_kit/_payload/templates/org/packs/non-engineer-builder/README.md +53 -0
  166. claude_kit/_payload/templates/org/packs/non-engineer-builder/pack.yaml +39 -0
  167. claude_kit/_payload/templates/org/packs/onboarding-and-docs/README.md +49 -0
  168. claude_kit/_payload/templates/org/packs/onboarding-and-docs/pack.yaml +26 -0
  169. claude_kit/_payload/templates/org/packs/product-to-code/README.md +50 -0
  170. claude_kit/_payload/templates/org/packs/product-to-code/pack.yaml +34 -0
  171. claude_kit/_payload/templates/org/packs/quality-and-review/README.md +53 -0
  172. claude_kit/_payload/templates/org/packs/quality-and-review/pack.yaml +40 -0
  173. claude_kit/_payload/templates/org/packs/security-and-compliance/README.md +50 -0
  174. claude_kit/_payload/templates/org/packs/security-and-compliance/pack.yaml +36 -0
  175. claude_kit/_payload/templates/org/rules/ai-working-agreement.md +45 -0
  176. claude_kit/_payload/templates/org/rules/ambiguity-resolution.md +36 -0
  177. claude_kit/_payload/templates/org/rules/branch-and-pr-policy.md +41 -0
  178. claude_kit/_payload/templates/org/rules/compliance-policy.md +50 -0
  179. claude_kit/_payload/templates/org/rules/non-engineer-safe-coding.md +37 -0
  180. claude_kit/_payload/templates/org/rules/pii-policy.md +46 -0
  181. claude_kit/_payload/templates/org/rules/production-data-policy.md +35 -0
  182. claude_kit/_payload/templates/org/rules/prompt-to-task-conversion.md +30 -0
  183. claude_kit/_payload/templates/org/rules/prototype-boundaries.md +40 -0
  184. claude_kit/_payload/templates/org/rules/secrets-policy.md +34 -0
  185. claude_kit/_payload/templates/org/skills/customer-issue-to-fix/SKILL.md +61 -0
  186. claude_kit/_payload/templates/org/skills/feature-from-idea/SKILL.md +56 -0
  187. claude_kit/_payload/templates/org/skills/prompt-to-safe-task/SKILL.md +59 -0
  188. claude_kit/_payload/templates/org/skills/prototype-to-production/SKILL.md +61 -0
  189. claude_kit/_payload/templates/org/skills/repo-onboarding/SKILL.md +60 -0
  190. claude_kit/_payload/templates/settings.json +53 -0
  191. claude_kit/_payload/templates/stacks/backend/python/fastapi/rules/fastapi-patterns.md +64 -0
  192. claude_kit/_payload/templates/stacks/db/mongodb/agents/migration-specialist.md +61 -0
  193. claude_kit/_payload/templates/stacks/db/mongodb/agents/mongodb-specialist.md +59 -0
  194. claude_kit/_payload/templates/stacks/db/mongodb/rules/mongodb-patterns.md +39 -0
  195. claude_kit/_payload/templates/stacks/db/postgres/agents/db-performance-reviewer.md +66 -0
  196. claude_kit/_payload/templates/stacks/db/postgres/agents/migration-specialist.md +56 -0
  197. claude_kit/_payload/templates/stacks/db/postgres/agents/postgres-specialist.md +58 -0
  198. claude_kit/_payload/templates/stacks/db/postgres/rules/database-performance.md +64 -0
  199. claude_kit/_payload/templates/stacks/db/postgres/rules/postgres-patterns.md +43 -0
  200. claude_kit/_payload/templates/stacks/frontend/react/rules/react-patterns.md +63 -0
  201. claude_kit/catalog.py +476 -0
  202. claude_kit/cli.py +327 -0
  203. claude_kit/hooks.py +246 -0
  204. claude_kit/models.py +205 -0
  205. claude_kit/prompts.py +209 -0
  206. claude_kit/render.py +146 -0
  207. claude_kit/scaffold.py +492 -0
  208. claude_kit/upgrader.py +294 -0
  209. claude_kit/validator.py +197 -0
@@ -0,0 +1,516 @@
1
+ ---
2
+ name: manual-test
3
+ description: Manually test a developed feature using browser automation in headed mode. Navigates to the page, interacts with elements, and verifies behavior visually — like a QA tester sitting at the screen.
4
+ argument-hint: [page route or feature name, e.g. "/store-view", "dashboard filters", "exception card"]
5
+ disable-model-invocation: true
6
+ ---
7
+
8
+ Manually test the feature: $ARGUMENTS.
9
+
10
+ ## Steps
11
+
12
+ ### 1. Identify what to test
13
+
14
+ Based on `$ARGUMENTS`, determine:
15
+ - Which page/route to navigate to
16
+ - Which UI elements to interact with
17
+ - What behavior to verify (renders, clicks, filters, navigation, edge cases)
18
+
19
+ If `$ARGUMENTS` is vague, ask the user:
20
+ - Which page or component should I test?
21
+ - What specific behavior should I verify?
22
+ - Any particular edge cases to check?
23
+
24
+ ### 2. Set up authenticated browser session
25
+
26
+ If the app requires authentication, use the project's E2E framework to create a headed (visible) browser session with auth bypassed or configured.
27
+
28
+ The helper should support **multiple browsers** and **custom viewports** for device simulation. Example pattern (adapt to your project's E2E framework):
29
+
30
+ ```typescript
31
+ // Example using Playwright
32
+ import { test, expect } from '@playwright/test';
33
+ import { chromium, firefox, webkit } from '@playwright/test';
34
+ import type { BrowserType } from '@playwright/test';
35
+
36
+ // Supported browsers
37
+ const BROWSERS = {
38
+ chrome: chromium,
39
+ firefox: firefox,
40
+ safari: webkit,
41
+ } as const;
42
+
43
+ // Device presets — screen sizes for testing
44
+ const DEVICES = {
45
+ // Mobile
46
+ 'iphone-se': { width: 375, height: 667, label: 'iPhone SE', isMobile: true },
47
+ 'iphone-14': { width: 390, height: 844, label: 'iPhone 14', isMobile: true },
48
+ 'iphone-14-pro-max': { width: 430, height: 932, label: 'iPhone 14 Pro Max', isMobile: true },
49
+ 'pixel-7': { width: 412, height: 915, label: 'Pixel 7', isMobile: true },
50
+ 'samsung-s23': { width: 360, height: 780, label: 'Samsung Galaxy S23', isMobile: true },
51
+ // Tablet
52
+ 'ipad': { width: 768, height: 1024, label: 'iPad', isMobile: true },
53
+ 'ipad-pro': { width: 1024, height: 1366, label: 'iPad Pro 12.9"', isMobile: true },
54
+ 'android-tablet': { width: 800, height: 1280, label: 'Android Tablet', isMobile: true },
55
+ // Desktop
56
+ 'laptop': { width: 1366, height: 768, label: 'Laptop (1366x768)', isMobile: false },
57
+ 'desktop': { width: 1920, height: 1080, label: 'Desktop (1080p)', isMobile: false },
58
+ 'desktop-xl': { width: 2560, height: 1440, label: 'Desktop (1440p)', isMobile: false },
59
+ } as const;
60
+
61
+ type BrowserName = keyof typeof BROWSERS;
62
+ type DeviceName = keyof typeof DEVICES;
63
+
64
+ interface AuthPageOptions {
65
+ browser?: BrowserName; // default: 'chrome'
66
+ device?: DeviceName; // default: 'desktop'
67
+ viewport?: { width: number; height: number }; // custom override
68
+ }
69
+
70
+ async function createAuthenticatedPage(options: AuthPageOptions = {}) {
71
+ const browserName = options.browser ?? 'chrome';
72
+ const browserType = BROWSERS[browserName];
73
+ const device = options.device ? DEVICES[options.device] : undefined;
74
+ const viewport = options.viewport ?? (device ? { width: device.width, height: device.height } : { width: 1920, height: 1080 });
75
+
76
+ const browser = await browserType.launch({ headless: false });
77
+ const context = await browser.newContext({
78
+ ignoreHTTPSErrors: true,
79
+ viewport,
80
+ isMobile: device?.isMobile ?? false,
81
+ hasTouch: device?.isMobile ?? false,
82
+ userAgent: device?.isMobile
83
+ ? 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1'
84
+ : undefined,
85
+ });
86
+ const page = await context.newPage();
87
+
88
+ const deviceLabel = device?.label ?? `${viewport.width}x${viewport.height}`;
89
+ console.log(`Browser: ${browserName} | Device: ${deviceLabel} | Viewport: ${viewport.width}x${viewport.height}`);
90
+
91
+ // Mock authentication or inject session storage
92
+ // Adapt this to your project's auth mechanism
93
+ await page.route('**/api/auth/session**', (route) => {
94
+ route.fulfill({
95
+ status: 200,
96
+ contentType: 'application/json',
97
+ body: JSON.stringify({
98
+ success: true,
99
+ user: {
100
+ firstName: 'Test', lastName: 'User',
101
+ email: 'test@example.com',
102
+ role: 'admin',
103
+ },
104
+ }),
105
+ });
106
+ });
107
+
108
+ // Navigate to login and inject session state
109
+ await page.goto('http://localhost:3000/login', {
110
+ waitUntil: 'domcontentloaded',
111
+ timeout: 15000,
112
+ });
113
+ await page.evaluate(() => {
114
+ sessionStorage.setItem('auth-state', JSON.stringify({
115
+ isAuthenticated: true,
116
+ user: {
117
+ firstName: 'Test', lastName: 'User',
118
+ email: 'test@example.com',
119
+ role: 'admin',
120
+ },
121
+ }));
122
+ });
123
+
124
+ return { browser, context, page, browserName, deviceLabel, viewport };
125
+ }
126
+ ```
127
+
128
+ ### 3. Write the test file
129
+
130
+ Create the test in the appropriate E2E test directory. Name it `<feature>.manual.spec.ts` or follow your project's naming convention.
131
+
132
+ **Test template:**
133
+
134
+ ```typescript
135
+ import { test, expect } from '@playwright/test';
136
+
137
+ // -- Auth helper with BROWSERS and DEVICES constants (from step 2) --
138
+
139
+ test.describe('<Feature Name> — Manual Test', () => {
140
+
141
+ test('<what you are testing>', async () => {
142
+ const { browser, page } = await createAuthenticatedPage();
143
+ // Or with specific browser/device:
144
+ // const { browser, page } = await createAuthenticatedPage({ browser: 'firefox' });
145
+ // const { browser, page } = await createAuthenticatedPage({ device: 'iphone-14' });
146
+ // const { browser, page } = await createAuthenticatedPage({ browser: 'safari', device: 'ipad' });
147
+
148
+ try {
149
+ await page.goto('http://localhost:3000/<route>', {
150
+ waitUntil: 'networkidle',
151
+ timeout: 30000,
152
+ });
153
+
154
+ await expect(page.locator('main')).toBeVisible({ timeout: 15000 });
155
+
156
+ // ... your test steps here ...
157
+
158
+ } finally {
159
+ await browser.close();
160
+ }
161
+ });
162
+ });
163
+ ```
164
+
165
+ ### 4. Build the test based on the feature type
166
+
167
+ Pick the relevant test patterns below and combine them:
168
+
169
+ #### Page load verification
170
+ ```typescript
171
+ // Verify page renders with key content
172
+ await page.goto('http://localhost:3000/<route>', {
173
+ waitUntil: 'networkidle', timeout: 30000,
174
+ });
175
+ await expect(page.locator('main')).toBeVisible({ timeout: 15000 });
176
+ await expect(page.getByRole('heading', { name: '<Page Title>' })).toBeVisible();
177
+ ```
178
+
179
+ #### Click interactions
180
+ ```typescript
181
+ // Click a button and verify result
182
+ const button = page.getByRole('button', { name: '<Button Text>' });
183
+ await expect(button).toBeVisible();
184
+ await button.click();
185
+ await expect(page.getByText('<Expected Result>')).toBeVisible();
186
+ ```
187
+
188
+ #### Filter / dropdown testing
189
+ ```typescript
190
+ // Open a filter dropdown, select option, verify results update
191
+ const filterButton = page.getByRole('button', { name: '<Filter Name>' }).first();
192
+ await filterButton.click();
193
+ await page.waitForTimeout(500);
194
+ const dropdown = page.locator('.dropdown-container');
195
+ await expect(dropdown).toBeVisible();
196
+
197
+ // Count options
198
+ const optionCount = await dropdown.locator('ul li button').count();
199
+ console.log(`Filter options: ${optionCount}`);
200
+
201
+ // Select an option
202
+ const firstOption = dropdown.locator('ul li button').first();
203
+ const optionText = await firstOption.textContent();
204
+ console.log(`Selecting: "${optionText}"`);
205
+ await firstOption.click();
206
+ await page.waitForTimeout(1000);
207
+ ```
208
+
209
+ #### Tab switching
210
+ ```typescript
211
+ // Click a tab and verify content changes
212
+ const tab = page.getByRole('tab', { name: '<Tab Name>' });
213
+ await tab.click();
214
+ await expect(page.getByRole('tabpanel')).toBeVisible();
215
+ await expect(page.getByText('<Expected Content>')).toBeVisible();
216
+ ```
217
+
218
+ #### Navigation
219
+ ```typescript
220
+ // Click a link/card and verify navigation
221
+ await page.click('a[href="/<target-route>"]');
222
+ await expect(page).toHaveURL('/<target-route>');
223
+ await expect(page.locator('main')).toBeVisible();
224
+ ```
225
+
226
+ #### Table / list verification
227
+ ```typescript
228
+ // Verify table renders with data
229
+ const table = page.locator('table');
230
+ await expect(table).toBeVisible();
231
+ const rows = table.locator('tbody tr');
232
+ const rowCount = await rows.count();
233
+ console.log(`Table rows: ${rowCount}`);
234
+ expect(rowCount).toBeGreaterThan(0);
235
+ ```
236
+
237
+ #### Empty state
238
+ ```typescript
239
+ // Verify empty state shows when no data
240
+ await expect(page.getByText(/no.*found/i)).toBeVisible();
241
+ ```
242
+
243
+ #### Cross-browser testing (Chrome + Firefox + Safari)
244
+
245
+ **ALWAYS run tests on multiple browsers.** Write a loop that tests the same page on Chrome, Firefox, and Safari:
246
+
247
+ ```typescript
248
+ // Test on all three browsers
249
+ for (const browserName of ['chrome', 'firefox', 'safari'] as const) {
250
+ test(`<Feature> works on ${browserName}`, async () => {
251
+ const { browser, page, deviceLabel } = await createAuthenticatedPage({ browser: browserName });
252
+
253
+ try {
254
+ await page.goto('http://localhost:3000/<route>', {
255
+ waitUntil: 'networkidle', timeout: 30000,
256
+ });
257
+ await expect(page.locator('main')).toBeVisible({ timeout: 15000 });
258
+
259
+ // ... your test assertions here ...
260
+
261
+ await page.screenshot({
262
+ path: `e2e/screenshots/<feature>-${browserName}.png`,
263
+ fullPage: true,
264
+ });
265
+ console.log(`[${browserName}] PASSED`);
266
+ } finally {
267
+ await browser.close();
268
+ }
269
+ });
270
+ }
271
+ ```
272
+
273
+ #### Multi-device responsive testing
274
+
275
+ **ALWAYS test on multiple screen sizes.** This runs the same test across mobile phones, tablets, and desktop screens:
276
+
277
+ ```typescript
278
+ // Devices to test — covers the critical breakpoints
279
+ const TEST_DEVICES: DeviceName[] = [
280
+ 'iphone-se', // 375px — smallest supported mobile
281
+ 'iphone-14', // 390px — common iPhone
282
+ 'pixel-7', // 412px — common Android
283
+ 'ipad', // 768px — tablet breakpoint
284
+ 'ipad-pro', // 1024px — large tablet / small laptop
285
+ 'laptop', // 1366px — common laptop
286
+ 'desktop', // 1920px — full HD desktop
287
+ ];
288
+
289
+ for (const deviceName of TEST_DEVICES) {
290
+ test(`<Feature> renders correctly on ${DEVICES[deviceName].label}`, async () => {
291
+ const { browser, page, deviceLabel, viewport } = await createAuthenticatedPage({
292
+ device: deviceName,
293
+ });
294
+
295
+ try {
296
+ await page.goto('http://localhost:3000/<route>', {
297
+ waitUntil: 'networkidle', timeout: 30000,
298
+ });
299
+
300
+ // Verify page loads
301
+ await expect(page.locator('main')).toBeVisible({ timeout: 15000 });
302
+
303
+ // Check for horizontal overflow (common mobile bug)
304
+ const bodyWidth = await page.evaluate(() => document.body.scrollWidth);
305
+ const windowWidth = await page.evaluate(() => window.innerWidth);
306
+ const hasOverflow = bodyWidth > windowWidth + 1;
307
+ console.log(`[${deviceLabel}] ${viewport.width}x${viewport.height} | Overflow: ${hasOverflow ? 'YES (BUG)' : 'none'}`);
308
+ expect(hasOverflow, `Horizontal overflow detected on ${deviceLabel}`).toBe(false);
309
+
310
+ // Check touch targets on mobile (buttons should be at least 44px)
311
+ if (DEVICES[deviceName].isMobile) {
312
+ const buttons = page.locator('button:visible');
313
+ const buttonCount = await buttons.count();
314
+ for (let i = 0; i < Math.min(buttonCount, 10); i++) {
315
+ const box = await buttons.nth(i).boundingBox();
316
+ if (box && box.height < 44) {
317
+ const text = await buttons.nth(i).textContent();
318
+ console.log(` WARNING: Button "${text?.trim()}" is ${box.height}px tall (min 44px)`);
319
+ }
320
+ }
321
+ }
322
+
323
+ // Screenshot for visual comparison
324
+ await page.screenshot({
325
+ path: `e2e/screenshots/<feature>-${deviceName}.png`,
326
+ fullPage: true,
327
+ });
328
+ console.log(`[${deviceLabel}] PASSED — screenshot saved`);
329
+
330
+ } finally {
331
+ await browser.close();
332
+ }
333
+ });
334
+ }
335
+ ```
336
+
337
+ #### Cross-browser + cross-device matrix (full coverage)
338
+
339
+ For critical features, test every browser on every device size:
340
+
341
+ ```typescript
342
+ // Full matrix: 3 browsers x 3 key screen sizes
343
+ const BROWSER_LIST: BrowserName[] = ['chrome', 'firefox', 'safari'];
344
+ const KEY_DEVICES: DeviceName[] = ['iphone-se', 'ipad', 'desktop'];
345
+
346
+ for (const browserName of BROWSER_LIST) {
347
+ for (const deviceName of KEY_DEVICES) {
348
+ test(`<Feature> on ${browserName} @ ${DEVICES[deviceName].label}`, async () => {
349
+ const { browser, page } = await createAuthenticatedPage({
350
+ browser: browserName,
351
+ device: deviceName,
352
+ });
353
+
354
+ try {
355
+ await page.goto('http://localhost:3000/<route>', {
356
+ waitUntil: 'networkidle', timeout: 30000,
357
+ });
358
+ await expect(page.locator('main')).toBeVisible({ timeout: 15000 });
359
+
360
+ // ... assertions ...
361
+
362
+ await page.screenshot({
363
+ path: `e2e/screenshots/<feature>-${browserName}-${deviceName}.png`,
364
+ fullPage: true,
365
+ });
366
+ console.log(`[${browserName} | ${DEVICES[deviceName].label}] PASSED`);
367
+ } finally {
368
+ await browser.close();
369
+ }
370
+ });
371
+ }
372
+ }
373
+ ```
374
+
375
+ #### Screenshot capture
376
+ ```typescript
377
+ // Take a screenshot for visual review
378
+ await page.screenshot({ path: `e2e/screenshots/<feature>-<state>.png`, fullPage: true });
379
+ console.log('Screenshot saved: e2e/screenshots/<feature>-<state>.png');
380
+ ```
381
+
382
+ ### 5. Run the test
383
+
384
+ Make sure the dev server is running first, then run the manual test using the project's E2E test runner:
385
+
386
+ ```bash
387
+ # Ensure dev server is running (in a separate terminal or background)
388
+ # Use the project's dev server command (examples: npm run dev, npm start, yarn dev, pnpm dev)
389
+
390
+ # Run the specific manual test in headed mode
391
+ # Adjust command based on your E2E framework (Playwright, Cypress, etc.)
392
+ # Example with Playwright:
393
+ npx playwright test e2e/manual/<feature>.manual.spec.ts --headed --reporter=list
394
+
395
+ # Run all manual tests
396
+ npx playwright test e2e/manual/ --headed --reporter=list
397
+
398
+ # Run with longer timeout for cross-browser matrix tests
399
+ npx playwright test e2e/manual/<feature>.manual.spec.ts --headed --reporter=list --timeout=120000
400
+ ```
401
+
402
+ **Important flags (Playwright example - adapt to your E2E framework):**
403
+ - `--headed` — opens a visible browser window so you can see the test running
404
+ - `--reporter=list` — shows step-by-step output in terminal
405
+ - `--timeout=120000` — increase timeout for multi-browser tests (2 min per test)
406
+ - `--debug` — opens test inspector for step-by-step debugging (optional)
407
+ - `--workers=1` — run tests sequentially (easier to watch headed browser)
408
+
409
+ **Note:** If using Playwright, Firefox and Safari (WebKit) require browser binaries. If not installed:
410
+ ```bash
411
+ npx playwright install firefox webkit
412
+ ```
413
+
414
+ ### 6. Report results
415
+
416
+ After running, output a report with browser and device coverage:
417
+
418
+ **If all tests pass:**
419
+ ```
420
+ Manual Test Results: <Feature Name>
421
+ Route: /<route>
422
+ Status: PASSED
423
+
424
+ Browser Coverage:
425
+ [PASS] Chrome (Desktop 1920x1080)
426
+ [PASS] Firefox (Desktop 1920x1080)
427
+ [PASS] Safari/WebKit (Desktop 1920x1080)
428
+
429
+ Device Coverage:
430
+ [PASS] iPhone SE (375x667) — no overflow, touch targets OK
431
+ [PASS] iPhone 14 (390x844) — no overflow, touch targets OK
432
+ [PASS] Pixel 7 (412x915) — no overflow, touch targets OK
433
+ [PASS] iPad (768x1024) — no overflow
434
+ [PASS] Laptop (1366x768) — no overflow
435
+ [PASS] Desktop (1920x1080) — no overflow
436
+
437
+ Feature Tests:
438
+ [PASS] Page loads with expected content
439
+ [PASS] <Interaction> works correctly
440
+ [PASS] <Filter/navigation> behaves as expected
441
+
442
+ Screenshots: e2e/screenshots/<feature>-*.png (one per browser/device)
443
+ ```
444
+
445
+ **If any test fails:**
446
+ ```
447
+ Manual Test Results: <Feature Name>
448
+ Route: /<route>
449
+ Status: FAILED
450
+
451
+ Failures:
452
+ [FAIL] Firefox @ iPad (768x1024)
453
+ Issue: Horizontal overflow detected (body 820px > viewport 768px)
454
+ Screenshot: e2e/screenshots/<feature>-firefox-ipad.png
455
+
456
+ [FAIL] Chrome @ iPhone SE (375x667)
457
+ Issue: Button "Apply Filters" is 32px tall (minimum 44px for touch)
458
+ Screenshot: e2e/screenshots/<feature>-chrome-iphone-se.png
459
+
460
+ Suggested fixes:
461
+ 1. Add overflow wrapper on the filter bar container
462
+ 2. Increase button minimum height to 44px for touch targets
463
+ ```
464
+
465
+ ## Selector Priority
466
+
467
+ Always prefer accessible selectors:
468
+
469
+ | Priority | Selector | Example |
470
+ |----------|----------|---------|
471
+ | 1 | `getByRole` | `page.getByRole('button', { name: 'Apply' })` |
472
+ | 2 | `getByText` | `page.getByText('Total Revenue')` |
473
+ | 3 | `getByLabel` | `page.getByLabel('Search stores')` |
474
+ | 4 | `getByPlaceholder` | `page.getByPlaceholder('Filter by name')` |
475
+ | 5 | `data-testid` | `page.locator('[data-testid="metric-card"]')` |
476
+ | 6 | CSS selector | `page.locator('main')` (last resort) |
477
+
478
+ ## Supported Browsers
479
+
480
+ | Key | Browser | Engine | Notes |
481
+ |-----|---------|--------|-------|
482
+ | `chrome` | Google Chrome | Chromium | Default. Most users. |
483
+ | `firefox` | Mozilla Firefox | Gecko | Second most popular. Tests CSS differences. |
484
+ | `safari` | Apple Safari | WebKit | Tests macOS/iOS rendering. |
485
+
486
+ Install missing browsers (Playwright): `npx playwright install firefox webkit`
487
+
488
+ ## Supported Devices
489
+
490
+ | Key | Device | Size | Type |
491
+ |-----|--------|------|------|
492
+ | `iphone-se` | iPhone SE | 375x667 | Mobile (smallest supported) |
493
+ | `iphone-14` | iPhone 14 | 390x844 | Mobile |
494
+ | `iphone-14-pro-max` | iPhone 14 Pro Max | 430x932 | Mobile (largest iPhone) |
495
+ | `pixel-7` | Pixel 7 | 412x915 | Mobile (Android) |
496
+ | `samsung-s23` | Samsung Galaxy S23 | 360x780 | Mobile (Android) |
497
+ | `ipad` | iPad | 768x1024 | Tablet |
498
+ | `ipad-pro` | iPad Pro 12.9" | 1024x1366 | Tablet (large) |
499
+ | `android-tablet` | Android Tablet | 800x1280 | Tablet (Android) |
500
+ | `laptop` | Laptop | 1366x768 | Desktop (common) |
501
+ | `desktop` | Desktop 1080p | 1920x1080 | Desktop (default) |
502
+ | `desktop-xl` | Desktop 1440p | 2560x1440 | Desktop (large) |
503
+
504
+ **Minimum test coverage:** Every feature MUST be tested on at least `iphone-se` (375px), `ipad` (768px), and `desktop` (1920px).
505
+
506
+ ## Tips
507
+
508
+ - Use `await page.waitForTimeout(500)` after clicks to let dropdowns/animations settle
509
+ - Use `await page.waitForSelector('<selector>')` instead of arbitrary timeouts when possible
510
+ - Use `console.log()` generously — the output shows in the terminal during test runs
511
+ - Use `page.pause()` to freeze the test and inspect the page manually in the browser
512
+ - Take screenshots at key steps for visual evidence
513
+ - Always close the browser in a `finally` block to prevent orphaned processes
514
+ - Run with `--workers=1` when using `--headed` to watch one browser at a time
515
+ - For cross-browser matrix tests, increase timeout appropriately
516
+ - Mobile tests automatically set `isMobile: true` and `hasTouch: true` for realistic simulation