testdriverai 7.2.47 → 7.2.48

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 (56) hide show
  1. package/.github/workflows/acceptance-linux-scheduled.yaml +1 -1
  2. package/.github/workflows/acceptance.yaml +2 -2
  3. package/.github/workflows/windows-self-hosted.yaml +1 -1
  4. package/README.md +2 -2
  5. package/docs/TEST-GITHUB-COMMENTS.md +2 -2
  6. package/docs/v7/_drafts/plugin-migration.mdx +1 -1
  7. package/docs/v7/aws-setup.mdx +1 -1
  8. package/docs/v7/examples.mdx +1 -1
  9. package/{test/testdriver → examples}/chrome-extension.test.mjs +1 -1
  10. package/package.json +1 -1
  11. package/test/manual/reconnect-provision.test.mjs +2 -2
  12. package/testdriver-plugin/skills/actions/SKILL.md +93 -0
  13. package/testdriver-plugin/skills/assertions/SKILL.md +77 -0
  14. package/testdriver-plugin/skills/caching/SKILL.md +66 -0
  15. package/testdriver-plugin/skills/creating-tests/SKILL.md +104 -0
  16. package/testdriver-plugin/skills/finding-elements/SKILL.md +77 -0
  17. package/testdriver-plugin/skills/github-actions/SKILL.md +100 -0
  18. package/testdriver-plugin/skills/running-tests/SKILL.md +77 -0
  19. package/testdriver-plugin/skills/secrets/SKILL.md +87 -0
  20. package/testdriver-plugin/skills/self-hosting/SKILL.md +89 -0
  21. package/testdriver-plugin/skills/setup/SKILL.md +76 -0
  22. package/testdriver-plugin/skills/variables/SKILL.md +88 -0
  23. package/testdriver-plugin/skills/waiting/SKILL.md +72 -0
  24. package/debug/01-table-initial.png +0 -0
  25. package/debug/02-after-ai-explore.png +0 -0
  26. package/debug/02-after-scroll.png +0 -0
  27. package/examples/github-actions.yml +0 -68
  28. package/examples/run-tests-with-recording.sh +0 -70
  29. package/examples/screenshot-example.js +0 -63
  30. package/examples/sdk-awesome-logs-demo.js +0 -177
  31. package/examples/sdk-cache-thresholds.js +0 -96
  32. package/examples/sdk-element-properties.js +0 -155
  33. package/examples/sdk-simple-example.js +0 -65
  34. package/examples/test-recording-example.test.js +0 -166
  35. /package/{test/testdriver → examples}/ai.test.mjs +0 -0
  36. /package/{test/testdriver → examples}/assert.test.mjs +0 -0
  37. /package/{test/testdriver → examples}/drag-and-drop.test.mjs +0 -0
  38. /package/{test/testdriver → examples}/element-not-found.test.mjs +0 -0
  39. /package/{test/testdriver → examples}/exec-output.test.mjs +0 -0
  40. /package/{test/testdriver → examples}/exec-pwsh.test.mjs +0 -0
  41. /package/{test/testdriver → examples}/focus-window.test.mjs +0 -0
  42. /package/{test/testdriver → examples}/formatted-logging.test.mjs +0 -0
  43. /package/{test/testdriver → examples}/hover-image.test.mjs +0 -0
  44. /package/{test/testdriver → examples}/hover-text-with-description.test.mjs +0 -0
  45. /package/{test/testdriver → examples}/hover-text.test.mjs +0 -0
  46. /package/{test/testdriver → examples}/installer.test.mjs +0 -0
  47. /package/{test/testdriver → examples}/launch-vscode-linux.test.mjs +0 -0
  48. /package/{test/testdriver → examples}/match-image.test.mjs +0 -0
  49. /package/{test/testdriver → examples}/press-keys.test.mjs +0 -0
  50. /package/{test/testdriver → examples}/prompt.test.mjs +0 -0
  51. /package/{test/testdriver → examples}/scroll-keyboard.test.mjs +0 -0
  52. /package/{test/testdriver → examples}/scroll-until-image.test.mjs +0 -0
  53. /package/{test/testdriver → examples}/scroll-until-text.test.mjs +0 -0
  54. /package/{test/testdriver → examples}/scroll.test.mjs +0 -0
  55. /package/{test/testdriver → examples}/type.test.mjs +0 -0
  56. /package/{test/testdriver → examples}/windows-installer.test.mjs +0 -0
