testdriverai 4.0.66 → 4.0.67

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.
@@ -9,7 +9,7 @@ jobs:
9
9
  uses: actions/setup-node@v2
10
10
  with:
11
11
  node-version: 20
12
- - name: npm install
12
+ - name: npm install
13
13
  run: npm install --only=dev --ignore-scripts
14
14
  - name: Run ESLint
15
15
  run: npx eslint
@@ -6,7 +6,7 @@ on:
6
6
  name: Publish to NPM
7
7
  jobs:
8
8
  bump_version:
9
- name: 'Bump Version'
9
+ name: "Bump Version"
10
10
  if: "!contains(github.event.head_commit.message, '[skip ci]')"
11
11
  runs-on: ubuntu-latest
12
12
  steps:
@@ -23,10 +23,10 @@ jobs:
23
23
  run: |
24
24
  git config --global user.name "github-actions[bot]"
25
25
  git config --global user.email "github-actions[bot]@users.noreply.github.com"
26
- - name: 'Bump version'
26
+ - name: "Bump version"
27
27
  run: npm version patch -m "Bump version to %s [skip ci]"
28
-
29
- - name: Push changes to main
28
+
29
+ - name: Push changes to main
30
30
  run: |
31
31
  git push https://${{ secrets.GH_TOKEN }}@github.com/testdriverai/testdriverai.git HEAD:main --force
32
32
 
@@ -43,4 +43,4 @@ jobs:
43
43
  node-version: "20"
44
44
  - uses: JS-DevTools/npm-publish@v3
45
45
  with:
46
- token: ${{ secrets.NPM_AUTH_TOKEN }}
46
+ token: ${{ secrets.NPM_AUTH_TOKEN }}
package/index.js CHANGED
@@ -1,20 +1,15 @@
1
1
  #!/usr/bin/env node
2
- const os = require('os');
2
+ const os = require("os");
3
3
 
4
4
  // Get the current process ID
5
5
  const pid = process.pid;
6
6
 
7
7
  try {
8
- // Display the current priority
9
- console.log('Current priority:', os.getPriority(pid));
10
-
11
8
  // Set the priority to the highest value
12
9
  os.setPriority(pid, -20);
13
-
14
- // Display the updated priority
15
- console.log('Updated priority:', os.getPriority(pid));
10
+ // eslint-disable-next-line no-unused-vars
16
11
  } catch (error) {
17
- console.error('Failed to set process priority:', error);
12
+ // console.error('Failed to set process priority:', error);
18
13
  }
19
14
 
20
15
  // disable depreciation warnings
@@ -28,7 +23,7 @@ require("./lib/profiler");
28
23
 
29
24
  const fs = require("fs");
30
25
  const readline = require("readline");
31
- const http = require('http');
26
+ const http = require("http");
32
27
 
33
28
  // third party modules
34
29
  const path = require("path");
