testdriverai 4.0.72 → 4.0.74

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/README.md CHANGED
@@ -81,7 +81,7 @@ If you have multiple monitors, make sure you do this on your primary display.
81
81
 
82
82
  Now, just tell TestDriver what you want it to do. For now, stick with single commands like "click sign up" and "scroll down."
83
83
 
84
- Later, try `/explore` to perform higher level objectives like "complete the onboarding."
84
+ Later, try to perform higher level objectives like "complete the onboarding."
85
85
 
86
86
  ```yaml
87
87
  > Click on sign up
package/index.js CHANGED
@@ -163,7 +163,7 @@ function fileCompleter(line) {
163
163
 
164
164
  function completer(line) {
165
165
  let completions =
166
- "/summarize /save /run /quit /explore /assert /undo /manual".split(" ");
166
+ "/summarize /save /run /quit /assert /undo /manual".split(" ");
167
167
  if (line.startsWith("/run ")) {
168
168
  return fileCompleter(line);
169
169
  } else {
@@ -524,7 +524,7 @@ const generate = async (type, count) => {
524
524
  let list = testPrompt.listsOrdered[0];
525
525
 
526
526
  let contents = list
527
- .map((item, index) => `${index + 1}. /explore ${item}`)
527
+ .map((item, index) => `${index + 1}. ${item}`)
528
528
  .join("\n");
529
529
  fs.writeFileSync(path1, contents);
530
530
  }
@@ -635,8 +635,6 @@ const firstPrompt = async () => {
635
635
  await exit();
636
636
  } else if (input.indexOf("/save") == 0) {
637
637
  await save({ filepath: commands[1] });
638
- } else if (input.indexOf("/explore") == 0) {
639
- await humanInput(commands.slice(1).join(" "), true);
640
638
  } else if (input.indexOf("/undo") == 0) {
641
639
  await undo();
642
640
  } else if (input.indexOf("/assert") == 0) {
@@ -648,7 +646,7 @@ const firstPrompt = async () => {
648
646
  } else if (input.indexOf("/generate") == 0) {
649
647
  await generate(commands[1], commands[2]);
650
648
  } else {
651
- await humanInput(input, false);
649
+ await humanInput(input, true);
652
650
  }
653
651
 
654
652
  setTerminalWindowTransparency(false);
package/lib/commands.js CHANGED
@@ -167,19 +167,19 @@ const scroll = async (direction = "down", amount = 300) => {
167
167
  switch (direction) {
168
168
  case "up":
169
169
  await robot.keyTap("pageup");
170
- await redraw.wait(2000);
170
+ await redraw.wait(10000);
171
171
  break;
172
172
  case "down":
173
173
  await robot.keyTap("pagedown");
174
- await redraw.wait(2000);
174
+ await redraw.wait(10000);
175
175
  break;
176
176
  case "left":
177
177
  await robot.scrollMouse(amount * -1, 0);
178
- await redraw.wait(2000);
178
+ await redraw.wait(10000);
179
179
  break;
180
180
  case "right":
181
181
  await robot.scrollMouse(amount, 0);
182
- await redraw.wait(2000);
182
+ await redraw.wait(10000);
183
183
  break;
184
184
  default:
185
185
  throw new AiError("Direction not found");
@@ -199,7 +199,7 @@ const click = async (x, y, button = "left", click = "single") => {
199
199
  robot.moveMouseSmooth(x, y, 0.1);
200
200
  await delay(1000); // wait for the mouse to move
201
201
  robot.mouseClick(button, double);
202
- await redraw.wait(2000);
202
+ await redraw.wait(10000);
203
203
  return;
204
204
  };
205
205
 
@@ -210,7 +210,7 @@ const hover = async (x, y) => {
210
210
  y = parseInt(y);
211
211
 
212
212
  await robot.moveMouseSmooth(x, y, 0.1);
213
- await redraw.wait(2000);
213
+ await redraw.wait(10000);
214
214
 
215
215
  return;
216
216
  };
@@ -236,6 +236,7 @@ let commands = {
236
236
 
237
237
  log("info", "");
238
238
  log("info", chalk.dim("thinking..."), true);
239
+ log("info", "");
239
240
 
240
241
  const mdStream = logger.createMarkdownStreamLogger();
241
242
  let response = await sdk.req(
@@ -270,6 +271,7 @@ let commands = {
270
271
  // take a screenshot
271
272
  log("info", "");
272
273
  log("info", chalk.dim("thinking..."), true);
274
+ log("info", "");
273
275
 
274
276
  let response = await sdk.req("hover/image", {
275
277
  needle: description,
@@ -313,7 +315,7 @@ let commands = {
313
315
  await redraw.start();
314
316
  string = string.toString();
315
317
  await robot.typeString(string);
316
- await redraw.wait(1000);
318
+ await redraw.wait(10000);
317
319
  return;
318
320
  },
319
321
  // press keys
@@ -371,7 +373,7 @@ let commands = {
371
373
  // finally, press the keys
372
374
  robot.keyTap(keysPressed[0], modsToPress);
373
375
 
374
- await redraw.wait(2000);
376
+ await redraw.wait(10000);
375
377
 
376
378
  // keyTap will release the normal keys, but will not release modifier keys
377
379
  // so we need to release the modifier keys manually
@@ -457,7 +459,7 @@ let commands = {
457
459
  ),
458
460
  true,
459
461
  );
460
- await redraw.wait(2000);
462
+ await redraw.wait(10000);
461
463
  }
462
464
  }
463
465
 
@@ -486,7 +488,7 @@ let commands = {
486
488
  await robot.keyTap("f", commandOrControl);
487
489
  // type the text
488
490
  await robot.typeString(text);
489
- await redraw.wait(2000);
491
+ await redraw.wait(10000);
490
492
  await robot.keyTap("escape");
491
493
  } catch (e) {
492
494
  console.log(e);
package/lib/network.js ADDED
@@ -0,0 +1,3 @@
1
+
2
+
3
+
package/lib/redraw.js CHANGED
@@ -3,6 +3,79 @@ const os = require("os");
3
3
  const path = require("path");
4
4
  const { compare } = require("odiff-bin");
5
5
 
6
+ // network
7
+ const si = require('systeminformation');
8
+ const chalk = require('chalk');
9
+ let lastTxBytes = null;
10
+ let lastRxBytes = null;
11
+ let measurements = [];
12
+ let networkSettled = true;
13
+ let lastUnsettled = null;
14
+ let watchNetwork = null;
15
+
16
+ async function resetNetwork() {
17
+ lastTxBytes = null;
18
+ lastRxBytes = null;
19
+ measurements = [];
20
+ networkSettled = true;
21
+ lastUnsettled = null;
22
+ }
23
+
24
+ async function updateNetwork() {
25
+ si.networkStats().then(data => {
26
+ let thisRxBytes = data[0].rx_bytes;
27
+ let thisTxBytes = data[0].tx_bytes;
28
+
29
+ let diffRxBytes = lastRxBytes !== null ? thisRxBytes - lastRxBytes : 0;
30
+ let diffTxBytes = lastTxBytes !== null ? thisTxBytes - lastTxBytes : 0;
31
+
32
+ lastRxBytes = thisRxBytes;
33
+ lastTxBytes = thisTxBytes;
34
+
35
+ measurements.push({ rx: diffRxBytes, tx: diffTxBytes });
36
+
37
+ if (measurements.length > 60) {
38
+ measurements.shift();
39
+ }
40
+
41
+ let avgRx = measurements.reduce((acc, m) => acc + m.rx, 0) / measurements.length;
42
+ let avgTx = measurements.reduce((acc, m) => acc + m.tx, 0) / measurements.length;
43
+
44
+ let stdDevRx = Math.sqrt(measurements.reduce((acc, m) => acc + Math.pow(m.rx - avgRx, 2), 0) / measurements.length);
45
+ let stdDevTx = Math.sqrt(measurements.reduce((acc, m) => acc + Math.pow(m.tx - avgTx, 2), 0) / measurements.length);
46
+
47
+ let zIndexRx = stdDevRx !== 0 ? (diffRxBytes - avgRx) / stdDevRx : 0;
48
+ let zIndexTx = stdDevTx !== 0 ? (diffTxBytes - avgTx) / stdDevTx : 0;
49
+
50
+ // log time since unsettlement
51
+
52
+ if ((new Date().getTime() - lastUnsettled) < 2000) {
53
+ networkSettled = false;
54
+ } else {
55
+
56
+ if ((zIndexRx < 0 && zIndexTx < 0) ) {
57
+ lastUnsettled = null;
58
+ networkSettled = true;
59
+ } else {
60
+ lastUnsettled = new Date().getTime();
61
+ networkSettled = false;
62
+ }
63
+
64
+ }
65
+
66
+ if (process.env["DEV"]) {
67
+
68
+ if (!networkSettled) {
69
+ console.log(chalk.red(new Date().getTime(), `,${zIndexRx}`, `,${zIndexTx}`));
70
+ } else {
71
+ console.log(new Date().getTime(), `,${zIndexRx}`, `,${zIndexTx}`);
72
+ }
73
+
74
+ }
75
+
76
+ });
77
+ }
78
+
6
79
  async function imageIsDifferent(image1Url, image2Url) {
7
80
 
8
81
  // generate a temporary file path
@@ -36,17 +109,21 @@ async function imageIsDifferent(image1Url, image2Url) {
36
109
  let startImage = null;
37
110
 
38
111
  async function start() {
112
+ resetNetwork();
113
+ watchNetwork = setInterval(updateNetwork, 500);
39
114
  startImage = await captureScreenPNG();
40
115
  return startImage;
41
116
  }
42
117
 
43
118
  async function checkCondition(resolve, startTime, timeoutMs) {
44
119
  let nowImage = await captureScreenPNG();
45
- let result = await imageIsDifferent(startImage, nowImage);
120
+ let screenDiff = await imageIsDifferent(startImage, nowImage);
46
121
 
47
- if (result) {
122
+ if (screenDiff && networkSettled) {
123
+ clearInterval(watchNetwork);
48
124
  resolve("Condition met");
49
125
  } else if (Date.now() - startTime >= timeoutMs) {
126
+ clearInterval(watchNetwork);
50
127
  resolve("Timeout reached");
51
128
  } else {
52
129
  setTimeout(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "4.0.72",
3
+ "version": "4.0.74",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "index.js",
6
6
  "bin": {