Overview
The TestDriver client is the main entry point for the SDK. It manages authentication, sandbox connections, and provides access to all testing methods — element finding, actions, assertions, and provisioning.
Constructor
import TestDriver from 'testdriverai' ;
const testdriver = new TestDriver ( options ? )
// or with explicit API key
const testdriver = new TestDriver ( apiKey , options ? )
Your TestDriver API key. If omitted, loaded automatically from the TD_API_KEY environment variable or .env file.
Configuration options for the client. API key (alternative to passing as first argument). Falls back to TD_API_KEY env var.
apiRoot
string
default: "https://testdriver-api.onrender.com"
API endpoint URL. Override for self-hosted deployments. Can also be set via TD_API_ROOT env var.
Operating system for the sandbox: 'windows' or 'linux'. Can also be set via TD_OS env var.
Screen resolution for the sandbox (e.g., '1920x1080', '1366x768').
Enable or disable usage analytics.
Enable or disable console logging.
Automatically capture screenshots before and after each command. Screenshots are saved to .testdriver/screenshots/<test>/ with descriptive filenames. See Screenshots for details. Force creation of a new sandbox instead of reusing an existing one.
Reconnect to the last used sandbox instead of creating a new one. When true, all provision methods are skipped since the application is already running. Throws error if no previous sandbox exists. Keep sandbox alive for the specified number of milliseconds after disconnect. Set to 0 to terminate immediately. Useful for debugging or reconnecting to the same sandbox.
preview
PreviewMode
default: "browser"
Preview mode for live test visualization:
"browser" — Opens debugger in default browser (default)
"ide" — Opens preview in IDE panel (VS Code, Cursor — requires TestDriver extension)
"none" — Headless mode, no visual preview
Deprecated : Use preview: "none" instead.
Keep the sandbox alive when a test fails so you can reconnect and debug interactively. The sandbox stays alive for 5 minutes and connection instructions are logged to the console.
Direct IP address to connect to a running sandbox instance (for self-hosted deployments).
Custom AMI ID for the sandbox instance (AWS deployments, e.g., 'ami-1234').
EC2 instance type for the sandbox (AWS deployments, e.g., 'i3.metal').
Enable or disable Dashcam video recording. cache
boolean | CacheConfig
default: true
Enable or disable element caching , or provide advanced threshold configuration. Enable or disable caching.
Cache key for grouping cached results. Auto-generated from the calling test file’s content hash when not provided.
Fine-tune cache matching. Thresholds for find() operations. Pixel diff threshold for screen comparison (0–1). 0.05 = 5% diff allowed.
OpenCV template match threshold for element matching (0–1). 0.8 = 80% correlation required.
Pixel diff threshold for assert() operations (0–1). 0.05 = 5% diff allowed.
Legacy : Use cache.cacheKey instead. Cache key for element finding operations.
redraw
boolean | RedrawConfig
default: false
Enable or disable screen-change (redraw) detection. Disabled by default since v7.3 — individual commands still use their own redraw options. Enable or disable global redraw detection.
Threshold configuration. Pixel diff threshold (0–1). Set to false to disable screen redraw detection.
Enable or disable network activity monitoring.
Additional environment variables to pass to the sandbox as key-value pairs.
Global AI sampling configuration. Controls how the AI model generates responses for find() verification and assert() calls. Can be overridden per-command. AI model to use (e.g., "gpt-4o", "claude-3").
Provider API key for BYOK (bring your own key).
Custom endpoint URL for the AI provider.
Enable thinking/reasoning mode for the AI model.
Controls randomness in AI responses. 0 = deterministic (best for verification), higher values = more creative.
Nucleus and top-k sampling parameters. Top-P (nucleus sampling). Limits token choices to smallest set whose cumulative probability exceeds P. Range: 0–1.
Top-K sampling. Limits token choices to top K most likely tokens. 1 = always pick most likely. 0 = disabled.
Examples
import TestDriver from 'testdriverai' ;
// Minimal — API key from .env
const testdriver = new TestDriver ();
// Specify OS and resolution
const testdriver = new TestDriver ({
os: 'windows' ,
resolution: '1920x1080' ,
});
// With explicit API key
const testdriver = new TestDriver ( 'your-api-key' , {
os: 'windows' ,
});
// With AI config and caching
const testdriver = new TestDriver ({
ai: { temperature: 0 , top: { p: 0.9 , k: 40 } },
cache: {
thresholds: {
find: { screen: 0.03 , element: 0.85 },
assert: 0.03 ,
},
},
});
// Self-hosted
const testdriver = new TestDriver ({
ip: '192.168.1.100' ,
apiRoot: 'https://my-testdriver.internal.com' ,
});
Lifecycle Methods
auth()
Authenticate with the TestDriver API. Exchanges your API key for a session token.
Returns: Promise<void>
You must call auth() before connect(). When using the Vitest hook or presets, this is handled automatically.
connect()
Connect to a sandbox environment. Creates or reconnects to a virtual machine where tests run.
await testdriver . connect ( options ? )
Connection options that override constructor settings. Existing sandbox ID to reconnect to.
Force creation of a new sandbox.
Reconnect to last used sandbox.
Direct IP address (self-hosted).
Override OS for this connection.
preview
PreviewMode
default: "browser"
Preview mode: "browser", "ide", or "none".
Reuse existing connection if connected.
Keep sandbox alive after disconnect (ms).
Returns: Promise<Object> — Sandbox instance details including instanceId, ip, vncPort.
// Basic connection
await testdriver . connect ();
// Reconnect to existing sandbox
await testdriver . connect ({ sandboxId: 'existing-sandbox-id-123' });
// Self-hosted
await testdriver . connect ({ ip: '192.168.1.100' });
ready()
Convenience method that calls auth() + connect() in sequence.
Returns: Promise<void>
const testdriver = new TestDriver ({ os: 'linux' });
await testdriver . ready (); // Authenticates and connects
disconnect()
Disconnect from the sandbox and clean up resources.
await testdriver . disconnect ()
Returns: Promise<void>
afterAll ( async () => {
await testdriver . disconnect ();
});
Always call disconnect() in cleanup hooks (afterAll, finally blocks). This prevents orphaned sandboxes from consuming resources.
getInstance()
Get the current sandbox instance details.
const instance = testdriver . getInstance ()
Returns: Object | null — Sandbox instance info (instanceId, ip, etc.)
getSessionId()
Get the current session ID for tracking and debugging.
const sessionId = testdriver . getSessionId ()
Returns: string | null
Properties
Property Type Description connectedbooleanWhether the SDK is connected to a sandbox osstringTarget operating system ('windows' or 'linux') resolutionstringScreen resolution (e.g., '1366x768') provisionProvisionAPIProvision API for launching appsdashcamDashcamLazy-initialized Dashcam instance dashcamEnabledbooleanWhether Dashcam recording is enabled autoScreenshotsbooleanWhether auto-screenshots are enabled optionsobjectResolved configuration options emitterEventEmitter2Event emitter for custom event handlingloggingEnabledbooleanWhether console logging is enabled
Static Properties
Property Type Description TestDriver.versionstringSDK version string
Logging & Events
setLogging()
Toggle console logging at runtime.
testdriver . setLogging ( enabled )
Whether to enable logging.
testdriver . setLogging ( false );
await testdriver . disconnect ();
testdriver . setLogging ( true );
getEmitter()
Get the EventEmitter2 instance for custom event handling.
const emitter = testdriver . getEmitter ()
Returns: EventEmitter2 — Supports wildcard events with : delimiter.
const emitter = testdriver . getEmitter ();
emitter . on ( 'command:start' , ( data ) => {
console . log ( 'Command started:' , data );
});
emitter . on ( 'command:success' , ( data ) => {
console . log ( 'Command succeeded:' , data );
});
emitter . on ( 'command:error' , ( error ) => {
console . error ( 'Command failed:' , error );
});
See Events for the full list of event namespaces.
getLogs() / clearLogs()
Access and manage the internal log buffer. Logs are stored in JSONL format for S3 upload.
const logData = testdriver . getLogs () // string (JSONL)
testdriver . clearLogs ()
Test Run Tracking
createTestRun()
Create a new test run in the TestDriver API.
const run = await testdriver . createTestRun ( options )
Returns: Promise<object> — Test run metadata.
completeTestRun()
Mark a test run as complete.
await testdriver . completeTestRun ( options )
recordTestCase()
Record an individual test case result.
await testdriver . recordTestCase ( options )
setTestContext()
Set the Vitest test context for automatic test metadata tracking.
testdriver . setTestContext ( context )
Vitest task context (context.task).
Unawaited Promise Detection
The SDK tracks the last returned promise. If a new command is called before the previous promise resolves, it logs a warning:
⚠️ Previous TestDriver command was not awaited!
Always await every TestDriver command to prevent race conditions:
// ❌ Missing await — will trigger warning
testdriver . find ( 'button' ). click ();
testdriver . type ( 'hello' );
// ✅ Correct
await testdriver . find ( 'button' ). click ();
await testdriver . type ( 'hello' );
Types
type PreviewMode = "browser" | "ide" | "none" ;
interface TestDriverOptions {
apiKey ?: string ;
apiRoot ?: string ;
os ?: "windows" | "linux" ;
resolution ?: string ;
analytics ?: boolean ;
logging ?: boolean ;
autoScreenshots ?: boolean ;
newSandbox ?: boolean ;
reconnect ?: boolean ;
keepAlive ?: number ;
preview ?: PreviewMode ;
headless ?: boolean ; // @deprecated → preview: "none"
debugOnFailure ?: boolean ;
ip ?: string ;
sandboxAmi ?: string ;
sandboxInstance ?: string ;
dashcam ?: boolean ;
cache ?: boolean | CacheConfig ;
cacheKey ?: string ; // @deprecated → cache.cacheKey
redraw ?: boolean | RedrawConfig ;
environment ?: Record < string , any >;
ai ?: AIConfig ;
}
interface CacheConfig {
enabled ?: boolean ;
cacheKey ?: string ;
thresholds ?: {
find ?: {
screen ?: number ; // Default: 0.05
element ?: number ; // Default: 0.8
};
assert ?: number ; // Default: 0.05
};
}
interface RedrawConfig {
enabled ?: boolean ;
thresholds ?: {
screen ?: number | false ; // Default: 0.05
network ?: boolean ; // Default: false
};
}
interface AIConfig {
model ?: string ;
provider ?: string ;
apiKey ?: string ;
baseURL ?: string ;
thinking ?: boolean ;
temperature ?: number ;
top ?: {
p ?: number ;
k ?: number ;
};
}
interface ConnectOptions {
sandboxId ?: string ;
newSandbox ?: boolean ;
reconnect ?: boolean ;
ip ?: string ;
os ?: "windows" | "linux" ;
sandboxAmi ?: string ;
sandboxInstance ?: string ;
preview ?: PreviewMode ;
reuseConnection ?: boolean ; // Default: true
keepAlive ?: number ; // Default: 60000
}
Environment Variables
The SDK reads these environment variables (also from .env files):
Variable Description Default TD_API_KEYAPI key for authentication — TD_API_ROOTAPI endpoint URL https://testdriver-api.onrender.comTD_OSDefault OS linux
Complete Example
import { beforeAll , afterAll , describe , it } from 'vitest' ;
import TestDriver from 'testdriverai' ;
describe ( 'My Test Suite' , () => {
let testdriver ;
beforeAll ( async () => {
testdriver = new TestDriver ({
os: 'windows' ,
resolution: '1366x768' ,
logging: true ,
cache: {
thresholds: {
find: { screen: 0.05 , element: 0.8 },
assert: 0.05 ,
},
},
});
const emitter = testdriver . getEmitter ();
emitter . on ( 'log:info' , ( msg ) => console . log ( '[INFO]' , msg ));
await testdriver . auth ();
const instance = await testdriver . connect ();
console . log ( 'Connected:' , instance . instanceId );
});
afterAll ( async () => {
await testdriver . disconnect ();
});
it ( 'runs a test' , async () => {
await testdriver . provision . chrome ({ url: 'https://example.com' });
await testdriver . find ( 'Get Started button' ). click ();
});
});
Best Practices
Reuse sandboxes across tests
Use beforeAll/afterAll to create one sandbox per test suite. This significantly reduces execution time vs creating a sandbox per test.
Handle connection errors gracefully
Wrap connect() in try-catch to handle network issues or quota limits: try {
await testdriver . connect ();
} catch ( error ) {
console . error ( 'Connection failed:' , error . message );
throw error ;
}
Always disconnect in cleanup
Use afterAll or try-finally blocks to ensure disconnect() is called even if tests fail: afterAll ( async () => {
await testdriver . disconnect ();
});
Use environment variables for API keys
Never hardcode API keys: TD_API_KEY = your_api_key_here
// API key loaded automatically
const testdriver = new TestDriver ();
Use debugOnFailure for debugging
When a test fails and you need to inspect the sandbox interactively: const testdriver = new TestDriver ({
debugOnFailure: true
});
The sandbox stays alive for 5 minutes after failure, and connection instructions are logged.