@vforsh/argus 0.1.7 → 0.1.8
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/.tsbuildinfo +1 -1
- package/dist/argus.js +474 -131
- package/dist/cli/register/registerDom.d.ts.map +1 -1
- package/dist/cli/register/registerDom.js +17 -0
- package/dist/cli/register/registerDom.js.map +1 -1
- package/dist/commands/domSetFile.d.ts.map +1 -1
- package/dist/commands/domSetFile.js +5 -0
- package/dist/commands/domSetFile.js.map +1 -1
- package/dist/commands/domSubmit.d.ts +10 -0
- package/dist/commands/domSubmit.d.ts.map +1 -0
- package/dist/commands/domSubmit.js +78 -0
- package/dist/commands/domSubmit.js.map +1 -0
- package/package.json +1 -1
package/dist/argus.js
CHANGED
|
@@ -5,15 +5,29 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
8
13
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
9
21
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
22
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
23
|
for (let key of __getOwnPropNames(mod))
|
|
12
24
|
if (!__hasOwnProp.call(to, key))
|
|
13
25
|
__defProp(to, key, {
|
|
14
|
-
get: (
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
15
27
|
enumerable: true
|
|
16
28
|
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
17
31
|
return to;
|
|
18
32
|
};
|
|
19
33
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
@@ -5211,16 +5225,72 @@ var buildModifyFunction = (options) => {
|
|
|
5211
5225
|
}
|
|
5212
5226
|
};
|
|
5213
5227
|
// ../argus-watcher/dist/cdp/dom/setFile.js
|
|
5228
|
+
var DISPATCH_FILE_EVENTS_AND_GET_COUNT = `function() {
|
|
5229
|
+
var el = this;
|
|
5230
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
5231
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
5232
|
+
return el.files ? el.files.length : 0;
|
|
5233
|
+
}`;
|
|
5234
|
+
var getBackendNodeId = async (session, nodeId) => {
|
|
5235
|
+
const described = await session.sendAndWait("DOM.describeNode", { nodeId });
|
|
5236
|
+
return described.node?.backendNodeId ?? null;
|
|
5237
|
+
};
|
|
5238
|
+
var resolveObjectId = async (session, params) => {
|
|
5239
|
+
const resolved = await session.sendAndWait("DOM.resolveNode", params);
|
|
5240
|
+
return resolved.object?.objectId ?? null;
|
|
5241
|
+
};
|
|
5242
|
+
var trySetFiles = async (session, params, files) => {
|
|
5243
|
+
try {
|
|
5244
|
+
await session.sendAndWait("DOM.setFileInputFiles", {
|
|
5245
|
+
files,
|
|
5246
|
+
...params
|
|
5247
|
+
});
|
|
5248
|
+
return true;
|
|
5249
|
+
} catch {
|
|
5250
|
+
return false;
|
|
5251
|
+
}
|
|
5252
|
+
};
|
|
5253
|
+
var setFilesUsingStableNodeRef = async (session, nodeId, files) => {
|
|
5254
|
+
const backendNodeId = await getBackendNodeId(session, nodeId);
|
|
5255
|
+
const objectIdFromBackendNode = backendNodeId != null ? await resolveObjectId(session, { backendNodeId }) : null;
|
|
5256
|
+
if (objectIdFromBackendNode != null && await trySetFiles(session, { objectId: objectIdFromBackendNode }, files)) {
|
|
5257
|
+
return { backendNodeId, objectId: objectIdFromBackendNode };
|
|
5258
|
+
}
|
|
5259
|
+
if (backendNodeId != null && await trySetFiles(session, { backendNodeId }, files)) {
|
|
5260
|
+
return { backendNodeId, objectId: objectIdFromBackendNode };
|
|
5261
|
+
}
|
|
5262
|
+
const objectIdFromNode = await resolveObjectId(session, { nodeId });
|
|
5263
|
+
if (objectIdFromNode != null && await trySetFiles(session, { objectId: objectIdFromNode }, files)) {
|
|
5264
|
+
return { backendNodeId, objectId: objectIdFromNode };
|
|
5265
|
+
}
|
|
5266
|
+
await session.sendAndWait("DOM.setFileInputFiles", { files, nodeId });
|
|
5267
|
+
return { backendNodeId, objectId: objectIdFromNode };
|
|
5268
|
+
};
|
|
5269
|
+
var setFileOnResolvedNode = async (session, nodeId, files) => {
|
|
5270
|
+
const { backendNodeId, objectId } = await setFilesUsingStableNodeRef(session, nodeId, files);
|
|
5271
|
+
const resolvedObjectId = objectId ?? await resolveObjectId(session, backendNodeId != null ? { backendNodeId } : { nodeId });
|
|
5272
|
+
if (!resolvedObjectId) {
|
|
5273
|
+
return false;
|
|
5274
|
+
}
|
|
5275
|
+
const result = await session.sendAndWait("Runtime.callFunctionOn", {
|
|
5276
|
+
objectId: resolvedObjectId,
|
|
5277
|
+
functionDeclaration: DISPATCH_FILE_EVENTS_AND_GET_COUNT,
|
|
5278
|
+
awaitPromise: false,
|
|
5279
|
+
returnByValue: true
|
|
5280
|
+
});
|
|
5281
|
+
return typeof result.result?.value === "number" && result.result.value > 0;
|
|
5282
|
+
};
|
|
5214
5283
|
var setFileOnResolvedNodes = async (session, nodeIds, files) => {
|
|
5215
5284
|
if (nodeIds.length === 0)
|
|
5216
5285
|
return 0;
|
|
5286
|
+
let updatedCount = 0;
|
|
5217
5287
|
for (const nodeId of nodeIds) {
|
|
5218
|
-
await session
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
}
|
|
5288
|
+
const ok = await setFileOnResolvedNode(session, nodeId, files);
|
|
5289
|
+
if (ok) {
|
|
5290
|
+
updatedCount += 1;
|
|
5291
|
+
}
|
|
5222
5292
|
}
|
|
5223
|
-
return
|
|
5293
|
+
return updatedCount;
|
|
5224
5294
|
};
|
|
5225
5295
|
// ../argus-watcher/dist/cdp/dom/fill.js
|
|
5226
5296
|
var FILL_FUNCTION = `function(value) {
|
|
@@ -5262,79 +5332,6 @@ var fillResolvedNodes = async (session, nodeIds, value) => {
|
|
|
5262
5332
|
}
|
|
5263
5333
|
return nodeIds.length;
|
|
5264
5334
|
};
|
|
5265
|
-
// ../argus-watcher/dist/http/routes/postDomTree.js
|
|
5266
|
-
var handle11 = async (req, res, _url, ctx) => {
|
|
5267
|
-
const payload = await readJsonBody(req, res);
|
|
5268
|
-
if (!payload) {
|
|
5269
|
-
return;
|
|
5270
|
-
}
|
|
5271
|
-
if (!payload.selector || typeof payload.selector !== "string") {
|
|
5272
|
-
return respondInvalidBody(res, "selector is required");
|
|
5273
|
-
}
|
|
5274
|
-
const all = payload.all ?? false;
|
|
5275
|
-
if (typeof all !== "boolean") {
|
|
5276
|
-
return respondInvalidBody(res, "all must be a boolean");
|
|
5277
|
-
}
|
|
5278
|
-
emitRequest(ctx, res, "dom/tree");
|
|
5279
|
-
try {
|
|
5280
|
-
const response = await fetchDomSubtreeBySelector(ctx.cdpSession, {
|
|
5281
|
-
selector: payload.selector,
|
|
5282
|
-
depth: payload.depth,
|
|
5283
|
-
maxNodes: payload.maxNodes,
|
|
5284
|
-
all,
|
|
5285
|
-
text: payload.text
|
|
5286
|
-
});
|
|
5287
|
-
if (!all && response.matches > 1) {
|
|
5288
|
-
return respondJson(res, {
|
|
5289
|
-
ok: false,
|
|
5290
|
-
error: {
|
|
5291
|
-
message: `Selector matched ${response.matches} elements; pass all=true to return all matches`,
|
|
5292
|
-
code: "multiple_matches"
|
|
5293
|
-
}
|
|
5294
|
-
}, 400);
|
|
5295
|
-
}
|
|
5296
|
-
respondJson(res, response);
|
|
5297
|
-
} catch (error) {
|
|
5298
|
-
respondError(res, error);
|
|
5299
|
-
}
|
|
5300
|
-
};
|
|
5301
|
-
|
|
5302
|
-
// ../argus-watcher/dist/http/routes/postDomInfo.js
|
|
5303
|
-
var handle12 = async (req, res, _url, ctx) => {
|
|
5304
|
-
const payload = await readJsonBody(req, res);
|
|
5305
|
-
if (!payload) {
|
|
5306
|
-
return;
|
|
5307
|
-
}
|
|
5308
|
-
if (!payload.selector || typeof payload.selector !== "string") {
|
|
5309
|
-
return respondInvalidBody(res, "selector is required");
|
|
5310
|
-
}
|
|
5311
|
-
const all = payload.all ?? false;
|
|
5312
|
-
if (typeof all !== "boolean") {
|
|
5313
|
-
return respondInvalidBody(res, "all must be a boolean");
|
|
5314
|
-
}
|
|
5315
|
-
emitRequest(ctx, res, "dom/info");
|
|
5316
|
-
try {
|
|
5317
|
-
const response = await fetchDomInfoBySelector(ctx.cdpSession, {
|
|
5318
|
-
selector: payload.selector,
|
|
5319
|
-
all,
|
|
5320
|
-
outerHtmlMaxChars: payload.outerHtmlMaxChars,
|
|
5321
|
-
text: payload.text
|
|
5322
|
-
});
|
|
5323
|
-
if (!all && response.matches > 1) {
|
|
5324
|
-
return respondJson(res, {
|
|
5325
|
-
ok: false,
|
|
5326
|
-
error: {
|
|
5327
|
-
message: `Selector matched ${response.matches} elements; pass all=true to return all matches`,
|
|
5328
|
-
code: "multiple_matches"
|
|
5329
|
-
}
|
|
5330
|
-
}, 400);
|
|
5331
|
-
}
|
|
5332
|
-
respondJson(res, response);
|
|
5333
|
-
} catch (error) {
|
|
5334
|
-
respondError(res, error);
|
|
5335
|
-
}
|
|
5336
|
-
};
|
|
5337
|
-
|
|
5338
5335
|
// ../argus-watcher/dist/cdp/mouse.js
|
|
5339
5336
|
var resolveDomSelectorMatches = async (session, selector, all, text) => {
|
|
5340
5337
|
await session.sendAndWait("DOM.enable");
|
|
@@ -5521,6 +5518,205 @@ var createNotInteractableError = (message) => {
|
|
|
5521
5518
|
return error;
|
|
5522
5519
|
};
|
|
5523
5520
|
|
|
5521
|
+
// ../argus-watcher/dist/cdp/dom/submit.js
|
|
5522
|
+
var SUBMIT_DECLARATION = `function(strategy) {
|
|
5523
|
+
var target = this;
|
|
5524
|
+
|
|
5525
|
+
function isForm(el) {
|
|
5526
|
+
return typeof HTMLFormElement !== 'undefined' && el instanceof HTMLFormElement;
|
|
5527
|
+
}
|
|
5528
|
+
|
|
5529
|
+
function resolveForm(el) {
|
|
5530
|
+
if (!el) {
|
|
5531
|
+
return null;
|
|
5532
|
+
}
|
|
5533
|
+
if (isForm(el)) {
|
|
5534
|
+
return el;
|
|
5535
|
+
}
|
|
5536
|
+
if (el.form) {
|
|
5537
|
+
return el.form;
|
|
5538
|
+
}
|
|
5539
|
+
if (typeof el.closest === 'function') {
|
|
5540
|
+
return el.closest('form');
|
|
5541
|
+
}
|
|
5542
|
+
return null;
|
|
5543
|
+
}
|
|
5544
|
+
|
|
5545
|
+
function resolveSubmitter(el, form) {
|
|
5546
|
+
if (!el || !form || isForm(el)) {
|
|
5547
|
+
return undefined;
|
|
5548
|
+
}
|
|
5549
|
+
if (
|
|
5550
|
+
typeof HTMLElement !== 'undefined'
|
|
5551
|
+
&& el instanceof HTMLElement
|
|
5552
|
+
&& el.form === form
|
|
5553
|
+
&& (
|
|
5554
|
+
(typeof HTMLButtonElement !== 'undefined' && el instanceof HTMLButtonElement)
|
|
5555
|
+
|| (
|
|
5556
|
+
typeof HTMLInputElement !== 'undefined'
|
|
5557
|
+
&& el instanceof HTMLInputElement
|
|
5558
|
+
&& (el.type === 'submit' || el.type === 'image')
|
|
5559
|
+
)
|
|
5560
|
+
)
|
|
5561
|
+
) {
|
|
5562
|
+
return el;
|
|
5563
|
+
}
|
|
5564
|
+
return undefined;
|
|
5565
|
+
}
|
|
5566
|
+
|
|
5567
|
+
function submitElement(el, submitter) {
|
|
5568
|
+
if (!el) {
|
|
5569
|
+
return false;
|
|
5570
|
+
}
|
|
5571
|
+
if (typeof el.requestSubmit === 'function') {
|
|
5572
|
+
try {
|
|
5573
|
+
if (submitter !== undefined) {
|
|
5574
|
+
el.requestSubmit(submitter);
|
|
5575
|
+
} else {
|
|
5576
|
+
el.requestSubmit();
|
|
5577
|
+
}
|
|
5578
|
+
} catch (_) {
|
|
5579
|
+
el.requestSubmit();
|
|
5580
|
+
}
|
|
5581
|
+
return true;
|
|
5582
|
+
}
|
|
5583
|
+
if (typeof el.submit === 'function') {
|
|
5584
|
+
el.submit();
|
|
5585
|
+
return true;
|
|
5586
|
+
}
|
|
5587
|
+
var event = new Event('submit', { bubbles: true, cancelable: true });
|
|
5588
|
+
el.dispatchEvent(event);
|
|
5589
|
+
return true;
|
|
5590
|
+
}
|
|
5591
|
+
|
|
5592
|
+
var nearestForm = resolveForm(target);
|
|
5593
|
+
var submitter = resolveSubmitter(target, nearestForm);
|
|
5594
|
+
|
|
5595
|
+
if (strategy === 'form') {
|
|
5596
|
+
return submitElement(nearestForm, submitter);
|
|
5597
|
+
}
|
|
5598
|
+
|
|
5599
|
+
if (strategy === 'self') {
|
|
5600
|
+
return submitElement(target);
|
|
5601
|
+
}
|
|
5602
|
+
|
|
5603
|
+
if (submitElement(nearestForm, submitter)) {
|
|
5604
|
+
return true;
|
|
5605
|
+
}
|
|
5606
|
+
|
|
5607
|
+
return submitElement(target);
|
|
5608
|
+
}`;
|
|
5609
|
+
var submitResolvedNode = async (session, nodeId, strategy) => {
|
|
5610
|
+
await scrollIntoView(session, nodeId);
|
|
5611
|
+
const resolved = await session.sendAndWait("DOM.resolveNode", { nodeId });
|
|
5612
|
+
const objectId = resolved.object?.objectId;
|
|
5613
|
+
if (!objectId) {
|
|
5614
|
+
return false;
|
|
5615
|
+
}
|
|
5616
|
+
const result = await session.sendAndWait("Runtime.callFunctionOn", {
|
|
5617
|
+
objectId,
|
|
5618
|
+
functionDeclaration: SUBMIT_DECLARATION,
|
|
5619
|
+
arguments: [{ value: strategy }],
|
|
5620
|
+
awaitPromise: false,
|
|
5621
|
+
returnByValue: true
|
|
5622
|
+
});
|
|
5623
|
+
return result.result?.value === true;
|
|
5624
|
+
};
|
|
5625
|
+
var submitResolvedNodes = async (session, nodeIds, strategy) => {
|
|
5626
|
+
if (nodeIds.length === 0) {
|
|
5627
|
+
return 0;
|
|
5628
|
+
}
|
|
5629
|
+
let submittedCount = 0;
|
|
5630
|
+
for (const nodeId of nodeIds) {
|
|
5631
|
+
const ok = await submitResolvedNode(session, nodeId, strategy);
|
|
5632
|
+
if (ok) {
|
|
5633
|
+
submittedCount += 1;
|
|
5634
|
+
}
|
|
5635
|
+
}
|
|
5636
|
+
return submittedCount;
|
|
5637
|
+
};
|
|
5638
|
+
var submitElements = async (session, options) => {
|
|
5639
|
+
await session.sendAndWait("DOM.enable");
|
|
5640
|
+
const all = options.all ?? false;
|
|
5641
|
+
const waitMs = options.wait ?? 0;
|
|
5642
|
+
const strategy = options.strategy ?? "auto";
|
|
5643
|
+
const result = waitMs > 0 ? await waitForSelectorMatches(session, options.selector, all, options.text, waitMs) : await resolveSelectorMatches(session, await getDomRootId(session), options.selector, all, options.text);
|
|
5644
|
+
const submittedCount = await submitResolvedNodes(session, result.nodeIds, strategy);
|
|
5645
|
+
return { allNodeIds: result.allNodeIds, submittedCount };
|
|
5646
|
+
};
|
|
5647
|
+
// ../argus-watcher/dist/http/routes/postDomTree.js
|
|
5648
|
+
var handle11 = async (req, res, _url, ctx) => {
|
|
5649
|
+
const payload = await readJsonBody(req, res);
|
|
5650
|
+
if (!payload) {
|
|
5651
|
+
return;
|
|
5652
|
+
}
|
|
5653
|
+
if (!payload.selector || typeof payload.selector !== "string") {
|
|
5654
|
+
return respondInvalidBody(res, "selector is required");
|
|
5655
|
+
}
|
|
5656
|
+
const all = payload.all ?? false;
|
|
5657
|
+
if (typeof all !== "boolean") {
|
|
5658
|
+
return respondInvalidBody(res, "all must be a boolean");
|
|
5659
|
+
}
|
|
5660
|
+
emitRequest(ctx, res, "dom/tree");
|
|
5661
|
+
try {
|
|
5662
|
+
const response = await fetchDomSubtreeBySelector(ctx.cdpSession, {
|
|
5663
|
+
selector: payload.selector,
|
|
5664
|
+
depth: payload.depth,
|
|
5665
|
+
maxNodes: payload.maxNodes,
|
|
5666
|
+
all,
|
|
5667
|
+
text: payload.text
|
|
5668
|
+
});
|
|
5669
|
+
if (!all && response.matches > 1) {
|
|
5670
|
+
return respondJson(res, {
|
|
5671
|
+
ok: false,
|
|
5672
|
+
error: {
|
|
5673
|
+
message: `Selector matched ${response.matches} elements; pass all=true to return all matches`,
|
|
5674
|
+
code: "multiple_matches"
|
|
5675
|
+
}
|
|
5676
|
+
}, 400);
|
|
5677
|
+
}
|
|
5678
|
+
respondJson(res, response);
|
|
5679
|
+
} catch (error) {
|
|
5680
|
+
respondError(res, error);
|
|
5681
|
+
}
|
|
5682
|
+
};
|
|
5683
|
+
|
|
5684
|
+
// ../argus-watcher/dist/http/routes/postDomInfo.js
|
|
5685
|
+
var handle12 = async (req, res, _url, ctx) => {
|
|
5686
|
+
const payload = await readJsonBody(req, res);
|
|
5687
|
+
if (!payload) {
|
|
5688
|
+
return;
|
|
5689
|
+
}
|
|
5690
|
+
if (!payload.selector || typeof payload.selector !== "string") {
|
|
5691
|
+
return respondInvalidBody(res, "selector is required");
|
|
5692
|
+
}
|
|
5693
|
+
const all = payload.all ?? false;
|
|
5694
|
+
if (typeof all !== "boolean") {
|
|
5695
|
+
return respondInvalidBody(res, "all must be a boolean");
|
|
5696
|
+
}
|
|
5697
|
+
emitRequest(ctx, res, "dom/info");
|
|
5698
|
+
try {
|
|
5699
|
+
const response = await fetchDomInfoBySelector(ctx.cdpSession, {
|
|
5700
|
+
selector: payload.selector,
|
|
5701
|
+
all,
|
|
5702
|
+
outerHtmlMaxChars: payload.outerHtmlMaxChars,
|
|
5703
|
+
text: payload.text
|
|
5704
|
+
});
|
|
5705
|
+
if (!all && response.matches > 1) {
|
|
5706
|
+
return respondJson(res, {
|
|
5707
|
+
ok: false,
|
|
5708
|
+
error: {
|
|
5709
|
+
message: `Selector matched ${response.matches} elements; pass all=true to return all matches`,
|
|
5710
|
+
code: "multiple_matches"
|
|
5711
|
+
}
|
|
5712
|
+
}, 400);
|
|
5713
|
+
}
|
|
5714
|
+
respondJson(res, response);
|
|
5715
|
+
} catch (error) {
|
|
5716
|
+
respondError(res, error);
|
|
5717
|
+
}
|
|
5718
|
+
};
|
|
5719
|
+
|
|
5524
5720
|
// ../argus-watcher/dist/http/routes/postDomHover.js
|
|
5525
5721
|
var handle13 = async (req, res, _url, ctx) => {
|
|
5526
5722
|
const payload = await readJsonBody(req, res);
|
|
@@ -6001,6 +6197,15 @@ var handle19 = async (req, res, _url, ctx) => {
|
|
|
6001
6197
|
}, 400);
|
|
6002
6198
|
}
|
|
6003
6199
|
const updatedCount = await setFileOnResolvedNodes(ctx.cdpSession, nodeIds, payload.files);
|
|
6200
|
+
if (nodeIds.length > 0 && updatedCount === 0) {
|
|
6201
|
+
return respondJson(res, {
|
|
6202
|
+
ok: false,
|
|
6203
|
+
error: {
|
|
6204
|
+
message: "Matched file input element(s), but none accepted files after DOM.setFileInputFiles + input/change dispatch",
|
|
6205
|
+
code: "set_file_failed"
|
|
6206
|
+
}
|
|
6207
|
+
}, 500);
|
|
6208
|
+
}
|
|
6004
6209
|
const response = { ok: true, matches: allNodeIds.length, updated: updatedCount };
|
|
6005
6210
|
respondJson(res, response);
|
|
6006
6211
|
} catch (error) {
|
|
@@ -6098,8 +6303,54 @@ var handle21 = async (req, res, _url, ctx) => {
|
|
|
6098
6303
|
}
|
|
6099
6304
|
};
|
|
6100
6305
|
|
|
6101
|
-
// ../argus-watcher/dist/http/routes/
|
|
6306
|
+
// ../argus-watcher/dist/http/routes/postDomSubmit.js
|
|
6102
6307
|
var handle22 = async (req, res, _url, ctx) => {
|
|
6308
|
+
const payload = await readJsonBody(req, res);
|
|
6309
|
+
if (!payload) {
|
|
6310
|
+
return;
|
|
6311
|
+
}
|
|
6312
|
+
if (!payload.selector || typeof payload.selector !== "string") {
|
|
6313
|
+
return respondInvalidBody(res, "selector is required");
|
|
6314
|
+
}
|
|
6315
|
+
const all = payload.all ?? false;
|
|
6316
|
+
if (typeof all !== "boolean") {
|
|
6317
|
+
return respondInvalidBody(res, "all must be a boolean");
|
|
6318
|
+
}
|
|
6319
|
+
const waitMs = payload.wait ?? 0;
|
|
6320
|
+
if (typeof waitMs !== "number" || !Number.isFinite(waitMs) || waitMs < 0) {
|
|
6321
|
+
return respondInvalidBody(res, "wait must be a non-negative number (ms)");
|
|
6322
|
+
}
|
|
6323
|
+
const strategy = payload.strategy ?? "auto";
|
|
6324
|
+
if (strategy !== "auto" && strategy !== "form" && strategy !== "self") {
|
|
6325
|
+
return respondInvalidBody(res, "strategy must be one of: auto, form, self");
|
|
6326
|
+
}
|
|
6327
|
+
emitRequest(ctx, res, "dom/submit");
|
|
6328
|
+
try {
|
|
6329
|
+
const { allNodeIds, submittedCount } = await submitElements(ctx.cdpSession, {
|
|
6330
|
+
selector: payload.selector,
|
|
6331
|
+
all,
|
|
6332
|
+
text: payload.text,
|
|
6333
|
+
wait: waitMs,
|
|
6334
|
+
strategy
|
|
6335
|
+
});
|
|
6336
|
+
if (!all && allNodeIds.length > 1) {
|
|
6337
|
+
return respondJson(res, {
|
|
6338
|
+
ok: false,
|
|
6339
|
+
error: {
|
|
6340
|
+
message: `Selector matched ${allNodeIds.length} elements; pass all=true to submit all matches`,
|
|
6341
|
+
code: "multiple_matches"
|
|
6342
|
+
}
|
|
6343
|
+
}, 400);
|
|
6344
|
+
}
|
|
6345
|
+
const response = { ok: true, matches: allNodeIds.length, submitted: submittedCount };
|
|
6346
|
+
respondJson(res, response);
|
|
6347
|
+
} catch (error) {
|
|
6348
|
+
respondError(res, error);
|
|
6349
|
+
}
|
|
6350
|
+
};
|
|
6351
|
+
|
|
6352
|
+
// ../argus-watcher/dist/http/routes/postDomScroll.js
|
|
6353
|
+
var handle23 = async (req, res, _url, ctx) => {
|
|
6103
6354
|
const payload = await readJsonBody(req, res);
|
|
6104
6355
|
if (!payload) {
|
|
6105
6356
|
return;
|
|
@@ -6168,7 +6419,7 @@ var getViewportSize = async (session) => {
|
|
|
6168
6419
|
};
|
|
6169
6420
|
|
|
6170
6421
|
// ../argus-watcher/dist/http/routes/postDomScrollTo.js
|
|
6171
|
-
var
|
|
6422
|
+
var handle24 = async (req, res, _url, ctx) => {
|
|
6172
6423
|
const payload = await readJsonBody(req, res);
|
|
6173
6424
|
if (!payload) {
|
|
6174
6425
|
return;
|
|
@@ -6227,14 +6478,14 @@ var handle23 = async (req, res, _url, ctx) => {
|
|
|
6227
6478
|
};
|
|
6228
6479
|
|
|
6229
6480
|
// ../argus-watcher/dist/http/routes/getEmulation.js
|
|
6230
|
-
var
|
|
6481
|
+
var handle25 = (_req, res, _url, ctx) => {
|
|
6231
6482
|
emitRequest(ctx, res, "emulation");
|
|
6232
6483
|
const status = ctx.emulationController.getStatus({ attached: ctx.getCdpStatus().attached });
|
|
6233
6484
|
respondJson(res, status);
|
|
6234
6485
|
};
|
|
6235
6486
|
|
|
6236
6487
|
// ../argus-watcher/dist/http/routes/postEmulation.js
|
|
6237
|
-
var
|
|
6488
|
+
var handle26 = async (req, res, _url, ctx) => {
|
|
6238
6489
|
const payload = await readJsonBody(req, res);
|
|
6239
6490
|
if (!payload) {
|
|
6240
6491
|
return;
|
|
@@ -6297,14 +6548,14 @@ var handle25 = async (req, res, _url, ctx) => {
|
|
|
6297
6548
|
};
|
|
6298
6549
|
|
|
6299
6550
|
// ../argus-watcher/dist/http/routes/getThrottle.js
|
|
6300
|
-
var
|
|
6551
|
+
var handle27 = (_req, res, _url, ctx) => {
|
|
6301
6552
|
emitRequest(ctx, res, "throttle");
|
|
6302
6553
|
const status = ctx.throttleController.getStatus({ attached: ctx.getCdpStatus().attached });
|
|
6303
6554
|
respondJson(res, status);
|
|
6304
6555
|
};
|
|
6305
6556
|
|
|
6306
6557
|
// ../argus-watcher/dist/http/routes/postThrottle.js
|
|
6307
|
-
var
|
|
6558
|
+
var handle28 = async (req, res, _url, ctx) => {
|
|
6308
6559
|
const payload = await readJsonBody(req, res);
|
|
6309
6560
|
if (!payload) {
|
|
6310
6561
|
return;
|
|
@@ -6402,7 +6653,7 @@ var buildActionCode = (action, key, value) => {
|
|
|
6402
6653
|
};
|
|
6403
6654
|
|
|
6404
6655
|
// ../argus-watcher/dist/http/routes/postStorageLocal.js
|
|
6405
|
-
var
|
|
6656
|
+
var handle29 = async (req, res, _url, ctx) => {
|
|
6406
6657
|
const payload = await readJsonBody(req, res);
|
|
6407
6658
|
if (!payload) {
|
|
6408
6659
|
return;
|
|
@@ -6427,7 +6678,7 @@ var handle28 = async (req, res, _url, ctx) => {
|
|
|
6427
6678
|
};
|
|
6428
6679
|
|
|
6429
6680
|
// ../argus-watcher/dist/http/routes/postReload.js
|
|
6430
|
-
var
|
|
6681
|
+
var handle30 = async (req, res, _url, ctx) => {
|
|
6431
6682
|
const payload = await readJsonBody(req, res);
|
|
6432
6683
|
if (!payload) {
|
|
6433
6684
|
return;
|
|
@@ -6445,7 +6696,7 @@ var handle29 = async (req, res, _url, ctx) => {
|
|
|
6445
6696
|
};
|
|
6446
6697
|
|
|
6447
6698
|
// ../argus-watcher/dist/http/routes/postShutdown.js
|
|
6448
|
-
var
|
|
6699
|
+
var handle31 = (_req, res, _url, ctx) => {
|
|
6449
6700
|
emitRequest(ctx, res, "shutdown");
|
|
6450
6701
|
const response = { ok: true };
|
|
6451
6702
|
respondJson(res, response);
|
|
@@ -6457,7 +6708,7 @@ var handle30 = (_req, res, _url, ctx) => {
|
|
|
6457
6708
|
};
|
|
6458
6709
|
|
|
6459
6710
|
// ../argus-watcher/dist/http/routes/getTargets.js
|
|
6460
|
-
var
|
|
6711
|
+
var handle32 = async (_req, res, _url, ctx) => {
|
|
6461
6712
|
if (!ctx.sourceHandle?.listTargets) {
|
|
6462
6713
|
return respondJson(res, { ok: false, error: { message: "Not available", code: "not_available" } }, 400);
|
|
6463
6714
|
}
|
|
@@ -6471,7 +6722,7 @@ var handle31 = async (_req, res, _url, ctx) => {
|
|
|
6471
6722
|
};
|
|
6472
6723
|
|
|
6473
6724
|
// ../argus-watcher/dist/http/routes/postAttach.js
|
|
6474
|
-
var
|
|
6725
|
+
var handle33 = async (req, res, _url, ctx) => {
|
|
6475
6726
|
if (!ctx.sourceHandle?.attachTarget) {
|
|
6476
6727
|
return respondJson(res, { ok: false, error: { message: "Not available", code: "not_available" } }, 400);
|
|
6477
6728
|
}
|
|
@@ -6492,7 +6743,7 @@ var handle32 = async (req, res, _url, ctx) => {
|
|
|
6492
6743
|
};
|
|
6493
6744
|
|
|
6494
6745
|
// ../argus-watcher/dist/http/routes/postDetach.js
|
|
6495
|
-
var
|
|
6746
|
+
var handle34 = async (req, res, _url, ctx) => {
|
|
6496
6747
|
if (!ctx.sourceHandle?.detachTarget) {
|
|
6497
6748
|
return respondJson(res, { ok: false, error: { message: "Not available", code: "not_available" } }, 400);
|
|
6498
6749
|
}
|
|
@@ -6535,18 +6786,19 @@ var routes = {
|
|
|
6535
6786
|
"POST /dom/set-file": { handler: handle19 },
|
|
6536
6787
|
"POST /dom/focus": { handler: handle20 },
|
|
6537
6788
|
"POST /dom/fill": { handler: handle21 },
|
|
6538
|
-
"POST /dom/
|
|
6539
|
-
"POST /dom/scroll
|
|
6540
|
-
"
|
|
6541
|
-
"
|
|
6542
|
-
"
|
|
6543
|
-
"
|
|
6544
|
-
"POST /
|
|
6545
|
-
"POST /
|
|
6546
|
-
"POST /
|
|
6547
|
-
"
|
|
6548
|
-
"
|
|
6549
|
-
"POST /
|
|
6789
|
+
"POST /dom/submit": { handler: handle22 },
|
|
6790
|
+
"POST /dom/scroll": { handler: handle23 },
|
|
6791
|
+
"POST /dom/scroll-to": { handler: handle24 },
|
|
6792
|
+
"GET /emulation": { handler: handle25 },
|
|
6793
|
+
"POST /emulation": { handler: handle26 },
|
|
6794
|
+
"GET /throttle": { handler: handle27 },
|
|
6795
|
+
"POST /throttle": { handler: handle28 },
|
|
6796
|
+
"POST /storage/local": { handler: handle29 },
|
|
6797
|
+
"POST /reload": { handler: handle30 },
|
|
6798
|
+
"POST /shutdown": { handler: handle31 },
|
|
6799
|
+
"GET /targets": { handler: handle32, extensionOnly: true },
|
|
6800
|
+
"POST /attach": { handler: handle33, extensionOnly: true },
|
|
6801
|
+
"POST /detach": { handler: handle34, extensionOnly: true }
|
|
6550
6802
|
};
|
|
6551
6803
|
var dispatch = (req, res, url, ctx) => {
|
|
6552
6804
|
const entry = routes[`${req.method} ${url.pathname}`];
|
|
@@ -7123,7 +7375,7 @@ var createTraceRecorder = (options) => {
|
|
|
7123
7375
|
await new Promise((resolve) => state.stream.end(resolve));
|
|
7124
7376
|
};
|
|
7125
7377
|
options.session.onEvent("Tracing.dataCollected", (params) => {
|
|
7126
|
-
if (!active
|
|
7378
|
+
if (!active) {
|
|
7127
7379
|
return;
|
|
7128
7380
|
}
|
|
7129
7381
|
const payload = params;
|
|
@@ -9178,7 +9430,7 @@ class SessionManager {
|
|
|
9178
9430
|
const enabledDomains = new Set;
|
|
9179
9431
|
const tabHandlers = new Map;
|
|
9180
9432
|
this.eventHandlers.set(tabId, tabHandlers);
|
|
9181
|
-
const
|
|
9433
|
+
const handle35 = {
|
|
9182
9434
|
isAttached: () => this.sessions.has(tabId),
|
|
9183
9435
|
sendAndWait: async (method, params, options) => {
|
|
9184
9436
|
if (!this.sessions.has(tabId)) {
|
|
@@ -9220,7 +9472,7 @@ class SessionManager {
|
|
|
9220
9472
|
title,
|
|
9221
9473
|
faviconUrl,
|
|
9222
9474
|
attachedAt: Date.now(),
|
|
9223
|
-
handle:
|
|
9475
|
+
handle: handle35,
|
|
9224
9476
|
enabledDomains
|
|
9225
9477
|
};
|
|
9226
9478
|
this.sessions.set(tabId, session);
|
|
@@ -10372,9 +10624,9 @@ var runStart = async (options) => {
|
|
|
10372
10624
|
artifactsBaseDir = resolvePath(trimmed);
|
|
10373
10625
|
}
|
|
10374
10626
|
const inject = await resolveInjectScript(options.inject, output);
|
|
10375
|
-
let
|
|
10627
|
+
let handle35;
|
|
10376
10628
|
try {
|
|
10377
|
-
|
|
10629
|
+
handle35 = await startWatcher({
|
|
10378
10630
|
id: watcherId,
|
|
10379
10631
|
source: "cdp",
|
|
10380
10632
|
match: Object.keys(match).length > 0 ? match : undefined,
|
|
@@ -10394,7 +10646,7 @@ var runStart = async (options) => {
|
|
|
10394
10646
|
}
|
|
10395
10647
|
const shutdown = async () => {
|
|
10396
10648
|
try {
|
|
10397
|
-
await
|
|
10649
|
+
await handle35.close();
|
|
10398
10650
|
} catch {}
|
|
10399
10651
|
await chrome.closeGracefully();
|
|
10400
10652
|
};
|
|
@@ -10410,23 +10662,23 @@ var runStart = async (options) => {
|
|
|
10410
10662
|
rmSync2(chrome.userDataDir, { recursive: true, force: true });
|
|
10411
10663
|
} catch {}
|
|
10412
10664
|
}
|
|
10413
|
-
|
|
10665
|
+
handle35.close().then(() => process.exit(0));
|
|
10414
10666
|
});
|
|
10415
|
-
|
|
10667
|
+
handle35.events.on("cdpAttached", ({ target }) => {
|
|
10416
10668
|
const typeInfo = target?.type ? ` (type: ${target.type})` : "";
|
|
10417
10669
|
output.writeHuman(`[${watcherId}] CDP attached: ${target?.title} (${target?.url})${typeInfo}`);
|
|
10418
10670
|
});
|
|
10419
|
-
|
|
10671
|
+
handle35.events.on("cdpDetached", ({ reason, target }) => {
|
|
10420
10672
|
output.writeHuman(`[${watcherId}] CDP detached: ${reason} (last target: ${target?.title})`);
|
|
10421
10673
|
});
|
|
10422
10674
|
const result = {
|
|
10423
|
-
id:
|
|
10675
|
+
id: handle35.watcher.id,
|
|
10424
10676
|
chromePid: chrome.chrome.pid,
|
|
10425
10677
|
cdpHost: chrome.cdpHost,
|
|
10426
10678
|
cdpPort: chrome.cdpPort,
|
|
10427
|
-
watcherHost:
|
|
10428
|
-
watcherPort:
|
|
10429
|
-
watcherPid:
|
|
10679
|
+
watcherHost: handle35.watcher.host,
|
|
10680
|
+
watcherPort: handle35.watcher.port,
|
|
10681
|
+
watcherPid: handle35.watcher.pid
|
|
10430
10682
|
};
|
|
10431
10683
|
if (options.json) {
|
|
10432
10684
|
output.writeJson(result);
|
|
@@ -11294,9 +11546,9 @@ var runWatcherStart = async (options) => {
|
|
|
11294
11546
|
if (options.parent?.trim()) {
|
|
11295
11547
|
match.parent = options.parent.trim();
|
|
11296
11548
|
}
|
|
11297
|
-
let
|
|
11549
|
+
let handle35;
|
|
11298
11550
|
try {
|
|
11299
|
-
|
|
11551
|
+
handle35 = await startWatcher({
|
|
11300
11552
|
id: watcherId,
|
|
11301
11553
|
source: sourceMode,
|
|
11302
11554
|
match: sourceMode === "cdp" && Object.keys(match).length > 0 ? match : undefined,
|
|
@@ -11314,10 +11566,10 @@ var runWatcherStart = async (options) => {
|
|
|
11314
11566
|
return;
|
|
11315
11567
|
}
|
|
11316
11568
|
const result = {
|
|
11317
|
-
id:
|
|
11318
|
-
host:
|
|
11319
|
-
port:
|
|
11320
|
-
pid:
|
|
11569
|
+
id: handle35.watcher.id,
|
|
11570
|
+
host: handle35.watcher.host,
|
|
11571
|
+
port: handle35.watcher.port,
|
|
11572
|
+
pid: handle35.watcher.pid,
|
|
11321
11573
|
source: sourceMode,
|
|
11322
11574
|
matchUrl: match.url,
|
|
11323
11575
|
matchType: match.type,
|
|
@@ -11330,7 +11582,7 @@ var runWatcherStart = async (options) => {
|
|
|
11330
11582
|
};
|
|
11331
11583
|
const cleanup = async () => {
|
|
11332
11584
|
try {
|
|
11333
|
-
await
|
|
11585
|
+
await handle35.close();
|
|
11334
11586
|
} catch {}
|
|
11335
11587
|
};
|
|
11336
11588
|
process.on("SIGINT", () => {
|
|
@@ -11339,12 +11591,12 @@ var runWatcherStart = async (options) => {
|
|
|
11339
11591
|
process.on("SIGTERM", () => {
|
|
11340
11592
|
cleanup().then(() => process.exit(0));
|
|
11341
11593
|
});
|
|
11342
|
-
|
|
11594
|
+
handle35.events.on("cdpAttached", ({ target }) => {
|
|
11343
11595
|
const typeInfo = target?.type ? ` (type: ${target.type})` : "";
|
|
11344
|
-
output.writeHuman(`[${
|
|
11596
|
+
output.writeHuman(`[${handle35.watcher.id}] CDP attached: ${target?.title} (${target?.url})${typeInfo}`);
|
|
11345
11597
|
});
|
|
11346
|
-
|
|
11347
|
-
output.writeHuman(`[${
|
|
11598
|
+
handle35.events.on("cdpDetached", ({ reason, target }) => {
|
|
11599
|
+
output.writeHuman(`[${handle35.watcher.id}] CDP detached: ${reason} (last target: ${target?.title})`);
|
|
11348
11600
|
});
|
|
11349
11601
|
if (options.json) {
|
|
11350
11602
|
output.writeJson(result);
|
|
@@ -11556,9 +11808,9 @@ var checkWatcherReachable = async (watcher) => {
|
|
|
11556
11808
|
// dist/commands/watcherNativeHost.js
|
|
11557
11809
|
var runWatcherNativeHost = async (options) => {
|
|
11558
11810
|
const watcherId = options.id?.trim() || "extension";
|
|
11559
|
-
let
|
|
11811
|
+
let handle35;
|
|
11560
11812
|
try {
|
|
11561
|
-
|
|
11813
|
+
handle35 = await startWatcher({
|
|
11562
11814
|
id: watcherId,
|
|
11563
11815
|
source: "extension",
|
|
11564
11816
|
host: "127.0.0.1",
|
|
@@ -11569,10 +11821,10 @@ var runWatcherNativeHost = async (options) => {
|
|
|
11569
11821
|
console.error(`Failed to start watcher: ${error instanceof Error ? error.message : error}`);
|
|
11570
11822
|
process.exit(1);
|
|
11571
11823
|
}
|
|
11572
|
-
console.error(`[NativeHost] Watcher started: id=${
|
|
11824
|
+
console.error(`[NativeHost] Watcher started: id=${handle35.watcher.id} port=${handle35.watcher.port}`);
|
|
11573
11825
|
const cleanup = async () => {
|
|
11574
11826
|
try {
|
|
11575
|
-
await
|
|
11827
|
+
await handle35.close();
|
|
11576
11828
|
} catch {}
|
|
11577
11829
|
};
|
|
11578
11830
|
process.on("SIGINT", () => {
|
|
@@ -14081,11 +14333,91 @@ var runDomSetFile = async (id, options) => {
|
|
|
14081
14333
|
process.exitCode = 1;
|
|
14082
14334
|
return;
|
|
14083
14335
|
}
|
|
14336
|
+
if (successResp.updated === 0) {
|
|
14337
|
+
output.writeWarn(`Matched ${successResp.matches} file input element(s), but none accepted files`);
|
|
14338
|
+
process.exitCode = 1;
|
|
14339
|
+
return;
|
|
14340
|
+
}
|
|
14084
14341
|
const fileLabel = files.length === 1 ? "1 file" : `${files.length} files`;
|
|
14085
14342
|
const elLabel = successResp.updated === 1 ? "1 element" : `${successResp.updated} elements`;
|
|
14086
14343
|
output.writeHuman(`Set ${fileLabel} on ${elLabel} for selector: ${options.selector}`);
|
|
14087
14344
|
};
|
|
14088
14345
|
|
|
14346
|
+
// dist/commands/domSubmit.js
|
|
14347
|
+
var runDomSubmit = async (id, options) => {
|
|
14348
|
+
const output = createOutput(options);
|
|
14349
|
+
if (!options.selector || options.selector.trim() === "") {
|
|
14350
|
+
output.writeWarn("--selector or --testid is required");
|
|
14351
|
+
process.exitCode = 2;
|
|
14352
|
+
return;
|
|
14353
|
+
}
|
|
14354
|
+
let waitMs = 0;
|
|
14355
|
+
if (options.wait != null) {
|
|
14356
|
+
const parsed = parseDurationMs(options.wait);
|
|
14357
|
+
if (parsed == null || parsed < 0) {
|
|
14358
|
+
output.writeWarn("Invalid --wait value: expected a duration like 5s, 500ms, 2m.");
|
|
14359
|
+
process.exitCode = 2;
|
|
14360
|
+
return;
|
|
14361
|
+
}
|
|
14362
|
+
waitMs = parsed;
|
|
14363
|
+
}
|
|
14364
|
+
const strategy = options.strategy ?? "auto";
|
|
14365
|
+
if (strategy !== "auto" && strategy !== "form" && strategy !== "self") {
|
|
14366
|
+
output.writeWarn("Invalid --strategy value: expected auto, form, or self.");
|
|
14367
|
+
process.exitCode = 2;
|
|
14368
|
+
return;
|
|
14369
|
+
}
|
|
14370
|
+
const body = {
|
|
14371
|
+
selector: options.selector,
|
|
14372
|
+
all: options.all ?? false,
|
|
14373
|
+
text: options.text,
|
|
14374
|
+
strategy
|
|
14375
|
+
};
|
|
14376
|
+
if (waitMs > 0) {
|
|
14377
|
+
body.wait = waitMs;
|
|
14378
|
+
}
|
|
14379
|
+
const result = await requestWatcherJson({
|
|
14380
|
+
id,
|
|
14381
|
+
path: "/dom/submit",
|
|
14382
|
+
method: "POST",
|
|
14383
|
+
body,
|
|
14384
|
+
timeoutMs: Math.max(30000, waitMs + 5000),
|
|
14385
|
+
returnErrorResponse: true
|
|
14386
|
+
});
|
|
14387
|
+
if (!result.ok) {
|
|
14388
|
+
writeRequestError(result, output);
|
|
14389
|
+
return;
|
|
14390
|
+
}
|
|
14391
|
+
const response = result.data;
|
|
14392
|
+
if (!response.ok) {
|
|
14393
|
+
const errorResp = response;
|
|
14394
|
+
if (options.json) {
|
|
14395
|
+
output.writeJson(response);
|
|
14396
|
+
} else {
|
|
14397
|
+
output.writeWarn(`Error: ${errorResp.error.message}`);
|
|
14398
|
+
}
|
|
14399
|
+
process.exitCode = 1;
|
|
14400
|
+
return;
|
|
14401
|
+
}
|
|
14402
|
+
const successResp = response;
|
|
14403
|
+
if (options.json) {
|
|
14404
|
+
output.writeJson(successResp);
|
|
14405
|
+
return;
|
|
14406
|
+
}
|
|
14407
|
+
if (successResp.matches === 0) {
|
|
14408
|
+
output.writeWarn(`No element found for selector: ${options.selector}`);
|
|
14409
|
+
process.exitCode = 1;
|
|
14410
|
+
return;
|
|
14411
|
+
}
|
|
14412
|
+
if (successResp.submitted === 0) {
|
|
14413
|
+
output.writeWarn(`Matched ${successResp.matches} element(s), but none could be submitted`);
|
|
14414
|
+
process.exitCode = 1;
|
|
14415
|
+
return;
|
|
14416
|
+
}
|
|
14417
|
+
const label = successResp.submitted === 1 ? "1 element" : `${successResp.submitted} elements`;
|
|
14418
|
+
output.writeHuman(`Submitted ${label} for selector: ${options.selector}`);
|
|
14419
|
+
};
|
|
14420
|
+
|
|
14089
14421
|
// dist/commands/domScroll.js
|
|
14090
14422
|
var runDomScroll = async (id, options) => {
|
|
14091
14423
|
const output = createOutput(options);
|
|
@@ -14548,6 +14880,17 @@ Examples:
|
|
|
14548
14880
|
return;
|
|
14549
14881
|
await runDomSetFile(id, options);
|
|
14550
14882
|
});
|
|
14883
|
+
dom.command("submit").argument("[id]", "Watcher id to query").description("Submit a form or the nearest form for the matched element(s)").option("--selector <css>", "CSS selector for a form or a descendant element").option("--testid <id>", `Shorthand for --selector "[data-testid='<id>']"`).option("--all", "Allow multiple matches (default: error if >1 match)").option("--text <string>", "Filter by textContent (trimmed). Supports /regex/flags syntax").option("--wait <duration>", "Wait for selector to appear (e.g. 5s, 500ms)").option("--strategy <mode>", "Submit strategy: auto (default), form, or self").option("--json", "Output JSON for automation").addHelpText("after", `
|
|
14884
|
+
Examples:
|
|
14885
|
+
$ argus dom submit app --selector "form"
|
|
14886
|
+
$ argus dom submit app --selector "input[type=email]"
|
|
14887
|
+
$ argus dom submit app --selector "button[type=submit]" --strategy form
|
|
14888
|
+
$ argus dom submit app --selector "#login" --wait 5s
|
|
14889
|
+
`).action(async (id, options) => {
|
|
14890
|
+
if (!resolveTestId(options))
|
|
14891
|
+
return;
|
|
14892
|
+
await runDomSubmit(id, options);
|
|
14893
|
+
});
|
|
14551
14894
|
dom.command("scroll").argument("[id]", "Watcher id to query").description("Emulate a touch scroll gesture (fires real scroll/wheel events)").option("--selector <css>", "CSS selector — scroll at element center").option("--testid <id>", `Shorthand for --selector "[data-testid='<id>']"`).option("--pos <x,y>", "Viewport coordinates to scroll at (mutually exclusive with selector)").requiredOption("--by <dx,dy>", "Scroll delta (positive y = scroll down)").option("--all", "Allow multiple matches (default: error if >1 match)").option("--text <string>", "Filter by textContent (trimmed). Supports /regex/flags syntax").option("--json", "Output JSON for automation").addHelpText("after", `
|
|
14552
14895
|
Examples:
|
|
14553
14896
|
$ argus dom scroll app --by 0,300
|