Passante A Passante publication

En Passante

In Passing
Field Kit

The screenshot captured the loading state

A screenshot is evidence only if the script blocked on the content it claims to show, and an asset that was never captured from a running thing should be labelled as such rather than shown as proof.

What happened

On 2026-07-07, an automated screenshot of a page that fetched its data client-side captured the loading state instead of the data, and the capture was rewritten as a browser-automation script that waited for specific card text to appear before shooting.

2026-07-07 Node · headless browser automation · local dev servers measured: capture contents with and without a content wait condition
3 prompts, in order
  1. Wait for content, not for time A visual check of a data-fetching page shows skeletons, spinners, empty cards, or zeros.
  2. Capture it for real or label it A page needs a screenshot of an application that is not hosted anywhere reachable.
  3. Audit which images are real captures A page carries several screenshots and nobody can say which came from running software.

1Wait for content, not for time

Run it when
A visual check of a data-fetching page shows skeletons, spinners, empty cards, or zeros.
It asks you for
The URL being captured. The exact text or selector that exists only after the data arrives. The current capture command. Whether a failed capture still writes a file.
You get back
A capture script that blocks on a post-fetch marker. It fails loudly on timeout. Plus a negative test to prove the wait works.
It refuses if
No text or element can be named that exists only after the data arrives.
copy this into a model
<stance>
Visual verification that reports success while showing nothing is a familiar trap. The browser reached its load event, the request was still in flight, and the image recorded a skeleton. The comfortable repair does not hold. Raising a fixed delay until the local machine stops failing only moves the race elsewhere. A capture is a claim. Make the script prove the content arrived before the shutter opens.
</stance>

<inputs>
Ask for these. Wait for each answer. Do not proceed on a guess.
1. The URL or route being captured.
2. The exact visible string, or selector, that appears only after the data request resolves. A heading in the page shell does not count.
3. The current capture command or script, verbatim.
4. What the current capture does on failure. Writes a file anyway, writes nothing, or unknown.
If item 2 comes back vague, push once for a literal string before continuing.
</inputs>

<method>

1. Classify the page. Ask whether the data is rendered on the server or fetched after hydration. If the user cannot say, have them load the route with the network offline. Server-rendered content still appears. Client-fetched content does not. State which case this is.
2. Locate a marker. Prefer a string that comes from the response payload, not from the component shell. Name it explicitly in the script.
3. Rewrite the capture. It navigates, waits for that marker to be visible, then shoots. Keep the timeout finite and have it throw.
4. Make failure visible. On timeout the script must exit non-zero. It must not leave a stale or partial image behind.
5. Prove the wait is load-bearing. Swap the marker for a string the page never renders. Confirm the script times out. An image produced anyway means the wait is not in the capture path.
6. Handle multiple requests. Wait on a marker from each one. Otherwise state plainly which sections the capture covers.

</method>

<deliver>

- Page classification and the evidence for it
- The chosen marker, quoted literally
- The capture script, with the wait and a finite timeout
- The negative test, and what a correct failure looks like
- Any region of the page the capture does not cover

</deliver>

<refuse>
Do not propose a fixed sleep as the fix. Do not propose one as a fallback either. Do not wait on a network-idle or load event instead of content. Both can settle before the data renders. If no post-fetch marker can be named, stop. Say the capture cannot be made trustworthy yet. Ask for one rendered value from the response. Do not call the capture verified until the negative test has timed out. If the user says the original image already looks right, answer plainly. A correct-looking image from a racing script is not evidence.
</refuse>

2Capture it for real or label it

Run it when
A page needs a screenshot of an application that is not hosted anywhere reachable.
It asks you for
What the image must show. Whether the application's source is on this machine. Its install and start commands. The port it serves on. Who will read the image as proof.
You get back
A sequence to install, start, and capture from the real application. Or a labelled stand-in with a provenance line attached.
It refuses if
Asked to dress up a mock image and present it as a real capture.
copy this into a model
<stance>
Placeholder art has a habit of outliving its purpose and then being quoted as proof that a feature exists. The grounded alternative is plain. Install the dependencies, start the application locally, and take one genuine screenshot. The shortcut that tempts here is a tidy mock that looks close enough, because nobody asks where it came from until someone does. An image shown as proof needs a running source behind it.
</stance>

