Test self-hosted environments end to end changedself-hosted-environments-testing
Nearest release: v2.1.296, published 6 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 9 Oct 2026 23:38 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 10 Oct 2026 00:07 UTC.
Upstream edited
Recorded here
Lines+14added
Lines−4removed
From line
75
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits9to this page, all time
The whole hunk
from line 75, old and new numbered
/
from line 75
7575
7676The `--environment` and `--ref` dispatch flags require Claude Code v2.1.224 or later on the machine that runs the script, the same floor as the runner itself. With the hook in place and a runner started on this host, the test script:
7777
781. Creates a session on the test environment with `claude -p "<prompt>" --environment <environment-id> --output-format json`, run from a git checkout so the CLI can auto-detect the repository from the `origin` remote. The optional `--ref <branch>` bases the session's checkout on a named ref instead of local HEAD. The command creates the session, prints one line of JSON containing `session_id`, and exits without waiting for Claude's reply.
781. Creates a session on the test environment with `claude -p "<prompt>" --environment <environment-id> --output-format json`. Run the command from a git checkout so the CLI can auto-detect the repository from the `origin` remote. The optional `--ref <branch>` bases the session's checkout on a named ref instead of local HEAD. The command exits without waiting for Claude's reply. What it prints tells your script the outcome:
79 * **Session created**: one line of JSON such as `{"ok":true,"session_id":"session_...","title":"...","url":"...","pool_id":"..."}`
80 * **Session creation failed**: the line `{"ok":false,"error":"..."}`, and the command exits with status 1
81 * **Some earlier errors**, such as cloud sessions being unavailable for your organization or a missing prompt: the error on stderr with no JSON line, and the command exits with status 1
79822. Waits for the reply to appear in `$E2E_REPLY_DIR/<session_id>.txt`, written by the Stop hook on the runner once the turn completes.
80833. Sends a follow-up with `claude -p "<message>" --cloud <session_id> --output-format json` (see [Send a follow-up message to a running session](/docs/en/claude-code-on-the-web#send-follow-ups-from-the-cli)), which posts a user event to the existing session and exits.
81844. Waits for the follow-up's reply the same way as step 2.
from line 91
8891
8992## Example script
9093
91The script below runs the full loop against `$CLAUDE_TEST_ENVIRONMENT_ID`, your test environment's `ccpool_...` ID, shown in the environment's detail dialog on the admin page or returned by the [create-environment call](#create-a-dedicated-test-environment), and asserts on a sentinel phrase in each reply. Run it from a git checkout of the repository you want the session to work in, after starting a runner on this host with the capture hook installed and `E2E_REPLY_DIR` exported. First sign in with a claude.ai account on the machine that runs the script, as [Authenticate from CI](#authenticate-from-ci) describes. Without that sign-in, the first dispatch fails with an error such as `Unable to get organization UUID for cloud session creation`.
94The example script runs on the same machine as the test runner. Before you run it, prepare that machine:
9295
96* **Repository checkout**: run the script from a git checkout of the repository you want the session to work in.
97* **Runner**: start a runner on this host with the capture hook installed and `E2E_REPLY_DIR` exported.
98* **Sign-in**: sign in with a claude.ai account on the machine that runs the script, as [Authenticate from CI](#authenticate-from-ci) describes.
99* **Environment ID**: set `CLAUDE_TEST_ENVIRONMENT_ID` to your test environment's `ccpool_...` ID, shown in the environment's detail dialog on the admin page or returned by the [create-environment call](#create-a-dedicated-test-environment).
100
101The script below runs the full loop against `$CLAUDE_TEST_ENVIRONMENT_ID` and asserts on a sentinel phrase in each reply.
102
93103```bash theme={null}
94104#!/usr/bin/env bash
95105# End-to-end test against a self-hosted environment, using Stop-hook read-back.
from line 146
136146TURN1="e2e-probe-$(date +%s)-$$: say exactly 'ok: custom tools are reachable' and nothing else"
137147EXPECT1="ok: custom tools are reachable"
138148create_json=$(claude -p "$TURN1" --environment "$CLAUDE_TEST_ENVIRONMENT_ID" \
139 --ref "$TEST_REPO_REF" --output-format json)
149 --ref "$TEST_REPO_REF" --output-format json < /dev/null)
140150echo "create: $create_json"
141151SESSION_ID=$(jq -er '.session_id' <<<"$create_json")
142152
from line 157
147157# 3. Post a follow-up via the CLI.
148158TURN2="e2e-probe-followup-$(date +%s): say exactly 'ok: follow-up delivered' and nothing else"
149159EXPECT2="ok: follow-up delivered"
150followup_json=$(claude -p "$TURN2" --cloud "$SESSION_ID" --output-format json)
160followup_json=$(claude -p "$TURN2" --cloud "$SESSION_ID" --output-format json < /dev/null)
151161echo "followup: $followup_json"
152162jq -e '.ok == true' <<<"$followup_json" >/dev/null
153163
No line in this hunk matches that.