@su-record/vibe 2.6.28 → 2.6.31

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 (243) hide show
  1. package/CLAUDE.md +235 -202
  2. package/LICENSE +21 -21
  3. package/README.md +276 -267
  4. package/agents/architect-low.md +41 -41
  5. package/agents/architect-medium.md +59 -59
  6. package/agents/architect.md +80 -80
  7. package/agents/build-error-resolver.md +115 -115
  8. package/agents/compounder.md +261 -261
  9. package/agents/diagrammer.md +178 -178
  10. package/agents/docs/api-documenter.md +99 -99
  11. package/agents/docs/changelog-writer.md +93 -93
  12. package/agents/e2e-tester.md +266 -266
  13. package/agents/explorer-low.md +42 -42
  14. package/agents/explorer-medium.md +59 -59
  15. package/agents/explorer.md +48 -48
  16. package/agents/implementer-low.md +43 -43
  17. package/agents/implementer-medium.md +52 -52
  18. package/agents/implementer.md +54 -54
  19. package/agents/planning/requirements-analyst.md +84 -84
  20. package/agents/planning/ux-advisor.md +83 -83
  21. package/agents/qa/acceptance-tester.md +86 -86
  22. package/agents/qa/edge-case-finder.md +93 -93
  23. package/agents/refactor-cleaner.md +143 -143
  24. package/agents/research/best-practices-agent.md +199 -199
  25. package/agents/research/codebase-patterns-agent.md +157 -157
  26. package/agents/research/framework-docs-agent.md +188 -188
  27. package/agents/research/security-advisory-agent.md +213 -213
  28. package/agents/review/architecture-reviewer.md +107 -107
  29. package/agents/review/complexity-reviewer.md +116 -116
  30. package/agents/review/data-integrity-reviewer.md +88 -88
  31. package/agents/review/git-history-reviewer.md +103 -103
  32. package/agents/review/performance-reviewer.md +86 -86
  33. package/agents/review/python-reviewer.md +150 -150
  34. package/agents/review/rails-reviewer.md +139 -139
  35. package/agents/review/react-reviewer.md +144 -144
  36. package/agents/review/security-reviewer.md +80 -80
  37. package/agents/review/simplicity-reviewer.md +140 -140
  38. package/agents/review/test-coverage-reviewer.md +116 -116
  39. package/agents/review/typescript-reviewer.md +127 -127
  40. package/agents/searcher.md +54 -54
  41. package/agents/simplifier.md +120 -120
  42. package/agents/tester.md +49 -49
  43. package/agents/ui-previewer.md +268 -268
  44. package/commands/vibe.analyze.md +356 -356
  45. package/commands/vibe.reason.md +329 -329
  46. package/commands/vibe.review.md +423 -423
  47. package/commands/vibe.run.md +1423 -1313
  48. package/commands/vibe.spec.md +1054 -1054
  49. package/commands/vibe.spec.review.md +412 -412
  50. package/commands/vibe.trace.md +161 -161
  51. package/commands/vibe.utils.md +376 -376
  52. package/commands/vibe.verify.md +375 -375
  53. package/dist/cli/collaborator.js +52 -52
  54. package/dist/cli/detect.js +32 -32
  55. package/dist/cli/hud.js +20 -20
  56. package/dist/cli/index.js +112 -112
  57. package/dist/cli/llm.js +144 -144
  58. package/dist/cli/postinstall.js +858 -858
  59. package/dist/lib/DeepInit.js +24 -24
  60. package/dist/lib/IterationTracker.js +11 -11
  61. package/dist/lib/PythonParser.js +108 -108
  62. package/dist/lib/ReviewRace.js +96 -96
  63. package/dist/lib/SkillFrontmatter.js +28 -28
  64. package/dist/lib/SkillQualityGate.js +9 -9
  65. package/dist/lib/SkillRepository.js +159 -159
  66. package/dist/lib/UltraQA.js +77 -77
  67. package/dist/lib/gemini-api.d.ts +13 -0
  68. package/dist/lib/gemini-api.d.ts.map +1 -1
  69. package/dist/lib/gemini-api.js +63 -5
  70. package/dist/lib/gemini-api.js.map +1 -1
  71. package/dist/lib/gpt-api.js +4 -4
  72. package/dist/lib/memory/KnowledgeGraph.js +4 -4
  73. package/dist/lib/memory/MemorySearch.js +43 -43
  74. package/dist/lib/memory/MemoryStorage.js +130 -130
  75. package/dist/lib/memory/ObservationStore.js +28 -28
  76. package/dist/lib/memory/SessionRAGRetriever.js +7 -7
  77. package/dist/lib/memory/SessionRAGStore.js +216 -216
  78. package/dist/lib/memory/SessionSummarizer.js +9 -9
  79. package/dist/orchestrator/AgentManager.js +12 -12
  80. package/dist/orchestrator/MultiLlmResearch.js +8 -8
  81. package/dist/orchestrator/SmartRouter.js +11 -11
  82. package/dist/orchestrator/SwarmOrchestrator.test.js +16 -16
  83. package/dist/orchestrator/parallelResearch.js +24 -24
  84. package/dist/tools/convention/analyzeComplexity.test.js +115 -115
  85. package/dist/tools/convention/validateCodeQuality.test.js +104 -104
  86. package/dist/tools/spec/prdParser.test.js +171 -171
  87. package/dist/tools/spec/specGenerator.js +169 -169
  88. package/dist/tools/spec/traceabilityMatrix.js +64 -64
  89. package/dist/tools/spec/traceabilityMatrix.test.js +28 -28
  90. package/hooks/hooks.json +115 -115
  91. package/hooks/scripts/code-check.js +70 -70
  92. package/hooks/scripts/code-review.js +22 -22
  93. package/hooks/scripts/complexity.js +22 -22
  94. package/hooks/scripts/compound.js +23 -23
  95. package/hooks/scripts/context-save.js +53 -53
  96. package/hooks/scripts/gemini-ui-gen.js +281 -281
  97. package/hooks/scripts/generate-brand-assets.js +474 -474
  98. package/hooks/scripts/hud-multiline.js +262 -262
  99. package/hooks/scripts/hud-status.js +291 -291
  100. package/hooks/scripts/keyword-detector.js +214 -214
  101. package/hooks/scripts/llm-orchestrate.js +245 -171
  102. package/hooks/scripts/post-edit.js +97 -97
  103. package/hooks/scripts/post-tool-verify.js +210 -210
  104. package/hooks/scripts/pre-tool-guard.js +125 -125
  105. package/hooks/scripts/prompt-dispatcher.js +161 -161
  106. package/hooks/scripts/recall.js +22 -22
  107. package/hooks/scripts/session-start.js +30 -30
  108. package/hooks/scripts/skill-injector.js +191 -191
  109. package/hooks/scripts/utils.js +97 -97
  110. package/languages/csharp-unity.md +515 -515
  111. package/languages/gdscript-godot.md +470 -470
  112. package/languages/ruby-rails.md +489 -489
  113. package/languages/typescript-angular.md +433 -433
  114. package/languages/typescript-astro.md +416 -416
  115. package/languages/typescript-electron.md +406 -406
  116. package/languages/typescript-nestjs.md +524 -524
  117. package/languages/typescript-svelte.md +407 -407
  118. package/languages/typescript-tauri.md +365 -365
  119. package/package.json +84 -84
  120. package/skills/brand-assets.md +141 -141
  121. package/skills/commerce-patterns.md +361 -361
  122. package/skills/context7-usage.md +102 -102
  123. package/skills/e2e-commerce.md +304 -304
  124. package/skills/frontend-design.md +92 -92
  125. package/skills/git-worktree.md +181 -181
  126. package/skills/parallel-research.md +77 -77
  127. package/skills/priority-todos.md +239 -239
  128. package/skills/seo-checklist.md +244 -244
  129. package/skills/tool-fallback.md +190 -190
  130. package/skills/vibe-capabilities.md +161 -161
  131. package/vibe/constitution.md +227 -227
  132. package/vibe/rules/core/communication-guide.md +98 -98
  133. package/vibe/rules/core/development-philosophy.md +52 -52
  134. package/vibe/rules/core/quick-start.md +102 -102
  135. package/vibe/rules/quality/bdd-contract-testing.md +393 -393
  136. package/vibe/rules/quality/checklist.md +276 -276
  137. package/vibe/rules/quality/testing-strategy.md +440 -440
  138. package/vibe/rules/standards/anti-patterns.md +541 -541
  139. package/vibe/rules/standards/code-structure.md +291 -291
  140. package/vibe/rules/standards/complexity-metrics.md +313 -313
  141. package/vibe/rules/standards/naming-conventions.md +198 -198
  142. package/vibe/setup.sh +31 -31
  143. package/vibe/templates/constitution-template.md +252 -252
  144. package/vibe/templates/contract-backend-template.md +526 -526
  145. package/vibe/templates/contract-frontend-template.md +599 -599
  146. package/vibe/templates/feature-template.md +96 -96
  147. package/vibe/templates/spec-template.md +221 -221
  148. package/dist/cli/mcp.d.ts +0 -49
  149. package/dist/cli/mcp.d.ts.map +0 -1
  150. package/dist/cli/mcp.js +0 -169
  151. package/dist/cli/mcp.js.map +0 -1
  152. package/dist/lib/gemini-mcp.d.ts +0 -10
  153. package/dist/lib/gemini-mcp.d.ts.map +0 -1
  154. package/dist/lib/gemini-mcp.js +0 -353
  155. package/dist/lib/gemini-mcp.js.map +0 -1
  156. package/dist/lib/gpt-mcp.d.ts +0 -10
  157. package/dist/lib/gpt-mcp.d.ts.map +0 -1
  158. package/dist/lib/gpt-mcp.js +0 -352
  159. package/dist/lib/gpt-mcp.js.map +0 -1
  160. package/dist/tools/analytics/getUsageAnalytics.d.ts +0 -10
  161. package/dist/tools/analytics/getUsageAnalytics.d.ts.map +0 -1
  162. package/dist/tools/analytics/getUsageAnalytics.js +0 -246
  163. package/dist/tools/analytics/getUsageAnalytics.js.map +0 -1
  164. package/dist/tools/analytics/index.d.ts +0 -5
  165. package/dist/tools/analytics/index.d.ts.map +0 -1
  166. package/dist/tools/analytics/index.js +0 -5
  167. package/dist/tools/analytics/index.js.map +0 -1
  168. package/dist/tools/convention/getCodingGuide.d.ts +0 -7
  169. package/dist/tools/convention/getCodingGuide.d.ts.map +0 -1
  170. package/dist/tools/convention/getCodingGuide.js +0 -69
  171. package/dist/tools/convention/getCodingGuide.js.map +0 -1
  172. package/dist/tools/planning/analyzeRequirements.d.ts +0 -9
  173. package/dist/tools/planning/analyzeRequirements.d.ts.map +0 -1
  174. package/dist/tools/planning/analyzeRequirements.js +0 -171
  175. package/dist/tools/planning/analyzeRequirements.js.map +0 -1
  176. package/dist/tools/planning/createUserStories.d.ts +0 -9
  177. package/dist/tools/planning/createUserStories.d.ts.map +0 -1
  178. package/dist/tools/planning/createUserStories.js +0 -124
  179. package/dist/tools/planning/createUserStories.js.map +0 -1
  180. package/dist/tools/planning/featureRoadmap.d.ts +0 -10
  181. package/dist/tools/planning/featureRoadmap.d.ts.map +0 -1
  182. package/dist/tools/planning/featureRoadmap.js +0 -207
  183. package/dist/tools/planning/featureRoadmap.js.map +0 -1
  184. package/dist/tools/planning/generatePrd.d.ts +0 -11
  185. package/dist/tools/planning/generatePrd.d.ts.map +0 -1
  186. package/dist/tools/planning/generatePrd.js +0 -161
  187. package/dist/tools/planning/generatePrd.js.map +0 -1
  188. package/dist/tools/planning/index.d.ts +0 -8
  189. package/dist/tools/planning/index.d.ts.map +0 -1
  190. package/dist/tools/planning/index.js +0 -8
  191. package/dist/tools/planning/index.js.map +0 -1
  192. package/dist/tools/prompt/analyzePrompt.d.ts +0 -7
  193. package/dist/tools/prompt/analyzePrompt.d.ts.map +0 -1
  194. package/dist/tools/prompt/analyzePrompt.js +0 -150
  195. package/dist/tools/prompt/analyzePrompt.js.map +0 -1
  196. package/dist/tools/prompt/enhancePrompt.d.ts +0 -8
  197. package/dist/tools/prompt/enhancePrompt.d.ts.map +0 -1
  198. package/dist/tools/prompt/enhancePrompt.js +0 -110
  199. package/dist/tools/prompt/enhancePrompt.js.map +0 -1
  200. package/dist/tools/prompt/enhancePromptGemini.d.ts +0 -8
  201. package/dist/tools/prompt/enhancePromptGemini.d.ts.map +0 -1
  202. package/dist/tools/prompt/enhancePromptGemini.js +0 -332
  203. package/dist/tools/prompt/enhancePromptGemini.js.map +0 -1
  204. package/dist/tools/prompt/index.d.ts +0 -7
  205. package/dist/tools/prompt/index.d.ts.map +0 -1
  206. package/dist/tools/prompt/index.js +0 -7
  207. package/dist/tools/prompt/index.js.map +0 -1
  208. package/dist/tools/reasoning/applyReasoningFramework.d.ts +0 -8
  209. package/dist/tools/reasoning/applyReasoningFramework.d.ts.map +0 -1
  210. package/dist/tools/reasoning/applyReasoningFramework.js +0 -266
  211. package/dist/tools/reasoning/applyReasoningFramework.js.map +0 -1
  212. package/dist/tools/reasoning/index.d.ts +0 -5
  213. package/dist/tools/reasoning/index.d.ts.map +0 -1
  214. package/dist/tools/reasoning/index.js +0 -5
  215. package/dist/tools/reasoning/index.js.map +0 -1
  216. package/dist/tools/thinking/analyzeProblem.d.ts +0 -7
  217. package/dist/tools/thinking/analyzeProblem.d.ts.map +0 -1
  218. package/dist/tools/thinking/analyzeProblem.js +0 -55
  219. package/dist/tools/thinking/analyzeProblem.js.map +0 -1
  220. package/dist/tools/thinking/breakDownProblem.d.ts +0 -8
  221. package/dist/tools/thinking/breakDownProblem.d.ts.map +0 -1
  222. package/dist/tools/thinking/breakDownProblem.js +0 -145
  223. package/dist/tools/thinking/breakDownProblem.js.map +0 -1
  224. package/dist/tools/thinking/createThinkingChain.d.ts +0 -7
  225. package/dist/tools/thinking/createThinkingChain.d.ts.map +0 -1
  226. package/dist/tools/thinking/createThinkingChain.js +0 -44
  227. package/dist/tools/thinking/createThinkingChain.js.map +0 -1
  228. package/dist/tools/thinking/formatAsPlan.d.ts +0 -9
  229. package/dist/tools/thinking/formatAsPlan.d.ts.map +0 -1
  230. package/dist/tools/thinking/formatAsPlan.js +0 -78
  231. package/dist/tools/thinking/formatAsPlan.js.map +0 -1
  232. package/dist/tools/thinking/index.d.ts +0 -10
  233. package/dist/tools/thinking/index.d.ts.map +0 -1
  234. package/dist/tools/thinking/index.js +0 -10
  235. package/dist/tools/thinking/index.js.map +0 -1
  236. package/dist/tools/thinking/stepByStepAnalysis.d.ts +0 -8
  237. package/dist/tools/thinking/stepByStepAnalysis.d.ts.map +0 -1
  238. package/dist/tools/thinking/stepByStepAnalysis.js +0 -63
  239. package/dist/tools/thinking/stepByStepAnalysis.js.map +0 -1
  240. package/dist/tools/thinking/thinkAloudProcess.d.ts +0 -8
  241. package/dist/tools/thinking/thinkAloudProcess.d.ts.map +0 -1
  242. package/dist/tools/thinking/thinkAloudProcess.js +0 -80
  243. package/dist/tools/thinking/thinkAloudProcess.js.map +0 -1
