@testdriverai/agent 7.11.229-test → 7.11.231-test

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/docs/_data/examples-manifest.json +16 -16
  2. package/docs/_scripts/generate-examples.js +38 -45
  3. package/docs/agent.mdx +174 -93
  4. package/docs/assert.mdx +73 -269
  5. package/docs/aws-setup.mdx +196 -314
  6. package/docs/bring-your-own-machine.mdx +139 -206
  7. package/docs/cache.mdx +144 -151
  8. package/docs/caching.mdx +99 -89
  9. package/docs/captcha.mdx +126 -111
  10. package/docs/ci-cd.mdx +154 -543
  11. package/docs/click.mdx +74 -229
  12. package/docs/client.mdx +177 -231
  13. package/docs/copilot/auto-healing.mdx +86 -370
  14. package/docs/copilot/running-tests.mdx +121 -930
  15. package/docs/customizing-devices.mdx +74 -251
  16. package/docs/dashcam.mdx +72 -405
  17. package/docs/debugging-with-screenshots.mdx +105 -371
  18. package/docs/docs.json +75 -18
  19. package/docs/double-click.mdx +48 -68
  20. package/docs/errors.mdx +102 -176
  21. package/docs/events.mdx +170 -327
  22. package/docs/examples/{hover-text-with-description.mdx → add-to-cart.mdx} +30 -35
  23. package/docs/examples/assert.mdx +28 -41
  24. package/docs/examples/click-button.mdx +71 -0
  25. package/docs/examples/{hover-image.mdx → click-icon.mdx} +32 -28
  26. package/docs/examples/element-not-found.mdx +27 -26
  27. package/docs/examples/findall-coffee-icons.mdx +28 -32
  28. package/docs/examples/installer.mdx +61 -25
  29. package/docs/examples/launch-vscode-linux.mdx +28 -51
  30. package/docs/examples/navigate-and-scroll.mdx +82 -0
  31. package/docs/examples/parse.mdx +24 -28
  32. package/docs/examples/press-keys.mdx +28 -25
  33. package/docs/examples/scroll.mdx +25 -27
  34. package/docs/examples/type.mdx +26 -21
  35. package/docs/exec.mdx +92 -256
  36. package/docs/extract.mdx +69 -170
  37. package/docs/find.mdx +140 -736
  38. package/docs/focus-application.mdx +69 -246
  39. package/docs/generating-tests.mdx +103 -137
  40. package/docs/guide/best-practices-polling.mdx +65 -141
  41. package/docs/hosted.mdx +80 -144
  42. package/docs/hover.mdx +62 -235
  43. package/docs/locating-elements.mdx +74 -369
  44. package/docs/making-assertions.mdx +116 -74
  45. package/docs/mcp-setup.mdx +80 -63
  46. package/docs/mouse-down.mdx +48 -125
  47. package/docs/mouse-up.mdx +47 -129
  48. package/docs/options.mdx +75 -48
  49. package/docs/parse.mdx +95 -184
  50. package/docs/performing-actions.mdx +104 -94
  51. package/docs/press-keys.mdx +59 -299
  52. package/docs/provision.mdx +137 -182
  53. package/docs/quickstart-claude.mdx +85 -0
  54. package/docs/quickstart-github.mdx +62 -32
  55. package/docs/quickstart-manual.mdx +60 -33
  56. package/docs/quickstart-vscode.mdx +97 -0
  57. package/docs/quickstart.mdx +25 -9
  58. package/docs/redraw.mdx +101 -165
  59. package/docs/reusable-code.mdx +97 -200
  60. package/docs/right-click.mdx +47 -89
  61. package/docs/screenshot.mdx +47 -201
  62. package/docs/screenshots.mdx +87 -137
  63. package/docs/scroll.mdx +71 -154
  64. package/docs/secrets.mdx +96 -91
  65. package/docs/self-hosted.mdx +83 -142
  66. package/docs/snippets/enterprise.mdx +15 -0
  67. package/docs/styles.css +68 -0
  68. package/docs/test-results-json.mdx +167 -204
  69. package/docs/type.mdx +56 -304
  70. package/docs/variables.mdx +121 -81
  71. package/docs/wait.mdx +33 -31
  72. package/docs/what-is-testdriver.mdx +80 -32
  73. package/examples/{hover-text-with-description.test.mjs → add-to-cart.test.mjs} +4 -5
  74. package/examples/assert.test.mjs +3 -20
  75. package/examples/{hover-text.test.mjs → click-button.test.mjs} +3 -4
  76. package/examples/{hover-image.test.mjs → click-icon.test.mjs} +5 -6
  77. package/examples/element-not-found.test.mjs +3 -5
  78. package/examples/findall-coffee-icons.test.mjs +3 -3
  79. package/examples/installer.test.mjs +1 -1
  80. package/examples/launch-vscode-linux.test.mjs +6 -33
  81. package/examples/{scroll-keyboard.test.mjs → navigate-and-scroll.test.mjs} +4 -5
  82. package/examples/parse.test.mjs +1 -2
  83. package/examples/press-keys.test.mjs +4 -4
  84. package/examples/scroll.test.mjs +3 -6
  85. package/examples/type.test.mjs +5 -2
  86. package/lib/provision.js +6 -2
  87. package/package.json +1 -1
  88. package/sdk.d.ts +4 -2
  89. package/sdk.js +1 -1
  90. package/docs/claude-mcp-plugin.mdx +0 -244
  91. package/docs/elements.mdx +0 -606
  92. package/docs/examples/ai.mdx +0 -78
  93. package/docs/examples/captcha-api.mdx +0 -92
  94. package/docs/examples/chrome-extension.mdx +0 -156
  95. package/docs/examples/drag-and-drop.mdx +0 -100
  96. package/docs/examples/formatted-logging.mdx +0 -74
  97. package/docs/examples/hover-text.mdx +0 -70
  98. package/docs/examples/match-image.mdx +0 -97
  99. package/docs/examples/scroll-keyboard.mdx +0 -80
  100. package/docs/examples/scroll-until-text.mdx +0 -109
