QA Ultimate Stack

Check a live page's dataLayer against the spec

Capture a page's real dataLayer by scanning the URL or pasting from DevTools, scope the check to the events that page should fire, and read matched, missing and unexpected events key by key.

Two ways to capture the dataLayer

Parity compares what a page actually pushed with what the spec says it should. You can capture the pushes in two ways:

  • Scan a URL. ODDVX opens the page and reads window.dataLayer. It's read-only, so it never clicks, scrolls or submits, and it catches what fires on page load.
  • Paste from DevTools. Do the journey yourself, then run copy(JSON.stringify(dataLayer)) in the console and paste the result. This catches events that only fire after an interaction, such as form_start or add_to_cart.
A missing interaction event isn't always a bugA URL scan won't see form_submit, because nothing was submitted. For interaction events, paste after doing the journey, or use a form test.
Scanning catches page-load events; pasting after the journey catches interaction events too.

Two panels comparing a read-only URL scan with pasting the dataLayer from DevTools after a journey.

Scope the check to what the page should fire

Checking a page against the whole spec is noisy: a homepage never pushes form_submit, and a thank-you page never pushes form_start. A saved parity check holds a URL, the brand and the events that page is expected to fire, so "missing" only ever means a real gap. Picking the brand also applies its template and skips anything it has marked N/A. Free keeps one saved parity check.

A URL, its brand and the two events it should fire: only those can be missing.

A saved parity check form with a URL, a brand and two events selected.

Read matched, missing and unexpected

  • Matched: the page pushed an event the spec expects. Its keys are then compared.
  • Missing: the spec expects it on this page, and it wasn't pushed.
  • Unexpected: the page pushed an event the spec doesn't describe. Not necessarily wrong; often it's a GTM-generated event (like a scroll trigger) or something the spec hasn't caught up with.
Two matched, one missing, two unexpected, each with its detail.

A parity results table with counts and rows for matched, missing and unexpected events.

Read the keys: present, missing, extra

For each matched event, parity lists which of the spec's keys were present, which were missing, and which extra keys the page pushed that the spec doesn't mention. You also see the captured push itself, with its real values, next to the template.

A missing key next to an extra one is usually the same field under two names, form_name in the spec and formName on the page. Decide which is right and fix the other.

form_name missing and formName extra: one field, two spellings.

Template keys compared with the captured push, showing one missing key and one extra key with a similar name.

What parity does and doesn't check

Parity checks top-level keys. For nested parameters such as ecommerce.items[].price, it checks that ecommerce is present, not every value inside it. It also confirms keys exist, not that their values are right. For values, use a form test (which checks parameters are non-blank) or read the decoded payload.

Top-level keys are checked here; nested values and correctness need other checks.

Two panels showing top-level keys checked, and nested values and correctness not checked by parity.

ODDVX for Windows

From the page to the hit, proved.

Start free with one saved form, one page and one parity check. Premium adds batch runs, exports and scheduled QA.