Skip to content
Start
Internal instrument · 02 of 07

Loupe

A browser that refuses to report what it did not measure.

By the count

26

Tools in the server

2.5k

Lines, over Playwright

5,319:1

Control separation on the dither metric

0

Verdicts issued over unmeasured pages

01 · The problem

Why this exists at all.

Checking a design through a normal automated browser kept failing in the worst possible way: it failed while reporting success. A window resize would say it applied 390px and deliver 1024. Device emulation and automation fought over one debugger socket. Contrast checks read colours out of the DOM and returned confident, plausible, wrong numbers whenever text sat on a photograph, a gradient or a translucent layer.

None of these produced an error. They produced a green result, which is far more expensive. A wrong number that looks like a right number gets believed, gets built on, and is only caught by a human much later, if at all.

The tooling was not the problem in the sense of being broken. Automation libraries are honest about what they are: they hand you a browser and a screenshot function. They have no opinion about whether the thing you just measured is true. That opinion is what was missing.

02 · The approach

The decisions, and what they rule out.

01

One rule, applied without exception

No measurement without its pixels. A tool never answers with what it was asked to do, only with what it measured afterwards. `viewport` does not report success; it applies the emulation, re-measures the result, and throws if the measured width does not match the request. A success is therefore itself the measurement, which removes the entire class of failure where a tool reports an intention as an outcome.

02

Contrast is read from the composited image, not the DOM

Every DOM-derived contrast checker guesses at the background, and every one of them is wrong on photographs, gradients, blends and overlaps. Loupe screenshots the element, screenshots it again with the text made transparent, and diffs. The pixels that changed are the text; the second image holds the true background behind each one. The compositor has already solved the hard problem. Loupe just reads its answer. Text that turns out to be covered reports `notVisible` instead of inventing a ratio.

03

Refuse to grade what cannot be graded

An error page, a login wall or a near-empty document passes every accessibility check trivially, and four green verdicts over zero elements is precisely the confident-but-meaningless report the tool exists to prevent. Loupe checks the page is real before grading it, and returns `blocked`, not a clean bill of health. A check that examined nothing reports `unmeasured`, never `pass`.

04

Built on Playwright, not against it

Loupe uses Playwright to drive its own Chromium. The value is the measurement discipline layered on top: assertion that emulation took, pixel-derived contrast, session isolation so parallel callers cannot serve each other's pages, and a refusal to convert an intention into a result. Roughly 2,500 lines over a library that is doing the heavy lifting.

03 · What testing found

The things thinking about it did not catch.

Every item below is a real defect, found by measurement, with a commit behind it. They are here because the failures are more informative than the features.

01

A shared browser served a competitor's site for most of a session

Found when a blind session used the tools on live client work. One page object shared between callers meant `shot` could return a screenshot of an entirely different site, and it looked like a normal result. Fixed with per-caller session isolation and a guard that asserts the page is still the one you opened before any measuring tool runs. That guard has since caught legitimate navigations too: capturing a screenshot of Kern, it refused because clicking had rewritten the URL to a permalink.

02

Success reported on a page with no body

A Wayback frameset returned a document with essentially nothing in it and passed. This is what produced the sanity gate: the tool now states what it found, character count, element count, HTTP status, and declines to grade instead of returning verdicts over an empty page.

03

The audit measured a defect and then discarded it

The overflow check returned two things: a page-level boolean for sideways scroll, and a list of every element hanging past the viewport edge. The composite audit read only the boolean. Because `body { overflow-x: hidden }` is on nearly every site, a clipped element never grows the document, so the boolean stayed false and nothing was reported. A hero graphic ending 340px outside the frame produced the verdict "Does it fit the screen? mobile ok, desktop ok". The data had been measured and thrown away one line before it was used.

04

The fix had to be tested for silence as much as for noise

Reporting every element past the edge would have made the check useless: off-canvas drawers, screen-reader-only text and carousel slides all legitimately sit outside the viewport. Only elements that straddle an edge count; anything reachable inside a horizontal scroller is excluded. The regression fixture carries two real defects and five patterns that must stay silent, and the assertions cover the silence. A check that cries wolf gets ignored, which is the same failure as the one being fixed.

05

A detector was validated against known controls before its result was believed

A dither detector reported that a site's images were not dithered. "Nothing to detect" and "the detector is broken" are indistinguishable without a positive control, so both were generated: a real Bayer-dithered gradient and a smooth one. The metric separated them by three orders of magnitude: 5,319 against null. Only then was the negative result trustworthy, and it turned out to be the important finding on that job.

06

The instrument was measuring its own smoothing

That same detector initially scaled every image down before analysing it, which averages a one-bit dither back into smooth grey. It was measuring the smoothing it had just applied and concluding, reasonably and wrongly, that nothing was dithered. Fixed to sample at native resolution. The negative survived the fix, which is what made it a result and not an artefact.

Built with
  • Node
  • Playwright
  • Model Context Protocol
  • pngjs
Still open
  • Content that escapes its container with `overflow: visible` and stops exactly on the viewport edge is neither a clip nor a page scroll, so nothing currently flags it. Found on our own site, by measuring after a screenshot looked wrong.
  • Composition, whether elements collide, or whether a design holds together, remains outside what any of these checks can see. The instrument raises the floor. It does not replace looking.
Internal

Runs inside the studio's own pipeline.