testdriverai 5.0.5 → 5.0.7

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
@@ -2,19 +2,33 @@
2
2
 
3
3
  # TestDriver.ai
4
4
 
5
- Automate and scale QA with agentic users. Next generation autonomous AI agent for end-to-end testing of web & desktop.
5
+ Automate and scale QA with computer-use agents.
6
6
 
7
7
  [Docs](https://docs.testdriver.ai) | [Website](https://testdriver.ai) | [GitHub Action](https://github.com/marketplace/actions/testdriver-ai) | [Join our Discord](https://discord.gg/a8Cq739VWn)
8
8
 
9
9
  ---
10
10
 
11
+
12
+
13
+ https://github.com/user-attachments/assets/4719e834-652a-43ba-8b8c-24ea6f357ae3
14
+
15
+
16
+
17
+ # Install via NPM
18
+
11
19
  ```sh
12
20
  npm install testdriverai -g
13
21
  ```
14
22
 
15
- | Windows | MacOS | Linux |
16
- ---------|-------|-------|
17
- | ✅ | ✅ | ❌ |
23
+ # Run Init
24
+
25
+ ```sh
26
+ testdriverai init
27
+ ```
28
+
29
+ [Follow the instructions on our docs for more.](https://docs.testdriver.ai/overview/quickstart).
30
+
31
+ # About
18
32
 
19
33
  TestDriver isn't like any test framework you've used before. TestDriver is an OS Agent for QA. TestDriver uses AI vision along with mouse and keyboard emulation to control the entire desktop. It's more like a QA employee than a test framework. This kind of black-box testing has some major advantages:
20
34
 
@@ -24,8 +38,6 @@ TestDriver isn't like any test framework you've used before. TestDriver is an OS
24
38
 
25
39
  ### Demo
26
40
 
27
- https://github.com/user-attachments/assets/fba08020-a751-4d9e-9505-50db541fd38b
28
-
29
41
  # Examples
30
42
 
31
43
  - Test any user flow on any website in any browser
package/agent.js CHANGED
@@ -232,7 +232,7 @@ const dieOnFatal = async (error) => {
232
232
  // and responds. notice `actOnMarkdown` which will continue
233
233
  // the thread until there are no more codeblocks to execute
234
234
  const haveAIResolveError = async (error, markdown, depth = 0, undo = true) => {
235
- if (thisCommand == "run" || error.fatal) {
235
+ if (error.fatal) {
236
236
  return await dieOnFatal(error);
237
237
  }
238
238
 
@@ -1183,7 +1183,7 @@ const makeSandbox = async () => {
1183
1183
  logger.info(chalk.gray(`- creating linux sandbox...`));
1184
1184
  await sandbox.boot();
1185
1185
  logger.info(chalk.gray(`- authenticating...`));
1186
- await sandbox.send({type: 'authenticate', apiKey: config.TD_API_KEY });
1186
+ await sandbox.send({type: 'authenticate', apiKey: config.TD_API_KEY, secret: config.TD_SECRET} );
1187
1187
  logger.info(chalk.gray(`- setting up...`));
1188
1188
  await sandbox.send({type: 'create', resolution: [1024, 768]});
1189
1189
  logger.info(chalk.gray(`- starting stream...`));
package/lib/commands.js CHANGED
@@ -707,7 +707,19 @@ let commands = {
707
707
  exec: async (cli_command, use_stderr = false, silent = false) => {
708
708
 
709
709
  if (config.TD_VM) {
710
- return await sandbox.send({type: "commands.run", commands: cli_command });
710
+ let result = await sandbox.send({type: "commands.run", command: cli_command });
711
+ if (!silent) {
712
+ if (use_stderr) {
713
+ logger.info(chalk.dim(result.out.stderr), true);
714
+ } else {
715
+ logger.info(chalk.dim(result.out.stdout), true);
716
+ }
717
+
718
+ }
719
+
720
+ let rtnr = use_stderr ? result.out.stderr : result.out.stdout;
721
+ return rtnr;
722
+
711
723
  } else {
712
724
 
713
725
  let args = {};
package/lib/config.js CHANGED
@@ -31,6 +31,7 @@ const config = {
31
31
  TD_DEV: parseValue(process.env["DEV"]),
32
32
  TD_PROFILE: false,
33
33
  TD_OVERLAY: true,
34
+ TD_SECRET: null,
34
35
  TD_VM: false
35
36
  };
36
37
 
@@ -52,42 +52,48 @@ const runPwsh = (appName, method) => {
52
52
  };
53
53
 
54
54
  async function focusApplication(appName) {
55
- try {
56
- if (platform() == "mac") {
57
- return await execSync(`osascript -e '${appleScriptSetFrontmost(appName)}'`);
58
- } else if (platform() == "linux") {
59
- // TODO: This needs fixing
60
- return;
61
- } else if (platform() == "windows") {
62
- return runPwsh(appName, "Focus");
55
+ if (!config.TD_VM) {
56
+ try {
57
+ if (platform() == "mac") {
58
+ return await execSync(`osascript -e '${appleScriptSetFrontmost(appName)}'`);
59
+ } else if (platform() == "linux") {
60
+ // TODO: This needs fixing
61
+ return;
62
+ } else if (platform() == "windows") {
63
+ return runPwsh(appName, "Focus");
64
+ }
65
+ } catch (error) {
66
+ logger.error(error);
63
67
  }
64
- } catch (error) {
65
- logger.error(error);
66
68
  }
67
69
  }
68
70
 
69
71
  async function hideTerminal(appName) {
70
- try {
71
- if (platform() == "mac") {
72
- robot.keyTap('m', ['command']);
73
- robot.keyToggle('command', 'up')
74
- } else if (platform() == "windows") {
75
- return runPwsh(appName, "Minimize");
72
+ if (!config.TD_VM) {
73
+ try {
74
+ if (platform() == "mac") {
75
+ robot.keyTap('m', ['command']);
76
+ robot.keyToggle('command', 'up')
77
+ } else if (platform() == "windows") {
78
+ return runPwsh(appName, "Minimize");
79
+ }
80
+ } catch (error) {
81
+ logger.error(error);
76
82
  }
77
- } catch (error) {
78
- logger.error(error);
79
83
  }
80
84
  }
81
85
 
82
86
  async function showTerminal(appName) {
83
- try {
84
- if (platform() == "mac") {
85
- return await execSync(`osascript -e '${appleScriptActivate(appName)}'`);
86
- } else if (platform() == "windows") {
87
- return runPwsh(appName, "Restore");
87
+ if (!config.TD_VM) {
88
+ try {
89
+ if (platform() == "mac") {
90
+ return await execSync(`osascript -e '${appleScriptActivate(appName)}'`);
91
+ } else if (platform() == "windows") {
92
+ return runPwsh(appName, "Restore");
93
+ }
94
+ } catch (error) {
95
+ logger.error(error);
88
96
  }
89
- } catch (error) {
90
- logger.error(error);
91
97
  }
92
98
  }
93
99
 
package/lib/sandbox.js CHANGED
@@ -54,6 +54,10 @@ class Sandbox {
54
54
  this.socket.on('message', (raw) => {
55
55
  let message = JSON.parse(raw);
56
56
 
57
+ if (message.type === 'error') {
58
+ console.error(message);
59
+ }
60
+
57
61
  if (this.ps[message.requestId]) {
58
62
  this.ps[message.requestId].resolve(message);
59
63
  delete this.ps[message.requestId];
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "5.0.0-beta.7",
3
+ "version": "5.0.6",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "testdriverai",
9
- "version": "5.0.0-beta.7",
9
+ "version": "5.0.6",
10
10
  "license": "ISC",
11
11
  "dependencies": {
12
12
  "@e2b/desktop": "^1.6.0",
@@ -2913,9 +2913,9 @@
2913
2913
  }
2914
2914
  },
2915
2915
  "node_modules/electron": {
2916
- "version": "33.4.4",
2917
- "resolved": "https://registry.npmjs.org/electron/-/electron-33.4.4.tgz",
2918
- "integrity": "sha512-IGfb8EZriE++6+GQn8dUEaUxreUA1WOZt3N76GGQu23TIFuz81DxKZ69xmoGMmgYm51p5S342U1mfQnrjwqTew==",
2916
+ "version": "33.4.5",
2917
+ "resolved": "https://registry.npmjs.org/electron/-/electron-33.4.5.tgz",
2918
+ "integrity": "sha512-rbDc4QOqfMT1uopUG+KcaMKzKgFAXAzN3wNIdgErnB1tUnpgTxwFv1BDN/exCl1vaVWBeM9YtbO5PgbGZeq7xw==",
2919
2919
  "hasInstallScript": true,
2920
2920
  "license": "MIT",
2921
2921
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "5.0.5",
3
+ "version": "5.0.7",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "index.js",
6
6
  "bin": {