@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,165 @@
1
+ # How a Deco Site Uses the Framework
2
+
3
+ Reference based on `deco-sites/osklenbr`, a production VTEX storefront using Fresh/Preact.
4
+
5
+ ## Site Structure
6
+
7
+ ```
8
+ osklenbr/
9
+ |-- deno.json # Dependencies, tasks, import map
10
+ |-- fresh.config.ts # Fresh + Deco plugin registration
11
+ |-- manifest.gen.ts # Auto-generated manifest (site blocks)
12
+ |-- fresh.gen.ts # Auto-generated Fresh manifest (routes + islands)
13
+ |-- runtime.ts # Typed invoke client
14
+ |-- main.ts # Production entry: start(manifest, config)
15
+ |-- dev.ts # Dev entry: tailwind build + dotenv + Fresh dev
16
+ |
17
+ |-- apps/ # App registrations (site.ts, decohub.ts)
18
+ |-- sections/ # 117 UI sections (Preact components)
19
+ |-- islands/ # 99 interactive islands (Preact)
20
+ |-- loaders/ # 13 site-specific loaders
21
+ |-- actions/ # 4 site-specific actions
22
+ |-- routes/ # 2 routes (_app.tsx, proxy.ts)
23
+ |-- sdk/ # Client-side utilities
24
+ |-- components/ # Shared Preact components
25
+ |-- static/ # Static assets
26
+ ```
27
+
28
+ ## Configuration
29
+
30
+ ### deno.json
31
+
32
+ Key imports: `$fresh/` (Fresh 1.7.3), `@deco/deco` (1.174.2), `apps/` (deco-cx/apps 0.139.0), `$store/` and `site/` (self-reference).
33
+
34
+ Tasks: `start` (production via deco.cx/run), `dev` (generate + Fresh dev), `gen` (manifest generation).
35
+
36
+ JSX: `react-jsx` with `preact` import source.
37
+
38
+ ### fresh.config.ts
39
+
40
+ ```typescript
41
+ import { defineConfig } from "$fresh/server.ts";
42
+ import { plugins } from "deco/plugins/deco.ts";
43
+ import manifest from "./manifest.gen.ts";
44
+
45
+ export default defineConfig({
46
+ plugins: plugins({ manifest, htmx: false }),
47
+ });
48
+ ```
49
+
50
+ ### runtime.ts
51
+
52
+ ```typescript
53
+ import { proxy } from "@deco/deco/web";
54
+ import type { Manifest } from "./manifest.gen.ts";
55
+ import type { Manifest as VTEXManifest } from "apps/vtex/manifest.gen.ts";
56
+
57
+ export const invoke = proxy<Manifest & VTEXManifest>();
58
+ ```
59
+
60
+ ## App Registration (`apps/`)
61
+
62
+ ### apps/site.ts
63
+
64
+ ```typescript
65
+ import manifest, { Manifest } from "../manifest.gen.ts";
66
+ import { type App, type AppContext as AC } from "@deco/deco";
67
+ import commerce from "apps/commerce/mod.ts";
68
+ import std from "apps/compat/std/mod.ts";
69
+
70
+ export type AppContext = AC<ReturnType<typeof Site>>;
71
+
72
+ export default function Site(state: Props): App<
73
+ Manifest, Props, [typeof std, ReturnType<typeof commerce>]
74
+ > {
75
+ return {
76
+ state,
77
+ manifest,
78
+ dependencies: [std(state), commerce(state)],
79
+ };
80
+ }
81
+ ```
82
+
83
+ Key pattern: site app bundles manifest + commerce dependencies. `AppContext` enables typed `ctx.invoke()`.
84
+
85
+ ### apps/decohub.ts
86
+
87
+ ```typescript
88
+ export { default, Preview } from "apps/decohub/mod.ts";
89
+ ```
90
+
91
+ ## Execution Flow
92
+
93
+ ### Production
94
+ ```
95
+ main.ts -> fresh.gen.ts + fresh.config.ts -> start(manifest, config)
96
+ -> Fresh server starts
97
+ -> Deco plugin initializes
98
+ -> Loads DecofileProvider (CMS state)
99
+ -> Installs apps (site -> commerce -> vtex)
100
+ -> Registers all block resolvers
101
+ -> Mounts routes + middleware
102
+ ```
103
+
104
+ ### Dev
105
+ ```
106
+ dev.ts -> Build Tailwind -> Load .env -> Fresh dev server -> Generate manifest -> Hot reload
107
+ ```
108
+
109
+ ## Manifest System
110
+
111
+ ### manifest.gen.ts (Deco)
112
+
113
+ Contains loaders (13), sections (117), actions (4), matchers (1), apps (2). Keys formatted as `site/loaders/...`, `site/sections/...`.
114
+
115
+ ### fresh.gen.ts (Fresh)
116
+
117
+ Contains routes (2) and islands (99). Generated by Fresh from the Deco plugin.
118
+
119
+ ## Loader/Action Patterns
120
+
121
+ ### Site Loader
122
+
123
+ ```typescript
124
+ import { AppContext } from "site/apps/site.ts";
125
+
126
+ export default async function loader(
127
+ props: Props,
128
+ _req: Request,
129
+ ctx: AppContext,
130
+ ): Promise<Store[]> {
131
+ // fetch data, transform, return
132
+ }
133
+ ```
134
+
135
+ ### Invoking Other Apps
136
+
137
+ ```typescript
138
+ export default async function loader(props: Props, _req: Request, ctx: AppContext) {
139
+ const products = await ctx.invoke(
140
+ "vtex/loaders/intelligentSearch/productListingPage.ts",
141
+ { query: props.query, count: 12 },
142
+ );
143
+ return products;
144
+ }
145
+ ```
146
+
147
+ ## Routes
148
+
149
+ `_app.tsx` is the global layout. Page routes are NOT file-based; they come from the CMS admin decofile.
150
+
151
+ ## Migration Patterns for TanStack
152
+
153
+ | Fresh/Deco Pattern | TanStack Equivalent |
154
+ |--------------------|---------------------|
155
+ | `manifest.gen.ts` | Explicit exports from `@decocms/apps-start` |
156
+ | `runtime.ts` invoke proxy | Direct function imports + React Query |
157
+ | Islands | Regular React components |
158
+ | Fresh `<Partial>` | TanStack Router navigation |
159
+ | `useSection()` partial render | React state + React Query invalidation |
160
+ | `ctx.invoke("key", props)` | Direct function call: `loaderFn(props)` |
161
+ | `AppContext` | `configureVtex()` + env vars |
162
+ | Deco plugin | TanStack Start entry + `@decocms/start` |
163
+ | DecofileProvider | Admin API from `@decocms/start` |
164
+ | `@preact/signals` | `@tanstack/react-store` or React state |
165
+ | `Deno.env.get()` | `process.env` or `import.meta.env` |
@@ -0,0 +1,372 @@
1
+ ---
2
+ name: deco-e2e-testing
3
+ description: Implement end-to-end performance tests for any Deco e-commerce site with lazy section tracking, cache analysis, and observability. Use this skill when asked to set up e2e tests, create performance testing infrastructure, or test user journeys on a Deco/VTEX site.
4
+ ---
5
+
6
+ # Deco E2E Performance Testing Skill
7
+
8
+ This skill helps you implement comprehensive e2e performance tests for Deco e-commerce sites. It covers the full user journey: Home → PLP → PDP → Add to Cart, with **lazy section tracking**, **cache analysis**, and **device-specific reports**.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Setting up e2e tests from scratch on a Deco site
13
+ - Creating performance testing infrastructure
14
+ - Testing cache performance (cold vs warm)
15
+ - Validating TTFB, FCP, and other Core Web Vitals
16
+ - **Debugging slow lazy sections** (`/deco/render` requests)
17
+ - **Analyzing page cache and CDN behavior**
18
+ - **Comparing performance across desktop/mobile**
19
+
20
+ ## Quick Start
21
+
22
+ 1. **Discover site-specific values** (read `discovery.md`)
23
+ 2. **Run scaffold script** or copy templates manually
24
+ 3. **Configure selectors** for your site
25
+ 4. **Add deno.json tasks** for easy test execution
26
+ 5. **Run tests** and verify
27
+
28
+ ## Workflow
29
+
30
+ ```
31
+ 1. Read discovery.md → Find site-specific selectors
32
+ 2. Run scaffold.sh → Create test directory structure
33
+ 3. Replace {{PLACEHOLDERS}} → Customize for site
34
+ 4. Add deno.json tasks → Enable `deno task test:e2e`
35
+ 5. npm install && deno task test:e2e → Verify tests work
36
+ ```
37
+
38
+ ## Directory Structure to Create
39
+
40
+ ```
41
+ tests/e2e/
42
+ ├── README.md
43
+ ├── package.json
44
+ ├── playwright.config.ts
45
+ ├── tsconfig.json
46
+ ├── specs/
47
+ │ └── ecommerce-flow.spec.ts
48
+ ├── utils/
49
+ │ └── metrics-collector.ts
50
+ ├── scripts/
51
+ │ └── baseline.ts
52
+ └── reports/ # gitignored
53
+ ├── report-desktop-chrome.json
54
+ ├── report-mobile-chrome.json
55
+ └── baselines/
56
+
57
+ scripts/
58
+ └── run-e2e.ts # Test runner with server management
59
+ ```
60
+
61
+ ## Test Flow
62
+
63
+ | Step | Page | Metrics |
64
+ |------|------|---------|
65
+ | 1 | Server Warmup | Liveness check, lazy import trigger |
66
+ | 2 | Homepage (cold cache) | TTFB, FCP, lazy sections, scroll |
67
+ | 3 | Homepage (warm cache) | Cache improvement |
68
+ | 4 | PLP (cold cache) | TTFB, products loaded, lazy sections |
69
+ | 5 | PLP (warm cache) | Cache improvement |
70
+ | 6 | PDP (cold cache) | TTFB, buy button, lazy sections |
71
+ | 7 | PDP (warm cache) | Cache improvement |
72
+ | 8 | Add to Cart | Response time |
73
+ | 9 | Minicart | Verification (with retry) |
74
+
75
+ ## Key Features
76
+
77
+ ### 1. Lazy Section Tracking
78
+
79
+ The test tracks all `/deco/render` requests (lazy-loaded sections) with:
80
+ - **Section name** extracted from `x-deco-section` header
81
+ - **Timing** with color-coded status (🟢 fast, 🟡 medium, 🔴 slow)
82
+ - **Cache status** (💾 HIT, ❌ MISS, ⏳ STALE)
83
+
84
+ ```
85
+ 🔄 Lazy Sections (14):
86
+ ┌───────────────────────────────────────────────────────────
87
+ │ 🔴 Product/ProductShelf: L... 1182ms 💾 cached
88
+ │ 🔴 Product/ProductShelfGroup 1000ms 💾 cached
89
+ │ 🟢 Footer/Footer 13ms 💾 cached
90
+ └───────────────────────────────────────────────────────────
91
+ 📊 Summary: 5 fast, 2 medium, 7 slow │ Total: 7121ms
92
+ ```
93
+
94
+ ### 2. Scroll-Based Lazy Loading
95
+
96
+ The test scrolls the page to trigger lazy sections and waits for them:
97
+
98
+ ```typescript
99
+ // Scroll until footer is visible, waiting for pending renders
100
+ await collector.scrollPage(page, true) // full=true for homepage
101
+ ```
102
+
103
+ This ensures all lazy sections are triggered and their performance is measured.
104
+
105
+ ### 3. Device-Specific Reports
106
+
107
+ Tests run on both desktop and mobile with separate reports:
108
+
109
+ ```
110
+ reports/
111
+ ├── report-desktop-chrome.json
112
+ ├── report-mobile-chrome.json
113
+ ├── report-latest-desktop.json
114
+ └── report-latest-mobile.json
115
+ ```
116
+
117
+ ### 4. Enhanced Report Structure
118
+
119
+ Reports include a summary for easy comparison:
120
+
121
+ ```json
122
+ {
123
+ "project": "desktop-chrome",
124
+ "timestamp": "2026-01-18T...",
125
+ "summary": {
126
+ "totalPages": 7,
127
+ "avgTTFB": 485,
128
+ "avgFCP": 892,
129
+ "totalLazyRenders": 32,
130
+ "totalLoaders": 12,
131
+ "cacheHits": 28,
132
+ "cacheMisses": 4,
133
+ "pages": [...]
134
+ },
135
+ "metrics": [...]
136
+ }
137
+ ```
138
+
139
+ ### 5. Deco Observability Headers
140
+
141
+ The test captures custom Deco headers for debugging:
142
+ - `x-deco-section` - Section component type and title
143
+ - `x-deco-page` - Matched page block name
144
+ - `x-deco-route` - Matched route template
145
+
146
+ ## Critical: Server Warmup
147
+
148
+ **Deco/Fresh lazily loads imports on first request.** This causes artificially high latency for the first request after server start. The test must:
149
+
150
+ 1. Wait for `/deco/_liveness` endpoint to return 200
151
+ 2. Make a warmup request to trigger lazy imports
152
+ 3. Only then start measuring performance
153
+
154
+ ```typescript
155
+ const LIVENESS_PATH = '/deco/_liveness'
156
+
157
+ async function waitForServerReady(baseUrl: string) {
158
+ // Step 1: Wait for liveness
159
+ for (let i = 0; i < 30; i++) {
160
+ const res = await fetch(`${baseUrl}/deco/_liveness`)
161
+ if (res.ok) break
162
+ await new Promise(r => setTimeout(r, 1000))
163
+ }
164
+
165
+ // Step 2: Warmup request to trigger lazy imports
166
+ await fetch(`${baseUrl}/?__d`)
167
+ }
168
+ ```
169
+
170
+ ## Key Configuration
171
+
172
+ The `SITE_CONFIG` object centralizes all site-specific values:
173
+
174
+ ```typescript
175
+ const SITE_CONFIG = {
176
+ // URLs
177
+ baseUrl: 'https://localhost--{sitename}.deco.site',
178
+ plpPath: '/category-path',
179
+ fallbackPdpPath: '/product-name-sku/p',
180
+
181
+ // Always use ?__d for Server-Timing headers
182
+ debugParam: '?__d',
183
+
184
+ // Deco framework endpoints
185
+ livenessPath: '/deco/_liveness',
186
+
187
+ // Selectors
188
+ productCard: '[data-deco="view-product"]',
189
+ productCardFallback: 'a:has-text("R$")',
190
+ buyButton: 'button:has-text("Comprar agora")',
191
+ buyButtonFallback: 'button:has-text("Comprar")',
192
+ minicartText: 'Produtos Adicionados',
193
+
194
+ // Sizes (fashion) or voltages (electronics)
195
+ sizes: ['P', 'M', 'G', 'GG'],
196
+ voltages: ['110V', '127V', '220V', 'Bivolt'],
197
+
198
+ // Thresholds (ms)
199
+ thresholds: {
200
+ coldTTFB: 5000,
201
+ warmTTFB: 2000,
202
+ homeTTFB: 3000,
203
+ homeWarmTTFB: 1500,
204
+ },
205
+
206
+ // Server warmup settings
207
+ warmup: {
208
+ livenessRetries: 30,
209
+ livenessRetryDelay: 1000,
210
+ warmupTimeout: 60000,
211
+ },
212
+ }
213
+ ```
214
+
215
+ ## deno.json Integration
216
+
217
+ Add these tasks to the site's `deno.json`:
218
+
219
+ ```json
220
+ {
221
+ "tasks": {
222
+ "test:e2e": "deno run -A scripts/run-e2e.ts",
223
+ "test:e2e:headed": "deno run -A scripts/run-e2e.ts --headed",
224
+ "test:e2e:install": "cd tests/e2e && npm install && npx playwright install chromium",
225
+ "test:e2e:baseline:save": "deno run -A tests/e2e/scripts/baseline.ts save",
226
+ "test:e2e:baseline:compare": "deno run -A tests/e2e/scripts/baseline.ts compare"
227
+ }
228
+ }
229
+ ```
230
+
231
+ ## .gitignore Updates
232
+
233
+ Add to `.gitignore`:
234
+
235
+ ```gitignore
236
+ # E2E test reports (generated artifacts)
237
+ tests/e2e/reports/report-*.json
238
+ tests/e2e/reports/test-results/
239
+ tests/e2e/reports/results.json
240
+ ```
241
+
242
+ ## Files in This Skill
243
+
244
+ | File | Purpose |
245
+ |------|---------|
246
+ | `SKILL.md` | This overview |
247
+ | `discovery.md` | How to find site-specific values |
248
+ | `templates/` | Ready-to-use test files |
249
+ | `templates/scripts/run-e2e.ts` | Test runner with server management |
250
+ | `templates/scripts/baseline.ts` | Baseline save/compare script |
251
+ | `selectors.md` | Platform-specific selector patterns |
252
+ | `troubleshooting.md` | Common issues and fixes |
253
+ | `scripts/scaffold.sh` | Auto-create test structure |
254
+
255
+ ## Expected Output
256
+
257
+ ```
258
+ ══════════════════════════════════════════════════════════════════════
259
+ 🖥️ Desktop (desktop-chrome)
260
+ ══════════════════════════════════════════════════════════════════════
261
+
262
+ ══════════════════════════════════════════════════════════════════════
263
+ 🏠 HOMEPAGE (cold cache)
264
+ ══════════════════════════════════════════════════════════════════════
265
+ 📜 Scrolling to trigger lazy renders (full)...
266
+ ⏳ Waiting for 1 pending render before next scroll...
267
+ ✅ Footer visible after 47 scrolls
268
+ 📜 Triggered 13 lazy renders
269
+
270
+ 🟢 TTFB: 414ms 🟡 FCP: 1508ms │ 🌐 369 requests (11.7 MB)
271
+
272
+ ⚡ Server Timing: 0ms total (1 loaders)
273
+
274
+ 🔄 Lazy Sections (14):
275
+ ┌───────────────────────────────────────────────────────────
276
+ │ 🔴 Product/ProductShelf: L... 1182ms 💾 cached
277
+ │ 🔴 Product/ProductShelfGroup 1000ms 💾 cached
278
+ │ 🟢 Content/SimpleText 18ms 💾 cached
279
+ │ 🟢 Footer/Footer 13ms 💾 cached
280
+ └───────────────────────────────────────────────────────────
281
+ 📊 Summary: 5 fast, 2 medium, 7 slow │ Total: 7121ms
282
+
283
+ ══════════════════════════════════════════════════════════════════════
284
+ 📊 PERFORMANCE SUMMARY
285
+ ══════════════════════════════════════════════════════════════════════
286
+
287
+ ┌──────────────────┬─────────────┬─────────────┬────────┐
288
+ │ Page │ TTFB │ FCP │ Lazy │
289
+ ├──────────────────┼─────────────┼─────────────┼────────┤
290
+ │ Homepage Cold │ 🟢 414ms │ 🟡 1508ms │ 14 │
291
+ │ Homepage Warm │ 🟢 485ms │ 🟢 560ms │ 4 │
292
+ │ PLP Cold │ 🟢 456ms │ 🟢 508ms │ 3 │
293
+ │ PDP Cold │ 🟢 459ms │ 🟢 520ms │ 4 │
294
+ └──────────────────┴─────────────┴─────────────┴────────┘
295
+
296
+ Legend: 🟢 Good 🟡 Needs Work 🔴 Poor
297
+ Thresholds: TTFB <500ms good, <800ms ok | FCP <1000ms good, <1800ms ok
298
+ ```
299
+
300
+ ## Baseline Comparison
301
+
302
+ Save performance baselines and compare future runs to detect regressions.
303
+
304
+ ### Save a Baseline
305
+
306
+ ```bash
307
+ deno task test:e2e:baseline:save
308
+ ```
309
+
310
+ ### Compare Against Baseline
311
+
312
+ ```bash
313
+ deno task test:e2e:baseline:compare
314
+ ```
315
+
316
+ ### Regression Thresholds
317
+
318
+ | Metric | Threshold |
319
+ |--------|-----------|
320
+ | TTFB | +10% |
321
+ | FCP | +10% |
322
+ | LCP | +15% |
323
+ | CLS | +50% |
324
+
325
+ ## Minicart Robustness
326
+
327
+ The minicart verification uses multiple selectors and retry logic:
328
+
329
+ ```typescript
330
+ async isMinicartOpen(): Promise<boolean> {
331
+ const selectors = [
332
+ `text=${SITE_CONFIG.minicartText}`,
333
+ '[data-testid="minicart"]',
334
+ '.minicart',
335
+ '[class*="minicart"]',
336
+ '[class*="cart-drawer"]',
337
+ ]
338
+
339
+ // Retry with increasing timeout
340
+ for (let attempt = 0; attempt < 3; attempt++) {
341
+ const timeout = 2000 + (attempt * 1000)
342
+ for (const selector of selectors) {
343
+ const visible = await this.page.locator(selector).first()
344
+ .isVisible({ timeout }).catch(() => false)
345
+ if (visible) return true
346
+ }
347
+ await this.page.waitForTimeout(500)
348
+ }
349
+ return false
350
+ }
351
+ ```
352
+
353
+ ## Integration with Deco Runtime
354
+
355
+ For full lazy section observability, ensure your deco runtime includes:
356
+
357
+ 1. **x-deco-section header** in `/deco/render` responses
358
+ 2. **x-deco-page header** with matched page block name
359
+ 3. **x-deco-route header** with matched route template
360
+
361
+ These are set in:
362
+ - `deco/runtime/features/render.tsx` - Section name extraction
363
+ - `deco/runtime/routes/render.tsx` - Header setting
364
+ - `deco/runtime/middleware.ts` - Page/route headers
365
+ - `apps/website/handlers/fresh.ts` - Page block state
366
+
367
+ ## Next Steps
368
+
369
+ 1. Read `discovery.md` to learn how to find the correct selectors and paths
370
+ 2. Check `selectors.md` for platform-specific patterns (VTEX, Shopify, VNDA)
371
+ 3. See `troubleshooting.md` if tests fail
372
+ 4. Use the MCP tools to search for related optimization patterns