testdriverai 7.2.86 → 7.2.88

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.
@@ -21,7 +21,8 @@ const createRedraw = (
21
21
  // Merge default options with provided defaults
22
22
  const baseOptions = { ...DEFAULT_REDRAW_OPTIONS, ...defaultOptions };
23
23
 
24
- const networkUpdateInterval = 15000;
24
+ // Network check interval (ms) - used for speed calculation display
25
+ const networkCheckInterval = 250;
25
26
 
26
27
  let lastTxBytes = null;
27
28
  let lastRxBytes = null;
@@ -125,15 +126,32 @@ const createRedraw = (
125
126
  }
126
127
  };
127
128
 
129
+ // Track if a network request is in flight to prevent overlapping requests
130
+ let networkRequestInFlight = false;
131
+
128
132
  async function updateNetwork() {
133
+ // Prevent overlapping requests - if one is already in flight, skip this cycle
134
+ if (networkRequestInFlight) {
135
+ emitter.emit(events.log.debug, '[redraw] updateNetwork() - skipping, request already in flight');
136
+ return;
137
+ }
138
+
129
139
  if (sandbox && sandbox.instanceSocketConnected) {
130
- let network = await sandbox.send({
131
- type: "system.network",
132
- });
133
- parseNetworkStats(
134
- network.out.totalBytesReceived,
135
- network.out.totalBytesSent,
136
- );
140
+ networkRequestInFlight = true;
141
+ try {
142
+ let network = await sandbox.send({
143
+ type: "system.network",
144
+ }, 10000); // Use a shorter 10 second timeout for network stats
145
+ parseNetworkStats(
146
+ network.out.totalBytesReceived,
147
+ network.out.totalBytesSent,
148
+ );
149
+ } catch (error) {
150
+ // Log the error but don't throw - network monitoring is non-critical
151
+ emitter.emit(events.log.debug, `[redraw] updateNetwork() failed: ${error.message}`);
152
+ } finally {
153
+ networkRequestInFlight = false;
154
+ }
137
155
  }
138
156
  }
139
157
 
@@ -181,14 +199,7 @@ const createRedraw = (
181
199
  }
182
200
  }
183
201
 
