testdriverai 5.3.7 → 5.3.9
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 +1 -0
- package/agent.js +7 -11
- package/docs/commands/if.mdx +1 -0
- package/docs/getting-started/vscode.mdx +12 -2
- package/electron/overlay.js +17 -8
- package/lib/commands.js +124 -104
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -153,4 +153,5 @@ gh pr create --web
|
|
|
153
153
|
```
|
|
154
154
|
|
|
155
155
|
Your test will run on every commit and the results will be posted as a Dashcam.io video within your GitHub summary! Learn more about deploying on CI [here](https://docs.testdriver.ai/continuous-integration/overview).
|
|
156
|
+
|
|
156
157
|
# vscode
|
package/agent.js
CHANGED
|
@@ -353,8 +353,6 @@ const check = async () => {
|
|
|
353
353
|
const runCommand = async (command, depth) => {
|
|
354
354
|
let yml = await yaml.dump(command);
|
|
355
355
|
|
|
356
|
-
await save({});
|
|
357
|
-
|
|
358
356
|
logger.debug(`running command: \n\n${yml}`);
|
|
359
357
|
|
|
360
358
|
try {
|
|
@@ -600,8 +598,6 @@ const exploratoryLoop = async (
|
|
|
600
598
|
logger.debug("showing prompt from exploratoryLoop response check");
|
|
601
599
|
}
|
|
602
600
|
|
|
603
|
-
await save({ silent: false });
|
|
604
|
-
|
|
605
601
|
return;
|
|
606
602
|
};
|
|
607
603
|
|
|
@@ -996,11 +992,6 @@ let summarize = async (error = null) => {
|
|
|
996
992
|
let save = async ({ filepath = thisFile, silent = false } = {}) => {
|
|
997
993
|
analytics.track("save", { silent });
|
|
998
994
|
|
|
999
|
-
if (!silent) {
|
|
1000
|
-
logger.info(chalk.dim(`saving as ${filepath}...`), true);
|
|
1001
|
-
logger.info("");
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
995
|
if (!executionHistory.length) {
|
|
1005
996
|
return;
|
|
1006
997
|
}
|
|
@@ -1026,7 +1017,7 @@ ${regression}
|
|
|
1026
1017
|
|
|
1027
1018
|
const fileName = filepath.split("/").pop();
|
|
1028
1019
|
if (!silent) {
|
|
1029
|
-
logger.info(chalk.dim(`saved as ${
|
|
1020
|
+
logger.info(chalk.dim(`saved as ${filepath}`));
|
|
1030
1021
|
}
|
|
1031
1022
|
}
|
|
1032
1023
|
|
|
@@ -1114,10 +1105,14 @@ ${yaml.dump(step)}
|
|
|
1114
1105
|
|
|
1115
1106
|
lastPrompt = step.prompt;
|
|
1116
1107
|
await actOnMarkdown(markdown, 0, true);
|
|
1108
|
+
|
|
1109
|
+
if (shouldSave) {
|
|
1110
|
+
await save({ silent: true });
|
|
1111
|
+
}
|
|
1117
1112
|
}
|
|
1118
1113
|
|
|
1119
1114
|
if (shouldSave) {
|
|
1120
|
-
await save({ filepath: file });
|
|
1115
|
+
await save({ filepath: file, silent: false });
|
|
1121
1116
|
}
|
|
1122
1117
|
|
|
1123
1118
|
setTerminalWindowTransparency(false);
|
|
@@ -1280,6 +1275,7 @@ const makeSandbox = async () => {
|
|
|
1280
1275
|
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
1281
1276
|
logger.info(chalk.green(``));
|
|
1282
1277
|
logger.info(chalk.green(`sandbox runner ready!`));
|
|
1278
|
+
logger.info(chalk.green(``));
|
|
1283
1279
|
} catch (e) {
|
|
1284
1280
|
logger.error(e);
|
|
1285
1281
|
logger.error(chalk.red(`sandbox runner failed to start`));
|
package/docs/commands/if.mdx
CHANGED
|
@@ -5,7 +5,17 @@ description: "Comprehensive guide to installing and setting up TestDriver.ai for
|
|
|
5
5
|
icon: "file-code"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
# Download the VSCode Extension
|
|
9
|
+
|
|
10
|
+
The TestDriver.ai VSCode extension is available for download on our GitHub releases page. This extension integrates seamlessly with Visual Studio Code, allowing you to leverage the power of TestDriver.ai directly within your development environment.
|
|
11
|
+
|
|
12
|
+
<Card
|
|
13
|
+
title="Download the VSCode Extension"
|
|
14
|
+
icon="download"
|
|
15
|
+
href="https://github.com/testdriverai/vscode/releases"
|
|
16
|
+
>
|
|
17
|
+
Get the latest version of the TestDriver.ai VSCode extension from our GitHub releases page.
|
|
18
|
+
</Card>
|
|
9
19
|
|
|
10
20
|
# Install the extension
|
|
11
21
|
|
|
@@ -18,7 +28,7 @@ icon: "file-code"
|
|
|
18
28
|
|
|
19
29
|
# Try the Walkthrough
|
|
20
30
|
|
|
21
|
-
The extension should launch a walkthrough. If it does not, you can manually start it by running the command `TestDriver: Start Walkthrough` from the Command Palette (`Ctrl+Shift+P`).
|
|
31
|
+
The extension should launch a walkthrough. If it does not, you can manually start it by running the command `TestDriver: Start Setup Walkthrough` from the Command Palette (`Ctrl+Shift+P`).
|
|
22
32
|
|
|
23
33
|

|
|
24
34
|
|
package/electron/overlay.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
const { default: nodeIPC } = require("node-ipc");
|
|
2
|
-
const {
|
|
2
|
+
const {
|
|
3
|
+
app: electronApp,
|
|
4
|
+
remote,
|
|
5
|
+
screen,
|
|
6
|
+
BrowserWindow,
|
|
7
|
+
Tray,
|
|
8
|
+
Menu,
|
|
9
|
+
} = require("electron");
|
|
3
10
|
const { eventsArray } = require("../lib/events.js");
|
|
4
11
|
const config = require("../lib/config.js");
|
|
5
|
-
const path = require(
|
|
12
|
+
const path = require("path");
|
|
6
13
|
|
|
7
14
|
let tray = null;
|
|
8
15
|
|
|
@@ -22,22 +29,21 @@ ipc.config.retry = 0;
|
|
|
22
29
|
ipc.config.silent = true;
|
|
23
30
|
|
|
24
31
|
app.whenReady().then(() => {
|
|
25
|
-
|
|
26
32
|
// Path to tray icon (must be .ico on Windows, .png on Mac/Linux)
|
|
27
|
-
const iconPath = path.join(__dirname,
|
|
33
|
+
const iconPath = path.join(__dirname, "tray.png");
|
|
28
34
|
|
|
29
35
|
tray = new Tray(iconPath);
|
|
30
36
|
|
|
31
37
|
const contextMenu = Menu.buildFromTemplate([
|
|
32
38
|
{
|
|
33
|
-
label:
|
|
39
|
+
label: "Quit",
|
|
34
40
|
click: () => {
|
|
35
41
|
app.quit();
|
|
36
42
|
},
|
|
37
43
|
},
|
|
38
44
|
]);
|
|
39
45
|
|
|
40
|
-
tray.setToolTip(
|
|
46
|
+
tray.setToolTip("TestDriver.ai");
|
|
41
47
|
tray.setContextMenu(contextMenu);
|
|
42
48
|
|
|
43
49
|
app.dock?.hide();
|
|
@@ -92,8 +98,11 @@ app.whenReady().then(() => {
|
|
|
92
98
|
visibleOnFullScreen: true,
|
|
93
99
|
});
|
|
94
100
|
} else {
|
|
95
|
-
window.setContentSize(
|
|
96
|
-
|
|
101
|
+
window.setContentSize(
|
|
102
|
+
config.TD_VM_RESOLUTION[0],
|
|
103
|
+
config.TD_VM_RESOLUTION[1],
|
|
104
|
+
);
|
|
105
|
+
window.setBackgroundColor("#000");
|
|
97
106
|
}
|
|
98
107
|
|
|
99
108
|
window.loadFile("overlay.html");
|
package/lib/commands.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// the actual commands to interact with the system
|
|
2
2
|
const sdk = require("./sdk");
|
|
3
|
-
const vm = require(
|
|
3
|
+
const vm = require("vm");
|
|
4
4
|
const chalk = require("chalk");
|
|
5
5
|
const server = require("./ipc").server;
|
|
6
6
|
const {
|
|
@@ -21,8 +21,8 @@ const cliProgress = require("cli-progress");
|
|
|
21
21
|
const redraw = require("./redraw");
|
|
22
22
|
const sandbox = require("./sandbox.js");
|
|
23
23
|
const config = require("./config.js");
|
|
24
|
-
const util = require(
|
|
25
|
-
const exec = util.promisify(require(
|
|
24
|
+
const util = require("util");
|
|
25
|
+
const exec = util.promisify(require("child_process").exec);
|
|
26
26
|
let robot;
|
|
27
27
|
|
|
28
28
|
let keymap;
|
|
@@ -191,26 +191,38 @@ const scroll = async (direction = "down", amount = 300, method = "mouse") => {
|
|
|
191
191
|
switch (direction) {
|
|
192
192
|
case "up":
|
|
193
193
|
if (method === "mouse") {
|
|
194
|
-
config.TD_VM
|
|
194
|
+
config.TD_VM
|
|
195
|
+
? await sandbox.send({ type: "scroll", amount })
|
|
196
|
+
: await robot.scrollMouse(0, amount);
|
|
195
197
|
} else {
|
|
196
|
-
config.TD_VM
|
|
198
|
+
config.TD_VM
|
|
199
|
+
? await sandbox.send({ type: "press", keys: ["pageup"] })
|
|
200
|
+
: await robot.keyTap("pageup");
|
|
197
201
|
}
|
|
198
202
|
await redraw.wait(2500);
|
|
199
203
|
break;
|
|
200
204
|
case "down":
|
|
201
205
|
if (method === "mouse") {
|
|
202
|
-
config.TD_VM
|
|
206
|
+
config.TD_VM
|
|
207
|
+
? await sandbox.send({ type: "scroll", amount: amount * -1 })
|
|
208
|
+
: await robot.scrollMouse(0, amount * -1);
|
|
203
209
|
} else {
|
|
204
|
-
config.TD_VM
|
|
210
|
+
config.TD_VM
|
|
211
|
+
? await sandbox.send({ type: "press", keys: ["pagedown"] })
|
|
212
|
+
: await robot.keyTap("pagedown");
|
|
205
213
|
}
|
|
206
214
|
await redraw.wait(2500);
|
|
207
215
|
break;
|
|
208
216
|
case "left":
|
|
209
|
-
config.TD_VM
|
|
217
|
+
config.TD_VM
|
|
218
|
+
? console.log("Not Supported")
|
|
219
|
+
: await robot.scrollMouse(amount * -1, 0);
|
|
210
220
|
await redraw.wait(2500);
|
|
211
221
|
break;
|
|
212
222
|
case "right":
|
|
213
|
-
config.TD_VM
|
|
223
|
+
config.TD_VM
|
|
224
|
+
? console.log("Not Supported")
|
|
225
|
+
: await robot.scrollMouse(amount, 0);
|
|
214
226
|
await redraw.wait(2500);
|
|
215
227
|
break;
|
|
216
228
|
default:
|
|
@@ -223,65 +235,67 @@ const scroll = async (direction = "down", amount = 300, method = "mouse") => {
|
|
|
223
235
|
const click = async (x, y, action = "click") => {
|
|
224
236
|
await redraw.start();
|
|
225
237
|
|
|
226
|
-
let button =
|
|
238
|
+
let button = "left";
|
|
227
239
|
let double = false;
|
|
228
240
|
|
|
229
|
-
if (action === "right-click" && platform !== "darwin"
|
|
241
|
+
if (action === "right-click" && platform !== "darwin") {
|
|
230
242
|
button = "right";
|
|
231
243
|
}
|
|
232
244
|
if (action === "double-click") {
|
|
233
245
|
double = true;
|
|
234
246
|
}
|
|
235
247
|
|
|
236
|
-
logger.debug(
|
|
248
|
+
logger.debug(
|
|
249
|
+
chalk.dim(`${action} ${button} clicking at ${x}, ${y}...`),
|
|
250
|
+
true,
|
|
251
|
+
);
|
|
237
252
|
|
|
238
253
|
x = parseInt(x);
|
|
239
254
|
y = parseInt(y);
|
|
240
255
|
|
|
241
|
-
config.TD_VM
|
|
256
|
+
config.TD_VM
|
|
257
|
+
? await sandbox.send({ type: "moveMouse", x, y })
|
|
258
|
+
: await robot.moveMouseSmooth(x, y, 0.1);
|
|
242
259
|
emitter.emit(events.mouseMove, { x, y });
|
|
243
260
|
|
|
244
261
|
await delay(1000); // wait for the mouse to move
|
|
245
262
|
|
|
246
|
-
if (!config.TD_VM && platform()== "darwin" && action === "right-click") {
|
|
247
|
-
robot.keyToggle(
|
|
263
|
+
if (!config.TD_VM && platform() == "darwin" && action === "right-click") {
|
|
264
|
+
robot.keyToggle("control", "down", "control");
|
|
248
265
|
await delay(250);
|
|
249
266
|
}
|
|
250
267
|
|
|
251
268
|
if (action !== "hover") {
|
|
252
269
|
if (config.TD_VM) {
|
|
253
270
|
if (action === "click" || action === "left-click") {
|
|
254
|
-
await sandbox.send({type: "leftClick" })
|
|
271
|
+
await sandbox.send({ type: "leftClick" });
|
|
255
272
|
} else if (action === "right-click") {
|
|
256
|
-
await sandbox.send({type: "rightClick" })
|
|
273
|
+
await sandbox.send({ type: "rightClick" });
|
|
257
274
|
} else if (action === "middle-click") {
|
|
258
|
-
await sandbox.send({type: "middleClick" })
|
|
275
|
+
await sandbox.send({ type: "middleClick" });
|
|
259
276
|
} else if (action === "double-click") {
|
|
260
|
-
await sandbox.send({type: "doubleClick" })
|
|
261
|
-
}else if (action === "drag-start") {
|
|
262
|
-
await sandbox.send({type: "mousePress", button: "left" })
|
|
263
|
-
}else if (action === "drag-end") {
|
|
264
|
-
await sandbox.send({type: "mouseRelease", button: "left" })
|
|
277
|
+
await sandbox.send({ type: "doubleClick" });
|
|
278
|
+
} else if (action === "drag-start") {
|
|
279
|
+
await sandbox.send({ type: "mousePress", button: "left" });
|
|
280
|
+
} else if (action === "drag-end") {
|
|
281
|
+
await sandbox.send({ type: "mouseRelease", button: "left" });
|
|
265
282
|
}
|
|
266
283
|
} else {
|
|
267
|
-
|
|
268
284
|
if (action === "drag-start") {
|
|
269
285
|
robot.mouseToggle("down", button);
|
|
270
|
-
} else if(
|
|
286
|
+
} else if (action === "drag-end") {
|
|
271
287
|
robot.mouseToggle("up", button);
|
|
272
288
|
} else {
|
|
273
289
|
robot.mouseClick(button, double);
|
|
274
290
|
}
|
|
275
|
-
|
|
276
291
|
}
|
|
277
292
|
|
|
278
293
|
emitter.emit(events.mouseClick, { x, y, button, click });
|
|
279
|
-
|
|
280
294
|
}
|
|
281
295
|
|
|
282
|
-
if (!config.TD_VM && platform()== "darwin" && action === "right-click") {
|
|
296
|
+
if (!config.TD_VM && platform() == "darwin" && action === "right-click") {
|
|
283
297
|
await delay(250);
|
|
284
|
-
robot.keyToggle(
|
|
298
|
+
robot.keyToggle("control", "up", "control");
|
|
285
299
|
}
|
|
286
300
|
|
|
287
301
|
await redraw.wait(5000);
|
|
@@ -294,7 +308,7 @@ const hover = async (x, y) => {
|
|
|
294
308
|
x = parseInt(x);
|
|
295
309
|
y = parseInt(y);
|
|
296
310
|
|
|
297
|
-
await sandbox.send({type: "moveMouse", x, y });
|
|
311
|
+
await sandbox.send({ type: "moveMouse", x, y });
|
|
298
312
|
|
|
299
313
|
await redraw.wait(2500);
|
|
300
314
|
|
|
@@ -350,10 +364,7 @@ let commands = {
|
|
|
350
364
|
}
|
|
351
365
|
},
|
|
352
366
|
// uses our api to find all images on screen
|
|
353
|
-
"hover-image": async (
|
|
354
|
-
description,
|
|
355
|
-
action = "click",
|
|
356
|
-
) => {
|
|
367
|
+
"hover-image": async (description, action = "click") => {
|
|
357
368
|
// take a screenshot
|
|
358
369
|
logger.info("");
|
|
359
370
|
logger.info(chalk.dim("thinking..."), true);
|
|
@@ -384,10 +395,7 @@ let commands = {
|
|
|
384
395
|
return response.data;
|
|
385
396
|
}
|
|
386
397
|
},
|
|
387
|
-
"match-image": async (
|
|
388
|
-
relativePath,
|
|
389
|
-
action = "click"
|
|
390
|
-
) => {
|
|
398
|
+
"match-image": async (relativePath, action = "click") => {
|
|
391
399
|
let image = await captureScreenPNG();
|
|
392
400
|
|
|
393
401
|
let result = await findImageOnScreen(relativePath, image);
|
|
@@ -405,20 +413,18 @@ let commands = {
|
|
|
405
413
|
// type a string
|
|
406
414
|
type: async (string, delay = 500) => {
|
|
407
415
|
await redraw.start();
|
|
408
|
-
|
|
416
|
+
|
|
409
417
|
string = string.toString();
|
|
410
418
|
|
|
411
419
|
if (config.TD_VM) {
|
|
412
|
-
await sandbox.send({type: "write", text: string });
|
|
420
|
+
await sandbox.send({ type: "write", text: string });
|
|
413
421
|
} else {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
await robot.
|
|
420
|
-
else
|
|
421
|
-
await robot.typeString(string);
|
|
422
|
+
// there is a bug in robotjs that causes repeated characters to only be typed once
|
|
423
|
+
// so we need to check for repeated characters and type them slowly if so
|
|
424
|
+
const hasRepeatedChars = /(.)\1/.test(string);
|
|
425
|
+
if (delay > 0 && hasRepeatedChars)
|
|
426
|
+
await robot.typeStringDelayed(string, delay);
|
|
427
|
+
else await robot.typeString(string);
|
|
422
428
|
}
|
|
423
429
|
// await redraw.wait(5000);
|
|
424
430
|
return;
|
|
@@ -439,7 +445,7 @@ let commands = {
|
|
|
439
445
|
// remove any modifier keys from the inputKeys array and put them in a new array
|
|
440
446
|
inputKeys.forEach((key) => {
|
|
441
447
|
// change command to control on windows
|
|
442
|
-
if (key === "command" && platform()== "win32") {
|
|
448
|
+
if (key === "command" && platform() == "win32") {
|
|
443
449
|
key = "control";
|
|
444
450
|
}
|
|
445
451
|
|
|
@@ -467,7 +473,7 @@ let commands = {
|
|
|
467
473
|
|
|
468
474
|
// make sure modifier keys are valid, multiple are allowed
|
|
469
475
|
let modsToPress = [];
|
|
470
|
-
|
|
476
|
+
|
|
471
477
|
if (!config.TD_VM) {
|
|
472
478
|
modifierKeysPressed.map((key) => {
|
|
473
479
|
if (keymap[key] === undefined) {
|
|
@@ -476,10 +482,10 @@ let commands = {
|
|
|
476
482
|
} else {
|
|
477
483
|
return keymap[key];
|
|
478
484
|
}
|
|
479
|
-
});
|
|
485
|
+
});
|
|
480
486
|
robot.keyTap(keysPressed[0], modsToPress);
|
|
481
487
|
} else {
|
|
482
|
-
await sandbox.send({type: "press", keys: keysPressed });
|
|
488
|
+
await sandbox.send({ type: "press", keys: keysPressed });
|
|
483
489
|
}
|
|
484
490
|
|
|
485
491
|
// finally, press the keys
|
|
@@ -514,8 +520,11 @@ let commands = {
|
|
|
514
520
|
let passed = false;
|
|
515
521
|
|
|
516
522
|
while (durationPassed < timeout && !passed) {
|
|
517
|
-
|
|
518
|
-
|
|
523
|
+
passed = await assert(
|
|
524
|
+
`An image matching the description "${description}" appears on screen.`,
|
|
525
|
+
false,
|
|
526
|
+
false,
|
|
527
|
+
);
|
|
519
528
|
|
|
520
529
|
durationPassed = new Date().getTime() - startTime;
|
|
521
530
|
if (!passed) {
|
|
@@ -525,6 +534,7 @@ let commands = {
|
|
|
525
534
|
),
|
|
526
535
|
true,
|
|
527
536
|
);
|
|
537
|
+
await delay(2500);
|
|
528
538
|
}
|
|
529
539
|
}
|
|
530
540
|
|
|
@@ -568,14 +578,14 @@ let commands = {
|
|
|
568
578
|
|
|
569
579
|
passed = response.data;
|
|
570
580
|
durationPassed = new Date().getTime() - startTime;
|
|
571
|
-
if (!passed
|
|
581
|
+
if (!passed) {
|
|
572
582
|
logger.info(
|
|
573
583
|
chalk.dim(
|
|
574
584
|
`${niceSeconds(durationPassed)} seconds have passed without finding "${text}"`,
|
|
575
585
|
),
|
|
576
586
|
true,
|
|
577
587
|
);
|
|
578
|
-
await
|
|
588
|
+
await delay(2500);
|
|
579
589
|
}
|
|
580
590
|
}
|
|
581
591
|
|
|
@@ -594,7 +604,7 @@ let commands = {
|
|
|
594
604
|
direction = "down",
|
|
595
605
|
maxDistance = 1200,
|
|
596
606
|
textMatchMethod = "turbo",
|
|
597
|
-
method = "keyboard"
|
|
607
|
+
method = "keyboard",
|
|
598
608
|
) => {
|
|
599
609
|
await redraw.start();
|
|
600
610
|
|
|
@@ -602,18 +612,16 @@ let commands = {
|
|
|
602
612
|
|
|
603
613
|
if (method === "keyboard") {
|
|
604
614
|
try {
|
|
605
|
-
|
|
606
615
|
if (!config.TD_VM) {
|
|
607
|
-
await robot.keyTap("f", commandOrControl)
|
|
616
|
+
await robot.keyTap("f", commandOrControl);
|
|
608
617
|
robot.keyToggle(commandOrControl, "up");
|
|
609
618
|
await robot.typeStringDelayed(text, 500);
|
|
610
619
|
} else {
|
|
611
|
-
await sandbox.send({type: "press", keys: ["f", commandOrControl] })
|
|
612
|
-
await sandbox.send({type: "write", text });
|
|
620
|
+
await sandbox.send({ type: "press", keys: ["f", commandOrControl] });
|
|
621
|
+
await sandbox.send({ type: "write", text });
|
|
613
622
|
await redraw.wait(5000);
|
|
614
|
-
await sandbox.send({type: "press", keys: ["escape"] });
|
|
623
|
+
await sandbox.send({ type: "press", keys: ["escape"] });
|
|
615
624
|
}
|
|
616
|
-
|
|
617
625
|
} catch (e) {
|
|
618
626
|
logger.error("%s", e);
|
|
619
627
|
throw new AiError(
|
|
@@ -684,8 +692,11 @@ let commands = {
|
|
|
684
692
|
let passed = false;
|
|
685
693
|
|
|
686
694
|
while (scrollDistance <= maxDistance && !passed) {
|
|
687
|
-
|
|
688
|
-
|
|
695
|
+
passed = await assert(
|
|
696
|
+
`An image matching the description "${description}" appears on screen.`,
|
|
697
|
+
false,
|
|
698
|
+
false,
|
|
699
|
+
);
|
|
689
700
|
|
|
690
701
|
if (!passed) {
|
|
691
702
|
logger.info(
|
|
@@ -724,90 +735,99 @@ let commands = {
|
|
|
724
735
|
return await assert(assertion, true, async);
|
|
725
736
|
},
|
|
726
737
|
exec: async (language, mac_code, windows_code, linux_code) => {
|
|
727
|
-
|
|
728
|
-
logger.info(chalk.dim(`calling exec...`), true,);
|
|
738
|
+
logger.info(chalk.dim(`calling exec...`), true);
|
|
729
739
|
|
|
730
740
|
let plat = platform();
|
|
731
|
-
|
|
732
|
-
const scriptCode =
|
|
741
|
+
|
|
742
|
+
const scriptCode =
|
|
743
|
+
plat == "linux"
|
|
744
|
+
? linux_code
|
|
745
|
+
: plat == "windows"
|
|
746
|
+
? windows_code
|
|
747
|
+
: plat == "mac"
|
|
748
|
+
? mac_code
|
|
749
|
+
: (() => {
|
|
750
|
+
throw new AiError(`Unsupported plat: ${plat}`);
|
|
751
|
+
})();
|
|
733
752
|
|
|
734
753
|
if (!scriptCode) {
|
|
735
754
|
logger.warn(`No code provided for ${plat}`);
|
|
736
755
|
return;
|
|
737
756
|
}
|
|
738
757
|
|
|
739
|
-
if (language ==
|
|
740
|
-
|
|
741
|
-
logger.info(chalk.dim(`running in shell...`), true,);
|
|
758
|
+
if (language == "shell") {
|
|
759
|
+
logger.info(chalk.dim(`running in shell...`), true);
|
|
742
760
|
|
|
743
761
|
if (plat == "linux") {
|
|
744
|
-
|
|
745
762
|
if (config.TD_VM) {
|
|
746
|
-
|
|
747
|
-
logger.info(chalk.dim(`sending value of \`linux\` to vm...`), true,);
|
|
763
|
+
logger.info(chalk.dim(`sending value of \`linux\` to vm...`), true);
|
|
748
764
|
|
|
749
765
|
return await sandbox.send({
|
|
750
766
|
type: "commands.run",
|
|
751
767
|
command: linux_code,
|
|
752
768
|
});
|
|
753
|
-
|
|
754
769
|
} else {
|
|
755
|
-
|
|
756
770
|
if (!linux_code) {
|
|
757
771
|
throw new AiError(`No code provided for linux`, true);
|
|
758
772
|
}
|
|
759
773
|
|
|
760
|
-
logger.info(
|
|
774
|
+
logger.info(
|
|
775
|
+
chalk.dim(`running value of \`${plat}\` on this machine...`),
|
|
776
|
+
true,
|
|
777
|
+
);
|
|
761
778
|
return await exec(mac_code, { cwd: cwd() });
|
|
762
779
|
}
|
|
763
780
|
} else if (plat == "windows") {
|
|
764
|
-
logger.info(
|
|
781
|
+
logger.info(
|
|
782
|
+
chalk.dim(`running value of \`${plat}\` on this machine...`),
|
|
783
|
+
true,
|
|
784
|
+
);
|
|
765
785
|
return await exec(windows_code, { cwd: cwd() });
|
|
766
786
|
} else if (plat == "mac") {
|
|
767
|
-
logger.info(
|
|
787
|
+
logger.info(
|
|
788
|
+
chalk.dim(`running value of \`${plat}\` on this machine...`),
|
|
789
|
+
true,
|
|
790
|
+
);
|
|
768
791
|
return await exec(mac_code, { cwd: cwd() });
|
|
769
|
-
|
|
770
792
|
}
|
|
793
|
+
} else if (language == "js") {
|
|
794
|
+
logger.info(chalk.dim(`running js...`), true);
|
|
771
795
|
|
|
772
|
-
} else if (language == 'js') {
|
|
773
|
-
|
|
774
|
-
logger.info(chalk.dim(`running js...`), true,);
|
|
775
|
-
|
|
776
796
|
// must be assigned to `result`
|
|
777
797
|
// do not overwrite `result`
|
|
778
798
|
// must install locally via npm install
|
|
779
799
|
|
|
780
|
-
if (config.TD_VM) {
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
} else {
|
|
787
|
-
|
|
788
|
-
|
|
800
|
+
// if (config.TD_VM) {
|
|
801
|
+
// logger.info(chalk.dim(`running value of \`linux\` on vm...`), true);
|
|
802
|
+
// return await sandbox.send({
|
|
803
|
+
// type: "js.run",
|
|
804
|
+
// js: linux_code,
|
|
805
|
+
// });
|
|
806
|
+
// } else {
|
|
807
|
+
logger.info(
|
|
808
|
+
chalk.dim(`running value of \`${plat}\` in local JS vm...`),
|
|
809
|
+
true,
|
|
810
|
+
);
|
|
789
811
|
|
|
790
|
-
|
|
812
|
+
const context = vm.createContext({ require, console, fs, process });
|
|
791
813
|
|
|
792
|
-
|
|
814
|
+
const script = new vm.Script(`
|
|
793
815
|
(async () => {
|
|
794
816
|
${scriptCode}
|
|
795
817
|
})();
|
|
796
818
|
`);
|
|
797
819
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
// wait for context.result to resolve
|
|
801
|
-
const stepResult = await context.result;
|
|
820
|
+
await script.runInContext(context);
|
|
802
821
|
|
|
803
|
-
|
|
804
|
-
|
|
822
|
+
// wait for context.result to resolve
|
|
823
|
+
const stepResult = await context.result;
|
|
805
824
|
|
|
825
|
+
return stepResult;
|
|
826
|
+
// }
|
|
806
827
|
} else {
|
|
807
828
|
throw new AiError(`Language not supported: ${language}`);
|
|
808
829
|
}
|
|
809
|
-
|
|
810
|
-
}
|
|
830
|
+
},
|
|
811
831
|
};
|
|
812
832
|
|
|
813
833
|
module.exports = { commands, assert };
|