Skip to main content
Run your tests on a machine you control instead of a cloud sandbox. It can be a laptop, a lab machine, or a VM in your own data center. Use it when the cloud can’t reproduce the machine under test, for example:
  • Specific hardware, or a device plugged in over USB.
  • A licensed desktop app.
  • An app that only reaches your internal network.
The machine runs the TestDriver runner. Your test sends commands to it through the TestDriver API.
The runner only makes outbound connections, to the TestDriver API and to Ably for realtime messages. You don’t need to open an inbound port.
For Windows EC2 instances that start and stop automatically, use the AWS setup instead.

Before you begin

The machine needs:
  • Node.js 18 or newer.
  • Python 3 with pyautogui and Pillow. The runner uses them for the mouse, keyboard, and screenshots.
  • An unlocked desktop session. The runner drives the real screen, so turn off sleep, screen savers, and lock timers.
  • Outbound HTTPS and WebSocket access to api.testdriver.ai and *.ably.io.
  • curl and jq, to register the machine in step 2.
You also need your TestDriver API key in TD_API_KEY. Copy it from the API keys page.
macOS blocks synthetic input and screen capture until you allow them. Open System Settings → Privacy & Security and add the terminal app that starts the runner to both lists:
  • Accessibility, so the runner can move the mouse and type.
  • Screen Recording, so the runner can take screenshots.
Quit and reopen the terminal after you change these settings.

Step 1: Install the runner

This installs the testdriver-sandbox-agent command, which connects the machine to a TestDriver session.

Step 2: Register the machine

Ask the API for a session on this machine. Replace 192.168.1.50 with the machine’s IP address, and set os to windows on a Windows machine:
The response includes a sandbox ID and an agentConfig object with everything the runner needs. Write agentConfig to the runner’s config file, and print the sandbox ID:
On Windows, run these commands in Git Bash and write the file to /c/Windows/Temp/testdriver-agent.json instead. Save the sandbox ID, such as sb-69cce96e-1e0, for step 4.
The config file contains your API key and a session token. Keep it readable only by the user who runs the runner, and never commit it.
To keep the config file somewhere else, set CONFIG_PATH to its full path before you start the runner. A registered machine uses one of your plan’s concurrency slots while its session is open.

Step 3: Start the runner

The runner reads the config file, connects, and waits for commands:
Leave it running. If the config file doesn’t exist yet, the runner waits up to 5 minutes for it.

Step 4: Point your test at the machine

Pass the machine’s ip and the sandboxId from step 2 to TestDriver(). Setting sandboxId stops TestDriver from creating a cloud sandbox.
tests/my-machine.test.mjs
On a Windows machine, also pass os: 'windows'.
Run these tests with the CI environment variable unset. When CI is set, TestDriver always requests a new sandbox and ignores sandboxId, so the test waits for a runner that never connects.
Run the test from any computer:
Each registration covers one session. When the test disconnects, the session ends. Repeat steps 2 and 3 before the next run.

Logs

The runner also writes testdriver-agent-status.json in the same folder, with the sandbox ID, process ID, IP address, and start time.

Security

  • Use a dedicated machine or user account. The runner can click anything on the desktop and run shell commands sent by your tests.
  • Treat the config file as a secret. It contains your API key and a session token.
  • Keep VNC private. If you add a VNC server for debugging, expose it only on localhost or your VPN.
  • Rotate your API key on the API keys page when you retire or share a machine.

Troubleshooting

The session ended, which happens after a test disconnects or the session’s keepAlive runs out. Repeat steps 2 and 3 for a fresh sandbox ID, and use the new ID in your test.
Accessibility or Screen Recording permission is missing. Add your terminal app to both lists in System Settings → Privacy & Security, then quit and reopen it.
The runner couldn’t find the config file. Write it on the same machine, readable by the user who starts the runner, or set CONFIG_PATH to where it is.
Check that both TD_MACHINE_IP and TD_SANDBOX_ID are set when you run the test. If sandboxId is undefined, TestDriver creates a cloud sandbox.
DISPLAY points at a display with no desktop, or the screen blanked. Start a desktop on that display and turn off blanking with xset s off && xset s noblank && xset -dpms.

Runner environment variables

Next steps

Self-host on AWS

Start a fresh Windows EC2 instance for each test.

Self-hosted

What the Enterprise plan includes.

Locate elements

Describe elements so TestDriver finds them on any screen.

Make assertions

Check that your app reached the right state.