testdriverai 7.4.0 → 7.4.2

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.
@@ -33,8 +33,8 @@ const element = await testdriver.find(description, options)
33
33
  Similarity threshold (0-1) for cache matching. Lower values require more similarity. Set to -1 to disable cache.
34
34
  </ParamField>
35
35
 
36
- <ParamField path="timeout" type="number">
37
- Maximum time in milliseconds to poll for the element. Retries every 5 seconds until found or timeout expires.
36
+ <ParamField path="timeout" type="number" default={10000}>
37
+ Maximum time in milliseconds to poll for the element. Retries every 5 seconds until found or timeout expires. Defaults to `10000` (10 seconds). Set to `0` to disable polling and make a single attempt.
38
38
  </ParamField>
39
39
 
40
40
  <ParamField path="confidence" type="number">
@@ -309,19 +309,28 @@ const el = await testdriver.find('the blue submit button', { type: 'any' });
309
309
  </Tip>
310
310
  ## Polling for Dynamic Elements
311
311
 
312
- For elements that may not be immediately visible, use the `timeout` option to automatically poll:
312
+ By default, `find()` polls for up to 10 seconds (retrying every 5 seconds) until the element is found. You can customize this with the `timeout` option:
313
313
 
314
314
  ```javascript
315
- // Poll for element (retries every 5 seconds until found or timeout)
315
+ // Uses default 10s timeout - polls every 5 seconds
316
+ const element = await testdriver.find('login button');
317
+ await element.click();
318
+
319
+ // Custom timeout - wait up to 30 seconds
316
320
  const element = await testdriver.find('login button', { timeout: 30000 });
317
321
  await element.click();
322
+
323
+ // Disable polling - single attempt only
324
+ const element = await testdriver.find('login button', { timeout: 0 });
318
325
  ```
319
326
 
320
327
  The `timeout` option:
328
+ - Defaults to `10000` (10 seconds)
321
329
  - Retries finding the element every 5 seconds
322
330
  - Stops when the element is found or the timeout expires
323
331
  - Logs progress during polling
324
332
  - Returns the element (check `element.found()` if not throwing on failure)
333
+ - Set to `0` to disable polling and make a single attempt
325
334
 
326
335
  ## Zoom Mode for Crowded UIs
327
336
 
@@ -6,10 +6,16 @@ description: Handle async operations and prevent flaky tests
6
6
 
7
7
  ## Waiting for Elements
8
8
 
9
- Use the `timeout` option with `find()` to wait for elements that appear after async operations:
9
+ By default, `find()` automatically polls for up to 10 seconds, retrying every 5 seconds until the element is found. This means most elements that appear after short async operations will be found without any extra configuration.
10
+
11
+ For longer operations, increase the `timeout`:
10
12
 
11
13
  ```javascript
12
- // Wait up to 30 seconds for element to appear (polls every 5 seconds)
14
+ // Default behavior - polls for up to 10 seconds automatically
15
+ const element = await testdriver.find('Loading complete indicator');
16
+ await element.click();
17
+
18
+ // Wait up to 30 seconds for slower operations
13
19
  const element = await testdriver.find('Loading complete indicator', { timeout: 30000 });
14
20
  await element.click();
15
21
 
@@ -17,8 +23,8 @@ await element.click();
17
23
  await testdriver.find('submit button').click();
18
24
  await testdriver.find('success message', { timeout: 15000 });
19
25
 
20
- // Short timeout for quick checks
21
- const toast = await testdriver.find('notification toast', { timeout: 5000 });
26
+ // Disable polling for instant checks
27
+ const toast = await testdriver.find('notification toast', { timeout: 0 });
22
28
  ```
23
29
 
24
30
  ## Flake Prevention
