@testdriverai/agent 7.11.229-test → 7.11.232-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/docs/_data/examples-manifest.json +16 -16
- package/docs/_scripts/generate-examples.js +38 -45
- package/docs/agent.mdx +174 -93
- package/docs/assert.mdx +73 -269
- package/docs/aws-setup.mdx +196 -314
- package/docs/bring-your-own-machine.mdx +139 -206
- package/docs/cache.mdx +144 -151
- package/docs/caching.mdx +99 -89
- package/docs/captcha.mdx +126 -111
- package/docs/ci-cd.mdx +154 -543
- package/docs/click.mdx +74 -229
- package/docs/client.mdx +177 -231
- package/docs/copilot/auto-healing.mdx +86 -370
- package/docs/copilot/running-tests.mdx +121 -930
- package/docs/customizing-devices.mdx +74 -251
- package/docs/dashcam.mdx +72 -405
- package/docs/debugging-with-screenshots.mdx +105 -371
- package/docs/docs.json +79 -22
- package/docs/double-click.mdx +48 -68
- package/docs/errors.mdx +102 -176
- package/docs/events.mdx +170 -327
- package/docs/examples/{hover-text-with-description.mdx → add-to-cart.mdx} +30 -35
- package/docs/examples/assert.mdx +28 -41
- package/docs/examples/click-button.mdx +71 -0
- package/docs/examples/{hover-image.mdx → click-icon.mdx} +32 -28
- package/docs/examples/element-not-found.mdx +27 -26
- package/docs/examples/findall-coffee-icons.mdx +28 -32
- package/docs/examples/installer.mdx +61 -25
- package/docs/examples/launch-vscode-linux.mdx +28 -51
- package/docs/examples/navigate-and-scroll.mdx +82 -0
- package/docs/examples/parse.mdx +24 -28
- package/docs/examples/press-keys.mdx +28 -25
- package/docs/examples/scroll.mdx +25 -27
- package/docs/examples/type.mdx +26 -21
- package/docs/exec.mdx +92 -256
- package/docs/extract.mdx +69 -170
- package/docs/find.mdx +140 -736
- package/docs/focus-application.mdx +69 -246
- package/docs/generating-tests.mdx +103 -137
- package/docs/guide/best-practices-polling.mdx +65 -141
- package/docs/hosted.mdx +80 -144
- package/docs/hover.mdx +62 -235
- package/docs/locating-elements.mdx +74 -369
- package/docs/making-assertions.mdx +116 -74
- package/docs/mcp-setup.mdx +80 -63
- package/docs/mouse-down.mdx +48 -125
- package/docs/mouse-up.mdx +47 -129
- package/docs/options.mdx +75 -48
- package/docs/parse.mdx +95 -184
- package/docs/performing-actions.mdx +104 -94
- package/docs/press-keys.mdx +59 -299
- package/docs/provision.mdx +137 -182
- package/docs/quickstart-claude.mdx +85 -0
- package/docs/quickstart-github.mdx +62 -32
- package/docs/quickstart-manual.mdx +60 -33
- package/docs/quickstart-vscode.mdx +97 -0
- package/docs/quickstart.mdx +26 -9
- package/docs/redraw.mdx +101 -165
- package/docs/reusable-code.mdx +97 -200
- package/docs/right-click.mdx +47 -89
- package/docs/screenshot.mdx +47 -201
- package/docs/screenshots.mdx +87 -137
- package/docs/scroll.mdx +71 -154
- package/docs/secrets.mdx +96 -91
- package/docs/self-hosted.mdx +83 -142
- package/docs/snippets/enterprise.mdx +15 -0
- package/docs/styles.css +68 -0
- package/docs/test-results-json.mdx +167 -204
- package/docs/type.mdx +56 -304
- package/docs/variables.mdx +121 -81
- package/docs/wait.mdx +33 -31
- package/docs/what-is-testdriver.mdx +80 -32
- package/examples/{hover-text-with-description.test.mjs → add-to-cart.test.mjs} +4 -5
- package/examples/assert.test.mjs +3 -20
- package/examples/{hover-text.test.mjs → click-button.test.mjs} +3 -4
- package/examples/{hover-image.test.mjs → click-icon.test.mjs} +5 -6
- package/examples/element-not-found.test.mjs +3 -5
- package/examples/findall-coffee-icons.test.mjs +3 -3
- package/examples/installer.test.mjs +1 -1
- package/examples/launch-vscode-linux.test.mjs +6 -33
- package/examples/{scroll-keyboard.test.mjs → navigate-and-scroll.test.mjs} +4 -5
- package/examples/parse.test.mjs +1 -2
- package/examples/press-keys.test.mjs +4 -4
- package/examples/scroll.test.mjs +3 -6
- package/examples/type.test.mjs +5 -2
- package/lib/provision.js +6 -2
- package/package.json +1 -1
- package/sdk.d.ts +4 -2
- package/sdk.js +1 -1
- package/docs/claude-mcp-plugin.mdx +0 -244
- package/docs/elements.mdx +0 -606
- package/docs/examples/ai.mdx +0 -78
- package/docs/examples/captcha-api.mdx +0 -92
- package/docs/examples/chrome-extension.mdx +0 -156
- package/docs/examples/drag-and-drop.mdx +0 -100
- package/docs/examples/formatted-logging.mdx +0 -74
- package/docs/examples/hover-text.mdx +0 -70
- package/docs/examples/match-image.mdx +0 -97
- package/docs/examples/scroll-keyboard.mdx +0 -80
- package/docs/examples/scroll-until-text.mdx +0 -109
package/docs/examples/assert.mdx
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Assert
|
|
2
|
+
title: "Assert that a page loaded"
|
|
3
3
|
sidebarTitle: "Assert"
|
|
4
|
-
description: "
|
|
4
|
+
description: "Open a login page in Chrome and use assert() to check that it loaded."
|
|
5
5
|
icon: "check-circle"
|
|
6
6
|
mode: "wide"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This test opens a login page in Chrome, saves a screenshot, and asserts that the page loaded.
|
|
10
10
|
|
|
11
|
-
Watch
|
|
11
|
+
## Watch it run
|
|
12
12
|
|
|
13
13
|
{/* assert.test.mjs output */}
|
|
14
14
|
<iframe
|
|
@@ -19,28 +19,21 @@ Watch this test execute in a real sandbox environment:
|
|
|
19
19
|
allow="fullscreen"
|
|
20
20
|
/>
|
|
21
21
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
```javascript title="assert.test.mjs" {22-24}
|
|
25
|
-
/**
|
|
26
|
-
* TestDriver SDK - Assert Test (Vitest)
|
|
27
|
-
* Converted from: testdriver/acceptance/assert.yaml
|
|
28
|
-
*/
|
|
22
|
+
## The test
|
|
29
23
|
|
|
24
|
+
```javascript title="assert.test.mjs"
|
|
30
25
|
import { describe, expect, it } from "vitest";
|
|
31
26
|
import { TestDriver } from "testdriverai/vitest/hooks";
|
|
32
27
|
|
|
33
28
|
describe("Assert Test", () => {
|
|
34
29
|
it("should assert the testdriver login page shows", async (context) => {
|
|
35
|
-
const testdriver = TestDriver(context
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// provision.chrome() automatically calls ready() and starts dashcam
|
|
30
|
+
const testdriver = TestDriver(context);
|
|
31
|
+
|
|
39
32
|
await testdriver.provision.chrome({
|
|
40
33
|
url: 'http://testdriver-sandbox.vercel.app/login',
|
|
41
34
|
});
|
|
42
35
|
|
|
43
|
-
//
|
|
36
|
+
// Save a screenshot to .testdriver/screenshots for debugging
|
|
44
37
|
await testdriver.screenshot();
|
|
45
38
|
|
|
46
39
|
// Assert the TestDriver.ai Sandbox login page is displayed
|
|
@@ -50,38 +43,32 @@ describe("Assert Test", () => {
|
|
|
50
43
|
|
|
51
44
|
expect(result).toBeTruthy();
|
|
52
45
|
});
|
|
53
|
-
// it("should assert the testdriver login page shows 2", async (context) => {
|
|
54
|
-
// const testdriver = TestDriver(context);
|
|
55
|
-
|
|
56
|
-
// // provision.chrome() automatically calls ready() and starts dashcam
|
|
57
|
-
// await testdriver.provision.chrome({
|
|
58
|
-
// url: 'http://testdriver-sandbox.vercel.app/login',
|
|
59
|
-
// });
|
|
60
|
-
|
|
61
|
-
// // Assert the TestDriver.ai Sandbox login page is displayed
|
|
62
|
-
// const result = await testdriver.assert(
|
|
63
|
-
// "the TestDriver.ai Sandbox login page is displayed",
|
|
64
|
-
// );
|
|
65
|
-
|
|
66
|
-
// expect(result).toBeTruthy();
|
|
67
|
-
// });
|
|
68
46
|
});
|
|
69
47
|
```
|
|
70
48
|
|
|
71
|
-
##
|
|
49
|
+
## How it works
|
|
50
|
+
|
|
51
|
+
- `provision.chrome({ url })` starts Chrome in the sandbox and opens the URL.
|
|
52
|
+
- `screenshot()` saves the screen to `.testdriver/screenshots/` and returns the file path. Use it to debug failures later.
|
|
53
|
+
- `assert()` asks the AI whether a statement about the screen is true.
|
|
54
|
+
- `assert()` throws when the statement is false, so the test fails at that line.
|
|
55
|
+
- The `expect()` after it makes the check explicit in the test.
|
|
56
|
+
|
|
57
|
+
## Run it
|
|
58
|
+
|
|
59
|
+
The test is in the [TestDriver SDK repository](https://github.com/testdriverai/testdriverai/tree/main/examples). Clone it, install dependencies, and run the file:
|
|
72
60
|
|
|
73
61
|
```bash
|
|
74
|
-
# Clone the TestDriver repository
|
|
75
62
|
git clone https://github.com/testdriverai/testdriverai
|
|
76
|
-
|
|
77
|
-
# Install dependencies
|
|
78
63
|
cd testdriverai
|
|
79
64
|
npm install
|
|
80
|
-
|
|
81
|
-
# Run this specific example
|
|
82
|
-
vitest run examples/assert.test.mjs
|
|
65
|
+
npx vitest run examples/assert.test.mjs
|
|
83
66
|
```
|
|
84
67
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
68
|
+
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.
|
|
69
|
+
|
|
70
|
+
## Related
|
|
71
|
+
|
|
72
|
+
- [assert()](/assert)
|
|
73
|
+
- [screenshot()](/screenshot)
|
|
74
|
+
- [Make assertions](/making-assertions)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Click a button by its label"
|
|
3
|
+
sidebarTitle: "Click a button"
|
|
4
|
+
description: "Click Sign In on an empty login form and assert that a validation error appears."
|
|
5
|
+
icon: "hand-pointer"
|
|
6
|
+
mode: "wide"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This test clicks **Sign In** on an empty login form and asserts that a "fields required" error appears.
|
|
10
|
+
|
|
11
|
+
## Watch it run
|
|
12
|
+
|
|
13
|
+
{/* click-button.test.mjs output */}
|
|
14
|
+
<iframe
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6ad6b60a022b6043aeec2bf1/replay"
|
|
16
|
+
width="100%"
|
|
17
|
+
height="390"
|
|
18
|
+
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
19
|
+
allow="fullscreen"
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
## The test
|
|
23
|
+
|
|
24
|
+
```javascript title="click-button.test.mjs"
|
|
25
|
+
import { describe, expect, it } from "vitest";
|
|
26
|
+
import { TestDriver } from "testdriverai/vitest/hooks";
|
|
27
|
+
|
|
28
|
+
describe("Hover Text Test", () => {
|
|
29
|
+
it("should click Sign In and verify error message", async (context) => {
|
|
30
|
+
const testdriver = TestDriver(context);
|
|
31
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
32
|
+
|
|
33
|
+
// Submit the login form without filling it in
|
|
34
|
+
const signInButton = await testdriver.find(
|
|
35
|
+
"Sign In, black button below the password field",
|
|
36
|
+
);
|
|
37
|
+
await signInButton.click();
|
|
38
|
+
|
|
39
|
+
// Assert that an error shows that fields are required
|
|
40
|
+
const result = await testdriver.assert(
|
|
41
|
+
"an error shows that fields are required",
|
|
42
|
+
);
|
|
43
|
+
expect(result).toBeTruthy();
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## How it works
|
|
49
|
+
|
|
50
|
+
- The `find()` description gives the button's label, look, and position ("black button below the password field").
|
|
51
|
+
- `click()` clicks the returned element. It throws if `find()` didn't locate it.
|
|
52
|
+
- `assert()` describes the error in plain language, so the test doesn't depend on exact wording or markup.
|
|
53
|
+
|
|
54
|
+
## Run it
|
|
55
|
+
|
|
56
|
+
The test is in the [TestDriver SDK repository](https://github.com/testdriverai/testdriverai/tree/main/examples). Clone it, install dependencies, and run the file:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
git clone https://github.com/testdriverai/testdriverai
|
|
60
|
+
cd testdriverai
|
|
61
|
+
npm install
|
|
62
|
+
npx vitest run examples/click-button.test.mjs
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
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.
|
|
66
|
+
|
|
67
|
+
## Related
|
|
68
|
+
|
|
69
|
+
- [find()](/find)
|
|
70
|
+
- [click()](/click)
|
|
71
|
+
- [assert()](/assert)
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
3
|
-
sidebarTitle: "
|
|
4
|
-
description: "
|
|
2
|
+
title: "Click an icon"
|
|
3
|
+
sidebarTitle: "Click an icon"
|
|
4
|
+
description: "Log in to a demo store, click the cart icon, and assert that the cart is empty."
|
|
5
5
|
icon: "hand-pointer"
|
|
6
6
|
mode: "wide"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This test logs in to a demo store, clicks the shopping cart icon, and asserts that the cart is empty.
|
|
10
10
|
|
|
11
|
-
Watch
|
|
11
|
+
## Watch it run
|
|
12
12
|
|
|
13
|
-
{/*
|
|
13
|
+
{/* click-icon.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
15
|
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6ad6b5f59af2067e32da0686/replay"
|
|
16
16
|
width="100%"
|
|
@@ -19,20 +19,15 @@ Watch this test execute in a real sandbox environment:
|
|
|
19
19
|
allow="fullscreen"
|
|
20
20
|
/>
|
|
21
21
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
```javascript title="hover-image.test.mjs" {40-42,47}
|
|
25
|
-
/**
|
|
26
|
-
* TestDriver SDK - Hover Image Test (Vitest)
|
|
27
|
-
* Converted from: testdriver/acceptance/hover-image.yaml
|
|
28
|
-
*/
|
|
22
|
+
## The test
|
|
29
23
|
|
|
24
|
+
```javascript title="click-icon.test.mjs"
|
|
30
25
|
import { describe, expect, it } from "vitest";
|
|
31
26
|
import { TestDriver } from "testdriverai/vitest/hooks";
|
|
32
27
|
|
|
33
28
|
/**
|
|
34
|
-
*
|
|
35
|
-
* @param {
|
|
29
|
+
* Log in to the TestDriver sandbox demo store.
|
|
30
|
+
* @param {object} client - TestDriver instance
|
|
36
31
|
* @param {string} username - Username (default: 'standard_user')
|
|
37
32
|
*/
|
|
38
33
|
async function performLogin(client, username = "standard_user") {
|
|
@@ -51,9 +46,8 @@ async function performLogin(client, username = "standard_user") {
|
|
|
51
46
|
|
|
52
47
|
describe("Hover Image Test", () => {
|
|
53
48
|
it("should click on shopping cart icon and verify empty cart", async (context) => {
|
|
54
|
-
const testdriver = TestDriver(context
|
|
55
|
-
|
|
56
|
-
// provision.chrome() automatically calls ready() and starts dashcam
|
|
49
|
+
const testdriver = TestDriver(context);
|
|
50
|
+
|
|
57
51
|
await testdriver.provision.chrome({
|
|
58
52
|
url: 'http://testdriver-sandbox.vercel.app/login'
|
|
59
53
|
});
|
|
@@ -76,20 +70,30 @@ describe("Hover Image Test", () => {
|
|
|
76
70
|
});
|
|
77
71
|
```
|
|
78
72
|
|
|
79
|
-
##
|
|
73
|
+
## How it works
|
|
74
|
+
|
|
75
|
+
- `performLogin()` is a plain function that takes the TestDriver instance, so any test can reuse it.
|
|
76
|
+
- The demo store shows its password on screen, so `extract()` reads it.
|
|
77
|
+
- `type(password, { secret: true })` keeps the password out of logs.
|
|
78
|
+
- `focusApplication('Google Chrome')` brings Chrome to the front before the test uses it.
|
|
79
|
+
- The `find()` description names the icon and its position ("next to the Cart text in the top right corner"). This helps the AI pick the right one.
|
|
80
|
+
|
|
81
|
+
## Run it
|
|
82
|
+
|
|
83
|
+
The test is in the [TestDriver SDK repository](https://github.com/testdriverai/testdriverai/tree/main/examples). Clone it, install dependencies, and run the file:
|
|
80
84
|
|
|
81
85
|
```bash
|
|
82
|
-
# Clone the TestDriver repository
|
|
83
86
|
git clone https://github.com/testdriverai/testdriverai
|
|
84
|
-
|
|
85
|
-
# Install dependencies
|
|
86
87
|
cd testdriverai
|
|
87
88
|
npm install
|
|
88
|
-
|
|
89
|
-
# Run this specific example
|
|
90
|
-
vitest run examples/hover-image.test.mjs
|
|
89
|
+
npx vitest run examples/click-icon.test.mjs
|
|
91
90
|
```
|
|
92
91
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
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.
|
|
93
|
+
|
|
94
|
+
## Related
|
|
95
|
+
|
|
96
|
+
- [find()](/find)
|
|
97
|
+
- [extract()](/extract)
|
|
98
|
+
- [Reuse code across tests](/reusable-code)
|
|
99
|
+
- [Secrets](/secrets)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
3
|
-
sidebarTitle: "Element
|
|
4
|
-
description: "
|
|
2
|
+
title: "Handle an element that isn't found"
|
|
3
|
+
sidebarTitle: "Element not found"
|
|
4
|
+
description: "See how find() returns an unfound element instead of throwing when nothing matches."
|
|
5
5
|
icon: "crosshairs"
|
|
6
6
|
mode: "wide"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This test looks for an element that isn't on the page. Use this pattern when an element may not appear.
|
|
10
10
|
|
|
11
|
-
Watch
|
|
11
|
+
## Watch it run
|
|
12
12
|
|
|
13
13
|
{/* element-not-found.test.mjs output */}
|
|
14
14
|
<iframe
|
|
@@ -19,24 +19,17 @@ Watch this test execute in a real sandbox environment:
|
|
|
19
19
|
allow="fullscreen"
|
|
20
20
|
/>
|
|
21
21
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
```javascript title="element-not-found.test.mjs" {16-18}
|
|
25
|
-
/**
|
|
26
|
-
* TestDriver SDK - Element Not Found Test
|
|
27
|
-
* Tests that finding a non-existent element returns properly without timing out
|
|
28
|
-
*/
|
|
22
|
+
## The test
|
|
29
23
|
|
|
24
|
+
```javascript title="element-not-found.test.mjs"
|
|
30
25
|
import { describe, expect, it } from "vitest";
|
|
31
26
|
import { TestDriver } from "testdriverai/vitest/hooks";
|
|
32
27
|
|
|
33
28
|
describe("Element Not Found Test", () => {
|
|
34
29
|
it("should handle non-existent element gracefully without timing out", async (context) => {
|
|
35
|
-
const testdriver = TestDriver(context
|
|
30
|
+
const testdriver = TestDriver(context);
|
|
36
31
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
37
32
|
|
|
38
|
-
//
|
|
39
|
-
|
|
40
33
|
// Try to find an element that definitely doesn't exist
|
|
41
34
|
const element = await testdriver.find(
|
|
42
35
|
"a purple unicorn dancing on the moon",
|
|
@@ -45,24 +38,32 @@ describe("Element Not Found Test", () => {
|
|
|
45
38
|
// Should return an element that is not found
|
|
46
39
|
expect(element.found()).toBe(false);
|
|
47
40
|
expect(element.coordinates).toBeNull();
|
|
48
|
-
});
|
|
41
|
+
});
|
|
49
42
|
});
|
|
50
43
|
```
|
|
51
44
|
|
|
52
|
-
##
|
|
45
|
+
## How it works
|
|
46
|
+
|
|
47
|
+
- By default, `find()` checks the screen every 5 seconds for up to 10 seconds.
|
|
48
|
+
- When nothing matches, `find()` doesn't throw.
|
|
49
|
+
- Instead, it returns an element whose `found()` is `false` and whose `coordinates` are `null`.
|
|
50
|
+
- Calling `click()` on an unfound element throws an `ElementNotFoundError`.
|
|
51
|
+
|
|
52
|
+
## Run it
|
|
53
|
+
|
|
54
|
+
The test is in the [TestDriver SDK repository](https://github.com/testdriverai/testdriverai/tree/main/examples). Clone it, install dependencies, and run the file:
|
|
53
55
|
|
|
54
56
|
```bash
|
|
55
|
-
# Clone the TestDriver repository
|
|
56
57
|
git clone https://github.com/testdriverai/testdriverai
|
|
57
|
-
|
|
58
|
-
# Install dependencies
|
|
59
58
|
cd testdriverai
|
|
60
59
|
npm install
|
|
61
|
-
|
|
62
|
-
# Run this specific example
|
|
63
|
-
vitest run examples/element-not-found.test.mjs
|
|
60
|
+
npx vitest run examples/element-not-found.test.mjs
|
|
64
61
|
```
|
|
65
62
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
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.
|
|
64
|
+
|
|
65
|
+
## Related
|
|
66
|
+
|
|
67
|
+
- [find()](/find)
|
|
68
|
+
- [Locate elements](/locating-elements)
|
|
69
|
+
- [Errors](/errors)
|
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
3
|
-
sidebarTitle: "
|
|
4
|
-
description: "
|
|
5
|
-
icon: "
|
|
2
|
+
title: "Find and click every matching element"
|
|
3
|
+
sidebarTitle: "Find all"
|
|
4
|
+
description: "Use findAll() to locate every coffee cup icon in a grid and click each one."
|
|
5
|
+
icon: "crosshairs"
|
|
6
6
|
mode: "wide"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This test uses `findAll()` to find every coffee cup in an icon grid, clicks each one, and asserts on the result.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Review the source code below to understand the implementation details and patterns used.
|
|
14
|
-
|
|
15
|
-
## Live Test Run
|
|
16
|
-
|
|
17
|
-
Watch this test execute in a real sandbox environment:
|
|
11
|
+
## Watch it run
|
|
18
12
|
|
|
19
13
|
{/* findall-coffee-icons.test.mjs output */}
|
|
20
14
|
<iframe
|
|
@@ -25,22 +19,15 @@ Watch this test execute in a real sandbox environment:
|
|
|
25
19
|
allow="fullscreen"
|
|
26
20
|
/>
|
|
27
21
|
|
|
28
|
-
##
|
|
22
|
+
## The test
|
|
29
23
|
|
|
30
24
|
```javascript title="findall-coffee-icons.test.mjs"
|
|
31
|
-
/**
|
|
32
|
-
* TestDriver SDK - FindAll Coffee Icons Test
|
|
33
|
-
* Loads a random icon grid and uses findAll() to locate and click all 4 coffee cup icons
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
25
|
import { describe, expect, it } from "vitest";
|
|
37
26
|
import { TestDriver } from "testdriverai/vitest/hooks";
|
|
38
27
|
|
|
39
28
|
describe("FindAll Coffee Icons", () => {
|
|
40
29
|
it("should find and click all 4 coffee cup icons", async (context) => {
|
|
41
|
-
const testdriver = TestDriver(context
|
|
42
|
-
headless: true,
|
|
43
|
-
});
|
|
30
|
+
const testdriver = TestDriver(context);
|
|
44
31
|
|
|
45
32
|
await testdriver.provision.chrome({
|
|
46
33
|
url: "https://v0-random-icon-grid.vercel.app/",
|
|
@@ -55,7 +42,7 @@ describe("FindAll Coffee Icons", () => {
|
|
|
55
42
|
console.log(` Icon ${i + 1}: (${icon.x}, ${icon.y}) center=(${icon.centerX}, ${icon.centerY})`);
|
|
56
43
|
});
|
|
57
44
|
|
|
58
|
-
//
|
|
45
|
+
// The grid has 4 coffee cups; allow one miss, matching the assertion below
|
|
59
46
|
expect(coffeeIcons.length).toBeGreaterThanOrEqual(3);
|
|
60
47
|
expect(coffeeIcons.length).toBeLessThanOrEqual(4);
|
|
61
48
|
|
|
@@ -70,20 +57,29 @@ describe("FindAll Coffee Icons", () => {
|
|
|
70
57
|
});
|
|
71
58
|
```
|
|
72
59
|
|
|
73
|
-
##
|
|
60
|
+
## How it works
|
|
61
|
+
|
|
62
|
+
- `findAll()` returns an array with one element per match.
|
|
63
|
+
- The description states how many to expect ("there are exactly 4 on the page").
|
|
64
|
+
- Each element has its position in `x`, `y`, `centerX`, and `centerY`.
|
|
65
|
+
- Each element has its own `click()`, so a `for...of` loop clicks them in turn.
|
|
66
|
+
- The test and assertion accept 3 or 4 matches, so one missed icon doesn't fail the run.
|
|
67
|
+
|
|
68
|
+
## Run it
|
|
69
|
+
|
|
70
|
+
The test is in the [TestDriver SDK repository](https://github.com/testdriverai/testdriverai/tree/main/examples). Clone it, install dependencies, and run the file:
|
|
74
71
|
|
|
75
72
|
```bash
|
|
76
|
-
# Clone the TestDriver repository
|
|
77
73
|
git clone https://github.com/testdriverai/testdriverai
|
|
78
|
-
|
|
79
|
-
# Install dependencies
|
|
80
74
|
cd testdriverai
|
|
81
75
|
npm install
|
|
82
|
-
|
|
83
|
-
# Run this specific example
|
|
84
|
-
vitest run examples/findall-coffee-icons.test.mjs
|
|
76
|
+
npx vitest run examples/findall-coffee-icons.test.mjs
|
|
85
77
|
```
|
|
86
78
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
79
|
+
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.
|
|
80
|
+
|
|
81
|
+
## Related
|
|
82
|
+
|
|
83
|
+
- [find()](/find)
|
|
84
|
+
- [click()](/click)
|
|
85
|
+
- [assert()](/assert)
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
3
|
-
sidebarTitle: "Linux
|
|
4
|
-
description: "
|
|
2
|
+
title: "Install a Linux package"
|
|
3
|
+
sidebarTitle: "Linux installer"
|
|
4
|
+
description: "Use provision.installer() to install command-line and desktop apps, and download a script, on Linux."
|
|
5
5
|
icon: "download"
|
|
6
6
|
mode: "wide"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This file has three `provision.installer()` tests in a Linux sandbox:
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- One installs a command-line tool from a `.deb` and runs it.
|
|
12
|
+
- One installs a desktop app from a `.deb` and checks that its window opens.
|
|
13
|
+
- One downloads a shell script without running it and checks that it exists.
|
|
14
|
+
|
|
15
|
+
## Watch it run
|
|
12
16
|
|
|
13
17
|
{/* installer.test.mjs output */}
|
|
14
18
|
<iframe
|
|
@@ -19,14 +23,9 @@ Watch this test execute in a real sandbox environment:
|
|
|
19
23
|
allow="fullscreen"
|
|
20
24
|
/>
|
|
21
25
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
```javascript title="installer.test.mjs" {16-18}
|
|
25
|
-
/**
|
|
26
|
-
* TestDriver SDK - Installer Test (Vitest)
|
|
27
|
-
* Tests the provision.installer() method for downloading and installing apps
|
|
28
|
-
*/
|
|
26
|
+
## The test
|
|
29
27
|
|
|
28
|
+
```javascript title="installer.test.mjs"
|
|
30
29
|
import { describe, expect, it } from "vitest";
|
|
31
30
|
import { TestDriver } from "testdriverai/vitest/hooks";
|
|
32
31
|
|
|
@@ -36,7 +35,7 @@ describe("Provision Installer", () => {
|
|
|
36
35
|
it.skipIf(!isLinux)(
|
|
37
36
|
"should download and install a .deb package on Linux",
|
|
38
37
|
async (context) => {
|
|
39
|
-
const testdriver = TestDriver(context
|
|
38
|
+
const testdriver = TestDriver(context);
|
|
40
39
|
|
|
41
40
|
// Install bat (a cat clone with syntax highlighting) using provision.installer
|
|
42
41
|
const filePath = await testdriver.provision.installer({
|
|
@@ -51,15 +50,41 @@ describe("Provision Installer", () => {
|
|
|
51
50
|
},
|
|
52
51
|
);
|
|
53
52
|
|
|
53
|
+
it.skipIf(!isLinux)(
|
|
54
|
+
"should install a .deb with missing dependencies and launch its window",
|
|
55
|
+
async (context) => {
|
|
56
|
+
const testdriver = TestDriver(context);
|
|
57
|
+
|
|
58
|
+
// Yaak is a Tauri app. Its .deb depends on WebKitGTK and libsoup,
|
|
59
|
+
// which aren't preinstalled, so dpkg alone leaves it unconfigured.
|
|
60
|
+
await testdriver.provision.installer({
|
|
61
|
+
url: 'https://github.com/mountain-loop/yaak/releases/download/v2026.9.0/yaak_2026.9.0_amd64.deb',
|
|
62
|
+
appName: 'Yaak',
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// The package and its dependencies are fully installed
|
|
66
|
+
const status = await testdriver.exec(
|
|
67
|
+
'sh',
|
|
68
|
+
"dpkg-query -W -f='${Status}' yaak",
|
|
69
|
+
10000,
|
|
70
|
+
);
|
|
71
|
+
expect(status).toBe('install ok installed');
|
|
72
|
+
|
|
73
|
+
// launch: true (the default) started the app, so its window is on screen
|
|
74
|
+
const result = await testdriver.assert('The Yaak app window is open');
|
|
75
|
+
expect(result).toBeTruthy();
|
|
76
|
+
},
|
|
77
|
+
);
|
|
78
|
+
|
|
54
79
|
it.skipIf(!isLinux)(
|
|
55
80
|
"should download a shell script and verify it exists",
|
|
56
81
|
async (context) => {
|
|
57
|
-
const testdriver = TestDriver(context
|
|
82
|
+
const testdriver = TestDriver(context);
|
|
58
83
|
|
|
59
84
|
// Download a shell script (nvm installer)
|
|
60
85
|
const filePath = await testdriver.provision.installer({
|
|
61
86
|
url: 'https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh',
|
|
62
|
-
launch: false, //
|
|
87
|
+
launch: false, // Download the script without running it
|
|
63
88
|
});
|
|
64
89
|
|
|
65
90
|
// Verify the file was downloaded
|
|
@@ -73,20 +98,31 @@ describe("Provision Installer", () => {
|
|
|
73
98
|
});
|
|
74
99
|
```
|
|
75
100
|
|
|
76
|
-
##
|
|
101
|
+
## How it works
|
|
102
|
+
|
|
103
|
+
- `provision.installer({ url })` downloads the file, installs it by extension, and returns its path.
|
|
104
|
+
- On Linux, a `.deb` is installed with `dpkg`, and missing dependencies are installed with `apt-get`. The step fails if the package still isn't fully installed.
|
|
105
|
+
- With `launch: true` (the default), a `.deb` app is started from its `.desktop` entry, then `appName` is focused. That's how the Yaak window opens.
|
|
106
|
+
- A `.sh` script is made executable and run.
|
|
107
|
+
- `launch: false` makes a `.sh` script executable without running it. It also skips focusing the app when you pass `appName`.
|
|
108
|
+
- With `launch: false`, packages such as `.deb` files are still installed.
|
|
109
|
+
- `exec('sh', command, timeout)` runs a shell command and returns its output. The test uses it to check that `bat` is installed.
|
|
110
|
+
- `it.skipIf(!isLinux)` skips every test when `TD_OS` is set to `windows`.
|
|
111
|
+
|
|
112
|
+
## Run it
|
|
113
|
+
|
|
114
|
+
The test is in the [TestDriver SDK repository](https://github.com/testdriverai/testdriverai/tree/main/examples). Clone it, install dependencies, and run the file:
|
|
77
115
|
|
|
78
116
|
```bash
|
|
79
|
-
# Clone the TestDriver repository
|
|
80
117
|
git clone https://github.com/testdriverai/testdriverai
|
|
81
|
-
|
|
82
|
-
# Install dependencies
|
|
83
118
|
cd testdriverai
|
|
84
119
|
npm install
|
|
85
|
-
|
|
86
|
-
# Run this specific example
|
|
87
|
-
vitest run examples/installer.test.mjs
|
|
120
|
+
npx vitest run examples/installer.test.mjs
|
|
88
121
|
```
|
|
89
122
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
123
|
+
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.
|
|
124
|
+
|
|
125
|
+
## Related
|
|
126
|
+
|
|
127
|
+
- [Launch apps](/provision)
|
|
128
|
+
- [exec()](/exec)
|