@midscene/cli 0.8.9 → 0.8.10-beta-20241225120902.0
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/dist/es/index.js +69 -419
- package/dist/lib/index.js +64 -413
- package/package.json +5 -5
package/dist/es/index.js
CHANGED
|
@@ -9934,7 +9934,7 @@ function renamed(from, to) {
|
|
|
9934
9934
|
throw new Error("Function yaml." + from + " is removed in js-yaml 4. Use yaml." + to + " instead, which is now safe by default.");
|
|
9935
9935
|
};
|
|
9936
9936
|
}
|
|
9937
|
-
var isNothing_1, isObject_1, toArray_1, repeat_1, isNegativeZero_1, extend_1, common, exception, snippet, TYPE_CONSTRUCTOR_OPTIONS, YAML_NODE_KINDS, type, schema, str, seq, map, failsafe, _null, bool, int, YAML_FLOAT_PATTERN, SCIENTIFIC_WITHOUT_DOT, float, json, core, YAML_DATE_REGEXP, YAML_TIMESTAMP_REGEXP, timestamp, merge, BASE64_MAP, binary, _hasOwnProperty$3, _toString$2, omap, _toString$1, pairs, _hasOwnProperty$2, set, _default, _hasOwnProperty$1, CONTEXT_FLOW_IN, CONTEXT_FLOW_OUT, CONTEXT_BLOCK_IN, CONTEXT_BLOCK_OUT, CHOMPING_CLIP, CHOMPING_STRIP, CHOMPING_KEEP, PATTERN_NON_PRINTABLE, PATTERN_NON_ASCII_LINE_BREAKS, PATTERN_FLOW_INDICATORS, PATTERN_TAG_HANDLE, PATTERN_TAG_URI, simpleEscapeCheck, simpleEscapeMap, i, directiveHandlers, loadAll_1, load_1, loader, _toString2, _hasOwnProperty, CHAR_BOM, CHAR_TAB, CHAR_LINE_FEED, CHAR_CARRIAGE_RETURN, CHAR_SPACE, CHAR_EXCLAMATION, CHAR_DOUBLE_QUOTE, CHAR_SHARP, CHAR_PERCENT, CHAR_AMPERSAND, CHAR_SINGLE_QUOTE, CHAR_ASTERISK, CHAR_COMMA, CHAR_MINUS, CHAR_COLON, CHAR_EQUALS, CHAR_GREATER_THAN, CHAR_QUESTION, CHAR_COMMERCIAL_AT, CHAR_LEFT_SQUARE_BRACKET, CHAR_RIGHT_SQUARE_BRACKET, CHAR_GRAVE_ACCENT, CHAR_LEFT_CURLY_BRACKET, CHAR_VERTICAL_LINE, CHAR_RIGHT_CURLY_BRACKET, ESCAPE_SEQUENCES, DEPRECATED_BOOLEANS_SYNTAX, DEPRECATED_BASE60_SYNTAX, QUOTING_TYPE_SINGLE, QUOTING_TYPE_DOUBLE, STYLE_PLAIN, STYLE_SINGLE, STYLE_LITERAL, STYLE_FOLDED, STYLE_DOUBLE, dump_1, dumper,
|
|
9937
|
+
var isNothing_1, isObject_1, toArray_1, repeat_1, isNegativeZero_1, extend_1, common, exception, snippet, TYPE_CONSTRUCTOR_OPTIONS, YAML_NODE_KINDS, type, schema, str, seq, map, failsafe, _null, bool, int, YAML_FLOAT_PATTERN, SCIENTIFIC_WITHOUT_DOT, float, json, core, YAML_DATE_REGEXP, YAML_TIMESTAMP_REGEXP, timestamp, merge, BASE64_MAP, binary, _hasOwnProperty$3, _toString$2, omap, _toString$1, pairs, _hasOwnProperty$2, set, _default, _hasOwnProperty$1, CONTEXT_FLOW_IN, CONTEXT_FLOW_OUT, CONTEXT_BLOCK_IN, CONTEXT_BLOCK_OUT, CHOMPING_CLIP, CHOMPING_STRIP, CHOMPING_KEEP, PATTERN_NON_PRINTABLE, PATTERN_NON_ASCII_LINE_BREAKS, PATTERN_FLOW_INDICATORS, PATTERN_TAG_HANDLE, PATTERN_TAG_URI, simpleEscapeCheck, simpleEscapeMap, i, directiveHandlers, loadAll_1, load_1, loader, _toString2, _hasOwnProperty, CHAR_BOM, CHAR_TAB, CHAR_LINE_FEED, CHAR_CARRIAGE_RETURN, CHAR_SPACE, CHAR_EXCLAMATION, CHAR_DOUBLE_QUOTE, CHAR_SHARP, CHAR_PERCENT, CHAR_AMPERSAND, CHAR_SINGLE_QUOTE, CHAR_ASTERISK, CHAR_COMMA, CHAR_MINUS, CHAR_COLON, CHAR_EQUALS, CHAR_GREATER_THAN, CHAR_QUESTION, CHAR_COMMERCIAL_AT, CHAR_LEFT_SQUARE_BRACKET, CHAR_RIGHT_SQUARE_BRACKET, CHAR_GRAVE_ACCENT, CHAR_LEFT_CURLY_BRACKET, CHAR_VERTICAL_LINE, CHAR_RIGHT_CURLY_BRACKET, ESCAPE_SEQUENCES, DEPRECATED_BOOLEANS_SYNTAX, DEPRECATED_BASE60_SYNTAX, QUOTING_TYPE_SINGLE, QUOTING_TYPE_DOUBLE, STYLE_PLAIN, STYLE_SINGLE, STYLE_LITERAL, STYLE_FOLDED, STYLE_DOUBLE, dump_1, dumper, load, loadAll, dump, safeLoad, safeLoadAll, safeDump;
|
|
9938
9938
|
var init_js_yaml = __esm({
|
|
9939
9939
|
"../../node_modules/.pnpm/js-yaml@4.1.0/node_modules/js-yaml/dist/js-yaml.mjs"() {
|
|
9940
9940
|
"use strict";
|
|
@@ -10336,51 +10336,12 @@ var init_js_yaml = __esm({
|
|
|
10336
10336
|
dumper = {
|
|
10337
10337
|
dump: dump_1
|
|
10338
10338
|
};
|
|
10339
|
-
Type = type;
|
|
10340
|
-
Schema = schema;
|
|
10341
|
-
FAILSAFE_SCHEMA = failsafe;
|
|
10342
|
-
JSON_SCHEMA = json;
|
|
10343
|
-
CORE_SCHEMA = core;
|
|
10344
|
-
DEFAULT_SCHEMA = _default;
|
|
10345
10339
|
load = loader.load;
|
|
10346
10340
|
loadAll = loader.loadAll;
|
|
10347
10341
|
dump = dumper.dump;
|
|
10348
|
-
YAMLException = exception;
|
|
10349
|
-
types2 = {
|
|
10350
|
-
binary,
|
|
10351
|
-
float,
|
|
10352
|
-
map,
|
|
10353
|
-
null: _null,
|
|
10354
|
-
pairs,
|
|
10355
|
-
set,
|
|
10356
|
-
timestamp,
|
|
10357
|
-
bool,
|
|
10358
|
-
int,
|
|
10359
|
-
merge,
|
|
10360
|
-
omap,
|
|
10361
|
-
seq,
|
|
10362
|
-
str
|
|
10363
|
-
};
|
|
10364
10342
|
safeLoad = renamed("safeLoad", "load");
|
|
10365
10343
|
safeLoadAll = renamed("safeLoadAll", "loadAll");
|
|
10366
10344
|
safeDump = renamed("safeDump", "dump");
|
|
10367
|
-
jsYaml = {
|
|
10368
|
-
Type,
|
|
10369
|
-
Schema,
|
|
10370
|
-
FAILSAFE_SCHEMA,
|
|
10371
|
-
JSON_SCHEMA,
|
|
10372
|
-
CORE_SCHEMA,
|
|
10373
|
-
DEFAULT_SCHEMA,
|
|
10374
|
-
load,
|
|
10375
|
-
loadAll,
|
|
10376
|
-
dump,
|
|
10377
|
-
YAMLException,
|
|
10378
|
-
types: types2,
|
|
10379
|
-
safeLoad,
|
|
10380
|
-
safeLoadAll,
|
|
10381
|
-
safeDump
|
|
10382
|
-
};
|
|
10383
|
-
js_yaml_default = jsYaml;
|
|
10384
10345
|
}
|
|
10385
10346
|
});
|
|
10386
10347
|
|
|
@@ -13189,19 +13150,19 @@ var require_build3 = __commonJS({
|
|
|
13189
13150
|
var require_sync = __commonJS({
|
|
13190
13151
|
"../../node_modules/.pnpm/escalade@3.2.0/node_modules/escalade/sync/index.js"(exports, module) {
|
|
13191
13152
|
"use strict";
|
|
13192
|
-
var { dirname:
|
|
13153
|
+
var { dirname: dirname2, resolve } = __require("path");
|
|
13193
13154
|
var { readdirSync: readdirSync2, statSync: statSync2 } = __require("fs");
|
|
13194
13155
|
module.exports = function(start, callback) {
|
|
13195
13156
|
let dir = resolve(".", start);
|
|
13196
13157
|
let tmp, stats = statSync2(dir);
|
|
13197
13158
|
if (!stats.isDirectory()) {
|
|
13198
|
-
dir =
|
|
13159
|
+
dir = dirname2(dir);
|
|
13199
13160
|
}
|
|
13200
13161
|
while (true) {
|
|
13201
13162
|
tmp = callback(dir, readdirSync2(dir));
|
|
13202
13163
|
if (tmp)
|
|
13203
13164
|
return resolve(dir, tmp);
|
|
13204
|
-
dir =
|
|
13165
|
+
dir = dirname2(tmp = dir);
|
|
13205
13166
|
if (tmp === dir)
|
|
13206
13167
|
break;
|
|
13207
13168
|
}
|
|
@@ -13238,9 +13199,9 @@ var require_require_directory = __commonJS({
|
|
|
13238
13199
|
"../../node_modules/.pnpm/require-directory@2.1.1/node_modules/require-directory/index.js"(exports, module) {
|
|
13239
13200
|
"use strict";
|
|
13240
13201
|
var fs = __require("fs");
|
|
13241
|
-
var
|
|
13202
|
+
var join2 = __require("path").join;
|
|
13242
13203
|
var resolve = __require("path").resolve;
|
|
13243
|
-
var
|
|
13204
|
+
var dirname2 = __require("path").dirname;
|
|
13244
13205
|
var defaultOptions = {
|
|
13245
13206
|
extensions: ["js", "json", "coffee"],
|
|
13246
13207
|
recurse: true,
|
|
@@ -13273,9 +13234,9 @@ var require_require_directory = __commonJS({
|
|
|
13273
13234
|
options[prop] = defaultOptions[prop];
|
|
13274
13235
|
}
|
|
13275
13236
|
}
|
|
13276
|
-
path2 = !path2 ?
|
|
13237
|
+
path2 = !path2 ? dirname2(m.filename) : resolve(dirname2(m.filename), path2);
|
|
13277
13238
|
fs.readdirSync(path2).forEach(function(filename) {
|
|
13278
|
-
var joined =
|
|
13239
|
+
var joined = join2(path2, filename), files, key, obj;
|
|
13279
13240
|
if (fs.statSync(joined).isDirectory() && options.recurse) {
|
|
13280
13241
|
files = requireDirectory(m, joined, options);
|
|
13281
13242
|
if (Object.keys(files).length) {
|
|
@@ -15050,7 +15011,7 @@ var require_package2 = __commonJS({
|
|
|
15050
15011
|
module.exports = {
|
|
15051
15012
|
name: "@midscene/cli",
|
|
15052
15013
|
description: "An AI-powered automation SDK can control the page, perform assertions, and extract data in JSON format using natural language. See https://midscenejs.com/ for details.",
|
|
15053
|
-
version: "0.8.
|
|
15014
|
+
version: "0.8.10-beta-20241225120902.0",
|
|
15054
15015
|
repository: "https://github.com/web-infra-dev/midscene",
|
|
15055
15016
|
homepage: "https://midscenejs.com/",
|
|
15056
15017
|
"jsnext:source": "./src/index.ts",
|
|
@@ -15072,8 +15033,8 @@ var require_package2 = __commonJS({
|
|
|
15072
15033
|
dependencies: {
|
|
15073
15034
|
"@midscene/core": "workspace:*",
|
|
15074
15035
|
"@midscene/web": "workspace:*",
|
|
15075
|
-
|
|
15076
|
-
|
|
15036
|
+
puppeteer: "23.0.2",
|
|
15037
|
+
"http-server": "14.1.1"
|
|
15077
15038
|
},
|
|
15078
15039
|
devDependencies: {
|
|
15079
15040
|
"@modern-js/module-tools": "2.60.6",
|
|
@@ -15093,7 +15054,7 @@ var require_package2 = __commonJS({
|
|
|
15093
15054
|
yargs: "17.7.2"
|
|
15094
15055
|
},
|
|
15095
15056
|
engines: {
|
|
15096
|
-
node: ">=
|
|
15057
|
+
node: ">=18.0.0"
|
|
15097
15058
|
},
|
|
15098
15059
|
publishConfig: {
|
|
15099
15060
|
access: "public",
|
|
@@ -15627,7 +15588,8 @@ var require_source = __commonJS({
|
|
|
15627
15588
|
|
|
15628
15589
|
// src/printer.ts
|
|
15629
15590
|
import { basename, dirname, relative } from "path";
|
|
15630
|
-
|
|
15591
|
+
import { flowItemBrief } from "@midscene/web";
|
|
15592
|
+
function indicatorForStatus(status) {
|
|
15631
15593
|
if (status === "init") {
|
|
15632
15594
|
return import_chalk.default.gray("◌");
|
|
15633
15595
|
}
|
|
@@ -15646,7 +15608,7 @@ function paddingLines(lines) {
|
|
|
15646
15608
|
return `${indent}${line}`;
|
|
15647
15609
|
});
|
|
15648
15610
|
}
|
|
15649
|
-
var import_chalk, isTTY, indent, spinnerInterval, spinnerFrames, currentSpinningFrame,
|
|
15611
|
+
var import_chalk, isTTY, indent, spinnerInterval, spinnerFrames, currentSpinningFrame, contextInfo, singleTaskInfo, contextTaskListSummary;
|
|
15650
15612
|
var init_printer = __esm({
|
|
15651
15613
|
"src/printer.ts"() {
|
|
15652
15614
|
"use strict";
|
|
@@ -15658,46 +15620,12 @@ var init_printer = __esm({
|
|
|
15658
15620
|
currentSpinningFrame = () => {
|
|
15659
15621
|
return spinnerFrames[Math.floor(Date.now() / spinnerInterval) % spinnerFrames.length];
|
|
15660
15622
|
};
|
|
15661
|
-
flowItemBrief = (flowItem) => {
|
|
15662
|
-
if (!flowItem) {
|
|
15663
|
-
return "";
|
|
15664
|
-
}
|
|
15665
|
-
const sliceText = (text) => {
|
|
15666
|
-
const lengthLimit = 60;
|
|
15667
|
-
if (text && text.length > lengthLimit) {
|
|
15668
|
-
return `${text.slice(0, lengthLimit)}...`;
|
|
15669
|
-
}
|
|
15670
|
-
return text || "";
|
|
15671
|
-
};
|
|
15672
|
-
if (flowItem.aiAction || flowItem.ai) {
|
|
15673
|
-
return `aiAction: ${sliceText(
|
|
15674
|
-
flowItem.aiActionProgressTip || flowItem.aiAction || flowItem.ai
|
|
15675
|
-
)}`;
|
|
15676
|
-
}
|
|
15677
|
-
if (flowItem.aiAssert) {
|
|
15678
|
-
return `aiAssert: ${sliceText(
|
|
15679
|
-
flowItem.aiAssert
|
|
15680
|
-
)}`;
|
|
15681
|
-
}
|
|
15682
|
-
if (flowItem.aiQuery) {
|
|
15683
|
-
return `aiQuery: ${sliceText(flowItem.aiQuery)}`;
|
|
15684
|
-
}
|
|
15685
|
-
if (flowItem.aiWaitFor) {
|
|
15686
|
-
return `aiWaitFor: ${sliceText(
|
|
15687
|
-
flowItem.aiWaitFor
|
|
15688
|
-
)}`;
|
|
15689
|
-
}
|
|
15690
|
-
if (flowItem.sleep) {
|
|
15691
|
-
return `sleep: ${flowItem.sleep}`;
|
|
15692
|
-
}
|
|
15693
|
-
return "";
|
|
15694
|
-
};
|
|
15695
15623
|
contextInfo = (context) => {
|
|
15696
15624
|
const filePath = context.file;
|
|
15697
15625
|
const fileName = basename(filePath);
|
|
15698
15626
|
const fileDir = dirname(filePath);
|
|
15699
15627
|
const fileNameToPrint = `${import_chalk.default.gray(`${fileDir}/`)}${fileName}`;
|
|
15700
|
-
const fileStatusText =
|
|
15628
|
+
const fileStatusText = indicatorForStatus(context.player.status);
|
|
15701
15629
|
const contextActionText = typeof context.player.currentTaskIndex === "undefined" && context.player.status === "running" ? import_chalk.default.gray("(navigating)") : "";
|
|
15702
15630
|
const outputFile = context.player.output;
|
|
15703
15631
|
const outputText = outputFile && Object.keys(context.player.result || {}).length > 0 ? `
|
|
@@ -15738,7 +15666,7 @@ ${indent}${import_chalk.default.gray(`report: ./${reportFileToShow}`)}` : "";
|
|
|
15738
15666
|
const errorText = task.status === "error" ? `
|
|
15739
15667
|
${indent}${import_chalk.default.gray("error:")}
|
|
15740
15668
|
${indent}${indent}${(_a4 = task.error) == null ? void 0 : _a4.message}` : "";
|
|
15741
|
-
const statusText =
|
|
15669
|
+
const statusText = indicatorForStatus(task.status);
|
|
15742
15670
|
const mergedLine = `${statusText} ${task.name} ${stepText}${errorText}`;
|
|
15743
15671
|
return {
|
|
15744
15672
|
nameText: task.name,
|
|
@@ -15748,12 +15676,12 @@ ${indent}${indent}${(_a4 = task.error) == null ? void 0 : _a4.message}` : "";
|
|
|
15748
15676
|
mergedLine
|
|
15749
15677
|
};
|
|
15750
15678
|
};
|
|
15751
|
-
contextTaskListSummary = (
|
|
15679
|
+
contextTaskListSummary = (taskStatusArray, context) => {
|
|
15752
15680
|
const prefixLines = [];
|
|
15753
15681
|
const currentLine = [];
|
|
15754
15682
|
const suffixText = [];
|
|
15755
15683
|
const { mergedText: fileInfo } = contextInfo(context);
|
|
15756
|
-
for (const task of
|
|
15684
|
+
for (const task of taskStatusArray) {
|
|
15757
15685
|
const { mergedLine } = singleTaskInfo(task);
|
|
15758
15686
|
if (context.player.status === "init") {
|
|
15759
15687
|
suffixText.push(mergedLine);
|
|
@@ -16319,47 +16247,58 @@ var init_tty_renderer = __esm({
|
|
|
16319
16247
|
}
|
|
16320
16248
|
});
|
|
16321
16249
|
|
|
16322
|
-
// src/yaml-
|
|
16250
|
+
// src/yaml-runner.ts
|
|
16251
|
+
import { readFileSync } from "fs";
|
|
16252
|
+
import { basename as basename2, extname } from "path";
|
|
16253
|
+
import { ScriptPlayer, parseYamlScript } from "@midscene/web";
|
|
16323
16254
|
import { createServer } from "http-server";
|
|
16324
|
-
import
|
|
16325
|
-
import
|
|
16326
|
-
import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
16327
|
-
import { basename as basename2, dirname as dirname2, extname, join as join2 } from "path";
|
|
16328
|
-
import { PuppeteerAgent } from "@midscene/web/puppeteer";
|
|
16329
|
-
import { paramStr, typeStr } from "@midscene/web/ui-utils";
|
|
16330
|
-
function loadYamlScript(content, filePath) {
|
|
16331
|
-
const obj = js_yaml_default.load(content);
|
|
16332
|
-
const pathTip = filePath ? `, failed to load ${filePath}` : "";
|
|
16333
|
-
assert2(obj.target, `property "target" is required in yaml script${pathTip}`);
|
|
16334
|
-
assert2(
|
|
16335
|
-
typeof obj.target === "object",
|
|
16336
|
-
`property "target" must be an object${pathTip}`
|
|
16337
|
-
);
|
|
16338
|
-
assert2(
|
|
16339
|
-
typeof obj.target.url === "string",
|
|
16340
|
-
`property "target.url" must be provided in yaml script: ${pathTip}`
|
|
16341
|
-
);
|
|
16342
|
-
assert2(obj.tasks, `property "tasks" is required in yaml script${pathTip}`);
|
|
16343
|
-
assert2(
|
|
16344
|
-
Array.isArray(obj.tasks),
|
|
16345
|
-
`property "tasks" must be an array${pathTip}`
|
|
16346
|
-
);
|
|
16347
|
-
return obj;
|
|
16348
|
-
}
|
|
16255
|
+
import { assert as assert2 } from "console";
|
|
16256
|
+
import { puppeteerAgentForTarget } from "@midscene/web/puppeteer";
|
|
16349
16257
|
function playYamlFiles(files, options) {
|
|
16350
16258
|
return __async(this, null, function* () {
|
|
16351
16259
|
const fileContextList = [];
|
|
16352
16260
|
for (const file of files) {
|
|
16353
|
-
const script =
|
|
16261
|
+
const script = parseYamlScript(readFileSync(file, "utf-8"), file);
|
|
16354
16262
|
const fileName = basename2(file, extname(file));
|
|
16355
|
-
const
|
|
16356
|
-
|
|
16357
|
-
|
|
16263
|
+
const preference = {
|
|
16264
|
+
headed: options == null ? void 0 : options.headed,
|
|
16265
|
+
keepWindow: options == null ? void 0 : options.keepWindow,
|
|
16266
|
+
testId: fileName
|
|
16267
|
+
};
|
|
16268
|
+
const player = new ScriptPlayer(
|
|
16269
|
+
script,
|
|
16270
|
+
(target) => __async(this, null, function* () {
|
|
16271
|
+
const freeFn = [];
|
|
16272
|
+
let localServer;
|
|
16273
|
+
let urlToVisit;
|
|
16274
|
+
assert2(typeof target.url === "string", "url is required");
|
|
16275
|
+
if (target.serve) {
|
|
16276
|
+
localServer = yield launchServer(target.serve);
|
|
16277
|
+
const serverAddress = localServer.server.address();
|
|
16278
|
+
freeFn.push({
|
|
16279
|
+
name: "local_server",
|
|
16280
|
+
fn: () => localServer == null ? void 0 : localServer.server.close()
|
|
16281
|
+
});
|
|
16282
|
+
if (target.url.startsWith("/")) {
|
|
16283
|
+
urlToVisit = `http://${serverAddress == null ? void 0 : serverAddress.address}:${serverAddress == null ? void 0 : serverAddress.port}${target.url}`;
|
|
16284
|
+
} else {
|
|
16285
|
+
urlToVisit = `http://${serverAddress == null ? void 0 : serverAddress.address}:${serverAddress == null ? void 0 : serverAddress.port}/${target.url}`;
|
|
16286
|
+
}
|
|
16287
|
+
target.url = urlToVisit;
|
|
16288
|
+
}
|
|
16289
|
+
const { agent, freeFn: newFreeFn } = yield puppeteerAgentForTarget(
|
|
16290
|
+
target,
|
|
16291
|
+
preference
|
|
16292
|
+
);
|
|
16293
|
+
freeFn.push(...newFreeFn);
|
|
16294
|
+
return { agent, freeFn };
|
|
16295
|
+
}),
|
|
16296
|
+
(taskStatus) => {
|
|
16358
16297
|
if (!isTTY) {
|
|
16359
16298
|
const { nameText } = singleTaskInfo(taskStatus);
|
|
16360
16299
|
}
|
|
16361
16300
|
}
|
|
16362
|
-
|
|
16301
|
+
);
|
|
16363
16302
|
fileContextList.push({ file, player });
|
|
16364
16303
|
}
|
|
16365
16304
|
if (isTTY) {
|
|
@@ -16367,7 +16306,7 @@ function playYamlFiles(files, options) {
|
|
|
16367
16306
|
const summary = [""];
|
|
16368
16307
|
for (const context of fileContextList) {
|
|
16369
16308
|
summary.push(
|
|
16370
|
-
contextTaskListSummary(context.player.
|
|
16309
|
+
contextTaskListSummary(context.player.taskStatusList, context)
|
|
16371
16310
|
);
|
|
16372
16311
|
}
|
|
16373
16312
|
summary.push("");
|
|
@@ -16389,25 +16328,21 @@ function playYamlFiles(files, options) {
|
|
|
16389
16328
|
const { mergedText } = contextInfo(context);
|
|
16390
16329
|
console.log(mergedText);
|
|
16391
16330
|
yield context.player.run();
|
|
16392
|
-
console.log(
|
|
16331
|
+
console.log(
|
|
16332
|
+
contextTaskListSummary(context.player.taskStatusList, context)
|
|
16333
|
+
);
|
|
16393
16334
|
}
|
|
16394
16335
|
}
|
|
16395
16336
|
const ifFail = fileContextList.some((task) => task.player.status === "error");
|
|
16396
16337
|
return !ifFail;
|
|
16397
16338
|
});
|
|
16398
16339
|
}
|
|
16399
|
-
var
|
|
16400
|
-
var
|
|
16401
|
-
"src/yaml-
|
|
16340
|
+
var launchServer, ttyRenderer;
|
|
16341
|
+
var init_yaml_runner = __esm({
|
|
16342
|
+
"src/yaml-runner.ts"() {
|
|
16402
16343
|
"use strict";
|
|
16403
|
-
init_js_yaml();
|
|
16404
16344
|
init_printer();
|
|
16405
16345
|
init_tty_renderer();
|
|
16406
|
-
defaultUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36";
|
|
16407
|
-
defaultViewportWidth = 1280;
|
|
16408
|
-
defaultViewportHeight = 960;
|
|
16409
|
-
defaultViewportScale = process.platform === "darwin" ? 2 : 1;
|
|
16410
|
-
defaultWaitForNetworkIdleTimeout = 10 * 1e3;
|
|
16411
16346
|
launchServer = (dir) => __async(void 0, null, function* () {
|
|
16412
16347
|
return new Promise((resolve, reject) => {
|
|
16413
16348
|
const server = createServer({
|
|
@@ -16418,291 +16353,6 @@ var init_yaml_player = __esm({
|
|
|
16418
16353
|
});
|
|
16419
16354
|
});
|
|
16420
16355
|
});
|
|
16421
|
-
ScriptPlayer = class {
|
|
16422
|
-
constructor(script, options) {
|
|
16423
|
-
this.script = script;
|
|
16424
|
-
this.options = options;
|
|
16425
|
-
__publicField(this, "currentTaskIndex");
|
|
16426
|
-
__publicField(this, "taskStatus", []);
|
|
16427
|
-
__publicField(this, "status", "init");
|
|
16428
|
-
__publicField(this, "reportFile");
|
|
16429
|
-
__publicField(this, "result");
|
|
16430
|
-
__publicField(this, "unnamedResultIndex", 0);
|
|
16431
|
-
__publicField(this, "output");
|
|
16432
|
-
__publicField(this, "errorInSetup");
|
|
16433
|
-
this.result = {};
|
|
16434
|
-
this.output = script.target.output;
|
|
16435
|
-
this.taskStatus = (script.tasks || []).map((task, taskIndex) => {
|
|
16436
|
-
var _a4;
|
|
16437
|
-
return __spreadProps(__spreadValues({}, task), {
|
|
16438
|
-
index: taskIndex,
|
|
16439
|
-
status: "init",
|
|
16440
|
-
totalSteps: ((_a4 = task.flow) == null ? void 0 : _a4.length) || 0
|
|
16441
|
-
});
|
|
16442
|
-
});
|
|
16443
|
-
}
|
|
16444
|
-
setPlayerStatus(status, error) {
|
|
16445
|
-
this.status = status;
|
|
16446
|
-
this.errorInSetup = error;
|
|
16447
|
-
}
|
|
16448
|
-
setTaskStatus(index, statusValue, error) {
|
|
16449
|
-
var _a4;
|
|
16450
|
-
this.taskStatus[index].status = statusValue;
|
|
16451
|
-
if (error) {
|
|
16452
|
-
this.taskStatus[index].error = error;
|
|
16453
|
-
}
|
|
16454
|
-
if ((_a4 = this.options) == null ? void 0 : _a4.onTaskStatusChange) {
|
|
16455
|
-
this.options.onTaskStatusChange(this.taskStatus[index]);
|
|
16456
|
-
}
|
|
16457
|
-
}
|
|
16458
|
-
setTaskIndex(taskIndex) {
|
|
16459
|
-
this.currentTaskIndex = taskIndex;
|
|
16460
|
-
}
|
|
16461
|
-
flushResult() {
|
|
16462
|
-
if (Object.keys(this.result).length && this.output) {
|
|
16463
|
-
const output = join2(process.cwd(), this.output);
|
|
16464
|
-
const outputDir = dirname2(output);
|
|
16465
|
-
if (!existsSync2(outputDir)) {
|
|
16466
|
-
mkdirSync(outputDir, { recursive: true });
|
|
16467
|
-
}
|
|
16468
|
-
writeFileSync(output, JSON.stringify(this.result, void 0, 2));
|
|
16469
|
-
}
|
|
16470
|
-
}
|
|
16471
|
-
playTask(_0, _1) {
|
|
16472
|
-
return __async(this, arguments, function* (taskStatus, {
|
|
16473
|
-
agent,
|
|
16474
|
-
browser,
|
|
16475
|
-
page
|
|
16476
|
-
}) {
|
|
16477
|
-
const { flow } = taskStatus;
|
|
16478
|
-
assert2(flow, "missing flow in task");
|
|
16479
|
-
for (const flowItemIndex in flow) {
|
|
16480
|
-
taskStatus.currentStep = Number.parseInt(flowItemIndex, 10);
|
|
16481
|
-
const flowItem = flow[flowItemIndex];
|
|
16482
|
-
if (flowItem.aiAction || flowItem.ai) {
|
|
16483
|
-
const actionTask = flowItem;
|
|
16484
|
-
const prompt = actionTask.aiAction || actionTask.ai;
|
|
16485
|
-
assert2(prompt, "missing prompt for ai (aiAction)");
|
|
16486
|
-
assert2(
|
|
16487
|
-
typeof prompt === "string",
|
|
16488
|
-
"prompt for aiAction must be a string"
|
|
16489
|
-
);
|
|
16490
|
-
yield agent.aiAction(prompt, {
|
|
16491
|
-
onTaskStart(task) {
|
|
16492
|
-
const tip = `${typeStr(task)} - ${paramStr(task)}`;
|
|
16493
|
-
flowItem.aiActionProgressTip = tip;
|
|
16494
|
-
}
|
|
16495
|
-
});
|
|
16496
|
-
} else if (flowItem.aiAssert) {
|
|
16497
|
-
const assertTask = flowItem;
|
|
16498
|
-
const prompt = assertTask.aiAssert;
|
|
16499
|
-
assert2(prompt, "missing prompt for aiAssert");
|
|
16500
|
-
assert2(
|
|
16501
|
-
typeof prompt === "string",
|
|
16502
|
-
"prompt for aiAssert must be a string"
|
|
16503
|
-
);
|
|
16504
|
-
yield agent.aiAssert(prompt);
|
|
16505
|
-
} else if (flowItem.aiQuery) {
|
|
16506
|
-
const queryTask = flowItem;
|
|
16507
|
-
const prompt = queryTask.aiQuery;
|
|
16508
|
-
assert2(prompt, "missing prompt for aiQuery");
|
|
16509
|
-
assert2(
|
|
16510
|
-
typeof prompt === "string",
|
|
16511
|
-
"prompt for aiQuery must be a string"
|
|
16512
|
-
);
|
|
16513
|
-
const queryResult = yield agent.aiQuery(prompt);
|
|
16514
|
-
const resultKey = queryTask.name || this.unnamedResultIndex++;
|
|
16515
|
-
if (this.result[resultKey]) {
|
|
16516
|
-
console.warn(
|
|
16517
|
-
`result key ${resultKey} already exists, will overwrite`
|
|
16518
|
-
);
|
|
16519
|
-
}
|
|
16520
|
-
this.result[resultKey] = queryResult;
|
|
16521
|
-
this.flushResult();
|
|
16522
|
-
} else if (flowItem.aiWaitFor) {
|
|
16523
|
-
const waitForTask = flowItem;
|
|
16524
|
-
const prompt = waitForTask.aiWaitFor;
|
|
16525
|
-
assert2(prompt, "missing prompt for aiWaitFor");
|
|
16526
|
-
assert2(
|
|
16527
|
-
typeof prompt === "string",
|
|
16528
|
-
"prompt for aiWaitFor must be a string"
|
|
16529
|
-
);
|
|
16530
|
-
const timeout = waitForTask.timeout;
|
|
16531
|
-
yield agent.aiWaitFor(prompt, { timeoutMs: timeout });
|
|
16532
|
-
} else if (flowItem.sleep) {
|
|
16533
|
-
const sleepTask = flowItem;
|
|
16534
|
-
const ms = sleepTask.sleep;
|
|
16535
|
-
assert2(
|
|
16536
|
-
ms && ms > 0,
|
|
16537
|
-
`ms for sleep must be greater than 0, but got ${ms}`
|
|
16538
|
-
);
|
|
16539
|
-
yield new Promise((resolve) => setTimeout(resolve, ms));
|
|
16540
|
-
} else {
|
|
16541
|
-
throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);
|
|
16542
|
-
}
|
|
16543
|
-
}
|
|
16544
|
-
this.reportFile = agent.reportFile;
|
|
16545
|
-
});
|
|
16546
|
-
}
|
|
16547
|
-
run() {
|
|
16548
|
-
return __async(this, null, function* () {
|
|
16549
|
-
var _a4, _b2, _c2, _d2, _e2, _f2;
|
|
16550
|
-
const { target, tasks } = this.script;
|
|
16551
|
-
this.setPlayerStatus("running");
|
|
16552
|
-
const ua = target.userAgent || defaultUA;
|
|
16553
|
-
let width = defaultViewportWidth;
|
|
16554
|
-
if (target.viewportWidth) {
|
|
16555
|
-
assert2(
|
|
16556
|
-
typeof target.viewportWidth === "number",
|
|
16557
|
-
"viewportWidth must be a number"
|
|
16558
|
-
);
|
|
16559
|
-
width = Number.parseInt(target.viewportWidth, 10);
|
|
16560
|
-
assert2(
|
|
16561
|
-
width > 0,
|
|
16562
|
-
`viewportWidth must be greater than 0, but got ${width}`
|
|
16563
|
-
);
|
|
16564
|
-
}
|
|
16565
|
-
let height = defaultViewportHeight;
|
|
16566
|
-
if (target.viewportHeight) {
|
|
16567
|
-
assert2(
|
|
16568
|
-
typeof target.viewportHeight === "number",
|
|
16569
|
-
"viewportHeight must be a number"
|
|
16570
|
-
);
|
|
16571
|
-
height = Number.parseInt(target.viewportHeight, 10);
|
|
16572
|
-
assert2(
|
|
16573
|
-
height > 0,
|
|
16574
|
-
`viewportHeight must be greater than 0, but got ${height}`
|
|
16575
|
-
);
|
|
16576
|
-
}
|
|
16577
|
-
let dpr = defaultViewportScale;
|
|
16578
|
-
if (target.viewportScale) {
|
|
16579
|
-
assert2(
|
|
16580
|
-
typeof target.viewportScale === "number",
|
|
16581
|
-
"viewportScale must be a number"
|
|
16582
|
-
);
|
|
16583
|
-
dpr = Number.parseInt(target.viewportScale, 10);
|
|
16584
|
-
assert2(dpr > 0, `viewportScale must be greater than 0, but got ${dpr}`);
|
|
16585
|
-
}
|
|
16586
|
-
const viewportConfig = {
|
|
16587
|
-
width,
|
|
16588
|
-
height,
|
|
16589
|
-
deviceScaleFactor: dpr
|
|
16590
|
-
};
|
|
16591
|
-
const freeFn = [];
|
|
16592
|
-
let localServer;
|
|
16593
|
-
let urlToVisit;
|
|
16594
|
-
assert2(typeof target.url === "string", "url is required");
|
|
16595
|
-
if (target.serve) {
|
|
16596
|
-
localServer = yield launchServer(target.serve);
|
|
16597
|
-
const serverAddress = localServer.server.address();
|
|
16598
|
-
freeFn.push({
|
|
16599
|
-
name: "local_server",
|
|
16600
|
-
fn: () => localServer == null ? void 0 : localServer.server.close()
|
|
16601
|
-
});
|
|
16602
|
-
if (target.url.startsWith("/")) {
|
|
16603
|
-
urlToVisit = `http://${serverAddress == null ? void 0 : serverAddress.address}:${serverAddress == null ? void 0 : serverAddress.port}${target.url}`;
|
|
16604
|
-
} else {
|
|
16605
|
-
urlToVisit = `http://${serverAddress == null ? void 0 : serverAddress.address}:${serverAddress == null ? void 0 : serverAddress.port}/${target.url}`;
|
|
16606
|
-
}
|
|
16607
|
-
} else {
|
|
16608
|
-
urlToVisit = target.url;
|
|
16609
|
-
}
|
|
16610
|
-
const headed = ((_a4 = this.options) == null ? void 0 : _a4.headed) || ((_b2 = this.options) == null ? void 0 : _b2.keepWindow);
|
|
16611
|
-
if (headed && process.env.CI === "1") {
|
|
16612
|
-
console.warn(
|
|
16613
|
-
"you are probably running headed mode in CI, this will usually fail."
|
|
16614
|
-
);
|
|
16615
|
-
}
|
|
16616
|
-
const browser = yield puppeteer.launch({
|
|
16617
|
-
headless: !headed,
|
|
16618
|
-
args: [
|
|
16619
|
-
"--no-sandbox",
|
|
16620
|
-
"--disable-setuid-sandbox",
|
|
16621
|
-
"--disable-features=PasswordLeakDetection",
|
|
16622
|
-
"--disable-save-password-bubble"
|
|
16623
|
-
]
|
|
16624
|
-
});
|
|
16625
|
-
freeFn.push({
|
|
16626
|
-
name: "puppeteer_browser",
|
|
16627
|
-
fn: () => {
|
|
16628
|
-
var _a5;
|
|
16629
|
-
if (!((_a5 = this.options) == null ? void 0 : _a5.keepWindow)) {
|
|
16630
|
-
browser.close();
|
|
16631
|
-
}
|
|
16632
|
-
}
|
|
16633
|
-
});
|
|
16634
|
-
const pages = yield browser.pages();
|
|
16635
|
-
const page = pages[0];
|
|
16636
|
-
yield page.setUserAgent(ua);
|
|
16637
|
-
yield page.setViewport(viewportConfig);
|
|
16638
|
-
if (target.cookie) {
|
|
16639
|
-
const cookieFileContent = readFileSync(target.cookie, "utf-8");
|
|
16640
|
-
yield page.setCookie(...JSON.parse(cookieFileContent));
|
|
16641
|
-
}
|
|
16642
|
-
yield page.goto(urlToVisit);
|
|
16643
|
-
const waitForNetworkIdleTimeout = typeof ((_c2 = target.waitForNetworkIdle) == null ? void 0 : _c2.timeout) === "number" ? target.waitForNetworkIdle.timeout : defaultWaitForNetworkIdleTimeout;
|
|
16644
|
-
try {
|
|
16645
|
-
if (waitForNetworkIdleTimeout > 0) {
|
|
16646
|
-
yield page.waitForNetworkIdle({
|
|
16647
|
-
timeout: waitForNetworkIdleTimeout
|
|
16648
|
-
});
|
|
16649
|
-
}
|
|
16650
|
-
} catch (e) {
|
|
16651
|
-
if (typeof ((_d2 = target.waitForNetworkIdle) == null ? void 0 : _d2.continueOnNetworkIdleError) === "boolean" && !((_e2 = target.waitForNetworkIdle) == null ? void 0 : _e2.continueOnNetworkIdleError)) {
|
|
16652
|
-
const newError = new Error(`failed to wait for network idle: ${e}`, {
|
|
16653
|
-
cause: e
|
|
16654
|
-
});
|
|
16655
|
-
this.setPlayerStatus("error", newError);
|
|
16656
|
-
return;
|
|
16657
|
-
}
|
|
16658
|
-
const newMessage = `failed to wait for network idle after ${waitForNetworkIdleTimeout}ms, but the script will continue.`;
|
|
16659
|
-
console.warn(newMessage);
|
|
16660
|
-
}
|
|
16661
|
-
const agent = new PuppeteerAgent(page, {
|
|
16662
|
-
autoPrintReportMsg: false,
|
|
16663
|
-
testId: (_f2 = this.options) == null ? void 0 : _f2.testId
|
|
16664
|
-
});
|
|
16665
|
-
freeFn.push({
|
|
16666
|
-
name: "midscene_puppeteer_agent",
|
|
16667
|
-
fn: () => agent.destroy()
|
|
16668
|
-
});
|
|
16669
|
-
let taskIndex = 0;
|
|
16670
|
-
this.setPlayerStatus("running");
|
|
16671
|
-
let errorFlag = false;
|
|
16672
|
-
while (taskIndex < tasks.length) {
|
|
16673
|
-
const task = tasks[taskIndex];
|
|
16674
|
-
this.setTaskStatus(taskIndex, "running");
|
|
16675
|
-
try {
|
|
16676
|
-
this.setTaskIndex(taskIndex);
|
|
16677
|
-
yield this.playTask(this.taskStatus[taskIndex], {
|
|
16678
|
-
agent,
|
|
16679
|
-
browser,
|
|
16680
|
-
page
|
|
16681
|
-
});
|
|
16682
|
-
} catch (e) {
|
|
16683
|
-
this.setTaskStatus(taskIndex, "error", e);
|
|
16684
|
-
this.setPlayerStatus("error");
|
|
16685
|
-
errorFlag = true;
|
|
16686
|
-
this.reportFile = agent.reportFile;
|
|
16687
|
-
taskIndex++;
|
|
16688
|
-
continue;
|
|
16689
|
-
}
|
|
16690
|
-
this.reportFile = agent.reportFile;
|
|
16691
|
-
this.setTaskStatus(taskIndex, "done");
|
|
16692
|
-
taskIndex++;
|
|
16693
|
-
}
|
|
16694
|
-
if (!errorFlag) {
|
|
16695
|
-
this.setPlayerStatus("done");
|
|
16696
|
-
}
|
|
16697
|
-
freeFn.forEach((fn) => {
|
|
16698
|
-
try {
|
|
16699
|
-
fn.fn();
|
|
16700
|
-
} catch (e) {
|
|
16701
|
-
}
|
|
16702
|
-
});
|
|
16703
|
-
});
|
|
16704
|
-
}
|
|
16705
|
-
};
|
|
16706
16356
|
}
|
|
16707
16357
|
});
|
|
16708
16358
|
|
|
@@ -16711,7 +16361,7 @@ var require_src = __commonJS({
|
|
|
16711
16361
|
"src/index.ts"(exports) {
|
|
16712
16362
|
init_config();
|
|
16713
16363
|
init_cli_utils();
|
|
16714
|
-
|
|
16364
|
+
init_yaml_runner();
|
|
16715
16365
|
Promise.resolve(
|
|
16716
16366
|
(() => __async(exports, null, function* () {
|
|
16717
16367
|
const { options, path: path2 } = yield parseProcessArgs();
|
package/dist/lib/index.js
CHANGED
|
@@ -3711,19 +3711,19 @@ var require_build3 = __commonJS({
|
|
|
3711
3711
|
var require_sync = __commonJS({
|
|
3712
3712
|
"../../node_modules/.pnpm/escalade@3.2.0/node_modules/escalade/sync/index.js"(exports2, module2) {
|
|
3713
3713
|
"use strict";
|
|
3714
|
-
var { dirname:
|
|
3714
|
+
var { dirname: dirname2, resolve } = require("path");
|
|
3715
3715
|
var { readdirSync: readdirSync2, statSync: statSync2 } = require("fs");
|
|
3716
3716
|
module2.exports = function(start, callback) {
|
|
3717
3717
|
let dir = resolve(".", start);
|
|
3718
3718
|
let tmp, stats = statSync2(dir);
|
|
3719
3719
|
if (!stats.isDirectory()) {
|
|
3720
|
-
dir =
|
|
3720
|
+
dir = dirname2(dir);
|
|
3721
3721
|
}
|
|
3722
3722
|
while (true) {
|
|
3723
3723
|
tmp = callback(dir, readdirSync2(dir));
|
|
3724
3724
|
if (tmp)
|
|
3725
3725
|
return resolve(dir, tmp);
|
|
3726
|
-
dir =
|
|
3726
|
+
dir = dirname2(tmp = dir);
|
|
3727
3727
|
if (tmp === dir)
|
|
3728
3728
|
break;
|
|
3729
3729
|
}
|
|
@@ -3760,9 +3760,9 @@ var require_require_directory = __commonJS({
|
|
|
3760
3760
|
"../../node_modules/.pnpm/require-directory@2.1.1/node_modules/require-directory/index.js"(exports2, module2) {
|
|
3761
3761
|
"use strict";
|
|
3762
3762
|
var fs = require("fs");
|
|
3763
|
-
var
|
|
3763
|
+
var join2 = require("path").join;
|
|
3764
3764
|
var resolve = require("path").resolve;
|
|
3765
|
-
var
|
|
3765
|
+
var dirname2 = require("path").dirname;
|
|
3766
3766
|
var defaultOptions = {
|
|
3767
3767
|
extensions: ["js", "json", "coffee"],
|
|
3768
3768
|
recurse: true,
|
|
@@ -3795,9 +3795,9 @@ var require_require_directory = __commonJS({
|
|
|
3795
3795
|
options[prop] = defaultOptions[prop];
|
|
3796
3796
|
}
|
|
3797
3797
|
}
|
|
3798
|
-
path2 = !path2 ?
|
|
3798
|
+
path2 = !path2 ? dirname2(m.filename) : resolve(dirname2(m.filename), path2);
|
|
3799
3799
|
fs.readdirSync(path2).forEach(function(filename) {
|
|
3800
|
-
var joined =
|
|
3800
|
+
var joined = join2(path2, filename), files, key, obj;
|
|
3801
3801
|
if (fs.statSync(joined).isDirectory() && options.recurse) {
|
|
3802
3802
|
files = requireDirectory(m, joined, options);
|
|
3803
3803
|
if (Object.keys(files).length) {
|
|
@@ -5556,7 +5556,7 @@ var require_package2 = __commonJS({
|
|
|
5556
5556
|
module2.exports = {
|
|
5557
5557
|
name: "@midscene/cli",
|
|
5558
5558
|
description: "An AI-powered automation SDK can control the page, perform assertions, and extract data in JSON format using natural language. See https://midscenejs.com/ for details.",
|
|
5559
|
-
version: "0.8.
|
|
5559
|
+
version: "0.8.10-beta-20241225120902.0",
|
|
5560
5560
|
repository: "https://github.com/web-infra-dev/midscene",
|
|
5561
5561
|
homepage: "https://midscenejs.com/",
|
|
5562
5562
|
"jsnext:source": "./src/index.ts",
|
|
@@ -5578,8 +5578,8 @@ var require_package2 = __commonJS({
|
|
|
5578
5578
|
dependencies: {
|
|
5579
5579
|
"@midscene/core": "workspace:*",
|
|
5580
5580
|
"@midscene/web": "workspace:*",
|
|
5581
|
-
|
|
5582
|
-
|
|
5581
|
+
puppeteer: "23.0.2",
|
|
5582
|
+
"http-server": "14.1.1"
|
|
5583
5583
|
},
|
|
5584
5584
|
devDependencies: {
|
|
5585
5585
|
"@modern-js/module-tools": "2.60.6",
|
|
@@ -5599,7 +5599,7 @@ var require_package2 = __commonJS({
|
|
|
5599
5599
|
yargs: "17.7.2"
|
|
5600
5600
|
},
|
|
5601
5601
|
engines: {
|
|
5602
|
-
node: ">=
|
|
5602
|
+
node: ">=18.0.0"
|
|
5603
5603
|
},
|
|
5604
5604
|
publishConfig: {
|
|
5605
5605
|
access: "public",
|
|
@@ -15379,51 +15379,12 @@ function renamed(from, to) {
|
|
|
15379
15379
|
throw new Error("Function yaml." + from + " is removed in js-yaml 4. Use yaml." + to + " instead, which is now safe by default.");
|
|
15380
15380
|
};
|
|
15381
15381
|
}
|
|
15382
|
-
var Type = type;
|
|
15383
|
-
var Schema = schema;
|
|
15384
|
-
var FAILSAFE_SCHEMA = failsafe;
|
|
15385
|
-
var JSON_SCHEMA = json;
|
|
15386
|
-
var CORE_SCHEMA = core;
|
|
15387
|
-
var DEFAULT_SCHEMA = _default;
|
|
15388
15382
|
var load = loader.load;
|
|
15389
15383
|
var loadAll = loader.loadAll;
|
|
15390
15384
|
var dump = dumper.dump;
|
|
15391
|
-
var YAMLException = exception;
|
|
15392
|
-
var types2 = {
|
|
15393
|
-
binary,
|
|
15394
|
-
float,
|
|
15395
|
-
map,
|
|
15396
|
-
null: _null,
|
|
15397
|
-
pairs,
|
|
15398
|
-
set,
|
|
15399
|
-
timestamp,
|
|
15400
|
-
bool,
|
|
15401
|
-
int,
|
|
15402
|
-
merge,
|
|
15403
|
-
omap,
|
|
15404
|
-
seq,
|
|
15405
|
-
str
|
|
15406
|
-
};
|
|
15407
15385
|
var safeLoad = renamed("safeLoad", "load");
|
|
15408
15386
|
var safeLoadAll = renamed("safeLoadAll", "loadAll");
|
|
15409
15387
|
var safeDump = renamed("safeDump", "dump");
|
|
15410
|
-
var jsYaml = {
|
|
15411
|
-
Type,
|
|
15412
|
-
Schema,
|
|
15413
|
-
FAILSAFE_SCHEMA,
|
|
15414
|
-
JSON_SCHEMA,
|
|
15415
|
-
CORE_SCHEMA,
|
|
15416
|
-
DEFAULT_SCHEMA,
|
|
15417
|
-
load,
|
|
15418
|
-
loadAll,
|
|
15419
|
-
dump,
|
|
15420
|
-
YAMLException,
|
|
15421
|
-
types: types2,
|
|
15422
|
-
safeLoad,
|
|
15423
|
-
safeLoadAll,
|
|
15424
|
-
safeDump
|
|
15425
|
-
};
|
|
15426
|
-
var js_yaml_default = jsYaml;
|
|
15427
15388
|
|
|
15428
15389
|
// ../../node_modules/.pnpm/yargs@17.7.2/node_modules/yargs/yargs.mjs
|
|
15429
15390
|
var import_build = __toESM(require_build4(), 1);
|
|
@@ -15475,17 +15436,15 @@ function matchYamlFiles(fileGlob) {
|
|
|
15475
15436
|
});
|
|
15476
15437
|
}
|
|
15477
15438
|
|
|
15478
|
-
// src/yaml-
|
|
15479
|
-
var import_http_server = require("http-server");
|
|
15480
|
-
var import_puppeteer = __toESM(require("puppeteer"));
|
|
15481
|
-
var import_node_assert2 = __toESM(require("assert"));
|
|
15439
|
+
// src/yaml-runner.ts
|
|
15482
15440
|
var import_node_fs3 = require("fs");
|
|
15483
15441
|
var import_node_path4 = require("path");
|
|
15484
|
-
var
|
|
15485
|
-
var
|
|
15442
|
+
var import_web2 = require("@midscene/web");
|
|
15443
|
+
var import_http_server = require("http-server");
|
|
15486
15444
|
|
|
15487
15445
|
// src/printer.ts
|
|
15488
15446
|
var import_node_path3 = require("path");
|
|
15447
|
+
var import_web = require("@midscene/web");
|
|
15489
15448
|
var import_chalk = __toESM(require_source());
|
|
15490
15449
|
var isTTY = process.env.MIDSCENE_CLI_LOG_ON_NON_TTY ? false : process.stdout.isTTY;
|
|
15491
15450
|
var indent = " ";
|
|
@@ -15494,41 +15453,7 @@ var spinnerFrames = ["◰", "◳", "◲", "◱"];
|
|
|
15494
15453
|
var currentSpinningFrame = () => {
|
|
15495
15454
|
return spinnerFrames[Math.floor(Date.now() / spinnerInterval) % spinnerFrames.length];
|
|
15496
15455
|
};
|
|
15497
|
-
|
|
15498
|
-
if (!flowItem) {
|
|
15499
|
-
return "";
|
|
15500
|
-
}
|
|
15501
|
-
const sliceText = (text) => {
|
|
15502
|
-
const lengthLimit = 60;
|
|
15503
|
-
if (text && text.length > lengthLimit) {
|
|
15504
|
-
return `${text.slice(0, lengthLimit)}...`;
|
|
15505
|
-
}
|
|
15506
|
-
return text || "";
|
|
15507
|
-
};
|
|
15508
|
-
if (flowItem.aiAction || flowItem.ai) {
|
|
15509
|
-
return `aiAction: ${sliceText(
|
|
15510
|
-
flowItem.aiActionProgressTip || flowItem.aiAction || flowItem.ai
|
|
15511
|
-
)}`;
|
|
15512
|
-
}
|
|
15513
|
-
if (flowItem.aiAssert) {
|
|
15514
|
-
return `aiAssert: ${sliceText(
|
|
15515
|
-
flowItem.aiAssert
|
|
15516
|
-
)}`;
|
|
15517
|
-
}
|
|
15518
|
-
if (flowItem.aiQuery) {
|
|
15519
|
-
return `aiQuery: ${sliceText(flowItem.aiQuery)}`;
|
|
15520
|
-
}
|
|
15521
|
-
if (flowItem.aiWaitFor) {
|
|
15522
|
-
return `aiWaitFor: ${sliceText(
|
|
15523
|
-
flowItem.aiWaitFor
|
|
15524
|
-
)}`;
|
|
15525
|
-
}
|
|
15526
|
-
if (flowItem.sleep) {
|
|
15527
|
-
return `sleep: ${flowItem.sleep}`;
|
|
15528
|
-
}
|
|
15529
|
-
return "";
|
|
15530
|
-
};
|
|
15531
|
-
function textForStatus(status) {
|
|
15456
|
+
function indicatorForStatus(status) {
|
|
15532
15457
|
if (status === "init") {
|
|
15533
15458
|
return import_chalk.default.gray("◌");
|
|
15534
15459
|
}
|
|
@@ -15547,7 +15472,7 @@ var contextInfo = (context) => {
|
|
|
15547
15472
|
const fileName = (0, import_node_path3.basename)(filePath);
|
|
15548
15473
|
const fileDir = (0, import_node_path3.dirname)(filePath);
|
|
15549
15474
|
const fileNameToPrint = `${import_chalk.default.gray(`${fileDir}/`)}${fileName}`;
|
|
15550
|
-
const fileStatusText =
|
|
15475
|
+
const fileStatusText = indicatorForStatus(context.player.status);
|
|
15551
15476
|
const contextActionText = typeof context.player.currentTaskIndex === "undefined" && context.player.status === "running" ? import_chalk.default.gray("(navigating)") : "";
|
|
15552
15477
|
const outputFile = context.player.output;
|
|
15553
15478
|
const outputText = outputFile && Object.keys(context.player.result || {}).length > 0 ? `
|
|
@@ -15576,7 +15501,7 @@ var singleTaskInfo = (task) => {
|
|
|
15576
15501
|
stepText = import_chalk.default.gray("(navigating)");
|
|
15577
15502
|
} else if (typeof task.currentStep === "number") {
|
|
15578
15503
|
const currentFlowItem = task.flow[task.currentStep];
|
|
15579
|
-
const taskBrief = currentFlowItem && flowItemBrief(currentFlowItem);
|
|
15504
|
+
const taskBrief = currentFlowItem && (0, import_web.flowItemBrief)(currentFlowItem);
|
|
15580
15505
|
const actionText = taskBrief ? `, ${taskBrief}` : "";
|
|
15581
15506
|
stepText = import_chalk.default.gray(
|
|
15582
15507
|
`(step ${task.currentStep + 1}/${task.totalSteps}${actionText})`.trim()
|
|
@@ -15588,7 +15513,7 @@ var singleTaskInfo = (task) => {
|
|
|
15588
15513
|
const errorText = task.status === "error" ? `
|
|
15589
15514
|
${indent}${import_chalk.default.gray("error:")}
|
|
15590
15515
|
${indent}${indent}${(_a4 = task.error) == null ? void 0 : _a4.message}` : "";
|
|
15591
|
-
const statusText =
|
|
15516
|
+
const statusText = indicatorForStatus(task.status);
|
|
15592
15517
|
const mergedLine = `${statusText} ${task.name} ${stepText}${errorText}`;
|
|
15593
15518
|
return {
|
|
15594
15519
|
nameText: task.name,
|
|
@@ -15603,12 +15528,12 @@ function paddingLines(lines) {
|
|
|
15603
15528
|
return `${indent}${line}`;
|
|
15604
15529
|
});
|
|
15605
15530
|
}
|
|
15606
|
-
var contextTaskListSummary = (
|
|
15531
|
+
var contextTaskListSummary = (taskStatusArray, context) => {
|
|
15607
15532
|
const prefixLines = [];
|
|
15608
15533
|
const currentLine = [];
|
|
15609
15534
|
const suffixText = [];
|
|
15610
15535
|
const { mergedText: fileInfo } = contextInfo(context);
|
|
15611
|
-
for (const task of
|
|
15536
|
+
for (const task of taskStatusArray) {
|
|
15612
15537
|
const { mergedLine } = singleTaskInfo(task);
|
|
15613
15538
|
if (context.player.status === "init") {
|
|
15614
15539
|
suffixText.push(mergedLine);
|
|
@@ -16130,31 +16055,9 @@ function getRenderedRowCount(contents, stream2) {
|
|
|
16130
16055
|
return count;
|
|
16131
16056
|
}
|
|
16132
16057
|
|
|
16133
|
-
// src/yaml-
|
|
16134
|
-
var
|
|
16135
|
-
var
|
|
16136
|
-
var defaultViewportHeight = 960;
|
|
16137
|
-
var defaultViewportScale = process.platform === "darwin" ? 2 : 1;
|
|
16138
|
-
var defaultWaitForNetworkIdleTimeout = 10 * 1e3;
|
|
16139
|
-
function loadYamlScript(content, filePath) {
|
|
16140
|
-
const obj = js_yaml_default.load(content);
|
|
16141
|
-
const pathTip = filePath ? `, failed to load ${filePath}` : "";
|
|
16142
|
-
(0, import_node_assert2.default)(obj.target, `property "target" is required in yaml script${pathTip}`);
|
|
16143
|
-
(0, import_node_assert2.default)(
|
|
16144
|
-
typeof obj.target === "object",
|
|
16145
|
-
`property "target" must be an object${pathTip}`
|
|
16146
|
-
);
|
|
16147
|
-
(0, import_node_assert2.default)(
|
|
16148
|
-
typeof obj.target.url === "string",
|
|
16149
|
-
`property "target.url" must be provided in yaml script: ${pathTip}`
|
|
16150
|
-
);
|
|
16151
|
-
(0, import_node_assert2.default)(obj.tasks, `property "tasks" is required in yaml script${pathTip}`);
|
|
16152
|
-
(0, import_node_assert2.default)(
|
|
16153
|
-
Array.isArray(obj.tasks),
|
|
16154
|
-
`property "tasks" must be an array${pathTip}`
|
|
16155
|
-
);
|
|
16156
|
-
return obj;
|
|
16157
|
-
}
|
|
16058
|
+
// src/yaml-runner.ts
|
|
16059
|
+
var import_node_console = require("console");
|
|
16060
|
+
var import_puppeteer = require("@midscene/web/puppeteer");
|
|
16158
16061
|
var launchServer = (dir) => __async(void 0, null, function* () {
|
|
16159
16062
|
return new Promise((resolve, reject) => {
|
|
16160
16063
|
const server = (0, import_http_server.createServer)({
|
|
@@ -16170,16 +16073,47 @@ function playYamlFiles(files, options) {
|
|
|
16170
16073
|
return __async(this, null, function* () {
|
|
16171
16074
|
const fileContextList = [];
|
|
16172
16075
|
for (const file of files) {
|
|
16173
|
-
const script =
|
|
16076
|
+
const script = (0, import_web2.parseYamlScript)((0, import_node_fs3.readFileSync)(file, "utf-8"), file);
|
|
16174
16077
|
const fileName = (0, import_node_path4.basename)(file, (0, import_node_path4.extname)(file));
|
|
16175
|
-
const
|
|
16176
|
-
|
|
16177
|
-
|
|
16078
|
+
const preference = {
|
|
16079
|
+
headed: options == null ? void 0 : options.headed,
|
|
16080
|
+
keepWindow: options == null ? void 0 : options.keepWindow,
|
|
16081
|
+
testId: fileName
|
|
16082
|
+
};
|
|
16083
|
+
const player = new import_web2.ScriptPlayer(
|
|
16084
|
+
script,
|
|
16085
|
+
(target) => __async(this, null, function* () {
|
|
16086
|
+
const freeFn = [];
|
|
16087
|
+
let localServer;
|
|
16088
|
+
let urlToVisit;
|
|
16089
|
+
(0, import_node_console.assert)(typeof target.url === "string", "url is required");
|
|
16090
|
+
if (target.serve) {
|
|
16091
|
+
localServer = yield launchServer(target.serve);
|
|
16092
|
+
const serverAddress = localServer.server.address();
|
|
16093
|
+
freeFn.push({
|
|
16094
|
+
name: "local_server",
|
|
16095
|
+
fn: () => localServer == null ? void 0 : localServer.server.close()
|
|
16096
|
+
});
|
|
16097
|
+
if (target.url.startsWith("/")) {
|
|
16098
|
+
urlToVisit = `http://${serverAddress == null ? void 0 : serverAddress.address}:${serverAddress == null ? void 0 : serverAddress.port}${target.url}`;
|
|
16099
|
+
} else {
|
|
16100
|
+
urlToVisit = `http://${serverAddress == null ? void 0 : serverAddress.address}:${serverAddress == null ? void 0 : serverAddress.port}/${target.url}`;
|
|
16101
|
+
}
|
|
16102
|
+
target.url = urlToVisit;
|
|
16103
|
+
}
|
|
16104
|
+
const { agent, freeFn: newFreeFn } = yield (0, import_puppeteer.puppeteerAgentForTarget)(
|
|
16105
|
+
target,
|
|
16106
|
+
preference
|
|
16107
|
+
);
|
|
16108
|
+
freeFn.push(...newFreeFn);
|
|
16109
|
+
return { agent, freeFn };
|
|
16110
|
+
}),
|
|
16111
|
+
(taskStatus) => {
|
|
16178
16112
|
if (!isTTY) {
|
|
16179
16113
|
const { nameText } = singleTaskInfo(taskStatus);
|
|
16180
16114
|
}
|
|
16181
16115
|
}
|
|
16182
|
-
|
|
16116
|
+
);
|
|
16183
16117
|
fileContextList.push({ file, player });
|
|
16184
16118
|
}
|
|
16185
16119
|
if (isTTY) {
|
|
@@ -16187,7 +16121,7 @@ function playYamlFiles(files, options) {
|
|
|
16187
16121
|
const summary = [""];
|
|
16188
16122
|
for (const context of fileContextList) {
|
|
16189
16123
|
summary.push(
|
|
16190
|
-
contextTaskListSummary(context.player.
|
|
16124
|
+
contextTaskListSummary(context.player.taskStatusList, context)
|
|
16191
16125
|
);
|
|
16192
16126
|
}
|
|
16193
16127
|
summary.push("");
|
|
@@ -16209,298 +16143,15 @@ function playYamlFiles(files, options) {
|
|
|
16209
16143
|
const { mergedText } = contextInfo(context);
|
|
16210
16144
|
console.log(mergedText);
|
|
16211
16145
|
yield context.player.run();
|
|
16212
|
-
console.log(
|
|
16146
|
+
console.log(
|
|
16147
|
+
contextTaskListSummary(context.player.taskStatusList, context)
|
|
16148
|
+
);
|
|
16213
16149
|
}
|
|
16214
16150
|
}
|
|
16215
16151
|
const ifFail = fileContextList.some((task) => task.player.status === "error");
|
|
16216
16152
|
return !ifFail;
|
|
16217
16153
|
});
|
|
16218
16154
|
}
|
|
16219
|
-
var ScriptPlayer = class {
|
|
16220
|
-
constructor(script, options) {
|
|
16221
|
-
this.script = script;
|
|
16222
|
-
this.options = options;
|
|
16223
|
-
__publicField(this, "currentTaskIndex");
|
|
16224
|
-
__publicField(this, "taskStatus", []);
|
|
16225
|
-
__publicField(this, "status", "init");
|
|
16226
|
-
__publicField(this, "reportFile");
|
|
16227
|
-
__publicField(this, "result");
|
|
16228
|
-
__publicField(this, "unnamedResultIndex", 0);
|
|
16229
|
-
__publicField(this, "output");
|
|
16230
|
-
__publicField(this, "errorInSetup");
|
|
16231
|
-
this.result = {};
|
|
16232
|
-
this.output = script.target.output;
|
|
16233
|
-
this.taskStatus = (script.tasks || []).map((task, taskIndex) => {
|
|
16234
|
-
var _a4;
|
|
16235
|
-
return __spreadProps(__spreadValues({}, task), {
|
|
16236
|
-
index: taskIndex,
|
|
16237
|
-
status: "init",
|
|
16238
|
-
totalSteps: ((_a4 = task.flow) == null ? void 0 : _a4.length) || 0
|
|
16239
|
-
});
|
|
16240
|
-
});
|
|
16241
|
-
}
|
|
16242
|
-
setPlayerStatus(status, error) {
|
|
16243
|
-
this.status = status;
|
|
16244
|
-
this.errorInSetup = error;
|
|
16245
|
-
}
|
|
16246
|
-
setTaskStatus(index, statusValue, error) {
|
|
16247
|
-
var _a4;
|
|
16248
|
-
this.taskStatus[index].status = statusValue;
|
|
16249
|
-
if (error) {
|
|
16250
|
-
this.taskStatus[index].error = error;
|
|
16251
|
-
}
|
|
16252
|
-
if ((_a4 = this.options) == null ? void 0 : _a4.onTaskStatusChange) {
|
|
16253
|
-
this.options.onTaskStatusChange(this.taskStatus[index]);
|
|
16254
|
-
}
|
|
16255
|
-
}
|
|
16256
|
-
setTaskIndex(taskIndex) {
|
|
16257
|
-
this.currentTaskIndex = taskIndex;
|
|
16258
|
-
}
|
|
16259
|
-
flushResult() {
|
|
16260
|
-
if (Object.keys(this.result).length && this.output) {
|
|
16261
|
-
const output = (0, import_node_path4.join)(process.cwd(), this.output);
|
|
16262
|
-
const outputDir = (0, import_node_path4.dirname)(output);
|
|
16263
|
-
if (!(0, import_node_fs3.existsSync)(outputDir)) {
|
|
16264
|
-
(0, import_node_fs3.mkdirSync)(outputDir, { recursive: true });
|
|
16265
|
-
}
|
|
16266
|
-
(0, import_node_fs3.writeFileSync)(output, JSON.stringify(this.result, void 0, 2));
|
|
16267
|
-
}
|
|
16268
|
-
}
|
|
16269
|
-
playTask(_0, _1) {
|
|
16270
|
-
return __async(this, arguments, function* (taskStatus, {
|
|
16271
|
-
agent,
|
|
16272
|
-
browser,
|
|
16273
|
-
page
|
|
16274
|
-
}) {
|
|
16275
|
-
const { flow } = taskStatus;
|
|
16276
|
-
(0, import_node_assert2.default)(flow, "missing flow in task");
|
|
16277
|
-
for (const flowItemIndex in flow) {
|
|
16278
|
-
taskStatus.currentStep = Number.parseInt(flowItemIndex, 10);
|
|
16279
|
-
const flowItem = flow[flowItemIndex];
|
|
16280
|
-
if (flowItem.aiAction || flowItem.ai) {
|
|
16281
|
-
const actionTask = flowItem;
|
|
16282
|
-
const prompt = actionTask.aiAction || actionTask.ai;
|
|
16283
|
-
(0, import_node_assert2.default)(prompt, "missing prompt for ai (aiAction)");
|
|
16284
|
-
(0, import_node_assert2.default)(
|
|
16285
|
-
typeof prompt === "string",
|
|
16286
|
-
"prompt for aiAction must be a string"
|
|
16287
|
-
);
|
|
16288
|
-
yield agent.aiAction(prompt, {
|
|
16289
|
-
onTaskStart(task) {
|
|
16290
|
-
const tip = `${(0, import_ui_utils.typeStr)(task)} - ${(0, import_ui_utils.paramStr)(task)}`;
|
|
16291
|
-
flowItem.aiActionProgressTip = tip;
|
|
16292
|
-
}
|
|
16293
|
-
});
|
|
16294
|
-
} else if (flowItem.aiAssert) {
|
|
16295
|
-
const assertTask = flowItem;
|
|
16296
|
-
const prompt = assertTask.aiAssert;
|
|
16297
|
-
(0, import_node_assert2.default)(prompt, "missing prompt for aiAssert");
|
|
16298
|
-
(0, import_node_assert2.default)(
|
|
16299
|
-
typeof prompt === "string",
|
|
16300
|
-
"prompt for aiAssert must be a string"
|
|
16301
|
-
);
|
|
16302
|
-
yield agent.aiAssert(prompt);
|
|
16303
|
-
} else if (flowItem.aiQuery) {
|
|
16304
|
-
const queryTask = flowItem;
|
|
16305
|
-
const prompt = queryTask.aiQuery;
|
|
16306
|
-
(0, import_node_assert2.default)(prompt, "missing prompt for aiQuery");
|
|
16307
|
-
(0, import_node_assert2.default)(
|
|
16308
|
-
typeof prompt === "string",
|
|
16309
|
-
"prompt for aiQuery must be a string"
|
|
16310
|
-
);
|
|
16311
|
-
const queryResult = yield agent.aiQuery(prompt);
|
|
16312
|
-
const resultKey = queryTask.name || this.unnamedResultIndex++;
|
|
16313
|
-
if (this.result[resultKey]) {
|
|
16314
|
-
console.warn(
|
|
16315
|
-
`result key ${resultKey} already exists, will overwrite`
|
|
16316
|
-
);
|
|
16317
|
-
}
|
|
16318
|
-
this.result[resultKey] = queryResult;
|
|
16319
|
-
this.flushResult();
|
|
16320
|
-
} else if (flowItem.aiWaitFor) {
|
|
16321
|
-
const waitForTask = flowItem;
|
|
16322
|
-
const prompt = waitForTask.aiWaitFor;
|
|
16323
|
-
(0, import_node_assert2.default)(prompt, "missing prompt for aiWaitFor");
|
|
16324
|
-
(0, import_node_assert2.default)(
|
|
16325
|
-
typeof prompt === "string",
|
|
16326
|
-
"prompt for aiWaitFor must be a string"
|
|
16327
|
-
);
|
|
16328
|
-
const timeout = waitForTask.timeout;
|
|
16329
|
-
yield agent.aiWaitFor(prompt, { timeoutMs: timeout });
|
|
16330
|
-
} else if (flowItem.sleep) {
|
|
16331
|
-
const sleepTask = flowItem;
|
|
16332
|
-
const ms = sleepTask.sleep;
|
|
16333
|
-
(0, import_node_assert2.default)(
|
|
16334
|
-
ms && ms > 0,
|
|
16335
|
-
`ms for sleep must be greater than 0, but got ${ms}`
|
|
16336
|
-
);
|
|
16337
|
-
yield new Promise((resolve) => setTimeout(resolve, ms));
|
|
16338
|
-
} else {
|
|
16339
|
-
throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);
|
|
16340
|
-
}
|
|
16341
|
-
}
|
|
16342
|
-
this.reportFile = agent.reportFile;
|
|
16343
|
-
});
|
|
16344
|
-
}
|
|
16345
|
-
run() {
|
|
16346
|
-
return __async(this, null, function* () {
|
|
16347
|
-
var _a4, _b2, _c2, _d2, _e2, _f2;
|
|
16348
|
-
const { target, tasks } = this.script;
|
|
16349
|
-
this.setPlayerStatus("running");
|
|
16350
|
-
const ua = target.userAgent || defaultUA;
|
|
16351
|
-
let width = defaultViewportWidth;
|
|
16352
|
-
if (target.viewportWidth) {
|
|
16353
|
-
(0, import_node_assert2.default)(
|
|
16354
|
-
typeof target.viewportWidth === "number",
|
|
16355
|
-
"viewportWidth must be a number"
|
|
16356
|
-
);
|
|
16357
|
-
width = Number.parseInt(target.viewportWidth, 10);
|
|
16358
|
-
(0, import_node_assert2.default)(
|
|
16359
|
-
width > 0,
|
|
16360
|
-
`viewportWidth must be greater than 0, but got ${width}`
|
|
16361
|
-
);
|
|
16362
|
-
}
|
|
16363
|
-
let height = defaultViewportHeight;
|
|
16364
|
-
if (target.viewportHeight) {
|
|
16365
|
-
(0, import_node_assert2.default)(
|
|
16366
|
-
typeof target.viewportHeight === "number",
|
|
16367
|
-
"viewportHeight must be a number"
|
|
16368
|
-
);
|
|
16369
|
-
height = Number.parseInt(target.viewportHeight, 10);
|
|
16370
|
-
(0, import_node_assert2.default)(
|
|
16371
|
-
height > 0,
|
|
16372
|
-
`viewportHeight must be greater than 0, but got ${height}`
|
|
16373
|
-
);
|
|
16374
|
-
}
|
|
16375
|
-
let dpr = defaultViewportScale;
|
|
16376
|
-
if (target.viewportScale) {
|
|
16377
|
-
(0, import_node_assert2.default)(
|
|
16378
|
-
typeof target.viewportScale === "number",
|
|
16379
|
-
"viewportScale must be a number"
|
|
16380
|
-
);
|
|
16381
|
-
dpr = Number.parseInt(target.viewportScale, 10);
|
|
16382
|
-
(0, import_node_assert2.default)(dpr > 0, `viewportScale must be greater than 0, but got ${dpr}`);
|
|
16383
|
-
}
|
|
16384
|
-
const viewportConfig = {
|
|
16385
|
-
width,
|
|
16386
|
-
height,
|
|
16387
|
-
deviceScaleFactor: dpr
|
|
16388
|
-
};
|
|
16389
|
-
const freeFn = [];
|
|
16390
|
-
let localServer;
|
|
16391
|
-
let urlToVisit;
|
|
16392
|
-
(0, import_node_assert2.default)(typeof target.url === "string", "url is required");
|
|
16393
|
-
if (target.serve) {
|
|
16394
|
-
localServer = yield launchServer(target.serve);
|
|
16395
|
-
const serverAddress = localServer.server.address();
|
|
16396
|
-
freeFn.push({
|
|
16397
|
-
name: "local_server",
|
|
16398
|
-
fn: () => localServer == null ? void 0 : localServer.server.close()
|
|
16399
|
-
});
|
|
16400
|
-
if (target.url.startsWith("/")) {
|
|
16401
|
-
urlToVisit = `http://${serverAddress == null ? void 0 : serverAddress.address}:${serverAddress == null ? void 0 : serverAddress.port}${target.url}`;
|
|
16402
|
-
} else {
|
|
16403
|
-
urlToVisit = `http://${serverAddress == null ? void 0 : serverAddress.address}:${serverAddress == null ? void 0 : serverAddress.port}/${target.url}`;
|
|
16404
|
-
}
|
|
16405
|
-
} else {
|
|
16406
|
-
urlToVisit = target.url;
|
|
16407
|
-
}
|
|
16408
|
-
const headed = ((_a4 = this.options) == null ? void 0 : _a4.headed) || ((_b2 = this.options) == null ? void 0 : _b2.keepWindow);
|
|
16409
|
-
if (headed && process.env.CI === "1") {
|
|
16410
|
-
console.warn(
|
|
16411
|
-
"you are probably running headed mode in CI, this will usually fail."
|
|
16412
|
-
);
|
|
16413
|
-
}
|
|
16414
|
-
const browser = yield import_puppeteer.default.launch({
|
|
16415
|
-
headless: !headed,
|
|
16416
|
-
args: [
|
|
16417
|
-
"--no-sandbox",
|
|
16418
|
-
"--disable-setuid-sandbox",
|
|
16419
|
-
"--disable-features=PasswordLeakDetection",
|
|
16420
|
-
"--disable-save-password-bubble"
|
|
16421
|
-
]
|
|
16422
|
-
});
|
|
16423
|
-
freeFn.push({
|
|
16424
|
-
name: "puppeteer_browser",
|
|
16425
|
-
fn: () => {
|
|
16426
|
-
var _a5;
|
|
16427
|
-
if (!((_a5 = this.options) == null ? void 0 : _a5.keepWindow)) {
|
|
16428
|
-
browser.close();
|
|
16429
|
-
}
|
|
16430
|
-
}
|
|
16431
|
-
});
|
|
16432
|
-
const pages = yield browser.pages();
|
|
16433
|
-
const page = pages[0];
|
|
16434
|
-
yield page.setUserAgent(ua);
|
|
16435
|
-
yield page.setViewport(viewportConfig);
|
|
16436
|
-
if (target.cookie) {
|
|
16437
|
-
const cookieFileContent = (0, import_node_fs3.readFileSync)(target.cookie, "utf-8");
|
|
16438
|
-
yield page.setCookie(...JSON.parse(cookieFileContent));
|
|
16439
|
-
}
|
|
16440
|
-
yield page.goto(urlToVisit);
|
|
16441
|
-
const waitForNetworkIdleTimeout = typeof ((_c2 = target.waitForNetworkIdle) == null ? void 0 : _c2.timeout) === "number" ? target.waitForNetworkIdle.timeout : defaultWaitForNetworkIdleTimeout;
|
|
16442
|
-
try {
|
|
16443
|
-
if (waitForNetworkIdleTimeout > 0) {
|
|
16444
|
-
yield page.waitForNetworkIdle({
|
|
16445
|
-
timeout: waitForNetworkIdleTimeout
|
|
16446
|
-
});
|
|
16447
|
-
}
|
|
16448
|
-
} catch (e) {
|
|
16449
|
-
if (typeof ((_d2 = target.waitForNetworkIdle) == null ? void 0 : _d2.continueOnNetworkIdleError) === "boolean" && !((_e2 = target.waitForNetworkIdle) == null ? void 0 : _e2.continueOnNetworkIdleError)) {
|
|
16450
|
-
const newError = new Error(`failed to wait for network idle: ${e}`, {
|
|
16451
|
-
cause: e
|
|
16452
|
-
});
|
|
16453
|
-
this.setPlayerStatus("error", newError);
|
|
16454
|
-
return;
|
|
16455
|
-
}
|
|
16456
|
-
const newMessage = `failed to wait for network idle after ${waitForNetworkIdleTimeout}ms, but the script will continue.`;
|
|
16457
|
-
console.warn(newMessage);
|
|
16458
|
-
}
|
|
16459
|
-
const agent = new import_puppeteer2.PuppeteerAgent(page, {
|
|
16460
|
-
autoPrintReportMsg: false,
|
|
16461
|
-
testId: (_f2 = this.options) == null ? void 0 : _f2.testId
|
|
16462
|
-
});
|
|
16463
|
-
freeFn.push({
|
|
16464
|
-
name: "midscene_puppeteer_agent",
|
|
16465
|
-
fn: () => agent.destroy()
|
|
16466
|
-
});
|
|
16467
|
-
let taskIndex = 0;
|
|
16468
|
-
this.setPlayerStatus("running");
|
|
16469
|
-
let errorFlag = false;
|
|
16470
|
-
while (taskIndex < tasks.length) {
|
|
16471
|
-
const task = tasks[taskIndex];
|
|
16472
|
-
this.setTaskStatus(taskIndex, "running");
|
|
16473
|
-
try {
|
|
16474
|
-
this.setTaskIndex(taskIndex);
|
|
16475
|
-
yield this.playTask(this.taskStatus[taskIndex], {
|
|
16476
|
-
agent,
|
|
16477
|
-
browser,
|
|
16478
|
-
page
|
|
16479
|
-
});
|
|
16480
|
-
} catch (e) {
|
|
16481
|
-
this.setTaskStatus(taskIndex, "error", e);
|
|
16482
|
-
this.setPlayerStatus("error");
|
|
16483
|
-
errorFlag = true;
|
|
16484
|
-
this.reportFile = agent.reportFile;
|
|
16485
|
-
taskIndex++;
|
|
16486
|
-
continue;
|
|
16487
|
-
}
|
|
16488
|
-
this.reportFile = agent.reportFile;
|
|
16489
|
-
this.setTaskStatus(taskIndex, "done");
|
|
16490
|
-
taskIndex++;
|
|
16491
|
-
}
|
|
16492
|
-
if (!errorFlag) {
|
|
16493
|
-
this.setPlayerStatus("done");
|
|
16494
|
-
}
|
|
16495
|
-
freeFn.forEach((fn) => {
|
|
16496
|
-
try {
|
|
16497
|
-
fn.fn();
|
|
16498
|
-
} catch (e) {
|
|
16499
|
-
}
|
|
16500
|
-
});
|
|
16501
|
-
});
|
|
16502
|
-
}
|
|
16503
|
-
};
|
|
16504
16155
|
|
|
16505
16156
|
// src/index.ts
|
|
16506
16157
|
Promise.resolve(
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midscene/cli",
|
|
3
3
|
"description": "An AI-powered automation SDK can control the page, perform assertions, and extract data in JSON format using natural language. See https://midscenejs.com/ for details.",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.10-beta-20241225120902.0",
|
|
5
5
|
"repository": "https://github.com/web-infra-dev/midscene",
|
|
6
6
|
"homepage": "https://midscenejs.com/",
|
|
7
7
|
"jsnext:source": "./src/index.ts",
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"bin"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"http-server": "14.1.1",
|
|
19
18
|
"puppeteer": "23.0.2",
|
|
20
|
-
"
|
|
21
|
-
"@midscene/
|
|
19
|
+
"http-server": "14.1.1",
|
|
20
|
+
"@midscene/core": "0.8.10-beta-20241225120902.0",
|
|
21
|
+
"@midscene/web": "0.8.10-beta-20241225120902.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@modern-js/module-tools": "2.60.6",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"yargs": "17.7.2"
|
|
39
39
|
},
|
|
40
40
|
"engines": {
|
|
41
|
-
"node": ">=
|
|
41
|
+
"node": ">=18.0.0"
|
|
42
42
|
},
|
|
43
43
|
"publishConfig": {
|
|
44
44
|
"access": "public",
|