testdriverai 7.3.4 → 7.3.6
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/.github/workflows/acceptance-linux-scheduled.yaml +1 -1
- package/.github/workflows/acceptance.yaml +38 -1
- package/.github/workflows/windows-self-hosted.yaml +9 -1
- package/CHANGELOG.md +8 -0
- package/docs/_data/examples-manifest.json +105 -0
- package/docs/_data/examples-manifest.schema.json +41 -0
- package/docs/_scripts/extract-example-urls.js +165 -0
- package/docs/_scripts/generate-examples.js +534 -0
- package/docs/docs.json +242 -212
- package/docs/v7/aws-setup.mdx +1 -1
- package/docs/v7/examples/ai.mdx +72 -0
- package/docs/v7/examples/assert.mdx +72 -0
- package/docs/v7/examples/captcha-api.mdx +92 -0
- package/docs/v7/examples/chrome-extension.mdx +132 -0
- package/docs/v7/examples/drag-and-drop.mdx +100 -0
- package/docs/v7/examples/element-not-found.mdx +67 -0
- package/docs/v7/examples/hover-image.mdx +94 -0
- package/docs/v7/examples/hover-text.mdx +69 -0
- package/docs/v7/examples/installer.mdx +91 -0
- package/docs/v7/examples/launch-vscode-linux.mdx +101 -0
- package/docs/v7/examples/match-image.mdx +96 -0
- package/docs/v7/examples/press-keys.mdx +92 -0
- package/docs/v7/examples/scroll-keyboard.mdx +79 -0
- package/docs/v7/examples/scroll-until-image.mdx +81 -0
- package/docs/v7/examples/scroll-until-text.mdx +109 -0
- package/docs/v7/examples/scroll.mdx +81 -0
- package/docs/v7/examples/type.mdx +92 -0
- package/docs/v7/examples/windows-installer.mdx +89 -0
- package/examples/ai.test.mjs +2 -1
- package/examples/assert.test.mjs +2 -2
- package/examples/captcha-api.test.mjs +3 -2
- package/examples/chrome-extension.test.mjs +3 -2
- package/examples/config.mjs +5 -0
- package/examples/drag-and-drop.test.mjs +2 -1
- package/examples/element-not-found.test.mjs +2 -1
- package/examples/exec-output.test.mjs +2 -1
- package/examples/exec-pwsh.test.mjs +2 -1
- package/examples/focus-window.test.mjs +2 -1
- package/examples/formatted-logging.test.mjs +2 -1
- package/examples/hover-image.test.mjs +2 -1
- package/examples/hover-text-with-description.test.mjs +2 -1
- package/examples/hover-text.test.mjs +2 -1
- package/examples/installer.test.mjs +3 -2
- package/examples/launch-vscode-linux.test.mjs +3 -2
- package/examples/match-image.test.mjs +2 -1
- package/examples/no-provision.test.mjs +2 -3
- package/examples/press-keys.test.mjs +7 -13
- package/examples/prompt.test.mjs +2 -1
- package/examples/scroll-keyboard.test.mjs +2 -1
- package/examples/scroll-until-image.test.mjs +2 -1
- package/examples/scroll-until-text.test.mjs +2 -1
- package/examples/scroll.test.mjs +2 -1
- package/examples/type.test.mjs +3 -2
- package/examples/windows-installer.test.mjs +2 -1
- package/interfaces/vitest-plugin.mjs +50 -18
- package/package.json +3 -1
- package/sdk.js +49 -38
- package/vitest.config.mjs +1 -1
- package/docs/v7/examples.mdx +0 -5
- package/jsconfig.json +0 -26
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Captcha Solving Example"
|
|
3
|
+
sidebarTitle: "Captcha Solving"
|
|
4
|
+
description: "Example test demonstrating automatic captcha solving with reCAPTCHA and Cloudflare Turnstile support."
|
|
5
|
+
icon: "shield-check"
|
|
6
|
+
mode: "wide"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Demo Test Run
|
|
10
|
+
|
|
11
|
+
Watch this test execute in a real sandbox environment:
|
|
12
|
+
|
|
13
|
+
{/* captcha-api.test.mjs output */}
|
|
14
|
+
<iframe
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/698b7da36513c6b23f858eee/replay"
|
|
16
|
+
width="100%"
|
|
17
|
+
height="390"
|
|
18
|
+
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
19
|
+
allow="fullscreen"
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
## Source Code
|
|
23
|
+
|
|
24
|
+
```javascript title="captcha-api.test.mjs" {18-20}
|
|
25
|
+
/**
|
|
26
|
+
* TestDriver SDK - Captcha Test
|
|
27
|
+
*/
|
|
28
|
+
import { describe, expect, it } from "vitest";
|
|
29
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
30
|
+
|
|
31
|
+
console.log("DEBUG: process.env.TD_OS:", process.env.TD_OS);
|
|
32
|
+
|
|
33
|
+
describe("testdriver.captcha() API", () => {
|
|
34
|
+
it("should solve reCAPTCHA v3 with auto-detect", async (context) => {
|
|
35
|
+
const testdriver = TestDriver(context);
|
|
36
|
+
|
|
37
|
+
// Launch Chrome (remote debugging is enabled automatically on Linux)
|
|
38
|
+
await testdriver.provision.chrome({
|
|
39
|
+
url: "https://2captcha.com/demo/recaptcha-v3",
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
await testdriver.screenshot();
|
|
43
|
+
|
|
44
|
+
// Solve the captcha with just the API key - everything else is auto-detected!
|
|
45
|
+
const result = await testdriver.captcha({
|
|
46
|
+
apiKey: process.env.TWOCAPTCHA_API_KEY,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
console.log("Captcha result:", result);
|
|
50
|
+
await testdriver.screenshot();
|
|
51
|
+
|
|
52
|
+
expect(result.success).toBe(true);
|
|
53
|
+
}, 180000);
|
|
54
|
+
|
|
55
|
+
it("should solve Cloudflare Turnstile", async (context) => {
|
|
56
|
+
const testdriver = TestDriver(context);
|
|
57
|
+
|
|
58
|
+
await testdriver.provision.chrome({
|
|
59
|
+
url: "https://2captcha.com/demo/cloudflare-turnstile",
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await testdriver.screenshot();
|
|
63
|
+
|
|
64
|
+
const result = await testdriver.captcha({
|
|
65
|
+
apiKey: process.env.TWOCAPTCHA_API_KEY,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
console.log("Turnstile result:", result);
|
|
69
|
+
await testdriver.screenshot();
|
|
70
|
+
|
|
71
|
+
expect(result.success).toBe(true);
|
|
72
|
+
}, 180000);
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Running This Example
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Clone the TestDriver repository
|
|
80
|
+
git clone https://github.com/testdriverai/testdriverai
|
|
81
|
+
|
|
82
|
+
# Install dependencies
|
|
83
|
+
cd testdriverai
|
|
84
|
+
npm install
|
|
85
|
+
|
|
86
|
+
# Run this specific example
|
|
87
|
+
npx vitest run examples/captcha-api.test.mjs
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
<Note>
|
|
91
|
+
Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
|
|
92
|
+
</Note>
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Chrome Extension Test Example"
|
|
3
|
+
sidebarTitle: "Chrome Extension"
|
|
4
|
+
description: "Example test showing how to load Chrome extensions from local paths or the Chrome Web Store."
|
|
5
|
+
icon: "chrome"
|
|
6
|
+
mode: "wide"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Demo Test Run
|
|
10
|
+
|
|
11
|
+
Watch this test execute in a real sandbox environment:
|
|
12
|
+
|
|
13
|
+
{/* chrome-extension.test.mjs output */}
|
|
14
|
+
<iframe
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/698b7ca711cc20acdd4ac83d/replay"
|
|
16
|
+
width="100%"
|
|
17
|
+
height="390"
|
|
18
|
+
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
19
|
+
allow="fullscreen"
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
## Source Code
|
|
23
|
+
|
|
24
|
+
```javascript title="chrome-extension.test.mjs" {31-33}
|
|
25
|
+
/**
|
|
26
|
+
* TestDriver SDK - Chrome Extension Test
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { describe, expect, it } from "vitest";
|
|
30
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
31
|
+
|
|
32
|
+
describe("Chrome Extension Test", () => {
|
|
33
|
+
it("should load hello-world Chrome extension from local path", async (context) => {
|
|
34
|
+
|
|
35
|
+
console.log('connecting to', process.env.TD_IP)
|
|
36
|
+
|
|
37
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, cacheKey: new Date().getTime().toString() });
|
|
38
|
+
|
|
39
|
+
// Determine OS-specific paths and commands
|
|
40
|
+
const shell = testdriver.os === 'windows' ? 'pwsh' : 'sh';
|
|
41
|
+
const extensionsDir = testdriver.os === 'windows'
|
|
42
|
+
? 'C:\\Users\\testdriver\\Downloads\\chrome-extensions-samples'
|
|
43
|
+
: '/tmp/chrome-extensions-samples';
|
|
44
|
+
const extensionPath = testdriver.os === 'windows'
|
|
45
|
+
? `${extensionsDir}\\functional-samples\\tutorial.hello-world`
|
|
46
|
+
: `${extensionsDir}/functional-samples/tutorial.hello-world`;
|
|
47
|
+
|
|
48
|
+
// Clone the Chrome extensions samples repo
|
|
49
|
+
const cloneCmd = testdriver.os === 'windows'
|
|
50
|
+
? `git clone --depth 1 https://github.com/GoogleChrome/chrome-extensions-samples.git "${extensionsDir}"`
|
|
51
|
+
: `git clone --depth 1 https://github.com/GoogleChrome/chrome-extensions-samples.git ${extensionsDir}`;
|
|
52
|
+
|
|
53
|
+
await testdriver.exec(shell, cloneCmd, 60000, true);
|
|
54
|
+
|
|
55
|
+
// Launch Chrome with the hello-world extension loaded
|
|
56
|
+
await testdriver.provision.chromeExtension({
|
|
57
|
+
extensionPath: extensionPath
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Navigate to testdriver.ai (extensions don't load on New Tab)
|
|
61
|
+
const addressBar = await testdriver.find("Chrome address bar");
|
|
62
|
+
await addressBar.click();
|
|
63
|
+
await testdriver.type("testdriver.ai");
|
|
64
|
+
await testdriver.pressKeys(["enter"]);
|
|
65
|
+
|
|
66
|
+
// Wait for page to load
|
|
67
|
+
const pageResult = await testdriver.assert("I can see testdriver.ai");
|
|
68
|
+
expect(pageResult).toBeTruthy();
|
|
69
|
+
|
|
70
|
+
// The hello-world extension adds a puzzle piece icon to the toolbar
|
|
71
|
+
// When clicked, it shows a popup with "Hello Extensions"
|
|
72
|
+
|
|
73
|
+
// Click on the extensions button (puzzle piece icon) in Chrome toolbar
|
|
74
|
+
const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar", {zoom: true});
|
|
75
|
+
await extensionsButton.click();
|
|
76
|
+
|
|
77
|
+
// Look for the hello world extension in the extensions menu
|
|
78
|
+
const helloExtension = await testdriver.find("Hello Extensions extension in the extensions dropdown");
|
|
79
|
+
await helloExtension.click();
|
|
80
|
+
|
|
81
|
+
// Verify the extension popup shows "Hello Extensions" text
|
|
82
|
+
const popupResult = await testdriver.assert("a popup shows with the text 'Hello Extensions'");
|
|
83
|
+
expect(popupResult).toBeTruthy();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should load Loom from Chrome Web Store by extensionId", async (context) => {
|
|
87
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
88
|
+
|
|
89
|
+
// Launch Chrome with Loom loaded by its Chrome Web Store ID
|
|
90
|
+
// Loom ID: liecbddmkiiihnedobmlmillhodjkdmb
|
|
91
|
+
await testdriver.provision.chromeExtension({
|
|
92
|
+
extensionId: 'liecbddmkiiihnedobmlmillhodjkdmb'
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Navigate to testdriver.ai (extensions don't load on New Tab)
|
|
96
|
+
const addressBar = await testdriver.find("Chrome address bar");
|
|
97
|
+
await addressBar.click();
|
|
98
|
+
await testdriver.type("testdriver.ai");
|
|
99
|
+
await testdriver.pressKeys(["enter"]);
|
|
100
|
+
|
|
101
|
+
// Wait for page to load
|
|
102
|
+
const pageResult = await testdriver.assert("I can see testdriver.ai");
|
|
103
|
+
expect(pageResult).toBeTruthy();
|
|
104
|
+
|
|
105
|
+
// Click on the extensions button (puzzle piece icon) in Chrome toolbar
|
|
106
|
+
const extensionsButton = await testdriver.find("The puzzle-shaped icon in the Chrome toolbar.", {zoom: true});
|
|
107
|
+
await extensionsButton.click();
|
|
108
|
+
|
|
109
|
+
// Look for Loom in the extensions menu
|
|
110
|
+
const loomExtension = await testdriver.find("Loom extension in the extensions dropdown");
|
|
111
|
+
expect(loomExtension.found()).toBeTruthy();
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Running This Example
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# Clone the TestDriver repository
|
|
120
|
+
git clone https://github.com/testdriverai/testdriverai
|
|
121
|
+
|
|
122
|
+
# Install dependencies
|
|
123
|
+
cd testdriverai
|
|
124
|
+
npm install
|
|
125
|
+
|
|
126
|
+
# Run this specific example
|
|
127
|
+
npx vitest run examples/chrome-extension.test.mjs
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
<Note>
|
|
131
|
+
Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
|
|
132
|
+
</Note>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Drag and Drop Test Example"
|
|
3
|
+
sidebarTitle: "Drag and Drop"
|
|
4
|
+
description: "Example test demonstrating drag and drop interactions using mouseDown and mouseUp."
|
|
5
|
+
icon: "arrows-up-down-left-right"
|
|
6
|
+
mode: "wide"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Demo Test Run
|
|
10
|
+
|
|
11
|
+
Watch this test execute in a real sandbox environment:
|
|
12
|
+
|
|
13
|
+
{/* drag-and-drop.test.mjs output */}
|
|
14
|
+
<iframe
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/698b7bd411cc20acdd4ac828/replay"
|
|
16
|
+
width="100%"
|
|
17
|
+
height="390"
|
|
18
|
+
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
19
|
+
allow="fullscreen"
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
## Source Code
|
|
23
|
+
|
|
24
|
+
```javascript title="drag-and-drop.test.mjs" {33-34,38-39}
|
|
25
|
+
/**
|
|
26
|
+
* TestDriver SDK - Drag and Drop Test
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { describe, expect, it } from "vitest";
|
|
30
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
31
|
+
|
|
32
|
+
const isLinux = (process.env.TD_OS || "linux") === "linux";
|
|
33
|
+
|
|
34
|
+
describe("Drag and Drop Test", () => {
|
|
35
|
+
it.skipIf(isLinux)(
|
|
36
|
+
'should drag "New Text Document" to "Recycle Bin"',
|
|
37
|
+
async (context) => {
|
|
38
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
39
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
40
|
+
|
|
41
|
+
//
|
|
42
|
+
// Show the desktop
|
|
43
|
+
await testdriver.pressKeys(["win", "d"]);
|
|
44
|
+
|
|
45
|
+
// Open the context menu
|
|
46
|
+
await testdriver.pressKeys(["shift", "f10"]);
|
|
47
|
+
|
|
48
|
+
// Hover over "New" in the context menu
|
|
49
|
+
const newOption = await testdriver.find(
|
|
50
|
+
"New, new option in the open context menu on the desktop",
|
|
51
|
+
);
|
|
52
|
+
await newOption.hover();
|
|
53
|
+
|
|
54
|
+
// Click "Text Document" in the context menu
|
|
55
|
+
const textDocOption = await testdriver.find(
|
|
56
|
+
"Text Document, text document option in the new submenu of the desktop context menu",
|
|
57
|
+
);
|
|
58
|
+
await textDocOption.click();
|
|
59
|
+
|
|
60
|
+
// Unfocus the "Text Document" text field
|
|
61
|
+
await testdriver.pressKeys(["esc"]);
|
|
62
|
+
|
|
63
|
+
// Drag the "New Text Document" icon to the "Recycle Bin"
|
|
64
|
+
const textDoc = await testdriver.find(
|
|
65
|
+
"New Text Document, new text document icon in the center of the desktop",
|
|
66
|
+
);
|
|
67
|
+
await textDoc.mouseDown();
|
|
68
|
+
|
|
69
|
+
const recycleBin = await testdriver.find(
|
|
70
|
+
"Recycle Bin, recycle bin icon in the top left corner of the desktop",
|
|
71
|
+
);
|
|
72
|
+
await recycleBin.mouseUp();
|
|
73
|
+
|
|
74
|
+
// Assert "New Text Document" icon is not on the Desktop
|
|
75
|
+
const result = await testdriver.assert(
|
|
76
|
+
'the "New Text Document" icon is not visible on the Desktop',
|
|
77
|
+
);
|
|
78
|
+
expect(result).toBeTruthy();
|
|
79
|
+
},
|
|
80
|
+
);
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Running This Example
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Clone the TestDriver repository
|
|
88
|
+
git clone https://github.com/testdriverai/testdriverai
|
|
89
|
+
|
|
90
|
+
# Install dependencies
|
|
91
|
+
cd testdriverai
|
|
92
|
+
npm install
|
|
93
|
+
|
|
94
|
+
# Run this specific example
|
|
95
|
+
npx vitest run examples/drag-and-drop.test.mjs
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
<Note>
|
|
99
|
+
Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
|
|
100
|
+
</Note>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Element Not Found Test"
|
|
3
|
+
sidebarTitle: "Element Not Found"
|
|
4
|
+
description: "Example test showing how to gracefully handle elements that don't exist on the page."
|
|
5
|
+
icon: "crosshairs"
|
|
6
|
+
mode: "wide"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Demo Test Run
|
|
10
|
+
|
|
11
|
+
Watch this test execute in a real sandbox environment:
|
|
12
|
+
|
|
13
|
+
{/* element-not-found.test.mjs output */}
|
|
14
|
+
<iframe
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/698b7dd44f24dc8fa701f5fc/replay"
|
|
16
|
+
width="100%"
|
|
17
|
+
height="390"
|
|
18
|
+
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
19
|
+
allow="fullscreen"
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
## Source Code
|
|
23
|
+
|
|
24
|
+
```javascript title="element-not-found.test.mjs" {16-18}
|
|
25
|
+
/**
|
|
26
|
+
* TestDriver SDK - Element Not Found Test
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { describe, expect, it } from "vitest";
|
|
30
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
31
|
+
|
|
32
|
+
describe("Element Not Found Test", () => {
|
|
33
|
+
it("should handle non-existent element gracefully without timing out", async (context) => {
|
|
34
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
35
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
36
|
+
|
|
37
|
+
//
|
|
38
|
+
|
|
39
|
+
// Try to find an element that definitely doesn't exist
|
|
40
|
+
const element = await testdriver.find(
|
|
41
|
+
"a purple unicorn dancing on the moon",
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// Should return an element that is not found
|
|
45
|
+
expect(element.found()).toBe(false);
|
|
46
|
+
expect(element.coordinates).toBeNull();
|
|
47
|
+
}); // 90 second timeout for the test (should complete much faster)
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Running This Example
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Clone the TestDriver repository
|
|
55
|
+
git clone https://github.com/testdriverai/testdriverai
|
|
56
|
+
|
|
57
|
+
# Install dependencies
|
|
58
|
+
cd testdriverai
|
|
59
|
+
npm install
|
|
60
|
+
|
|
61
|
+
# Run this specific example
|
|
62
|
+
npx vitest run examples/element-not-found.test.mjs
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
<Note>
|
|
66
|
+
Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
|
|
67
|
+
</Note>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Clicking Image Example"
|
|
3
|
+
sidebarTitle: "Clicking on an Image"
|
|
4
|
+
description: "Example test that finds and clicks on an image element using AI-powered visual recognition."
|
|
5
|
+
icon: "hand-pointer"
|
|
6
|
+
mode: "wide"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Demo Test Run
|
|
10
|
+
|
|
11
|
+
Watch this test execute in a real sandbox environment:
|
|
12
|
+
|
|
13
|
+
{/* hover-image.test.mjs output */}
|
|
14
|
+
<iframe
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/698b7c9211cc20acdd4ac83c/replay"
|
|
16
|
+
width="100%"
|
|
17
|
+
height="390"
|
|
18
|
+
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
19
|
+
allow="fullscreen"
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
## Source Code
|
|
23
|
+
|
|
24
|
+
```javascript title="hover-image.test.mjs" {40-42,47}
|
|
25
|
+
/**
|
|
26
|
+
* TestDriver SDK - Hover Image Test
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { describe, expect, it } from "vitest";
|
|
30
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Perform login flow for SauceLabs demo app
|
|
34
|
+
* @param {import('../../sdk.js').default} client - TestDriver client instance
|
|
35
|
+
* @param {string} username - Username (default: 'standard_user')
|
|
36
|
+
*/
|
|
37
|
+
async function performLogin(client, username = "standard_user") {
|
|
38
|
+
await client.focusApplication("Google Chrome");
|
|
39
|
+
const password = await client.extract("the password");
|
|
40
|
+
const usernameField = await client.find(
|
|
41
|
+
"username input",
|
|
42
|
+
);
|
|
43
|
+
await usernameField.click();
|
|
44
|
+
await client.type(username);
|
|
45
|
+
await client.pressKeys(["tab"]);
|
|
46
|
+
await client.type(password, { secret: true });
|
|
47
|
+
await client.pressKeys(["tab"]);
|
|
48
|
+
await client.pressKeys(["enter"]);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
describe("Hover Image Test", () => {
|
|
52
|
+
it("should click on shopping cart icon and verify empty cart", async (context) => {
|
|
53
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, redraw: false });
|
|
54
|
+
|
|
55
|
+
// provision.chrome() automatically calls ready() and starts dashcam
|
|
56
|
+
await testdriver.provision.chrome({
|
|
57
|
+
url: 'http://testdriver-sandbox.vercel.app/login'
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Perform login first
|
|
61
|
+
await performLogin(testdriver);
|
|
62
|
+
|
|
63
|
+
// Click on the shopping cart icon
|
|
64
|
+
await testdriver.focusApplication("Google Chrome");
|
|
65
|
+
const cartIcon = await testdriver.find(
|
|
66
|
+
"shopping cart icon next to the Cart text in the top right corner",
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
await cartIcon.click();
|
|
70
|
+
|
|
71
|
+
// Assert that you see an empty shopping cart
|
|
72
|
+
const result = await testdriver.assert("Your cart is empty");
|
|
73
|
+
expect(result).toBeTruthy();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Running This Example
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Clone the TestDriver repository
|
|
82
|
+
git clone https://github.com/testdriverai/testdriverai
|
|
83
|
+
|
|
84
|
+
# Install dependencies
|
|
85
|
+
cd testdriverai
|
|
86
|
+
npm install
|
|
87
|
+
|
|
88
|
+
# Run this specific example
|
|
89
|
+
npx vitest run examples/hover-image.test.mjs
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
<Note>
|
|
93
|
+
Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
|
|
94
|
+
</Note>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Clicking on Text Example"
|
|
3
|
+
sidebarTitle: "Hover Text"
|
|
4
|
+
description: "Example test that finds and clicks on text elements using natural language descriptions."
|
|
5
|
+
icon: "hand-pointer"
|
|
6
|
+
mode: "wide"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Demo Test Run
|
|
10
|
+
|
|
11
|
+
Watch this test execute in a real sandbox environment:
|
|
12
|
+
|
|
13
|
+
{/* hover-text.test.mjs output */}
|
|
14
|
+
<iframe
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/698b7e186513c6b23f858efc/replay"
|
|
16
|
+
width="100%"
|
|
17
|
+
height="390"
|
|
18
|
+
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
19
|
+
allow="fullscreen"
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
## Source Code
|
|
23
|
+
|
|
24
|
+
```javascript title="hover-text.test.mjs" {13-15,18-20}
|
|
25
|
+
/**
|
|
26
|
+
* TestDriver SDK - Hover Text Test
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { describe, expect, it } from "vitest";
|
|
30
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
31
|
+
|
|
32
|
+
describe("Hover Text Test", () => {
|
|
33
|
+
it("should click Sign In and verify error message", async (context) => {
|
|
34
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
35
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
36
|
+
|
|
37
|
+
// Click on Sign In button using new find() API
|
|
38
|
+
|
|
39
|
+
const signInButton = await testdriver.find(
|
|
40
|
+
"Sign In, black button below the password field",
|
|
41
|
+
);
|
|
42
|
+
await signInButton.click();
|
|
43
|
+
|
|
44
|
+
// Assert that an error shows that fields are required
|
|
45
|
+
const result = await testdriver.assert(
|
|
46
|
+
"an error shows that fields are required",
|
|
47
|
+
);
|
|
48
|
+
expect(result).toBeTruthy();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Running This Example
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Clone the TestDriver repository
|
|
57
|
+
git clone https://github.com/testdriverai/testdriverai
|
|
58
|
+
|
|
59
|
+
# Install dependencies
|
|
60
|
+
cd testdriverai
|
|
61
|
+
npm install
|
|
62
|
+
|
|
63
|
+
# Run this specific example
|
|
64
|
+
npx vitest run examples/hover-text.test.mjs
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
<Note>
|
|
68
|
+
Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
|
|
69
|
+
</Note>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Linux App Installation Test Example"
|
|
3
|
+
sidebarTitle: "Linux Installer"
|
|
4
|
+
description: "Example test demonstrating how to download and install .deb packages and shell scripts on Linux."
|
|
5
|
+
icon: "download"
|
|
6
|
+
mode: "wide"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Demo Test Run
|
|
10
|
+
|
|
11
|
+
Watch this test execute in a real sandbox environment:
|
|
12
|
+
|
|
13
|
+
{/* installer.test.mjs output */}
|
|
14
|
+
<iframe
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/698b7ce511cc20acdd4ac844/replay"
|
|
16
|
+
width="100%"
|
|
17
|
+
height="390"
|
|
18
|
+
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
19
|
+
allow="fullscreen"
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
## Source Code
|
|
23
|
+
|
|
24
|
+
```javascript title="installer.test.mjs" {16-18}
|
|
25
|
+
/**
|
|
26
|
+
* TestDriver SDK - Installer Test
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { describe, expect, it } from "vitest";
|
|
30
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
31
|
+
|
|
32
|
+
const isLinux = (process.env.TD_OS || "linux") === "linux";
|
|
33
|
+
|
|
34
|
+
describe("Provision Installer", () => {
|
|
35
|
+
it.skipIf(!isLinux)(
|
|
36
|
+
"should download and install a .deb package on Linux",
|
|
37
|
+
async (context) => {
|
|
38
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
39
|
+
|
|
40
|
+
// Install bat (a cat clone with syntax highlighting) using provision.installer
|
|
41
|
+
const filePath = await testdriver.provision.installer({
|
|
42
|
+
url: 'https://github.com/sharkdp/bat/releases/download/v0.24.0/bat_0.24.0_amd64.deb',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Verify the file was downloaded
|
|
46
|
+
expect(filePath).toContain('bat');
|
|
47
|
+
|
|
48
|
+
// Verify bat was installed by running it
|
|
49
|
+
await testdriver.exec('sh', 'bat --version', 10000);
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
it.skipIf(!isLinux)(
|
|
54
|
+
"should download a shell script and verify it exists",
|
|
55
|
+
async (context) => {
|
|
56
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
57
|
+
|
|
58
|
+
// Download a shell script (nvm installer)
|
|
59
|
+
const filePath = await testdriver.provision.installer({
|
|
60
|
+
url: 'https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh',
|
|
61
|
+
launch: false, // Don't auto-run the script
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Verify the file was downloaded
|
|
65
|
+
expect(filePath).toContain('install.sh');
|
|
66
|
+
|
|
67
|
+
// Verify the file is executable
|
|
68
|
+
const result = await testdriver.exec('sh', `ls -la "${filePath}"`, 10000);
|
|
69
|
+
expect(result).toBeTruthy();
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Running This Example
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Clone the TestDriver repository
|
|
79
|
+
git clone https://github.com/testdriverai/testdriverai
|
|
80
|
+
|
|
81
|
+
# Install dependencies
|
|
82
|
+
cd testdriverai
|
|
83
|
+
npm install
|
|
84
|
+
|
|
85
|
+
# Run this specific example
|
|
86
|
+
npx vitest run examples/installer.test.mjs
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
<Note>
|
|
90
|
+
Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
|
|
91
|
+
</Note>
|