@@ -21,10 +21,6 @@
21
21
  "url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62b99dc33133fc0da9440",
22
22
  "lastUpdated": "2026-03-03T00:32:25.282Z"
23
23
  },
24
- "hover-text-with-description.test.mjs": {
25
- "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b5f0022b6043aeec2beb",
26
- "lastUpdated": "2026-10-20T00:30:09.018Z"
27
- },
28
24
  "windows-installer.test.mjs": {
29
25
  "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b5f29af2067e32da0685",
30
26
  "lastUpdated": "2026-10-20T00:33:18.176Z"
@@ -41,10 +37,6 @@
41
37
  "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b5eeff9c1cd5b2e06bf9",
42
38
  "lastUpdated": "2026-10-20T00:30:38.454Z"
43
39
  },
44
- "hover-image.test.mjs": {
45
- "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b5f59af2067e32da0686",
46
- "lastUpdated": "2026-10-20T00:29:41.180Z"
47
- },
48
40
  "installer.test.mjs": {
49
41
  "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b5f79af2067e32da0688",
50
42
  "lastUpdated": "2026-10-20T00:29:43.255Z"
@@ -59,10 +51,6 @@
59
51
  "embedUrl": "https://console-test.testdriver.ai/replay/6ad6b808ff9c1cd5b2e06c32?share=5iVQVpaLc2kTqD7pV7nynA&embed=true",
60
52
  "lastUpdated": "2026-10-20T00:38:38.191Z"
61
53
  },
62
- "scroll-keyboard.test.mjs": {
63
- "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b600022b6043aeec2bf0",
64
- "lastUpdated": "2026-10-20T00:30:55.250Z"
65
- },
66
54
  "scroll.test.mjs": {
67
55
  "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b6069af2067e32da068a",
68
56
  "lastUpdated": "2026-10-20T00:30:29.949Z"
@@ -91,10 +79,6 @@
91
79
  "url": "https://console-test.testdriver.ai/runs/69c8738614b73310c7839412/69c873a714b73310c7839450",
92
80
  "lastUpdated": "2026-03-29T00:36:10.628Z"
93
81
  },
