testdriverai 7.2.3 → 7.2.10
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/publish.yaml +15 -7
- package/.github/workflows/testdriver.yml +163 -0
- package/.testdriver/last-sandbox +7 -0
- package/agent/events.js +1 -0
- package/agent/index.js +99 -163
- package/agent/lib/sandbox.js +11 -1
- package/agents.md +393 -0
- package/bin/testdriverai.js +8 -0
- package/debug/01-table-initial.png +0 -0
- package/debug/02-after-ai-explore.png +0 -0
- package/debug/02-after-scroll.png +0 -0
- package/debugger/index.html +37 -0
- package/docs/docs.json +93 -125
- package/docs/v7/_drafts/architecture.mdx +1 -26
- package/docs/v7/_drafts/caching.mdx +2 -2
- package/docs/v7/{getting-started → _drafts}/installation.mdx +0 -66
- package/docs/v7/{features/coverage.mdx → _drafts/powerful.mdx} +1 -90
- package/docs/v7/_drafts/quick-start-test-recording.mdx +0 -1
- package/docs/v7/{features → _drafts}/scalable.mdx +126 -4
- package/docs/v7/_drafts/screenshot.mdx +155 -0
- package/docs/v7/_drafts/test-recording.mdx +0 -6
- package/docs/v7/_drafts/writing-tests.mdx +25 -0
- package/docs/v7/{api/act.mdx → ai.mdx} +28 -27
- package/docs/v7/{api/assert.mdx → assert.mdx} +3 -3
- package/docs/v7/aws-setup.mdx +338 -0
- package/docs/v7/caching.mdx +128 -0
- package/docs/v7/ci-cd.mdx +605 -0
- package/docs/v7/{api/click.mdx → click.mdx} +4 -4
- package/docs/v7/cloud.mdx +120 -0
- package/docs/v7/customizing-devices.mdx +129 -0
- package/docs/v7/{api/doubleClick.mdx → double-click.mdx} +5 -5
- package/docs/v7/enterprise.mdx +135 -0
- package/docs/v7/examples.mdx +5 -0
- package/docs/v7/{api/exec.mdx → exec.mdx} +3 -3
- package/docs/v7/{api/find.mdx → find.mdx} +17 -21
- package/docs/v7/{api/focusApplication.mdx → focus-application.mdx} +3 -3
- package/docs/v7/generating-tests.mdx +32 -0
- package/docs/v7/{api/hover.mdx → hover.mdx} +3 -3
- package/docs/v7/locating-elements.mdx +71 -0
- package/docs/v7/making-assertions.mdx +32 -0
- package/docs/v7/{api/mouseDown.mdx → mouse-down.mdx} +7 -7
- package/docs/v7/{api/mouseUp.mdx → mouse-up.mdx} +8 -8
- package/docs/v7/performing-actions.mdx +51 -0
- package/docs/v7/{api/pressKeys.mdx → press-keys.mdx} +3 -3
- package/docs/v7/quickstart.mdx +162 -0
- package/docs/v7/reusable-code.mdx +240 -0
- package/docs/v7/{api/rightClick.mdx → right-click.mdx} +5 -5
- package/docs/v7/running-tests.mdx +181 -0
- package/docs/v7/{api/scroll.mdx → scroll.mdx} +3 -3
- package/docs/v7/secrets.mdx +115 -0
- package/docs/v7/self-hosted.mdx +66 -0
- package/docs/v7/{api/type.mdx → type.mdx} +3 -3
- package/docs/v7/variables.mdx +111 -0
- package/docs/v7/waiting-for-elements.mdx +66 -0
- package/docs/v7/what-is-testdriver.mdx +54 -0
- package/interfaces/cli/commands/init.js +33 -19
- package/interfaces/cli/lib/base.js +24 -0
- package/interfaces/cli.js +8 -1
- package/interfaces/logger.js +8 -3
- package/interfaces/vitest-plugin.mjs +16 -71
- package/lib/sentry.js +343 -0
- package/lib/vitest/hooks.mjs +81 -81
- package/package.json +4 -3
- package/sdk-log-formatter.js +41 -0
- package/sdk.d.ts +22 -9
- package/sdk.js +344 -100
- package/test/manual/reconnect-provision.test.mjs +49 -0
- package/test/manual/reconnect-signin.test.mjs +41 -0
- package/test/testdriver/act.test.mjs +30 -0
- package/test/testdriver/ai.test.mjs +30 -0
- package/test/testdriver/assert.test.mjs +1 -1
- package/test/testdriver/hover-text.test.mjs +1 -1
- package/test/testdriver/setup/testHelpers.mjs +8 -119
- package/test/testdriver/windows-installer.test.mjs +61 -0
- package/tests/example.test.js +33 -0
- package/tests/login.js +28 -0
- package/tests/table-sort-enrollments.test.mjs +72 -0
- package/tests/table-sort-experiment.test.mjs +42 -0
- package/tests/table-sort-setup.test.mjs +59 -0
- package/vitest.config.mjs +3 -1
- package/agent/lib/cache.js +0 -142
- package/docs/v7/api/assertions.mdx +0 -403
- package/docs/v7/features/ai-native.mdx +0 -413
- package/docs/v7/features/application-logs.mdx +0 -353
- package/docs/v7/features/browser-logs.mdx +0 -414
- package/docs/v7/features/cache-management.mdx +0 -402
- package/docs/v7/features/continuous-testing.mdx +0 -346
- package/docs/v7/features/data-driven-testing.mdx +0 -441
- package/docs/v7/features/easy-to-write.mdx +0 -280
- package/docs/v7/features/enterprise.mdx +0 -656
- package/docs/v7/features/fast.mdx +0 -406
- package/docs/v7/features/managed-sandboxes.mdx +0 -384
- package/docs/v7/features/network-monitoring.mdx +0 -568
- package/docs/v7/features/parallel-execution.mdx +0 -381
- package/docs/v7/features/powerful.mdx +0 -531
- package/docs/v7/features/sandbox-customization.mdx +0 -229
- package/docs/v7/features/stable.mdx +0 -473
- package/docs/v7/features/system-performance.mdx +0 -616
- package/docs/v7/features/test-analytics.mdx +0 -373
- package/docs/v7/features/test-cases.mdx +0 -393
- package/docs/v7/features/test-replays.mdx +0 -408
- package/docs/v7/features/test-reports.mdx +0 -308
- package/docs/v7/getting-started/debugging-tests.mdx +0 -382
- package/docs/v7/getting-started/quickstart.mdx +0 -90
- package/docs/v7/getting-started/running-tests.mdx +0 -173
- package/docs/v7/getting-started/setting-up-in-ci.mdx +0 -612
- package/docs/v7/getting-started/writing-tests.mdx +0 -534
- package/docs/v7/overview/what-is-testdriver.mdx +0 -386
- package/docs/v7/presets/chrome-extension.mdx +0 -248
- package/docs/v7/presets/chrome.mdx +0 -300
- package/docs/v7/presets/electron.mdx +0 -460
- package/docs/v7/presets/vscode.mdx +0 -417
- package/docs/v7/presets/webapp.mdx +0 -393
- /package/docs/v7/{commands → _drafts/commands}/assert.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/exec.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/focus-application.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/hover-image.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/hover-text.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/if.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/match-image.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/press-keys.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/remember.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/run.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/scroll-until-image.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/scroll-until-text.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/scroll.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/type.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/wait-for-image.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/wait-for-text.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/wait.mdx +0 -0
- /package/docs/v7/{getting-started → _drafts}/configuration.mdx +0 -0
- /package/docs/v7/{features → _drafts}/observable.mdx +0 -0
- /package/docs/v7/{platforms → _drafts/platforms}/linux.mdx +0 -0
- /package/docs/v7/{platforms → _drafts/platforms}/macos.mdx +0 -0
- /package/docs/v7/{platforms → _drafts/platforms}/windows.mdx +0 -0
- /package/docs/v7/{playwright.mdx → _drafts/playwright.mdx} +0 -0
- /package/docs/v7/{overview → _drafts}/readme.mdx +0 -0
- /package/docs/v7/{features → _drafts}/reports.mdx +0 -0
- /package/docs/v7/{api/client.mdx → client.mdx} +0 -0
- /package/docs/v7/{api/dashcam.mdx → dashcam.mdx} +0 -0
- /package/docs/v7/{api/elements.mdx → elements.mdx} +0 -0
- /package/docs/v7/{api/sandbox.mdx → sandbox.mdx} +0 -0
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: 'Sandbox Customization'
|
|
3
|
-
description: 'Customize your test environments with pre-installed applications, dependencies, and configurations'
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
TestDriver sandboxes can be customized to match your testing requirements. Install applications, configure system settings, and prepare environments programmatically to ensure your tests run in the right context.
|
|
9
|
-
|
|
10
|
-
## Provisioning API
|
|
11
|
-
|
|
12
|
-
The provisioning API allows you to customize sandbox environments before running tests.
|
|
13
|
-
|
|
14
|
-
### Installing Applications
|
|
15
|
-
|
|
16
|
-
Use the provisioning API to install software packages:
|
|
17
|
-
|
|
18
|
-
```javascript
|
|
19
|
-
import { ai } from '@testdriverai/sdk';
|
|
20
|
-
|
|
21
|
-
// Install applications before tests
|
|
22
|
-
await ai('install Chrome browser');
|
|
23
|
-
await ai('install Node.js version 18');
|
|
24
|
-
await ai('install PostgreSQL database');
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
### System Configuration
|
|
28
|
-
|
|
29
|
-
Configure system settings and preferences:
|
|
30
|
-
|
|
31
|
-
```javascript
|
|
32
|
-
// Set environment variables
|
|
33
|
-
await ai('set NODE_ENV to production');
|
|
34
|
-
|
|
35
|
-
// Configure system settings
|
|
36
|
-
await ai('enable dark mode');
|
|
37
|
-
await ai('set screen resolution to 1920x1080');
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Exec Command
|
|
41
|
-
|
|
42
|
-
The `exec` command allows you to run shell commands directly in the sandbox:
|
|
43
|
-
|
|
44
|
-
```javascript
|
|
45
|
-
import { exec } from '@testdriverai/sdk';
|
|
46
|
-
|
|
47
|
-
// Install packages via package manager
|
|
48
|
-
await exec('apt-get update && apt-get install -y git');
|
|
49
|
-
|
|
50
|
-
// Run setup scripts
|
|
51
|
-
await exec('npm install -g typescript');
|
|
52
|
-
|
|
53
|
-
// Configure applications
|
|
54
|
-
await exec('cp config.json /etc/myapp/config.json');
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Examples
|
|
58
|
-
|
|
59
|
-
#### Installing Development Tools
|
|
60
|
-
|
|
61
|
-
```javascript
|
|
62
|
-
// Install common development tools
|
|
63
|
-
await exec('apt-get update');
|
|
64
|
-
await exec('apt-get install -y curl wget git vim');
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
#### Setting Up a Web Server
|
|
68
|
-
|
|
69
|
-
```javascript
|
|
70
|
-
// Install and configure nginx
|
|
71
|
-
await exec('apt-get install -y nginx');
|
|
72
|
-
await exec('systemctl start nginx');
|
|
73
|
-
await exec('systemctl enable nginx');
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
#### Installing Language Runtimes
|
|
77
|
-
|
|
78
|
-
```javascript
|
|
79
|
-
// Install Python and pip
|
|
80
|
-
await exec('apt-get install -y python3 python3-pip');
|
|
81
|
-
await exec('pip3 install requests pytest');
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Pre-Test Setup
|
|
85
|
-
|
|
86
|
-
Run setup commands before each test:
|
|
87
|
-
|
|
88
|
-
```javascript
|
|
89
|
-
import { beforeAll } from 'vitest';
|
|
90
|
-
|
|
91
|
-
beforeAll(async () => {
|
|
92
|
-
// Install dependencies
|
|
93
|
-
await exec('npm install');
|
|
94
|
-
|
|
95
|
-
// Start services
|
|
96
|
-
await exec('npm run start-server &');
|
|
97
|
-
|
|
98
|
-
// Wait for service to be ready
|
|
99
|
-
await ai('wait for server to start on port 3000');
|
|
100
|
-
});
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## Environment Templates
|
|
104
|
-
|
|
105
|
-
Create reusable environment configurations:
|
|
106
|
-
|
|
107
|
-
```javascript
|
|
108
|
-
// environments/chrome-dev.js
|
|
109
|
-
export async function setupChromeDev() {
|
|
110
|
-
await exec('apt-get update');
|
|
111
|
-
await exec('apt-get install -y google-chrome-stable');
|
|
112
|
-
await exec('npm install -g lighthouse');
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Use in tests
|
|
116
|
-
import { setupChromeDev } from './environments/chrome-dev';
|
|
117
|
-
|
|
118
|
-
beforeAll(async () => {
|
|
119
|
-
await setupChromeDev();
|
|
120
|
-
});
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Custom VM Images (Enterprise)
|
|
124
|
-
|
|
125
|
-
For more complex customization needs, Enterprise customers can work with TestDriver to create custom VM images.
|
|
126
|
-
|
|
127
|
-
### Benefits of Custom AMIs
|
|
128
|
-
|
|
129
|
-
- **Faster Startup**: Pre-installed applications ready to use
|
|
130
|
-
- **Consistency**: Identical environments across all test runs
|
|
131
|
-
- **Complex Setup**: Handle intricate installation procedures once
|
|
132
|
-
- **Version Control**: Track and manage environment changes
|
|
133
|
-
|
|
134
|
-
### What Can Be Pre-Installed
|
|
135
|
-
|
|
136
|
-
- Desktop applications (browsers, IDEs, etc.)
|
|
137
|
-
- System dependencies and libraries
|
|
138
|
-
- Language runtimes and frameworks
|
|
139
|
-
- Database servers and tools
|
|
140
|
-
- Custom certificates and credentials
|
|
141
|
-
- System configurations and settings
|
|
142
|
-
|
|
143
|
-
### Working with TestDriver
|
|
144
|
-
|
|
145
|
-
Enterprise customers receive dedicated support for custom environments:
|
|
146
|
-
|
|
147
|
-
1. **Requirements Gathering**: Discuss your environment needs
|
|
148
|
-
2. **AMI Development**: We build and test the custom image
|
|
149
|
-
3. **Validation**: Review and approve the environment
|
|
150
|
-
4. **Deployment**: Roll out to your test infrastructure
|
|
151
|
-
5. **Maintenance**: Regular updates and security patches
|
|
152
|
-
|
|
153
|
-
Learn more about custom environments in our [Enterprise documentation](/v7/features/enterprise#custom-environments).
|
|
154
|
-
|
|
155
|
-
## Best Practices
|
|
156
|
-
|
|
157
|
-
### Keep Setup Scripts Fast
|
|
158
|
-
|
|
159
|
-
- Pre-install large dependencies in custom AMIs when possible
|
|
160
|
-
- Cache downloaded files and packages
|
|
161
|
-
- Run setup in parallel when independent
|
|
162
|
-
|
|
163
|
-
### Make Setup Idempotent
|
|
164
|
-
|
|
165
|
-
- Check if software is already installed before installing
|
|
166
|
-
- Use version checks to avoid unnecessary reinstalls
|
|
167
|
-
- Handle errors gracefully
|
|
168
|
-
|
|
169
|
-
```javascript
|
|
170
|
-
async function ensureNodeInstalled() {
|
|
171
|
-
try {
|
|
172
|
-
await exec('node --version');
|
|
173
|
-
} catch {
|
|
174
|
-
await exec('curl -fsSL https://deb.nodesource.com/setup_18.x | bash -');
|
|
175
|
-
await exec('apt-get install -y nodejs');
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Version Lock Dependencies
|
|
181
|
-
|
|
182
|
-
- Specify exact versions of tools and packages
|
|
183
|
-
- Avoid "latest" tags that can change
|
|
184
|
-
- Document version requirements
|
|
185
|
-
|
|
186
|
-
```javascript
|
|
187
|
-
// Good - specific version
|
|
188
|
-
await exec('npm install -g typescript@5.3.3');
|
|
189
|
-
|
|
190
|
-
// Avoid - version may change
|
|
191
|
-
await exec('npm install -g typescript');
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
## Troubleshooting
|
|
195
|
-
|
|
196
|
-
### Installation Failures
|
|
197
|
-
|
|
198
|
-
Check logs for detailed error messages:
|
|
199
|
-
|
|
200
|
-
```javascript
|
|
201
|
-
try {
|
|
202
|
-
await exec('apt-get install -y mypackage');
|
|
203
|
-
} catch (error) {
|
|
204
|
-
console.error('Installation failed:', error);
|
|
205
|
-
}
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### Permission Issues
|
|
209
|
-
|
|
210
|
-
Some commands may require sudo:
|
|
211
|
-
|
|
212
|
-
```javascript
|
|
213
|
-
await exec('sudo apt-get update');
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
### Network Issues
|
|
217
|
-
|
|
218
|
-
Ensure your sandbox has internet access for downloads:
|
|
219
|
-
|
|
220
|
-
```javascript
|
|
221
|
-
// Test connectivity
|
|
222
|
-
await exec('ping -c 3 google.com');
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
## Learn More
|
|
226
|
-
|
|
227
|
-
- [Exec API Reference](/v7/api/exec)
|
|
228
|
-
- [Managed Sandboxes](/v7/features/managed-sandboxes)
|
|
229
|
-
- [Enterprise Features](/v7/features/enterprise)
|
|
@@ -1,473 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Flake Prevention"
|
|
3
|
-
description: "Anti-flake technology that eliminates test instability"
|
|
4
|
-
icon: "shield-check"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Test flakiness is the bane of CI/CD pipelines. TestDriver eliminates flaky tests with built-in anti-flake technology that automatically handles timing issues, animations, and dynamic content.
|
|
8
|
-
|
|
9
|
-
## The Flaky Test Problem
|
|
10
|
-
|
|
11
|
-
Traditional test frameworks suffer from race conditions and timing issues:
|
|
12
|
-
|
|
13
|
-
<CodeGroup>
|
|
14
|
-
```javascript Traditional - Flaky
|
|
15
|
-
// ❌ May fail randomly
|
|
16
|
-
await page.click('button');
|
|
17
|
-
await page.click('.dropdown-item'); // Element might not be ready!
|
|
18
|
-
|
|
19
|
-
// ❌ Arbitrary waits
|
|
20
|
-
await page.click('button');
|
|
21
|
-
await page.waitForTimeout(1000); // Hope 1 second is enough
|
|
22
|
-
await page.click('.dropdown-item');
|
|
23
|
-
|
|
24
|
-
// ❌ Complex wait logic
|
|
25
|
-
await page.click('button');
|
|
26
|
-
await page.waitForSelector('.dropdown-item', {
|
|
27
|
-
state: 'visible',
|
|
28
|
-
timeout: 5000
|
|
29
|
-
});
|
|
30
|
-
await page.waitForLoadState('networkidle');
|
|
31
|
-
await page.waitForTimeout(200); // Still need extra buffer!
|
|
32
|
-
await page.click('.dropdown-item');
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
```javascript TestDriver - Stable
|
|
36
|
-
// ✅ Just works
|
|
37
|
-
await testdriver.find('button').click();
|
|
38
|
-
await testdriver.find('dropdown item').click();
|
|
39
|
-
// TestDriver automatically waits for stability
|
|
40
|
-
```
|
|
41
|
-
</CodeGroup>
|
|
42
|
-
|
|
43
|
-
<Check>
|
|
44
|
-
TestDriver handles all timing automatically. No explicit waits, no arbitrary timeouts, no flaky tests.
|
|
45
|
-
</Check>
|
|
46
|
-
|
|
47
|
-
## Redraw Detection
|
|
48
|
-
|
|
49
|
-
TestDriver's redraw detection system automatically waits for the UI to stabilize before taking any action.
|
|
50
|
-
|
|
51
|
-
<Card title="What Redraw Detects" icon="eye">
|
|
52
|
-
The system monitors multiple stability signals:
|
|
53
|
-
|
|
54
|
-
- **Layout Reflows** - Position or size changes
|
|
55
|
-
- **CSS Animations** - Running animations and transitions
|
|
56
|
-
- **Network Activity** - Pending XHR/fetch requests
|
|
57
|
-
- **Visual Changes** - Pixel-level screenshot differences
|
|
58
|
-
- **Loading Indicators** - Spinners, progress bars, skeleton screens
|
|
59
|
-
</Card>
|
|
60
|
-
|
|
61
|
-
### How It Works
|
|
62
|
-
|
|
63
|
-
```mermaid
|
|
64
|
-
sequenceDiagram
|
|
65
|
-
participant Test as Your Test
|
|
66
|
-
participant TD as TestDriver
|
|
67
|
-
participant Monitor as Redraw Monitor
|
|
68
|
-
participant UI as Application UI
|
|
69
|
-
|
|
70
|
-
Test->>TD: find('dropdown item').click()
|
|
71
|
-
TD->>Monitor: Start monitoring stability
|
|
72
|
-
Monitor->>UI: Capture initial state
|
|
73
|
-
|
|
74
|
-
loop Stability Check
|
|
75
|
-
Monitor->>UI: Check for changes
|
|
76
|
-
alt UI is changing
|
|
77
|
-
UI-->>Monitor: DOM mutation detected
|
|
78
|
-
Monitor->>Monitor: Reset stability timer
|
|
79
|
-
else UI is stable
|
|
80
|
-
UI-->>Monitor: No changes
|
|
81
|
-
Monitor->>Monitor: Increment stable duration
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
Monitor->>TD: UI stable for 200ms
|
|
86
|
-
TD->>UI: Perform click action
|
|
87
|
-
TD-->>Test: Action completed
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Configurable Stability
|
|
91
|
-
|
|
92
|
-
Fine-tune stability detection for your application's needs:
|
|
93
|
-
|
|
94
|
-
```javascript
|
|
95
|
-
// Default stability settings (recommended)
|
|
96
|
-
await testdriver.find('button').click();
|
|
97
|
-
|
|
98
|
-
// Disable redraw detection for specific actions (advanced)
|
|
99
|
-
await testdriver.find('element', {
|
|
100
|
-
redraw: {
|
|
101
|
-
enabled: false // Skip stability detection
|
|
102
|
-
}
|
|
103
|
-
}).click();
|
|
104
|
-
|
|
105
|
-
// Disable only screen monitoring (keep network monitoring)
|
|
106
|
-
await testdriver.find('animated element', {
|
|
107
|
-
redraw: {
|
|
108
|
-
screenRedraw: false // Skip screen stability, still wait for network
|
|
109
|
-
}
|
|
110
|
-
}).click();
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
<Tip>
|
|
114
|
-
The default redraw settings work for 95% of applications. Only adjust if you have unusually subtle animations or need to bypass stability checks.
|
|
115
|
-
</Tip>
|
|
116
|
-
|
|
117
|
-
## Network Monitoring
|
|
118
|
-
|
|
119
|
-
TestDriver waits for network activity to complete before asserting or locating elements:
|
|
120
|
-
|
|
121
|
-
<AccordionGroup>
|
|
122
|
-
<Accordion title="Automatic Network Waiting">
|
|
123
|
-
```javascript
|
|
124
|
-
// TestDriver automatically waits for:
|
|
125
|
-
// 1. Pending XHR/fetch requests to complete
|
|
126
|
-
// 2. WebSocket messages to be processed
|
|
127
|
-
// 3. Image/asset loading to finish
|
|
128
|
-
|
|
129
|
-
await testdriver.find('submit button').click();
|
|
130
|
-
// ↑ Triggers API call
|
|
131
|
-
|
|
132
|
-
await testdriver.assert('Success message is visible');
|
|
133
|
-
// ↑ Automatically waits for API response before asserting
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
No need for manual `waitForResponse` or `waitForLoadState` calls.
|
|
137
|
-
</Accordion>
|
|
138
|
-
|
|
139
|
-
<Accordion title="Loading Indicator Detection">
|
|
140
|
-
```javascript
|
|
141
|
-
// TestDriver detects common loading patterns:
|
|
142
|
-
await testdriver.find('Load More button').click();
|
|
143
|
-
|
|
144
|
-
// Automatically waits for:
|
|
145
|
-
// - Loading spinner to appear and disappear
|
|
146
|
-
// - Skeleton screens to be replaced
|
|
147
|
-
// - Progress bars to complete
|
|
148
|
-
// - "Loading..." text to disappear
|
|
149
|
-
|
|
150
|
-
await testdriver.find('newly loaded content').click();
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
Common loading indicators are recognized and waited for automatically.
|
|
154
|
-
</Accordion>
|
|
155
|
-
|
|
156
|
-
<Accordion title="Custom Polling for Slow Elements">
|
|
157
|
-
```javascript
|
|
158
|
-
// For elements that take time to appear, use polling
|
|
159
|
-
async function waitForElement(description, timeoutMs = 60000) {
|
|
160
|
-
const startTime = Date.now();
|
|
161
|
-
while (Date.now() - startTime < timeoutMs) {
|
|
162
|
-
const element = await testdriver.find(description);
|
|
163
|
-
if (element.found()) return element;
|
|
164
|
-
await new Promise(r => setTimeout(r, 1000));
|
|
165
|
-
}
|
|
166
|
-
throw new Error(`Element "${description}" not found`);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const button = await waitForElement('submit button');
|
|
170
|
-
await button.click();
|
|
171
|
-
```
|
|
172
|
-
</Accordion>
|
|
173
|
-
</AccordionGroup>
|
|
174
|
-
|
|
175
|
-
## Screen Stability Monitoring
|
|
176
|
-
|
|
177
|
-
Visual stability is critical for reliable element location:
|
|
178
|
-
|
|
179
|
-
```javascript
|
|
180
|
-
// TestDriver monitors pixel-level changes
|
|
181
|
-
await testdriver.find('animated element').click();
|
|
182
|
-
|
|
183
|
-
// Waits for:
|
|
184
|
-
// ✓ CSS animations to complete
|
|
185
|
-
// ✓ Fade-in/fade-out effects to finish
|
|
186
|
-
// ✓ Slide transitions to settle
|
|
187
|
-
// ✓ Scroll animations to stop
|
|
188
|
-
// ✓ Dynamic content to load
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
<Card title="Example: Accordion Animation" icon="angles-down">
|
|
192
|
-
```javascript
|
|
193
|
-
// Traditional approach - prone to failure
|
|
194
|
-
await page.click('.accordion-header');
|
|
195
|
-
await page.waitForTimeout(300); // Hope animation is done
|
|
196
|
-
await page.click('.accordion-content button'); // Might fail!
|
|
197
|
-
|
|
198
|
-
// TestDriver - just works
|
|
199
|
-
await testdriver.find('accordion header').click();
|
|
200
|
-
await testdriver.find('button inside accordion content').click();
|
|
201
|
-
// ✅ Automatically waits for accordion animation to complete
|
|
202
|
-
```
|
|
203
|
-
</Card>
|
|
204
|
-
|
|
205
|
-
## Debugging Element Location
|
|
206
|
-
|
|
207
|
-
When elements aren't found, TestDriver provides detailed debugging information to help you understand why:
|
|
208
|
-
|
|
209
|
-
<Steps>
|
|
210
|
-
<Step title="Check Element Existence">
|
|
211
|
-
Verify if the element was found before interacting with it.
|
|
212
|
-
|
|
213
|
-
```javascript
|
|
214
|
-
const element = await testdriver.find('button');
|
|
215
|
-
if (element.found()) {
|
|
216
|
-
await element.click();
|
|
217
|
-
} else {
|
|
218
|
-
console.log('Button not found on page');
|
|
219
|
-
}
|
|
220
|
-
```
|
|
221
|
-
</Step>
|
|
222
|
-
|
|
223
|
-
<Step title="Review Debug Information">
|
|
224
|
-
Access detailed debugging data from the element response.
|
|
225
|
-
|
|
226
|
-
```javascript
|
|
227
|
-
const element = await testdriver.find('submit button');
|
|
228
|
-
|
|
229
|
-
console.log('Found:', element.found());
|
|
230
|
-
console.log('Similarity:', element.aiResponse?.similarity);
|
|
231
|
-
console.log('Cache hit:', element.aiResponse?.cacheHit);
|
|
232
|
-
console.log('Screenshot:', element.screenshotPath);
|
|
233
|
-
```
|
|
234
|
-
</Step>
|
|
235
|
-
|
|
236
|
-
<Step title="Analyze Visual Differences">
|
|
237
|
-
Compare what TestDriver saw vs. what you expected.
|
|
238
|
-
|
|
239
|
-
```javascript
|
|
240
|
-
const element = await testdriver.find('login button');
|
|
241
|
-
|
|
242
|
-
if (!element.found()) {
|
|
243
|
-
// Screenshot shows what TestDriver analyzed
|
|
244
|
-
console.log('Check screenshot:', element.screenshotPath);
|
|
245
|
-
|
|
246
|
-
// Similarity score indicates how close it got
|
|
247
|
-
console.log('Best match similarity:', element.aiResponse?.similarity);
|
|
248
|
-
|
|
249
|
-
// Review the description for clarity
|
|
250
|
-
console.log('Search description:', 'login button');
|
|
251
|
-
}
|
|
252
|
-
```
|
|
253
|
-
</Step>
|
|
254
|
-
|
|
255
|
-
<Step title="Refine Your Description">
|
|
256
|
-
Use debug insights to improve element descriptions.
|
|
257
|
-
|
|
258
|
-
```javascript
|
|
259
|
-
// Too vague
|
|
260
|
-
const btn = await testdriver.find('button');
|
|
261
|
-
|
|
262
|
-
// Better - more specific
|
|
263
|
-
const loginBtn = await testdriver.find('blue login button in header');
|
|
264
|
-
|
|
265
|
-
// Best - unique identifying features
|
|
266
|
-
const submitBtn = await testdriver.find('submit button with arrow icon');
|
|
267
|
-
```
|
|
268
|
-
</Step>
|
|
269
|
-
</Steps>
|
|
270
|
-
|
|
271
|
-
## Polling for Dynamic Elements
|
|
272
|
-
|
|
273
|
-
For elements that may take time to appear, implement polling:
|
|
274
|
-
|
|
275
|
-
```javascript
|
|
276
|
-
// Standard polling for normal elements
|
|
277
|
-
const timeoutMs = 30000; // 30 seconds
|
|
278
|
-
const startTime = Date.now();
|
|
279
|
-
let results;
|
|
280
|
-
|
|
281
|
-
while (Date.now() - startTime < timeoutMs) {
|
|
282
|
-
results = await testdriver.find('search results');
|
|
283
|
-
if (results.found()) break;
|
|
284
|
-
await new Promise(r => setTimeout(r, 1000)); // Check every second
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
if (results.found()) {
|
|
288
|
-
await results.click();
|
|
289
|
-
}
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
## Advanced: Redraw Configuration
|
|
293
|
-
|
|
294
|
-
The redraw system is configurable through [redraw.js](/agent/lib/redraw.js):
|
|
295
|
-
|
|
296
|
-
```javascript
|
|
297
|
-
// Global redraw settings
|
|
298
|
-
const testdriver = new TestDriver({
|
|
299
|
-
apiKey: process.env.TD_API_KEY,
|
|
300
|
-
redraw: {
|
|
301
|
-
enabled: true, // Master switch for redraw detection
|
|
302
|
-
screenRedraw: true, // Enable screen stability detection
|
|
303
|
-
networkMonitor: true, // Enable network activity monitoring
|
|
304
|
-
}
|
|
305
|
-
});
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### Per-Action Configuration
|
|
309
|
-
|
|
310
|
-
```javascript
|
|
311
|
-
// Override redraw settings for specific actions
|
|
312
|
-
await testdriver.find('fast element', {
|
|
313
|
-
redraw: {
|
|
314
|
-
enabled: false // Skip redraw detection entirely
|
|
315
|
-
}
|
|
316
|
-
}).click();
|
|
317
|
-
|
|
318
|
-
await testdriver.find('element with animation', {
|
|
319
|
-
redraw: {
|
|
320
|
-
screenRedraw: false, // Skip screen stability check
|
|
321
|
-
networkMonitor: true // Still wait for network to settle
|
|
322
|
-
}
|
|
323
|
-
}).click();
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
## Debugging Stability Issues
|
|
327
|
-
|
|
328
|
-
If you encounter stability issues, TestDriver provides detailed diagnostics:
|
|
329
|
-
|
|
330
|
-
```javascript
|
|
331
|
-
// Enable verbose logging to see redraw detection in action
|
|
332
|
-
const testdriver = new TestDriver({
|
|
333
|
-
apiKey: process.env.TD_API_KEY,
|
|
334
|
-
verbosity: 2 // Show detailed redraw logs
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
await testdriver.find('element').click();
|
|
338
|
-
// Console output will show:
|
|
339
|
-
// [redraw] Screen diff: 0.15%
|
|
340
|
-
// [redraw] Network activity: 1250 b/s
|
|
341
|
-
// [redraw] Waiting for stability...
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
## Common Stability Patterns
|
|
345
|
-
|
|
346
|
-
<AccordionGroup>
|
|
347
|
-
<Accordion title="Dropdown Menus">
|
|
348
|
-
```javascript
|
|
349
|
-
// Traditional - flaky
|
|
350
|
-
await page.click('.menu-button');
|
|
351
|
-
await page.waitForTimeout(200);
|
|
352
|
-
await page.click('.menu-item');
|
|
353
|
-
|
|
354
|
-
// TestDriver - stable
|
|
355
|
-
await testdriver.find('menu button').click();
|
|
356
|
-
await testdriver.find('menu item').click();
|
|
357
|
-
```
|
|
358
|
-
</Accordion>
|
|
359
|
-
|
|
360
|
-
<Accordion title="Modal Dialogs">
|
|
361
|
-
```javascript
|
|
362
|
-
// Traditional - flaky
|
|
363
|
-
await page.click('.open-modal');
|
|
364
|
-
await page.waitForSelector('.modal', { state: 'visible' });
|
|
365
|
-
await page.waitForTimeout(300); // Wait for animation
|
|
366
|
-
await page.click('.modal-button');
|
|
367
|
-
|
|
368
|
-
// TestDriver - stable
|
|
369
|
-
await testdriver.find('open modal button').click();
|
|
370
|
-
await testdriver.find('modal button').click();
|
|
371
|
-
```
|
|
372
|
-
</Accordion>
|
|
373
|
-
|
|
374
|
-
<Accordion title="Infinite Scroll">
|
|
375
|
-
```javascript
|
|
376
|
-
// Traditional - flaky
|
|
377
|
-
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
|
|
378
|
-
await page.waitForTimeout(1000);
|
|
379
|
-
await page.waitForLoadState('networkidle');
|
|
380
|
-
await page.click('.load-more');
|
|
381
|
-
|
|
382
|
-
// TestDriver - stable
|
|
383
|
-
await testdriver.scroll('down', 1000);
|
|
384
|
-
await testdriver.find('load more button').click();
|
|
385
|
-
```
|
|
386
|
-
</Accordion>
|
|
387
|
-
|
|
388
|
-
<Accordion title="Form Submissions">
|
|
389
|
-
```javascript
|
|
390
|
-
// Traditional - flaky
|
|
391
|
-
await page.fill('input[name="email"]', 'user@example.com');
|
|
392
|
-
await page.click('button[type="submit"]');
|
|
393
|
-
await page.waitForNavigation();
|
|
394
|
-
await page.waitForTimeout(500);
|
|
395
|
-
|
|
396
|
-
// TestDriver - stable
|
|
397
|
-
await testdriver.find('email input').type('user@example.com');
|
|
398
|
-
await testdriver.find('submit button').click();
|
|
399
|
-
await testdriver.assert('success message is visible');
|
|
400
|
-
```
|
|
401
|
-
</Accordion>
|
|
402
|
-
</AccordionGroup>
|
|
403
|
-
|
|
404
|
-
## Best Practices
|
|
405
|
-
|
|
406
|
-
<Card title="Let TestDriver Handle Timing" icon="clock">
|
|
407
|
-
Don't:
|
|
408
|
-
```javascript
|
|
409
|
-
await testdriver.find('button').click();
|
|
410
|
-
await new Promise(resolve => setTimeout(resolve, 1000)); // ❌
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
Do:
|
|
414
|
-
```javascript
|
|
415
|
-
await testdriver.find('button').click();
|
|
416
|
-
await testdriver.find('next element').click(); // ✅
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
Trust TestDriver's automatic stability detection.
|
|
420
|
-
</Card>
|
|
421
|
-
|
|
422
|
-
<Card title="Use Natural Assertions" icon="check">
|
|
423
|
-
Don't:
|
|
424
|
-
```javascript
|
|
425
|
-
await testdriver.find('button').click();
|
|
426
|
-
const element = await testdriver.find('result');
|
|
427
|
-
expect(element).toBeTruthy(); // ❌ Redundant
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
Do:
|
|
431
|
-
```javascript
|
|
432
|
-
await testdriver.find('button').click();
|
|
433
|
-
await testdriver.assert('result is visible'); // ✅ Natural
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
TestDriver's assert automatically waits for stability.
|
|
437
|
-
</Card>
|
|
438
|
-
|
|
439
|
-
## Learn More
|
|
440
|
-
|
|
441
|
-
<CardGroup cols={2}>
|
|
442
|
-
<Card
|
|
443
|
-
title="Redraw Implementation"
|
|
444
|
-
icon="code"
|
|
445
|
-
href="/agent/lib/redraw.js"
|
|
446
|
-
>
|
|
447
|
-
View the redraw detection source code
|
|
448
|
-
</Card>
|
|
449
|
-
|
|
450
|
-
<Card
|
|
451
|
-
title="Error Handling Guide"
|
|
452
|
-
icon="triangle-exclamation"
|
|
453
|
-
href="/v7/guides/error-handling"
|
|
454
|
-
>
|
|
455
|
-
Learn about error handling patterns
|
|
456
|
-
</Card>
|
|
457
|
-
|
|
458
|
-
<Card
|
|
459
|
-
title="Best Practices"
|
|
460
|
-
icon="star"
|
|
461
|
-
href="/v7/guides/best-practices"
|
|
462
|
-
>
|
|
463
|
-
Testing best practices with TestDriver
|
|
464
|
-
</Card>
|
|
465
|
-
|
|
466
|
-
<Card
|
|
467
|
-
title="Debugging Guide"
|
|
468
|
-
icon="bug"
|
|
469
|
-
href="/v7/guides/debugging"
|
|
470
|
-
>
|
|
471
|
-
Debug failing tests effectively
|
|
472
|
-
</Card>
|
|
473
|
-
</CardGroup>
|