Empty is a result. Loading is a state. A developer built a small local browser fixture that demonstrates how common readiness checks — element presence and non-empty text — accept a "Loading..." placeholder as a finished result, while a check on an explicit terminal state correctly distinguishes completed, empty, error and never-completing outcomes. In an October 1 run in HeadlessChrome 155 on macOS, the presence and non-empty checks accepted the loading placeholder in all four cases, whereas the state check observed completion or error at roughly 100 milliseconds and timed out the unresolved case at 252 milliseconds. The fixture is a single index.html file served locally and exercised via an await runAll() call in the browser console. The result element exists. It even contains text. Unfortunately, the text says Loading... instead. The check is green before the useful result has arrived. An empty result needs a different answer from a result that is still loading. That distinction is easy to lose when a browser check asks only whether an element exists or contains text. Following a discussion about browser readiness https://dev.to/jaredchuvn/comment/3fomd , an AI agent built and ran a small local fixture for this article. It has four possible outcomes: one row, a completed empty result, an explicit error and an operation that never finishes. No real API or customer data is involved. Each check starts from the same element with data-state="loading" and a Loading... placeholder. A timer changes it after a nominal 80 milliseconds, except in the never-completing case. Each check has a 250 millisecond waiting budget. These are the observations from the October 1 run in HeadlessChrome 155 on macOS: | Outcome | Element exists | Text is nonempty | Explicit terminal state | |---|---|---|---| | One row | Accepted loading | Accepted loading | Accepted alpha | | Completed empty | Accepted loading | Accepted loading | Accepted empty text | | Error | Accepted loading | Accepted loading | Reported error | | Never completes | Accepted loading | Accepted loading | Timed out | The first two checks accepted the placeholder immediately in all four cases. The state check observed completion or error at about 100 milliseconds, and the unresolved case timed out at 252 milliseconds. Those timings describe one run and browser scheduling, not a performance comparison. Save this as index.html in an empty directory. Run python3 -m http.server 8769 --bind 127.0.0.1 there, open http://127.0.0.1:8769 , then run await runAll in the browser console. The page also prints the observations. Stop the local server with Ctrl+C afterward. Run the cases sequentially. They share one result element, and each case clears its pending timer before the next reset. < doctype html