Back to the marketplace
Developer ToolingVerifiedv1.0.0

WCAG 2.2 Audit Suite for Headless Chrome

By iTechVista Studio•No reviews yet•0 purchases

Overview

A zero-dependency Node.js command-line tool that renders pages in headless Chrome over the DevTools protocol and measures WCAG 2.2 problems rather than guessing from markup. Ten checks: text contrast against the background actually painted behind the text (translucent layers composited, opacity applied), clipping under the 1.4.12 text-spacing overrides and at 200% default text size, reflow at 320px with target size including both 2.5.8 exceptions, controls that lose their edge in forced colours, invisible or obscured focus, a keyboard walk that catches traps, missing focus indicators and scripts that throw focus away, unnamed controls and images from the accessibility tree, broken id references, and motion that ignores reduced-motion. One command gives a console report with a CSS selector per finding, a JSON report and CI exit codes, including a separate code when a page failed to load or a built-in canary was missed, so a broken run is never reported as clean. Tested only on Windows 11 with Node 24.19 and Chrome 154. It is not a conformance audit: warnings need human review.

#wcag#accessibility#chrome-devtools-protocol#cli#zero-dependency

Source preview

    let bg = null, painted = '';
    for (const node of (idx >= 0 ? stack.slice(idx) : [el])) {
      const ncs = getComputedStyle(node);
      if (ncs.backgroundImage && ncs.backgroundImage !== 'none') { painted = 'background-image'; break; }
      const c = parse(ncs.backgroundColor);
      if (c && c.a > 0) { bg = bg ? over(bg, c) : c; if (bg.a >= 0.99) break; }
    }
    if (!painted && (!bg || bg.a < 0.99)) {
      for (let node = el.parentElement; node; node = node.parentElement) {
        const ncs = getComputedStyle(node);
        if (ncs.backgroundImage && ncs.backgroundImage !== 'none') { painted = 'background-image'; break; }
        const c = parse(ncs.backgroundColor);
        if (c && c.a > 0) { bg = bg ? over(bg, c) : c; if (bg.a >= 0.99) break; }
      }
    }
    // Nothing opaque anywhere: the canvas behind the page is white.
    if (!painted && (!bg || bg.a < 0.99)) bg = bg ? over(bg, { r: 255, g: 255, b: 255, a: 1 }) : { r: 255, g: 255, b: 255, a: 1 };
    if (painted) { unknown.push({ element: __name(el), selector: __path(el), text: text.slice(0, 40), why: painted }); continue; }
    measured++;

    const size = parseFloat(cs.fontSize);
    const weight = parseInt(cs.fontWeight, 10) || 400;
    const large = size >= 24 || (size >= 18.66 && weight >= 700);
    // CSS opacity fades text against its own background. Ignoring it
    // OVERSTATES contrast, which is the direction that hides a real failure.
    const textAlpha = Math.min(1, fg.a * (parseFloat(cs.opacity) || 1));
    const cr = ratio(textAlpha < 1 ? over({ ...fg, a: textAlpha }, bg) : fg, bg);
    const need = large ? 3 : 4.5;
    if (cr >= need) continue;
Choose a licence
$24.00

Excludes tax, added at checkout where it applies.

DeliveryPrivate download link
Review statusPassed