VisualQ

Pillar steps

Use VisualQ's accessibility, performance, VRT, and tracking checks directly inside Gherkin scenarios.

Pillar steps are system step definitions that bridge a Gherkin scenario with VisualQ's quality engines. Instead of writing a custom assertion to check accessibility or VRT, you write a natural-language Then line.

Available pillar steps

Accessibility (axe)

Then the page should pass accessibility (axe) with score >= 90
Then the page should have no critical accessibility violations
Then the element "main" should be accessible

The bridge runs @axe-core/playwright, computes a 0-100 score, and records the result in the scenario's pillarMetrics.

Visual regression (VRT)

Then the visual diff with baseline "checkout" should be below 0.1%
Then the visible region should match the baseline "homepage"

Re-uses VisualQ's existing VRT engine. Baselines are managed in the project's VRT tab — pillar steps just consume them.

Performance (Lighthouse / Web Vitals)

Then the page should load within 2500ms (LCP)
Then the CLS should be below 0.1
Then the INP should be below 200ms

Performance metrics are captured live during the scenario via injected PerformanceObservers — no extra navigation required.

Tracking / analytics

Then the analytics event "checkout_started" should fire
Then the GTM tag "GA4 - Pageview" should fire on this page
Then the tracking call should include {"event":"add_to_cart"}

The bridge listens on dataLayer pushes and gtag calls during the scenario and matches them against the Gherkin assertion.

Console

Then no console errors should be present
Then no console warnings should be present matching "deprecated"

Security headers

Then the page should send a strict CSP header
Then the page should not expose "X-Powered-By"

Writing your own pillar steps

If your team needs a domain-specific check (e.g. "the OneTrust banner should disappear in under 500ms"), wrap the logic into a custom step definition with pillarHook: 'tracking' (or another pillar) — it will appear in the library under the same group.

// Body excerpt — has access to ctx.pillar.tracking
await ctx.pillar.tracking.assertEvent({ event: 'cookie_banner_closed' })
ctx.recordPillarMetric('cookieBannerCloseMs', closeMs)

recordPillarMetric() values bubble up to the run timeline and are graphed across runs so you can spot regressions over time.

On this page