Skip to content
datalayer-analytics-playwright logo

DataLayer Analytics — Playwright

datalayer-analytics-playwright

Automated window.dataLayer analytics validation for GTM/GA4. Creates test suites from tracking specs or discovers events from live pages using Playwright codegen and dataLayer capture. Supports standard Playwright and BDD modes. Use when creating, running, capturing, or debugging GTM/GA4 tracking...

mbatra5/skills0installs0stars

SKILL.md

Full skill instructions

DataLayer Analytics — Playwright

Automated window.dataLayer event validation using Playwright. Creates, runs, and maintains analytics tracking tests so you never ship broken tracking again.

When to Use

  • Validate GTM / GA4 events fire correctly with the right payloads
  • Create analytics regression tests from a tracking spec (Confluence, Notion, or manual)
  • Discover what events a page actually fires (no spec needed)
  • Debug mismatches between expected and actual dataLayer payloads
  • Maintain test data as tracking implementations evolve

Two Test Modes

Auto-detected based on your project setup:

ModeFiles per ComponentDetection
Standard Playwright3 (JSON + spec + page object)Default
BDD (playwright-bdd)4 (JSON + feature + steps + page object)playwright-bdd in package.json or .feature files present

Both modes share the same JSON format, page objects, and DataLayer utilities.

Supported Events

EventFires When
element_visibilityComponent scrolls into view
cta_clickUser clicks a CTA / button / link
form_interactionUser interacts with form fields
form_submitForm is submitted
generate_leadLead generation conversion (GA4)
select_contentUser selects content (GA4)
add_to_cartItem added to cart (GA4 ecommerce)
purchaseTransaction completed (GA4 ecommerce)
Any custom eventYour tracking fires it

What You Can Say to Your Agent

"Create dataLayer tests for the hero component using this Confluence spec: https://wiki.example.com/pages/12345"

"Create analytics tests for the newsletter signup — no spec, discover the events from the live page"

"Discover the events for the nav menu by recording my clicks with codegen, then capture the payloads"

"Create dataLayer tests for the checkout button. It fires cta_click with click_text='Buy Now', click_url='/​checkout', component_name='Checkout CTA'"

"Run the analytics tests for the button component and show me what's different"

"The cta_click changes look correct — update the JSON with those actuals"

"Don't update — the actual looks wrong, this might be a tracking bug"

"Add an element_visibility event to the button component tests"

"The button test is failing because the locator changed — inspect the live DOM and update the page object"

"Show me everything in the dataLayer on the checkout page"

Workflow Modes

ModeWhenWhat Happens
Full"Create tests for X using this spec"Create files → run → extract → compare → wait for approval → update → verify
Discovery"Create tests for X — no spec"Infer events → skeleton JSON → run → extract → compare → wait → fill
Deferred"Create test files for X — don't run"Create files from spec only. Execute later.
Debug"Run the tests for X and show me diffs"Run → extract → compare. No update unless asked.

Assertion Strategy

AssertionBDD StepClears?Context
First-match + clearcontain expected "{key}" eventYesStorybook (isolated components)
Component-aware matchcontain a matching "{key}" eventNoApp tests (multi-component pages)
Component-aware + clearcontain a matching "{key}" event and clearYesApp interaction events

Storybook: Default to first-match + clear. App tests: Always use findMatchingDataLayerEvent — extracts event + parameters.content.name from expected JSON to locate the correct component's event, then toMatchObject provides field diffs. See references/​assertion-strategy.md for details.

Critical Rules

  1. Capture ALL properties from actual events. Only exclude gtm.uniqueEventId.
  2. Never remove properties to fix flaky tests. Make dynamic values deterministic via URL args.
  3. Never modify analytics-common-step.ts, analytics-logger.ts, or analytics-helpers.ts. New utility methods may be added to datalayer-util.ts but existing methods must not be altered.
  4. Use toMatchObject() for assertions. toEqual() is banned.
  5. Never auto-update JSON — always present comparison and wait for user approval.
  6. Only fetch tracking specs from URLs explicitly provided by the user. Always display extracted event names for user approval before creating files.
  7. One attempt per fix. After a failed run, apply one fix and re-run once. If it still fails, stop and report what was tried, the exact error, and the likely cause — never loop.
  8. Accept the consent banner before capture ONLY if the page gates tracking behind it. No consent gate → skip it; don't add banner handling pre-emptively. The accept selector is project-specific — ask the user.

References

For detailed implementation instructions, read these in order:

  1. references/​workflow.md — Full step-by-step: setup, spec extraction, file creation, execution, extraction, comparison
  2. references/​discovery-and-capture.md — Codegen for interactions + window.dataLayer dump for payloads, conditional consent gating, tracking pre-flight
  3. references/​locator-rules.md — Hybrid locator model (CSS default, role-based fallback), container-level ambiguity, CTA navigation prevention
  4. references/​assertion-strategy.md — First-match vs deep-partial-match with examples
  5. references/​event-patterns.md — Standard dataLayer event structures and parameters
  6. references/​extraction-workflow.md — Token-efficient extraction and comparison pattern

Requirements

  • Node.js 18+
  • Playwright
  • allure-js-commons + allure-playwright
  • playwright-bdd (BDD mode only)