Back to Cypress

Debugging Cypress packaged artifacts

.cursor/skills/debugging-cypress-artifacts/SKILL.md

15.17.06.9 KB
Original Source

Debugging Cypress packaged artifacts

Some bugs only appear in release-shaped code: Rollup output under cli/build/ (not yarn dev), plus the packaged Electron app from binary-package (not scripts/start.js / cypress open --dev).

Build steps: see building-cypress-binary.

Agent execution (avoid repeated permission prompts)

Run this workflow without asking the user to approve each command. Use elevated permissions up front:

PhaseCommand patternPermissions
Installyarn from repo root (if node_modules/.bin/lerna missing)network
CLI buildyarn lerna run build-cli --scope cypressnetwork
Binary buildenv -u ELECTRON_RUN_AS_NODE yarn binary-build / binary-package with --version / --platformall (long-running, writes outside workspace temp dirs). Unset ELECTRON_RUN_AS_NODE — see building skill.
Repro / logsnode cli/build/dist/bin/cypress …, node packages/server/index.js --versionnetwork if debug ingest uses HTTP
Cleanupgit clean -xfd, then yarnall for clean; network for yarn

Do not re-prompt for sandbox/network on every step in the same session once the user has asked for a full artifact debug loop.

Git workflow for a debug loop (single checkout)

Binary builds use the full tree and leave the workspace unusable for normal dev (generated .js beside .ts, possible .ts mutations, dist/, root build/ symlink, etc.). Do not use git stash push -a — stash mixes real WIP with binary cruft.

Use a WIP commit as a bookmark, then reset (not git revert) to restore edits after cleanup:

  1. git checkout -b debug/<topic> (or stay on an existing debug branch).

  2. Analysis edits (logging, temporary probes, etc.). Commit only what you mean — prefer git add <paths> over blind git commit -a, so build noise on tracked files is not swept into the WIP commit.

  3. git commit -m "wip: debug …" if there are changes worth preserving (see Husky below if commit fails).

  4. Build packaged CLI and binary (see building skill): yarn lerna run build-cli --scope cypress, then env -u ELECTRON_RUN_AS_NODE yarn binary-build / binary-package with matching --version (discover via env -u ELECTRON_RUN_AS_NODE node packages/server/index.js --version) and --platform.

  5. Repro with packaged entrypoints (below).

  6. Restore workspace:

    bash
    git clean -xfd && yarn
    

    Then either:

    • git reset HEAD~1 (mixed, default) if step 3 succeeded — WIP commit becomes unstaged changes again; not git revert.
    • git restore --staged --worktree <paths> if there was no WIP commit (instrumentation-only files listed in step 2). Remove any temporary helper files (e.g. packages/server/lib/util/debug-agent-log.js) with rm.
  7. Repeat from step 2.

Rules: Do not git reset HEAD~1 after pushing that WIP commit unless you intend to rewrite remote history. Untracked files not in the WIP commit are gone after git clean -xfd. .cursor/skills/ is gitignored except !.cursor/skills — skills survive git clean -xfd; other .cursor/* files may not.

Husky: If git commit fails with missing .husky/_/husky.sh, do not loop on commit. Proceed with staged instrumentation, then restore via git restore in step 6 (or fix Husky / run yarn so hooks install, then commit).

Alternative: a separate git worktree for binary-only work avoids the commit/reset dance; see the building skill’s reset section.

Packaged CLI entrypoint

After yarn lerna run build-cli --scope cypress:

bash
node <repo>/cli/build/dist/bin/cypress <command>

Rollup emits the instrumented entry at cli/build/dist/bin/cypress. cli/build/bin/cypress is a thin copy of cli/bin/cypress (loads ../dist/cli via a different path) and is not the same as the Rollup bundle — do not use it for artifact or agent-log repro.

Prefer an absolute path when cwd might confuse postinstall-relative logic.

Point the CLI at your packaged binary

bash
export CYPRESS_RUN_BINARY=/path/to/platform/executable

Set the real executable (validated in cli/lib/tasks/state.ts via realpath), not the .app folder alone:

OSExample shape
macOS…/Cypress.app/Contents/MacOS/Cypress
Linux…/Cypress (unpacked binary)
win32…/Cypress.exe

Align CLI package version with the binary --version used at build time when possible.

Log and trace flags

  • DEBUG=cypress:cli* — CLI install, verify, spawn.
  • DEBUG=cypress:electron* — Electron install/open; CLI spawn also uses cypress:electron.
  • ELECTRON_ENABLE_LOGGING=1 — unfiltered Electron stderr (packages/electron/src/open.ts).
  • Prefer scoped DEBUG patterns over DEBUG=cypress:*.

Attach debuggers

  • CLI (Node): node --inspect-brk <repo>/cli/build/dist/bin/cypress <command>
  • Electron main (packaged): node <repo>/cli/build/dist/bin/cypress open --inspect-brk (or --inspect); forwarded in cli/lib/exec/open.ts / run.ts. Use with CYPRESS_RUN_BINARY so the debuggee is your local package output.

Debug-session instrumentation (agents)

When using Cursor debug-mode HTTP ingest (127.0.0.1:7709, session log under .cursor/debug-<session>.log):

  • Entry layers to tag: CLI bin → CLI init → CLI spawn (only when the binary is spawned, not for version) → packages/server/index.js (startCypress) → packages/server/start-cypress.js.
  • Short-lived CLI: fire-and-forget fetch alone often loses events because the process exits first. Also appendFileSync the same NDJSON line to the session log path (or a small debug-agent-log.js helper on the server side) in addition to fetch.
  • Verify server layers without a full green binary: env -u ELECTRON_RUN_AS_NODE node packages/server/index.js --version from packages/server (exercises index + start-cypress; unset ELECTRON_RUN_AS_NODE if the agent host sets it).
  • Verify CLI layers: node cli/build/dist/bin/cypress version (does not hit spawn). CLI bin is unaffected by ELECTRON_RUN_AS_NODE for the version subcommand, but binary-build still needs the var unset.

What to skip

  • --dev on open / run
  • Assuming yarn dev matches packaged behavior (cli/lib/tasks/verify.ts uses scripts/start.js when dev is true)

Common workspace gotcha after yarn

If yarn / Vite fails on urqlSchema or urqlCacheKeys imports from @packages/data-context, stale packages/data-context/src/**/*.js files may be shadowing .ts. Regenerate (yarn workspace @packages/data-context build) and remove .js siblings that have a matching .ts under packages/data-context/src/ before retrying yarn.