testdriverai 7.2.53 → 7.2.55

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.
@@ -13,12 +13,18 @@ const createSystem = (emitter, sandbox, config) => {
13
13
  });
14
14
 
15
15
  if (!base64) {
16
- console.error("Failed to take screenshot");
17
- } else {
18
- let image = Buffer.from(base64, "base64");
19
- fs.writeFileSync(options.filename, image);
20
- return { filename: options.filename };
16
+ throw new Error("Failed to take screenshot: sandbox returned empty data");
21
17
  }
18
+
19
+ let image = Buffer.from(base64, "base64");
20
+
21
+ // Verify we got actual image data (PNG header starts with these bytes)
22
+ if (image.length < 100) {
23
+ throw new Error(`Failed to take screenshot: received only ${image.length} bytes`);
24
+ }
25
+
26
+ fs.writeFileSync(options.filename, image);
27
+ return { filename: options.filename };
22
28
  };
23
29
 
24
30
  let primaryDisplay = null;
@@ -57,6 +63,11 @@ const createSystem = (emitter, sandbox, config) => {
57
63
 
58
64
  // Load the screenshot image with Jimp
59
65
  let image = await Jimp.read(step1);
66
+
67
+ // Validate the image was loaded correctly (not a 1x1 or tiny placeholder)
68
+ if (image.getWidth() < 10 || image.getHeight() < 10) {
69
+ throw new Error(`Screenshot appears corrupted: got ${image.getWidth()}x${image.getHeight()} pixels`);
70
+ }
60
71
 
61
72
  // Resize the image
62
73
  image.resize(
package/agents.md CHANGED
@@ -151,7 +151,7 @@ element.found(); // check if found (boolean)
151
151
  **Use `screenshot()` liberally during development** to see exactly what the sandbox screen looks like. Screenshots are saved locally and organized by test file.
152
152
 
153
153
  ```javascript
154
- // Capture a screenshot - saved to .testdriverai/screenshots/<test-file>/
154
+ // Capture a screenshot - saved to .testdriver/screenshots/<test-file>/
155
155
  const screenshotPath = await testdriver.screenshot();
156
156
  console.log('Screenshot saved to:', screenshotPath);
157
157
 
@@ -168,7 +168,7 @@ await testdriver.screenshot(1, false, true);
168
168
 
169
169
  **Screenshot file organization:**
170
170
  ```
171
- .testdriverai/
171
+ .testdriver/
172
172
  screenshots/
173
173
  login.test/ # Folder per test file
174
174
  screenshot-1737633600000.png
@@ -443,7 +443,7 @@ console.log('Screenshot with mouse saved to: screenshot-with-mouse.png');
443
443
  4. **Log element properties** to understand what the AI sees
444
444
  5. **Use `assert()` with specific, descriptive natural language**
445
445
  6. **Start simple** - get one step working before adding more
446
- 7. **Take screenshots liberally** - use `await testdriver.screenshot()` after key steps to debug what the sandbox actually shows. Check `.testdriverai/screenshots/<test-file>/` to review them.
446
+ 7. **Take screenshots liberally** - use `await testdriver.screenshot()` after key steps to debug what the sandbox actually shows. Check `.testdriver/screenshots/<test-file>/` to review them.
447
447
  8. **Always `await` async methods** - TestDriver will warn if you forget, but for TypeScript projects, add `@typescript-eslint/no-floating-promises` to your ESLint config to catch missing `await` at compile time:
448
448
  ```json
449
449
  // eslint.config.js (for TypeScript projects)
@@ -12,21 +12,13 @@ Capture a screenshot of the current screen and automatically save it to a local
12
12
  ## Syntax
13
13
 
14
14
  ```javascript
15
- const filePath = await testdriver.screenshot(scale, silent, mouse)
15
+ const filePath = await testdriver.screenshot(filename)
16
16
  ```
17
17
 
18
18
  ## Parameters
19
19
 
20
- <ParamField path="scale" type="number" default="1">
21
- Scale factor for the screenshot (1 = original size, 0.5 = half size, 2 = double size)
22
- </ParamField>
23
-
24
- <ParamField path="silent" type="boolean" default="false">
25
- Whether to suppress the log message showing where the screenshot was saved
26
- </ParamField>
27
-
28
- <ParamField path="mouse" type="boolean" default="false">
29
- Whether to include the mouse cursor in the screenshot
20
+ <ParamField path="filename" type="string" optional>
21
+ Custom filename for the screenshot (without .png extension). If not provided, a timestamp-based filename is generated automatically.
30
22
  </ParamField>
31
23
 
32
24
  ## Returns
@@ -35,14 +27,14 @@ const filePath = await testdriver.screenshot(scale, silent, mouse)
35
27
 
36
28
  ## File Organization
37
29
 
38
- Screenshots are automatically saved to `.testdriverai/screenshots/<test-file-name>/` in your project root:
30
+ Screenshots are automatically saved to `.testdriver/screenshots/<test-file-name>/` in your project root:
39
31
 
40
32
  ```
41
- .testdriverai/
33
+ .testdriver/
42
34
  screenshots/
43
35
  login.test/
44
36
  screenshot-1737633600000.png
45
- screenshot-1737633605000.png
37
+ login-page.png
46
38
  checkout.test/
47
39
  screenshot-1737633700000.png
48
40
  ```
@@ -56,23 +48,20 @@ Screenshots are automatically saved to `.testdriverai/screenshots/<test-file-nam
56
48
  ### Basic Screenshot
57
49
 
58
50
  ```javascript
59
- // Capture a screenshot with default settings
51
+ // Capture a screenshot with auto-generated filename
60
52
  const screenshotPath = await testdriver.screenshot();
61
53
  console.log('Screenshot saved to:', screenshotPath);
62
54
  ```
63
55
 
64
- ### Screenshot with Mouse Cursor
56
+ ### Custom Filename
65
57
 
66
58
  ```javascript
67
- // Capture a screenshot showing the mouse cursor position
68
- const screenshotPath = await testdriver.screenshot(1, false, true);
69
- ```
70
-
71
- ### Silent Screenshot
59
+ // Save with a descriptive filename
60
+ await testdriver.screenshot("login-page");
61
+ // Saves to: .testdriver/screenshots/<test>/login-page.png
72
62
 
73
- ```javascript
74
- // Capture without logging the save location
75
- await testdriver.screenshot(1, true);
63
+ await testdriver.screenshot("after-click");
64
+ // Saves to: .testdriver/screenshots/<test>/after-click.png
76
65
  ```
77
66
 
78
67
  ### Debugging with Screenshots
@@ -136,11 +125,11 @@ describe("Login Flow", () => {
136
125
  </Accordion>
137
126
 
138
127
  <Accordion title="Add to .gitignore">
139
- Add `.testdriverai/screenshots/` to your `.gitignore` to avoid committing screenshots to version control:
128
+ Add `.testdriver/screenshots/` to your `.gitignore` to avoid committing screenshots to version control:
140
129
 
141
130
  ```
142
131
  # .gitignore
143
- .testdriverai/screenshots/
132
+ .testdriver/screenshots/
144
133
  ```
145
134
  </Accordion>
146
135
  </AccordionGroup>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.2.53",
3
+ "version": "7.2.55",
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.d.ts CHANGED
@@ -1136,26 +1136,20 @@ export default class TestDriverSDK {
1136
1136
  // Utility Methods
1137
1137
 
1138
1138
  /**
1139
- * Capture a screenshot of the current screen and save it to .testdriverai/screenshots
1140
- * @param scale - Scale factor for the screenshot (default: 1 = original size)
1141
- * @param silent - Whether to suppress logging (default: false)
1142
- * @param mouse - Whether to include mouse cursor (default: false)
1139
+ * Capture a screenshot of the current screen and save it to .testdriver/screenshots
1140
+ * @param filename - Custom filename (without .png extension)
1143
1141
  * @returns The file path where the screenshot was saved
1144
1142
  *
1145
1143
  * @example
1146
- * // Capture a screenshot (saves to .testdriverai/screenshots)
1147
- * const screenshotPath = await client.screenshot();
1148
- * console.log('Screenshot saved to:', screenshotPath);
1144
+ * // Capture a screenshot with auto-generated filename
1145
+ * const screenshotPath = await testdriver.screenshot();
1149
1146
  *
1150
1147
  * @example
1151
- * // Capture with mouse cursor visible
1152
- * const screenshotPath = await client.screenshot(1, false, true);
1148
+ * // Capture with custom filename
1149
+ * const screenshotPath = await testdriver.screenshot("login-page");
1150
+ * // Saves to: .testdriver/screenshots/<test>/login-page.png
1153
1151
  */
1154
- screenshot(
1155
- scale?: number,
1156
- silent?: boolean,
1157
- mouse?: boolean,
1158
- ): Promise<string>;
1152
+ screenshot(filename?: string): Promise<string>;
1159
1153
 
1160
1154
  /**
1161
1155
  * Wait for specified time
package/sdk.js CHANGED
@@ -2118,7 +2118,7 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
2118
2118
  // Clean up screenshots folder for this test file before running
2119
2119
  if (this.testFile) {
2120
2120
  const testFileName = path.basename(this.testFile, path.extname(this.testFile));
2121
- const screenshotsDir = path.join(process.cwd(), ".testdriverai", "screenshots", testFileName);
2121
+ const screenshotsDir = path.join(process.cwd(), ".testdriver", "screenshots", testFileName);
2122
2122
  if (fs.existsSync(screenshotsDir)) {
2123
2123
  fs.rmSync(screenshotsDir, { recursive: true, force: true });
2124
2124
  }
@@ -2772,27 +2772,30 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
2772
2772
  // ====================================
2773
2773
 
2774
2774
  /**
2775
- * Capture a screenshot of the current screen and save it to .testdriverai/screenshots
2776
- * @param {number} [scale=1] - Scale factor for the screenshot (1 = original size)
2777
- * @param {boolean} [silent=false] - Whether to suppress logging
2778
- * @param {boolean} [mouse=false] - Whether to include mouse cursor
2775
+ * Capture a screenshot of the current screen and save it to .testdriver/screenshots
2776
+ * @param {string} [filename] - Custom filename (without .png extension)
2779
2777
  * @returns {Promise<string>} The file path where the screenshot was saved
2780
2778
  *
2781
2779
  * @example
2782
- * // Capture a screenshot (saves to .testdriverai/screenshots)
2783
- * const screenshotPath = await client.screenshot();
2784
- * console.log('Screenshot saved to:', screenshotPath);
2780
+ * // Capture a screenshot with auto-generated filename
2781
+ * const screenshotPath = await testdriver.screenshot();
2785
2782
  *
2786
2783
  * @example
2787
- * // Capture with mouse cursor visible
2788
- * const screenshotPath = await client.screenshot(1, false, true);
2784
+ * // Capture with custom filename
2785
+ * const screenshotPath = await testdriver.screenshot("login-page");
2786
+ * // Saves to: .testdriver/screenshots/<test>/login-page.png
2789
2787
  */
2790
- async screenshot(scale = 1, silent = false, mouse = false) {
2788
+ async screenshot(filename) {
2791
2789
  this._ensureConnected();
2792
- const base64Data = await this.system.captureScreenBase64(scale, silent, mouse);
2793
2790
 
2794
- // Save to .testdriverai/screenshots/<test-file-name> directory
2795
- let screenshotsDir = path.join(process.cwd(), ".testdriverai", "screenshots");
2791
+ const finalFilename = filename
2792
+ ? (filename.endsWith('.png') ? filename : `${filename}.png`)
2793
+ : `screenshot-${Date.now()}.png`;
2794
+
2795
+ const base64Data = await this.system.captureScreenBase64(1, false, false);
2796
+
2797
+ // Save to .testdriver/screenshots/<test-file-name> directory
2798
+ let screenshotsDir = path.join(process.cwd(), ".testdriver", "screenshots");
2796
2799
  if (this.testFile) {
2797
2800
  const testFileName = path.basename(this.testFile, path.extname(this.testFile));
2798
2801
  screenshotsDir = path.join(screenshotsDir, testFileName);
@@ -2801,8 +2804,7 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
2801
2804
  fs.mkdirSync(screenshotsDir, { recursive: true });
2802
2805
  }
2803
2806
 
2804
- const filename = `screenshot-${Date.now()}.png`;
2805
- const filePath = path.join(screenshotsDir, filename);
2807
+ const filePath = path.join(screenshotsDir, finalFilename);
2806
2808
 
2807
2809
  // Remove data:image/png;base64, prefix if present
2808
2810
  const cleanBase64 = base64Data.replace(/^data:image\/\w+;base64,/, "");
@@ -2810,9 +2812,7 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
2810
2812
 
2811
2813
  fs.writeFileSync(filePath, buffer);
2812
2814
 
2813
- if (!silent) {
2814
- this.emitter.emit("log:info", `📸 Screenshot saved to: ${filePath}`);
2815
- }
2815
+ this.emitter.emit("log:info", `📸 Screenshot saved to: ${filePath}`);
2816
2816
 
2817
2817
  return filePath;
2818
2818
  }