@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 CHANGED
@@ -2,8 +2,4 @@
2
2
 
3
3
  require('../dist/lib/help.js');
4
4
 
5
- if (process.argv.indexOf('playground') !== -1) {
6
- require('../dist/lib/playground.js');
7
- } else {
8
- require('../dist/lib/index.js');
9
- }
5
+ require('../dist/lib/index.js');
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
- --url <url> The URL to visit, required
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((resolve, reject) => {
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 ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
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 parse(args) {
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
- let paramStr;
123
- if (typeof param === "object") {
124
- paramStr = JSON.stringify(param, null, 2);
125
- } else if (name === "sleep") {
126
- paramStr = `${param}ms`;
127
- } else {
128
- paramStr = param;
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 = parse(process.argv);
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.name) || Object.values(actionArgs).includes(arg.name),
178
- `Unknown argument: ${arg.name}`
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", url));
220
- yield page.goto(url);
221
- updateSpin(stepString("waitForNetworkIdle", url));
275
+ updateSpin(stepString("launch", urlToVisit));
276
+ yield page.goto(urlToVisit);
277
+ updateSpin(stepString("waitForNetworkIdle", urlToVisit));
222
278
  yield page.waitForNetworkIdle();
223
- printStep("launched", url);
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 <= args.length - 1) {
231
- const arg = args[index];
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((resolve) => setTimeout(resolve, param));
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
- --url <url> The URL to visit, required
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((resolve, reject) => {
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 ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
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 parse(args2) {
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
- let paramStr;
136
- if (typeof param === "object") {
137
- paramStr = JSON.stringify(param, null, 2);
138
- } else if (name === "sleep") {
139
- paramStr = `${param}ms`;
140
- } else {
141
- paramStr = param;
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 = parse(process.argv);
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.name) || Object.values(actionArgs).includes(arg.name),
191
- `Unknown argument: ${arg.name}`
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", url));
233
- yield page.goto(url);
234
- updateSpin(stepString("waitForNetworkIdle", url));
288
+ updateSpin(stepString("launch", urlToVisit));
289
+ yield page.goto(urlToVisit);
290
+ updateSpin(stepString("waitForNetworkIdle", urlToVisit));
235
291
  yield page.waitForNetworkIdle();
236
- printStep("launched", url);
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 <= args.length - 1) {
244
- const arg = args[index];
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((resolve) => setTimeout(resolve, param));
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",
File without changes
@@ -1 +0,0 @@
1
- "use strict";
@@ -1,2 +0,0 @@
1
-
2
- export { }