CLI

Test browser workflows with the CLI

Resolve browser targets, inspect the supported API, verify UI actions, and recover asynchronous work.

Resolve the browser before testing it

Use browser commands for UI inspection, navigation, and testing. Use the project and document APIs for work that should continue independently of a browser tab. A valid account login does not by itself select the right browser or authorize every browser action.

Step 1: Discover and verify an existing session

Sign in using the quickstart, open the intended project in CoCalc, and list browser sessions:

export CLI_PROFILE=cocalc-ai
export PROJECT_ID='REPLACE_WITH_FULL_PROJECT_ID'

cocalc --profile "$CLI_PROFILE" --json browser session list

Choose the session you intend to test and copy its full browser ID:

export BROWSER_ID='REPLACE_WITH_BROWSER_ID'

cocalc --profile "$CLI_PROFILE" --json browser target-resolve \
  --project-id "$PROJECT_ID" --browser "$BROWSER_ID" \
  --active-only --require-discovery

This resolves the target without performing a browser action. Confirm data.browser_id and data.resolved.project_id, and require no data.resolved.project_error. An outer ok:true can accompany a project resolution error. The active project reported by the session can differ from your explicit target; inspect that difference before acting.

For a local source-development server, reload its matching dev:hub:env or dev:lite:env in the current shell before discovery. See authentication and targets.

Step 2: Read the session's API and inspect the page

cocalc --profile "$CLI_PROFILE" browser exec-api \
  --browser "$BROWSER_ID" --session-project-id "$PROJECT_ID" --active-only

cocalc --profile "$CLI_PROFILE" --json browser exec \
  --project-id "$PROJECT_ID" --browser "$BROWSER_ID" --posture prod \
  'return { projectId: api.projectId, pageUrl: api.pageUrl };'

For synchronous browser exec, check outer ok:true, data.ok:true, the selected browser/project, and the returned data.result. This example inspects the page; it does not demonstrate that a later UI action will be permitted or succeed.

The declaration comes from the running browser session. In constrained QuickJS mode, window, document, and top-level await are unavailable. The exposed API calls behave synchronously from the script's point of view. For example, after inspecting the page and choosing an expected visible string:

cocalc --profile "$CLI_PROFILE" --json browser exec \
  --project-id "$PROJECT_ID" --browser "$BROWSER_ID" --posture prod \
  'return api.waitForText({ includes: "REPLACE_WITH_VISIBLE_TEXT", timeout_ms: 5000 });'

Require data.result.ok:true for this assertion. A successful exec envelope can contain an unsuccessful assertion result.

Step 3: Use a stable action and verify its result

Discover documented UI destinations before inventing selectors:

cocalc docs actions --executable
cocalc docs action settings.environment.secrets
cocalc browser action docs --help

When opening the project's secrets settings is the intended UI action:

cocalc --profile "$CLI_PROFILE" --json browser action docs \
  settings.environment.secrets \
  --project-id "$PROJECT_ID" --browser "$BROWSER_ID"

Opening settings does not modify a secret. Inspect the returned action result and then verify the visible destination. Prefer a stable action ID over a selector tied to incidental page layout.

Policies and capabilities

Without an explicit posture or COCALC_BROWSER_POSTURE override, CLI posture defaults to dev for loopback targets and prod otherwise. The site also enforces its own automation and raw-execution policy. Choosing a posture or supplying --allow-raw-exec cannot override a server-side denial. Read the returned declaration and policy information; do not assume every session exposes the same API or that a stale browser has received new code.

Local Playwright session spawning is not supported in standalone CLI binaries. An existing browser session and a source-built CLI have different capabilities. Check browser session --help and your installed build before choosing a test strategy.

Recover asynchronous browser work

browser exec --async returns an exec_id. Keep that ID and the browser ID. Use these commands to inspect, wait, or deliberately request cancellation:

cocalc --profile "$CLI_PROFILE" --json browser exec-get "$EXEC_ID" \
  --browser "$BROWSER_ID"
cocalc --profile "$CLI_PROFILE" --json browser exec-wait "$EXEC_ID" \
  --browser "$BROWSER_ID" --timeout 5m
cocalc --profile "$CLI_PROFILE" --json browser exec-cancel "$EXEC_ID" \
  --browser "$BROWSER_ID"

Set EXEC_ID to the returned ID before running these examples. An exec_id is neither a project execution job_id nor a hub operation op_id. A wait timeout does not cancel the execution. Read its current state before resubmitting work. Even a completed execution still needs the script-specific assertion checks.

browser action batch runs steps sequentially and can leave earlier actions applied when a later one fails. Inspect failed_steps and individual step results rather than treating a successful outer response as an atomic batch success. --continue-on-error changes whether later steps are attempted; it does not roll back earlier ones.

Collect evidence for a failed UI test

cocalc --profile "$CLI_PROFILE" --json browser logs tail \
  --browser "$BROWSER_ID" --lines 50
cocalc --profile "$CLI_PROFILE" --json browser logs uncaught \
  --browser "$BROWSER_ID" --no-follow --lines 50
cocalc browser network summary --help
cocalc browser network trace --help

Record the target, relevant logs, expected UI state, and observed state. Network capture may need to be enabled before reproducing an issue; an empty buffer does not establish that no requests failed. Limit and review captured data before sharing it. Clear or stop capture deliberately when finished.