package/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [7.3.44](https://github.com/testdriverai/testdriverai/compare/v7.3.43...v7.3.44) (2026-02-26)
2
+
3
+
4
+
1
5
  ## [7.3.43](https://github.com/testdriverai/testdriverai/compare/v7.3.42...v7.3.43) (2026-02-25)
2
6
 
3
7
 
@@ -24,7 +24,7 @@ const testdriver = new TestDriver(apiKey, options)
24
24
  Configuration options for the client
25
25
 
26
26
  <Expandable title="properties">
27
- <ParamField path="os" type="string" default="windows">
27
+ <ParamField path="os" type="string" default="linux">
28
28
  Operating system for the sandbox: `'windows'` or `'linux'`
29
29
  </ParamField>
30
30
 
@@ -32,7 +32,7 @@ const testdriver = new TestDriver(apiKey, options)
32
32
  Screen resolution for the sandbox (e.g., `'1920x1080'`, `'1366x768'`)
33
33
  </ParamField>
34
34
 
35
- <ParamField path="apiRoot" type="string" default="https://testdriver-api.onrender.com">
35
+ <ParamField path="apiRoot" type="string">
36
36
  API endpoint URL (typically only changed for self-hosted deployments)
37
37
  </ParamField>
38
38
 
@@ -48,6 +48,111 @@ const testdriver = new TestDriver(apiKey, options)
48
48
  Automatically capture screenshots before and after each command. Screenshots are saved to `.testdriver/screenshots/<test>/` with descriptive filenames that include the line number and action name. Format: `<seq>-<action>-<phase>-L<line>-<description>.png`
49
49
  </ParamField>
50
50
 
51
+ <ParamField path="newSandbox" type="boolean" default="true">
52
+ Force creation of a new sandbox instead of reusing an existing one
53
+ </ParamField>
54
+
55
+ <ParamField path="reconnect" type="boolean" default="false">
56
+ Reconnect to the last used sandbox instead of creating a new one. When `true`, provision methods (`chrome`, `vscode`, `installer`, etc.) will be skipped since the application is already running. Throws error if no previous sandbox exists.
57
+ </ParamField>
58
+
59
+ <ParamField path="keepAlive" type="number" default="60000">
60
+ Keep sandbox alive for the specified number of milliseconds after disconnect. Set to `0` to terminate immediately on disconnect. Useful for debugging or reconnecting to the same sandbox.
61
+ </ParamField>
62
+
63
+ <ParamField path="preview" type="string" default="browser">
64
+ Preview mode for live test visualization:
65
+ - `"browser"` — Opens debugger in default browser (default)
66
+ - `"ide"` — Opens preview in IDE panel (VSCode, Cursor - requires TestDriver extension)
67
+ - `"none"` — Headless mode, no visual preview
68
+ </ParamField>
69
+
70
+ <ParamField path="headless" type="boolean" default="false">
71
+ **Deprecated**: Use `preview: "none"` instead. Run in headless mode without opening the debugger.
72
+ </ParamField>
73
+
74
+ <ParamField path="debugOnFailure" type="boolean" default="false">
75
+ Keep the sandbox alive when a test fails so you can reconnect and debug interactively. The sandbox ID is printed to the console.
76
+ </ParamField>
77
+
78
+ <ParamField path="ip" type="string">
79
+ Direct IP address to connect to a running sandbox instance (for self-hosted deployments)
80
+ </ParamField>
81
+
82
+ <ParamField path="sandboxAmi" type="string">
83
+ Custom AMI ID for the sandbox instance (AWS deployments, e.g., `'ami-1234'`)
84
+ </ParamField>
85
+
86
+ <ParamField path="sandboxInstance" type="string">
87
+ EC2 instance type for the sandbox (AWS deployments, e.g., `'i3.metal'`)
88
+ </ParamField>
89
+
90
+ <ParamField path="cache" type="boolean | object" default="true">
91
+ Enable or disable element caching, or provide advanced threshold configuration.
92
+
93
+ <Expandable title="advanced config">
94
+ <ParamField path="enabled" type="boolean" default="true">
95
+ Enable or disable caching
96
+ </ParamField>
97
+
98
+ <ParamField path="thresholds" type="object">
99
+ Fine-tune cache matching
100
+
101
+ <Expandable title="properties">
102
+ <ParamField path="find" type="object">
103
+ Thresholds for `find()` operations
104
+
105
+ <Expandable title="properties">
106
+ <ParamField path="screen" type="number" default="0.05">
107
+ Pixel diff threshold for screen comparison (0-1). `0.05` = 5% diff allowed.
108
+ </ParamField>
109
+
110
+ <ParamField path="element" type="number" default="0.8">
111
+ OpenCV template match threshold for element matching (0-1). `0.8` = 80% correlation.
112
+ </ParamField>
113
+ </Expandable>
114
+ </ParamField>
115
+
116
+ <ParamField path="assert" type="number" default="0.05">
117
+ Pixel diff threshold for `assert()` operations (0-1). `0.05` = 5% diff allowed.
118
+ </ParamField>
119
+ </Expandable>
120
+ </ParamField>
121
+ </Expandable>
122
+ </ParamField>
123
+
124
+ <ParamField path="cacheKey" type="string">
125
+ Cache key for element finding operations. If provided, enables caching tied to this key.
126
+ </ParamField>
127
+
128
+ <ParamField path="dashcam" type="boolean" default="true">
129
+ Enable or disable Dashcam video recording
130
+ </ParamField>
131
+
132
+ <ParamField path="redraw" type="boolean | object" default="true">
133
+ Enable or disable screen-change (redraw) detection, or provide advanced configuration.
134
+
135
+ <Expandable title="advanced config">
136
+ <ParamField path="enabled" type="boolean" default="true">
137
+ Enable or disable redraw detection
138
+ </ParamField>
139
+
140
+ <ParamField path="thresholds" type="object">
141
+ Threshold configuration
142
+
143
+ <Expandable title="properties">
144
+ <ParamField path="screen" type="number | false" default="0.05">
145
+ Pixel diff threshold (0-1). Set to `false` to disable screen redraw detection.
146
+ </ParamField>
147
+
148
+ <ParamField path="network" type="boolean" default="false">
149
+ Enable or disable network activity monitoring
150
+ </ParamField>
151
+ </Expandable>
152
+ </ParamField>
153
+ </Expandable>
154
+ </ParamField>
155
+
51
156
  <ParamField path="environment" type="object">
52
157
  Additional environment variables to pass to the sandbox
53
158
  </ParamField>
@@ -10,7 +10,64 @@ Configure TestDriver behavior with options passed to the `TestDriver()` function
10
10
 
11
11
  ```javascript
12
12
  const testdriver = TestDriver(context, {
13
- reconnect: false,
13
+ // === Sandbox & Connection ===
14
+ newSandbox: true, // Force creation of a new sandbox (default: true)
15
+ reconnect: false, // Reconnect to last sandbox (default: false)
16
+ keepAlive: 60000, // Keep sandbox alive after disconnect in ms (default: 60000)
17
+ os: "linux", // 'linux' | 'windows' (default: 'linux')
18
+ resolution: "1366x768", // Sandbox resolution (e.g., '1920x1080')
19
+ ip: "203.0.113.42", // Direct IP for self-hosted sandbox
20
+ sandboxAmi: "ami-1234", // Custom AMI ID (AWS deployments)
21
+ sandboxInstance: "i3.metal", // EC2 instance type (AWS deployments)
22
+
23
+ // === Preview & Debugging ===
24
+ preview: "browser", // "browser" | "ide" | "none" (default: "browser")
25
+ headless: false, // @deprecated - use preview: "none" instead
26
+ debugOnFailure: false, // Keep sandbox alive on test failure for debugging
27
+
28
+ // === Caching ===
29
+ cache: true, // Enable element caching (default: true)
30
+ // Or use advanced caching config:
31
+ // cache: {
32
+ // enabled: true,
33
+ // thresholds: {
34
+ // find: { screen: 0.05, element: 0.8 },
35
+ // assert: 0.05
36
+ // }
37
+ // },
38
+ cacheKey: "my-test", // Cache key for element finding operations
39
+
40
+ // === Recording & Screenshots ===
41
+ dashcam: true, // Enable/disable Dashcam video recording (default: true)
42
+ autoScreenshots: true, // Capture screenshots before/after each command (default: true)
43
+
44
+ // === AI Configuration ===
45
+ ai: { // Global AI sampling configuration
46
+ temperature: 0, // 0 = deterministic, higher = more creative
47
+ top: {
48
+ p: 0.9, // Top-P nucleus sampling (0-1)
49
+ k: 40, // Top-K sampling (1 = most likely, 0 = disabled)
50
+ },
51
+ },
52
+
53
+ // === Screen Change Detection ===
54
+ redraw: true, // Enable redraw detection (default: true)
55
+ // Or use advanced redraw config:
56
+ // redraw: {
57
+ // enabled: true,
58
+ // thresholds: {
59
+ // screen: 0.05, // Pixel diff threshold (0-1), false to disable
60
+ // network: false, // Monitor network activity (default: false)
61
+ // }
62
+ // },
63
+
64
+ // === Logging & Analytics ===
65
+ logging: true, // Enable console logging output (default: true)
66
+ analytics: true, // Enable analytics tracking (default: true)
67
+
68
+ // === Advanced ===
69
+ apiRoot: "https://...", // API endpoint URL (for self-hosted deployments)
70
+ environment: {}, // Additional environment variables for the sandbox
14
71
  });
15
72
  ```
16
73
 
@@ -54,6 +111,16 @@ const testdriver = TestDriver(context, {
54
111
  The legacy `headless: true` option still works for backward compatibility and maps to `preview: "none"`.
55
112
  </Note>
56
113
 
114
+ ### Debug on Failure
115
+
116
+ Keep the sandbox alive when a test fails so you can reconnect and debug interactively. The sandbox ID is printed to the console along with instructions for reconnecting via MCP.
117
+
118
+ ```javascript
119
+ const testdriver = TestDriver(context, {
120
+ debugOnFailure: true,
121
+ });
122
+ ```
123
+
57
124
  ### IP Target
58
125
 
59
126
  If self-hosting TestDriver, use `ip` to specify the device IP. See [Self-Hosting TestDriver](../self-hosting.md) for details.
@@ -105,11 +172,102 @@ steps:
105
172
  - run: TD_OS=${{ matrix.os }} vitest run
106
173
  ```
107
174
 
108
- ## Keepalive
175
+ ### Dashcam Recording
176
+
177
+ Dashcam video recording is enabled by default. Disable it to skip recording:
178
+
179
+ ```javascript
180
+ const testdriver = TestDriver(context, {
181
+ dashcam: false,
182
+ });
183
+ ```
184
+
185
+ ### Automatic Screenshots
186
+
187
+ Screenshots are automatically captured before and after every command (click, type, find, assert, etc.) by default. Each screenshot filename includes the line number from your test file.
188
+
189
+ Disable automatic screenshots:
190
+
191
+ ```javascript
192
+ const testdriver = TestDriver(context, {
193
+ autoScreenshots: false,
194
+ });
195
+ ```
196
+
197
+ ### Caching
198
+
199
+ Element caching speeds up repeated `find()` and `assert()` calls. Enabled by default.
200
+
201
+ ```javascript
202
+ // Disable caching
203
+ const testdriver = TestDriver(context, {
204
+ cache: false,
205
+ });
206
+
207
+ // Advanced: custom thresholds
208
+ const testdriver = TestDriver(context, {
209
+ cache: {
210
+ enabled: true,
211
+ thresholds: {
212
+ find: { screen: 0.05, element: 0.8 },
213
+ assert: 0.05,
214
+ },
215
+ },
216
+ cacheKey: "my-test",
217
+ });
218
+ ```
109
219
 
110
- By default, sandboxes terminate immediately when the test finishes. Set this value to keep the sandbox alive for reconnection.
220
+ ### Redraw Detection
111
221
 
112
- The `keepAlive` param enables you to keep the sandbox running after the test completes for debugging or reconnection. This will allow you to use the debugger to inspect the state of the device after the test has finished.
222
+ Redraw detection waits for the screen to stabilize before taking actions. Enabled by default.
223
+
224
+ ```javascript
225
+ // Disable redraw detection
226
+ const testdriver = TestDriver(context, {
227
+ redraw: false,
228
+ });
229
+
230
+ // Advanced: custom thresholds with network monitoring
231
+ const testdriver = TestDriver(context, {
232
+ redraw: {
233
+ enabled: true,
234
+ thresholds: {
235
+ screen: 0.05,
236
+ network: true,
237
+ },
238
+ },
239
+ });
240
+ ```
241
+
242
+ ### AI Configuration
243
+
244
+ Control how the AI model generates responses for `find()` verification and `assert()` calls:
245
+
246
+ ```javascript
247
+ const testdriver = TestDriver(context, {
248
+ ai: {
249
+ temperature: 0, // 0 = deterministic
250
+ top: { p: 0.9, k: 40 },
251
+ },
252
+ });
253
+ ```
254
+
255
+ ### Environment Variables
256
+
257
+ Pass additional environment variables to the sandbox:
258
+
259
+ ```javascript
260
+ const testdriver = TestDriver(context, {
261
+ environment: {
262
+ MY_VAR: "value",
263
+ DEBUG: "true",
264
+ },
265
+ });
266
+ ```
267
+
268
+ ## Keepalive
269
+
270
+ By default, sandboxes stay alive for 60 seconds after disconnect. Customize this with `keepAlive`:
113
271
 
114
272
  ```javascript
115
273
  const testdriver = TestDriver(context, {
@@ -117,6 +275,14 @@ const testdriver = TestDriver(context, {
117
275
  });
118
276
  ```
119
277
 
278
+ Set to `0` to terminate immediately:
279
+
280
+ ```javascript
281
+ const testdriver = TestDriver(context, {
282
+ keepAlive: 0, // Terminate sandbox immediately on disconnect
283
+ });
284
+ ```
285
+
120
286
  ### Reconnecting to Existing Sandbox
121
287
 
122
288
  Speed up test development by reconnecting to an existing sandbox instead of starting fresh each time. This lets you iterate quickly on failing steps without re-running the entire test from the beginning.
@@ -33,8 +33,8 @@ const element = await testdriver.find(description, options)
33
33
  Similarity threshold (0-1) for cache matching. Lower values require more similarity. Set to -1 to disable cache.
34
34
  </ParamField>
35
35
 
36
- <ParamField path="timeout" type="number">
37
- Maximum time in milliseconds to poll for the element. Retries every 5 seconds until found or timeout expires.
36
+ <ParamField path="timeout" type="number" default={10000}>
37
+ Maximum time in milliseconds to poll for the element. Retries every 5 seconds until found or timeout expires. Defaults to `10000` (10 seconds). Set to `0` to disable polling and make a single attempt.
38
38
  </ParamField>
39
39
 
40
40
  <ParamField path="confidence" type="number">
@@ -309,19 +309,28 @@ const el = await testdriver.find('the blue submit button', { type: 'any' });
309
309
  </Tip>
310
310
  ## Polling for Dynamic Elements
311
311
 
312
- For elements that may not be immediately visible, use the `timeout` option to automatically poll:
312
+ By default, `find()` polls for up to 10 seconds (retrying every 5 seconds) until the element is found. You can customize this with the `timeout` option:
313
313
 
314
314
  ```javascript
315
- // Poll for element (retries every 5 seconds until found or timeout)
315
+ // Uses default 10s timeout - polls every 5 seconds
316
+ const element = await testdriver.find('login button');
317
+ await element.click();
318
+
319
+ // Custom timeout - wait up to 30 seconds
316
320
  const element = await testdriver.find('login button', { timeout: 30000 });
317
321
  await element.click();
322
+
323
+ // Disable polling - single attempt only
324
+ const element = await testdriver.find('login button', { timeout: 0 });
318
325
  ```
319
326
 
320
327
  The `timeout` option:
328
+ - Defaults to `10000` (10 seconds)
321
329
  - Retries finding the element every 5 seconds
322
330
  - Stops when the element is found or the timeout expires
323
331
  - Logs progress during polling
324
332
  - Returns the element (check `element.found()` if not throwing on failure)
333
+ - Set to `0` to disable polling and make a single attempt
325
334
 
326
335
  ## Zoom Mode for Crowded UIs
327
336
 
@@ -6,10 +6,16 @@ description: Handle async operations and prevent flaky tests
6
6
 
7
7
  ## Waiting for Elements
8
8
 
9
- Use the `timeout` option with `find()` to wait for elements that appear after async operations:
9
+ By default, `find()` automatically polls for up to 10 seconds, retrying every 5 seconds until the element is found. This means most elements that appear after short async operations will be found without any extra configuration.
10
+
11
+ For longer operations, increase the `timeout`:
10
12
 
11
13
  ```javascript
12
- // Wait up to 30 seconds for element to appear (polls every 5 seconds)
14
+ // Default behavior - polls for up to 10 seconds automatically
15
+ const element = await testdriver.find('Loading complete indicator');
16
+ await element.click();
17
+
18
+ // Wait up to 30 seconds for slower operations
13
19
  const element = await testdriver.find('Loading complete indicator', { timeout: 30000 });
14
20
  await element.click();
15
21
 
@@ -17,8 +23,8 @@ await element.click();
17
23
  await testdriver.find('submit button').click();
18
24
  await testdriver.find('success message', { timeout: 15000 });
19
25
 
20
- // Short timeout for quick checks
21
- const toast = await testdriver.find('notification toast', { timeout: 5000 });
26
+ // Disable polling for instant checks
27
+ const toast = await testdriver.find('notification toast', { timeout: 0 });
22
28
  ```
23
29
 
24
30
  ## Flake Prevention
package/docs/v7/find.mdx CHANGED
@@ -34,8 +34,8 @@ const element = await testdriver.find(description, options)
34
34
  Similarity threshold (0-1) for cache matching. Lower values require more similarity. Set to -1 to disable cache.
35
35
  </ParamField>
36
36
 
37
- <ParamField path="timeout" type="number">
38
- Maximum time in milliseconds to poll for the element. Retries every 5 seconds until found or timeout expires.
37
+ <ParamField path="timeout" type="number" default={10000}>
38
+ Maximum time in milliseconds to poll for the element. Retries every 5 seconds until found or timeout expires. Defaults to `10000` (10 seconds). Set to `0` to disable polling and make a single attempt.
39
39
  </ParamField>
40
40
 
41
41
  <ParamField path="confidence" type="number">
@@ -310,19 +310,28 @@ const el = await testdriver.find('the blue submit button', { type: 'any' });
310
310
  </Tip>
311
311
  ## Polling for Dynamic Elements
312
312
 
313
- For elements that may not be immediately visible, use the `timeout` option to automatically poll:
313
+ By default, `find()` polls for up to 10 seconds (retrying every 5 seconds) until the element is found. You can customize this with the `timeout` option:
314
314
 
315
315
  ```javascript
316
- // Poll for element (retries every 5 seconds until found or timeout)
316
+ // Uses default 10s timeout - polls every 5 seconds
317
+ const element = await testdriver.find('login button');
318
+ await element.click();
319
+
320
+ // Custom timeout - wait up to 30 seconds
317
321
  const element = await testdriver.find('login button', { timeout: 30000 });
318
322
  await element.click();
323
+
324
+ // Disable polling - single attempt only
325
+ const element = await testdriver.find('login button', { timeout: 0 });
319
326
  ```
320
327
 
321
328
  The `timeout` option:
329
+ - Defaults to `10000` (10 seconds)
322
330
  - Retries finding the element every 5 seconds
323
331
  - Stops when the element is found or the timeout expires
324
332
  - Logs progress during polling
325
333
  - Returns the element (check `element.found()` if not throwing on failure)
334
+ - Set to `0` to disable polling and make a single attempt
326
335
 
327
336
  ## Zoom Mode for Crowded UIs
328
337
 
@@ -6,10 +6,16 @@ icon: "clock"
6
6
 
7
7
  ## Waiting for Elements
8
8
 
9
- Use the `timeout` option with `find()` to wait for elements that appear after async operations:
9
+ By default, `find()` automatically polls for up to 10 seconds, retrying every 5 seconds until the element is found. This means most elements that appear after short async operations will be found without any extra configuration.
10
+
11
+ For longer operations, increase the `timeout`:
10
12
 
11
13
  ```javascript
12
- // Wait up to 30 seconds for element to appear (polls every 5 seconds)
14
+ // Default behavior - polls for up to 10 seconds automatically
15
+ const element = await testdriver.find('Loading complete indicator');
16
+ await element.click();
17
+
18
+ // Wait up to 30 seconds for slower operations
13
19
  const element = await testdriver.find('Loading complete indicator', { timeout: 30000 });
14
20
  await element.click();
15
21
 
@@ -17,8 +23,8 @@ await element.click();
17
23
  await testdriver.find('submit button').click();
18
24
  await testdriver.find('success message', { timeout: 15000 });
19
25
 
20
- // Short timeout for quick checks
21
- const toast = await testdriver.find('notification toast', { timeout: 5000 });
26
+ // Disable polling for instant checks
27
+ const toast = await testdriver.find('notification toast', { timeout: 0 });
22
28
  ```
23
29
 
24
30
  ## Flake Prevention
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.4.0",
3
+ "version": "7.4.2",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "sdk.js",
6
6
  "types": "sdk.d.ts",
package/sdk.js CHANGED
@@ -436,8 +436,10 @@ class Element {
436
436
  * @returns {Promise<Element>} This element instance
437
437
  */
438
438
  async find(newDescription, options) {
439
- // Handle timeout/polling option
440
- const timeout = typeof options === "object" ? options?.timeout : null;
439
+ // Handle timeout/polling option (default: 30s)
440
+ const timeout = typeof options === "object" && options?.timeout !== undefined
441
+ ? options.timeout
442
+ : 10000;
441
443
  if (timeout && timeout > 0) {
442
444
  return this._findWithTimeout(newDescription, options, timeout);
443
445
  }
@@ -666,7 +668,7 @@ class Element {
666
668
 
667
669
  // Create options without timeout to avoid infinite recursion
668
670
  const findOptions = typeof options === "object" ? { ...options } : {};
669
- delete findOptions.timeout;
671
+ findOptions.timeout = 0;
670
672
 
671
673
  let attempts = 0;
672
674
  while (Date.now() - startTime < timeout) {
@@ -1729,6 +1731,8 @@ class TestDriverSDK {
1729
1731
  */
1730
1732
  async _waitForChromeDebuggerReady(timeoutMs = 60000) {
1731
1733
  const shell = this.os === "windows" ? "pwsh" : "sh";
1734
+ // PowerShell: Use async connect with 2-second timeout to match Linux curl behavior.
1735
+ // TcpClient.Connect() is synchronous and can hang indefinitely, causing exec timeouts.
1732
1736
  const portCheckCmd = this.os === "windows"
1733
1737
  ? `$tcp = New-Object System.Net.Sockets.TcpClient; $tcp.Connect('127.0.0.1', 9222); $tcp.Close(); echo 'open'`
1734
1738
  : `curl -s -o /dev/null --connect-timeout 2 http://localhost:9222 2>/dev/null && echo 'open' || echo 'closed'`;
@@ -1895,7 +1899,7 @@ class TestDriverSDK {
1895
1899
  // Add web log tracking with domain wildcard pattern, then start dashcam
1896
1900
  if (this.dashcamEnabled) {
1897
1901
  const domainPattern = this._getUrlDomainPattern(url);
1898
- // await this.dashcam.addWebLog(domainPattern, "Web Logs");
1902
+ await this.dashcam.addWebLog(domainPattern, "Web Logs");
1899
1903
 
1900
1904
  // Start dashcam recording after logs are configured
1901
1905
  if (!(await this.dashcam.isRecording())) {
@@ -2462,7 +2466,7 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
2462
2466
  const pattern = this._provisionedChromeUrl
2463
2467
  ? this._getUrlDomainPattern(this._provisionedChromeUrl)
2464
2468
  : "**";
2465
- // await this.dashcam.addWebLog(pattern, "Web Logs");
2469
+ await this.dashcam.addWebLog(pattern, "Web Logs");
2466
2470
  }
2467
2471
 
2468
2472
  // Start recording if not already recording