<inputs>
Collect these. Wait on each.
1. What the screenshot must demonstrate, in one sentence.
2. Is the application's source on this machine? Yes, no, or unknown.
3. Its install command and its start command, if known.
4. The port or local URL it serves on, if known.
5. Where the image will be published.
6. Whether a reader will take it as evidence that the application runs.
</inputs>

<method>

1. Decide whether a real capture is reachable. If the source is present, treat local run then capture as the default path. If the source is absent, say so early. Do not drift toward a substitute.
2. Write the sequence out. Install dependencies, start the server, confirm the route answers, capture, stop the server. Keep the capture step separate from the start step. A failure then tells you which half broke.
3. Confirm the running thing is the right thing. Check the served route matches the caption. Check the data on screen belongs to the application, not to a leftover seed fixture.
4. Add a content wait condition. A locally started server is often slow on first paint. The race gets worse here, not better.
5. If no real capture is possible, build a stand-in that cannot be mistaken for one. Give it a visible label. Add a provenance line saying what it represents and what would have to run to replace it.
6. Store the capture command next to the asset. The next person regenerates it instead of trusting it.

</method>

<deliver>

- Verdict: real capture possible, or not, with the reason
- The run-and-capture sequence, step by step
- The provenance line to store with the asset
- The visible label text, if a stand-in is used
- What to re-run when the application becomes reachable

</deliver>

<refuse>
Do not composite or hand-edit an image and present it as a screenshot. Do not reuse an older image without checking which version it came from. If the source cannot be run and readers will treat the image as proof, stop. Say the asset cannot be supplied honestly yet. Name the one thing needed to unblock it. Do not claim the capture succeeded before the served route answers. Do not claim it before the content wait passes.
</refuse>

3Audit which images are real captures

Run it when
A page carries several screenshots and nobody can say which came from running software.
It asks you for
The list of image assets. Any capture scripts or commands in the project. The claim each image supports.
You get back
A per-asset table marking each image real, stand-in, or unknown. The evidence that decided it. The command to regenerate it.
It refuses if
An image cannot be tied to a capture command, a running source, or a stated origin.
copy this into a model
<stance>
Unknown provenance is a finding, not a gap to smooth over. A review can pass because every image loaded. That says nothing about whether any came from running code. The pull here is to rank images by how convincing they look, and the cleanest asset in the set is often the one somebody drew. The output is a ledger. Unknown is a legitimate entry in it.
</stance>

<inputs>
Ask for these. Wait.
1. The image assets under review, by name.
2. Any capture scripts, automation commands, or generation steps in the project.
3. For each image, the sentence it supports on the page.
4. Whether the applications shown can be run locally now.
If images arrive without their claims, ask for the claims. An unclaimed image needs no audit.
</inputs>

<method>

1. For each asset, look for a capture path. A script naming the route, a wait condition on real content, or a recorded command all count. Absence of all three is the finding.
2. Read the image against its claim. If the claim is that data loads, check the image shows data. Skeletons, empty states, or zeros mean the capture raced and shipped anyway.
3. Mark each asset. Real means a capture command exists and the content matches the claim. Stand-in means it was authored, not captured. Unknown means neither can be established. Never round unknown up to real.
4. For every unknown or stand-in, state what would settle it. A runnable source, a capture script, or a labelled caption.
5. Rank by exposure, not by appearance. An unknown image carrying a strong public claim outranks a stand-in that is already labelled.
6. Where a capture script exists without a content wait, flag it. It is regenerable but unreliable, and the wait comes first.

</method>

<deliver>

- Asset table: name, claim, verdict, evidence
- Unknowns, with the single item that would resolve each
- Captures that exist but lack a content wait
- Regeneration commands, where they exist
- One line on what the page currently over-claims

</deliver>

<refuse>
Do not infer a real capture from a filename, a resolution, or how plausible an image looks. Do not mark an asset real because a capture script exists elsewhere, unless that script names this route. If the project has no capture commands and no runnable sources, stop. Report that provenance cannot be established for any asset. Do not produce a table of guesses. Do not recommend deleting assets. Recommend labelling or regenerating them, and leave the decision with the user.
</refuse>
How you know it worked

Point the wait condition at a string the page never renders. Run the capture again. The script should time out and write no file. Then remove the wait and capture against a cold server. A loading skeleton in that image shows the wait was load-bearing.

from a real incident, 2026-07-07 · stack Node · headless browser automation · local dev servers · verified by capture contents with and without a content wait condition · visual-testingbrowser-automationrace-conditionsprovenance

← every Field Kit