deco-e2e-testing

Deco E2E Performance Testing Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "deco-e2e-testing" with this command: npx skills add decocms/deco-start/decocms-deco-start-deco-e2e-testing

Deco E2E Performance Testing Skill

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.

When to Use This Skill

  • Setting up e2e tests from scratch on a Deco site

  • Creating performance testing infrastructure

  • Testing cache performance (cold vs warm)

  • Validating TTFB, FCP, and other Core Web Vitals

  • Debugging slow lazy sections (/deco/render requests)

  • Analyzing page cache and CDN behavior

  • Comparing performance across desktop/mobile

Quick Start

  • Discover site-specific values (read discovery.md )

  • Run scaffold script or copy templates manually

  • Configure selectors for your site

  • Add deno.json tasks for easy test execution

  • Run tests and verify

Workflow

  1. Read discovery.md → Find site-specific selectors
  2. Run scaffold.sh → Create test directory structure
  3. Replace {{PLACEHOLDERS}} → Customize for site
  4. Add deno.json tasks → Enable deno task test:e2e
  5. npm install && deno task test:e2e → Verify tests work

Directory Structure to Create

tests/e2e/ ├── README.md ├── package.json ├── playwright.config.ts ├── tsconfig.json ├── specs/ │ └── ecommerce-flow.spec.ts ├── utils/ │ └── metrics-collector.ts ├── scripts/ │ └── baseline.ts └── reports/ # gitignored ├── report-desktop-chrome.json ├── report-mobile-chrome.json └── baselines/

scripts/ └── run-e2e.ts # Test runner with server management

Test Flow

Step Page Metrics

1 Server Warmup Liveness check, lazy import trigger

2 Homepage (cold cache) TTFB, FCP, lazy sections, scroll

3 Homepage (warm cache) Cache improvement

4 PLP (cold cache) TTFB, products loaded, lazy sections

5 PLP (warm cache) Cache improvement

6 PDP (cold cache) TTFB, buy button, lazy sections

7 PDP (warm cache) Cache improvement

8 Add to Cart Response time

9 Minicart Verification (with retry)

Key Features

  1. Lazy Section Tracking

The test tracks all /deco/render requests (lazy-loaded sections) with:

  • Section name extracted from x-deco-section header

  • Timing with color-coded status (🟢 fast, 🟡 medium, 🔴 slow)

  • Cache status (💾 HIT, ❌ MISS, ⏳ STALE)

🔄 Lazy Sections (14): ┌─────────────────────────────────────────────────────────── │ 🔴 Product/ProductShelf: L... 1182ms 💾 cached │ 🔴 Product/ProductShelfGroup 1000ms 💾 cached │ 🟢 Footer/Footer 13ms 💾 cached └─────────────────────────────────────────────────────────── 📊 Summary: 5 fast, 2 medium, 7 slow │ Total: 7121ms

  1. Scroll-Based Lazy Loading

The test scrolls the page to trigger lazy sections and waits for them:

// Scroll until footer is visible, waiting for pending renders await collector.scrollPage(page, true) // full=true for homepage

This ensures all lazy sections are triggered and their performance is measured.

  1. Device-Specific Reports

Tests run on both desktop and mobile with separate reports:

reports/ ├── report-desktop-chrome.json ├── report-mobile-chrome.json ├── report-latest-desktop.json └── report-latest-mobile.json

  1. Enhanced Report Structure

Reports include a summary for easy comparison:

{ "project": "desktop-chrome", "timestamp": "2026-01-18T...", "summary": { "totalPages": 7, "avgTTFB": 485, "avgFCP": 892, "totalLazyRenders": 32, "totalLoaders": 12, "cacheHits": 28, "cacheMisses": 4, "pages": [...] }, "metrics": [...] }

  1. Deco Observability Headers

The test captures custom Deco headers for debugging:

  • x-deco-section

  • Section component type and title

  • x-deco-page

  • Matched page block name

  • x-deco-route

  • Matched route template

Critical: Server Warmup

Deco/Fresh lazily loads imports on first request. This causes artificially high latency for the first request after server start. The test must:

  • Wait for /deco/_liveness endpoint to return 200

  • Make a warmup request to trigger lazy imports

  • Only then start measuring performance

const LIVENESS_PATH = '/deco/_liveness'

async function waitForServerReady(baseUrl: string) { // Step 1: Wait for liveness for (let i = 0; i < 30; i++) { const res = await fetch(${baseUrl}/deco/_liveness) if (res.ok) break await new Promise(r => setTimeout(r, 1000)) }

// Step 2: Warmup request to trigger lazy imports
await fetch(`${baseUrl}/?__d`)

}

Key Configuration

The SITE_CONFIG object centralizes all site-specific values:

const SITE_CONFIG = { // URLs baseUrl: 'https://localhost--{sitename}.deco.site', plpPath: '/category-path', fallbackPdpPath: '/product-name-sku/p',

// Always use ?__d for Server-Timing headers
debugParam: '?__d',

// Deco framework endpoints
livenessPath: '/deco/_liveness',

// Selectors
productCard: '[data-deco="view-product"]',
productCardFallback: 'a:has-text("R$")',
buyButton: 'button:has-text("Comprar agora")',
buyButtonFallback: 'button:has-text("Comprar")',
minicartText: 'Produtos Adicionados',

// Sizes (fashion) or voltages (electronics)
sizes: ['P', 'M', 'G', 'GG'],
voltages: ['110V', '127V', '220V', 'Bivolt'],

// Thresholds (ms)
thresholds: {
    coldTTFB: 5000,
    warmTTFB: 2000,
    homeTTFB: 3000,
    homeWarmTTFB: 1500,
},

// Server warmup settings
warmup: {
    livenessRetries: 30,
    livenessRetryDelay: 1000,
    warmupTimeout: 60000,
},

}

