testdriverai 5.1.0 → 5.1.2

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/agent.js CHANGED
@@ -31,7 +31,7 @@ const sanitizeFilename = require("sanitize-filename");
31
31
  const macScreenPerms = require("mac-screen-capture-permissions");
32
32
 
33
33
  // local modules
34
- const wss = require("./lib/websockets.js");
34
+ const websocketserver = require("./lib/websockets.js");
35
35
  const speak = require("./lib/speak.js");
36
36
  const analytics = require("./lib/analytics.js");
37
37
  const log = require("./lib/logger.js");
@@ -63,6 +63,7 @@ let checkCount = 0;
63
63
  let checkLimit = 7;
64
64
  let lastScreenshot = null;
65
65
  let rl;
66
+ let wss;
66
67
 
67
68
  // list of prompts that the user has given us
68
69
  let tasks = [];
@@ -691,6 +692,26 @@ const actOnMarkdown = async (content, depth, pushToHistory = false, dry = false)
691
692
  }
692
693
  };
693
694
 
695
+ const ensureMacScreenPerms = async () => {
696
+
697
+ // if os is mac, check for screen capture permissions
698
+ if (
699
+ !config.TD_VM &&
700
+ process.platform === "darwin" &&
701
+ !macScreenPerms.hasScreenCapturePermission()
702
+ ) {
703
+ logger.info(chalk.red("Screen capture permissions not enabled."));
704
+ logger.info(
705
+ "You must enable screen capture permissions for the application calling `testdriverai`.",
706
+ );
707
+ logger.info(
708
+ "Read More: https://docs.testdriver.ai/faq/screen-recording-permissions-mac-only",
709
+ );
710
+ analytics.track("noMacPermissions");
711
+ return exit();
712
+ }
713
+ }
714
+
694
715
  const newSession = async () => {
695
716
  // should be start of new session
696
717
  const sessionRes = await sdk.req("session/start", {
@@ -817,7 +838,7 @@ const firstPrompt = async () => {
817
838
 
818
839
  rl.on("line", handleInput);
819
840
 
820
- wss.addEventListener("input", async (message) => {
841
+ config.TD_VM && wss.addEventListener("input", async (message) => {
821
842
  handleInput(message.data);
822
843
  });
823
844
 
@@ -1061,7 +1082,7 @@ ${yaml.dump(step)}
1061
1082
  };
1062
1083
 
1063
1084
  const promptUser = () => {
1064
- wss.sendToClients("done");
1085
+ config.TD_VM && wss.sendToClients("done");
1065
1086
  emitter.emit(events.interactive, true);
1066
1087
  rl.prompt(true);
1067
1088
  };
@@ -1122,6 +1143,16 @@ const embed = async (file, depth) => {
1122
1143
  logger.info(`${file} (end)`);
1123
1144
  };
1124
1145
 
1146
+ const buildEnv = async () => {
1147
+ let win = await system.activeWin();
1148
+ if (config.TD_VM) {
1149
+ wss = websocketserver.create();
1150
+ }
1151
+ setTerminalApp(win);
1152
+ await ensureMacScreenPerms();
1153
+ await makeSandbox();
1154
+ }
1155
+
1125
1156
  const start = async () => {
1126
1157
  // logger.info(await system.getPrimaryDisplay());
1127
1158
 
@@ -1135,28 +1166,12 @@ const start = async () => {
1135
1166
 
1136
1167
  // await sdk.auth();
1137
1168
 
1138
- // if os is mac, check for screen capture permissions
1139
- if (
1140
- process.platform === "darwin" &&
1141
- !macScreenPerms.hasScreenCapturePermission()
1142
- ) {
1143
- logger.info(chalk.red("Screen capture permissions not enabled."));
1144
- logger.info(
1145
- "You must enable screen capture permissions for the application calling `testdriverai`.",
1146
- );
1147
- logger.info(
1148
- "Read More: https://docs.testdriver.ai/faq/screen-recording-permissions-mac-only",
1149
- );
1150
- analytics.track("noMacPermissions");
1151
- return exit();
1152
- }
1153
-
1154
1169
  if (thisCommand !== "run") {
1155
1170
  speak("Howdy! I am TestDriver version " + package.version);
1156
1171
 
1157
1172
  if (!config.TD_VM) {
1158
1173
  logger.info(
1159
- chalk.red("Warning!") +
1174
+ chalk.red("Warning!" ) +
1160
1175
  chalk.dim("Local mode sends screenshots of the desktop to our API."),
1161
1176
  );
1162
1177
  logger.info(
@@ -1170,11 +1185,11 @@ const start = async () => {
1170
1185
  analytics.track("command", { command: thisCommand, file: thisFile });
1171
1186
 
1172
1187
  if (thisCommand == "edit") {
1173
- await makeSandbox();
1188
+ await buildEnv();
1174
1189
  firstPrompt();
1175
1190
  } else if (thisCommand == "run") {
1191
+ await buildEnv();
1176
1192
  errorLimit = 100;
1177
- await makeSandbox();
1178
1193
  run(thisFile);
1179
1194
  } else if (thisCommand == "init") {
1180
1195
  await init();
package/index.js CHANGED
@@ -10,11 +10,9 @@ if (process.argv[2] === "--help" || process.argv[2] === "-h") {
10
10
  }
11
11
 
12
12
  (async () => {
13
- let win = await system.activeWin();
14
13
 
15
14
  if (!config.TD_OVERLAY) {
16
15
  let agent = require("./agent.js");
17
- agent.setTerminalApp(win);
18
16
  agent.start();
19
17
  } else {
20
18
  // Intercept all stdout and stderr calls (works with console as well)
package/lib/logger.js CHANGED
@@ -10,6 +10,7 @@ const shouldLog =
10
10
  // responsible for rendering ai markdown output
11
11
  const { marked } = require("marked");
12
12
  const { markedTerminal } = require("marked-terminal");
13
+ const { config } = require("dotenv");
13
14
 
14
15
  const { printf } = winston.format;
15
16
 
@@ -19,6 +20,13 @@ const logFormat = printf(({ message }) => {
19
20
 
20
21
  let interpolationVars = JSON.parse(process.env.TD_INTERPOLATION_VARS || '{}');
21
22
 
23
+ // this handles local `TD_*` variables
24
+ for (const [key, value] of Object.entries(process.env)) {
25
+ if (key.startsWith("TD_") && key !== "TD_INTERPOLATION_VARS") {
26
+ interpolationVars[key] = value;
27
+ }
28
+ }
29
+
22
30
  const censorSensitiveData = (message) => {
23
31
  for (let value of Object.values(interpolationVars)) {
24
32
 
@@ -77,7 +85,9 @@ const createMarkdownStreamLogger = () => {
77
85
  return;
78
86
  }
79
87
 
80
- websockets.sendToClients("output", chunk);
88
+ if (config.TD_VM) {
89
+ websockets.sendToClients("output", chunk);
90
+ }
81
91
 
82
92
  const previousConsoleOutput = markedParsePartial(buffer, 0, -1);
83
93
 
package/lib/speak.js CHANGED
@@ -6,7 +6,6 @@ const websockets = require("./websockets");
6
6
  module.exports = (message) => {
7
7
  if (config["TD_SPEAK"]) {
8
8
  say.stop();
9
- // websockets.sendToClients("output", message);
10
9
  if (process.platform === "darwin") {
11
10
  say.speak(message, "Fred", 1.2);
12
11
  } else {
package/lib/system.js CHANGED
@@ -171,19 +171,10 @@ const initializeActiveWindow = async () => {
171
171
  const activeWin = async () => {
172
172
 
173
173
  if (config.TD_VM) {
174
-
175
- return "error getting active window, proceed normally";
176
-
174
+ return "error getting active window, proceed normally";
177
175
  } else {
178
-
179
- try {
180
- const activeWindow = await initializeActiveWindow();
181
- return await activeWindow();
182
- } catch (error) {
183
- logger.error('Error getting active window: %s', error);
184
- return null;
185
- }
186
-
176
+ const activeWindow = await initializeActiveWindow();
177
+ return await activeWindow();
187
178
  }
188
179
  };
189
180
 
package/lib/websockets.js CHANGED
@@ -1,7 +1,10 @@
1
1
  const WebSocket = require('ws');
2
+ const config = require('./config');
2
3
 
4
+ let instance;
3
5
  class WebSocketServerSingleton {
4
6
  constructor() {
7
+
5
8
  if (!WebSocketServerSingleton.instance) {
6
9
  this.wss = new WebSocket.Server({ port: 8080 }, () => {
7
10
  });
@@ -72,7 +75,11 @@ class WebSocketServerSingleton {
72
75
  }
73
76
  }
74
77
 
75
- const instance = new WebSocketServerSingleton();
76
- Object.freeze(instance);
77
78
 
78
- module.exports = instance;
79
+ module.exports = {
80
+ create: () => {
81
+ instance = new WebSocketServerSingleton();
82
+ Object.freeze(instance);
83
+ return instance;
84
+ }
85
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "5.1.0",
3
+ "version": "5.1.2",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "index.js",
6
6
  "bin": {