184
- // Start network monitoring only when needed
185
- function startNetworkMonitoring() {
186
- if (!networkInterval) {
187
- networkInterval = setInterval(updateNetwork, networkUpdateInterval);
188
- }
189
- }
190
-
191
- // Stop network monitoring
202
+ // Stop network monitoring (cleanup any residual interval)
192
203
  function stopNetworkMonitoring() {
193
204
  if (networkInterval) {
194
205
  clearInterval(networkInterval);
@@ -220,11 +231,6 @@ const createRedraw = (
220
231
 
221
232
  resetState();
222
233
 
223
- // Only start network monitoring if enabled
224
- if (currentOptions.networkMonitor) {
225
- startNetworkMonitoring();
226
- }
227
-
228
234
  // Capture initial image for screen stability monitoring
229
235
  if (currentOptions.screenRedraw) {
230
236
  initialScreenImage = await system.captureScreenPNG(0.25, true);
@@ -244,6 +250,11 @@ const createRedraw = (
244
250
  return;
245
251
  }
246
252
 
253
+ // Update network stats on each check (with guard against overlapping requests)
254
+ if (networkMonitor) {
255
+ await updateNetwork();
256
+ }
257
+
247
258
  let nowImage = screenRedraw ? await system.captureScreenPNG(0.25, true) : null;
248
259
  let timeElapsed = Date.now() - startTime;
249
260
  let diffFromInitial = 0;
@@ -305,7 +316,7 @@ const createRedraw = (
305
316
  : effectiveNetworkSettled
306
317
  ? theme.green(`y`)
307
318
  : theme.dim(
308
- `${Math.trunc((diffRxBytes + diffTxBytes) / networkUpdateInterval)}b/s`,
319
+ `${Math.trunc((diffRxBytes + diffTxBytes) / (networkCheckInterval / 1000))}b/s`,
309
320
  );
310
321
  let timeoutText = isTimeout
311
322
  ? theme.green(`y`)
@@ -370,10 +381,6 @@ const createRedraw = (
370
381
 
371
382
  return new Promise((resolve) => {
372
383
  const startTime = Date.now();
373
- // Start network monitoring if not already started and enabled
374
- if (waitOptions.networkMonitor) {
375
- startNetworkMonitoring();
376
- }
377
384
  checkCondition(resolve, startTime, timeoutMs, waitOptions);
378
385
  });
379
386
  }
@@ -44,7 +44,8 @@ Use this agent when the user asks to:
44
44
  4. **⚠️ WRITE CODE IMMEDIATELY**: After EVERY successful action, append the generated code to the test file RIGHT AWAY. Do NOT wait until the end.
45
45
  5. **Verify Actions**: Use `check` after actions to verify they succeeded (for YOUR understanding only).
46
46
  6. **Add Assertions**: Use `assert` for test conditions that should be in the final test file.
47
- 7. **⚠️ RUN THE TEST YOURSELF**: Use `npx vitest run <testFile> --reporter=dot` to run the test - do NOT tell the user to run it. Iterate until it passes.
47
+ 7. **⚠️ RUN THE TEST YOURSELF**: Use `vitest run <testFile> --reporter=dot` to run the test - do NOT tell the user to run it. Iterate until it passes. **NEVER use `npx vitest`** - always use `vitest` directly.
48
+ 8. **⚠️ SHARE THE TEST REPORT**: After EVERY test run, find the `TESTDRIVER_RUN_URL` in the output (e.g., `TESTDRIVER_RUN_URL=https://console.testdriver.ai/runs/...`) and share it with the user so they can view the recording and results.
48
49
 
49
50
  ## Prerequisites
50
51
 
@@ -80,7 +81,7 @@ The `init` command creates:
80
81
 
81
82
  **After running init:**
82
83
  1. User adds their API key to `.env`: `TD_API_KEY=...`
83
- 2. Test the setup: `npx vitest run`
84
+ 2. Test the setup: `vitest run`
84
85
  3. Start building custom tests using the examples as templates
85
86
 
86
87
  ### API Key Setup
@@ -254,7 +255,7 @@ TestDriver **automatically captures screenshots before and after every command**
254
255
 
255
256
  **Every MCP tool response includes "ACTION REQUIRED: Append this code..." - you MUST write that code to the test file IMMEDIATELY before proceeding to the next action.**
256
257
 
257
- **When ready to validate, RUN THE TEST YOURSELF using `npx vitest run`. Do NOT tell the user to run it.**
258
+ **When ready to validate, RUN THE TEST YOURSELF using `vitest run`. Do NOT tell the user to run it. NEVER use `npx vitest`.**
258
259
 
259
260
  ### Step 1: Start a Session
260
261
 
@@ -311,17 +312,17 @@ assert({ assertion: "the dashboard is visible" })
311
312
 
312
313
  ### Step 5: Run the Test Yourself
313
314
 
314
- **⚠️ YOU must run the test - do NOT tell the user to run it:**
315
+ **⚠️ YOU must run the test - do NOT tell the user to run it. NEVER use `npx vitest` - always use `vitest` directly:**
315
316
 
316
317
  ```bash
317
- npx vitest run tests/login.test.mjs --reporter=dot
318
+ vitest run tests/login.test.mjs --reporter=dot
318
319
  ```
319
320
 
320
321
  **Always use `--reporter=dot`** for cleaner, more concise output that's easier to parse.
321
322
 
322
323
  Analyze the output, fix any issues, and iterate until the test passes.
323
324
 
324
- **⚠️ ALWAYS share the test report link with the user.** After each test run, look for the "View Report" URL in the test output (e.g., `https://app.testdriver.ai/projects/.../reports/...`) and share it with the user so they can review the recording and results.
325
+ **⚠️ ALWAYS share the test report link with the user.** After each test run, look for `TESTDRIVER_RUN_URL` in the test output (e.g., `TESTDRIVER_RUN_URL=https://console.testdriver.ai/runs/...`) and share it with the user so they can view the recording and results. This is CRITICAL - users need to see the visual recording to understand test behavior.
325
326
 
326
327
  ### MCP Tools Reference
327
328
 
@@ -456,7 +457,7 @@ list_local_screenshots({ directory: "checkout.test", phase: "before", limit: 10
456
457
  ### Tips for MCP Workflow
457
458
 
458
459
  1. **⚠️ Write code IMMEDIATELY** - After EVERY action, append generated code to test file RIGHT AWAY
459
- 2. **⚠️ Run tests YOURSELF** - Use `npx vitest run` - do NOT tell user to run tests
460
+ 2. **⚠️ Run tests YOURSELF** - Use `vitest run` (NEVER `npx vitest`) - do NOT tell user to run tests
460
461
  3. **⚠️ Add screenshots liberally** - Include `await testdriver.screenshot()` after every significant action for debugging
461
462
  4. **⚠️ Use screenshot viewing for debugging** - When tests fail, use `list_local_screenshots` and `view_local_screenshot` to understand what went wrong
462
463
  5. **Work incrementally** - Don't try to build the entire test at once
@@ -616,7 +617,8 @@ await testdriver.screenshot(1, false, true);
616
617
  ## Tips for Agents
617
618
 
618
619
  1. **⚠️ WRITE CODE IMMEDIATELY** - After EVERY successful MCP action, append the generated code to the test file RIGHT AWAY. Do NOT wait until the session ends.
619
- 2. **⚠️ RUN TESTS YOURSELF** - Do NOT tell the user to run tests. YOU must run the tests using `npx vitest run <testFile> --reporter=dot`. Always use `--reporter=dot` for cleaner output. Analyze the output and iterate until the test passes. **Always share the test report link** (e.g., `https://app.testdriver.ai/projects/.../reports/...`) with the user after each run.
620
+ 2. **⚠️ RUN TESTS YOURSELF** - Do NOT tell the user to run tests. YOU must run the tests using `vitest run <testFile> --reporter=dot` (NEVER use `npx vitest` - it breaks the reporter). Always use `--reporter=dot` for cleaner output. Analyze the output and iterate until the test passes.
621
+ 3. **⚠️ SHARE THE TEST REPORT URL** - After EVERY test run, find `TESTDRIVER_RUN_URL=https://console.testdriver.ai/runs/...` in the output and share it with the user. This is CRITICAL - users need to view the recording to understand what happened.
620
622
  3. **Screenshots are automatic** - TestDriver captures screenshots before/after every command by default. Each screenshot filename includes the line number (e.g., `001-click-before-L42-submit-button.png`) making it easy to trace issues.
621
623
  4. **⚠️ USE SCREENSHOT VIEWING FOR DEBUGGING** - When tests fail, use `list_local_screenshots` and `view_local_screenshot` MCP commands to see exactly what the UI looked like. The filenames tell you which line of code triggered each screenshot.
622
624
  5. **⚠️ NEVER USE `.wait()`** - Do NOT use any `.wait()` method. Instead, use `find()` with a `timeout` option to poll for elements, or use `assert()` / `check()` to verify state. Explicit waits are flaky and slow.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.2.86",
3
+ "version": "7.2.88",
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",