@testdriverai/mcp 7.9.150-test → 7.9.152-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.
- package/ai/skills/testdriver-caching/SKILL.md +13 -6
- package/ai/skills/testdriver-ci-cd/SKILL.md +20 -34
- package/ai/skills/testdriver-client/SKILL.md +5 -1
- package/ai/skills/testdriver-debugging-with-screenshots/SKILL.md +14 -4
- package/ai/skills/testdriver-find/SKILL.md +2 -0
- package/ai/skills/testdriver-generating-tests/SKILL.md +159 -8
- package/ai/skills/testdriver-machine-setup/SKILL.md +75 -8
- package/ai/skills/testdriver-making-assertions/SKILL.md +78 -2
- package/ai/skills/testdriver-performing-actions/SKILL.md +97 -2
- package/ai/skills/testdriver-quickstart/SKILL.md +47 -28
- package/ai/skills/testdriver-wait/SKILL.md +1 -1
- package/ai/skills/testdriver:generating-tests/SKILL.md +0 -11
- package/docs/changelog.mdx +1 -1
- package/docs/docs.json +14 -39
- package/docs/v7/assert.mdx +0 -1
- package/docs/v7/caching.mdx +14 -10
- package/docs/v7/ci-cd.mdx +20 -34
- package/docs/v7/client.mdx +1 -1
- package/docs/v7/copilot/auto-healing.mdx +167 -18
- package/docs/v7/copilot/running-tests.mdx +915 -54
- package/docs/v7/debugging-with-screenshots.mdx +17 -7
- package/docs/v7/generating-tests.mdx +166 -10
- package/docs/v7/making-assertions.mdx +81 -4
- package/docs/v7/performing-actions.mdx +100 -4
- package/docs/v7/quickstart.mdx +299 -21
- package/docs/v7/wait.mdx +1 -1
- package/package.json +3 -3
- package/docs/v7/ai/agent.mdx +0 -72
- package/docs/v7/ai/mcp.mdx +0 -228
- package/docs/v7/ai/skills.mdx +0 -73
- package/docs/v7/ai.mdx +0 -205
- package/docs/v7/copilot/creating-tests.mdx +0 -156
- package/docs/v7/copilot/github.mdx +0 -143
- package/docs/v7/copilot/setup.mdx +0 -143
- package/docs/v7/device-config.mdx +0 -317
- package/docs/v7/locating-elements.mdx +0 -71
- package/docs/v7/machine-setup.mdx +0 -331
- package/docs/v7/running-tests.mdx +0 -185
- package/docs/v7/waiting-for-elements.mdx +0 -90
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: testdriver:performing-actions
|
|
3
|
-
description:
|
|
3
|
+
description: Perform actions and handle dynamic, async UI so tests adapt to change
|
|
4
4
|
---
|
|
5
5
|
<!-- Generated from performing-actions.mdx. DO NOT EDIT. -->
|
|
6
6
|
|
|
7
|
+
Real apps move, load, and change. Adapt your tests to handle it.
|
|
8
|
+
|
|
9
|
+
Once you've [generated](/v7/generating-tests) and [learned](/v7/caching) your tests and gotten them [running](/v7/copilot/running-tests), the next challenge is the real world: buttons appear after a spinner, pages navigate, animations play, and content streams in over the network. To keep tests reliable, you need to perform the right actions and handle timing so your tests adapt to how the UI actually behaves instead of breaking.
|
|
10
|
+
|
|
7
11
|
## Performing Actions
|
|
8
12
|
|
|
9
13
|
TestDriver provides a variety of actions you can perform, like [clicking](/v7/click), [typing](/v7/type), [hovering](/v7/hover), and [scrolling](/v7/scroll). For a full list, see the [API Reference](/v7/click).
|
|
@@ -36,7 +40,7 @@ const price = await testdriver.extract('the total price');
|
|
|
36
40
|
const orderNumber = await testdriver.extract('the order confirmation number');
|
|
37
41
|
```
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
### Chaining Actions
|
|
40
44
|
|
|
41
45
|
TestDriver supports method chaining for cleaner code:
|
|
42
46
|
|
|
@@ -51,3 +55,94 @@ Or save element reference for later use:
|
|
|
51
55
|
const button = await testdriver.find('submit button');
|
|
52
56
|
await button.click();
|
|
53
57
|
```
|
|
58
|
+
|
|
59
|
+
## Waiting for Dynamic Content
|
|
60
|
+
|
|
61
|
+
By default, `find()` automatically polls for up to 10 seconds, retrying every 5 seconds until the element is found. This means most elements that appear after short async operations will be found without any extra configuration.
|
|
62
|
+
|
|
63
|
+
For longer operations, increase the `timeout`:
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
// Default behavior - polls for up to 10 seconds automatically
|
|
67
|
+
const element = await testdriver.find('Loading complete indicator');
|
|
68
|
+
await element.click();
|
|
69
|
+
|
|
70
|
+
// Wait up to 30 seconds for slower operations
|
|
71
|
+
const element = await testdriver.find('Loading complete indicator', { timeout: 30000 });
|
|
72
|
+
await element.click();
|
|
73
|
+
|
|
74
|
+
// Useful after actions that trigger loading states
|
|
75
|
+
await testdriver.find('submit button').click();
|
|
76
|
+
await testdriver.find('success message', { timeout: 15000 });
|
|
77
|
+
|
|
78
|
+
// Disable polling for instant checks
|
|
79
|
+
const toast = await testdriver.find('notification toast', { timeout: 0 });
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Flake Prevention
|
|
83
|
+
|
|
84
|
+
TestDriver automatically waits for the screen and network to stabilize after each action using **redraw detection**. This prevents flaky tests caused by animations, loading states, or dynamic content updates.
|
|
85
|
+
|
|
86
|
+
<Note>
|
|
87
|
+
Redraw detection adds a small delay after each action but significantly reduces test flakiness.
|
|
88
|
+
</Note>
|
|
89
|
+
|
|
90
|
+
For example, when clicking a submit button that navigates to a new page:
|
|
91
|
+
|
|
92
|
+
```javascript
|
|
93
|
+
// Click submit - TestDriver automatically waits for the new page to load
|
|
94
|
+
await testdriver.find('submit button').click();
|
|
95
|
+
|
|
96
|
+
// By the time this runs, the page has fully loaded and stabilized
|
|
97
|
+
await testdriver.assert('dashboard is displayed');
|
|
98
|
+
await testdriver.find('welcome message');
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Without redraw detection, you'd need manual waits or retries to handle the page transition. TestDriver handles this automatically by detecting when the screen stops changing and network requests complete.
|
|
102
|
+
|
|
103
|
+
You can disable redraw detection or customize its behavior:
|
|
104
|
+
|
|
105
|
+
```javascript
|
|
106
|
+
// Disable redraw detection for faster tests (less reliable)
|
|
107
|
+
const testdriver = TestDriver(context, {
|
|
108
|
+
redraw: false
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Here is an example of customizing redraw detection:
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
// Fine-tune redraw detection
|
|
116
|
+
const testdriver = TestDriver(context, {
|
|
117
|
+
redraw: {
|
|
118
|
+
enabled: true,
|
|
119
|
+
diffThreshold: 0.1, // Pixel difference threshold (0-1)
|
|
120
|
+
screenRedraw: true, // Monitor screen changes
|
|
121
|
+
networkMonitor: true, // Wait for network idle
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Simple Delays with `wait()`
|
|
127
|
+
|
|
128
|
+
For simple pauses — waiting for animations, transitions, or state changes after an action — use `wait()`:
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
// Wait for an animation to complete
|
|
132
|
+
await testdriver.find('menu toggle').click();
|
|
133
|
+
await testdriver.wait(2000);
|
|
134
|
+
|
|
135
|
+
// Wait for a page transition to settle
|
|
136
|
+
await testdriver.find('next page button').click();
|
|
137
|
+
await testdriver.wait(1000);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
<Note>
|
|
141
|
+
For waiting for specific **elements** to appear, prefer `find()` with a `timeout` option. Use `wait()` only for simple time-based pauses.
|
|
142
|
+
</Note>
|
|
143
|
+
|
|
144
|
+
Once your tests can reliably act on a changing UI and [assert](/v7/making-assertions) the results, the next step is figuring out what happened when something does go wrong.
|
|
145
|
+
|
|
146
|
+
<Card title="Next: Debug" icon="bug" href="/v7/debugging-with-screenshots">
|
|
147
|
+
Use screenshots and run output to see exactly what your test saw and pinpoint failures.
|
|
148
|
+
</Card>
|
|
@@ -9,6 +9,53 @@ TestDriver makes it easy to write automated computer-use tests for web browsers,
|
|
|
9
9
|
<Tip><a href="https://discord.com/invite/cWDFW8DzPm" target="_blank" rel="noreferrer">Join our Discord</a> if you have any questions or need help getting started!</Tip>
|
|
10
10
|
|
|
11
11
|
<Tabs>
|
|
12
|
+
<Tab title="Add to GitHub" icon="github">
|
|
13
|
+
|
|
14
|
+
Drop-in UI testing for any GitHub repository. Mention `@testdriverai` anywhere in your repo and it writes UI tests and catches regressions before they merge.
|
|
15
|
+
|
|
16
|
+
<Card
|
|
17
|
+
title="Add to GitHub"
|
|
18
|
+
icon="github"
|
|
19
|
+
href="https://go.testdriver.ai/github"
|
|
20
|
+
arrow
|
|
21
|
+
horizontal
|
|
22
|
+
>
|
|
23
|
+
Install the TestDriver GitHub app and start testing in minutes — no setup required.
|
|
24
|
+
</Card>
|
|
25
|
+
|
|
26
|
+
<Steps>
|
|
27
|
+
<Step title="Install the GitHub App">
|
|
28
|
+
Click **Add to GitHub** above and install TestDriver on the repositories you want to test.
|
|
29
|
+
</Step>
|
|
30
|
+
|
|
31
|
+
<Step title="Mention @testdriverai">
|
|
32
|
+
Open a pull request or issue and mention `@testdriverai` to have it write and run UI tests:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
@testdriverai Write a test that verifies the homepage loads and the signup button works.
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
TestDriver spawns a sandbox, writes the test, and posts results right in the conversation.
|
|
39
|
+
</Step>
|
|
40
|
+
|
|
41
|
+
<Step title="Catch Regressions Automatically">
|
|
42
|
+
Once your tests are committed, TestDriver runs them on every pull request and flags regressions before they merge.
|
|
43
|
+
</Step>
|
|
44
|
+
</Steps>
|
|
45
|
+
|
|
46
|
+
Want to use TestDriver from GitHub Copilot or the GitHub Mobile app instead? See the full GitHub guide:
|
|
47
|
+
|
|
48
|
+
<Card
|
|
49
|
+
title="GitHub Integration Guide"
|
|
50
|
+
icon="arrow-right"
|
|
51
|
+
href="/v7/copilot/auto-healing#use-testdriver-in-github"
|
|
52
|
+
arrow
|
|
53
|
+
horizontal
|
|
54
|
+
>
|
|
55
|
+
Use TestDriver from GitHub web, Copilot chat, PR reviews, and mobile.
|
|
56
|
+
</Card>
|
|
57
|
+
|
|
58
|
+
</Tab>
|
|
12
59
|
<Tab title="CLI" icon="terminal">
|
|
13
60
|
|
|
14
61
|
Get started quickly with the TestDriver CLI.
|
|
@@ -39,34 +86,6 @@ TestDriver makes it easy to write automated computer-use tests for web browsers,
|
|
|
39
86
|
</Step>
|
|
40
87
|
</Steps>
|
|
41
88
|
</Tab>
|
|
42
|
-
<Tab title="GitHub Copilot" icon="github">
|
|
43
|
-
|
|
44
|
-
Use the TestDriver VS Code extension with GitHub Copilot for an AI-powered testing workflow.
|
|
45
|
-
|
|
46
|
-
<Card
|
|
47
|
-
title="Install TestDriver for VS Code"
|
|
48
|
-
icon="/images/content/extension/vscode.svg"
|
|
49
|
-
href="vscode:extension/testdriver.testdriver"
|
|
50
|
-
arrow
|
|
51
|
-
horizontal
|
|
52
|
-
>
|
|
53
|
-
</Card>
|
|
54
|
-
|
|
55
|
-
The extension provides one-click sign-in, project initialization, a live preview panel for watching tests execute, and MCP server configuration for GitHub Copilot.
|
|
56
|
-
|
|
57
|
-
Once installed, follow the full setup guide to configure MCP and start building tests with AI assistance:
|
|
58
|
-
|
|
59
|
-
<Card
|
|
60
|
-
title="VS Code + Copilot Setup Guide"
|
|
61
|
-
icon="arrow-right"
|
|
62
|
-
href="/v7/copilot/setup"
|
|
63
|
-
arrow
|
|
64
|
-
horizontal
|
|
65
|
-
>
|
|
66
|
-
Sign in, initialize your project, and configure MCP for GitHub Copilot.
|
|
67
|
-
</Card>
|
|
68
|
-
|
|
69
|
-
</Tab>
|
|
70
89
|
<Tab title="Manual" icon="wrench">
|
|
71
90
|
|
|
72
91
|
Install TestDriver and manually create the files yourself.
|
|
@@ -47,4 +47,4 @@ await testdriver.wait();
|
|
|
47
47
|
const element = await testdriver.find('success message');
|
|
48
48
|
```
|
|
49
49
|
- Avoid excessively long timeouts to keep tests efficient.
|
|
50
|
-
- Use sparingly — TestDriver's [redraw detection](/v7/waiting-for-
|
|
50
|
+
- Use sparingly — TestDriver's [redraw detection](/v7/performing-actions#waiting-for-dynamic-content) automatically waits for screen and network stability after each action.
|
|
@@ -23,14 +23,3 @@ Type password Password123 into Password field
|
|
|
23
23
|
Push Submit button
|
|
24
24
|
Verify new page contains expected text 'logged in'
|
|
25
25
|
```
|
|
26
|
-
|
|
27
|
-
## AI Exploration Mode
|
|
28
|
-
|
|
29
|
-
Within a test, the `ai()` method lets TestDriver autonomously figure out how to accomplish a task. It's useful for dynamic or unpredictable UIs where explicit actions may be difficult to define.
|
|
30
|
-
|
|
31
|
-
```javascript
|
|
32
|
-
// Handle dynamic or unpredictable UI
|
|
33
|
-
await testdriver.ai('dismiss any popups or modals that appear');
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
<Info>Explicit commands are preferred for production tests, as they are cheaper, faster, and more reliable.</Info>
|
package/docs/changelog.mdx
CHANGED
|
@@ -93,7 +93,7 @@ This release includes all changes from v7.8.0-test.6 with version bumps across a
|
|
|
93
93
|
|
|
94
94
|
✨ New features
|
|
95
95
|
|
|
96
|
-
- **[GitHub Copilot integration](/v7/copilot/
|
|
96
|
+
- **[GitHub Copilot integration](/v7/copilot/running-tests)** — Use TestDriver directly from GitHub Copilot in VS Code. The new MCP server lets Copilot launch sandboxes, interact with elements, and run assertions through natural language. Includes guides for [creating tests](/v7/generating-tests), [running tests](/v7/copilot/running-tests), [GitHub Actions integration](/v7/copilot/auto-healing#use-testdriver-in-github), and [auto-healing](/v7/copilot/auto-healing).
|
|
97
97
|
|
|
98
98
|
🔧 Improvements
|
|
99
99
|
|
package/docs/docs.json
CHANGED
|
@@ -53,33 +53,16 @@
|
|
|
53
53
|
"/changelog"
|
|
54
54
|
]
|
|
55
55
|
},
|
|
56
|
-
{
|
|
57
|
-
"group": "GitHub Copilot",
|
|
58
|
-
"pages": [
|
|
59
|
-
"/v7/copilot/setup",
|
|
60
|
-
"/v7/copilot/creating-tests",
|
|
61
|
-
"/v7/copilot/running-tests",
|
|
62
|
-
"/v7/copilot/github",
|
|
63
|
-
"/v7/copilot/auto-healing"
|
|
64
|
-
]
|
|
65
|
-
},
|
|
66
56
|
{
|
|
67
57
|
"group": "Guide",
|
|
68
58
|
"pages": [
|
|
69
59
|
"/v7/generating-tests",
|
|
70
|
-
"/v7/device-config",
|
|
71
|
-
"/v7/machine-setup",
|
|
72
|
-
"/v7/locating-elements",
|
|
73
|
-
"/v7/waiting-for-elements",
|
|
74
|
-
"/v7/performing-actions",
|
|
75
|
-
"/v7/making-assertions"
|
|
76
|
-
]
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"group": "Running Tests",
|
|
80
|
-
"pages": [
|
|
81
|
-
"/v7/running-tests",
|
|
82
60
|
"/v7/caching",
|
|
61
|
+
"/v7/copilot/running-tests",
|
|
62
|
+
"/v7/making-assertions",
|
|
63
|
+
"/v7/performing-actions",
|
|
64
|
+
"/v7/debugging-with-screenshots",
|
|
65
|
+
"/v7/copilot/auto-healing",
|
|
83
66
|
"/v7/ci-cd",
|
|
84
67
|
"/v7/test-results-json"
|
|
85
68
|
]
|
|
@@ -91,7 +74,7 @@
|
|
|
91
74
|
"/v7/secrets",
|
|
92
75
|
"/v7/reusable-code",
|
|
93
76
|
{
|
|
94
|
-
"group": "Self-Hosting
|
|
77
|
+
"group": "Self-Hosting",
|
|
95
78
|
"icon": "server",
|
|
96
79
|
"pages": [
|
|
97
80
|
"/v7/aws-setup"
|
|
@@ -99,25 +82,9 @@
|
|
|
99
82
|
}
|
|
100
83
|
]
|
|
101
84
|
},
|
|
102
|
-
{
|
|
103
|
-
"group": "AI",
|
|
104
|
-
"icon": "robot",
|
|
105
|
-
"pages": [
|
|
106
|
-
"/v7/ai/agent",
|
|
107
|
-
"/v7/ai/skills",
|
|
108
|
-
"/v7/ai/mcp"
|
|
109
|
-
]
|
|
110
|
-
},
|
|
111
85
|
{
|
|
112
86
|
"group": "Actions",
|
|
113
87
|
"pages": [
|
|
114
|
-
{
|
|
115
|
-
"group": "ai",
|
|
116
|
-
"tag": "Beta",
|
|
117
|
-
"pages": [
|
|
118
|
-
"/v7/ai"
|
|
119
|
-
]
|
|
120
|
-
},
|
|
121
88
|
"/v7/assert",
|
|
122
89
|
"/v7/captcha",
|
|
123
90
|
"/v7/click",
|
|
@@ -366,6 +333,14 @@
|
|
|
366
333
|
}
|
|
367
334
|
},
|
|
368
335
|
"redirects": [
|
|
336
|
+
{
|
|
337
|
+
"source": "/v7/ai",
|
|
338
|
+
"destination": "/v7/quickstart"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"source": "/v7/ai/:slug*",
|
|
342
|
+
"destination": "/v7/quickstart"
|
|
343
|
+
},
|
|
369
344
|
{
|
|
370
345
|
"source": "/guides/github-actions",
|
|
371
346
|
"destination": "/v6/action/setup"
|
package/docs/v7/assert.mdx
CHANGED
package/docs/v7/caching.mdx
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
title: "Learn"
|
|
3
|
+
sidebarTitle: "Learn"
|
|
4
|
+
description: "How TestDriver learns your app and caches what it discovers for instant, deterministic replays"
|
|
5
|
+
icon: "brain"
|
|
5
6
|
---
|
|
6
7
|
|
|
7
|
-
TestDriver
|
|
8
|
+
Once the agent has [explored your app](/v7/generating-tests), TestDriver remembers what it found. Every element the AI vision agent discovers is cached with a vision fingerprint—a perceptual hash of the screen state where it was located. On the next run, TestDriver matches against that cache instead of calling the AI again. Passing tests replay instantly, deterministically, and cheaply.
|
|
8
9
|
|
|
10
|
+
This learning is what makes TestDriver fast. Intelligent caching delivers up to **1.7x faster** test execution by skipping redundant AI vision analysis—the agent only thinks when it sees something new.
|
|
9
11
|
|
|
10
12
|
```javascript
|
|
11
13
|
// First run: builds cache
|
|
@@ -17,7 +19,7 @@ await testdriver.find('submit button');
|
|
|
17
19
|
|
|
18
20
|
## Automatic Caching
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
Learning is enabled automatically with zero configuration. The cache key—the fingerprint TestDriver uses to recognize what it already knows—is computed from:
|
|
21
23
|
|
|
22
24
|
- **File hash**: SHA-256 hash of the test file contents
|
|
23
25
|
- **Selector prompt**: The exact text description passed to `find()`
|
|
@@ -53,7 +55,7 @@ You can clear the cache within the TestDriver console. There, you'll also find p
|
|
|
53
55
|
|
|
54
56
|
## Debugging Cache Hits and Misses
|
|
55
57
|
|
|
56
|
-
You can track cache performance in your tests:
|
|
58
|
+
You can track what TestDriver has learned by inspecting cache performance in your tests:
|
|
57
59
|
|
|
58
60
|
```javascript
|
|
59
61
|
test('monitor cache performance', async (context) => {
|
|
@@ -75,7 +77,7 @@ test('monitor cache performance', async (context) => {
|
|
|
75
77
|
|
|
76
78
|
## Configuring the Cache
|
|
77
79
|
|
|
78
|
-
You can configure
|
|
80
|
+
You can configure how TestDriver learns globally when initializing TestDriver:
|
|
79
81
|
|
|
80
82
|
```javascript
|
|
81
83
|
import { TestDriver } from 'testdriverai';
|
|
@@ -103,7 +105,7 @@ await testdriver.find('submit button', {
|
|
|
103
105
|
|
|
104
106
|
## Caching with Variables
|
|
105
107
|
|
|
106
|
-
Custom cache keys prevent cache pollution when using variables in prompts, dramatically improving cache hit rates.
|
|
108
|
+
Custom cache keys prevent cache pollution when using variables in prompts, dramatically improving cache hit rates—so TestDriver reuses what it learned even when your data changes.
|
|
107
109
|
|
|
108
110
|
```javascript
|
|
109
111
|
// ❌ Without cache key - creates new cache for each variable value
|
|
@@ -123,6 +125,8 @@ await testdriver.find(`order ${orderId} status`, {
|
|
|
123
125
|
});
|
|
124
126
|
```
|
|
125
127
|
|
|
128
|
+
## Next
|
|
126
129
|
|
|
127
|
-
|
|
128
|
-
|
|
130
|
+
<Card href="/v7/copilot/running-tests" title="Run" icon="play">
|
|
131
|
+
Now that TestDriver has learned your app, run your tests in CI and locally—replaying the cache for fast, deterministic results.
|
|
132
|
+
</Card>
|
package/docs/v7/ci-cd.mdx
CHANGED
|
@@ -7,37 +7,33 @@ icon: "code-branch"
|
|
|
7
7
|
|
|
8
8
|
TestDriver integrates seamlessly with popular CI providers, enabling automated end-to-end testing on every push and pull request.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Authentication
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
On **GitHub Actions, prefer OIDC** via the published `testdriverai/action` —
|
|
13
|
+
there's no `TD_API_KEY` secret to store, copy, or rotate. The action proves the
|
|
14
|
+
workflow is running inside your org and TestDriver exchanges that proof for your
|
|
15
|
+
team's key at run time. See the GitHub Actions tab below.
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
</Step>
|
|
18
|
-
<Step title="Add Secret to Your CI Provider">
|
|
19
|
-
Add `TD_API_KEY` as a secret environment variable in your CI provider's settings.
|
|
20
|
-
</Step>
|
|
21
|
-
</Steps>
|
|
17
|
+
For other CI providers (or self-hosted runners without OIDC), fall back to a
|
|
18
|
+
stored API key from [console.testdriver.ai/team](https://console.testdriver.ai/team),
|
|
19
|
+
added as a `TD_API_KEY` secret in your CI provider's settings.
|
|
22
20
|
|
|
23
21
|
<Note>
|
|
24
|
-
Never commit your API key directly in code. Always use your CI provider's secrets management.
|
|
22
|
+
Never commit your API key directly in code. Always use OIDC or your CI provider's secrets management.
|
|
25
23
|
</Note>
|
|
26
24
|
|
|
27
25
|
## CI Provider Examples
|
|
28
26
|
|
|
29
27
|
<Tabs>
|
|
30
28
|
<Tab title="GitHub Actions">
|
|
31
|
-
### Authenticate with OIDC (recommended)
|
|
29
|
+
### Authenticate with OIDC via `testdriverai/action` (recommended)
|
|
32
30
|
|
|
33
|
-
|
|
31
|
+
Use the published [`testdriverai/action`](https://github.com/testdriverai/action) — it mints the OIDC token, exchanges it for your team's API key, and exports `TD_API_KEY` for the steps that follow. **No `TD_API_KEY` secret to store or rotate.**
|
|
34
32
|
|
|
35
33
|
<Note>
|
|
36
|
-
|
|
34
|
+
One-time setup: authorize the [TestDriver GitHub App](https://console.testdriver.ai) for your org so the org → team binding exists. If your org authorized the App before OIDC support shipped, re-authorize once. If the App isn't authorized, the action fails with a console link (or falls back to the `api-key` secret if you provide one).
|
|
37
35
|
</Note>
|
|
38
36
|
|
|
39
|
-
Grant the job the `id-token: write` permission and exchange the OIDC token for your API key:
|
|
40
|
-
|
|
41
37
|
```yaml .github/workflows/testdriver.yml
|
|
42
38
|
name: TestDriver Tests
|
|
43
39
|
|
|
@@ -51,7 +47,7 @@ TestDriver requires an API key to authenticate with the TestDriver cloud. Store
|
|
|
51
47
|
test:
|
|
52
48
|
runs-on: ubuntu-latest
|
|
53
49
|
permissions:
|
|
54
|
-
id-token: write #
|
|
50
|
+
id-token: write # REQUIRED to mint an OIDC token
|
|
55
51
|
contents: read
|
|
56
52
|
|
|
57
53
|
steps:
|
|
@@ -64,28 +60,18 @@ TestDriver requires an API key to authenticate with the TestDriver cloud. Store
|
|
|
64
60
|
|
|
65
61
|
- run: npm ci
|
|
66
62
|
|
|
67
|
-
- name: Authenticate to TestDriver
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=testdriver" | jq -r '.value')
|
|
72
|
-
API_KEY=$(curl -sS -X POST https://api.testdriver.ai/github/actions/auth \
|
|
73
|
-
-H "Content-Type: application/json" \
|
|
74
|
-
-d "{\"token\":\"$OIDC_TOKEN\"}" | jq -r '.apiKey')
|
|
75
|
-
echo "::add-mask::$API_KEY"
|
|
76
|
-
echo "TD_API_KEY=$API_KEY" >> "$GITHUB_ENV"
|
|
63
|
+
- name: Authenticate to TestDriver
|
|
64
|
+
uses: testdriverai/action@stable # pin @stable / @canary / @test to your SDK channel
|
|
65
|
+
with:
|
|
66
|
+
api-key: ${{ secrets.TD_API_KEY }} # optional fallback if OIDC isn't set up
|
|
77
67
|
|
|
78
68
|
- name: Run TestDriver tests
|
|
79
|
-
|
|
80
|
-
TD_API_KEY: ${{ env.TD_API_KEY }}
|
|
81
|
-
run: vitest --run
|
|
69
|
+
run: npx vitest run
|
|
82
70
|
```
|
|
83
71
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
### Adding Secrets
|
|
72
|
+
### Stored-key fallback
|
|
87
73
|
|
|
88
|
-
|
|
74
|
+
Only if you can't use OIDC (e.g. self-hosted runners without an OIDC provider). Add the key as a secret and pass it via `env`:
|
|
89
75
|
|
|
90
76
|
1. Navigate to your GitHub repository
|
|
91
77
|
2. Go to **Settings** → **Secrets and variables** → **Actions**
|
package/docs/v7/client.mdx
CHANGED
|
@@ -54,7 +54,7 @@ const testdriver = new TestDriver(apiKey, options)
|
|
|
54
54
|
</ParamField>
|
|
55
55
|
|
|
56
56
|
<ParamField path="reconnect" type="boolean" default="false">
|
|
57
|
-
Reattach to the last used sandbox instead of creating a new one. When `true`, the SDK reads the sandbox id from `.testdriver/last-sandbox` (written automatically on every successful connect) and rejoins that VM. Provision methods (`chrome`, `vscode`, `installer`, etc.) are skipped because the application is already running. The previous sandbox must still be alive — see [`keepAlive`](#keepalive) and the [
|
|
57
|
+
Reattach to the last used sandbox instead of creating a new one. When `true`, the SDK reads the sandbox id from `.testdriver/last-sandbox` (written automatically on every successful connect) and rejoins that VM. Provision methods (`chrome`, `vscode`, `installer`, etc.) are skipped because the application is already running. The previous sandbox must still be alive — see [`keepAlive`](#keepalive) and the [Run guide](/v7/copilot/running-tests#keeping-machines-alive-between-runs).
|
|
58
58
|
</ParamField>
|
|
59
59
|
|
|
60
60
|
<ParamField path="sandboxId" type="string">
|