testdriverai 4.1.37 → 4.1.39

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
@@ -863,9 +863,6 @@ ${regression}
863
863
  // it parses the markdown file and executes the codeblocks exactly as if they were
864
864
  // generated by the AI in a single prompt
865
865
  let run = async (file, overwrite = false, shouldExit = true) => {
866
- // parse potential string value for exit
867
- shouldExit = shouldExit === "false" ? false : true;
868
- overwrite = overwrite === "false" ? false : true;
869
866
 
870
867
  setTerminalWindowTransparency(true);
871
868
 
@@ -887,6 +884,9 @@ let run = async (file, overwrite = false, shouldExit = true) => {
887
884
  await exit(true);
888
885
  }
889
886
 
887
+ // Inject environment variables into any ${VAR} strings
888
+ yml = parser.interpolate(yml, process.env);
889
+
890
890
  let ymlObj = null;
891
891
  try {
892
892
  ymlObj = await yaml.load(yml);
@@ -934,13 +934,13 @@ ${yaml.dump(step)}
934
934
  await actOnMarkdown(markdown, 0, true);
935
935
  }
936
936
 
937
- if (overwrite) {
937
+ if (overwrite || overwrite == "true") {
938
938
  await save({ filepath: file });
939
939
  }
940
940
 
941
941
  setTerminalWindowTransparency(false);
942
942
 
943
- if (shouldExit) {
943
+ if (shouldExit || shouldExit == "true") {
944
944
  await summarize();
945
945
  await exit(false);
946
946
  }
package/eslint.config.js CHANGED
@@ -10,6 +10,7 @@ module.exports = [
10
10
  globals: {
11
11
  ...globals.browser,
12
12
  ...globals.node,
13
+ ...globals.jest
13
14
  },
14
15
  },
15
16
  },
package/lib/parser.js CHANGED
@@ -76,10 +76,24 @@ const parseYAML = async function (inputYaml) {
76
76
  return doc;
77
77
  };
78
78
 
79
+ // Replace ${VAR} with the value from the vars object
80
+ // Will skip variables that are not in the vars object
81
+ // Will skip escaped variables like \${VAR}
82
+ function interpolate (yaml, vars) {
83
+ let newyaml = yaml;
84
+ Object.keys(vars).forEach((key) => {
85
+ newyaml = newyaml.replace(new RegExp(`(?<!\\\\)\\$\\{${key}\\}`, "g"), vars[key]);
86
+ });
87
+ // Replace \$ with $
88
+ newyaml = newyaml.replace(/\\(\${[^}]+})/g, "$1");
89
+ return newyaml;
90
+ }
91
+
79
92
  module.exports = {
80
93
  findCodeBlocks,
81
94
  findGenerativePrompts,
82
95
  getYAMLFromCodeBlock,
96
+ interpolate,
83
97
  getCommands: async function (codeBlock) {
84
98
  const yml = getYAMLFromCodeBlock(codeBlock);
85
99
  let yamlArray = await parseYAML(yml);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "4.1.37",
3
+ "version": "4.1.39",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -10,7 +10,8 @@
10
10
  "start": "node index.js",
11
11
  "dev": "DEV=true node index.js",
12
12
  "debug": "DEV=true VERBOSE=true node index.js",
13
- "bundle": "node build.mjs"
13
+ "bundle": "node build.mjs",
14
+ "test": "mocha test/*"
14
15
  },
15
16
  "author": "",
16
17
  "license": "ISC",
@@ -56,6 +57,8 @@
56
57
  "globals": "^15.9.0",
57
58
  "node-addon-api": "^8.0.0",
58
59
  "node-gyp": "^10.1.0",
60
+ "mocha": "^10.8.2",
61
+ "chai": "^5.1.2",
59
62
  "prettier": "3.3.3"
60
63
  },
61
64
  "optionalDependencies": {
@@ -0,0 +1,48 @@
1
+ const chai = require('chai');
2
+ const expect = chai.expect;
3
+ const { interpolate } = require('../lib/parser');
4
+
5
+ describe('interpolate', function() {
6
+ it('should replace variables in the string with values from the dictionary', function() {
7
+ const template = 'Hello, ${name}!';
8
+ const vars = { name: 'World' };
9
+ const result = interpolate(template, vars);
10
+ expect(result).to.equal('Hello, World!');
11
+ });
12
+
13
+ it('should replace multiple variables in the string', function() {
14
+ const template = 'Hi, ${firstName} ${lastName}!';
15
+ const vars = { firstName: 'Marcy', lastName: 'the Dog' };
16
+ const result = interpolate(template, vars);
17
+ expect(result).to.equal('Hi, Marcy the Dog!');
18
+ });
19
+
20
+ it('should leave variables unchanged if they are not in the dictionary', function() {
21
+ const template = 'Hi, ${name} ${surname}!';
22
+ const vars = { name: 'John' };
23
+ const result = interpolate(template, vars);
24
+ expect(result).to.equal('Hi, John ${surname}!');
25
+ });
26
+
27
+ it('should return the original string if no variables are present', function() {
28
+ const template = 'Hello, World!';
29
+ const vars = { name: 'John' };
30
+ const result = interpolate(template, vars);
31
+ expect(result).to.equal('Hello, World!');
32
+ });
33
+
34
+ it('should handle an empty dictionary gracefully', function() {
35
+ const template = 'Hi, ${name}!';
36
+ const vars = {};
37
+ const result = interpolate(template, vars);
38
+ expect(result).to.equal('Hi, ${name}!');
39
+ });
40
+
41
+ it('should not replace escaped variables', function() {
42
+ const template = 'Hello, \\${name}!';
43
+ const vars = { name: 'World' };
44
+ const result = interpolate(template, vars);
45
+ expect(result).to.equal('Hello, ${name}!');
46
+ });
47
+ });
48
+