@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.
- package/.cursor/skills/deco-api-call-dedup/SKILL.md +443 -0
- package/.cursor/skills/deco-apps-architecture/SKILL.md +255 -0
- package/.cursor/skills/deco-apps-architecture/app-pattern.md +288 -0
- package/.cursor/skills/deco-apps-architecture/commerce-types.md +239 -0
- package/.cursor/skills/deco-apps-architecture/new-app-guide.md +268 -0
- package/.cursor/skills/deco-apps-architecture/scripts-codegen.md +148 -0
- package/.cursor/skills/deco-apps-architecture/shared-utils.md +181 -0
- package/.cursor/skills/deco-apps-architecture/vtex-deep-structure.md +253 -0
- package/.cursor/skills/deco-apps-architecture/website-app.md +169 -0
- package/.cursor/skills/deco-apps-vtex-porting/SKILL.md +189 -0
- package/.cursor/skills/deco-apps-vtex-porting/adaptation-patterns.md +335 -0
- package/.cursor/skills/deco-apps-vtex-porting/commerce-porting.md +155 -0
- package/.cursor/skills/deco-apps-vtex-porting/cookie-auth-patterns.md +148 -0
- package/.cursor/skills/deco-apps-vtex-porting/structure-map.md +234 -0
- package/.cursor/skills/deco-apps-vtex-porting/transform-mapping.md +99 -0
- package/.cursor/skills/deco-apps-vtex-porting/website-porting.md +194 -0
- package/.cursor/skills/deco-apps-vtex-review/SKILL.md +234 -0
- package/.cursor/skills/deco-async-rendering-architecture/SKILL.md +270 -0
- package/.cursor/skills/deco-async-rendering-site-guide/SKILL.md +417 -0
- package/.cursor/skills/deco-cms-layout-caching/SKILL.md +293 -0
- package/.cursor/skills/deco-cms-route-config/SKILL.md +388 -0
- package/.cursor/skills/deco-core-architecture/SKILL.md +185 -0
- package/.cursor/skills/deco-core-architecture/blocks.md +196 -0
- package/.cursor/skills/deco-core-architecture/deco-vs-deco-start.md +191 -0
- package/.cursor/skills/deco-core-architecture/engine.md +220 -0
- package/.cursor/skills/deco-core-architecture/hooks-components.md +157 -0
- package/.cursor/skills/deco-core-architecture/plugins-clients.md +136 -0
- package/.cursor/skills/deco-core-architecture/runtime.md +116 -0
- package/.cursor/skills/deco-core-architecture/site-usage.md +165 -0
- package/.cursor/skills/deco-e2e-testing/SKILL.md +372 -0
- package/.cursor/skills/deco-e2e-testing/discovery.md +337 -0
- package/.cursor/skills/deco-e2e-testing/scripts/scaffold.sh +81 -0
- package/.cursor/skills/deco-e2e-testing/selectors.md +175 -0
- package/.cursor/skills/deco-e2e-testing/templates/package.json +18 -0
- package/.cursor/skills/deco-e2e-testing/templates/playwright.config.ts +65 -0
- package/.cursor/skills/deco-e2e-testing/templates/scripts/baseline.ts +279 -0
- package/.cursor/skills/deco-e2e-testing/templates/scripts/run-e2e.ts +194 -0
- package/.cursor/skills/deco-e2e-testing/templates/specs/ecommerce-flow.spec.ts +612 -0
- package/.cursor/skills/deco-e2e-testing/templates/tsconfig.json +12 -0
- package/.cursor/skills/deco-e2e-testing/templates/utils/metrics-collector.ts +918 -0
- package/.cursor/skills/deco-e2e-testing/troubleshooting.md +602 -0
- package/.cursor/skills/deco-edge-caching/SKILL.md +316 -0
- package/.cursor/skills/deco-full-analysis/SKILL.md +898 -0
- package/.cursor/skills/deco-full-analysis/checklists/asset-optimization.md +251 -0
- package/.cursor/skills/deco-full-analysis/checklists/bug-fix.md +189 -0
- package/.cursor/skills/deco-full-analysis/checklists/cache-strategy.md +144 -0
- package/.cursor/skills/deco-full-analysis/checklists/dependency-update.md +150 -0
- package/.cursor/skills/deco-full-analysis/checklists/hydration-fix.md +191 -0
- package/.cursor/skills/deco-full-analysis/checklists/image-optimization.md +180 -0
- package/.cursor/skills/deco-full-analysis/checklists/loader-optimization.md +165 -0
- package/.cursor/skills/deco-full-analysis/checklists/seo-fix.md +183 -0
- package/.cursor/skills/deco-full-analysis/checklists/site-cleanup.md +281 -0
- package/.cursor/skills/deco-full-analysis/discovery.md +548 -0
- package/.cursor/skills/deco-incident-debugging/SKILL.md +378 -0
- package/.cursor/skills/deco-incident-debugging/headless-mode.md +510 -0
- package/.cursor/skills/deco-incident-debugging/learnings-index.md +227 -0
- package/.cursor/skills/deco-incident-debugging/triage-workflow.md +312 -0
- package/.cursor/skills/deco-islands-migration/SKILL.md +251 -0
- package/.cursor/skills/deco-loader-n-plus-1-detector/SKILL.md +275 -0
- package/.cursor/skills/deco-performance-audit/SKILL.md +530 -0
- package/.cursor/skills/deco-performance-audit/tools-reference.md +428 -0
- package/.cursor/skills/deco-performance-audit/workflow.md +457 -0
- package/.cursor/skills/deco-server-functions-invoke/SKILL.md +92 -0
- package/.cursor/skills/deco-server-functions-invoke/architecture.md +166 -0
- package/.cursor/skills/deco-server-functions-invoke/generator.md +122 -0
- package/.cursor/skills/deco-server-functions-invoke/problem.md +98 -0
- package/.cursor/skills/deco-server-functions-invoke/troubleshooting.md +110 -0
- package/.cursor/skills/deco-site-deployment/SKILL.md +396 -0
- package/.cursor/skills/deco-site-memory-debugging/SKILL.md +121 -0
- package/.cursor/skills/deco-site-memory-debugging/cdp-connection.md +222 -0
- package/.cursor/skills/deco-site-memory-debugging/memory-analysis.md +362 -0
- package/.cursor/skills/deco-site-patterns/SKILL.md +124 -0
- package/.cursor/skills/deco-site-patterns/app-composition.md +337 -0
- package/.cursor/skills/deco-site-patterns/client-patterns.md +341 -0
- package/.cursor/skills/deco-site-patterns/cms-wiring.md +230 -0
- package/.cursor/skills/deco-site-patterns/section-patterns.md +340 -0
- package/.cursor/skills/deco-site-scaling-tuning/SKILL.md +240 -0
- package/.cursor/skills/deco-site-scaling-tuning/analysis-scripts.md +267 -0
- package/.cursor/skills/deco-start-architecture/SKILL.md +218 -0
- package/.cursor/skills/deco-start-architecture/admin-protocol.md +156 -0
- package/.cursor/skills/deco-start-architecture/cms-resolution.md +201 -0
- package/.cursor/skills/deco-start-architecture/code-quality.md +158 -0
- package/.cursor/skills/deco-start-architecture/gap-analysis.md +129 -0
- package/.cursor/skills/deco-start-architecture/sdk-utilities.md +197 -0
- package/.cursor/skills/deco-start-architecture/worker-entry-caching.md +154 -0
- package/.cursor/skills/deco-startup-analysis/SKILL.md +248 -0
- package/.cursor/skills/deco-storefront-test-checklist/SKILL.md +369 -0
- package/.cursor/skills/deco-tanstack-hydration-fixes/SKILL.md +468 -0
- package/.cursor/skills/deco-tanstack-navigation/SKILL.md +681 -0
- package/.cursor/skills/deco-tanstack-search/SKILL.md +411 -0
- package/.cursor/skills/deco-tanstack-storefront-patterns/SKILL.md +1013 -0
- package/.cursor/skills/deco-to-tanstack-migration/SKILL.md +518 -0
- package/.cursor/skills/deco-to-tanstack-migration/references/codemod-commands.md +174 -0
- package/.cursor/skills/deco-to-tanstack-migration/references/commerce/README.md +78 -0
- package/.cursor/skills/deco-to-tanstack-migration/references/deco-framework/README.md +128 -0
- package/.cursor/skills/deco-to-tanstack-migration/references/gotchas.md +719 -0
- package/.cursor/skills/deco-to-tanstack-migration/references/imports/README.md +70 -0
- package/.cursor/skills/deco-to-tanstack-migration/references/platform-hooks/README.md +154 -0
- package/.cursor/skills/deco-to-tanstack-migration/references/signals/README.md +220 -0
- package/.cursor/skills/deco-to-tanstack-migration/references/vite-config/README.md +78 -0
- package/.cursor/skills/deco-to-tanstack-migration/templates/package-json.md +55 -0
- package/.cursor/skills/deco-to-tanstack-migration/templates/root-route.md +110 -0
- package/.cursor/skills/deco-to-tanstack-migration/templates/router.md +96 -0
- package/.cursor/skills/deco-to-tanstack-migration/templates/setup-ts.md +167 -0
- package/.cursor/skills/deco-to-tanstack-migration/templates/vite-config.md +122 -0
- package/.cursor/skills/deco-to-tanstack-migration/templates/worker-entry.md +67 -0
- package/.cursor/skills/deco-typescript-fixes/SKILL.md +178 -0
- package/.cursor/skills/deco-typescript-fixes/common-fixes.md +330 -0
- package/.cursor/skills/deco-typescript-fixes/strategy.md +148 -0
- package/.cursor/skills/deco-variant-selection-perf/SKILL.md +272 -0
- package/.cursor/skills/deco-vtex-fetch-cache/SKILL.md +225 -0
- package/.cursor/skills/find-skills/SKILL.md +133 -0
- package/.cursor/skills/incident-report/SKILL.md +179 -0
- package/.cursor/skills/incident-report/references/5-whys.md +75 -0
- package/.cursor/skills/incident-report/templates/client-report.md +187 -0
- package/.cursor/skills/incident-report/templates/internal-report.md +206 -0
- package/.cursor/skills/template-skill/SKILL.md +38 -0
- package/.github/workflows/release.yml +32 -0
- package/.releaserc.json +25 -0
- package/CLAUDE.md +135 -0
- package/GAP_ANALYSIS.md +224 -0
- package/GAP_ANALYSIS_V2.md +1013 -0
- package/biome.json +39 -0
- package/knip.json +5 -0
- package/package.json +87 -0
- package/scripts/generate-blocks.ts +69 -0
- package/scripts/generate-invoke.ts +378 -0
- package/scripts/generate-schema.ts +657 -0
- package/src/admin/cors.ts +29 -0
- package/src/admin/decofile.ts +72 -0
- package/src/admin/index.ts +24 -0
- package/src/admin/invoke.ts +163 -0
- package/src/admin/liveControls.ts +29 -0
- package/src/admin/meta.ts +70 -0
- package/src/admin/render.ts +205 -0
- package/src/admin/schema.ts +686 -0
- package/src/admin/setup.ts +44 -0
- package/src/cms/index.ts +59 -0
- package/src/cms/loader.ts +180 -0
- package/src/cms/registry.ts +162 -0
- package/src/cms/resolve.ts +1005 -0
- package/src/cms/sectionLoaders.ts +294 -0
- package/src/hooks/DecoPageRenderer.tsx +444 -0
- package/src/hooks/LazySection.tsx +109 -0
- package/src/hooks/LiveControls.tsx +108 -0
- package/src/hooks/SectionErrorFallback.tsx +85 -0
- package/src/hooks/index.ts +8 -0
- package/src/index.ts +5 -0
- package/src/matchers/builtins.ts +184 -0
- package/src/matchers/posthog.ts +154 -0
- package/src/middleware/decoState.ts +55 -0
- package/src/middleware/healthMetrics.ts +131 -0
- package/src/middleware/index.ts +80 -0
- package/src/middleware/liveness.ts +21 -0
- package/src/middleware/observability.ts +205 -0
- package/src/routes/adminRoutes.ts +83 -0
- package/src/routes/cmsRoute.ts +302 -0
- package/src/routes/components.tsx +34 -0
- package/src/routes/index.ts +15 -0
- package/src/sdk/analytics.ts +72 -0
- package/src/sdk/cacheHeaders.ts +268 -0
- package/src/sdk/cachedLoader.ts +206 -0
- package/src/sdk/clx.ts +3 -0
- package/src/sdk/cookie.ts +39 -0
- package/src/sdk/createInvoke.ts +57 -0
- package/src/sdk/csp.ts +59 -0
- package/src/sdk/env.ts +27 -0
- package/src/sdk/index.ts +63 -0
- package/src/sdk/instrumentedFetch.ts +137 -0
- package/src/sdk/invoke.ts +133 -0
- package/src/sdk/mergeCacheControl.ts +150 -0
- package/src/sdk/redirects.ts +217 -0
- package/src/sdk/requestContext.ts +184 -0
- package/src/sdk/serverTimings.ts +68 -0
- package/src/sdk/signal.ts +41 -0
- package/src/sdk/sitemap.ts +143 -0
- package/src/sdk/urlUtils.ts +117 -0
- package/src/sdk/useDevice.ts +82 -0
- package/src/sdk/useId.ts +7 -0
- package/src/sdk/useScript.ts +101 -0
- package/src/sdk/workerEntry.ts +703 -0
- package/src/sdk/wrapCaughtErrors.ts +107 -0
- package/src/types/index.ts +39 -0
- package/src/types/widgets.ts +13 -0
- 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
|
+
```
|