@decocms/start 0.19.0

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 (185) hide show
  1. package/.cursor/skills/deco-api-call-dedup/SKILL.md +443 -0
  2. package/.cursor/skills/deco-apps-architecture/SKILL.md +255 -0
  3. package/.cursor/skills/deco-apps-architecture/app-pattern.md +288 -0
  4. package/.cursor/skills/deco-apps-architecture/commerce-types.md +239 -0
  5. package/.cursor/skills/deco-apps-architecture/new-app-guide.md +268 -0
  6. package/.cursor/skills/deco-apps-architecture/scripts-codegen.md +148 -0
  7. package/.cursor/skills/deco-apps-architecture/shared-utils.md +181 -0
  8. package/.cursor/skills/deco-apps-architecture/vtex-deep-structure.md +253 -0
  9. package/.cursor/skills/deco-apps-architecture/website-app.md +169 -0
  10. package/.cursor/skills/deco-apps-vtex-porting/SKILL.md +189 -0
  11. package/.cursor/skills/deco-apps-vtex-porting/adaptation-patterns.md +335 -0
  12. package/.cursor/skills/deco-apps-vtex-porting/commerce-porting.md +155 -0
  13. package/.cursor/skills/deco-apps-vtex-porting/cookie-auth-patterns.md +148 -0
  14. package/.cursor/skills/deco-apps-vtex-porting/structure-map.md +234 -0
  15. package/.cursor/skills/deco-apps-vtex-porting/transform-mapping.md +99 -0
  16. package/.cursor/skills/deco-apps-vtex-porting/website-porting.md +194 -0
  17. package/.cursor/skills/deco-apps-vtex-review/SKILL.md +234 -0
  18. package/.cursor/skills/deco-async-rendering-architecture/SKILL.md +270 -0
  19. package/.cursor/skills/deco-async-rendering-site-guide/SKILL.md +417 -0
  20. package/.cursor/skills/deco-cms-layout-caching/SKILL.md +293 -0
  21. package/.cursor/skills/deco-cms-route-config/SKILL.md +388 -0
  22. package/.cursor/skills/deco-core-architecture/SKILL.md +185 -0
  23. package/.cursor/skills/deco-core-architecture/blocks.md +196 -0
  24. package/.cursor/skills/deco-core-architecture/deco-vs-deco-start.md +191 -0
  25. package/.cursor/skills/deco-core-architecture/engine.md +220 -0
  26. package/.cursor/skills/deco-core-architecture/hooks-components.md +157 -0
  27. package/.cursor/skills/deco-core-architecture/plugins-clients.md +136 -0
  28. package/.cursor/skills/deco-core-architecture/runtime.md +116 -0
  29. package/.cursor/skills/deco-core-architecture/site-usage.md +165 -0
  30. package/.cursor/skills/deco-e2e-testing/SKILL.md +372 -0
  31. package/.cursor/skills/deco-e2e-testing/discovery.md +337 -0
  32. package/.cursor/skills/deco-e2e-testing/scripts/scaffold.sh +81 -0
  33. package/.cursor/skills/deco-e2e-testing/selectors.md +175 -0
  34. package/.cursor/skills/deco-e2e-testing/templates/package.json +18 -0
  35. package/.cursor/skills/deco-e2e-testing/templates/playwright.config.ts +65 -0
  36. package/.cursor/skills/deco-e2e-testing/templates/scripts/baseline.ts +279 -0
  37. package/.cursor/skills/deco-e2e-testing/templates/scripts/run-e2e.ts +194 -0
  38. package/.cursor/skills/deco-e2e-testing/templates/specs/ecommerce-flow.spec.ts +612 -0
  39. package/.cursor/skills/deco-e2e-testing/templates/tsconfig.json +12 -0
  40. package/.cursor/skills/deco-e2e-testing/templates/utils/metrics-collector.ts +918 -0
  41. package/.cursor/skills/deco-e2e-testing/troubleshooting.md +602 -0
  42. package/.cursor/skills/deco-edge-caching/SKILL.md +316 -0
  43. package/.cursor/skills/deco-full-analysis/SKILL.md +898 -0
  44. package/.cursor/skills/deco-full-analysis/checklists/asset-optimization.md +251 -0
  45. package/.cursor/skills/deco-full-analysis/checklists/bug-fix.md +189 -0
  46. package/.cursor/skills/deco-full-analysis/checklists/cache-strategy.md +144 -0
  47. package/.cursor/skills/deco-full-analysis/checklists/dependency-update.md +150 -0
  48. package/.cursor/skills/deco-full-analysis/checklists/hydration-fix.md +191 -0
  49. package/.cursor/skills/deco-full-analysis/checklists/image-optimization.md +180 -0
  50. package/.cursor/skills/deco-full-analysis/checklists/loader-optimization.md +165 -0
  51. package/.cursor/skills/deco-full-analysis/checklists/seo-fix.md +183 -0
  52. package/.cursor/skills/deco-full-analysis/checklists/site-cleanup.md +281 -0
  53. package/.cursor/skills/deco-full-analysis/discovery.md +548 -0
  54. package/.cursor/skills/deco-incident-debugging/SKILL.md +378 -0
  55. package/.cursor/skills/deco-incident-debugging/headless-mode.md +510 -0
  56. package/.cursor/skills/deco-incident-debugging/learnings-index.md +227 -0
  57. package/.cursor/skills/deco-incident-debugging/triage-workflow.md +312 -0
  58. package/.cursor/skills/deco-islands-migration/SKILL.md +251 -0
  59. package/.cursor/skills/deco-loader-n-plus-1-detector/SKILL.md +275 -0
  60. package/.cursor/skills/deco-performance-audit/SKILL.md +530 -0
  61. package/.cursor/skills/deco-performance-audit/tools-reference.md +428 -0
  62. package/.cursor/skills/deco-performance-audit/workflow.md +457 -0
  63. package/.cursor/skills/deco-server-functions-invoke/SKILL.md +92 -0
  64. package/.cursor/skills/deco-server-functions-invoke/architecture.md +166 -0
  65. package/.cursor/skills/deco-server-functions-invoke/generator.md +122 -0
  66. package/.cursor/skills/deco-server-functions-invoke/problem.md +98 -0
  67. package/.cursor/skills/deco-server-functions-invoke/troubleshooting.md +110 -0
  68. package/.cursor/skills/deco-site-deployment/SKILL.md +396 -0
  69. package/.cursor/skills/deco-site-memory-debugging/SKILL.md +121 -0
  70. package/.cursor/skills/deco-site-memory-debugging/cdp-connection.md +222 -0
  71. package/.cursor/skills/deco-site-memory-debugging/memory-analysis.md +362 -0
  72. package/.cursor/skills/deco-site-patterns/SKILL.md +124 -0
  73. package/.cursor/skills/deco-site-patterns/app-composition.md +337 -0
  74. package/.cursor/skills/deco-site-patterns/client-patterns.md +341 -0
  75. package/.cursor/skills/deco-site-patterns/cms-wiring.md +230 -0
  76. package/.cursor/skills/deco-site-patterns/section-patterns.md +340 -0
  77. package/.cursor/skills/deco-site-scaling-tuning/SKILL.md +240 -0
  78. package/.cursor/skills/deco-site-scaling-tuning/analysis-scripts.md +267 -0
  79. package/.cursor/skills/deco-start-architecture/SKILL.md +218 -0
  80. package/.cursor/skills/deco-start-architecture/admin-protocol.md +156 -0
  81. package/.cursor/skills/deco-start-architecture/cms-resolution.md +201 -0
  82. package/.cursor/skills/deco-start-architecture/code-quality.md +158 -0
  83. package/.cursor/skills/deco-start-architecture/gap-analysis.md +129 -0
  84. package/.cursor/skills/deco-start-architecture/sdk-utilities.md +197 -0
  85. package/.cursor/skills/deco-start-architecture/worker-entry-caching.md +154 -0
  86. package/.cursor/skills/deco-startup-analysis/SKILL.md +248 -0
  87. package/.cursor/skills/deco-storefront-test-checklist/SKILL.md +369 -0
  88. package/.cursor/skills/deco-tanstack-hydration-fixes/SKILL.md +468 -0
  89. package/.cursor/skills/deco-tanstack-navigation/SKILL.md +681 -0
  90. package/.cursor/skills/deco-tanstack-search/SKILL.md +411 -0
  91. package/.cursor/skills/deco-tanstack-storefront-patterns/SKILL.md +1013 -0
  92. package/.cursor/skills/deco-to-tanstack-migration/SKILL.md +518 -0
  93. package/.cursor/skills/deco-to-tanstack-migration/references/codemod-commands.md +174 -0
  94. package/.cursor/skills/deco-to-tanstack-migration/references/commerce/README.md +78 -0
  95. package/.cursor/skills/deco-to-tanstack-migration/references/deco-framework/README.md +128 -0
  96. package/.cursor/skills/deco-to-tanstack-migration/references/gotchas.md +719 -0
  97. package/.cursor/skills/deco-to-tanstack-migration/references/imports/README.md +70 -0
  98. package/.cursor/skills/deco-to-tanstack-migration/references/platform-hooks/README.md +154 -0
  99. package/.cursor/skills/deco-to-tanstack-migration/references/signals/README.md +220 -0
  100. package/.cursor/skills/deco-to-tanstack-migration/references/vite-config/README.md +78 -0
  101. package/.cursor/skills/deco-to-tanstack-migration/templates/package-json.md +55 -0
  102. package/.cursor/skills/deco-to-tanstack-migration/templates/root-route.md +110 -0
  103. package/.cursor/skills/deco-to-tanstack-migration/templates/router.md +96 -0
  104. package/.cursor/skills/deco-to-tanstack-migration/templates/setup-ts.md +167 -0
  105. package/.cursor/skills/deco-to-tanstack-migration/templates/vite-config.md +122 -0
  106. package/.cursor/skills/deco-to-tanstack-migration/templates/worker-entry.md +67 -0
  107. package/.cursor/skills/deco-typescript-fixes/SKILL.md +178 -0
  108. package/.cursor/skills/deco-typescript-fixes/common-fixes.md +330 -0
  109. package/.cursor/skills/deco-typescript-fixes/strategy.md +148 -0
  110. package/.cursor/skills/deco-variant-selection-perf/SKILL.md +272 -0
  111. package/.cursor/skills/deco-vtex-fetch-cache/SKILL.md +225 -0
  112. package/.cursor/skills/find-skills/SKILL.md +133 -0
  113. package/.cursor/skills/incident-report/SKILL.md +179 -0
  114. package/.cursor/skills/incident-report/references/5-whys.md +75 -0
  115. package/.cursor/skills/incident-report/templates/client-report.md +187 -0
  116. package/.cursor/skills/incident-report/templates/internal-report.md +206 -0
  117. package/.cursor/skills/template-skill/SKILL.md +38 -0
  118. package/.github/workflows/release.yml +32 -0
  119. package/.releaserc.json +25 -0
  120. package/CLAUDE.md +135 -0
  121. package/GAP_ANALYSIS.md +224 -0
  122. package/GAP_ANALYSIS_V2.md +1013 -0
  123. package/biome.json +39 -0
  124. package/knip.json +5 -0
  125. package/package.json +87 -0
  126. package/scripts/generate-blocks.ts +69 -0
  127. package/scripts/generate-invoke.ts +378 -0
  128. package/scripts/generate-schema.ts +657 -0
  129. package/src/admin/cors.ts +29 -0
  130. package/src/admin/decofile.ts +72 -0
  131. package/src/admin/index.ts +24 -0
  132. package/src/admin/invoke.ts +163 -0
  133. package/src/admin/liveControls.ts +29 -0
  134. package/src/admin/meta.ts +70 -0
  135. package/src/admin/render.ts +205 -0
  136. package/src/admin/schema.ts +686 -0
  137. package/src/admin/setup.ts +44 -0
  138. package/src/cms/index.ts +59 -0
  139. package/src/cms/loader.ts +180 -0
  140. package/src/cms/registry.ts +162 -0
  141. package/src/cms/resolve.ts +1005 -0
  142. package/src/cms/sectionLoaders.ts +294 -0
  143. package/src/hooks/DecoPageRenderer.tsx +444 -0
  144. package/src/hooks/LazySection.tsx +109 -0
  145. package/src/hooks/LiveControls.tsx +108 -0
  146. package/src/hooks/SectionErrorFallback.tsx +85 -0
  147. package/src/hooks/index.ts +8 -0
  148. package/src/index.ts +5 -0
  149. package/src/matchers/builtins.ts +184 -0
  150. package/src/matchers/posthog.ts +154 -0
  151. package/src/middleware/decoState.ts +55 -0
  152. package/src/middleware/healthMetrics.ts +131 -0
  153. package/src/middleware/index.ts +80 -0
  154. package/src/middleware/liveness.ts +21 -0
  155. package/src/middleware/observability.ts +205 -0
  156. package/src/routes/adminRoutes.ts +83 -0
  157. package/src/routes/cmsRoute.ts +302 -0
  158. package/src/routes/components.tsx +34 -0
  159. package/src/routes/index.ts +15 -0
  160. package/src/sdk/analytics.ts +72 -0
  161. package/src/sdk/cacheHeaders.ts +268 -0
  162. package/src/sdk/cachedLoader.ts +206 -0
  163. package/src/sdk/clx.ts +3 -0
  164. package/src/sdk/cookie.ts +39 -0
  165. package/src/sdk/createInvoke.ts +57 -0
  166. package/src/sdk/csp.ts +59 -0
  167. package/src/sdk/env.ts +27 -0
  168. package/src/sdk/index.ts +63 -0
  169. package/src/sdk/instrumentedFetch.ts +137 -0
  170. package/src/sdk/invoke.ts +133 -0
  171. package/src/sdk/mergeCacheControl.ts +150 -0
  172. package/src/sdk/redirects.ts +217 -0
  173. package/src/sdk/requestContext.ts +184 -0
  174. package/src/sdk/serverTimings.ts +68 -0
  175. package/src/sdk/signal.ts +41 -0
  176. package/src/sdk/sitemap.ts +143 -0
  177. package/src/sdk/urlUtils.ts +117 -0
  178. package/src/sdk/useDevice.ts +82 -0
  179. package/src/sdk/useId.ts +7 -0
  180. package/src/sdk/useScript.ts +101 -0
  181. package/src/sdk/workerEntry.ts +703 -0
  182. package/src/sdk/wrapCaughtErrors.ts +107 -0
  183. package/src/types/index.ts +39 -0
  184. package/src/types/widgets.ts +13 -0
  185. package/tsconfig.json +13 -0