@@ -31,7 +31,7 @@ jobs:
31
31
 
32
32
  - name: Run Linux tests with Sentry Cron monitoring
33
33
  run: |
34
- sentry-cli monitors run testdriver-linux-acceptance -- npx vitest run test/testdriver/*.test.mjs
34
+ sentry-cli monitors run testdriver-linux-acceptance -- npx vitest run examples/*.test.mjs
35
35
  env:
36
36
  SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
37
37
  TD_API_KEY: ${{ secrets.TD_API_KEY }}
@@ -29,7 +29,7 @@ jobs:
29
29
  run: npm ci
30
30
 
31
31
  - name: Run Linux tests
32
- run: npx vitest run test/testdriver/*.test.mjs
32
+ run: npx vitest run examples/*.test.mjs
33
33
  env:
34
34
  TD_API_KEY: ${{ secrets.TD_API_KEY }}
35
35
  TD_OS: linux
@@ -52,7 +52,7 @@ jobs:
52
52
  if: contains(github.event.pull_request.labels.*.name, 'test-windows')
53
53
  uses: ./.github/workflows/windows-self-hosted.yaml
54
54
  with:
55
- test_pattern: 'test/testdriver/assert.test.mjs'
55
+ test_pattern: 'examples/assert.test.mjs'
56
56
  secrets:
57
57
  TD_API_KEY: ${{ secrets.TD_API_KEY }}
58
58
  TD_WEBSITE: ${{ secrets.TD_WEBSITE }}
@@ -7,7 +7,7 @@ on:
7
7
  description: 'Test file pattern to run'
8
8
  required: false
9
9
  type: string
10
- default: 'test/testdriver/*.test.mjs'
10
+ default: 'examples/*.test.mjs'
11
11
  secrets:
12
12
  TD_API_KEY:
13
13
  required: true
package/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
  <br />
12
12
  <br />
13
13
 
14
- [🚀 **Quick Start**](#-quick-start) • [📖 **Documentation**](https://docs.testdriver.ai) • [💻 **Examples**](https://github.com/testdriverai/testdriverai/tree/main/test/testdriver) • [📖 **Pricing**](https://docs.testdriver.ai) • [💬 **Discord**](https://discord.com/invite/cWDFW8DzPm) • [🌐 **Website**](https://testdriver.ai)
14
+ [🚀 **Quick Start**](#-quick-start) • [📖 **Documentation**](https://docs.testdriver.ai) • [💻 **Examples**](https://github.com/testdriverai/testdriverai/tree/main/examples) • [📖 **Pricing**](https://docs.testdriver.ai) • [💬 **Discord**](https://discord.com/invite/cWDFW8DzPm) • [🌐 **Website**](https://testdriver.ai)
15
15
 
16
16
  </div>
17
17
 
@@ -41,7 +41,7 @@ const result = await testdriver.assert(
41
41
  expect(result).toBeTruthy();
42
42
  ```
43
43
 
44
- [See Full Example](https://github.com/testdriverai/testdriverai/blob/main/test/testdriver/drag-and-drop.test.mjs) • [Browse All Examples](https://github.com/testdriverai/testdriverai/tree/main/test/testdriver)
44
+ [See Full Example](https://github.com/testdriverai/testdriverai/blob/main/examples/drag-and-drop.test.mjs) • [Browse All Examples](https://github.com/testdriverai/testdriverai/tree/main/examples)
45
45
 
46
46
  ---
47
47
 
@@ -38,7 +38,7 @@
38
38
 
39
39
  ## What the Test Does
40
40
 
41
- The workflow runs `test/testdriver/assert.test.mjs` which:
41
+ The workflow runs `examples/assert.test.mjs` which:
42
42
  - Provisions a Chrome browser
43
43
  - Navigates to https://saucedemo.com
44
44
  - Performs login actions
@@ -72,7 +72,7 @@ Skipped: 0 ⏭️
72
72
 
73
73
  | Status | Test | File | Duration | Replay |
74
74
  |--------|------|------|----------|--------|
75
- | ✅ | Assert Test | `test/testdriver/assert.test.mjs` | 25.3s | [🎥 View](https://console.testdriver.ai/replay/...) |
75
+ | ✅ | Assert Test | `examples/assert.test.mjs` | 25.3s | [🎥 View](https://console.testdriver.ai/replay/...) |
76
76
 
77
77
  ## 🎥 Dashcam Replays
78
78
 
@@ -142,7 +142,7 @@ export default defineConfig({
142
142
 
143
143
  ### Test Helpers
144
144
 
145
- - ✅ **Removed**: `test/testdriver/setup/` folder (legacy helpers)
145
+ - ✅ **Removed**: `examples/setup/` folder (legacy helpers)
146
146
  - Code moved to `lib/vitest/hooks.mjs` framework
147
147
  - Tests now use `TestDriver(context, options)` pattern directly
148
148
 
@@ -257,7 +257,7 @@ jobs:
257
257
  run: npm ci
258
258
 
259
259
  - name: Run Windows tests with self-hosted instances
260
- run: npx vitest run test/testdriver/*.test.mjs
260
+ run: npx vitest run examples/*.test.mjs
261
261
  env:
262
262
  TD_API_KEY: ${{ secrets.TD_API_KEY }}
263
263
  TD_OS: windows
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  title: "Examples"
3
- url: "https://github.com/testdriverai/testdriverai/tree/main/test/testdriver"
3
+ url: "https://github.com/testdriverai/testdriverai/tree/main/examples"
4
4
  icon: 'code'
5
5
  ---
@@ -55,7 +55,7 @@ describe("Chrome Extension Test", () => {
55
55
  // When clicked, it shows a popup with "Hello Extensions"
56
56
 
57
57
  // Click on the extensions button (puzzle piece icon) in Chrome toolbar
58
- const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar");
58
+ const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar", {zoom: true});
59
59
  await extensionsButton.click();
60
60
 
61
61
  // Look for the hello world extension in the extensions menu
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.2.47",
3
+ "version": "7.2.48",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "sdk.js",
6
6
  "types": "sdk.d.ts",
@@ -8,8 +8,8 @@
8
8
  * Run reconnect-signin.test.mjs within 2 minutes of this test completing.
9
9
  *
10
10
  * Usage:
11
- * 1. npm test -- test/testdriver/reconnect-provision.test.mjs
12
- * 2. (within 2 minutes) npm test -- test/testdriver/reconnect-signin.test.mjs
11
+ * 1. npm test -- examples/reconnect-provision.test.mjs
12
+ * 2. (within 2 minutes) examples/reconnect-signin.test.mjs
13
13
  */