94
- "hover-text.test.mjs": {
95
- "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b60a022b6043aeec2bf1",
96
- "lastUpdated": "2026-10-20T00:30:33.458Z"
97
- },
98
82
  "no-provision.test.mjs": {
99
83
  "url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62b7706a177a05bccd1cf",
100
84
  "lastUpdated": "2026-03-03T00:32:25.279Z"
@@ -180,6 +164,22 @@
180
164
  "exec-stream-logs.test.mjs": {
181
165
  "url": "https://console-test.testdriver.ai/runs/69c9c4feffa05350a7d3abc1/69c9c520ffa05350a7d3abd9",
182
166
  "lastUpdated": "2026-03-30T00:35:14.437Z"
167
+ },
168
+ "click-icon.test.mjs": {
169
+ "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b5f59af2067e32da0686",
170
+ "lastUpdated": "2026-10-20T00:29:41.180Z"
171
+ },
172
+ "click-button.test.mjs": {
173
+ "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b60a022b6043aeec2bf1",
174
+ "lastUpdated": "2026-10-20T00:30:33.458Z"
175
+ },
176
+ "add-to-cart.test.mjs": {
177
+ "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b5f0022b6043aeec2beb",
178
+ "lastUpdated": "2026-10-20T00:30:09.018Z"
179
+ },
180
+ "navigate-and-scroll.test.mjs": {
181
+ "url": "https://console-test.testdriver.ai/runs/6ad6b5ebff9c1cd5b2e06bf7/6ad6b600022b6043aeec2bf0",
182
+ "lastUpdated": "2026-10-20T00:30:55.250Z"
183
183
  }
184
184
  }
185
185
  }
@@ -108,11 +108,18 @@ function transformContentForDocs(content) {
108
108
  ''
109
109
  );
110
110
 
111
- // Replace getDefaults(context) spread with inline defaults
112
- transformed = transformed.replace(
113
- /\{\s*\.\.\.getDefaults\(context\)\s*/g,
114
- '{ ip: context.ip || process.env.TD_IP'
115
- );
111
+ // Drop CI-only TestDriver options so readers see the minimal setup:
112
+ // `...getDefaults(context)` (sandbox IP, preview and cache settings for CI)
113
+ // and `headless: true` (deprecated, and only there to keep CI runs headless).
114
+ transformed = transformed.replace(/\.\.\.getDefaults\(context\),?\s*/g, '');
115
+ transformed = transformed.replace(/headless:\s*true,?\s*/g, '');
116
+ // `TestDriver(context, { })` left empty by the removals above
117
+ transformed = transformed.replace(/TestDriver\(context,\s*\{\s*\}\s*\)/g, 'TestDriver(context)');
118
+ // Tidy `{ ` / ` }` padding left behind on single-line option objects
119
+ transformed = transformed.replace(/TestDriver\(context,\s*\{\s*([^{}\n]*?)\s*\}\)/g, 'TestDriver(context, { $1 })');
120
+
121
+ // Drop the file's leading JSDoc header; the page's intro already says what the test does
122
+ transformed = transformed.replace(/^\/\*\*\n[\s\S]*?\n\s*\*\/\n+/, '');
116
123
 
117
124
  return transformed;
118
125
  }
