testdriverai 7.2.9 → 7.2.11

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 (124) hide show
  1. package/.github/workflows/testdriver.yml +127 -0
  2. package/.testdriver/last-sandbox +7 -0
  3. package/agent/events.js +1 -0
  4. package/agent/index.js +71 -54
  5. package/agent/lib/sandbox.js +11 -1
  6. package/agents.md +393 -0
  7. package/debug/01-table-initial.png +0 -0
  8. package/debug/02-after-ai-explore.png +0 -0
  9. package/debug/02-after-scroll.png +0 -0
  10. package/docs/docs.json +87 -126
  11. package/docs/v7/_drafts/caching.mdx +2 -2
  12. package/docs/v7/{getting-started → _drafts}/installation.mdx +0 -66
  13. package/docs/v7/{features/coverage.mdx → _drafts/powerful.mdx} +1 -90
  14. package/docs/v7/{features → _drafts}/scalable.mdx +126 -4
  15. package/docs/v7/_drafts/screenshot.mdx +155 -0
  16. package/docs/v7/_drafts/writing-tests.mdx +25 -0
  17. package/docs/v7/{api/act.mdx → ai.mdx} +27 -27
  18. package/docs/v7/{api/assert.mdx → assert.mdx} +3 -3
  19. package/docs/v7/aws-setup.mdx +338 -0
  20. package/docs/v7/caching.mdx +128 -0
  21. package/docs/v7/ci-cd.mdx +605 -0
  22. package/docs/v7/{api/click.mdx → click.mdx} +4 -4
  23. package/docs/v7/cloud.mdx +120 -0
  24. package/docs/v7/customizing-devices.mdx +129 -0
  25. package/docs/v7/{api/dashcam.mdx → dashcam.mdx} +0 -78
  26. package/docs/v7/{api/doubleClick.mdx → double-click.mdx} +5 -5
  27. package/docs/v7/{api/elements.mdx → elements.mdx} +1 -54
  28. package/docs/v7/enterprise.mdx +116 -0
  29. package/docs/v7/examples.mdx +5 -0
  30. package/docs/v7/{api/exec.mdx → exec.mdx} +3 -3
  31. package/docs/v7/{api/find.mdx → find.mdx} +17 -21
  32. package/docs/v7/{api/focusApplication.mdx → focus-application.mdx} +3 -3
  33. package/docs/v7/generating-tests.mdx +36 -0
  34. package/docs/v7/{api/hover.mdx → hover.mdx} +3 -3
  35. package/docs/v7/locating-elements.mdx +71 -0
  36. package/docs/v7/making-assertions.mdx +32 -0
  37. package/docs/v7/{api/mouseDown.mdx → mouse-down.mdx} +7 -7
  38. package/docs/v7/{api/mouseUp.mdx → mouse-up.mdx} +8 -8
  39. package/docs/v7/performing-actions.mdx +51 -0
  40. package/docs/v7/{api/pressKeys.mdx → press-keys.mdx} +3 -3
  41. package/docs/v7/quickstart.mdx +162 -0
  42. package/docs/v7/reusable-code.mdx +240 -0
  43. package/docs/v7/{api/rightClick.mdx → right-click.mdx} +5 -5
  44. package/docs/v7/running-tests.mdx +181 -0
  45. package/docs/v7/{api/scroll.mdx → scroll.mdx} +3 -3
  46. package/docs/v7/secrets.mdx +115 -0
  47. package/docs/v7/self-hosted.mdx +66 -0
  48. package/docs/v7/{api/type.mdx → type.mdx} +3 -3
  49. package/docs/v7/variables.mdx +111 -0
  50. package/docs/v7/waiting-for-elements.mdx +66 -0
  51. package/docs/v7/what-is-testdriver.mdx +54 -0
  52. package/lib/vitest/hooks.mjs +80 -68
  53. package/package.json +1 -1
  54. package/sdk.d.ts +22 -9
  55. package/sdk.js +177 -44
  56. package/test/manual/reconnect-provision.test.mjs +49 -0
  57. package/test/manual/reconnect-signin.test.mjs +41 -0
  58. package/test/testdriver/ai.test.mjs +30 -0
  59. package/test/testdriver/setup/testHelpers.mjs +0 -1
  60. package/test/testdriver/windows-installer.test.mjs +61 -0
  61. package/tests/table-sort-enrollments.test.mjs +72 -0
  62. package/tests/table-sort-experiment.test.mjs +42 -0
  63. package/tests/table-sort-setup.test.mjs +59 -0
  64. package/vitest.config.mjs +1 -0
  65. package/docs/v7/api/assertions.mdx +0 -403
  66. package/docs/v7/api/sandbox.mdx +0 -404
  67. package/docs/v7/features/ai-native.mdx +0 -413
  68. package/docs/v7/features/application-logs.mdx +0 -353
  69. package/docs/v7/features/browser-logs.mdx +0 -414
  70. package/docs/v7/features/cache-management.mdx +0 -402
  71. package/docs/v7/features/continuous-testing.mdx +0 -346
  72. package/docs/v7/features/data-driven-testing.mdx +0 -441
  73. package/docs/v7/features/easy-to-write.mdx +0 -280
  74. package/docs/v7/features/enterprise.mdx +0 -656
  75. package/docs/v7/features/fast.mdx +0 -406
  76. package/docs/v7/features/managed-sandboxes.mdx +0 -384
  77. package/docs/v7/features/network-monitoring.mdx +0 -568
  78. package/docs/v7/features/parallel-execution.mdx +0 -381
  79. package/docs/v7/features/powerful.mdx +0 -531
  80. package/docs/v7/features/sandbox-customization.mdx +0 -229
  81. package/docs/v7/features/stable.mdx +0 -473
  82. package/docs/v7/features/system-performance.mdx +0 -616
  83. package/docs/v7/features/test-analytics.mdx +0 -373
  84. package/docs/v7/features/test-cases.mdx +0 -393
  85. package/docs/v7/features/test-replays.mdx +0 -408
  86. package/docs/v7/features/test-reports.mdx +0 -308
  87. package/docs/v7/getting-started/debugging-tests.mdx +0 -382
  88. package/docs/v7/getting-started/quickstart.mdx +0 -90
  89. package/docs/v7/getting-started/running-tests.mdx +0 -173
  90. package/docs/v7/getting-started/setting-up-in-ci.mdx +0 -612
  91. package/docs/v7/getting-started/writing-tests.mdx +0 -534
  92. package/docs/v7/overview/what-is-testdriver.mdx +0 -386
  93. package/docs/v7/presets/chrome-extension.mdx +0 -248
  94. package/docs/v7/presets/chrome.mdx +0 -300
  95. package/docs/v7/presets/electron.mdx +0 -460
  96. package/docs/v7/presets/vscode.mdx +0 -417
  97. package/docs/v7/presets/webapp.mdx +0 -393
  98. package/vitest.config.js +0 -18
  99. /package/docs/v7/{commands → _drafts/commands}/assert.mdx +0 -0
  100. /package/docs/v7/{commands → _drafts/commands}/exec.mdx +0 -0
  101. /package/docs/v7/{commands → _drafts/commands}/focus-application.mdx +0 -0
  102. /package/docs/v7/{commands → _drafts/commands}/hover-image.mdx +0 -0
  103. /package/docs/v7/{commands → _drafts/commands}/hover-text.mdx +0 -0
  104. /package/docs/v7/{commands → _drafts/commands}/if.mdx +0 -0
  105. /package/docs/v7/{commands → _drafts/commands}/match-image.mdx +0 -0
  106. /package/docs/v7/{commands → _drafts/commands}/press-keys.mdx +0 -0
  107. /package/docs/v7/{commands → _drafts/commands}/remember.mdx +0 -0
  108. /package/docs/v7/{commands → _drafts/commands}/run.mdx +0 -0
  109. /package/docs/v7/{commands → _drafts/commands}/scroll-until-image.mdx +0 -0
  110. /package/docs/v7/{commands → _drafts/commands}/scroll-until-text.mdx +0 -0
  111. /package/docs/v7/{commands → _drafts/commands}/scroll.mdx +0 -0
  112. /package/docs/v7/{commands → _drafts/commands}/type.mdx +0 -0
  113. /package/docs/v7/{commands → _drafts/commands}/wait-for-image.mdx +0 -0
  114. /package/docs/v7/{commands → _drafts/commands}/wait-for-text.mdx +0 -0
  115. /package/docs/v7/{commands → _drafts/commands}/wait.mdx +0 -0
  116. /package/docs/v7/{getting-started → _drafts}/configuration.mdx +0 -0
  117. /package/docs/v7/{features → _drafts}/observable.mdx +0 -0
  118. /package/docs/v7/{platforms → _drafts/platforms}/linux.mdx +0 -0
  119. /package/docs/v7/{platforms → _drafts/platforms}/macos.mdx +0 -0
  120. /package/docs/v7/{platforms → _drafts/platforms}/windows.mdx +0 -0
  121. /package/docs/v7/{playwright.mdx → _drafts/playwright.mdx} +0 -0
  122. /package/docs/v7/{overview → _drafts}/readme.mdx +0 -0
  123. /package/docs/v7/{features → _drafts}/reports.mdx +0 -0
  124. /package/docs/v7/{api/client.mdx → client.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>