@@ -272,7 +267,6 @@ const haveAIResolveError = async (error, markdown, depth = 0, undo = false) => {
272
267
  // this checks that the task is "really done" using a screenshot of the desktop state
273
268
  // it's likely that the task will not be complete and the AI will respond with more codeblocks to execute
274
269
  const check = async () => {
275
-
276
270
  checkCount++;
277
271
 
278
272
  if (checkCount >= checkLimit) {
@@ -451,7 +445,6 @@ commands:
451
445
  // this function responds to the result of `promptUser()` which is the user input
452
446
  // it kicks off the exploratory loop, which is the main function that interacts with the AI
453
447
  const humanInput = async (currentTask, validateAndLoop = false) => {
454
-
455
448
  lastPrompt = currentTask;
456
449
  checkCount = 0;
457
450
 
@@ -498,7 +491,7 @@ const generate = async (type, count) => {
498
491
  image,
499
492
  mousePosition: await system.getMousePosition(),
500
493
  activeWindow: await system.activeWin(),
501
- count
494
+ count,
502
495
  });
503
496
 
504
497
  log.prettyMarkdown(message);
@@ -507,7 +500,6 @@ const generate = async (type, count) => {
507
500
 
508
501
  // for each testPrompt
509
502
  for (const testPrompt of testPrompts) {
510
-
511
503
  // with the contents of the testPrompt
512
504
  let fileName =
513
505
  sanitizeFilename(testPrompt.headings[0])
@@ -515,7 +507,7 @@ const generate = async (type, count) => {
515
507
  .replace(/ /g, "-")
516
508
  .toLowerCase() + ".md";
517
509
  let path1 = path.join(process.cwd(), "testdriver", "generate", fileName);
518
-
510
+
519
511
  // create generate directory if it doesn't exist
520
512
  if (!fs.existsSync(path.join(process.cwd(), "testdriver", "generate"))) {
521
513
  fs.mkdirSync(path.join(process.cwd(), "testdriver", "generate"));
@@ -694,29 +686,31 @@ New commands will be appended.
694
686
  };
695
687
 
696
688
  let setTerminalWindowTransparency = async (hide) => {
697
-
698
689
  if (hide) {
699
-
700
690
  try {
701
- http.get('http://localhost:60305/hide').on('error',function(){}).end();
691
+ http
692
+ .get("http://localhost:60305/hide")
693
+ .on("error", function () {})
694
+ .end();
702
695
  } catch (e) {
703
- // Suppress error
704
- console.error('Caught exception:', e);
696
+ // Suppress error
697
+ console.error("Caught exception:", e);
705
698
  }
706
699
  } else {
707
-
708
700
  try {
709
- http.get('http://localhost:60305/hide').on('error',function(){}).end();
701
+ http
702
+ .get("http://localhost:60305/hide")
703
+ .on("error", function () {})
704
+ .end();
710
705
  } catch (e) {
711
- // Suppress error
712
- console.error('Caught exception:', e);
706
+ // Suppress error
707
+ console.error("Caught exception:", e);
713
708
  }
714
-
715
709
  }
716
710
 
717
711
  if (!config.TD_MINIMIZE) {
718
- return
719
- };
712
+ return;
713
+ }
720
714
 
721
715
  try {
722
716
  if (hide) {
package/lib/commander.js CHANGED
@@ -6,7 +6,7 @@ const yaml = require("js-yaml");
6
6
  const speak = require("./speak");
7
7
  const notify = require("./notify");
8
8
  const analytics = require("./analytics");
9
- const marky = require('marky');
9
+ const marky = require("marky");
10
10
 
11
11
  // object is a json representation of the individual yml command
12
12
  // the process turns markdown -> yml -> json -> js function execution
@@ -178,7 +178,7 @@ commands:
178
178
  }
179
179
 
180
180
  let timing = marky.stop(object.command);
181
- await analytics.track("command", { data: object, depth, timing});
181
+ await analytics.track("command", { data: object, depth, timing });
182
182
 
183
183
  return response;
184
184
  };
package/lib/commands.js CHANGED
@@ -122,7 +122,6 @@ const assert = async (assertion, shouldThrow = false, async = false) => {
122
122
  }
123
123
 
124
124
  const handleAssertResponse = (response) => {
125
-
126
125
  logger.prettyMarkdown(response);
127
126
 
128
127
  if (response.indexOf("The task passed") > -1) {
@@ -40,7 +40,6 @@ async function focusApplication(appName) {
40
40
  }
41
41
 
42
42
  async function hideTerminal(appName) {
43
-
44
43
  try {
45
44
  if (platform() == "mac") {
46
45
  return await execSync(`osascript -e '${appleScriptMin(appName)}'`);
@@ -53,7 +52,6 @@ async function hideTerminal(appName) {
53
52
  }
54
53
 
55
54
  async function showTerminal(appName) {
56
-
57
55
  try {
58
56
  if (platform() == "mac") {
59
57
  return await execSync(`osascript -e '${appleScriptMax(appName)}'`);
@@ -70,4 +68,3 @@ module.exports = {
70
68
  hideTerminal,
71
69
  showTerminal,
72
70
  };
73
-
package/lib/init.js CHANGED
@@ -67,7 +67,7 @@ module.exports = async () => {
67
67
  console.log("");
68
68
  console.log("Beginning setup...");
69
69
  console.log("");
70
-
70
+
71
71
  const response = await prompts([
72
72
  // {
73
73
  // type: 'password',
package/lib/redraw.js CHANGED
@@ -1,18 +1,30 @@
1
1
  const { captureScreenPNG } = require("./system");
2
2
 
3
- const Jimp = require("jimp");
4
-
5
- async function compareImages(image1Url, image2Url) {
6
- const image1 = await Jimp.read(image1Url);
7
- const image2 = await Jimp.read(image2Url);
8
-
9
- // Pixel difference
10
- const diff = Jimp.diff(image1, image2);
11
-
12
- if (diff.percent < 0.15) {
3
+ const { compare } = require("odiff-bin");
4
+
5
+ async function imageIsDifferent(image1Url, image2Url) {
6
+ const { reason, diffPercentage, match } = await compare(
7
+ image1Url,
8
+ image2Url,
9
+ "/tmp/diff.png",
10
+ {
11
+ failOnLayoutDiff: false,
12
+ outputDiffMask: false,
13
+ },
14
+ );
15
+
16
+ if (match) {
13
17
  return false;
14
18
  } else {
15
- return true;
19
+ if (reason === "pixel-diff") {
20
+ if (diffPercentage > 15) {
21
+ return true;
22
+ } else {
23
+ return false;
24
+ }
25
+ } else {
26
+ return false;
27
+ }
16
28
  }
17
29
  }
18
30
 
@@ -23,26 +35,25 @@ async function start() {
23
35
  return startImage;
24
36
  }
25
37
 
38
+ async function checkCondition(resolve, startTime, timeoutMs) {
39
+ let nowImage = await captureScreenPNG();
40
+ let result = await imageIsDifferent(startImage, nowImage);
41
+
42
+ if (result) {
43
+ resolve("Condition met");
44
+ } else if (Date.now() - startTime >= timeoutMs) {
45
+ resolve("Timeout reached");
46
+ } else {
47
+ setTimeout(() => {
48
+ checkCondition(resolve, startTime, timeoutMs);
49
+ }, 250);
50
+ }
51
+ }
52
+
26
53
  function wait(timeoutMs) {
27
54
  return new Promise((resolve) => {
28
55
  const startTime = Date.now();
29
-
30
- async function checkCondition() {
31
- let nowImage = await captureScreenPNG();
32
- let result = await compareImages(startImage, nowImage);
33
-
34
- if (result) {
35
- resolve("Condition met");
36
- } else if (Date.now() - startTime >= timeoutMs) {
37
- resolve("Timeout reached");
38
- } else {
39
- setTimeout(() => {
40
- checkCondition();
41
- }, 200);
42
- }
43
- }
44
-
45
- checkCondition();
56
+ checkCondition(resolve, startTime, timeoutMs);
46
57
  });
47
58
  }
48
59
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "4.0.66",
3
+ "version": "4.0.67",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -31,6 +31,7 @@
31
31
  "marked-terminal": "^7.0.0",
32
32
  "marky": "^1.2.5",
33
33
  "node-notifier": "^10.0.1",
34
+ "odiff-bin": "^3.1.2",
34
35
  "prompts": "^2.4.2",
35
36
  "remark-parse": "^11.0.0",
36
37
  "rimraf": "^5.0.5",