@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,337 @@
|
|
|
1
|
+
# Site Discovery Guide
|
|
2
|
+
|
|
3
|
+
Before implementing e2e tests, you MUST discover these site-specific values. This guide shows exactly where to find each one.
|
|
4
|
+
|
|
5
|
+
## Required Information Checklist
|
|
6
|
+
|
|
7
|
+
| Info | Status | Value |
|
|
8
|
+
|------|--------|-------|
|
|
9
|
+
| Site URL | ☐ | |
|
|
10
|
+
| PLP Path | ☐ | |
|
|
11
|
+
| Fallback PDP Path | ☐ | |
|
|
12
|
+
| Product Card Selector | ☐ | |
|
|
13
|
+
| Buy Button Selector | ☐ | |
|
|
14
|
+
| Size Button Pattern | ☐ | |
|
|
15
|
+
| Available Sizes | ☐ | |
|
|
16
|
+
| Minicart Text | ☐ | |
|
|
17
|
+
| Currency Symbol | ☐ | |
|
|
18
|
+
| Voltage Options | ☐ | (electronics only) |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Framework Endpoints
|
|
23
|
+
|
|
24
|
+
All Deco sites have these built-in endpoints:
|
|
25
|
+
|
|
26
|
+
| Endpoint | Purpose |
|
|
27
|
+
|----------|---------|
|
|
28
|
+
| `/deco/_liveness` | Health check - returns 200 when server is ready |
|
|
29
|
+
| `?__d` | Debug mode - adds server-timing headers |
|
|
30
|
+
|
|
31
|
+
The liveness endpoint is critical for test warmup - see SKILL.md for details.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 1. Site URL
|
|
36
|
+
|
|
37
|
+
**Where to find:**
|
|
38
|
+
- `deno.json` → look for `site` or site name
|
|
39
|
+
- `apps/site.ts` → site configuration
|
|
40
|
+
- Any `.deco.site` URL references
|
|
41
|
+
|
|
42
|
+
**Search commands:**
|
|
43
|
+
```bash
|
|
44
|
+
grep -r "deco.site" deno.json apps/
|
|
45
|
+
grep -r "localhost--" .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Format:** `https://localhost--{sitename}.deco.site`
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 2. PLP Path (Category Page)
|
|
53
|
+
|
|
54
|
+
**Where to find:**
|
|
55
|
+
- `components/header/` → menu/nav components
|
|
56
|
+
- `sections/Header*.tsx` → navigation links
|
|
57
|
+
- `static/` → sitemap or nav configs
|
|
58
|
+
|
|
59
|
+
**Search commands:**
|
|
60
|
+
```bash
|
|
61
|
+
grep -r 'href="/' components/header/
|
|
62
|
+
grep -r 'href="/' sections/Header*.tsx
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Common patterns:**
|
|
66
|
+
- `/feminino`, `/masculino` (fashion)
|
|
67
|
+
- `/roupas`, `/calcados` (apparel)
|
|
68
|
+
- `/category/{slug}` (generic)
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 3. Fallback PDP Path
|
|
73
|
+
|
|
74
|
+
**Where to find:**
|
|
75
|
+
- Any product URL in sections or loaders
|
|
76
|
+
- Search for `/p` suffix (VTEX pattern)
|
|
77
|
+
- Product loader test fixtures
|
|
78
|
+
|
|
79
|
+
**Search commands:**
|
|
80
|
+
```bash
|
|
81
|
+
grep -r '"/.*\/p"' sections/ loaders/
|
|
82
|
+
grep -r 'productId\|skuId' loaders/
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Format:** `/product-name-sku/p`
|
|
86
|
+
|
|
87
|
+
**IMPORTANT - Choosing a good fallback product:**
|
|
88
|
+
- **Avoid electronics** that require voltage selection (110V/220V modals block the cart)
|
|
89
|
+
- **Avoid fashion items** that require size selection if possible
|
|
90
|
+
- **Prefer simple products** like:
|
|
91
|
+
- Thermal boxes, containers
|
|
92
|
+
- Pillows, towels, bedding
|
|
93
|
+
- Kitchen utensils
|
|
94
|
+
- Decorative items
|
|
95
|
+
- Look for products in `.deco/blocks/` JSON files that link to `/p` URLs
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 4. Product Card Selector
|
|
100
|
+
|
|
101
|
+
**Where to find:**
|
|
102
|
+
- `components/product/ProductCard.tsx`
|
|
103
|
+
- Look for the main link/anchor wrapping the product
|
|
104
|
+
|
|
105
|
+
**Search commands:**
|
|
106
|
+
```bash
|
|
107
|
+
cat components/product/ProductCard.tsx | head -100
|
|
108
|
+
grep -r 'data-product\|ProductCard' components/
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Read the file and identify:**
|
|
112
|
+
- What wrapper element is clickable?
|
|
113
|
+
- What text always appears? (usually price)
|
|
114
|
+
|
|
115
|
+
**Common selectors:**
|
|
116
|
+
| Platform | Selector |
|
|
117
|
+
|----------|----------|
|
|
118
|
+
| VTEX (BRL) | `a:has-text("R$")` |
|
|
119
|
+
| VTEX (USD) | `a:has-text("$")` |
|
|
120
|
+
| Generic | `[data-product-card]` |
|
|
121
|
+
| Shopify | `.product-item a` |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 5. Buy Button Selector
|
|
126
|
+
|
|
127
|
+
**Where to find:**
|
|
128
|
+
- `components/product/AddToCartButton.tsx`
|
|
129
|
+
- `components/product/ProductDetails.tsx`
|
|
130
|
+
- `islands/AddToCartButton.tsx`
|
|
131
|
+
|
|
132
|
+
**Search commands:**
|
|
133
|
+
```bash
|
|
134
|
+
grep -r 'Comprar\|Add to Cart\|Adicionar' components/product/
|
|
135
|
+
grep -r 'addToCart\|add-to-cart' islands/
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Common selectors:**
|
|
139
|
+
| Language | Selector |
|
|
140
|
+
|----------|----------|
|
|
141
|
+
| PT-BR | `button:has-text("Comprar")` |
|
|
142
|
+
| EN | `button:has-text("Add to Cart")` |
|
|
143
|
+
| Generic | `button[data-add-to-cart]` |
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 6. Size Button Pattern
|
|
148
|
+
|
|
149
|
+
**Where to find:**
|
|
150
|
+
- `components/product/VariantSelector.tsx`
|
|
151
|
+
- `components/product/Sizes.tsx`
|
|
152
|
+
- `islands/Sizes.tsx`
|
|
153
|
+
|
|
154
|
+
**Search commands:**
|
|
155
|
+
```bash
|
|
156
|
+
cat components/product/VariantSelector.tsx
|
|
157
|
+
grep -r 'size\|variant\|sku' components/product/
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Common patterns:**
|
|
161
|
+
| Structure | Pattern |
|
|
162
|
+
|-----------|---------|
|
|
163
|
+
| List buttons | `li button:has-text("${size}")` |
|
|
164
|
+
| Direct buttons | `button[data-size="${size}"]` |
|
|
165
|
+
| Radio inputs | `input[value="${size}"]` |
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 7. Available Sizes
|
|
170
|
+
|
|
171
|
+
**Where to find:**
|
|
172
|
+
- Same files as size button
|
|
173
|
+
- Look for size arrays or enums
|
|
174
|
+
- Check variant options in product loaders
|
|
175
|
+
|
|
176
|
+
**Common size sets:**
|
|
177
|
+
| Type | Sizes |
|
|
178
|
+
|------|-------|
|
|
179
|
+
| Clothing (BR) | `['PP', 'P', 'M', 'G', 'GG', 'G1', 'G2']` |
|
|
180
|
+
| Clothing (US) | `['XS', 'S', 'M', 'L', 'XL', 'XXL']` |
|
|
181
|
+
| Shoes (BR) | `['34', '35', '36', '37', '38', '39', '40', '41', '42']` |
|
|
182
|
+
| Shoes (US) | `['6', '7', '8', '9', '10', '11', '12']` |
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 8. Voltage Options (Electronics Stores)
|
|
187
|
+
|
|
188
|
+
**When needed:** For stores selling electronics (appliances, TVs, etc), products may require voltage selection before adding to cart.
|
|
189
|
+
|
|
190
|
+
**Where to find:**
|
|
191
|
+
- Same components as size selector
|
|
192
|
+
- Look for voltage-specific variant handling
|
|
193
|
+
|
|
194
|
+
**Search commands:**
|
|
195
|
+
```bash
|
|
196
|
+
grep -r 'voltage\|tensao\|110V\|220V' components/product/
|
|
197
|
+
grep -r 'Bivolt' components/
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Common voltages:**
|
|
201
|
+
```typescript
|
|
202
|
+
voltages: ['110V', '127V', '220V', 'Bivolt']
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Common selectors:**
|
|
206
|
+
```typescript
|
|
207
|
+
voltageSelector: (voltage: string) => `button:has-text("${voltage}")`
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 9. Minicart Text
|
|
213
|
+
|
|
214
|
+
**Where to find:**
|
|
215
|
+
- `components/minicart/`
|
|
216
|
+
- `islands/Cart.tsx`
|
|
217
|
+
- Look for drawer/modal header
|
|
218
|
+
|
|
219
|
+
**Search commands:**
|
|
220
|
+
```bash
|
|
221
|
+
grep -r 'Sacola\|Cart\|Bag\|Carrinho' components/minicart/
|
|
222
|
+
cat components/minicart/Cart.tsx | head -50
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Common values:**
|
|
226
|
+
| Language | Text |
|
|
227
|
+
|----------|------|
|
|
228
|
+
| PT-BR | `Minha Sacola` |
|
|
229
|
+
| EN | `Your Cart` or `Shopping Bag` |
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 9. Currency Symbol
|
|
234
|
+
|
|
235
|
+
**Where to find:**
|
|
236
|
+
- `sdk/format.ts` or similar
|
|
237
|
+
- Price components
|
|
238
|
+
- Locale configuration
|
|
239
|
+
|
|
240
|
+
**Common values:**
|
|
241
|
+
- `R$` (Brazil)
|
|
242
|
+
- `$` (US/Generic)
|
|
243
|
+
- `€` (Europe)
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Discovery Workflow
|
|
248
|
+
|
|
249
|
+
1. **Clone/open the site repo**
|
|
250
|
+
2. **Run discovery searches** for each item above
|
|
251
|
+
3. **Read key component files** to verify selectors
|
|
252
|
+
4. **Test selectors manually** in browser DevTools:
|
|
253
|
+
```javascript
|
|
254
|
+
// In browser console on the live site:
|
|
255
|
+
document.querySelectorAll('a:has-text("R$")').length
|
|
256
|
+
document.querySelectorAll('button:has-text("Comprar")').length
|
|
257
|
+
```
|
|
258
|
+
5. **Fill in the checklist** and proceed to implementation
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## 10. Deco Observability Headers
|
|
263
|
+
|
|
264
|
+
The test suite captures these Deco-specific headers for debugging:
|
|
265
|
+
|
|
266
|
+
| Header | Source | Purpose |
|
|
267
|
+
|--------|--------|---------|
|
|
268
|
+
| `x-deco-section` | `/deco/render` response | Section component type and title |
|
|
269
|
+
| `x-deco-page` | Page response | Matched page block name |
|
|
270
|
+
| `x-deco-route` | Page response | Matched route template |
|
|
271
|
+
| `x-deco-platform` | All responses | Platform identifier |
|
|
272
|
+
| `server-timing` | `?__d` mode | Loader timings and cache status |
|
|
273
|
+
|
|
274
|
+
**These are set automatically by the Deco runtime.** If they're missing, ensure you're using a recent version of:
|
|
275
|
+
- `@deco/deco` (runtime)
|
|
276
|
+
- `apps/website/handlers/fresh.ts` (page handler)
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Example: Completed Discovery
|
|
281
|
+
|
|
282
|
+
### Brazilian Fashion E-commerce
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
const SITE_CONFIG = {
|
|
286
|
+
baseUrl: 'https://localhost--lojastorra-2.deco.site',
|
|
287
|
+
plpPath: '/feminino',
|
|
288
|
+
fallbackPdpPath: '/macaquinho-feminino-curto-berry-16171000788507/p',
|
|
289
|
+
debugParam: '?__d',
|
|
290
|
+
|
|
291
|
+
productCard: 'a:has-text("R$")',
|
|
292
|
+
pdpUrlPattern: /\/p/,
|
|
293
|
+
buyButton: 'button:has-text("Comprar")',
|
|
294
|
+
sizeButton: (size: string) => `li button:has-text("${size}")`,
|
|
295
|
+
minicartText: 'Minha Sacola',
|
|
296
|
+
|
|
297
|
+
sizes: ['PP', 'P', 'M', 'G', 'GG', 'G1', 'G2', 'G3', '38', '40', '42'],
|
|
298
|
+
|
|
299
|
+
thresholds: {
|
|
300
|
+
coldTTFB: 5000,
|
|
301
|
+
warmTTFB: 2000,
|
|
302
|
+
homeTTFB: 3000,
|
|
303
|
+
},
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Brazilian Electronics Store (Casa e Video)
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
const SITE_CONFIG = {
|
|
311
|
+
baseUrl: 'https://localhost--casaevideo.deco.site',
|
|
312
|
+
// Use non-electronics PLP to avoid voltage selection
|
|
313
|
+
plpPath: '/utilidades-domesticas',
|
|
314
|
+
// Simple product without voltage/size variants
|
|
315
|
+
fallbackPdpPath: '/caixa-termica-12l-botafogo-azul/p',
|
|
316
|
+
debugParam: '?__d',
|
|
317
|
+
|
|
318
|
+
// Deco-specific data attribute
|
|
319
|
+
productCard: '[data-deco="view-product"]',
|
|
320
|
+
productCardFallback: 'a:has-text("R$")',
|
|
321
|
+
pdpUrlPattern: /\/p/,
|
|
322
|
+
buyButton: 'button:has-text("Comprar agora")',
|
|
323
|
+
buyButtonFallback: 'button:has-text("Comprar")',
|
|
324
|
+
minicartText: 'Produtos Adicionados',
|
|
325
|
+
|
|
326
|
+
// Electronics store - voltage selection
|
|
327
|
+
voltages: ['110V', '127V', '220V', 'Bivolt'],
|
|
328
|
+
voltageSelector: (voltage: string) => `button:has-text("${voltage}")`,
|
|
329
|
+
|
|
330
|
+
thresholds: {
|
|
331
|
+
coldTTFB: 5000,
|
|
332
|
+
warmTTFB: 2000,
|
|
333
|
+
homeTTFB: 3000,
|
|
334
|
+
homeWarmTTFB: 1500,
|
|
335
|
+
},
|
|
336
|
+
}
|
|
337
|
+
```
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Scaffold E2E test structure for a Deco site
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# ./scaffold.sh /path/to/site-repo site-name
|
|
7
|
+
#
|
|
8
|
+
# Example:
|
|
9
|
+
# ./scaffold.sh ~/Projects/lojastorra-2 lojastorra-2
|
|
10
|
+
#
|
|
11
|
+
|
|
12
|
+
set -e
|
|
13
|
+
|
|
14
|
+
SITE_PATH="${1:-.}"
|
|
15
|
+
SITE_NAME="${2:-my-site}"
|
|
16
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
17
|
+
TEMPLATES_DIR="$SCRIPT_DIR/templates"
|
|
18
|
+
|
|
19
|
+
echo "🚀 Scaffolding E2E tests for: $SITE_NAME"
|
|
20
|
+
echo " Site path: $SITE_PATH"
|
|
21
|
+
echo " Templates: $TEMPLATES_DIR"
|
|
22
|
+
echo ""
|
|
23
|
+
|
|
24
|
+
# Create directory structure
|
|
25
|
+
E2E_DIR="$SITE_PATH/tests/e2e"
|
|
26
|
+
mkdir -p "$E2E_DIR/specs"
|
|
27
|
+
mkdir -p "$E2E_DIR/utils"
|
|
28
|
+
mkdir -p "$E2E_DIR/reports"
|
|
29
|
+
|
|
30
|
+
# Copy and customize templates
|
|
31
|
+
echo "📁 Creating files..."
|
|
32
|
+
|
|
33
|
+
# package.json
|
|
34
|
+
sed "s/{{SITE_NAME}}/$SITE_NAME/g" "$TEMPLATES_DIR/package.json" > "$E2E_DIR/package.json"
|
|
35
|
+
echo " ✓ package.json"
|
|
36
|
+
|
|
37
|
+
# playwright.config.ts
|
|
38
|
+
sed "s/{{SITE_NAME}}/$SITE_NAME/g" "$TEMPLATES_DIR/playwright.config.ts" > "$E2E_DIR/playwright.config.ts"
|
|
39
|
+
echo " ✓ playwright.config.ts"
|
|
40
|
+
|
|
41
|
+
# tsconfig.json
|
|
42
|
+
cp "$TEMPLATES_DIR/tsconfig.json" "$E2E_DIR/tsconfig.json"
|
|
43
|
+
echo " ✓ tsconfig.json"
|
|
44
|
+
|
|
45
|
+
# Test spec (needs manual customization)
|
|
46
|
+
sed "s/{{SITE_NAME}}/$SITE_NAME/g" "$TEMPLATES_DIR/specs/ecommerce-flow.spec.ts" > "$E2E_DIR/specs/ecommerce-flow.spec.ts"
|
|
47
|
+
echo " ✓ specs/ecommerce-flow.spec.ts"
|
|
48
|
+
|
|
49
|
+
# Metrics collector
|
|
50
|
+
cp "$TEMPLATES_DIR/utils/metrics-collector.ts" "$E2E_DIR/utils/metrics-collector.ts"
|
|
51
|
+
echo " ✓ utils/metrics-collector.ts"
|
|
52
|
+
|
|
53
|
+
# Add reports to .gitignore if not already there
|
|
54
|
+
GITIGNORE="$SITE_PATH/.gitignore"
|
|
55
|
+
if [ -f "$GITIGNORE" ]; then
|
|
56
|
+
if ! grep -q "tests/e2e/reports" "$GITIGNORE"; then
|
|
57
|
+
echo "" >> "$GITIGNORE"
|
|
58
|
+
echo "# E2E test reports" >> "$GITIGNORE"
|
|
59
|
+
echo "tests/e2e/reports/" >> "$GITIGNORE"
|
|
60
|
+
echo " ✓ Updated .gitignore"
|
|
61
|
+
fi
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
echo ""
|
|
65
|
+
echo "✅ Scaffold complete!"
|
|
66
|
+
echo ""
|
|
67
|
+
echo "📋 Next steps:"
|
|
68
|
+
echo " 1. cd $E2E_DIR"
|
|
69
|
+
echo " 2. Open specs/ecommerce-flow.spec.ts"
|
|
70
|
+
echo " 3. Replace {{PLACEHOLDERS}} with your site values:"
|
|
71
|
+
echo " - {{PLP_PATH}}"
|
|
72
|
+
echo " - {{FALLBACK_PDP_PATH}}"
|
|
73
|
+
echo " - {{PRODUCT_CARD_SELECTOR}}"
|
|
74
|
+
echo " - {{BUY_BUTTON_SELECTOR}}"
|
|
75
|
+
echo " - {{MINICART_TEXT}}"
|
|
76
|
+
echo ""
|
|
77
|
+
echo " 4. npm install"
|
|
78
|
+
echo " 5. npx playwright install chromium"
|
|
79
|
+
echo " 6. npm test"
|
|
80
|
+
echo ""
|
|
81
|
+
echo "📖 See discovery.md for how to find each value."
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Platform-Specific Selectors
|
|
2
|
+
|
|
3
|
+
Different e-commerce platforms have different DOM structures. Use these as starting points.
|
|
4
|
+
|
|
5
|
+
## VTEX-based Sites (Most Deco Sites)
|
|
6
|
+
|
|
7
|
+
VTEX is the most common backend for Deco sites in Brazil.
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
const SITE_CONFIG = {
|
|
11
|
+
// Products always show price with R$
|
|
12
|
+
productCard: 'a:has-text("R$")',
|
|
13
|
+
|
|
14
|
+
// PDP URLs end with /p
|
|
15
|
+
pdpUrlPattern: /\/p$/,
|
|
16
|
+
|
|
17
|
+
// Portuguese buy button
|
|
18
|
+
buyButton: 'button:has-text("Comprar")',
|
|
19
|
+
|
|
20
|
+
// Sizes in list items
|
|
21
|
+
sizeButton: (size: string) => `li button:has-text("${size}")`,
|
|
22
|
+
|
|
23
|
+
// Cart drawer header
|
|
24
|
+
minicartText: 'Minha Sacola',
|
|
25
|
+
|
|
26
|
+
// Brazilian sizes
|
|
27
|
+
sizes: ['PP', 'P', 'M', 'G', 'GG', 'G1', 'G2', 'G3'],
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Cart API patterns to wait for:**
|
|
32
|
+
```typescript
|
|
33
|
+
await page.waitForResponse(r =>
|
|
34
|
+
r.url().includes('orderForm') || // VTEX orderForm API
|
|
35
|
+
r.url().includes('/items') // Cart items endpoint
|
|
36
|
+
)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Shopify-based Sites
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
const SITE_CONFIG = {
|
|
45
|
+
productCard: '[data-product-card] a',
|
|
46
|
+
pdpUrlPattern: /\/products\//,
|
|
47
|
+
buyButton: 'button[name="add"]',
|
|
48
|
+
sizeButton: (size: string) => `input[value="${size}"]`,
|
|
49
|
+
minicartText: 'Your Cart',
|
|
50
|
+
sizes: ['XS', 'S', 'M', 'L', 'XL'],
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Cart API patterns:**
|
|
55
|
+
```typescript
|
|
56
|
+
await page.waitForResponse(r =>
|
|
57
|
+
r.url().includes('/cart/add') ||
|
|
58
|
+
r.url().includes('/cart.js')
|
|
59
|
+
)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## VNDA-based Sites
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
const SITE_CONFIG = {
|
|
68
|
+
productCard: '.product-item a',
|
|
69
|
+
pdpUrlPattern: /\/produto\//,
|
|
70
|
+
buyButton: 'button.add-to-cart',
|
|
71
|
+
sizeButton: (size: string) => `.variant-option:has-text("${size}")`,
|
|
72
|
+
minicartText: 'Carrinho',
|
|
73
|
+
sizes: ['P', 'M', 'G', 'GG'],
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Wake Commerce Sites
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
const SITE_CONFIG = {
|
|
83
|
+
productCard: '[data-product] a',
|
|
84
|
+
pdpUrlPattern: /\/p\//,
|
|
85
|
+
buyButton: 'button:has-text("Adicionar")',
|
|
86
|
+
sizeButton: (size: string) => `[data-variant="${size}"]`,
|
|
87
|
+
minicartText: 'Sacola',
|
|
88
|
+
sizes: ['P', 'M', 'G', 'GG'],
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## English Language Sites (US/International)
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
const SITE_CONFIG = {
|
|
98
|
+
productCard: 'a:has-text("$")', // USD currency
|
|
99
|
+
buyButton: 'button:has-text("Add to Cart")',
|
|
100
|
+
minicartText: 'Shopping Bag',
|
|
101
|
+
sizes: ['XS', 'S', 'M', 'L', 'XL', 'XXL'],
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Selector Testing Tips
|
|
108
|
+
|
|
109
|
+
### In Browser DevTools
|
|
110
|
+
|
|
111
|
+
Test your selectors before using them:
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
// Count matching elements
|
|
115
|
+
document.querySelectorAll('a:has-text("R$")').length
|
|
116
|
+
|
|
117
|
+
// Check if element is visible
|
|
118
|
+
document.querySelector('button:has-text("Comprar")')?.offsetParent !== null
|
|
119
|
+
|
|
120
|
+
// Find all size buttons
|
|
121
|
+
document.querySelectorAll('li button').forEach(b => console.log(b.textContent))
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### In Playwright
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// Debug: log all matching elements
|
|
128
|
+
const products = await page.locator('a:has-text("R$")').all()
|
|
129
|
+
console.log(`Found ${products.length} products`)
|
|
130
|
+
|
|
131
|
+
// Debug: take screenshot of element
|
|
132
|
+
await page.locator('button:has-text("Comprar")').screenshot({ path: 'buy-button.png' })
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Fallback Strategies
|
|
138
|
+
|
|
139
|
+
When primary selectors fail:
|
|
140
|
+
|
|
141
|
+
### Product Cards
|
|
142
|
+
```typescript
|
|
143
|
+
// Try multiple patterns
|
|
144
|
+
const selectors = [
|
|
145
|
+
'a:has-text("R$")',
|
|
146
|
+
'[data-product-card]',
|
|
147
|
+
'.product-card a',
|
|
148
|
+
'a[href*="/p"]',
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
for (const sel of selectors) {
|
|
152
|
+
const count = await page.locator(sel).count()
|
|
153
|
+
if (count > 0) {
|
|
154
|
+
console.log(`Using selector: ${sel} (${count} matches)`)
|
|
155
|
+
return sel
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Buy Button
|
|
161
|
+
```typescript
|
|
162
|
+
const buySelectors = [
|
|
163
|
+
'button:has-text("Comprar")',
|
|
164
|
+
'button:has-text("Add to Cart")',
|
|
165
|
+
'button:has-text("Adicionar")',
|
|
166
|
+
'button[data-add-to-cart]',
|
|
167
|
+
'.add-to-cart-button',
|
|
168
|
+
]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Sizes
|
|
172
|
+
```typescript
|
|
173
|
+
// Generic: any button with short text (likely a size)
|
|
174
|
+
const sizeButtons = page.locator('li button').filter({ hasText: /^[A-Z0-9]{1,3}$/ })
|
|
175
|
+
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{SITE_NAME}}-e2e-tests",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "E2E Performance Tests for {{SITE_NAME}}",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "npx playwright test",
|
|
8
|
+
"test:headed": "HEADED=true npx playwright test --headed",
|
|
9
|
+
"test:debug": "npx playwright test --debug",
|
|
10
|
+
"install-browsers": "npx playwright install chromium",
|
|
11
|
+
"baseline:save": "deno run -A scripts/baseline.ts save",
|
|
12
|
+
"baseline:compare": "deno run -A scripts/baseline.ts compare",
|
|
13
|
+
"baseline:list": "deno run -A scripts/baseline.ts list"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@playwright/test": "^1.40.0"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Playwright configuration for E2E Performance Tests
|
|
5
|
+
*
|
|
6
|
+
* Environment variables:
|
|
7
|
+
* SITE_URL - Target URL to test (default: localhost tunnel)
|
|
8
|
+
* HEADED - Set to 'true' for headed mode
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const isHeaded = process.env.HEADED === 'true'
|
|
12
|
+
|
|
13
|
+
export default defineConfig({
|
|
14
|
+
testDir: './specs',
|
|
15
|
+
fullyParallel: false,
|
|
16
|
+
forbidOnly: !!process.env.CI,
|
|
17
|
+
retries: process.env.CI ? 2 : 0,
|
|
18
|
+
workers: 1,
|
|
19
|
+
|
|
20
|
+
timeout: 120_000,
|
|
21
|
+
expect: { timeout: 10_000 },
|
|
22
|
+
|
|
23
|
+
reporter: [
|
|
24
|
+
['list'],
|
|
25
|
+
['html', { open: 'never' }],
|
|
26
|
+
['json', { outputFile: 'reports/results.json' }],
|
|
27
|
+
],
|
|
28
|
+
|
|
29
|
+
use: {
|
|
30
|
+
// REPLACE WITH YOUR SITE URL
|
|
31
|
+
baseURL: process.env.SITE_URL || 'https://localhost--{{SITE_NAME}}.deco.site',
|
|
32
|
+
|
|
33
|
+
trace: 'on-first-retry',
|
|
34
|
+
screenshot: 'only-on-failure',
|
|
35
|
+
video: 'on-first-retry',
|
|
36
|
+
viewport: { width: 1280, height: 720 },
|
|
37
|
+
reducedMotion: 'reduce',
|
|
38
|
+
headless: !isHeaded,
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
projects: [
|
|
42
|
+
{
|
|
43
|
+
name: 'desktop-chrome',
|
|
44
|
+
use: {
|
|
45
|
+
...devices['Desktop Chrome'],
|
|
46
|
+
launchOptions: {
|
|
47
|
+
args: ['--enable-precise-memory-info'],
|
|
48
|
+
slowMo: isHeaded ? 100 : 0,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'mobile-chrome',
|
|
54
|
+
use: {
|
|
55
|
+
...devices['Pixel 5'],
|
|
56
|
+
launchOptions: {
|
|
57
|
+
args: ['--enable-precise-memory-info'],
|
|
58
|
+
slowMo: isHeaded ? 100 : 0,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
|
|
64
|
+
outputDir: './reports/test-results/',
|
|
65
|
+
})
|