@@ -123,8 +130,8 @@ function parseTestFile(filePath) {
123
130
  const content = transformContentForDocs(raw);
124
131
  const filename = path.basename(filePath);
125
132
 
126
- // Extract JSDoc comment at top of file
127
- const jsdocMatch = content.match(/^\/\*\*\n([\s\S]*?)\n\s*\*\//);
133
+ // Extract JSDoc comment at top of file (from the raw source; the docs copy strips it)
134
+ const jsdocMatch = raw.match(/^\/\*\*\n([\s\S]*?)\n\s*\*\//);
128
135
  const jsdoc = jsdocMatch
129
136
  ? jsdocMatch[1]
130
137
  .split("\n")
@@ -197,7 +204,7 @@ async function generateAIDescription(testMeta, options) {
197
204
  return generateFallbackDescription(testMeta);
198
205
  }
199
206
 
200
- const prompt = `You are a technical writer for TestDriver.ai documentation. Generate a concise 2-3 paragraph description for this test example.
207
+ const prompt = `You are a technical writer for TestDriver.ai documentation. Write the one- or two-sentence introduction for this test example's docs page.
201
208
 
202
209
  Test file: ${testMeta.filename}
203
210
  Test suite name: ${testMeta.describeName || "N/A"}
@@ -209,12 +216,7 @@ Test code:
209
216
  ${testMeta.content}
210
217
  \`\`\`
211
218
 
212
- Write a description that:
213
- 1. Explains what this test demonstrates (first paragraph)
214
- 2. Describes the key TestDriver SDK methods used (second paragraph)
215
- 3. Mentions any important patterns or best practices shown (optional third paragraph)
216
-
217
- Keep it professional and focused on helping developers understand the example. Do not include code blocks in your response.`;
219
+ Say what the test does and which TestDriver methods it demonstrates, in second person and present tense (for example: "This test opens the login page and uses \`assert()\` to check that it loaded."). No marketing words, no headings, no code blocks.`;
218
220
 
219
221
  try {
220
222
  const response = await fetch("https://api.openai.com/v1/chat/completions", {
@@ -226,7 +228,7 @@ Keep it professional and focused on helping developers understand the example. D
226
228
  body: JSON.stringify({
227
229
  model: "gpt-4o-mini",
228
230
  messages: [{ role: "user", content: prompt }],
229
- max_tokens: 500,
231
+ max_tokens: 150,
230
232
  temperature: 0.7,
231
233
  }),
232
234
  });
@@ -260,10 +262,6 @@ function generateFallbackDescription(testMeta) {
260
262
  );
261
263
  }
262
264
 
263
- parts.push(
264
- "\nReview the source code below to understand the implementation details and patterns used."
265
- );
266
-
267
265
  return parts.join("\n");
268
266
  }
269
267
 
@@ -397,62 +395,52 @@ description: "${shortDescription.replace(/"/g, '\\"')}"
397
395
  icon: "${testMeta.icon}"
398
396
  ---
399
397
 
400
- ## Overview
401
-
402
398
  ${description}
403
399
 
404
400
  `;
405
401
 
406
- // Add Live Test Run section if URL exists
402
+ // Recording of the latest CI run, if the manifest has one
407
403
  if (replayEmbedUrl) {
408
- mdx += `## Live Test Run
409
-
410
- Watch this test execute in a real sandbox environment:
404
+ mdx += `## Watch it run
411
405
 
412
406
  {/* ${testMeta.filename} output */}
413
- <iframe
414
- src="${replayEmbedUrl}"
415
- width="100%"
416
- height="600"
407
+ <iframe
408
+ src="${replayEmbedUrl}"
409
+ width="100%"
410
+ height="600"
417
411
  style={{ border: "1px solid #333", borderRadius: "8px" }}
418
412
  allow="fullscreen"
419
413
  />
420
414
 
421
415
  `;
422
416
  } else {
423
- mdx += `## Live Test Run
417
+ mdx += `## Watch it run
424
418
 
425
419
  <Note>
426
- A live test recording will be available after the next CI run.
420
+ A recording appears here after the next CI run.
427
421
  </Note>
428
422
 
429
423
  `;
430
424
  }
431
425
 
432
- // Add Source Code section
433
- mdx += `## Source Code
426
+ mdx += `## The test
434
427
 
435
428
  \`\`\`javascript title="${testMeta.filename}"
436
429
  ${testMeta.content.trim()}
437
430
  \`\`\`
438
431
 
439
- ## Running This Example
432
+ ## Run it
433
+
434
+ The test is in the [TestDriver SDK repository](https://github.com/testdriverai/testdriverai/tree/main/examples). Clone it, install dependencies, and run the file:
440
435
 
441
436
  \`\`\`bash
442
- # Clone the TestDriver repository
443
437
  git clone https://github.com/testdriverai/testdriverai
444
-
445
- # Install dependencies
446
438
  cd testdriverai
447
439
  npm install
448
-
449
- # Run this specific example
450
- vitest run examples/${testMeta.filename}
440
+ npx vitest run examples/${testMeta.filename}
451
441
  \`\`\`
452
442
 
453
- <Note>
454
- Make sure you have \`TD_API_KEY\` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
455
- </Note>
443
+ The test reads your API key from \`TD_API_KEY\`. Create a key at [console.testdriver.ai/team/api-keys](https://console.testdriver.ai/team/api-keys). Then set it in your environment or a \`.env\` file.
456
444
  `;
457
445
 
458
446
  return mdx;
@@ -491,8 +479,13 @@ function updateDocsNavigation(docsJson, examplePages, options) {
491
479
  }
492
480
 
493
481
  if (examplesGroup) {
494
- // Update existing group
495
- examplesGroup.pages = examplesPages;
482
+ // Keep the hand-picked order of pages already in the sidebar, drop pages
483
+ // whose test file is gone, and append new examples at the end.
484
+ const kept = examplesGroup.pages.filter(
485
+ (p) => typeof p === "string" && examplesPages.includes(p)
486
+ );
487
+ const added = examplesPages.filter((p) => !kept.includes(p));
488
+ examplesGroup.pages = [...kept, ...added];
496
489
  if (options.verbose) {
497
490
  console.log("🔄 Updated existing Examples group in navigation");
498
491
  }
package/docs/agent.mdx CHANGED
@@ -1,102 +1,183 @@
1
1
  ---
2
- title: "The TestDriver Agent"
2
+ title: "The TestDriver agent"
3
3
  sidebarTitle: "Introduction"
4
- description: "How the TestDriver agent behaves on GitHub issues, pull requests, and @mentions"
4
+ description: "How the TestDriver agent reviews pull requests, builds tests, and answers @mentions on GitHub."
5
5
  icon: "hand-horns"
6
6
  ---
7
7
 
8
- The TestDriver agent is an AI teammate in your GitHub repository. It is
9
- **code review that runs your app**. It does not only read a diff and guess
10
- what can break. It starts a real sandbox, controls the real app, and reports what
11
- really happens.
12
-
13
- ## Scope: it only builds and maintains tests
14
-
15
- The agent has one purpose. It does one thing: it **writes, debugs, fixes, and keeps
16
- automated tests** with TestDriver. It reviews pull requests. It writes and runs
17
- a test against the change. It does not do work that is not in scope. It does not edit
18
- your application code, fix product bugs, answer other programming questions, or
19
- act as a general coding assistant.
20
-
21
- ## How it behaves depends on the surface
22
-
23
- The agent reacts to three different GitHub surfaces. Its behavior is
24
- different on each one.
25
-
26
- | Surface | Trigger | What it does |
27
- |---------|---------|--------------|
28
- | **Pull request opened** | Automatic (no mention) | Silent, evidence-based **code review** |
29
- | **Issue opened** | Automatic (no mention) | **Onboarding / test-building** |
30
- | **@mention** (issue or PR) | You mention the bot | Interactive, chatty conversation |
31
-
32
- ## Pull requests — automatic code review
33
-
34
- When a pull request is **opened**, the agent reviews it automatically. Nobody has
35
- to ask.
36
-
37
- - **The review is the deliverable, not chatter.** No person asks for an automatic review.
38
- Thus the agent stays quiet while it works. It posts a **single review
39
- comment** at the end. It does not put many inline threads across the diff. It does not
40
- tell each step.
41
- - **It runs the change when it can.** Its default first move is to start a session,
42
- work out what the PR changes from a user's point of view, and write and run a
43
- TestDriver test that exercises exactly that. A bug it *watched happen* is far
44
- more valuable than one it inferred.
45
- - **Findings are labeled by how they were found.** Each finding is marked
46
- `observed` (proven by actually running the change) or `suspected` (reasoned out
47
- from reading the diff). If the installation isn't signed in to TestDriver, the
48
- agent can't run anything, so it reviews by reading and marks every finding
49
- `suspected`.
50
- - **It focuses on real bugs.** Logic errors, regressions, broken edge cases,
51
- mishandled errors — not style, naming, or "consider extracting this."
52
- - **Zero findings is a good review.** If the change looks correct, it says so in a
53
- sentence. If there's nothing worth reviewing (only lockfiles, generated files, or
54
- formatting), it posts nothing at all.
55
- - **It comments, it never blocks.** The review is always a `COMMENT` — it never
56
- approves and never requests changes, so it can't gate a merge.
57
-
58
- It also fires a native GitHub **Check Run** for the PR's TestDriver suite, and
59
- re-runs that check on every push (not a full re-review — push more commits and
60
- @mention the agent if you want it to review again).
61
-
62
- <Note>
63
- The agent never reviews its own pull requests. PRs opened by the bot are skipped,
64
- so it won't wake itself up to review the tests it just committed.
65
- </Note>
66
-
67
- ## Issues — onboarding and test building
68
-
69
- When an issue is **opened**, the agent treats it as a cue to help you build a test.
70
-
71
- - **If the issue describes a task**, it acts on the request — writing or debugging
72
- the test you asked for.
73
- - **If the issue is empty**, it introduces itself, explains that it writes and
74
- debugs computer-use tests, and walks you through signing in to TestDriver and
75
- creating your first test.
76
- - **It finishes by opening a pull request** with the test it wrote.
77
-
78
- ## @mentions — interactive conversation
79
-
80
- Mentioning the bot (on either an issue or a PR) starts a **solicited**, interactive
81
- turn. Because you asked directly, the agent is chatty: it posts progress updates,
82
- shows you screenshots of what's happening in the sandbox, and answers follow-ups in
83
- the thread.
84
-
85
- On a PR, an @mention overrides the silent auto-review behavior — you'll see the full
86
- play-by-play instead of just the final review comment.
87
-
88
- You can also manage the agent from a comment:
89
-
90
- - **`@bot logout`** (or "sign out") revokes the installation's shared TestDriver
91
- sign-in and tears down the live sandbox, so the next mention will prompt whoever
92
- responds to sign in again.
8
+ The TestDriver agent is an AI teammate that lives in your GitHub repository.
9
+
10
+ - It reviews every pull request's code for bugs.
11
+ - For user-visible changes, it drives your app in a real sandbox and reports what happened.
12
+ - It writes, runs, and maintains your end-to-end tests.
13
+
14
+ To install it, see [Add TestDriver to GitHub](/quickstart-github).
15
+
16
+ ## What the agent does
17
+
18
+ The agent does two jobs:
19
+
20
+ - **Code review.** It reviews pull requests like a senior engineer. It reads the diff for logic errors, security problems, and regressions. When it can, it runs the change in a sandbox to prove what it finds.
21
+ - **Test building.** It writes new TestDriver tests, debugs and fixes failing ones, and keeps them up to date.
22
+
23
+ It declines work outside that scope:
24
+
25
+ - It doesn't edit your application code.
26
+ - It doesn't fix product bugs.
27
+ - It doesn't act as a general coding assistant.
28
+
29
+ When it finds a bug in a pull request, it reports the bug instead of pushing a fix.
30
+
31
+ ## How it responds on each surface
32
+
33
+ The agent behaves differently depending on what woke it up:
34
+
35
+ | Event | Trigger | What the agent does |
36
+ | --- | --- | --- |
37
+ | Pull request opened, or new commits pushed | Automatic | Reviews the change and posts one review comment |
38
+ | Issue opened | Automatic | Acts on the request in the issue, or onboards a new user |
39
+ | @mention on an issue or pull request | You mention the agent | Works with you interactively in the thread |
40
+
41
+ Automatic turns are unsolicited, so the agent posts only when it has something useful to say.
42
+
43
+ When you @mention it, someone is waiting. It always replies and narrates its progress.
44
+
45
+ ## Pull request reviews
46
+
47
+ The agent reviews a pull request without being asked when it's opened or gets new commits.
48
+
49
+ <Steps>
50
+ <Step title="Triage the change">
51
+
52
+ The agent reads the changed files and decides whether there's anything to review or run.
53
+
54
+ A pull request that only touches lockfiles, generated output, or formatting gets an 👀 reaction and no comment.
55
+
56
+ </Step>
57
+ <Step title="Read the code">
58
+
59
+ It reviews the diff like a senior engineer. It opens surrounding files only when the diff isn't enough on its own.
60
+
61
+ It looks for:
62
+
63
+ - Logic errors
64
+ - Unhandled error paths
65
+ - Security problems
66
+ - Race conditions
67
+ - Broken contracts for callers
68
+ - Risky logic with no tests
69
+
70
+ It skips style issues that a linter would catch.
71
+
72
+ </Step>
73
+ <Step title="Run the change">
74
+
75
+ This step runs if the change has a user-visible surface and your installation is signed in to TestDriver. The agent:
76
+
77
+ - Starts a sandbox.
78
+ - Drives the exact flow the diff touches.
79
+ - Runs any existing tests that cover it.
80
+ - Writes and runs a new test for the change.
81
+
82
+ While it works, a single comment on the pull request shows the latest screenshot. The comment finishes with the run recording.
83
+
84
+ </Step>
85
+ <Step title="Post the review">
86
+
87
+ It posts one review comment with:
88
+
89
+ - A summary and verdict
90
+ - A short walkthrough of each meaningful file
91
+ - Its findings
92
+
93
+ On a re-review after a push, it reassesses its earlier findings against the new code. It drops the fixed ones and checks the new commits for regressions.
94
+
95
+ </Step>
96
+ </Steps>
97
+
98
+ ### What's in a finding
99
+
100
+ Each finding has:
101
+
102
+ - A file and line
103
+ - A severity: `critical`, `major`, `minor`, or `nit`
104
+ - A category
105
+ - A suggested replacement, when the fix is small and certain
106
+
107
+ Findings are also labelled by how the agent found them:
108
+
109
+ - **`observed`**: the agent saw the bug happen during a run in the sandbox.
110
+ - **`suspected`**: the agent inferred the bug from reading the code.
111
+
112
+ If a run confirms a suspected finding, the agent upgrades it to `observed` instead of listing it twice.
113
+
114
+ If the change looks correct, the review says so in a sentence and has no findings.
115
+
116
+ ### The review never blocks a merge
117
+
118
+ Reviews are posted as GitHub `COMMENT` reviews. The agent never approves a pull request or requests changes, so it can't gate a merge.
119
+
120
+ ### Tests from a review
121
+
122
+ During a review, the agent may write a test worth keeping: one that passes, or one that cleanly reproduces a bug.
123
+
124
+ It opens a separate pull request for that test and links it from the review. The pull request uses a `testdriver/session/…` branch and targets your default branch.
125
+
126
+ It never pushes to the branch it's reviewing.
127
+
128
+ ### Pull requests the agent skips
129
+
130
+ - **Draft pull requests** get no review until they're marked ready for review.
131
+ - **Pull requests opened by bots** are never reviewed. This includes the agent's own test pull requests, so it doesn't review its own work.
132
+ - **Teams without a subscription** don't get automatic reviews, because automatic review is a paid feature. If your team has used its allowance, the pull request gets one short notice explaining why there's no review.
133
+
134
+ ## Issues
135
+
136
+ When an issue is opened, the agent reads its title and description:
137
+
138
+ - **If the issue describes a test task**, the agent does it. It asks you to sign in only if a step needs it.
139
+ - **If the issue is empty** and you look like a new user, the agent introduces itself. It walks you through signing in to TestDriver and creating your first test.
140
+ - **If the agent can't help with the issue**, such as a product bug report or a feature request, it stays silent instead of posting an off-topic reply.
141
+
142
+ Whenever the agent creates or changes a test file, it finishes by opening a pull request with the test.
143
+
144
+ ## @mentions
145
+
146
+ Mention the agent on an issue or pull request to start an interactive conversation. Because you asked directly, the agent:
147
+
148
+ - Posts progress updates and sandbox screenshots as it works.
149
+ - Answers follow-up questions in the thread.
150
+ - Opens a pull request with any test it writes.
151
+
152
+ On a pull request, an @mention gets you this play-by-play instead of the quiet automatic review.
153
+
154
+ ### Sign out
155
+
156
+ To revoke your installation's TestDriver sign-in, mention the agent with `logout`:
157
+
158
+ ```text
159
+ @testdriverai logout
160
+ ```
161
+
162
+ `sign out` and `disconnect` work too.
163
+
164
+ The agent revokes the installation's shared sign-in and shuts down its live sandbox. The next person to mention it is asked to sign in again.
93
165
 
94
166
  ## Signing in
95
167
 
96
- Reading a diff needs nothing, but **running** the app needs a TestDriver session,
97
- which requires the installation to be signed in. Sign-in state doesn't decide
98
- *whether* the agent reviews — it decides *how good* the review gets. A signed-out
99
- install still gets its bugs caught from reading the code; signing in upgrades
100
- findings from `suspected` to `observed`.
168
+ Reading a diff doesn't need a TestDriver account, but running your app does.
169
+
170
+ When your installation isn't signed in, the agent still reviews pull requests by reading the code. It marks every finding `suspected`.
171
+
172
+ Signing in lets it run each change, so findings it proves become `observed`.
173
+
174
+ ## Related
101
175
 
102
- test
176
+ <CardGroup cols={2}>
177
+ <Card title="Add TestDriver to GitHub" icon="github" href="/quickstart-github">
178
+ Install the GitHub app and get your first review.
179
+ </Card>
180
+ <Card title="Run tests in CI/CD" icon="code-branch" href="/ci-cd">
181
+ Run your TestDriver suite in GitHub Actions and other CI systems.
182
+ </Card>
183
+ </CardGroup>