@midscene/cli 0.8.0 → 0.8.1-beta-20241112034501.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/bin/midscene +1 -5
- package/dist/es/help.js +10 -6
- package/dist/es/index.js +116 -59
- package/dist/lib/help.js +10 -6
- package/dist/lib/index.js +116 -59
- package/package.json +6 -2
- package/dist/es/playground.js +0 -0
- package/dist/lib/playground.js +0 -1
- package/dist/types/playground.d.ts +0 -2
package/bin/midscene
CHANGED
package/dist/es/help.js
CHANGED
|
@@ -9,7 +9,7 @@ var require_package = __commonJS({
|
|
|
9
9
|
module.exports = {
|
|
10
10
|
name: "@midscene/cli",
|
|
11
11
|
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.",
|
|
12
|
-
version: "0.8.0",
|
|
12
|
+
version: "0.8.1-beta-20241112034501.0",
|
|
13
13
|
repository: "https://github.com/web-infra-dev/midscene",
|
|
14
14
|
homepage: "https://midscenejs.com/",
|
|
15
15
|
"jsnext:source": "./src/index.ts",
|
|
@@ -30,12 +30,16 @@ var require_package = __commonJS({
|
|
|
30
30
|
},
|
|
31
31
|
dependencies: {
|
|
32
32
|
"@midscene/web": "workspace:*",
|
|
33
|
+
dotenv: "16.4.5",
|
|
34
|
+
"http-server": "14.1.1",
|
|
35
|
+
minimist: "1.2.5",
|
|
33
36
|
"ora-classic": "5.4.2",
|
|
34
37
|
puppeteer: "23.0.2",
|
|
35
38
|
yargs: "17.7.2"
|
|
36
39
|
},
|
|
37
40
|
devDependencies: {
|
|
38
41
|
"@modern-js/module-tools": "2.60.6",
|
|
42
|
+
"@types/minimist": "1.2.5",
|
|
39
43
|
"@types/node": "^18.0.0",
|
|
40
44
|
"@types/yargs": "17.0.32",
|
|
41
45
|
execa: "9.3.0",
|
|
@@ -64,7 +68,8 @@ if (process.argv.indexOf("--help") !== -1) {
|
|
|
64
68
|
Usage: midscene [options] [actions]
|
|
65
69
|
|
|
66
70
|
Options:
|
|
67
|
-
--
|
|
71
|
+
--serve <root-directory> Serve the local path as a static server, optional
|
|
72
|
+
--url <url> The URL to visit, required. If --serve is provided, provide the path to the file to visit
|
|
68
73
|
--user-agent <ua> The user agent to use, optional
|
|
69
74
|
--viewport-width <width> The width of the viewport, optional
|
|
70
75
|
--viewport-height <height> The height of the viewport, optional
|
|
@@ -90,6 +95,9 @@ if (process.argv.indexOf("--help") !== -1) {
|
|
|
90
95
|
--query-output status.json \\
|
|
91
96
|
--query '{name: string, status: string}[], service status of github page'
|
|
92
97
|
|
|
98
|
+
# serve the current directory and visit the index.html file
|
|
99
|
+
midscene --serve . --url "index.html" --assert "the content title is 'My App'"
|
|
100
|
+
|
|
93
101
|
Examples with Chinese Prompts
|
|
94
102
|
# headed 模式(即可见浏览器)访问 baidu.com 并搜索“天气”
|
|
95
103
|
midscene --headed --url "https://www.baidu.com" --action "在搜索框输入 '天气', 敲回车" --wait-for 界面上出现了天气信息
|
|
@@ -98,10 +106,6 @@ if (process.argv.indexOf("--help") !== -1) {
|
|
|
98
106
|
midscene --url "https://www.githubstatus.com/" \\
|
|
99
107
|
--query-output status.json \\
|
|
100
108
|
--query '{serviceName: string, status: string}[], github 页面的服务状态,返回服务名称'
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
To launch a playground server, run the following command:
|
|
104
|
-
midscene playground
|
|
105
109
|
`);
|
|
106
110
|
process.exit(0);
|
|
107
111
|
} else if (process.argv.indexOf("--version") !== -1) {
|
package/dist/es/index.js
CHANGED
|
@@ -6,7 +6,7 @@ var __commonJS = (cb, mod) => function __require() {
|
|
|
6
6
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
7
7
|
};
|
|
8
8
|
var __async = (__this, __arguments, generator) => {
|
|
9
|
-
return new Promise((
|
|
9
|
+
return new Promise((resolve2, reject) => {
|
|
10
10
|
var fulfilled = (value) => {
|
|
11
11
|
try {
|
|
12
12
|
step(generator.next(value));
|
|
@@ -21,13 +21,23 @@ var __async = (__this, __arguments, generator) => {
|
|
|
21
21
|
reject(e);
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
|
-
var step = (x) => x.done ?
|
|
24
|
+
var step = (x) => x.done ? resolve2(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
25
25
|
step((generator = generator.apply(__this, __arguments)).next());
|
|
26
26
|
});
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
// src/args.ts
|
|
30
|
-
function
|
|
30
|
+
function findOnlyItemInArgs(args, name) {
|
|
31
|
+
const found = args[name];
|
|
32
|
+
if (found === void 0) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (Array.isArray(found) && found.length > 1) {
|
|
36
|
+
throw new Error(`Multiple values found for ${name}`);
|
|
37
|
+
}
|
|
38
|
+
return found;
|
|
39
|
+
}
|
|
40
|
+
function orderMattersParse(args) {
|
|
31
41
|
const orderedArgs = [];
|
|
32
42
|
args.forEach((arg, index) => {
|
|
33
43
|
if (arg.startsWith("--")) {
|
|
@@ -41,16 +51,6 @@ function parse(args) {
|
|
|
41
51
|
});
|
|
42
52
|
return orderedArgs;
|
|
43
53
|
}
|
|
44
|
-
function findOnlyItemInArgs(args, name) {
|
|
45
|
-
const found = args.filter((arg) => arg.name === name);
|
|
46
|
-
if (found.length === 0) {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
if (found.length > 1) {
|
|
50
|
-
throw new Error(`Multiple values found for ${name}`);
|
|
51
|
-
}
|
|
52
|
-
return found[0].value;
|
|
53
|
-
}
|
|
54
54
|
var init_args = __esm({
|
|
55
55
|
"src/args.ts"() {
|
|
56
56
|
"use strict";
|
|
@@ -63,7 +63,7 @@ var require_package = __commonJS({
|
|
|
63
63
|
module.exports = {
|
|
64
64
|
name: "@midscene/cli",
|
|
65
65
|
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.",
|
|
66
|
-
version: "0.8.0",
|
|
66
|
+
version: "0.8.1-beta-20241112034501.0",
|
|
67
67
|
repository: "https://github.com/web-infra-dev/midscene",
|
|
68
68
|
homepage: "https://midscenejs.com/",
|
|
69
69
|
"jsnext:source": "./src/index.ts",
|
|
@@ -84,12 +84,16 @@ var require_package = __commonJS({
|
|
|
84
84
|
},
|
|
85
85
|
dependencies: {
|
|
86
86
|
"@midscene/web": "workspace:*",
|
|
87
|
+
dotenv: "16.4.5",
|
|
88
|
+
"http-server": "14.1.1",
|
|
89
|
+
minimist: "1.2.5",
|
|
87
90
|
"ora-classic": "5.4.2",
|
|
88
91
|
puppeteer: "23.0.2",
|
|
89
92
|
yargs: "17.7.2"
|
|
90
93
|
},
|
|
91
94
|
devDependencies: {
|
|
92
95
|
"@modern-js/module-tools": "2.60.6",
|
|
96
|
+
"@types/minimist": "1.2.5",
|
|
93
97
|
"@types/node": "^18.0.0",
|
|
94
98
|
"@types/yargs": "17.0.32",
|
|
95
99
|
execa: "9.3.0",
|
|
@@ -111,30 +115,40 @@ var require_package = __commonJS({
|
|
|
111
115
|
// src/index.ts
|
|
112
116
|
import assert from "assert";
|
|
113
117
|
import { writeFileSync } from "fs";
|
|
118
|
+
import { resolve } from "path";
|
|
114
119
|
import { PuppeteerAgent } from "@midscene/web/puppeteer";
|
|
120
|
+
import { createServer } from "http-server";
|
|
121
|
+
import minimist from "minimist";
|
|
115
122
|
import ora from "ora-classic";
|
|
116
123
|
import puppeteer from "puppeteer";
|
|
124
|
+
import "dotenv/config";
|
|
117
125
|
var require_src = __commonJS({
|
|
118
126
|
"src/index.ts"(exports) {
|
|
119
127
|
init_args();
|
|
120
128
|
var spinner;
|
|
121
|
-
var stepString = (name, param) => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
var stepString = (name, param, line2) => {
|
|
130
|
+
const paramToString = (data) => {
|
|
131
|
+
if (name === "sleep") {
|
|
132
|
+
return `${data}ms`;
|
|
133
|
+
}
|
|
134
|
+
if (typeof data === "object") {
|
|
135
|
+
return JSON.stringify(data, null, 2);
|
|
136
|
+
}
|
|
137
|
+
return String(data);
|
|
138
|
+
};
|
|
139
|
+
let paramStr = paramToString(param);
|
|
140
|
+
if (line2) {
|
|
141
|
+
paramStr = `${paramStr}
|
|
142
|
+
${line2}`;
|
|
129
143
|
}
|
|
130
144
|
return `${name}
|
|
131
145
|
${paramStr ? `${paramStr}` : ""}`;
|
|
132
146
|
};
|
|
133
|
-
var printStep = (name, param) => {
|
|
147
|
+
var printStep = (name, param, line2) => {
|
|
134
148
|
if (spinner) {
|
|
135
149
|
spinner.stop();
|
|
136
150
|
}
|
|
137
|
-
console.log(`- ${stepString(name, param)}`);
|
|
151
|
+
console.log(`- ${stepString(name, param, line2)}`);
|
|
138
152
|
};
|
|
139
153
|
var updateSpin = (text) => {
|
|
140
154
|
if (!spinner) {
|
|
@@ -145,8 +159,19 @@ var require_src = __commonJS({
|
|
|
145
159
|
spinner.start();
|
|
146
160
|
}
|
|
147
161
|
};
|
|
162
|
+
var launchServer = (dir) => __async(exports, null, function* () {
|
|
163
|
+
return new Promise((resolve2, reject) => {
|
|
164
|
+
const server = createServer({
|
|
165
|
+
root: dir
|
|
166
|
+
});
|
|
167
|
+
server.listen(0, "127.0.0.1", () => {
|
|
168
|
+
resolve2(server);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
});
|
|
148
172
|
var preferenceArgs = {
|
|
149
173
|
url: "url",
|
|
174
|
+
serve: "serve",
|
|
150
175
|
headed: "headed",
|
|
151
176
|
viewportWidth: "viewport-width",
|
|
152
177
|
viewportHeight: "viewport-height",
|
|
@@ -166,44 +191,75 @@ var require_src = __commonJS({
|
|
|
166
191
|
var 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";
|
|
167
192
|
var welcome = "\nWelcome to @midscene/cli\n";
|
|
168
193
|
console.log(welcome);
|
|
169
|
-
var args =
|
|
194
|
+
var args = minimist(process.argv);
|
|
170
195
|
if (findOnlyItemInArgs(args, "version")) {
|
|
171
196
|
const versionFromPkgJson = require_package().version;
|
|
172
197
|
console.log(`@midscene/cli version ${versionFromPkgJson}`);
|
|
173
198
|
process.exit(0);
|
|
174
199
|
}
|
|
175
|
-
args.forEach((arg) => {
|
|
200
|
+
Object.keys(args).forEach((arg) => {
|
|
201
|
+
if (arg === "_")
|
|
202
|
+
return;
|
|
176
203
|
assert(
|
|
177
|
-
Object.values(preferenceArgs).includes(arg
|
|
178
|
-
`Unknown argument: ${arg
|
|
204
|
+
Object.values(preferenceArgs).includes(arg) || Object.values(actionArgs).includes(arg),
|
|
205
|
+
`Unknown argument: ${arg}`
|
|
179
206
|
);
|
|
180
207
|
});
|
|
181
|
-
var preferHeaded = findOnlyItemInArgs(args, preferenceArgs.headed);
|
|
182
|
-
var userExpectWidth = findOnlyItemInArgs(args, preferenceArgs.viewportWidth);
|
|
183
|
-
var userExpectHeight = findOnlyItemInArgs(
|
|
184
|
-
args,
|
|
185
|
-
preferenceArgs.viewportHeight
|
|
186
|
-
);
|
|
187
|
-
var userExpectDpr = findOnlyItemInArgs(args, preferenceArgs.viewportScale);
|
|
188
|
-
var defaultDpr = process.platform === "darwin" ? 2 : 1;
|
|
189
|
-
var viewportConfig = {
|
|
190
|
-
width: typeof userExpectWidth === "number" ? userExpectWidth : 1280,
|
|
191
|
-
height: typeof userExpectHeight === "number" ? userExpectHeight : 1280,
|
|
192
|
-
deviceScaleFactor: typeof userExpectDpr === "number" ? userExpectDpr : defaultDpr
|
|
193
|
-
};
|
|
194
|
-
var url = findOnlyItemInArgs(args, preferenceArgs.url);
|
|
195
|
-
assert(url, "URL is required");
|
|
196
|
-
assert(typeof url === "string", "URL must be a string");
|
|
197
|
-
var preferredUA = findOnlyItemInArgs(args, preferenceArgs.useragent);
|
|
198
|
-
var ua = typeof preferredUA === "string" ? preferredUA : defaultUA;
|
|
199
|
-
printStep(preferenceArgs.url, url);
|
|
200
|
-
printStep(preferenceArgs.useragent, ua);
|
|
201
|
-
printStep("viewport", JSON.stringify(viewportConfig));
|
|
202
|
-
if (preferHeaded) {
|
|
203
|
-
printStep(preferenceArgs.headed, "true");
|
|
204
|
-
}
|
|
205
208
|
Promise.resolve(
|
|
206
209
|
(() => __async(exports, null, function* () {
|
|
210
|
+
const staticServerConfig = findOnlyItemInArgs(args, "serve");
|
|
211
|
+
let staticServerUrl;
|
|
212
|
+
if (staticServerConfig) {
|
|
213
|
+
const serverDir = typeof staticServerConfig === "string" ? staticServerConfig : process.cwd();
|
|
214
|
+
const finalServerDir = resolve(process.cwd(), serverDir);
|
|
215
|
+
const staticServerResult = yield launchServer(finalServerDir);
|
|
216
|
+
const server = staticServerResult.server;
|
|
217
|
+
const serverAddress = server.address();
|
|
218
|
+
staticServerUrl = `http://${serverAddress == null ? void 0 : serverAddress.address}:${serverAddress == null ? void 0 : serverAddress.port}`;
|
|
219
|
+
printStep("static server", finalServerDir, staticServerUrl);
|
|
220
|
+
}
|
|
221
|
+
const preferHeaded = findOnlyItemInArgs(args, preferenceArgs.headed);
|
|
222
|
+
const userExpectWidth = findOnlyItemInArgs(
|
|
223
|
+
args,
|
|
224
|
+
preferenceArgs.viewportWidth
|
|
225
|
+
);
|
|
226
|
+
const userExpectHeight = findOnlyItemInArgs(
|
|
227
|
+
args,
|
|
228
|
+
preferenceArgs.viewportHeight
|
|
229
|
+
);
|
|
230
|
+
const userExpectDpr = findOnlyItemInArgs(
|
|
231
|
+
args,
|
|
232
|
+
preferenceArgs.viewportScale
|
|
233
|
+
);
|
|
234
|
+
const defaultDpr = process.platform === "darwin" ? 2 : 1;
|
|
235
|
+
const viewportConfig = {
|
|
236
|
+
width: typeof userExpectWidth === "number" ? userExpectWidth : 1280,
|
|
237
|
+
height: typeof userExpectHeight === "number" ? userExpectHeight : 1280,
|
|
238
|
+
deviceScaleFactor: typeof userExpectDpr === "number" ? userExpectDpr : defaultDpr
|
|
239
|
+
};
|
|
240
|
+
const url = findOnlyItemInArgs(args, preferenceArgs.url);
|
|
241
|
+
let urlToVisit;
|
|
242
|
+
if (staticServerUrl) {
|
|
243
|
+
if (typeof url !== "undefined") {
|
|
244
|
+
if (url.startsWith("/")) {
|
|
245
|
+
urlToVisit = `${staticServerUrl}${url}`;
|
|
246
|
+
} else {
|
|
247
|
+
urlToVisit = `${staticServerUrl}/${url}`;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
urlToVisit = url;
|
|
252
|
+
}
|
|
253
|
+
assert(urlToVisit, "URL is required");
|
|
254
|
+
assert(typeof urlToVisit === "string", "URL must be a string");
|
|
255
|
+
const preferredUA = findOnlyItemInArgs(args, preferenceArgs.useragent);
|
|
256
|
+
const ua = typeof preferredUA === "string" ? preferredUA : defaultUA;
|
|
257
|
+
printStep(preferenceArgs.url, urlToVisit);
|
|
258
|
+
printStep(preferenceArgs.useragent, ua);
|
|
259
|
+
printStep("viewport", JSON.stringify(viewportConfig));
|
|
260
|
+
if (preferHeaded) {
|
|
261
|
+
printStep(preferenceArgs.headed, "true");
|
|
262
|
+
}
|
|
207
263
|
updateSpin(stepString("launch", "puppeteer"));
|
|
208
264
|
const browser = yield puppeteer.launch({
|
|
209
265
|
headless: !preferHeaded
|
|
@@ -216,19 +272,20 @@ var require_src = __commonJS({
|
|
|
216
272
|
let argValue;
|
|
217
273
|
let agent;
|
|
218
274
|
try {
|
|
219
|
-
updateSpin(stepString("launch",
|
|
220
|
-
yield page.goto(
|
|
221
|
-
updateSpin(stepString("waitForNetworkIdle",
|
|
275
|
+
updateSpin(stepString("launch", urlToVisit));
|
|
276
|
+
yield page.goto(urlToVisit);
|
|
277
|
+
updateSpin(stepString("waitForNetworkIdle", urlToVisit));
|
|
222
278
|
yield page.waitForNetworkIdle();
|
|
223
|
-
printStep("launched",
|
|
279
|
+
printStep("launched", urlToVisit);
|
|
224
280
|
agent = new PuppeteerAgent(page, {
|
|
225
281
|
autoPrintReportMsg: false
|
|
226
282
|
});
|
|
283
|
+
const orderedArgs = orderMattersParse(process.argv);
|
|
227
284
|
let index = 0;
|
|
228
285
|
let outputPath;
|
|
229
286
|
let actionStarted = false;
|
|
230
|
-
while (index <=
|
|
231
|
-
const arg =
|
|
287
|
+
while (index <= orderedArgs.length - 1) {
|
|
288
|
+
const arg = orderedArgs[index];
|
|
232
289
|
argName = arg.name;
|
|
233
290
|
argValue = arg.value;
|
|
234
291
|
updateSpin(stepString(argName, String(argValue)));
|
|
@@ -287,7 +344,7 @@ var require_src = __commonJS({
|
|
|
287
344
|
if (!param)
|
|
288
345
|
break;
|
|
289
346
|
assert(typeof param === "number", "sleep must be a number");
|
|
290
|
-
yield new Promise((
|
|
347
|
+
yield new Promise((resolve2) => setTimeout(resolve2, param));
|
|
291
348
|
printStep(argName, String(argValue));
|
|
292
349
|
break;
|
|
293
350
|
}
|
package/dist/lib/help.js
CHANGED
|
@@ -10,7 +10,7 @@ var require_package = __commonJS({
|
|
|
10
10
|
module2.exports = {
|
|
11
11
|
name: "@midscene/cli",
|
|
12
12
|
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.",
|
|
13
|
-
version: "0.8.0",
|
|
13
|
+
version: "0.8.1-beta-20241112034501.0",
|
|
14
14
|
repository: "https://github.com/web-infra-dev/midscene",
|
|
15
15
|
homepage: "https://midscenejs.com/",
|
|
16
16
|
"jsnext:source": "./src/index.ts",
|
|
@@ -31,12 +31,16 @@ var require_package = __commonJS({
|
|
|
31
31
|
},
|
|
32
32
|
dependencies: {
|
|
33
33
|
"@midscene/web": "workspace:*",
|
|
34
|
+
dotenv: "16.4.5",
|
|
35
|
+
"http-server": "14.1.1",
|
|
36
|
+
minimist: "1.2.5",
|
|
34
37
|
"ora-classic": "5.4.2",
|
|
35
38
|
puppeteer: "23.0.2",
|
|
36
39
|
yargs: "17.7.2"
|
|
37
40
|
},
|
|
38
41
|
devDependencies: {
|
|
39
42
|
"@modern-js/module-tools": "2.60.6",
|
|
43
|
+
"@types/minimist": "1.2.5",
|
|
40
44
|
"@types/node": "^18.0.0",
|
|
41
45
|
"@types/yargs": "17.0.32",
|
|
42
46
|
execa: "9.3.0",
|
|
@@ -65,7 +69,8 @@ if (process.argv.indexOf("--help") !== -1) {
|
|
|
65
69
|
Usage: midscene [options] [actions]
|
|
66
70
|
|
|
67
71
|
Options:
|
|
68
|
-
--
|
|
72
|
+
--serve <root-directory> Serve the local path as a static server, optional
|
|
73
|
+
--url <url> The URL to visit, required. If --serve is provided, provide the path to the file to visit
|
|
69
74
|
--user-agent <ua> The user agent to use, optional
|
|
70
75
|
--viewport-width <width> The width of the viewport, optional
|
|
71
76
|
--viewport-height <height> The height of the viewport, optional
|
|
@@ -91,6 +96,9 @@ if (process.argv.indexOf("--help") !== -1) {
|
|
|
91
96
|
--query-output status.json \\
|
|
92
97
|
--query '{name: string, status: string}[], service status of github page'
|
|
93
98
|
|
|
99
|
+
# serve the current directory and visit the index.html file
|
|
100
|
+
midscene --serve . --url "index.html" --assert "the content title is 'My App'"
|
|
101
|
+
|
|
94
102
|
Examples with Chinese Prompts
|
|
95
103
|
# headed 模式(即可见浏览器)访问 baidu.com 并搜索“天气”
|
|
96
104
|
midscene --headed --url "https://www.baidu.com" --action "在搜索框输入 '天气', 敲回车" --wait-for 界面上出现了天气信息
|
|
@@ -99,10 +107,6 @@ if (process.argv.indexOf("--help") !== -1) {
|
|
|
99
107
|
midscene --url "https://www.githubstatus.com/" \\
|
|
100
108
|
--query-output status.json \\
|
|
101
109
|
--query '{serviceName: string, status: string}[], github 页面的服务状态,返回服务名称'
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
To launch a playground server, run the following command:
|
|
105
|
-
midscene playground
|
|
106
110
|
`);
|
|
107
111
|
process.exit(0);
|
|
108
112
|
} else if (process.argv.indexOf("--version") !== -1) {
|
package/dist/lib/index.js
CHANGED
|
@@ -25,7 +25,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
mod
|
|
26
26
|
));
|
|
27
27
|
var __async = (__this, __arguments, generator) => {
|
|
28
|
-
return new Promise((
|
|
28
|
+
return new Promise((resolve2, reject) => {
|
|
29
29
|
var fulfilled = (value) => {
|
|
30
30
|
try {
|
|
31
31
|
step(generator.next(value));
|
|
@@ -40,7 +40,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
40
40
|
reject(e);
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
|
-
var step = (x) => x.done ?
|
|
43
|
+
var step = (x) => x.done ? resolve2(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
44
44
|
step((generator = generator.apply(__this, __arguments)).next());
|
|
45
45
|
});
|
|
46
46
|
};
|
|
@@ -51,7 +51,7 @@ var require_package = __commonJS({
|
|
|
51
51
|
module2.exports = {
|
|
52
52
|
name: "@midscene/cli",
|
|
53
53
|
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.",
|
|
54
|
-
version: "0.8.0",
|
|
54
|
+
version: "0.8.1-beta-20241112034501.0",
|
|
55
55
|
repository: "https://github.com/web-infra-dev/midscene",
|
|
56
56
|
homepage: "https://midscenejs.com/",
|
|
57
57
|
"jsnext:source": "./src/index.ts",
|
|
@@ -72,12 +72,16 @@ var require_package = __commonJS({
|
|
|
72
72
|
},
|
|
73
73
|
dependencies: {
|
|
74
74
|
"@midscene/web": "workspace:*",
|
|
75
|
+
dotenv: "16.4.5",
|
|
76
|
+
"http-server": "14.1.1",
|
|
77
|
+
minimist: "1.2.5",
|
|
75
78
|
"ora-classic": "5.4.2",
|
|
76
79
|
puppeteer: "23.0.2",
|
|
77
80
|
yargs: "17.7.2"
|
|
78
81
|
},
|
|
79
82
|
devDependencies: {
|
|
80
83
|
"@modern-js/module-tools": "2.60.6",
|
|
84
|
+
"@types/minimist": "1.2.5",
|
|
81
85
|
"@types/node": "^18.0.0",
|
|
82
86
|
"@types/yargs": "17.0.32",
|
|
83
87
|
execa: "9.3.0",
|
|
@@ -99,12 +103,25 @@ var require_package = __commonJS({
|
|
|
99
103
|
// src/index.ts
|
|
100
104
|
var import_node_assert = __toESM(require("assert"));
|
|
101
105
|
var import_node_fs = require("fs");
|
|
106
|
+
var import_node_path = require("path");
|
|
102
107
|
var import_puppeteer = require("@midscene/web/puppeteer");
|
|
108
|
+
var import_http_server = require("http-server");
|
|
109
|
+
var import_minimist = __toESM(require("minimist"));
|
|
103
110
|
var import_ora_classic = __toESM(require("ora-classic"));
|
|
104
111
|
var import_puppeteer2 = __toESM(require("puppeteer"));
|
|
105
112
|
|
|
106
113
|
// src/args.ts
|
|
107
|
-
function
|
|
114
|
+
function findOnlyItemInArgs(args2, name) {
|
|
115
|
+
const found = args2[name];
|
|
116
|
+
if (found === void 0) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
if (Array.isArray(found) && found.length > 1) {
|
|
120
|
+
throw new Error(`Multiple values found for ${name}`);
|
|
121
|
+
}
|
|
122
|
+
return found;
|
|
123
|
+
}
|
|
124
|
+
function orderMattersParse(args2) {
|
|
108
125
|
const orderedArgs = [];
|
|
109
126
|
args2.forEach((arg, index) => {
|
|
110
127
|
if (arg.startsWith("--")) {
|
|
@@ -118,36 +135,33 @@ function parse(args2) {
|
|
|
118
135
|
});
|
|
119
136
|
return orderedArgs;
|
|
120
137
|
}
|
|
121
|
-
function findOnlyItemInArgs(args2, name) {
|
|
122
|
-
const found = args2.filter((arg) => arg.name === name);
|
|
123
|
-
if (found.length === 0) {
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
if (found.length > 1) {
|
|
127
|
-
throw new Error(`Multiple values found for ${name}`);
|
|
128
|
-
}
|
|
129
|
-
return found[0].value;
|
|
130
|
-
}
|
|
131
138
|
|
|
132
139
|
// src/index.ts
|
|
140
|
+
var import_config = require("dotenv/config");
|
|
133
141
|
var spinner;
|
|
134
|
-
var stepString = (name, param) => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
+
var stepString = (name, param, line2) => {
|
|
143
|
+
const paramToString = (data) => {
|
|
144
|
+
if (name === "sleep") {
|
|
145
|
+
return `${data}ms`;
|
|
146
|
+
}
|
|
147
|
+
if (typeof data === "object") {
|
|
148
|
+
return JSON.stringify(data, null, 2);
|
|
149
|
+
}
|
|
150
|
+
return String(data);
|
|
151
|
+
};
|
|
152
|
+
let paramStr = paramToString(param);
|
|
153
|
+
if (line2) {
|
|
154
|
+
paramStr = `${paramStr}
|
|
155
|
+
${line2}`;
|
|
142
156
|
}
|
|
143
157
|
return `${name}
|
|
144
158
|
${paramStr ? `${paramStr}` : ""}`;
|
|
145
159
|
};
|
|
146
|
-
var printStep = (name, param) => {
|
|
160
|
+
var printStep = (name, param, line2) => {
|
|
147
161
|
if (spinner) {
|
|
148
162
|
spinner.stop();
|
|
149
163
|
}
|
|
150
|
-
console.log(`- ${stepString(name, param)}`);
|
|
164
|
+
console.log(`- ${stepString(name, param, line2)}`);
|
|
151
165
|
};
|
|
152
166
|
var updateSpin = (text) => {
|
|
153
167
|
if (!spinner) {
|
|
@@ -158,8 +172,19 @@ var updateSpin = (text) => {
|
|
|
158
172
|
spinner.start();
|
|
159
173
|
}
|
|
160
174
|
};
|
|
175
|
+
var launchServer = (dir) => __async(exports, null, function* () {
|
|
176
|
+
return new Promise((resolve2, reject) => {
|
|
177
|
+
const server = (0, import_http_server.createServer)({
|
|
178
|
+
root: dir
|
|
179
|
+
});
|
|
180
|
+
server.listen(0, "127.0.0.1", () => {
|
|
181
|
+
resolve2(server);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
});
|
|
161
185
|
var preferenceArgs = {
|
|
162
186
|
url: "url",
|
|
187
|
+
serve: "serve",
|
|
163
188
|
headed: "headed",
|
|
164
189
|
viewportWidth: "viewport-width",
|
|
165
190
|
viewportHeight: "viewport-height",
|
|
@@ -179,44 +204,75 @@ var actionArgs = {
|
|
|
179
204
|
var 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";
|
|
180
205
|
var welcome = "\nWelcome to @midscene/cli\n";
|
|
181
206
|
console.log(welcome);
|
|
182
|
-
var args =
|
|
207
|
+
var args = (0, import_minimist.default)(process.argv);
|
|
183
208
|
if (findOnlyItemInArgs(args, "version")) {
|
|
184
209
|
const versionFromPkgJson = require_package().version;
|
|
185
210
|
console.log(`@midscene/cli version ${versionFromPkgJson}`);
|
|
186
211
|
process.exit(0);
|
|
187
212
|
}
|
|
188
|
-
args.forEach((arg) => {
|
|
213
|
+
Object.keys(args).forEach((arg) => {
|
|
214
|
+
if (arg === "_")
|
|
215
|
+
return;
|
|
189
216
|
(0, import_node_assert.default)(
|
|
190
|
-
Object.values(preferenceArgs).includes(arg
|
|
191
|
-
`Unknown argument: ${arg
|
|
217
|
+
Object.values(preferenceArgs).includes(arg) || Object.values(actionArgs).includes(arg),
|
|
218
|
+
`Unknown argument: ${arg}`
|
|
192
219
|
);
|
|
193
220
|
});
|
|
194
|
-
var preferHeaded = findOnlyItemInArgs(args, preferenceArgs.headed);
|
|
195
|
-
var userExpectWidth = findOnlyItemInArgs(args, preferenceArgs.viewportWidth);
|
|
196
|
-
var userExpectHeight = findOnlyItemInArgs(
|
|
197
|
-
args,
|
|
198
|
-
preferenceArgs.viewportHeight
|
|
199
|
-
);
|
|
200
|
-
var userExpectDpr = findOnlyItemInArgs(args, preferenceArgs.viewportScale);
|
|
201
|
-
var defaultDpr = process.platform === "darwin" ? 2 : 1;
|
|
202
|
-
var viewportConfig = {
|
|
203
|
-
width: typeof userExpectWidth === "number" ? userExpectWidth : 1280,
|
|
204
|
-
height: typeof userExpectHeight === "number" ? userExpectHeight : 1280,
|
|
205
|
-
deviceScaleFactor: typeof userExpectDpr === "number" ? userExpectDpr : defaultDpr
|
|
206
|
-
};
|
|
207
|
-
var url = findOnlyItemInArgs(args, preferenceArgs.url);
|
|
208
|
-
(0, import_node_assert.default)(url, "URL is required");
|
|
209
|
-
(0, import_node_assert.default)(typeof url === "string", "URL must be a string");
|
|
210
|
-
var preferredUA = findOnlyItemInArgs(args, preferenceArgs.useragent);
|
|
211
|
-
var ua = typeof preferredUA === "string" ? preferredUA : defaultUA;
|
|
212
|
-
printStep(preferenceArgs.url, url);
|
|
213
|
-
printStep(preferenceArgs.useragent, ua);
|
|
214
|
-
printStep("viewport", JSON.stringify(viewportConfig));
|
|
215
|
-
if (preferHeaded) {
|
|
216
|
-
printStep(preferenceArgs.headed, "true");
|
|
217
|
-
}
|
|
218
221
|
Promise.resolve(
|
|
219
222
|
(() => __async(exports, null, function* () {
|
|
223
|
+
const staticServerConfig = findOnlyItemInArgs(args, "serve");
|
|
224
|
+
let staticServerUrl;
|
|
225
|
+
if (staticServerConfig) {
|
|
226
|
+
const serverDir = typeof staticServerConfig === "string" ? staticServerConfig : process.cwd();
|
|
227
|
+
const finalServerDir = (0, import_node_path.resolve)(process.cwd(), serverDir);
|
|
228
|
+
const staticServerResult = yield launchServer(finalServerDir);
|
|
229
|
+
const server = staticServerResult.server;
|
|
230
|
+
const serverAddress = server.address();
|
|
231
|
+
staticServerUrl = `http://${serverAddress == null ? void 0 : serverAddress.address}:${serverAddress == null ? void 0 : serverAddress.port}`;
|
|
232
|
+
printStep("static server", finalServerDir, staticServerUrl);
|
|
233
|
+
}
|
|
234
|
+
const preferHeaded = findOnlyItemInArgs(args, preferenceArgs.headed);
|
|
235
|
+
const userExpectWidth = findOnlyItemInArgs(
|
|
236
|
+
args,
|
|
237
|
+
preferenceArgs.viewportWidth
|
|
238
|
+
);
|
|
239
|
+
const userExpectHeight = findOnlyItemInArgs(
|
|
240
|
+
args,
|
|
241
|
+
preferenceArgs.viewportHeight
|
|
242
|
+
);
|
|
243
|
+
const userExpectDpr = findOnlyItemInArgs(
|
|
244
|
+
args,
|
|
245
|
+
preferenceArgs.viewportScale
|
|
246
|
+
);
|
|
247
|
+
const defaultDpr = process.platform === "darwin" ? 2 : 1;
|
|
248
|
+
const viewportConfig = {
|
|
249
|
+
width: typeof userExpectWidth === "number" ? userExpectWidth : 1280,
|
|
250
|
+
height: typeof userExpectHeight === "number" ? userExpectHeight : 1280,
|
|
251
|
+
deviceScaleFactor: typeof userExpectDpr === "number" ? userExpectDpr : defaultDpr
|
|
252
|
+
};
|
|
253
|
+
const url = findOnlyItemInArgs(args, preferenceArgs.url);
|
|
254
|
+
let urlToVisit;
|
|
255
|
+
if (staticServerUrl) {
|
|
256
|
+
if (typeof url !== "undefined") {
|
|
257
|
+
if (url.startsWith("/")) {
|
|
258
|
+
urlToVisit = `${staticServerUrl}${url}`;
|
|
259
|
+
} else {
|
|
260
|
+
urlToVisit = `${staticServerUrl}/${url}`;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
} else {
|
|
264
|
+
urlToVisit = url;
|
|
265
|
+
}
|
|
266
|
+
(0, import_node_assert.default)(urlToVisit, "URL is required");
|
|
267
|
+
(0, import_node_assert.default)(typeof urlToVisit === "string", "URL must be a string");
|
|
268
|
+
const preferredUA = findOnlyItemInArgs(args, preferenceArgs.useragent);
|
|
269
|
+
const ua = typeof preferredUA === "string" ? preferredUA : defaultUA;
|
|
270
|
+
printStep(preferenceArgs.url, urlToVisit);
|
|
271
|
+
printStep(preferenceArgs.useragent, ua);
|
|
272
|
+
printStep("viewport", JSON.stringify(viewportConfig));
|
|
273
|
+
if (preferHeaded) {
|
|
274
|
+
printStep(preferenceArgs.headed, "true");
|
|
275
|
+
}
|
|
220
276
|
updateSpin(stepString("launch", "puppeteer"));
|
|
221
277
|
const browser = yield import_puppeteer2.default.launch({
|
|
222
278
|
headless: !preferHeaded
|
|
@@ -229,19 +285,20 @@ Promise.resolve(
|
|
|
229
285
|
let argValue;
|
|
230
286
|
let agent;
|
|
231
287
|
try {
|
|
232
|
-
updateSpin(stepString("launch",
|
|
233
|
-
yield page.goto(
|
|
234
|
-
updateSpin(stepString("waitForNetworkIdle",
|
|
288
|
+
updateSpin(stepString("launch", urlToVisit));
|
|
289
|
+
yield page.goto(urlToVisit);
|
|
290
|
+
updateSpin(stepString("waitForNetworkIdle", urlToVisit));
|
|
235
291
|
yield page.waitForNetworkIdle();
|
|
236
|
-
printStep("launched",
|
|
292
|
+
printStep("launched", urlToVisit);
|
|
237
293
|
agent = new import_puppeteer.PuppeteerAgent(page, {
|
|
238
294
|
autoPrintReportMsg: false
|
|
239
295
|
});
|
|
296
|
+
const orderedArgs = orderMattersParse(process.argv);
|
|
240
297
|
let index = 0;
|
|
241
298
|
let outputPath;
|
|
242
299
|
let actionStarted = false;
|
|
243
|
-
while (index <=
|
|
244
|
-
const arg =
|
|
300
|
+
while (index <= orderedArgs.length - 1) {
|
|
301
|
+
const arg = orderedArgs[index];
|
|
245
302
|
argName = arg.name;
|
|
246
303
|
argValue = arg.value;
|
|
247
304
|
updateSpin(stepString(argName, String(argValue)));
|
|
@@ -300,7 +357,7 @@ Promise.resolve(
|
|
|
300
357
|
if (!param)
|
|
301
358
|
break;
|
|
302
359
|
(0, import_node_assert.default)(typeof param === "number", "sleep must be a number");
|
|
303
|
-
yield new Promise((
|
|
360
|
+
yield new Promise((resolve2) => setTimeout(resolve2, param));
|
|
304
361
|
printStep(argName, String(argValue));
|
|
305
362
|
break;
|
|
306
363
|
}
|
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.0",
|
|
4
|
+
"version": "0.8.1-beta-20241112034501.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,13 +15,17 @@
|
|
|
15
15
|
"bin"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
+
"dotenv": "16.4.5",
|
|
19
|
+
"http-server": "14.1.1",
|
|
20
|
+
"minimist": "1.2.5",
|
|
18
21
|
"ora-classic": "5.4.2",
|
|
19
22
|
"puppeteer": "23.0.2",
|
|
20
23
|
"yargs": "17.7.2",
|
|
21
|
-
"@midscene/web": "0.8.0"
|
|
24
|
+
"@midscene/web": "0.8.1-beta-20241112034501.0"
|
|
22
25
|
},
|
|
23
26
|
"devDependencies": {
|
|
24
27
|
"@modern-js/module-tools": "2.60.6",
|
|
28
|
+
"@types/minimist": "1.2.5",
|
|
25
29
|
"@types/node": "^18.0.0",
|
|
26
30
|
"@types/yargs": "17.0.32",
|
|
27
31
|
"execa": "9.3.0",
|
package/dist/es/playground.js
DELETED
|
File without changes
|
package/dist/lib/playground.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|