@@ -1,304 +1,304 @@
1
- ---
2
- name: e2e-commerce
3
- description: "E2E test scenarios for commerce checkout and payment flows"
4
- triggers: [e2e commerce, checkout test, payment test, order flow test]
5
- priority: 65
6
- ---
7
- # E2E Commerce Test Scenarios
8
-
9
- Playwright-based E2E testing for commerce checkout flows.
10
-
11
- ## When to Use
12
-
13
- - After implementing checkout/payment features
14
- - Before production deployment
15
- - CI/CD pipeline quality gate
16
- - Regression testing after changes
17
-
18
- ## Test Scenarios
19
-
20
- ### 1. Happy Path - Complete Checkout
21
-
22
- ```typescript
23
- // tests/e2e/checkout.spec.ts
24
- import { test, expect } from '@playwright/test';
25
-
26
- test.describe('Checkout Flow', () => {
27
- test('complete purchase - happy path', async ({ page }) => {
28
- // 1. Add to cart
29
- await page.goto('/products/test-product');
30
- await page.click('[data-testid="add-to-cart"]');
31
- await expect(page.locator('[data-testid="cart-count"]')).toHaveText('1');
32
-
33
- // 2. Go to cart
34
- await page.click('[data-testid="cart-icon"]');
35
- await expect(page).toHaveURL('/cart');
36
-
37
- // 3. Proceed to checkout
38
- await page.click('[data-testid="checkout-button"]');
39
- await expect(page).toHaveURL('/checkout');
40
-
41
- // 4. Fill shipping info
42
- await page.fill('[name="name"]', 'Test User');
43
- await page.fill('[name="phone"]', '010-1234-5678');
44
- await page.fill('[name="address"]', 'Test Address 123');
45
-
46
- // 5. Select payment method
47
- await page.click('[data-testid="payment-card"]');
48
-
49
- // 6. Complete payment (sandbox/mock)
50
- await page.click('[data-testid="pay-button"]');
51
-
52
- // 7. Verify order complete
53
- await expect(page).toHaveURL(/\/orders\/\w+/);
54
- await expect(page.locator('[data-testid="order-status"]')).toHaveText('결제 완료');
55
- });
56
- });
57
- ```
58
-
59
- ### 2. Stock Validation
60
-
61
- ```typescript
62
- test('prevent checkout when out of stock', async ({ page }) => {
63
- // Setup: Product with stock = 1, another user reserves it
64
- await page.goto('/products/low-stock-product');
65
- await page.click('[data-testid="add-to-cart"]');
66
- await page.goto('/checkout');
67
-
68
- // Simulate stock depletion during checkout
69
- await page.evaluate(async () => {
70
- await fetch('/api/test/deplete-stock', { method: 'POST' });
71
- });
72
-
73
- // Attempt payment
74
- await page.click('[data-testid="pay-button"]');
75
-
76
- // Should show out of stock error
77
- await expect(page.locator('[data-testid="error-message"]'))
78
- .toContainText('재고가 부족합니다');
79
- });
80
- ```
81
-
82
- ### 3. Payment Failure Handling
83
-
84
- ```typescript
85
- test('handle payment failure gracefully', async ({ page }) => {
86
- await page.goto('/products/test-product');
87
- await page.click('[data-testid="add-to-cart"]');
88
- await page.goto('/checkout');
89
-
90
- // Fill form
91
- await page.fill('[name="name"]', 'Test User');
92
- await page.fill('[name="address"]', 'Test Address');
93
-
94
- // Use test card that triggers failure
95
- await page.fill('[name="card-number"]', '4000000000000002'); // Decline card
96
- await page.click('[data-testid="pay-button"]');
97
-
98
- // Verify error handling
99
- await expect(page.locator('[data-testid="payment-error"]'))
100
- .toContainText('결제가 거절되었습니다');
101
-
102
- // Stock should be released
103
- await page.goto('/products/test-product');
104
- await expect(page.locator('[data-testid="stock-status"]'))
105
- .not.toContainText('품절');
106
- });
107
- ```
108
-
109
- ### 4. Duplicate Payment Prevention
110
-
111
- ```typescript
112
- test('prevent duplicate payment on double click', async ({ page }) => {
113
- await page.goto('/checkout');
114
- // Fill checkout form...
115
-
116
- // Double click pay button rapidly
117
- const payButton = page.locator('[data-testid="pay-button"]');
118
- await Promise.all([
119
- payButton.click(),
120
- payButton.click(),
121
- ]);
122
-
123
- // Wait for completion
124
- await page.waitForURL(/\/orders\/\w+/);
125
-
126
- // Verify only one order created
127
- const orderId = page.url().split('/').pop();
128
- const response = await page.request.get(`/api/orders?userId=test`);
129
- const orders = await response.json();
130
-
131
- expect(orders.filter(o => o.id === orderId)).toHaveLength(1);
132
- });
133
- ```
134
-
135
- ### 5. Coupon Application
136
-
137
- ```typescript
138
- test('apply coupon and verify discount', async ({ page }) => {
139
- await page.goto('/products/test-product'); // Price: 10,000
140
- await page.click('[data-testid="add-to-cart"]');
141
- await page.goto('/checkout');
142
-
143
- // Original price
144
- await expect(page.locator('[data-testid="total-price"]'))
145
- .toHaveText('10,000원');
146
-
147
- // Apply 10% coupon
148
- await page.fill('[name="coupon"]', 'DISCOUNT10');
149
- await page.click('[data-testid="apply-coupon"]');
150
-
151
- // Verify discount applied
152
- await expect(page.locator('[data-testid="discount-amount"]'))
153
- .toHaveText('-1,000원');
154
- await expect(page.locator('[data-testid="total-price"]'))
155
- .toHaveText('9,000원');
156
- });
157
- ```
158
-
159
- ### 6. Webhook Resilience
160
-
161
- ```typescript
162
- test('order completes even with webhook delay', async ({ page, request }) => {
163
- // Configure webhook delay in test environment
164
- await request.post('/api/test/configure-webhook', {
165
- data: { delay: 5000 } // 5 second delay
166
- });
167
-
168
- // Complete checkout
169
- await page.goto('/checkout');
170
- // ... fill form
171
- await page.click('[data-testid="pay-button"]');
172
-
173
- // Should show processing state
174
- await expect(page.locator('[data-testid="order-status"]'))
175
- .toHaveText('처리 중');
176
-
177
- // Wait for webhook
178
- await page.waitForSelector('[data-testid="order-status"]:has-text("결제 완료")', {
179
- timeout: 10000
180
- });
181
- });
182
- ```
183
-
184
- ## CLI Usage
185
-
186
- ```bash
187
- # Run all commerce e2e tests
188
- /vibe.utils --e2e commerce
189
-
190
- # Run specific scenario
191
- /vibe.utils --e2e checkout-flow
192
-
193
- # Run with visual recording
194
- /vibe.utils --e2e commerce --record
195
-
196
- # Run against staging
197
- /vibe.utils --e2e commerce --env staging
198
- ```
199
-
200
- ## Test Environment Setup
201
-
202
- ### Mock PG Server
203
- ```typescript
204
- // tests/mocks/pg-server.ts
205
- import { setupServer } from 'msw/node';
206
- import { http, HttpResponse } from 'msw';
207
-
208
- export const pgMockServer = setupServer(
209
- // Success response
210
- http.post('/payments/authorize', () => {
211
- return HttpResponse.json({
212
- success: true,
213
- transactionId: `txn_${Date.now()}`,
214
- status: 'AUTHORIZED',
215
- });
216
- }),
217
-
218
- // Failure simulation
219
- http.post('/payments/authorize', ({ request }) => {
220
- const body = request.json();
221
- if (body.cardNumber === '4000000000000002') {
222
- return HttpResponse.json({
223
- success: false,
224
- error: 'CARD_DECLINED',
225
- }, { status: 400 });
226
- }
227
- }),
228
- );
229
- ```
230
-
231
- ### Database Seeding
232
- ```typescript
233
- // tests/fixtures/commerce.ts
234
- export async function seedCommerceData(db: Database) {
235
- // Create test products
236
- await db.products.createMany([
237
- { id: 'test-product', name: 'Test Product', price: 10000, stock: 100 },
238
- { id: 'low-stock', name: 'Low Stock', price: 5000, stock: 1 },
239
- ]);
240
-
241
- // Create test coupons
242
- await db.coupons.create({
243
- code: 'DISCOUNT10',
244
- discountPercent: 10,
245
- expiresAt: addDays(new Date(), 30),
246
- });
247
- }
248
- ```
249
-
250
- ## CI/CD Integration
251
-
252
- ```yaml
253
- # .github/workflows/e2e.yml
254
- name: E2E Commerce Tests
255
-
256
- on:
257
- pull_request:
258
- paths:
259
- - 'src/checkout/**'
260
- - 'src/payment/**'
261
- - 'src/cart/**'
262
-
263
- jobs:
264
- e2e:
265
- runs-on: ubuntu-latest
266
- steps:
267
- - uses: actions/checkout@v4
268
-
269
- - name: Install dependencies
270
- run: npm ci
271
-
272
- - name: Start test server
273
- run: npm run start:test &
274
-
275
- - name: Run E2E tests
276
- run: npx playwright test tests/e2e/commerce/
277
-
278
- - name: Upload test results
279
- if: failure()
280
- uses: actions/upload-artifact@v4
281
- with:
282
- name: playwright-report
283
- path: playwright-report/
284
- ```
285
-
286
- ## Quality Checklist
287
-
288
- ### Must Pass (P0)
289
- - [ ] Happy path checkout completes
290
- - [ ] Payment failure releases stock
291
- - [ ] Duplicate payment prevented
292
- - [ ] Out of stock blocks checkout
293
-
294
- ### Should Pass (P1)
295
- - [ ] Coupon calculation correct
296
- - [ ] Webhook retry handled
297
- - [ ] Cart merge on login works
298
- - [ ] Partial refund processed
299
-
300
- ### Nice to Have (P2)
301
- - [ ] Multiple payment methods
302
- - [ ] Guest checkout flow
303
- - [ ] Order cancellation
304
- - [ ] Subscription renewal
1
+ ---
2
+ name: e2e-commerce
3
+ description: "E2E test scenarios for commerce checkout and payment flows"
4
+ triggers: [e2e commerce, checkout test, payment test, order flow test]
5
+ priority: 65
6
+ ---
7
+ # E2E Commerce Test Scenarios
8
+
9
+ Playwright-based E2E testing for commerce checkout flows.
10
+
11
+ ## When to Use
12
+
13
+ - After implementing checkout/payment features
14
+ - Before production deployment
15
+ - CI/CD pipeline quality gate
16
+ - Regression testing after changes
17
+
18
+ ## Test Scenarios
19
+
20
+ ### 1. Happy Path - Complete Checkout
21
+
22
+ ```typescript
23
+ // tests/e2e/checkout.spec.ts
24
+ import { test, expect } from '@playwright/test';
25
+
26
+ test.describe('Checkout Flow', () => {
27
+ test('complete purchase - happy path', async ({ page }) => {
28
+ // 1. Add to cart
29
+ await page.goto('/products/test-product');
30
+ await page.click('[data-testid="add-to-cart"]');
31
+ await expect(page.locator('[data-testid="cart-count"]')).toHaveText('1');
32
+
33
+ // 2. Go to cart
34
+ await page.click('[data-testid="cart-icon"]');
35
+ await expect(page).toHaveURL('/cart');
36
+
37
+ // 3. Proceed to checkout
38
+ await page.click('[data-testid="checkout-button"]');
39
+ await expect(page).toHaveURL('/checkout');
40
+
41
+ // 4. Fill shipping info
42
+ await page.fill('[name="name"]', 'Test User');
43
+ await page.fill('[name="phone"]', '010-1234-5678');
44
+ await page.fill('[name="address"]', 'Test Address 123');
45
+
46
+ // 5. Select payment method
47
+ await page.click('[data-testid="payment-card"]');
48
+
49
+ // 6. Complete payment (sandbox/mock)
50
+ await page.click('[data-testid="pay-button"]');
51
+
52
+ // 7. Verify order complete
53
+ await expect(page).toHaveURL(/\/orders\/\w+/);
54
+ await expect(page.locator('[data-testid="order-status"]')).toHaveText('결제 완료');
55
+ });
56
+ });
57
+ ```
58
+
59
+ ### 2. Stock Validation
60
+
61
+ ```typescript
62
+ test('prevent checkout when out of stock', async ({ page }) => {
63
+ // Setup: Product with stock = 1, another user reserves it
64
+ await page.goto('/products/low-stock-product');
65
+ await page.click('[data-testid="add-to-cart"]');
66
+ await page.goto('/checkout');
67
+
68
+ // Simulate stock depletion during checkout
69
+ await page.evaluate(async () => {
70
+ await fetch('/api/test/deplete-stock', { method: 'POST' });
71
+ });
72
+
73
+ // Attempt payment
74
+ await page.click('[data-testid="pay-button"]');
75
+
76
+ // Should show out of stock error
77
+ await expect(page.locator('[data-testid="error-message"]'))
78
+ .toContainText('재고가 부족합니다');
79
+ });
80
+ ```
81
+
82
+ ### 3. Payment Failure Handling
83
+
84
+ ```typescript
85
+ test('handle payment failure gracefully', async ({ page }) => {
86
+ await page.goto('/products/test-product');
87
+ await page.click('[data-testid="add-to-cart"]');
88
+ await page.goto('/checkout');
89
+
90
+ // Fill form
91
+ await page.fill('[name="name"]', 'Test User');
92
+ await page.fill('[name="address"]', 'Test Address');
93
+
94
+ // Use test card that triggers failure
95
+ await page.fill('[name="card-number"]', '4000000000000002'); // Decline card
96
+ await page.click('[data-testid="pay-button"]');
97
+
98
+ // Verify error handling
99
+ await expect(page.locator('[data-testid="payment-error"]'))
100
+ .toContainText('결제가 거절되었습니다');
101
+
102
+ // Stock should be released
103
+ await page.goto('/products/test-product');
104
+ await expect(page.locator('[data-testid="stock-status"]'))
105
+ .not.toContainText('품절');
106
+ });
107
+ ```
108
+
109
+ ### 4. Duplicate Payment Prevention
110
+
111
+ ```typescript
112
+ test('prevent duplicate payment on double click', async ({ page }) => {
113
+ await page.goto('/checkout');
114
+ // Fill checkout form...
115
+
116
+ // Double click pay button rapidly
117
+ const payButton = page.locator('[data-testid="pay-button"]');
118
+ await Promise.all([
119
+ payButton.click(),
120
+ payButton.click(),
121
+ ]);
122
+
123
+ // Wait for completion
124
+ await page.waitForURL(/\/orders\/\w+/);
125
+
126
+ // Verify only one order created
127
+ const orderId = page.url().split('/').pop();
128
+ const response = await page.request.get(`/api/orders?userId=test`);
129
+ const orders = await response.json();
130
+
131
+ expect(orders.filter(o => o.id === orderId)).toHaveLength(1);
132
+ });
133
+ ```
134
+
135
+ ### 5. Coupon Application
136
+
137
+ ```typescript
138
+ test('apply coupon and verify discount', async ({ page }) => {
139
+ await page.goto('/products/test-product'); // Price: 10,000
140
+ await page.click('[data-testid="add-to-cart"]');
141
+ await page.goto('/checkout');
142
+
143
+ // Original price
144
+ await expect(page.locator('[data-testid="total-price"]'))
145
+ .toHaveText('10,000원');
146
+
147
+ // Apply 10% coupon
148
+ await page.fill('[name="coupon"]', 'DISCOUNT10');
149
+ await page.click('[data-testid="apply-coupon"]');
150
+
151
+ // Verify discount applied
152
+ await expect(page.locator('[data-testid="discount-amount"]'))
153
+ .toHaveText('-1,000원');
154
+ await expect(page.locator('[data-testid="total-price"]'))
155
+ .toHaveText('9,000원');
156
+ });
157
+ ```
158
+
159
+ ### 6. Webhook Resilience
160
+
161
+ ```typescript
162
+ test('order completes even with webhook delay', async ({ page, request }) => {
163
+ // Configure webhook delay in test environment
164
+ await request.post('/api/test/configure-webhook', {
165
+ data: { delay: 5000 } // 5 second delay
166
+ });
167
+
168
+ // Complete checkout
169
+ await page.goto('/checkout');
170
+ // ... fill form
171
+ await page.click('[data-testid="pay-button"]');
172
+
173
+ // Should show processing state
174
+ await expect(page.locator('[data-testid="order-status"]'))
175
+ .toHaveText('처리 중');
176
+
177
+ // Wait for webhook
178
+ await page.waitForSelector('[data-testid="order-status"]:has-text("결제 완료")', {
179
+ timeout: 10000
180
+ });
181
+ });
182
+ ```
183
+
184
+ ## CLI Usage
185
+
186
+ ```bash
187
+ # Run all commerce e2e tests
188
+ /vibe.utils --e2e commerce
189
+
190
+ # Run specific scenario
191
+ /vibe.utils --e2e checkout-flow
192
+
193
+ # Run with visual recording
194
+ /vibe.utils --e2e commerce --record
195
+
196
+ # Run against staging
197
+ /vibe.utils --e2e commerce --env staging
198
+ ```
199
+
200
+ ## Test Environment Setup
201
+
202
+ ### Mock PG Server
203
+ ```typescript
204
+ // tests/mocks/pg-server.ts
205
+ import { setupServer } from 'msw/node';
206
+ import { http, HttpResponse } from 'msw';
207
+
208
+ export const pgMockServer = setupServer(
209
+ // Success response
210
+ http.post('/payments/authorize', () => {
211
+ return HttpResponse.json({
212
+ success: true,
213
+ transactionId: `txn_${Date.now()}`,
214
+ status: 'AUTHORIZED',
215
+ });
216
+ }),
217
+
218
+ // Failure simulation
219
+ http.post('/payments/authorize', ({ request }) => {
220
+ const body = request.json();
221
+ if (body.cardNumber === '4000000000000002') {
222
+ return HttpResponse.json({
223
+ success: false,
224
+ error: 'CARD_DECLINED',
225
+ }, { status: 400 });
226
+ }
227
+ }),
228
+ );
229
+ ```
230
+
231
+ ### Database Seeding
232
+ ```typescript
233
+ // tests/fixtures/commerce.ts
234
+ export async function seedCommerceData(db: Database) {
235
+ // Create test products
236
+ await db.products.createMany([
237
+ { id: 'test-product', name: 'Test Product', price: 10000, stock: 100 },
238
+ { id: 'low-stock', name: 'Low Stock', price: 5000, stock: 1 },
239
+ ]);
240
+
241
+ // Create test coupons
242
+ await db.coupons.create({
243
+ code: 'DISCOUNT10',
244
+ discountPercent: 10,
245
+ expiresAt: addDays(new Date(), 30),
246
+ });
247
+ }
248
+ ```
249
+
250
+ ## CI/CD Integration
251
+
252
+ ```yaml
253
+ # .github/workflows/e2e.yml
254
+ name: E2E Commerce Tests
255
+
256
+ on:
257
+ pull_request:
258
+ paths:
259
+ - 'src/checkout/**'
260
+ - 'src/payment/**'
261
+ - 'src/cart/**'
262
+
263
+ jobs:
264
+ e2e:
265
+ runs-on: ubuntu-latest
266
+ steps:
267
+ - uses: actions/checkout@v4
268
+
269
+ - name: Install dependencies
270
+ run: npm ci
271
+
272
+ - name: Start test server
273
+ run: npm run start:test &
274
+
275
+ - name: Run E2E tests
276
+ run: npx playwright test tests/e2e/commerce/
277
+
278
+ - name: Upload test results
279
+ if: failure()
280
+ uses: actions/upload-artifact@v4
281
+ with:
282
+ name: playwright-report
283
+ path: playwright-report/
284
+ ```
285
+
286
+ ## Quality Checklist
287
+
288
+ ### Must Pass (P0)
289
+ - [ ] Happy path checkout completes
290
+ - [ ] Payment failure releases stock
291
+ - [ ] Duplicate payment prevented
292
+ - [ ] Out of stock blocks checkout
293
+
294
+ ### Should Pass (P1)
295
+ - [ ] Coupon calculation correct
296
+ - [ ] Webhook retry handled
297
+ - [ ] Cart merge on login works
298
+ - [ ] Partial refund processed
299
+
300
+ ### Nice to Have (P2)
301
+ - [ ] Multiple payment methods
302
+ - [ ] Guest checkout flow
303
+ - [ ] Order cancellation
304
+ - [ ] Subscription renewal