Genie React
Workflows

Loading and error states

Hold brief branches still, verify them, and restore the app.

Query loading

Use the bound TanStack Start session from Measure the loading-state height gap. Hold its known query, then prove the cache and visible branch agree:

npx @genie-react/cli call query_simulate_state \
  '{"queryKey":["dashboard","metrics"],"state":"pending"}'
query_state="$(npx @genie-react/cli call query_get \
  '{"queryKey":["dashboard","metrics"]}' --json)"
printf '%s\n' "$query_state" | \
  jq -e '.status == "pending" and .simulatedState == "pending"'
agent-browser --session docs-case-start get text body | rg -F 'Loading metrics…'

Suspense fallback

Use the bound Router session from Verify routes and forced states. Navigate, discover the current component ID, force the fallback, then join React evidence to visible text:

npx @genie-react/cli call router_navigate '{"to":"/suspense"}'
npx @genie-react/cli call devtools_wait \
  '{"condition":"navigation","name":"/suspense","timeoutMs":5000}'
agent-browser --session docs-case-router wait '[data-testid="lazy-content"]'
lazy_panel_id="$(npx @genie-react/cli call react_find_components \
  '{"query":"LazyPanel","exact":true}' --json | \
  jq -er 'if (.matches | length) == 1 then .matches[0].id else error("expected one LazyPanel") end')"
npx @genie-react/cli call react_toggle_suspense_fallback \
  "$(jq -cn --argjson id "$lazy_panel_id" '{id:$id,showFallback:true}')" --json
suspense_state="$(npx @genie-react/cli call react_error_state '{}' --json)"
printf '%s\n' "$suspense_state" | \
  jq -e 'any(.suspended[]; .forced == true and .isFallbackShowing == true)'
agent-browser --session docs-case-router get text body | rg -F 'Loading lazy panel…'

Error boundary

Navigate to the error fixture and discover its current child ID before forcing the boundary:

npx @genie-react/cli call react_reset_overrides '{}'
npx @genie-react/cli call router_navigate '{"to":"/error"}'
npx @genie-react/cli call devtools_wait \
  '{"condition":"navigation","name":"/error","timeoutMs":5000}'
agent-browser --session docs-case-router wait '[data-testid="throw"]'
bomb_id="$(npx @genie-react/cli call react_find_components \
  '{"query":"Bomb","exact":true}' --json | \
  jq -er 'if (.matches | length) == 1 then .matches[0].id else error("expected one Bomb") end')"
npx @genie-react/cli call react_force_error_boundary \
  "$(jq -cn --argjson id "$bomb_id" '{id:$id,forceError:true}')" --json
error_state="$(npx @genie-react/cli call react_error_state '{}' --json)"
printf '%s\n' "$error_state" | \
  jq -e 'any(.caughtErrors[]; .forced == true and .boundaryName == "Boundary")'
agent-browser --session docs-case-router get text body | \
  rg -F 'Caught: Simulated error coming from DevTools'

forced:true separates these development checks from organic errors and suspensions.

Verify the UI

Use the browser driver to check:

  • The skeleton matches the final content size.
  • Buttons and links keep their position.
  • The fallback has a useful accessible name or status.
  • The error stays inside the intended boundary.
  • Retry returns to real content.

Restore

Restore the Query session and verify the synthetic marker is gone:

npx @genie-react/cli call query_restore_state \
  '{"queryKey":["dashboard","metrics"]}' --json
query_state="$(npx @genie-react/cli call query_get \
  '{"queryKey":["dashboard","metrics"]}' --json)"
printf '%s\n' "$query_state" | jq -e 'has("simulatedState") | not'
agent-browser --session docs-case-start get text body | rg -F 'Acme NA #1'

Reset the Router session and verify the real child is visible again:

reset="$(npx @genie-react/cli call react_reset_overrides '{}' --json)"
printf '%s\n' "$reset" | jq -e '.remaining == 0'
agent-browser --session docs-case-router get text body | rg -F 'Throw'
unset query_state suspense_state error_state reset lazy_panel_id bomb_id

Agent outcome

The agent can verify states that normally last only a few milliseconds. This makes layout-shift, fallback, and error-boundary work testable without adding temporary app code.

On this page