@@ -0,0 +1,602 @@
1
+ # Troubleshooting E2E Tests
2
+
3
+ Common issues and their solutions.
4
+
5
+ ---
6
+
7
+ ## Installation Issues
8
+
9
+ ### `Cannot find package '@playwright/test'`
10
+
11
+ **Cause:** Dependencies not installed.
12
+
13
+ **Fix:**
14
+ ```bash
15
+ cd tests/e2e
16
+ npm install
17
+ npx playwright install chromium
18
+ ```
19
+
20
+ ### Playwright browsers not found
21
+
22
+ **Cause:** Browser binaries not downloaded.
23
+
24
+ **Fix:**
25
+ ```bash
26
+ npx playwright install chromium
27
+ # Or install all browsers:
28
+ npx playwright install
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Server Warmup Issues
34
+
35
+ ### Extremely slow first request (10s+ TTFB)
36
+
37
+ **Cause:** Deco/Fresh lazily loads imports on the first request after server start. This means the first request triggers all module loading, causing artificially high latency that doesn't reflect real-world performance.
38
+
39
+ **Symptoms:**
40
+ - First test shows TTFB of 10-30+ seconds
41
+ - Subsequent tests are much faster
42
+ - Only happens right after `deno task dev`
43
+ - "No products loaded" if test times out during warmup
44
+
45
+ **Fix:** Add server warmup in `test.beforeAll`:
46
+
47
+ ```typescript
48
+ async function waitForServerReady(baseUrl: string) {
49
+ // Step 1: Wait for liveness endpoint (server is up)
50
+ for (let i = 0; i < 30; i++) {
51
+ try {
52
+ const res = await fetch(`${baseUrl}/deco/_liveness`, {
53
+ signal: AbortSignal.timeout(5000),
54
+ })
55
+ if (res.ok) break
56
+ } catch {}
57
+ await new Promise(r => setTimeout(r, 1000))
58
+ }
59
+
60
+ // Step 2: Warmup request to trigger lazy imports
61
+ console.log('🔥 Warming up server (triggering lazy imports)...')
62
+ await fetch(`${baseUrl}/?__d`, {
63
+ signal: AbortSignal.timeout(60000),
64
+ })
65
+ console.log('✅ Warmup complete')
66
+ }
67
+
68
+ test.beforeAll(async () => {
69
+ await waitForServerReady(SITE_CONFIG.baseUrl)
70
+ })
71
+ ```
72
+
73
+ ### Server not responding at `/deco/_liveness`
74
+
75
+ **Cause:** Liveness endpoint not available or server crashed during startup.
76
+
77
+ **Diagnosis:**
78
+ ```bash
79
+ # Check if server is running
80
+ curl -v http://localhost:8000/deco/_liveness
81
+
82
+ # Check server logs for errors
83
+ deno task dev
84
+ ```
85
+
86
+ **Fix:** Increase liveness retry count and timeout:
87
+ ```typescript
88
+ const warmup = {
89
+ livenessRetries: 60, // Increase from 30
90
+ livenessRetryDelay: 1000,
91
+ warmupTimeout: 120000, // Increase from 60s
92
+ }
93
+ ```
94
+
95
+ ### Warmup request times out
96
+
97
+ **Cause:** Server is alive but first page load is extremely slow (heavy imports, slow VTEX API, etc).
98
+
99
+ **Fix:**
100
+ 1. Increase warmup timeout
101
+ 2. Consider warming up with a lighter page first
102
+ 3. Check for slow loaders in the homepage
103
+
104
+ ```typescript
105
+ // Warmup with liveness first (very light)
106
+ await fetch(`${baseUrl}/deco/_liveness`)
107
+
108
+ // Then warmup with homepage
109
+ await fetch(`${baseUrl}/?__d`, {
110
+ signal: AbortSignal.timeout(120000), // 2 minutes
111
+ })
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Test Execution Issues
117
+
118
+ ### Tests timeout
119
+
120
+ **Possible causes:**
121
+ 1. Site not running
122
+ 2. Tunnel not open
123
+ 3. Network issues
124
+
125
+ **Diagnosis:**
126
+ ```bash
127
+ # Check if site is accessible
128
+ curl -I https://localhost--yoursite.deco.site
129
+
130
+ # Check if dev server is running
131
+ deno task dev
132
+ ```
133
+
134
+ **Fix:** Start the dev server and ensure tunnel is active.
135
+
136
+ ### Products not loading on PLP
137
+
138
+ **Possible causes:**
139
+ 1. Products require JavaScript hydration
140
+ 2. Wrong selector
141
+ 3. Site has loading states/skeletons
142
+
143
+ **Diagnosis:**
144
+ ```typescript
145
+ // Add debug logging
146
+ const productCount = await page.locator('a:has-text("R$")').count()
147
+ console.log(`Found ${productCount} products`)
148
+
149
+ // Take a screenshot
150
+ await page.screenshot({ path: 'debug-plp.png' })
151
+ ```
152
+
153
+ **Fixes:**
154
+ ```typescript
155
+ // Wait longer for hydration
156
+ await page.waitForTimeout(3000)
157
+
158
+ // Wait for specific element that indicates load complete
159
+ await page.waitForSelector('[data-loaded="true"]')
160
+
161
+ // Use fallback PDP if PLP fails
162
+ if (productCount === 0) {
163
+ await page.goto(SITE_CONFIG.fallbackPdpPath)
164
+ }
165
+ ```
166
+
167
+ ---
168
+
169
+ ## Product Selection Issues
170
+
171
+ ### Voltage/variant modal blocks minicart
172
+
173
+ **Cause:** Electronics products require voltage selection (110V/220V). If the product shows a voltage modal before add to cart, and the test doesn't handle it, the cart operation may fail silently.
174
+
175
+ **Symptoms:**
176
+ - Add to cart seems to succeed (buy button clicked)
177
+ - Minicart never opens
178
+ - No error thrown
179
+
180
+ **Fixes:**
181
+
182
+ 1. **Best fix: Choose products without voltage requirements for tests**
183
+ - Use non-electronics categories (e.g., `/utilidades-domesticas` instead of `/eletroportateis`)
184
+ - Use simple products like thermal boxes, pillows, kitchenware as fallback PDP
185
+ - Avoid smartphones, air fryers, TVs, and other electronics
186
+
187
+ 2. **If you must test electronics, handle voltage selection:**
188
+ ```typescript
189
+ // Select voltage BEFORE clicking add to cart
190
+ async selectVoltage(): Promise<string | null> {
191
+ for (const voltage of ['110V', '127V', '220V', 'Bivolt']) {
192
+ const btn = this.page.locator(`button:has-text("${voltage}")`).first()
193
+ if (await btn.count() > 0 && await btn.isEnabled()) {
194
+ await btn.click()
195
+ await this.page.waitForTimeout(300)
196
+ return voltage
197
+ }
198
+ }
199
+ return null
200
+ }
201
+ ```
202
+
203
+ 3. **Always assert minicart visibility:**
204
+ ```typescript
205
+ const minicartOpen = await actions.isMinicartOpen()
206
+ expect(minicartOpen, 'Minicart should be visible after add to cart').toBe(true)
207
+ ```
208
+
209
+ ### Fallback PDP product out of stock
210
+
211
+ **Cause:** Hardcoded fallback PDP may go out of stock over time.
212
+
213
+ **Fix:** Choose stable, always-available products like:
214
+ - Store brand items (always in stock)
215
+ - Basic accessories (thermal boxes, pillows, etc.)
216
+ - Avoid seasonal or limited items
217
+
218
+ ---
219
+
220
+ ## Selector Issues
221
+
222
+ ### Buy button not found
223
+
224
+ **Possible causes:**
225
+ 1. Wrong button text
226
+ 2. Button inside shadow DOM
227
+ 3. Button dynamically rendered
228
+
229
+ **Diagnosis:**
230
+ ```typescript
231
+ // Log all buttons on page
232
+ const buttons = await page.locator('button').all()
233
+ for (const btn of buttons) {
234
+ console.log(await btn.textContent())
235
+ }
236
+ ```
237
+
238
+ **Common button texts to try:**
239
+ - `Comprar`
240
+ - `Adicionar`
241
+ - `Add to Cart`
242
+ - `Buy Now`
243
+ - `Adicionar ao Carrinho`
244
+
245
+ ### Size buttons not clickable
246
+
247
+ **Possible causes:**
248
+ 1. Sizes are in `<input>` not `<button>`
249
+ 2. Need to click parent element
250
+ 3. Out of stock sizes disabled
251
+
252
+ **Diagnosis:**
253
+ ```typescript
254
+ // Check if using radio inputs instead
255
+ const radios = await page.locator('input[type="radio"]').count()
256
+ console.log(`Found ${radios} radio inputs`)
257
+ ```
258
+
259
+ **Fixes:**
260
+ ```typescript
261
+ // Try input elements
262
+ sizeButton: (size: string) => `input[value="${size}"]`
263
+
264
+ // Try label elements
265
+ sizeButton: (size: string) => `label:has-text("${size}")`
266
+ ```
267
+
268
+ ### Minicart not opening
269
+
270
+ **Possible causes:**
271
+ 1. Cart uses URL navigation (`/cart`) instead of drawer
272
+ 2. Overlay/modal not detected
273
+ 3. Different minicart text
274
+
275
+ **Diagnosis:**
276
+ ```typescript
277
+ // Check URL after add to cart
278
+ console.log('Current URL:', page.url())
279
+
280
+ // Check for any cart-related text
281
+ const cartText = await page.locator('text=/cart|sacola|bag/i').first()
282
+ console.log('Cart element:', await cartText.isVisible())
283
+ ```
284
+
285
+ **Fixes:**
286
+ ```typescript
287
+ // If cart redirects to /cart page
288
+ if (page.url().includes('/cart')) {
289
+ console.log('Cart uses page navigation, not drawer')
290
+ // Test passes - cart works
291
+ }
292
+
293
+ // Try multiple minicart texts
294
+ const minicartTexts = ['Minha Sacola', 'Sacola', 'Carrinho', 'Cart']
295
+ for (const text of minicartTexts) {
296
+ if (await page.locator(`text=${text}`).isVisible().catch(() => false)) {
297
+ console.log(`Minicart found with text: ${text}`)
298
+ break
299
+ }
300
+ }
301
+ ```
302
+
303
+ ---
304
+
305
+ ## Performance Issues
306
+
307
+ ### TTFB too high (> 5s)
308
+
309
+ **Possible causes:**
310
+ 1. Cold cache on first request
311
+ 2. Slow VTEX API
312
+ 3. Too many sync loaders
313
+
314
+ **This is often normal for first requests.** Check warm cache performance instead.
315
+
316
+ **Fixes:**
317
+ - Increase threshold for cold cache
318
+ - Focus assertions on warm cache performance
319
+ - Check `?__d` response for slow loaders
320
+
321
+ ### Warm cache not faster than cold
322
+
323
+ **Possible causes:**
324
+ 1. Cache not working
325
+ 2. Different pages being tested
326
+ 3. Dynamic content
327
+
328
+ **Diagnosis:**
329
+ ```typescript
330
+ console.log(`Cold: ${coldMetrics.performance.TTFB}ms`)
331
+ console.log(`Warm: ${warmMetrics.performance.TTFB}ms`)
332
+
333
+ const improvement = coldMetrics.performance.TTFB - warmMetrics.performance.TTFB
334
+ console.log(`Improvement: ${improvement}ms`)
335
+ ```
336
+
337
+ **If no improvement:** Check server-timing headers for cache status.
338
+
339
+ ---
340
+
341
+ ## Network Issues
342
+
343
+ ### Cart response not detected
344
+
345
+ **Possible causes:**
346
+ 1. Different API endpoint
347
+ 2. Response timeout
348
+ 3. Cart uses WebSocket
349
+
350
+ **Diagnosis:**
351
+ ```typescript
352
+ // Log all responses after click
353
+ page.on('response', (res) => {
354
+ if (res.url().includes('cart') || res.url().includes('order')) {
355
+ console.log('Cart response:', res.url(), res.status())
356
+ }
357
+ })
358
+ ```
359
+
360
+ **Fixes:**
361
+ ```typescript
362
+ // Add more endpoint patterns
363
+ await page.waitForResponse(r =>
364
+ r.url().includes('orderForm') ||
365
+ r.url().includes('cart') ||
366
+ r.url().includes('items') ||
367
+ r.url().includes('checkout'),
368
+ { timeout: 10000 }
369
+ )
370
+
371
+ // Or just wait fixed time
372
+ await page.waitForTimeout(3000)
373
+ ```
374
+
375
+ ---
376
+
377
+ ## Process Cleanup Issues
378
+
379
+ ### Server lingers after test interruption
380
+
381
+ **Cause:** When tests are stopped with Ctrl+C or fail midway, the dev server process may not be properly terminated.
382
+
383
+ **Symptoms:**
384
+ - Next test run fails because port 8000 is already in use
385
+ - Multiple `deno` processes running in background
386
+ - "Address already in use" errors
387
+
388
+ **Check for lingering processes:**
389
+ ```bash
390
+ # Find processes on port 8000
391
+ lsof -i :8000
392
+
393
+ # Find deno processes
394
+ ps aux | grep deno
395
+ ```
396
+
397
+ **Kill lingering processes:**
398
+ ```bash
399
+ # Kill by port
400
+ kill $(lsof -t -i :8000)
401
+
402
+ # Or kill all deno processes (careful!)
403
+ pkill -f "deno task dev"
404
+ ```
405
+
406
+ **Prevention:** The run-e2e.ts script handles cleanup automatically via:
407
+ - SIGINT handler (Ctrl+C)
408
+ - SIGTERM handler
409
+ - Unhandled rejection handler
410
+
411
+ If cleanup still fails, check that the script is using the latest version with signal handlers.
412
+
413
+ ---
414
+
415
+ ## Lazy Section Issues
416
+
417
+ ### Lazy sections "hanging" or not loading
418
+
419
+ **Cause:** Lazy sections (`/deco/render` requests) can hang if they are triggered too quickly before the previous one completes, or if the server is overloaded.
420
+
421
+ **Symptoms:**
422
+ - Test times out waiting for footer
423
+ - Some sections never appear
424
+ - Console shows "Waiting for pending render..."
425
+
426
+ **Fix:** Use the strict queue approach in `scrollPage`:
427
+
428
+ ```typescript
429
+ // STRICT: Never scroll while there's a pending request
430
+ if (this.pendingLazyRenders > 0) {
431
+ console.log(`Waiting for ${this.pendingLazyRenders} pending render...`)
432
+ await this.waitForPendingRenders(8000)
433
+ }
434
+ ```
435
+
436
+ ### Lazy section names showing as "Unknown Section"
437
+
438
+ **Cause:** The section name extraction couldn't find a meaningful identifier.
439
+
440
+ **Fixes:**
441
+ 1. Ensure your Deco runtime sends `x-deco-section` header (see SKILL.md)
442
+ 2. Check that sections have `__resolveType` or title props
443
+ 3. The metrics collector falls back through: x-deco-section header → props parsing → sectionId → resolveChain → renderSalt
444
+
445
+ ### Too many lazy sections slowing down tests
446
+
447
+ **Cause:** Homepage with 20+ lazy sections takes a long time to scroll and load.
448
+
449
+ **Fix:** Use the `maxTime` option to limit scroll time:
450
+
451
+ ```typescript
452
+ await collector.scrollPage({ full: true, maxTime: 20000 }) // 20s max
453
+ ```
454
+
455
+ The test will still collect metrics for all triggered sections, but won't wait forever.
456
+
457
+ ---
458
+
459
+ ## Minicart Verification Issues
460
+
461
+ ### Minicart not detected despite product being added
462
+
463
+ **Cause:** Different sites use different minicart implementations (drawer, modal, redirect to /cart).
464
+
465
+ **Symptoms:**
466
+ - Test says "Minicart not visible"
467
+ - Product was actually added (can see in network)
468
+ - Cart functionality works manually
469
+
470
+ **Fix:** Use robust selector with retry logic:
471
+
472
+ ```typescript
473
+ async isMinicartOpen(): Promise<boolean> {
474
+ const selectors = [
475
+ `text=${SITE_CONFIG.minicartText}`,
476
+ '[data-testid="minicart"]',
477
+ '.minicart',
478
+ '[class*="minicart"]',
479
+ '[class*="cart-drawer"]',
480
+ '[class*="drawer"][class*="open"]',
481
+ ]
482
+
483
+ for (let attempt = 0; attempt < 3; attempt++) {
484
+ const timeout = 2000 + (attempt * 1000)
485
+ for (const selector of selectors) {
486
+ const visible = await this.page.locator(selector).first()
487
+ .isVisible({ timeout }).catch(() => false)
488
+ if (visible) return true
489
+ }
490
+ await this.page.waitForTimeout(500)
491
+ }
492
+ return false
493
+ }
494
+ ```
495
+
496
+ ---
497
+
498
+ ## Report Issues
499
+
500
+ ### Desktop and mobile reports overwriting each other
501
+
502
+ **Cause:** Both device types saving to the same file.
503
+
504
+ **Fix:** Use `testInfo.project.name` to create unique files:
505
+
506
+ ```typescript
507
+ test.beforeAll(async ({}, testInfo) => {
508
+ projectName = testInfo.project.name || 'default'
509
+ })
510
+
511
+ test.afterAll(async () => {
512
+ const reportFile = `./reports/report-${projectName}.json`
513
+ fs.writeFileSync(reportFile, JSON.stringify(report, null, 2))
514
+ })
515
+ ```
516
+
517
+ ### Server Timing not showing loaders
518
+
519
+ **Cause:** The `?__d` debug flag is not being used.
520
+
521
+ **Fix:** Always append `?__d` to URLs:
522
+
523
+ ```typescript
524
+ // In SITE_CONFIG
525
+ debugParam: '?__d', // Always enabled
526
+
527
+ // In withDebug helper
528
+ private withDebug(path: string): string {
529
+ const hasQuery = path.includes('?')
530
+ return path + (hasQuery ? '&__d' : SITE_CONFIG.debugParam)
531
+ }
532
+ ```
533
+
534
+ ### Reports missing cache analysis data
535
+
536
+ **Cause:** Metrics not being collected properly before page navigation.
537
+
538
+ **Fix:** Always call `collectPageMetrics` before navigating away:
539
+
540
+ ```typescript
541
+ const metrics = await collector.collectPageMetrics('Page Name')
542
+ // metrics.cacheAnalysis contains all lazy render and cache data
543
+ // metrics.serverTiming contains all loader timings
544
+ // metrics.decoHeaders contains page block and route info
545
+ ```
546
+
547
+ ---
548
+
549
+ ## Playwright Pattern Issues
550
+
551
+ ### Error: "First argument must use object destructuring pattern"
552
+
553
+ **Cause:** Playwright requires a specific pattern for `test.beforeAll` when accessing `testInfo`.
554
+
555
+ **Fix:**
556
+ ```typescript
557
+ // Wrong:
558
+ test.beforeAll(async (_, testInfo) => { ... })
559
+
560
+ // Correct:
561
+ // biome-ignore lint/correctness/noEmptyPattern: Playwright requires this
562
+ test.beforeAll(async ({}, testInfo) => { ... })
563
+ ```
564
+
565
+ ---
566
+
567
+ ## Environment Issues
568
+
569
+ ### Different results locally vs CI
570
+
571
+ **Possible causes:**
572
+ 1. Network speed differences
573
+ 2. Different screen sizes
574
+ 3. Timezone/locale issues
575
+
576
+ **Fixes:**
577
+ ```typescript
578
+ // Set consistent viewport
579
+ use: {
580
+ viewport: { width: 1280, height: 720 },
581
+ }
582
+
583
+ // Increase timeouts in CI
584
+ timeout: process.env.CI ? 180_000 : 120_000
585
+ ```
586
+
587
+ ### Tests pass locally but fail in CI
588
+
589
+ **Common CI fixes:**
590
+ ```typescript
591
+ // In playwright.config.ts
592
+ export default defineConfig({
593
+ retries: process.env.CI ? 2 : 0,
594
+ timeout: process.env.CI ? 180_000 : 120_000,
595
+ use: {
596
+ // Slower animations in CI
597
+ launchOptions: {
598
+ slowMo: process.env.CI ? 100 : 0,
599
+ },
600
+ },
601
+ })
602
+ ```