deno.json Integration

Add these tasks to the site's deno.json :

{ "tasks": { "test:e2e": "deno run -A scripts/run-e2e.ts", "test:e2e:headed": "deno run -A scripts/run-e2e.ts --headed", "test:e2e:install": "cd tests/e2e && npm install && npx playwright install chromium", "test:e2e:baseline:save": "deno run -A tests/e2e/scripts/baseline.ts save", "test:e2e:baseline:compare": "deno run -A tests/e2e/scripts/baseline.ts compare" } }

.gitignore Updates

Add to .gitignore :

E2E test reports (generated artifacts)

tests/e2e/reports/report-*.json tests/e2e/reports/test-results/ tests/e2e/reports/results.json

Files in This Skill

File Purpose

SKILL.md

This overview

discovery.md

How to find site-specific values

templates/

Ready-to-use test files

templates/scripts/run-e2e.ts

Test runner with server management

templates/scripts/baseline.ts

Baseline save/compare script

selectors.md

Platform-specific selector patterns

troubleshooting.md

Common issues and fixes

scripts/scaffold.sh

Auto-create test structure

Expected Output

══════════════════════════════════════════════════════════════════════ 🖥️ Desktop (desktop-chrome) ══════════════════════════════════════════════════════════════════════

══════════════════════════════════════════════════════════════════════ 🏠 HOMEPAGE (cold cache) ══════════════════════════════════════════════════════════════════════ 📜 Scrolling to trigger lazy renders (full)... ⏳ Waiting for 1 pending render before next scroll... ✅ Footer visible after 47 scrolls 📜 Triggered 13 lazy renders

🟢 TTFB: 414ms 🟡 FCP: 1508ms │ 🌐 369 requests (11.7 MB)

⚡ Server Timing: 0ms total (1 loaders)

🔄 Lazy Sections (14): ┌─────────────────────────────────────────────────────────── │ 🔴 Product/ProductShelf: L... 1182ms 💾 cached │ 🔴 Product/ProductShelfGroup 1000ms 💾 cached │ 🟢 Content/SimpleText 18ms 💾 cached │ 🟢 Footer/Footer 13ms 💾 cached └─────────────────────────────────────────────────────────── 📊 Summary: 5 fast, 2 medium, 7 slow │ Total: 7121ms

══════════════════════════════════════════════════════════════════════ 📊 PERFORMANCE SUMMARY ══════════════════════════════════════════════════════════════════════

┌──────────────────┬─────────────┬─────────────┬────────┐ │ Page │ TTFB │ FCP │ Lazy │ ├──────────────────┼─────────────┼─────────────┼────────┤ │ Homepage Cold │ 🟢 414ms │ 🟡 1508ms │ 14 │ │ Homepage Warm │ 🟢 485ms │ 🟢 560ms │ 4 │ │ PLP Cold │ 🟢 456ms │ 🟢 508ms │ 3 │ │ PDP Cold │ 🟢 459ms │ 🟢 520ms │ 4 │ └──────────────────┴─────────────┴─────────────┴────────┘

Legend: 🟢 Good 🟡 Needs Work 🔴 Poor Thresholds: TTFB <500ms good, <800ms ok | FCP <1000ms good, <1800ms ok

Baseline Comparison

Save performance baselines and compare future runs to detect regressions.

Save a Baseline

deno task test:e2e:baseline:save

Compare Against Baseline

deno task test:e2e:baseline:compare

Regression Thresholds

Metric Threshold

TTFB +10%

FCP +10%

LCP +15%

CLS +50%

Minicart Robustness

The minicart verification uses multiple selectors and retry logic:

async isMinicartOpen(): Promise<boolean> { const selectors = [ text=${SITE_CONFIG.minicartText}, '[data-testid="minicart"]', '.minicart', '[class*="minicart"]', '[class*="cart-drawer"]', ]

// Retry with increasing timeout
for (let attempt = 0; attempt &#x3C; 3; attempt++) {
    const timeout = 2000 + (attempt * 1000)
    for (const selector of selectors) {
        const visible = await this.page.locator(selector).first()
            .isVisible({ timeout }).catch(() => false)
        if (visible) return true
    }
    await this.page.waitForTimeout(500)
}
return false

}

Integration with Deco Runtime

For full lazy section observability, ensure your deco runtime includes:

  • x-deco-section header in /deco/render responses

  • x-deco-page header with matched page block name

  • x-deco-route header with matched route template

These are set in:

  • deco/runtime/features/render.tsx

  • Section name extraction

  • deco/runtime/routes/render.tsx

  • Header setting

  • deco/runtime/middleware.ts

  • Page/route headers

  • apps/website/handlers/fresh.ts

  • Page block state

Next Steps

  • Read discovery.md to learn how to find the correct selectors and paths

  • Check selectors.md for platform-specific patterns (VTEX, Shopify, VNDA)

  • See troubleshooting.md if tests fail

  • Use the MCP tools to search for related optimization patterns

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

deco-storefront-test-checklist

No summary provided by upstream source.

Repository SourceNeeds Review
General

deco-tanstack-search

No summary provided by upstream source.

Repository SourceNeeds Review
General

deco-site-memory-debugging

No summary provided by upstream source.

Repository SourceNeeds Review
General

deco-tanstack-navigation

No summary provided by upstream source.

Repository SourceNeeds Review