Use before claiming a web change works. Reading HTML and CSS is not seeing the page — render it, in every theme, and look.
Scanned 9/4/2026
Install to Claude Code
npx -y skills add everywan-dev/claude-code-engineering --skill look-at-the-rendered-page --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Look At The Rendered Page?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/everywan-dev-look-at-the-rendered-page)More formats (shields.io, HTML) on the badges page.
---
name: look-at-the-rendered-page
description: Use before claiming a web change works. Reading HTML and CSS is not seeing the page — render it, in every theme, and look.
---
# Look at the rendered page
**The browser is the only thing that knows what the user sees.**
Everything upstream of it is an opinion. The template is an opinion. The
stylesheet is an opinion. The test that greps the response body for a string is
an opinion about which string matters. The page is the fact.
This is the visual twin of [verify-before-saying-done](../verify-before-saying-done/SKILL.md):
that one asks for a check that could have failed; this one is about the class of
web failure where *every* check passes and the page is still wrong.
## When to use this
- You changed a template, a stylesheet, or anything that produces markup
- You are about to say a page "works", "looks right", or "is fixed"
- A test asserts a string is present — that is not the same as it being visible
- You changed a design token, a colour, or a theme
- The page needs a session, so nobody has actually opened it since the change
## Why the tests keep missing it
Assertions are written to confirm something is **there**. The visual failures
are things that are there and wrong, or things that are there twice, or things
whose colour makes them unreadable. A test that asserts `assertIn("Contract",
html)` passes just as happily when the button is black text on a black
background.
Four failures found in a single day on one project, none caught by a green test
suite, all four obvious within two seconds of looking:
| What the tests said | What the page showed |
|---|---|
| All assertions pass | Seven lines of an internal code comment printed as body text |
| Quota renders correctly | `999 / 999 / 999`, which reads as a broken panel, not "unlimited" |
| Button present with correct link | Black text on a black button — invisible in the light theme |
| Notification email delivered | The alert that was supposed to accompany it never fired |
## The procedure
**1. Render it. Do not reason about it.** Headless Chrome is enough and is
already on most machines:
```bash
chrome --headless --disable-gpu --window-size=1500,1100 \
--screenshot=out.png --virtual-time-budget=10000 \
--hide-scrollbars "file://$PWD/page.html"
```
`--virtual-time-budget` matters: without it you screenshot the page before its
fonts, images and scripts have settled, and then debug a problem that only your
screenshot has.
**2. If the page needs a session, borrow one — do not skip the page.** The
pages that go unlooked-at are exactly the authenticated ones. Mint a session for
a throwaway user server-side, fetch the page with that cookie, and render the
result:
```bash
# server-side: create a session for a disposable user, print the key
# then, locally:
curl -s -H "Cookie: sessionid=<key>" https://host/the/page/ > page.html
```
Delete the throwaway user and its session afterwards. It is test data in a real
system; leaving it there is how test data becomes production data.
**3. Rewrite relative asset URLs before rendering from a file.** A saved page
loaded over `file://` will silently fail to fetch `/static/app.css` and render
naked. Point the assets at the real origin so you are looking at the page with
its actual stylesheet:
```bash
sed -i '' 's|href="/static/|href="https://host/static/|g' page.html
```
If you skip this you will "discover" a layout bug that does not exist.
**4. Look at every theme, not the one you happen to be in.** This is the single
most common miss. A colour that is legible in dark mode can be invisible in
light mode, and you will never see it because your own machine is set to one of
them.
Force each theme explicitly and render both:
```bash
sed 's|data-theme="dark"|data-theme="light"|' page.html > light.html
```
**5. Read the image.** Not the DOM you dumped, not the CSS you wrote. The
screenshot. Then state what you saw, not what should have been there.
**6. Say which parts you did not render.** Modals, error states, empty states,
mobile widths. They are pages too and nobody has looked at them either.
## Real cases
> **A comment printed to the customer.** A template comment written across seven
> lines used the single-line comment syntax. The templating engine consumed the
> first line and emitted the remaining six as page content. Every test passed —
> they all asserted that certain strings were *present*, and they were. The
> customer saw a paragraph of internal engineering notes beside the product
> cards. It was found by opening the page.
>
> The test added afterwards asserts the opposite of the usual: that comment
> markers and internal phrasing are **absent** from served HTML.
> **Black on black.** A button used a design token for its inverted text colour.
> The token did not exist; it fell through to a hard-coded dark hex that was
> dark in *both* themes. In the dark theme the button had a light background, so
> it looked correct and shipped. In the light theme the background was dark too,
> and the label vanished. Only one theme had been rendered.
> **`999` means unlimited.** A plan stored its quotas as `999` to mean "no
> limit". In a table, three columns of `999` in a row read as a malfunctioning
> page, not as the most generous plan on offer. No test could have caught this:
> the number was correct. It was a rendering decision, and it needed eyes.
## Traps
🔴 **"The string is in the HTML" is not "the user can see it."** It can be
behind a collapsed element, the same colour as its background, off-screen, or
below a `z-index` that covers it.
🔴 **One theme is half a check.** If the product has a light and a dark mode,
an unrendered theme is an unrendered page.
⚠️ **A screenshot from `file://` is not the live page.** Scripts that call an
API will fail from a local file. Know which parts of your screenshot are dead
for that reason, and say so rather than reporting them as broken.
⚠️ **Do not screenshot immediately after a deploy.** You will catch the restart
window and photograph a `502`. Poll for a healthy response first, then render.
⚠️ **Your own browser cache lies.** Render from a clean context, or version the
asset.
## What a rendered check looks like
```markdown
**Claim:** the plan table shows the entry price and links to the right section.
**Rendered:** dark and light, 1500×1100, headless Chrome, post-deploy.
**Saw:** ten rows, prices right-aligned, "Contract" legible in both themes.
**Found while looking:** quota columns printed `999` instead of "unlimited".
**Not rendered:** mobile width, the checkout modal, the empty state.
```
## Related
- [verify-before-saying-done](../verify-before-saying-done/SKILL.md) — the general rule this one applies to pixels
- [debug-a-silent-failure](../debug-a-silent-failure/SKILL.md) — for when nothing complained at all
- [validate-your-validator](../validate-your-validator/SKILL.md) — because a test suite that passed on all four of these needs looking at
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!