testdriver-agent
How the TestDriver agent behaves on GitHub issues, pull requests, and @mentions
Listen to SDK lifecycle events with wildcard support
Claude Code
$ npx -y skills add testdriverai/testdriverai --skill testdriver-events --agent claude-code
Codex
$ npx skills add testdriverai/testdriverai --skill testdriver-events -a codex -y
Cursor
$ npx skills add testdriverai/testdriverai --skill testdriver-events -a cursor -y
Gemini CLI
$ npx skills add testdriverai/testdriverai --skill testdriver-events -a gemini-cli -y
GitHub Copilot
$ npx skills add testdriverai/testdriverai --skill testdriver-events -a github-copilot -y
OpenCode
$ npx skills add testdriverai/testdriverai --skill testdriver-events -a opencode -y
Windsurf
$ npx skills add testdriverai/testdriverai --skill testdriver-events -a windsurf -y
name: testdriver:events description: Listen to SDK lifecycle events with wildcard support
<!-- Generated from events.mdx. DO NOT EDIT. -->
TestDriver uses [EventEmitter2](https://github.com/EventEmitter2/EventEmitter2) for its event system. Events use a namespace pattern with colons. They permit wildcard listeners.
Use the emitter through `testdriver.emitter`:
testdriver.emitter.on('command:start', (data) => {
console.log(`Running: ${data.command}`);
});The internal emitter is created with:
new EventEmitter2({
wildcard: true,
delimiter: ':',
maxListeners: 20,
verboseMemoryLeak: false,
ignoreErrors: false,
});Use `*` to match one level. Use `**` to match many levels:
// Match all log events
testdriver.emitter.on('log:*', (message) => {
console.log(message);
});
// Match all events in any namespace
testdriver.emitter.on('**', (...args) => {
console.log('Event:', this.event, args);
});Emitted during the execution of SDK commands (`click`, `type`, `find`, etc.).
| Event | Payload | |---|---| | `command:start` | `{ command, depth, data, timestamp, sourcePosition }` | | `command:success` | `{ command, depth, data, duration, response, timestamp, sourcePosition }` | | `command:error` | `{ command, depth, data, error, duration, timestamp, sourcePosition }` | | `command:status` | `{ command, status: "executing", data, depth, timestamp }` | | `command:progress` | `{ command, status: "completed", timing, data, depth, timestamp }` |
testdriver.emitter.on('command:start', ({ command, data }) => {
console.log(`Starting ${command}`, data);
});
testdriver.emitter.on('command:error', ({ command, error, duration }) => {
console.error(`${command} failed after ${duration}ms: ${error}`);
});Emitted for each AI reasoning step within a command.
| Event | Payload | |---|---| | `step:start` | `{ stepIndex, prompt, commandCount, timestamp, sourcePosition }` | | `step:success` | `{ stepIndex, prompt, commandCount, duration, timestamp, sourcePosition }` | | `step:error` | `{ stepIndex, prompt, error, duration?, timestamp, sourcePosition? }` |
testdriver.emitter.on('step:start', ({ stepIndex, prompt }) => {
console.log(`Step ${stepIndex}: ${prompt}`);
});Emitted when a test file execution starts.
| Event | Payload | |---|---| | `test:start` | `{ filePath, timestamp }` | | `test:success` | *Emitted on test completion* | | `test:error` | *Emitted on test failure* |
Emitted for all log output from the SDK.
| Event | Payload | |---|---| | `log:log` | `(message: string)` — general log message | | `log:warn` | `(message: string)` — warning message | | `log:debug` | `(message: string)` — debug output (only when `VERBOSE`/`DEBUG`/`TD_DEBUG` env set) | | `log:info` | `(message: string)` — informational message | | `log:error` | `(message: string)` — error message | | `log:narration` | `(message: string, overwrite?: boolean)` — in-place status line | | `log:markdown` | `(markdown: string)` — full static markdown content | | `log:markdown:start` | `(streamId: string)` — begin streaming markdown | | `log:markdown:chunk` | `(streamId: string, chunk: string)` — incremental chunk | | `log:markdown:end` | `(streamId: string)` — end streaming markdown |
// Capture all logs
testdriver.emitter.on('log:*', function (message) {
console.log(`[${this.event}]`, message);
});Emitted during screenshot capture.
| Event | Payload | |---|---| | `screen-capture:start` | `{ scale, silent, display }` | | `screen-capture:end` | `{ scale, silent, display }` | | `screen-capture:error` | `{ error, scale, silent, display }` |
Emitted for sandbox WebSocket lifecycle and communication.
| Event | Payload | |---|---| | `sandbox:connected` | *No payload* — WebSocket connection established | | `sandbox:authenticated` | `{ traceId }` — authentication successful | | `sandbox:error` | `(err: Error \| string)` — connection or sandbox error | | `sandbox:sent` | `(message: object)` — WebSocket message sent | | `sandbox:received` | *No payload* — successful message reply received | | `sandbox:progress` | `{ step, message }` — sandbox setup progress |
testdriver.emitter.on('sandbox:connected', () => {
console.log('Connected to sandbox');
});
testdriver.emitter.on('sandbox:progress', ({ step, message }) => {
console.log(`Sandbox: [${step}] ${message}`);
});Emitted during screen stability detection. See [Redraw](/redraw) for more details.
| Event | Payload | |---|---| | `redraw:status` | `{ redraw: { enabled, settled, hasChangedFromInitial, consecutiveFramesStable, diffFromInitial, diffFromLast, text }, network: { enabled, settled, rxBytes, txBytes, text }, timeout: { isTimeout, elapsed, max, text } }` | | `redraw:complete` | `{ screenSettled, hasChangedFromInitial, consecutiveFramesStable, networkSettled, isTimeout, timeElapsed }` |
testdriver.emitter.on('redraw:complete', (result) => {
if (result.isTimeout) {
console.warn('Redraw timed out after', result.timeElapsed, 'ms');
}
});Emitted during file load/save operations in the agent.
| Event | Payload | |---|---| | `file:start` | `{ operation: "load" \| "save" \| "run", filePath, timestamp }` | | `file:stop` | `{ operation, filePath, duration, success, sourceMap?, reason?, timestamp }` | | `file:load` | `{ filePath, size, timestamp }` | | `file:save` | `{ filePath, size, timestamp }` | | `file:diff` | `{ filePath, diff: { patches, sourceMaps, summary: { additions, deletions, modifications } }, timestamp }` | | `file:error` | `{ operation, filePath, error, duration?, timestamp }` |
Emitted for errors at various severity levels.
| Event | Payload | |---
How the TestDriver agent behaves on GitHub issues, pull requests, and @mentions
Deploy TestDriver on your AWS infrastructure using CloudFormation
How TestDriver learns your app and caches what it discovers for instant, deterministic replays
Produce the "Playwright 1.xx API Review" artifact for a range of commits - the public API additions and the breaking or behavior…
Write, refine, run, and QA promptfoo evaluation suites: promptfooconfig.yaml, prompts, providers, vars, tests, assertions,…
DeepEval evaluation workflow for AI agents and LLM applications. TRIGGER when the user wants to evaluate or improve an AI agent,…