{"slug": "give-your-coding-agent-eyes-debug-cypress-through-a-live-browser-session", "title": "Give Your Coding Agent Eyes: Debug Cypress Through a Live Browser Session", "summary": "A developer introduced `cypress tap`, a terminal interface that lets coding agents inspect a live Cypress open-mode session rather than relying on `cypress run` exit codes. The tool exposes the Command Log, DOM snapshots, accessibility tree, and historical browser state via JSON commands like `status`, `reporter`, `command`, `pin`, `aria`, and `inspect`, enabling agents to gather the same evidence a human developer would before proposing a fix. The beta tool requires Cypress 15.21.0 or later, works only with `cypress open` and a Chromium-based browser, and includes a polling protocol to avoid stale-state verdicts.", "body_md": "A coding agent can run `cypress run` and read the exit code. That tells it whether a spec passed. It does not show the Command Log, the DOM at the failed command, the accessibility tree, or the browser state a human sees in Cypress open mode.\n\nThis gap matters when the failure is visual or stateful. “Element not found” could mean the selector is wrong, the page never loaded, an overlay covered the control, or the test inspected the wrong retry attempt.\n\n`cypress tap` adds a terminal interface to a live Cypress open-mode session. The interesting part is not that an AI can execute another command. It is that the agent can inspect the same evidence a developer would use before proposing a fix.\n\nStart Cypress and select a Chromium-based browser:\n\n```\nnpx cypress open --e2e --browser=chrome\n```\n\nIn another terminal:\n\n```\nnpx cypress tap specs --json\nnpx cypress tap run cypress/e2e/login.cy.ts --json\nnpx cypress tap status --json\n```\n\nThe `run` command requests a run and returns immediately. It does **not** mean the spec has started or finished. A reliable agent must poll `status`, set its own timeout, and wait for a terminal `passed` or `failed` state.\n\nThere is a subtle stale-state trap: the previous run's verdict remains readable until the next run starts. The JSON status includes `startedAt`; compare it with the run you requested before trusting the verdict.\n\nThat produces a bounded protocol:\n\n```\ntype TapStatus = {\n  status:\n    | \"not connected\"\n    | \"browser not selected\"\n    | \"spec not selected\"\n    | \"loading\"\n    | \"running\"\n    | \"passed\"\n    | \"failed\";\n  startedAt: string | null;\n};\n\nasync function waitForVerdict(requestedAfter: number) {\n  for (let attempt = 0; attempt < 60; attempt++) {\n    const status = await runJson<TapStatus>(\"npx cypress tap status --json\");\n    const started = status.startedAt ? Date.parse(status.startedAt) : 0;\n\n    if (started >= requestedAfter &&\n        (status.status === \"passed\" || status.status === \"failed\")) {\n      return status;\n    }\n\n    await delay(500);\n  }\n\n  throw new Error(\"Cypress session did not produce a fresh verdict\");\n}\n```\n\nThe timeout is part of the correctness model. A build failure can leave the session in `loading`, so “poll until success” can otherwise become an agent loop.\n\nThere is another important contract: `cypress tap status` exits successfully for a determinable stage, including a reported test failure. Automation must branch on the JSON `status`, not treat shell exit code zero as a passing spec. Prefer `--json`, pin Cypress in the lockfile, and let the agent inspect `cypress tap --help` so its command assumptions match the attached session.\n\nOnce the run fails, get the reporter view:\n\n```\nnpx cypress tap reporter --json\nnpx cypress tap reporter --test-id r3 --attempt 1 --json\n```\n\nThe test-level report includes routes, hooks, the Command Log, and failure details. If retries occurred, inspect the failed attempt instead of assuming the final attempt represents the original failure.\n\nThen narrow the investigation:\n\n```\nnpx cypress tap command \\\n  --test-id r3 \\\n  --command-id 7 \\\n  --attempt 1 \\\n  --json\n\nnpx cypress tap pin \\\n  --test-id r3 \\\n  --command-id 7 \\\n  --attempt 1 \\\n  --at after\n\nnpx cypress tap aria --selector \"main\"\nnpx cypress tap inspect --selector \"[data-testid=submit]\"\n```\n\n`pin` restores a command snapshot into the app-under-test frame. `dom`, `aria`, and `inspect` can then read that historical state. This is far stronger evidence than asking an agent to infer browser state from an error string.\n\nBrowser access should not become an unbounded “fix until green” loop. I use a small policy:\n\nThe agent should also report what it observed and why the proposed edit addresses that evidence. A green rerun is necessary, but it does not prove the change preserved the intended assertion.\n\n`cypress tap` is beta and requires Cypress 15.21.0 or later. It works with `cypress open`, not headless `cypress run`, and currently requires a Chromium-based browser. Its commands and output may still change between releases.\n\nBeta also changes the evidence contract. Store the Cypress version, browser, testing type, session identifier, spec path, attempt, and `startedAt` beside any captured report. A JSON field that changes in a later release should fail your adapter clearly instead of being interpreted as a new test result.\n\nIt also exposes page structure to the terminal. Treat DOM text, routes, and console properties as potentially sensitive, especially when a coding agent sends context to a remote model.\n\nThe useful mental model is simple: the agent is not replacing the test runner or the reviewer. It is gaining a structured window into the live evidence between “failed” and “I know why.”", "url": "https://wpnews.pro/news/give-your-coding-agent-eyes-debug-cypress-through-a-live-browser-session", "canonical_source": "https://dev.to/raju_dandigam/give-your-coding-agent-eyes-debug-cypress-through-a-live-browser-session-5ffi", "published_at": "2026-09-16 17:31:00+00:00", "updated_at": "2026-09-16 17:42:26.228380+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools"], "entities": ["Cypress", "Chromium", "cypress tap"], "alternates": {"html": "https://wpnews.pro/news/give-your-coding-agent-eyes-debug-cypress-through-a-live-browser-session", "markdown": "https://wpnews.pro/news/give-your-coding-agent-eyes-debug-cypress-through-a-live-browser-session.md", "text": "https://wpnews.pro/news/give-your-coding-agent-eyes-debug-cypress-through-a-live-browser-session.txt", "jsonld": "https://wpnews.pro/news/give-your-coding-agent-eyes-debug-cypress-through-a-live-browser-session.jsonld"}}