14
14
 
15
15
  import { afterAll, describe, expect, it } from "vitest";
@@ -0,0 +1,93 @@
1
+ ---
2
+ name: actions
3
+ description: Perform actions in TestDriver tests. Use when clicking, typing, pressing keys, scrolling, hovering, dragging, or interacting with UI elements.
4
+ ---
5
+
6
+ # Performing Actions
7
+
8
+ Read these docs:
9
+ - `node_modules/testdriverai/docs/v7/click.mdx`
10
+ - `node_modules/testdriverai/docs/v7/type.mdx`
11
+ - `node_modules/testdriverai/docs/v7/press-keys.mdx`
12
+ - `node_modules/testdriverai/docs/v7/scroll.mdx`
13
+ - `node_modules/testdriverai/docs/v7/hover.mdx`
14
+ - `node_modules/testdriverai/docs/v7/double-click.mdx`
15
+ - `node_modules/testdriverai/docs/v7/right-click.mdx`
16
+ - `node_modules/testdriverai/docs/v7/mouse-down.mdx`
17
+ - `node_modules/testdriverai/docs/v7/mouse-up.mdx`
18
+
19
+ ## Click Actions
20
+
21
+ ```javascript
22
+ const element = await testdriver.find("button");
23
+ await element.click();
24
+ await element.doubleClick();
25
+ await element.rightClick();
26
+ await element.hover();
27
+ ```
28
+
29
+ ## Typing
30
+
31
+ ```javascript
32
+ await testdriver.find("Email input").click();
33
+ await testdriver.type("user@example.com");
34
+ ```
35
+
36
+ ### Clear before typing
37
+ ```javascript
38
+ await testdriver.find("Search input").click();
39
+ await testdriver.pressKeys(["ctrl", "a"]);
40
+ await testdriver.type("new search term");
41
+ ```
42
+
43
+ ## Keyboard Input
44
+
45
+ ```javascript
46
+ await testdriver.pressKeys(["enter"]);
47
+ await testdriver.pressKeys(["tab"]);
48
+ await testdriver.pressKeys(["escape"]);
49
+ await testdriver.pressKeys(["ctrl", "a"]); // Select all
50
+ await testdriver.pressKeys(["ctrl", "c"]); // Copy
51
+ await testdriver.pressKeys(["ctrl", "v"]); // Paste
52
+ await testdriver.pressKeys(["alt", "f4"]); // Close (Windows)
53
+ await testdriver.pressKeys(["cmd", "q"]); // Quit (macOS)
54
+ ```
55
+
56
+ ## Scrolling
57
+
58
+ ```javascript
59
+ await testdriver.scroll("down");
60
+ await testdriver.scroll("up");
61
+ await testdriver.scrollUntilText("Footer content");
62
+ await testdriver.scrollUntilImage("Product image at bottom");
63
+ ```
64
+
65
+ ## Drag and Drop
66
+
67
+ ```javascript
68
+ const source = await testdriver.find("Draggable item");
69
+ const target = await testdriver.find("Drop zone");
70
+ await source.mouseDown();
71
+ await target.hover();
72
+ await target.mouseUp();
73
+ ```
74
+
75
+ ## Execute Code in Sandbox
76
+
77
+ ```javascript
78
+ // JavaScript (browser)
79
+ const title = await testdriver.exec("js", "return document.title", 5000);
80
+
81
+ // Shell (Linux)
82
+ await testdriver.exec("sh", "ls -la", 5000);
83
+
84
+ // PowerShell (Windows)
85
+ await testdriver.exec("pwsh", "Get-Date", 5000);
86
+ ```
87
+
88
+ ## Examples
89
+
90
+ - `node_modules/testdriverai/examples/type.test.mjs`
91
+ - `node_modules/testdriverai/examples/press-keys.test.mjs`
92
+ - `node_modules/testdriverai/examples/scroll.test.mjs`
93
+ - `node_modules/testdriverai/examples/drag-and-drop.test.mjs`
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: assertions
3
+ description: Make assertions in TestDriver tests. Use when verifying UI state, checking visual conditions, or validating test outcomes with natural language.
4
+ ---
5
+
6
+ # Making Assertions
7
+
8
+ Read: `node_modules/testdriverai/docs/v7/assert.mdx`
9
+ Read: `node_modules/testdriverai/docs/v7/making-assertions.mdx`
10
+
11
+ ## Basic Usage
12
+
13
+ ```javascript
14
+ const result = await testdriver.assert("the dashboard is visible");
15
+ expect(result).toBeTruthy();
16
+ ```
17
+
18
+ ## Writing Good Assertions
19
+
20
+ **Be specific:**
21
+ ```javascript
22
+ // ✅ Good
23
+ await testdriver.assert("the login button is visible in the header");
24
+ await testdriver.assert("user's name 'John' appears in the profile section");
25
+ await testdriver.assert("error message 'Invalid email' is displayed");
26
+
27
+ // ❌ Vague
28
+ await testdriver.assert("button visible");
29
+ await testdriver.assert("it worked");
30
+ ```
31
+
32
+ **Describe what you see:**
33
+ ```javascript
34
+ await testdriver.assert("the settings panel is open on the right side");
35
+ await testdriver.assert("a green success checkmark appears next to the form");
36
+ await testdriver.assert("the page shows 'Welcome back, John'");
37
+ ```
38
+
39
+ **Include context:**
40
+ ```javascript
41
+ await testdriver.assert("the shopping cart shows 3 items");
42
+ await testdriver.assert("the price total is $99.99");
43
+ await testdriver.assert("the submit button is disabled");
44
+ ```
45
+
46
+ ## Common Patterns
47
+
48
+ ### After navigation
49
+ ```javascript
50
+ await testdriver.find("Settings link").click();
51
+ const result = await testdriver.assert("Settings page is displayed");
52
+ expect(result).toBeTruthy();
53
+ ```
54
+
55
+ ### Form validation
56
+ ```javascript
57
+ await testdriver.find("Submit button").click();
58
+ const hasError = await testdriver.assert("email validation error is shown");
59
+ expect(hasError).toBeTruthy();
60
+ ```
61
+
62
+ ### State changes
63
+ ```javascript
64
+ await testdriver.find("Toggle switch").click();
65
+ const isOn = await testdriver.assert("the toggle is now in the ON position");
66
+ expect(isOn).toBeTruthy();
67
+ ```
68
+
69
+ ### Negative assertions
70
+ ```javascript
71
+ const noError = await testdriver.assert("no error messages are visible");
72
+ expect(noError).toBeTruthy();
73
+ ```
74
+
75
+ ## Examples
76
+
77
+ See `node_modules/testdriverai/examples/assert.test.mjs`
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: caching
3
+ description: Understand TestDriver element caching. Use when optimizing test speed, managing cache keys, or troubleshooting cached element issues.
4
+ ---
5
+
6
+ # Element Caching
7
+
8
+ Read: `node_modules/testdriverai/docs/v7/caching.mdx`
9
+
10
+ ## How Caching Works
11
+
12
+ TestDriver caches element locations to speed up subsequent test runs. When you `find()` an element, the result is stored and reused in future runs.
13
+
14
+ ## Cache Options
15
+
16
+ ```javascript
17
+ const testdriver = TestDriver(context, {
18
+ cache: true, // Enable caching (default: true)
19
+ cacheKey: 'my-test', // Custom cache key
20
+ });
21
+ ```
22
+
23
+ ## When to Use Custom Cache Keys
24
+
25
+ Use different cache keys when:
26
+ - Testing different pages/states with similar elements
27
+ - Running tests in different environments
28
+ - Elements have different positions in different contexts
29
+
30
+ ```javascript
31
+ // Login page test
32
+ const testdriver = TestDriver(context, { cacheKey: 'login-page' });
33
+
34
+ // Dashboard test
35
+ const testdriver = TestDriver(context, { cacheKey: 'dashboard' });
36
+ ```
37
+
38
+ ## Disabling Cache
39
+
40
+ Disable caching when:
41
+ - Elements frequently change position
42
+ - Debugging element detection issues
43
+ - Dynamic content that varies between runs
44
+
45
+ ```javascript
46
+ const testdriver = TestDriver(context, { cache: false });
47
+ ```
48
+
49
+ ## Cache Invalidation
50
+
51
+ The cache is automatically invalidated when:
52
+ - Element is not found at cached location
53
+ - Test fails due to element mismatch
54
+ - Cache key changes
55
+
56
+ ## Troubleshooting
57
+
58
+ **Element found at wrong position?**
59
+ - Try disabling cache: `cache: false`
60
+ - Use a different cache key
61
+ - The UI may have changed since last run
62
+
63
+ **Tests slower than expected?**
64
+ - Ensure caching is enabled
65
+ - Use consistent cache keys
66
+ - Cache builds up over successful runs
@@ -0,0 +1,104 @@
1
+ ---
2
+ name: creating-tests
3
+ description: Create TestDriver tests. Use when writing new test files, structuring test suites, using the two-file workflow pattern, or setting up provision for browser/desktop testing.
4
+ ---
5
+
6
+ # Creating Tests
7
+
8
+ Read: `node_modules/testdriverai/docs/v7/quickstart.mdx`
9
+
10
+ ## Basic Test Structure
11
+
12
+ ```javascript
13
+ import { describe, expect, it } from "vitest";
14
+ import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
15
+
16
+ describe("My Test Suite", () => {
17
+ it("should do something", async (context) => {
18
+ const testdriver = TestDriver(context);
19
+
20
+ await testdriver.provision.chrome({ url: 'https://example.com' });
21
+
22
+ const button = await testdriver.find("Sign In button");
23
+ await button.click();
24
+
25
+ const result = await testdriver.assert("dashboard is visible");
26
+ expect(result).toBeTruthy();
27
+ });
28
+ });
29
+ ```
30
+
31
+ ## Provisioning
32
+
33
+ ### Web Testing
34
+ ```javascript
35
+ await testdriver.provision.chrome({ url: 'https://your-app.com' });
36
+ ```
37
+
38
+ ### Desktop App Testing
39
+ ```javascript
40
+ await testdriver.provision.installer({
41
+ url: 'https://example.com/app.deb', // or .msi, .exe
42
+ launch: true,
43
+ });
44
+ ```
45
+
46
+ ## Two-File Workflow (Recommended for Development)
47
+
48
+ Use two files to iterate efficiently without restarting from scratch.
49
+
50
+ ### setup.test.mjs
51
+ ```javascript
52
+ import { afterAll, describe, expect, it } from "vitest";
53
+ import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
54
+
55
+ describe("Setup", () => {
56
+ afterAll(async () => {
57
+ console.log("Sandbox staying alive for reconnect");
58
+ });
59
+
60
+ it("should set up state", async (context) => {
61
+ const testdriver = TestDriver(context);
62
+ await testdriver.provision.chrome({ url: 'https://your-app.com' });
63
+ const result = await testdriver.assert("page loaded");
64
+ expect(result).toBeTruthy();
65
+ console.log("✅ Run experiment.test.mjs now");
66
+ });
67
+ });
68
+ ```
69
+
70
+ ### experiment.test.mjs
71
+ ```javascript
72
+ import { describe, expect, it } from "vitest";
73
+ import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
74
+
75
+ describe("Experiment", () => {
76
+ it("should continue", async (context) => {
77
+ const testdriver = TestDriver(context, { reconnect: true });
78
+ // NO provision - sandbox already running
79
+ // Add new steps here...
80
+ });
81
+ });
82
+ ```
83
+
84
+ Run setup first, then experiment within 2 minutes.
85
+
86
+ ⚠️ **NEVER remove `reconnect: true`** unless combining into a final test.
87
+
88
+ ## TestDriver Options
89
+
90
+ ```javascript
91
+ TestDriver(context, {
92
+ newSandbox: true, // Create new sandbox
93
+ reconnect: false, // Reconnect to last sandbox
94
+ keepAlive: 30000, // Keep alive after test (ms)
95
+ os: 'linux', // 'linux' | 'windows'
96
+ resolution: '1366x768', // Sandbox resolution
97
+ });
98
+ ```
99
+
100
+ See `node_modules/testdriverai/docs/v7/device-config.mdx` for all options.
101
+
102
+ ## Examples
103
+
104
+ See `node_modules/testdriverai/examples/` for working test patterns.
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: finding-elements
3
+ description: Find elements in TestDriver tests. Use when locating UI elements by natural language description, understanding element properties, or debugging element detection.
4
+ ---
5
+
6
+ # Finding Elements
7
+
8
+ Read: `node_modules/testdriverai/docs/v7/find.mdx`
9
+ Read: `node_modules/testdriverai/docs/v7/elements.mdx`
10
+ Read: `node_modules/testdriverai/docs/v7/locating-elements.mdx`
11
+
12
+ ## Basic Usage
13
+
14
+ ```javascript
15
+ const button = await testdriver.find("Sign In button");
16
+ const input = await testdriver.find("Email input field");
17
+ const link = await testdriver.find("Forgot password link");
18
+ ```
19
+
20
+ ## Find All Matching Elements
21
+
22
+ ```javascript
23
+ const items = await testdriver.findAll("Product cards in the grid");
24
+ console.log(`Found ${items.length} products`);
25
+ ```
26
+
27
+ ## Element Properties
28
+
29
+ ```javascript
30
+ const element = await testdriver.find("Submit button");
31
+
32
+ // Check if found
33
+ console.log(element.found()); // boolean
34
+
35
+ // Coordinates
36
+ console.log(element.x, element.y); // top-left
37
+ console.log(element.centerX, element.centerY); // center
38
+
39
+ // Dimensions
40
+ console.log(element.width, element.height);
41
+
42
+ // AI detection info
43
+ console.log(element.confidence); // 0-1
44
+ console.log(element.text); // detected text
45
+ console.log(element.boundingBox); // full box
46
+ ```
47
+
48
+ ## Tips for Good Element Descriptions
49
+
50
+ **Be specific:**
51
+ - ✅ "Sign In button in the header"
52
+ - ❌ "button"
53
+
54
+ **Include context:**
55
+ - ✅ "Email input field in the login form"
56
+ - ❌ "input"
57
+
58
+ **Describe visual appearance:**
59
+ - ✅ "Blue Submit button at bottom of form"
60
+ - ✅ "User avatar in top right corner"
61
+
62
+ ## Debugging
63
+
64
+ Log element info to understand what AI sees:
65
+
66
+ ```javascript
67
+ const element = await testdriver.find("Some element");
68
+ console.log("Found:", element.found());
69
+ console.log("Position:", element.x, element.y);
70
+ console.log("Size:", element.width, element.height);
71
+ console.log("Confidence:", element.confidence);
72
+ console.log("Text:", element.text);
73
+ ```
74
+
75
+ ## Examples
76
+
77
+ See `node_modules/testdriverai/examples/hover-text.test.mjs`
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: github-actions
3
+ description: Integrate TestDriver with GitHub Actions. Use when setting up CI/CD pipelines, configuring workflows, or automating test runs on pull requests.
4
+ ---
5
+
6
+ # GitHub Actions Integration
7
+
8
+ Read: `node_modules/testdriverai/docs/v7/ci-cd.mdx`
9
+
10
+ ## Basic Workflow
11
+
12
+ Create `.github/workflows/testdriver.yml`:
13
+
14
+ ```yaml
15
+ name: TestDriver Tests
16
+
17
+ on:
18
+ push:
19
+ branches: [main]
20
+ pull_request:
21
+ branches: [main]
22
+
23
+ jobs:
24
+ test:
25
+ runs-on: ubuntu-latest
26
+
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+
30
+ - name: Setup Node.js
31
+ uses: actions/setup-node@v4
32
+ with:
33
+ node-version: '20'
34
+
35
+ - name: Install dependencies
36
+ run: npm ci
37
+
38
+ - name: Run TestDriver tests
39
+ env:
40
+ TD_API_KEY: ${{ secrets.TD_API_KEY }}
41
+ run: npx vitest run
42
+
43
+ - name: Upload test results
44
+ uses: actions/upload-artifact@v4
45
+ if: always()
46
+ with:
47
+ name: test-results
48
+ path: test-report.junit.xml
49
+ ```
50
+
51
+ ## Required Secrets
52
+
53
+ Add to your repository secrets (Settings → Secrets → Actions):
54
+ - `TD_API_KEY` - Your TestDriver API key
55
+
56
+ ## Windows Testing
57
+
58
+ For Windows sandbox testing, add AWS credentials:
59
+
60
+ ```yaml
61
+ - name: Run TestDriver tests (Windows)
62
+ env:
63
+ TD_API_KEY: ${{ secrets.TD_API_KEY }}
64
+ TD_OS: windows
65
+ AWS_REGION: ${{ secrets.AWS_REGION }}
66
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
67
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
68
+ AMI_ID: ${{ secrets.AMI_ID }}
69
+ AWS_LAUNCH_TEMPLATE_ID: ${{ secrets.AWS_LAUNCH_TEMPLATE_ID }}
70
+ run: npx vitest run
71
+ ```
72
+
73
+ ## JUnit Test Reports
74
+
75
+ TestDriver outputs JUnit XML for CI integration:
76
+
77
+ ```yaml
78
+ - name: Publish Test Results
79
+ uses: dorny/test-reporter@v1
80
+ if: always()
81
+ with:
82
+ name: TestDriver Results
83
+ path: test-report.junit.xml
84
+ reporter: java-junit
85
+ ```
86
+
87
+ ## Parallel Testing
88
+
89
+ ```yaml
90
+ jobs:
91
+ test:
92
+ runs-on: ubuntu-latest
93
+ strategy:
94
+ matrix:
95
+ test-file: [login, checkout, settings]
96
+ steps:
97
+ # ...
98
+ - name: Run tests
99
+ run: npx vitest run tests/${{ matrix.test-file }}.test.mjs
100
+ ```