@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.
Files changed (39) hide show
  1. package/ai/skills/testdriver-caching/SKILL.md +13 -6
  2. package/ai/skills/testdriver-ci-cd/SKILL.md +20 -34
  3. package/ai/skills/testdriver-client/SKILL.md +5 -1
  4. package/ai/skills/testdriver-debugging-with-screenshots/SKILL.md +14 -4
  5. package/ai/skills/testdriver-find/SKILL.md +2 -0
  6. package/ai/skills/testdriver-generating-tests/SKILL.md +159 -8
  7. package/ai/skills/testdriver-machine-setup/SKILL.md +75 -8
  8. package/ai/skills/testdriver-making-assertions/SKILL.md +78 -2
  9. package/ai/skills/testdriver-performing-actions/SKILL.md +97 -2
  10. package/ai/skills/testdriver-quickstart/SKILL.md +47 -28
  11. package/ai/skills/testdriver-wait/SKILL.md +1 -1
  12. package/ai/skills/testdriver:generating-tests/SKILL.md +0 -11
  13. package/docs/changelog.mdx +1 -1
  14. package/docs/docs.json +14 -39
  15. package/docs/v7/assert.mdx +0 -1
  16. package/docs/v7/caching.mdx +14 -10
  17. package/docs/v7/ci-cd.mdx +20 -34
  18. package/docs/v7/client.mdx +1 -1
  19. package/docs/v7/copilot/auto-healing.mdx +167 -18
  20. package/docs/v7/copilot/running-tests.mdx +915 -54
  21. package/docs/v7/debugging-with-screenshots.mdx +17 -7
  22. package/docs/v7/generating-tests.mdx +166 -10
  23. package/docs/v7/making-assertions.mdx +81 -4
  24. package/docs/v7/performing-actions.mdx +100 -4
  25. package/docs/v7/quickstart.mdx +299 -21
  26. package/docs/v7/wait.mdx +1 -1
  27. package/package.json +3 -3
  28. package/docs/v7/ai/agent.mdx +0 -72
  29. package/docs/v7/ai/mcp.mdx +0 -228
  30. package/docs/v7/ai/skills.mdx +0 -73
  31. package/docs/v7/ai.mdx +0 -205
  32. package/docs/v7/copilot/creating-tests.mdx +0 -156
  33. package/docs/v7/copilot/github.mdx +0 -143
  34. package/docs/v7/copilot/setup.mdx +0 -143
  35. package/docs/v7/device-config.mdx +0 -317
  36. package/docs/v7/locating-elements.mdx +0 -71
  37. package/docs/v7/machine-setup.mdx +0 -331
  38. package/docs/v7/running-tests.mdx +0 -185
  39. package/docs/v7/waiting-for-elements.mdx +0 -90
@@ -1,9 +1,13 @@
1
1
  ---
2
2
  name: testdriver:performing-actions
3
- description: Click, type, hover, scroll and more with TestDriver
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
- ## Chaining Actions
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-elements) automatically waits for screen and network stability after each action.
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>
@@ -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/setup)** — 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/copilot/creating-tests), [running tests](/v7/copilot/running-tests), [GitHub Actions integration](/v7/copilot/github), and [auto-healing](/v7/copilot/auto-healing).
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 Setup",
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"
@@ -313,4 +313,3 @@ describe('Assertions', () => {
313
313
 
314
314
  - [`extract()`](/v7/extract) - Extract information for detailed assertions
315
315
  - [`find()`](/v7/find) - Locate elements to verify
316
- - [`ai()`](/v7/ai) - Complex AI-driven tasks
@@ -1,11 +1,13 @@
1
1
  ---
2
- title: "Caching Prompts"
3
- description: "1.7x faster test execution with intelligent caching and optimization"
4
- icon: "bolt"
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 is engineered for performance with intelligent caching that delivers up to **1.7x faster** test execution by skipping redundant AI vision analysis.
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
- Caching is enabled automatically with zero configuration. The cache key is computed from:
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 cache behavior globally when initializing TestDriver:
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
- ## Adding Your API Key
10
+ ## Authentication
11
11
 
12
- TestDriver requires an API key to authenticate with the TestDriver cloud. Store this securely as a secret in your CI provider.
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
- <Steps>
15
- <Step title="Get Your API Key">
16
- Go to [console.testdriver.ai/team](https://console.testdriver.ai/team) and copy your team's API key
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
- If you've installed the [TestDriver GitHub App](https://console.testdriver.ai), your workflow can authenticate using GitHub's OIDC token no long-lived `TD_API_KEY` secret to store or rotate. The workflow proves it's running inside your org, and TestDriver exchanges that proof for your team's API key at run time.
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
- This requires the TestDriver GitHub App to be authorized for your organization once (from the [console](https://console.testdriver.ai)). If your org authorized the App before OIDC support shipped, re-run the authorization once so the binding is created.
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 # required to mint an OIDC token
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 via OIDC
68
- run: |
69
- OIDC_TOKEN=$(curl -sS \
70
- -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
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
- env:
80
- TD_API_KEY: ${{ env.TD_API_KEY }}
81
- run: vitest --run
69
+ run: npx vitest run
82
70
  ```
83
71
 
84
- `ACTIONS_ID_TOKEN_REQUEST_TOKEN` and `ACTIONS_ID_TOKEN_REQUEST_URL` are injected automatically once `permissions: id-token: write` is set. `::add-mask::` keeps the resolved key out of the logs.
85
-
86
- ### Adding Secrets
72
+ ### Stored-key fallback
87
73
 
88
- Prefer OIDC above when possible. If you can't use the GitHub App (e.g. self-hosted runners without OIDC, or a non-GitHub registry), fall back to a stored API key:
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**
@@ -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 [Machine Setup guide](/v7/machine-setup#keeping-machines-alive-between-runs).
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">