visual-test
Skill4 starsChanged 18 days agoMITView on GitHub
Visually inspect web pages and components at mobile (390px) and desktop (1280px) viewports with headless Chrome. Takes screenshots, detects horizontal scroll and locates the exact element that overflows, reports objective mobile-usability signals, runs a real accessibility audit with axe-core, and catches four things none of the above sees: content that an entrance animation leaves invisible forever, hydration failures, contrast that only fails on hover or in the active state, and the vertical rhythm between sections. Use when polishing responsive design, when someone reports that something looks wrong on mobile, when chasing a horizontal overflow, when reviewing entrance animations, or when you want to compare mobile and desktop before deploying.
- Installs packages
7 other projects use a version of this.
Adopted by
Most recently taken up by
- skyhook-io/radartheir own version, first seen Oct 24, 2026
- sirakinb/claude-code-skillstheir own version, first seen Oct 11, 2026
- UI5/webcomponentstheir own version, first seen Oct 8, 2026
- LiberatedPixelCup/Universal-LPC-Spritesheet-Character-Generatortheir own version, first seen Oct 8, 2026
- zulip/zuliptheir own version, first seen Oct 8, 2026
- microsoft/fluentuitheir own version, first seen Oct 5, 2026
Other versions7 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 7
- zulip/zulip★ 26ksame name
- microsoft/fluentui★ 20ksame name
- skyhook-io/radar★ 4.1ksame name
- LiberatedPixelCup/Universal-LPC-Spritesheet-Character-Generator★ 1.9ksame name
- UI5/webcomponents★ 1.8ksame name
- plugyawn/armada★ 2same name
- sirakinb/claude-code-skills★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository46 other files it gives its agents.
- AGENTS.mdAGENTS.md
- add-repo-to-docsSkill
- adrSkill
- auth-bypass-localSkill
- before-afterSkill
- bug-huntSkill
- carry-envSkill
- code-healthSkill
- crux-doctorSkill
- crux-initSkill
- css-to-componentsSkill
- deploy-fallbackSkill
- deploy-watchSkill
- device-loopSkill
- drive-browserSkill
- e2eSkill
- end-sessionSkill
- eval-fixturesSkill
- explain-planSkill
- flowSkill
- grillSkill
- merge-conflictsSkill
- motion-videoSkill
- oauth-reauthorizeSkill
- prod-signalsSkill
- promote-to-docsSkill
- prose-checkSkill
- read-documentSkill
- render-loopSkill
- repo-mapSkill
- review-prSkill
- root-causeSkill
- runbookSkill
- security-auditSkill
- share-localSkill
- shipSkill
- skill-auditSkill
- skill-creatorSkill
- teachSkill
- ui-behaviourSkill
- ui-tellsSkill
- visual-diffSkill
- wizardSkill
- workspaceSkill
- write-testsSkill
- x-postsSkill
The file
We split this skill into the rules it gives an agent
4 rules. 0 are common, 3 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 7 edited versions we read keep these.
3
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 74
Do not chain | head: the process dies before writing.
- Distinctive: line 75
Check that the port serves the application you think it does.
- Distinctive: line 76
After touching the root layout, restart the development server.
- Distinctive: line 77
If the error page for dynamic chunks appears, retry.
“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Visual test
Headless visual inspection with the system Chrome: see the page as on a real
phone, detect horizontal scroll and catch the culprit element. The real cases
behind each check and the full gotchas are in
<this-skill-directory>/references/why.md.
Setup, once
It needs google-chrome or chromium (autodetected; forced with CHROME_BIN)
and the application running locally.
mkdir -p ~/.cache/visual-test && cd ~/.cache/visual-test
[ -d node_modules/playwright-core ] || npm i playwright-core >/dev/null 2>&1
cp "<this-skill-directory>/scripts/visual.mjs" .Usage
cd ~/.cache/visual-test
node visual.mjs shot http://localhost:3000/path /tmp/a.png [--scroll 560] [--desktop]
node visual.mjs audit <url> [<url>…] # horizontal scroll
node visual.mjs bisect <url> # which element overflows
node visual.mjs checks <url> # mobile usability signals
node visual.mjs a11y <url> [--desktop] # WCAG with axe-core (needs network)
node visual.mjs invisible <url> [<url>…] # content that stays at opacity 0
node visual.mjs hydration <url> [<url>…] # hydration failures
node visual.mjs states <url> # contrast at rest and on hover
node visual.mjs rhythm <url> # spacing between sectionsOpen the screenshots and look at them. It is not optional: the skill is for seeing, not for deducing. No page is accepted without having looked at its screenshot on mobile and on desktop, whatever the commands report.
How to read the results
checksgives hints, not verdicts (touch areas < 44px, text < 12px, images without alt, text stuck to the edge); some are intentional.a11yis the reliable source for accessibility.audit:innerWidth=390 overflowH=0px okis fine; a largerinnerWidthmeans something forces that width. Thenbisect.bisect: the culprit is the node withkids=0; its ancestors show up because hiding them makes it disappear too.invisibleexits with code 1 if it finds anything.states: the active state of tabs and the like has to be triggered by hand; axe only sees the one that comes selected.
Two rules for entrance animations: never hide a whole container, and exclude whatever lives inside a carousel.
Typical causes of horizontal scroll
- A flex item without
min-width: 0with text that does not wrap. Fix it on the container. - A full-bleed element with negative margins outside the container that sets the padding. Wrap it in an element with that padding.
overflow-x: hiddenon the root hides it but does not fix it. Look for the cause withbisect.
Gotchas
- Measure after hydrating: scroll down in stages with a pause and wait for a selector that only exists once hydrated.
- Walk the page without returning to the top, or
invisiblegives false positives. - Do not chain
| head: the process dies before writing. Redirect to a file. - Check that the port serves the application you think it does.
- After touching the root layout, restart the development server.
- If the error page for dynamic chunks appears, retry.
- Kill the development server by PID, never with
pkill.
Related
/device-loop— the real app on an Android emulator/render-loop— iterate on a rendered output/ui-behaviour— that controls do something useful
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

