helixlife-v5-cli 1.1.9 → 1.2.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.
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
(() => {
|
|
2
|
+
const ROOT_ID = '__helix_cli_automation_overlay';
|
|
3
|
+
|
|
4
|
+
function ensureOverlay() {
|
|
5
|
+
if (document.getElementById(ROOT_ID)) {
|
|
6
|
+
return window.__helixCliOverlay;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const root = document.createElement('div');
|
|
10
|
+
root.id = ROOT_ID;
|
|
11
|
+
root.setAttribute('data-helix-cli', 'automation-overlay');
|
|
12
|
+
root.setAttribute('aria-hidden', 'true');
|
|
13
|
+
root.style.cssText = [
|
|
14
|
+
'position:fixed',
|
|
15
|
+
'top:16px',
|
|
16
|
+
'right:16px',
|
|
17
|
+
'z-index:2147483647',
|
|
18
|
+
'pointer-events:none',
|
|
19
|
+
'box-sizing:border-box',
|
|
20
|
+
'max-width:280px',
|
|
21
|
+
'padding:10px 14px',
|
|
22
|
+
'border-radius:12px',
|
|
23
|
+
'background:#f5b942',
|
|
24
|
+
'color:#3d2b00',
|
|
25
|
+
'font:13px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"PingFang SC","Microsoft YaHei",sans-serif',
|
|
26
|
+
'box-shadow:0 4px 14px rgba(0,0,0,.18)',
|
|
27
|
+
'letter-spacing:.01em',
|
|
28
|
+
].join(';');
|
|
29
|
+
|
|
30
|
+
const title = document.createElement('div');
|
|
31
|
+
title.dataset.line = 'title';
|
|
32
|
+
title.style.cssText = 'font-weight:600;margin-bottom:4px;word-break:break-all;';
|
|
33
|
+
|
|
34
|
+
const status = document.createElement('div');
|
|
35
|
+
status.dataset.line = 'status';
|
|
36
|
+
status.style.cssText = 'opacity:.92;';
|
|
37
|
+
|
|
38
|
+
const detail = document.createElement('div');
|
|
39
|
+
detail.dataset.line = 'detail';
|
|
40
|
+
detail.style.cssText = 'opacity:.78;margin-top:2px;font-size:12px;';
|
|
41
|
+
|
|
42
|
+
root.append(title, status, detail);
|
|
43
|
+
(document.body || document.documentElement).appendChild(root);
|
|
44
|
+
|
|
45
|
+
const api = {
|
|
46
|
+
update(payload = {}) {
|
|
47
|
+
const el = document.getElementById(ROOT_ID);
|
|
48
|
+
if (!el) return;
|
|
49
|
+
const t = el.querySelector('[data-line="title"]');
|
|
50
|
+
const s = el.querySelector('[data-line="status"]');
|
|
51
|
+
const d = el.querySelector('[data-line="detail"]');
|
|
52
|
+
if (t) t.textContent = payload.title || 'helixlife-v5-cli';
|
|
53
|
+
if (s) s.textContent = payload.status || '机器自动化';
|
|
54
|
+
if (d) d.textContent = payload.detail || 'CLI 操作中';
|
|
55
|
+
el.style.display = payload.hidden ? 'none' : 'block';
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
window.__helixCliOverlay = api;
|
|
60
|
+
return api;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function boot() {
|
|
64
|
+
ensureOverlay().update({
|
|
65
|
+
title: 'helixlife-v5-cli',
|
|
66
|
+
status: '机器自动化',
|
|
67
|
+
detail: '会话已就绪',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (document.readyState === 'loading') {
|
|
72
|
+
document.addEventListener('DOMContentLoaded', boot, { once: true });
|
|
73
|
+
} else {
|
|
74
|
+
boot();
|
|
75
|
+
}
|
|
76
|
+
})();
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Playwright browser init script: inject automation status overlay on every document.
|
|
2
|
+
// Source is duplicated from automation-overlay.browser.js (keep in sync when editing).
|
|
3
|
+
(() => {
|
|
4
|
+
const ROOT_ID = '__helix_cli_automation_overlay';
|
|
5
|
+
|
|
6
|
+
function ensureOverlay() {
|
|
7
|
+
if (document.getElementById(ROOT_ID)) {
|
|
8
|
+
return window.__helixCliOverlay;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const root = document.createElement('div');
|
|
12
|
+
root.id = ROOT_ID;
|
|
13
|
+
root.setAttribute('data-helix-cli', 'automation-overlay');
|
|
14
|
+
root.setAttribute('aria-hidden', 'true');
|
|
15
|
+
root.style.cssText = [
|
|
16
|
+
'position:fixed',
|
|
17
|
+
'top:16px',
|
|
18
|
+
'right:16px',
|
|
19
|
+
'z-index:2147483647',
|
|
20
|
+
'pointer-events:none',
|
|
21
|
+
'box-sizing:border-box',
|
|
22
|
+
'max-width:280px',
|
|
23
|
+
'padding:10px 14px',
|
|
24
|
+
'border-radius:12px',
|
|
25
|
+
'background:#f5b942',
|
|
26
|
+
'color:#3d2b00',
|
|
27
|
+
'font:13px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"PingFang SC","Microsoft YaHei",sans-serif',
|
|
28
|
+
'box-shadow:0 4px 14px rgba(0,0,0,.18)',
|
|
29
|
+
'letter-spacing:.01em',
|
|
30
|
+
].join(';');
|
|
31
|
+
|
|
32
|
+
const title = document.createElement('div');
|
|
33
|
+
title.dataset.line = 'title';
|
|
34
|
+
title.style.cssText = 'font-weight:600;margin-bottom:4px;word-break:break-all;';
|
|
35
|
+
|
|
36
|
+
const status = document.createElement('div');
|
|
37
|
+
status.dataset.line = 'status';
|
|
38
|
+
status.style.cssText = 'opacity:.92;';
|
|
39
|
+
|
|
40
|
+
const detail = document.createElement('div');
|
|
41
|
+
detail.dataset.line = 'detail';
|
|
42
|
+
detail.style.cssText = 'opacity:.78;margin-top:2px;font-size:12px;';
|
|
43
|
+
|
|
44
|
+
root.append(title, status, detail);
|
|
45
|
+
(document.body || document.documentElement).appendChild(root);
|
|
46
|
+
|
|
47
|
+
const api = {
|
|
48
|
+
update(payload = {}) {
|
|
49
|
+
const el = document.getElementById(ROOT_ID);
|
|
50
|
+
if (!el) return;
|
|
51
|
+
const t = el.querySelector('[data-line="title"]');
|
|
52
|
+
const s = el.querySelector('[data-line="status"]');
|
|
53
|
+
const d = el.querySelector('[data-line="detail"]');
|
|
54
|
+
if (t) t.textContent = payload.title || 'helixlife-v5-cli';
|
|
55
|
+
if (s) s.textContent = payload.status || '机器自动化';
|
|
56
|
+
if (d) d.textContent = payload.detail || 'CLI 操作中';
|
|
57
|
+
el.style.display = payload.hidden ? 'none' : 'block';
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
window.__helixCliOverlay = api;
|
|
62
|
+
return api;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function boot() {
|
|
66
|
+
ensureOverlay().update({
|
|
67
|
+
title: 'helixlife-v5-cli',
|
|
68
|
+
status: '机器自动化',
|
|
69
|
+
detail: '会话已就绪',
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (document.readyState === 'loading') {
|
|
74
|
+
document.addEventListener('DOMContentLoaded', boot, { once: true });
|
|
75
|
+
} else {
|
|
76
|
+
boot();
|
|
77
|
+
}
|
|
78
|
+
})();
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("node:fs");
|
|
4
|
+
const path = require("node:path");
|
|
5
|
+
|
|
6
|
+
const OVERLAY_SKIP_COMMANDS = new Set([
|
|
7
|
+
"run-code",
|
|
8
|
+
"list",
|
|
9
|
+
"close",
|
|
10
|
+
"close-all",
|
|
11
|
+
"kill-all",
|
|
12
|
+
"detach",
|
|
13
|
+
"delete-data",
|
|
14
|
+
"config-print",
|
|
15
|
+
"cookie-list",
|
|
16
|
+
"cookie-get",
|
|
17
|
+
"cookie-set",
|
|
18
|
+
"cookie-delete",
|
|
19
|
+
"cookie-clear",
|
|
20
|
+
"localstorage-list",
|
|
21
|
+
"localstorage-get",
|
|
22
|
+
"localstorage-set",
|
|
23
|
+
"localstorage-delete",
|
|
24
|
+
"localstorage-clear",
|
|
25
|
+
"sessionstorage-list",
|
|
26
|
+
"sessionstorage-get",
|
|
27
|
+
"sessionstorage-set",
|
|
28
|
+
"sessionstorage-delete",
|
|
29
|
+
"sessionstorage-clear",
|
|
30
|
+
"route-list",
|
|
31
|
+
"tab-list",
|
|
32
|
+
"console",
|
|
33
|
+
"network",
|
|
34
|
+
"state-save",
|
|
35
|
+
"state-load",
|
|
36
|
+
"tracing-start",
|
|
37
|
+
"tracing-stop",
|
|
38
|
+
"video-start",
|
|
39
|
+
"video-stop",
|
|
40
|
+
"video-chapter",
|
|
41
|
+
"highlight",
|
|
42
|
+
"generate-locator",
|
|
43
|
+
"show",
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
const OVERLAY_SESSION_OPEN_COMMANDS = new Set(["open", "attach"]);
|
|
47
|
+
|
|
48
|
+
let cachedBrowserScript = null;
|
|
49
|
+
|
|
50
|
+
function isOverlayEnabled() {
|
|
51
|
+
const flag = process.env.HELIX_AUTOMATION_OVERLAY;
|
|
52
|
+
if (flag === "0" || flag === "false" || flag === "off") {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function resolveCliConfigPath() {
|
|
59
|
+
if (process.env.HELIX_CLI_CONFIG) {
|
|
60
|
+
return path.resolve(process.env.HELIX_CLI_CONFIG);
|
|
61
|
+
}
|
|
62
|
+
const initScriptPath = path.join(__dirname, "automation-overlay.init.js");
|
|
63
|
+
const runtimeConfigPath = path.join(__dirname, "cli.runtime.config.json");
|
|
64
|
+
const config = {
|
|
65
|
+
browser: {
|
|
66
|
+
initScript: [initScriptPath],
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
fs.writeFileSync(
|
|
70
|
+
runtimeConfigPath,
|
|
71
|
+
`${JSON.stringify(config, null, 2)}\n`,
|
|
72
|
+
"utf8",
|
|
73
|
+
);
|
|
74
|
+
return runtimeConfigPath;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getBrowserOverlayScript() {
|
|
78
|
+
if (!cachedBrowserScript) {
|
|
79
|
+
cachedBrowserScript = fs.readFileSync(
|
|
80
|
+
path.join(__dirname, "automation-overlay.browser.js"),
|
|
81
|
+
"utf8",
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
return cachedBrowserScript;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function stripLeadingFlags(tokens) {
|
|
88
|
+
let i = 0;
|
|
89
|
+
while (i < tokens.length) {
|
|
90
|
+
const t = tokens[i];
|
|
91
|
+
if (t === "--raw" || t === "--json") {
|
|
92
|
+
i += 1;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (t.startsWith("-s=")) {
|
|
96
|
+
i += 1;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
return tokens.slice(i);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function truncate(text, max = 48) {
|
|
105
|
+
const s = String(text || "")
|
|
106
|
+
.replace(/\s+/g, " ")
|
|
107
|
+
.trim();
|
|
108
|
+
if (s.length <= max) return s;
|
|
109
|
+
return `${s.slice(0, max - 1)}…`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function describeOverlayPayload(tokens, phase) {
|
|
113
|
+
const core = stripLeadingFlags(tokens);
|
|
114
|
+
const command = core[0];
|
|
115
|
+
if (!command) {
|
|
116
|
+
return {
|
|
117
|
+
title: "helixlife-v5-cli",
|
|
118
|
+
status: phase === "after" ? "已完成" : "执行中...",
|
|
119
|
+
detail: "CLI自动化操作中",
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const args = core.slice(1).filter((t) => !t.startsWith("--"));
|
|
124
|
+
let title = command;
|
|
125
|
+
let detail = args.length ? truncate(args.join(" ")) : "CLI自动化操作中";
|
|
126
|
+
|
|
127
|
+
switch (command) {
|
|
128
|
+
case "click":
|
|
129
|
+
case "dblclick":
|
|
130
|
+
case "hover":
|
|
131
|
+
case "check":
|
|
132
|
+
case "uncheck":
|
|
133
|
+
title = command;
|
|
134
|
+
detail = truncate(args[0] || "元素", 40);
|
|
135
|
+
break;
|
|
136
|
+
case "fill":
|
|
137
|
+
title = "fill";
|
|
138
|
+
detail = truncate(args[0] || "输入框", 40);
|
|
139
|
+
break;
|
|
140
|
+
case "type":
|
|
141
|
+
title = "type";
|
|
142
|
+
detail = truncate(args[0] || "", 32);
|
|
143
|
+
break;
|
|
144
|
+
case "goto":
|
|
145
|
+
case "open":
|
|
146
|
+
title = command;
|
|
147
|
+
detail = truncate(args[0] || "页面", 56);
|
|
148
|
+
break;
|
|
149
|
+
case "snapshot":
|
|
150
|
+
title = "snapshot";
|
|
151
|
+
detail = "页面验收";
|
|
152
|
+
break;
|
|
153
|
+
case "run-code":
|
|
154
|
+
title = "run-code";
|
|
155
|
+
detail = truncate(args[0] || "脚本", 40);
|
|
156
|
+
break;
|
|
157
|
+
case "press":
|
|
158
|
+
title = "press";
|
|
159
|
+
detail = truncate(args[0] || "按键", 24);
|
|
160
|
+
break;
|
|
161
|
+
case "select":
|
|
162
|
+
title = "select";
|
|
163
|
+
detail = truncate(args.join(" "), 40);
|
|
164
|
+
break;
|
|
165
|
+
case "upload":
|
|
166
|
+
title = "upload";
|
|
167
|
+
detail = truncate(args[0] || "文件", 40);
|
|
168
|
+
break;
|
|
169
|
+
case "eval":
|
|
170
|
+
title = "eval";
|
|
171
|
+
detail = "读取页面状态";
|
|
172
|
+
break;
|
|
173
|
+
default:
|
|
174
|
+
title = command;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
title,
|
|
180
|
+
status: phase === "after" ? "已完成" : "执行中...",
|
|
181
|
+
detail: phase === "after" ? "CLI自动化操作中" : detail || "CLI自动化操作中",
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function shouldUpdateOverlay(tokens) {
|
|
186
|
+
const core = stripLeadingFlags(tokens);
|
|
187
|
+
const command = core[0];
|
|
188
|
+
if (!command) return false;
|
|
189
|
+
if (OVERLAY_SKIP_COMMANDS.has(command)) return false;
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function shouldInjectOpenConfig(tokens) {
|
|
194
|
+
const core = stripLeadingFlags(tokens);
|
|
195
|
+
const command = core[0];
|
|
196
|
+
if (!command || !OVERLAY_SESSION_OPEN_COMMANDS.has(command)) return false;
|
|
197
|
+
return !tokens.some((t) => t === "--config" || t.startsWith("--config="));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function injectOpenConfig(tokens) {
|
|
201
|
+
if (!isOverlayEnabled() || !shouldInjectOpenConfig(tokens)) {
|
|
202
|
+
return tokens;
|
|
203
|
+
}
|
|
204
|
+
const configPath = resolveCliConfigPath();
|
|
205
|
+
const next = [...tokens];
|
|
206
|
+
const core = stripLeadingFlags(tokens);
|
|
207
|
+
const insertAt = tokens.indexOf(core[0]);
|
|
208
|
+
next.splice(insertAt + 1, 0, `--config=${configPath}`);
|
|
209
|
+
return next;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function buildOverlayRunCode(payload) {
|
|
213
|
+
const browserScript = getBrowserOverlayScript();
|
|
214
|
+
const payloadJson = JSON.stringify(payload);
|
|
215
|
+
return [
|
|
216
|
+
"async page => {",
|
|
217
|
+
` const browserScript = ${JSON.stringify(browserScript)};`,
|
|
218
|
+
` const payload = ${payloadJson};`,
|
|
219
|
+
" await page.evaluate(({ script, data }) => {",
|
|
220
|
+
" // eslint-disable-next-line no-eval",
|
|
221
|
+
" eval(script);",
|
|
222
|
+
" if (window.__helixCliOverlay) window.__helixCliOverlay.update(data);",
|
|
223
|
+
" }, { script: browserScript, data: payload });",
|
|
224
|
+
"}",
|
|
225
|
+
].join("\n");
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
module.exports = {
|
|
229
|
+
OVERLAY_SKIP_COMMANDS,
|
|
230
|
+
isOverlayEnabled,
|
|
231
|
+
resolveCliConfigPath,
|
|
232
|
+
stripLeadingFlags,
|
|
233
|
+
describeOverlayPayload,
|
|
234
|
+
shouldUpdateOverlay,
|
|
235
|
+
shouldInjectOpenConfig,
|
|
236
|
+
injectOpenConfig,
|
|
237
|
+
buildOverlayRunCode,
|
|
238
|
+
};
|
package/lib/cli.js
CHANGED
|
@@ -4,6 +4,13 @@ const path = require('node:path');
|
|
|
4
4
|
const { spawnSync } = require('node:child_process');
|
|
5
5
|
|
|
6
6
|
const PACKAGE_JSON = require(path.join(__dirname, '..', 'package.json'));
|
|
7
|
+
const {
|
|
8
|
+
isOverlayEnabled,
|
|
9
|
+
injectOpenConfig,
|
|
10
|
+
shouldUpdateOverlay,
|
|
11
|
+
describeOverlayPayload,
|
|
12
|
+
buildOverlayRunCode,
|
|
13
|
+
} = require('./automation-overlay');
|
|
7
14
|
|
|
8
15
|
/** 默认快照/下载等工作区目录名(相对 cwd),替代引擎默认的 .playwright-cli */
|
|
9
16
|
const DEFAULT_OUTPUT_DIR_NAME = 'helixlife-v5-cli';
|
|
@@ -35,9 +42,9 @@ function buildChildEnv() {
|
|
|
35
42
|
* 将参数原样交给底层浏览器自动化引擎,返回子进程退出码。
|
|
36
43
|
* 使用 node 直接执行入口脚本,避免依赖 npx、Shell 与 PATH,在 Windows / macOS 上一致。
|
|
37
44
|
*/
|
|
38
|
-
function runPlaywrightCliPassthrough(args) {
|
|
45
|
+
function runPlaywrightCliPassthrough(args, options = {}) {
|
|
39
46
|
const result = spawnSync(process.execPath, [playwrightCliEntry(), ...args], {
|
|
40
|
-
stdio: 'inherit',
|
|
47
|
+
stdio: options.quiet ? ['ignore', 'ignore', 'ignore'] : 'inherit',
|
|
41
48
|
env: buildChildEnv(),
|
|
42
49
|
windowsHide: true,
|
|
43
50
|
});
|
|
@@ -51,6 +58,27 @@ function runPlaywrightCliPassthrough(args) {
|
|
|
51
58
|
return result.status === null || result.status === undefined ? 1 : result.status;
|
|
52
59
|
}
|
|
53
60
|
|
|
61
|
+
function updateAutomationOverlay(tokens, phase) {
|
|
62
|
+
if (!isOverlayEnabled() || !shouldUpdateOverlay(tokens)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const payload = describeOverlayPayload(tokens, phase);
|
|
66
|
+
const code = buildOverlayRunCode(payload);
|
|
67
|
+
runPlaywrightCliPassthrough(['run-code', code], { quiet: true });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function runPlaywrightCliWithOverlay(tokens) {
|
|
71
|
+
const args = injectOpenConfig(tokens);
|
|
72
|
+
if (isOverlayEnabled() && shouldUpdateOverlay(args)) {
|
|
73
|
+
updateAutomationOverlay(args, 'before');
|
|
74
|
+
}
|
|
75
|
+
const code = runPlaywrightCliPassthrough(args);
|
|
76
|
+
if (code === 0 && isOverlayEnabled() && shouldUpdateOverlay(args)) {
|
|
77
|
+
updateAutomationOverlay(args, 'after');
|
|
78
|
+
}
|
|
79
|
+
return code;
|
|
80
|
+
}
|
|
81
|
+
|
|
54
82
|
function parseHelixFlags(tokens, startIndex) {
|
|
55
83
|
const options = {
|
|
56
84
|
headless: false,
|
|
@@ -114,6 +142,10 @@ function printHelp() {
|
|
|
114
142
|
console.log(
|
|
115
143
|
` HELIX_OUTPUT_DIR / PLAYWRIGHT_MCP_OUTPUT_DIR(默认输出目录 <cwd>/${DEFAULT_OUTPUT_DIR_NAME})`
|
|
116
144
|
);
|
|
145
|
+
console.log(
|
|
146
|
+
' HELIX_AUTOMATION_OVERLAY(设为 0/false/off 可关闭右上角机器操作浮层,默认开启)'
|
|
147
|
+
);
|
|
148
|
+
console.log(' HELIX_CLI_CONFIG(自定义 Playwright CLI 配置文件路径)');
|
|
117
149
|
}
|
|
118
150
|
|
|
119
151
|
function getBaseUrl() {
|
|
@@ -130,12 +162,12 @@ function helixHome(options) {
|
|
|
130
162
|
if (!options.headless) {
|
|
131
163
|
openArgs.push('--headed');
|
|
132
164
|
}
|
|
133
|
-
const code =
|
|
165
|
+
const code = runPlaywrightCliWithOverlay(openArgs);
|
|
134
166
|
if (code !== 0) {
|
|
135
167
|
return code;
|
|
136
168
|
}
|
|
137
169
|
console.error(`[${PACKAGE_JSON.name}] opened: ${baseUrl}`);
|
|
138
|
-
return
|
|
170
|
+
return runPlaywrightCliWithOverlay(['eval', 'document.title']);
|
|
139
171
|
}
|
|
140
172
|
|
|
141
173
|
function helixDoctor(options) {
|
|
@@ -198,7 +230,7 @@ async function main(argv = process.argv) {
|
|
|
198
230
|
return 2;
|
|
199
231
|
}
|
|
200
232
|
|
|
201
|
-
return
|
|
233
|
+
return runPlaywrightCliWithOverlay(tokens);
|
|
202
234
|
}
|
|
203
235
|
|
|
204
236
|
main.printHelp = printHelp;
|