ARTICLE
Projects

Visual testing that measures the DOM instead of comparing screenshots

14 August 2026Majed Alandajani

The common approach to visual testing is screenshot comparison: capture a baseline image, diff every run against it, allow some pixel tolerance.

I tried it, and three problems eventually pushed me away from it.

Why I left screenshot comparison

Baselines need maintenance. A single intentional design change invalidates dozens of images at once, and while you are busy re-approving them, real failures slip through unnoticed.

Tests also get flaky for reasons that have nothing to do with your code. A font smoothing difference between your machine and the build server is enough to fail a run.

The biggest problem: an image does not know what it is looking at. A twenty-pixel difference might be a shadow that moved, or it might be a button that lost half its word. To the diff, those two cases look identical.

What I built instead

A check that opens the page and asks the elements about themselves:


el.scrollWidth > el.clientWidth    // the text is bigger than its box, so it is clipped
document.elementFromPoint(x, y)    // is the element really in front?
getComputedStyle(el).letterSpacing // tracking applied to Arabic text

The incident that proved the difference

I shipped an admin panel with an actions list. Every check passed: no horizontal scroll, no console errors. Even the translation read correctly in both directions.

Then the owner opened it and found buttons reading "سُد" and "حذ". Five buttons, each cut down to two letters.

Screenshot comparison would have caught this, provided a baseline existed for that exact screen with that exact content. The measuring check needed no baseline at all; it produced one line, from a rule that runs on every screen:


clipped label [['سُدد بتحويل بنكي', 118, 28], ['حذف بيانات العميل (PDPL)', 165, 98]]

The two numbers are the width the label needs and the width it was given. A button needing 118 pixels got 28.

What this catches and screenshots do not

A clipped label on any element, wherever it sits on the page, and an element that is rendered yet buried under another layer where no click can reach it. The check also flags letter-spacing applied to Arabic text, which breaks the joins between letters and is invisible in a small image.

What screenshots catch and this does not

Aesthetic drift: a colour or shadow that changed, spacing that slid out of alignment. If that is the thing you are protecting, screenshots remain the right tool.

The conclusion

Screenshots answer one question: did the appearance change? Measuring the DOM answers another: is the interface still usable and readable? In my work the second question comes up far more often.

Related reading

Have a project in mind?
Tell me what you want to build. Your first 15 minutes of consulting are free.
Book a consultation