misoai-web 1.0.6 → 1.5.7
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/README.md +5 -349
- package/dist/es/agent.js +165 -428
- package/dist/es/agent.js.map +1 -1
- package/dist/es/bridge-mode-browser.js +10 -9
- package/dist/es/bridge-mode-browser.js.map +1 -1
- package/dist/es/bridge-mode.js +167 -430
- package/dist/es/bridge-mode.js.map +1 -1
- package/dist/es/chrome-extension.js +173 -435
- package/dist/es/chrome-extension.js.map +1 -1
- package/dist/es/index.js +185 -432
- package/dist/es/index.js.map +1 -1
- package/dist/es/midscene-playground.js +165 -428
- package/dist/es/midscene-playground.js.map +1 -1
- package/dist/es/midscene-server.js.map +1 -1
- package/dist/es/playground.js +165 -428
- package/dist/es/playground.js.map +1 -1
- package/dist/es/playwright-report.js +1 -1
- package/dist/es/playwright-report.js.map +1 -1
- package/dist/es/playwright.js +182 -429
- package/dist/es/playwright.js.map +1 -1
- package/dist/es/puppeteer-agent-launcher.js +169 -432
- package/dist/es/puppeteer-agent-launcher.js.map +1 -1
- package/dist/es/puppeteer.js +169 -432
- package/dist/es/puppeteer.js.map +1 -1
- package/dist/es/ui-utils.js.map +1 -1
- package/dist/es/utils.js +7 -4
- package/dist/es/utils.js.map +1 -1
- package/dist/es/yaml.js +29 -3
- package/dist/es/yaml.js.map +1 -1
- package/dist/lib/agent.js +163 -426
- package/dist/lib/agent.js.map +1 -1
- package/dist/lib/bridge-mode-browser.js +10 -9
- package/dist/lib/bridge-mode-browser.js.map +1 -1
- package/dist/lib/bridge-mode.js +165 -428
- package/dist/lib/bridge-mode.js.map +1 -1
- package/dist/lib/chrome-extension.js +171 -433
- package/dist/lib/chrome-extension.js.map +1 -1
- package/dist/lib/index.js +183 -430
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/midscene-playground.js +163 -426
- package/dist/lib/midscene-playground.js.map +1 -1
- package/dist/lib/midscene-server.js.map +1 -1
- package/dist/lib/playground.js +163 -426
- package/dist/lib/playground.js.map +1 -1
- package/dist/lib/playwright-report.js +1 -1
- package/dist/lib/playwright-report.js.map +1 -1
- package/dist/lib/playwright.js +180 -427
- package/dist/lib/playwright.js.map +1 -1
- package/dist/lib/puppeteer-agent-launcher.js +167 -430
- package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
- package/dist/lib/puppeteer.js +167 -430
- package/dist/lib/puppeteer.js.map +1 -1
- package/dist/lib/ui-utils.js.map +1 -1
- package/dist/lib/utils.js +7 -4
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/yaml.js +29 -3
- package/dist/lib/yaml.js.map +1 -1
- package/dist/types/agent.d.ts +13 -51
- package/dist/types/bridge-mode-browser.d.ts +2 -3
- package/dist/types/bridge-mode.d.ts +2 -3
- package/dist/types/{browser-aec1055d.d.ts → browser-9b472ffb.d.ts} +1 -1
- package/dist/types/chrome-extension.d.ts +2 -3
- package/dist/types/index.d.ts +1 -2
- package/dist/types/midscene-server.d.ts +1 -2
- package/dist/types/{page-86ab0fe1.d.ts → page-ed0ecb44.d.ts} +19 -9
- package/dist/types/playground.d.ts +2 -3
- package/dist/types/playwright.d.ts +9 -2
- package/dist/types/puppeteer-agent-launcher.d.ts +1 -2
- package/dist/types/puppeteer.d.ts +6 -5
- package/dist/types/ui-utils.d.ts +1 -1
- package/dist/types/utils.d.ts +1 -2
- package/dist/types/yaml.d.ts +1 -2
- package/iife-script/htmlElement.js +53 -75
- package/iife-script/htmlElementDebug.js +35 -56
- package/package.json +24 -24
- package/LICENSE +0 -21
package/dist/lib/index.js
CHANGED
@@ -60,10 +60,11 @@ var ScriptPlayer = class {
|
|
60
60
|
this.unnamedResultIndex = 0;
|
61
61
|
this.pageAgent = null;
|
62
62
|
this.result = {};
|
63
|
+
const target = script.target || script.web || script.android;
|
63
64
|
if (import_utils.ifInBrowser) {
|
64
65
|
this.output = void 0;
|
65
|
-
} else if (
|
66
|
-
this.output = (0, import_node_path.resolve)(process.cwd(),
|
66
|
+
} else if (target?.output) {
|
67
|
+
this.output = (0, import_node_path.resolve)(process.cwd(), target.output);
|
67
68
|
} else {
|
68
69
|
this.output = (0, import_node_path.join)((0, import_common.getMidsceneRunSubDir)("output"), `${process.pid}.json`);
|
69
70
|
}
|
@@ -137,15 +138,20 @@ var ScriptPlayer = class {
|
|
137
138
|
} else if ("aiAssert" in flowItem) {
|
138
139
|
const assertTask = flowItem;
|
139
140
|
const prompt = assertTask.aiAssert;
|
141
|
+
const msg = assertTask.errorMessage;
|
140
142
|
(0, import_utils.assert)(prompt, "missing prompt for aiAssert");
|
141
143
|
(0, import_utils.assert)(
|
142
144
|
typeof prompt === "string",
|
143
145
|
"prompt for aiAssert must be a string"
|
144
146
|
);
|
145
|
-
await agent.aiAssert(prompt);
|
147
|
+
await agent.aiAssert(prompt, msg);
|
146
148
|
} else if ("aiQuery" in flowItem) {
|
147
149
|
const queryTask = flowItem;
|
148
150
|
const prompt = queryTask.aiQuery;
|
151
|
+
const options = {
|
152
|
+
domIncluded: queryTask.domIncluded,
|
153
|
+
screenshotIncluded: queryTask.screenshotIncluded
|
154
|
+
};
|
149
155
|
(0, import_utils.assert)(prompt, "missing prompt for aiQuery");
|
150
156
|
(0, import_utils.assert)(
|
151
157
|
typeof prompt === "string",
|
@@ -156,6 +162,10 @@ var ScriptPlayer = class {
|
|
156
162
|
} else if ("aiNumber" in flowItem) {
|
157
163
|
const numberTask = flowItem;
|
158
164
|
const prompt = numberTask.aiNumber;
|
165
|
+
const options = {
|
166
|
+
domIncluded: numberTask.domIncluded,
|
167
|
+
screenshotIncluded: numberTask.screenshotIncluded
|
168
|
+
};
|
159
169
|
(0, import_utils.assert)(prompt, "missing prompt for number");
|
160
170
|
(0, import_utils.assert)(
|
161
171
|
typeof prompt === "string",
|
@@ -166,6 +176,10 @@ var ScriptPlayer = class {
|
|
166
176
|
} else if ("aiString" in flowItem) {
|
167
177
|
const stringTask = flowItem;
|
168
178
|
const prompt = stringTask.aiString;
|
179
|
+
const options = {
|
180
|
+
domIncluded: stringTask.domIncluded,
|
181
|
+
screenshotIncluded: stringTask.screenshotIncluded
|
182
|
+
};
|
169
183
|
(0, import_utils.assert)(prompt, "missing prompt for string");
|
170
184
|
(0, import_utils.assert)(
|
171
185
|
typeof prompt === "string",
|
@@ -176,6 +190,10 @@ var ScriptPlayer = class {
|
|
176
190
|
} else if ("aiBoolean" in flowItem) {
|
177
191
|
const booleanTask = flowItem;
|
178
192
|
const prompt = booleanTask.aiBoolean;
|
193
|
+
const options = {
|
194
|
+
domIncluded: booleanTask.domIncluded,
|
195
|
+
screenshotIncluded: booleanTask.screenshotIncluded
|
196
|
+
};
|
179
197
|
(0, import_utils.assert)(prompt, "missing prompt for boolean");
|
180
198
|
(0, import_utils.assert)(
|
181
199
|
typeof prompt === "string",
|
@@ -218,6 +236,9 @@ var ScriptPlayer = class {
|
|
218
236
|
} else if ("aiTap" in flowItem) {
|
219
237
|
const tapTask = flowItem;
|
220
238
|
await agent.aiTap(tapTask.aiTap, tapTask);
|
239
|
+
} else if ("aiRightClick" in flowItem) {
|
240
|
+
const rightClickTask = flowItem;
|
241
|
+
await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);
|
221
242
|
} else if ("aiHover" in flowItem) {
|
222
243
|
const hoverTask = flowItem;
|
223
244
|
await agent.aiHover(hoverTask.aiHover, hoverTask);
|
@@ -240,6 +261,11 @@ var ScriptPlayer = class {
|
|
240
261
|
evaluateJavaScriptTask.javascript
|
241
262
|
);
|
242
263
|
this.setResult(evaluateJavaScriptTask.name, result);
|
264
|
+
} else if ("logScreenshot" in flowItem) {
|
265
|
+
const logScreenshotTask = flowItem;
|
266
|
+
await agent.logScreenshot(logScreenshotTask.logScreenshot, {
|
267
|
+
content: logScreenshotTask.content || ""
|
268
|
+
});
|
243
269
|
} else {
|
244
270
|
throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);
|
245
271
|
}
|
@@ -488,7 +514,8 @@ var WebElementInfo = class {
|
|
488
514
|
id,
|
489
515
|
attributes,
|
490
516
|
indexId,
|
491
|
-
xpaths
|
517
|
+
xpaths,
|
518
|
+
isVisible
|
492
519
|
}) {
|
493
520
|
this.content = content;
|
494
521
|
this.rect = rect;
|
@@ -501,6 +528,7 @@ var WebElementInfo = class {
|
|
501
528
|
this.attributes = attributes;
|
502
529
|
this.indexId = indexId;
|
503
530
|
this.xpaths = xpaths;
|
531
|
+
this.isVisible = isVisible;
|
504
532
|
}
|
505
533
|
};
|
506
534
|
|
@@ -523,14 +551,15 @@ async function parseContextFromWebPage(page, _opt) {
|
|
523
551
|
})
|
524
552
|
]);
|
525
553
|
const webTree = (0, import_extractor.traverseTree)(tree, (elementInfo) => {
|
526
|
-
const { rect, id, content, attributes, locator, indexId } = elementInfo;
|
554
|
+
const { rect, id, content, attributes, locator, indexId, isVisible } = elementInfo;
|
527
555
|
return new WebElementInfo({
|
528
556
|
rect,
|
529
557
|
locator,
|
530
558
|
id,
|
531
559
|
content,
|
532
560
|
attributes,
|
533
|
-
indexId
|
561
|
+
indexId,
|
562
|
+
isVisible
|
534
563
|
});
|
535
564
|
});
|
536
565
|
(0, import_utils4.assert)(screenshotBase64, "screenshotBase64 is required");
|
@@ -560,7 +589,7 @@ function printReportMsg(filepath) {
|
|
560
589
|
(0, import_utils4.logMsg)(`Midscene - report file updated: ${filepath}`);
|
561
590
|
}
|
562
591
|
function replaceIllegalPathCharsAndSpace(str) {
|
563
|
-
return str.replace(/[
|
592
|
+
return str.replace(/[:*?"<>| ]/g, "-");
|
564
593
|
}
|
565
594
|
function forceClosePopup(page, debug7) {
|
566
595
|
page.on("popup", async (popup) => {
|
@@ -874,10 +903,10 @@ var PageTaskExecutor = class {
|
|
874
903
|
if (!taskParam || !taskParam.value) {
|
875
904
|
return;
|
876
905
|
}
|
877
|
-
await this.page.keyboard.type(taskParam.value);
|
878
|
-
} else {
|
879
|
-
await this.page.keyboard.type(taskParam.value);
|
880
906
|
}
|
907
|
+
await this.page.keyboard.type(taskParam.value, {
|
908
|
+
autoDismissKeyboard: taskParam.autoDismissKeyboard
|
909
|
+
});
|
881
910
|
}
|
882
911
|
};
|
883
912
|
tasks.push(taskActionInput);
|
@@ -906,6 +935,22 @@ var PageTaskExecutor = class {
|
|
906
935
|
}
|
907
936
|
};
|
908
937
|
tasks.push(taskActionTap);
|
938
|
+
} else if (plan2.type === "RightClick") {
|
939
|
+
const taskActionRightClick = {
|
940
|
+
type: "Action",
|
941
|
+
subType: "RightClick",
|
942
|
+
thought: plan2.thought,
|
943
|
+
locate: plan2.locate,
|
944
|
+
executor: async (param, { element }) => {
|
945
|
+
(0, import_utils6.assert)(element, "Element not found, cannot right click");
|
946
|
+
await this.page.mouse.click(
|
947
|
+
element.center[0],
|
948
|
+
element.center[1],
|
949
|
+
{ button: "right" }
|
950
|
+
);
|
951
|
+
}
|
952
|
+
};
|
953
|
+
tasks.push(taskActionRightClick);
|
909
954
|
} else if (plan2.type === "Drag") {
|
910
955
|
const taskActionDrag = {
|
911
956
|
type: "Action",
|
@@ -1434,7 +1479,7 @@ var PageTaskExecutor = class {
|
|
1434
1479
|
executor: taskExecutor
|
1435
1480
|
};
|
1436
1481
|
}
|
1437
|
-
async createTypeQueryTask(type, demand) {
|
1482
|
+
async createTypeQueryTask(type, demand, opt) {
|
1438
1483
|
const taskExecutor = new import_misoai_core.Executor(
|
1439
1484
|
taskTitleStr(
|
1440
1485
|
type,
|
@@ -1465,7 +1510,10 @@ var PageTaskExecutor = class {
|
|
1465
1510
|
result: `${type}, ${demand}`
|
1466
1511
|
};
|
1467
1512
|
}
|
1468
|
-
const { data, usage } = await this.insight.extract(
|
1513
|
+
const { data, usage } = await this.insight.extract(
|
1514
|
+
demandInput,
|
1515
|
+
opt
|
1516
|
+
);
|
1469
1517
|
let outputResult = data;
|
1470
1518
|
if (ifTypeRestricted) {
|
1471
1519
|
(0, import_utils6.assert)(data?.result !== void 0, "No result in query data");
|
@@ -1485,17 +1533,17 @@ var PageTaskExecutor = class {
|
|
1485
1533
|
executor: taskExecutor
|
1486
1534
|
};
|
1487
1535
|
}
|
1488
|
-
async query(demand) {
|
1489
|
-
return this.createTypeQueryTask("Query", demand);
|
1536
|
+
async query(demand, opt) {
|
1537
|
+
return this.createTypeQueryTask("Query", demand, opt);
|
1490
1538
|
}
|
1491
|
-
async boolean(prompt) {
|
1492
|
-
return this.createTypeQueryTask("Boolean", prompt);
|
1539
|
+
async boolean(prompt, opt) {
|
1540
|
+
return this.createTypeQueryTask("Boolean", prompt, opt);
|
1493
1541
|
}
|
1494
|
-
async number(prompt) {
|
1495
|
-
return this.createTypeQueryTask("Number", prompt);
|
1542
|
+
async number(prompt, opt) {
|
1543
|
+
return this.createTypeQueryTask("Number", prompt, opt);
|
1496
1544
|
}
|
1497
|
-
async string(prompt) {
|
1498
|
-
return this.createTypeQueryTask("String", prompt);
|
1545
|
+
async string(prompt, opt) {
|
1546
|
+
return this.createTypeQueryTask("String", prompt, opt);
|
1499
1547
|
}
|
1500
1548
|
async assert(assertion) {
|
1501
1549
|
const description = `assert: ${assertion}`;
|
@@ -1631,7 +1679,7 @@ function buildPlans(type, locateParam, param) {
|
|
1631
1679
|
param: locateParam,
|
1632
1680
|
thought: ""
|
1633
1681
|
} : null;
|
1634
|
-
if (type === "Tap" || type === "Hover") {
|
1682
|
+
if (type === "Tap" || type === "Hover" || type === "RightClick") {
|
1635
1683
|
(0, import_utils8.assert)(locateParam, `missing locate info for action "${type}"`);
|
1636
1684
|
(0, import_utils8.assert)(locatePlan, `missing locate info for action "${type}"`);
|
1637
1685
|
const tapPlan = {
|
@@ -1711,7 +1759,7 @@ var import_js_yaml3 = __toESM(require("js-yaml"));
|
|
1711
1759
|
var import_semver = __toESM(require("semver"));
|
1712
1760
|
|
1713
1761
|
// package.json
|
1714
|
-
var version = "1.0.
|
1762
|
+
var version = "1.0.3";
|
1715
1763
|
|
1716
1764
|
// src/common/task-cache.ts
|
1717
1765
|
var debug3 = (0, import_logger3.getDebug)("cache");
|
@@ -1739,70 +1787,44 @@ var TaskCache = class {
|
|
1739
1787
|
this.cache = cacheContent;
|
1740
1788
|
this.cacheOriginalLength = this.cache.caches.length;
|
1741
1789
|
}
|
1742
|
-
matchCache(prompt, type
|
1743
|
-
const contextHash = contextData ? this.generateContextHash(contextData) : void 0;
|
1790
|
+
matchCache(prompt, type) {
|
1744
1791
|
for (let i = 0; i < this.cacheOriginalLength; i++) {
|
1745
1792
|
const item = this.cache.caches[i];
|
1746
1793
|
const key = `${type}:${prompt}:${i}`;
|
1747
|
-
if (item.type
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1794
|
+
if (item.type === type && item.prompt === prompt && !this.matchedCacheIndices.has(key)) {
|
1795
|
+
this.matchedCacheIndices.add(key);
|
1796
|
+
debug3(
|
1797
|
+
"cache found and marked as used, type: %s, prompt: %s, index: %d",
|
1798
|
+
type,
|
1799
|
+
prompt,
|
1800
|
+
i
|
1801
|
+
);
|
1802
|
+
return {
|
1803
|
+
cacheContent: item,
|
1804
|
+
updateFn: (cb) => {
|
1805
|
+
debug3(
|
1806
|
+
"will call updateFn to update cache, type: %s, prompt: %s, index: %d",
|
1807
|
+
type,
|
1808
|
+
prompt,
|
1809
|
+
i
|
1810
|
+
);
|
1811
|
+
cb(item);
|
1812
|
+
debug3(
|
1813
|
+
"cache updated, will flush to file, type: %s, prompt: %s, index: %d",
|
1814
|
+
type,
|
1815
|
+
prompt,
|
1816
|
+
i
|
1817
|
+
);
|
1818
|
+
this.flushCacheToFile();
|
1756
1819
|
}
|
1757
|
-
}
|
1758
|
-
debug3("cache context availability mismatch, type: %s, prompt: %s, index: %d", type, prompt, i);
|
1759
|
-
continue;
|
1760
|
-
}
|
1820
|
+
};
|
1761
1821
|
}
|
1762
|
-
this.matchedCacheIndices.add(key);
|
1763
|
-
debug3(
|
1764
|
-
"cache found and marked as used, type: %s, prompt: %s, index: %d, contextMatch: %s",
|
1765
|
-
type,
|
1766
|
-
prompt,
|
1767
|
-
i,
|
1768
|
-
contextHash ? "yes" : "no-context"
|
1769
|
-
);
|
1770
|
-
return {
|
1771
|
-
cacheContent: item,
|
1772
|
-
updateFn: (cb) => {
|
1773
|
-
debug3(
|
1774
|
-
"will call updateFn to update cache, type: %s, prompt: %s, index: %d",
|
1775
|
-
type,
|
1776
|
-
prompt,
|
1777
|
-
i
|
1778
|
-
);
|
1779
|
-
cb(item);
|
1780
|
-
debug3(
|
1781
|
-
"cache updated, will flush to file, type: %s, prompt: %s, index: %d",
|
1782
|
-
type,
|
1783
|
-
prompt,
|
1784
|
-
i
|
1785
|
-
);
|
1786
|
-
this.flushCacheToFile();
|
1787
|
-
}
|
1788
|
-
};
|
1789
1822
|
}
|
1790
|
-
debug3("no unused cache found, type: %s, prompt: %s
|
1823
|
+
debug3("no unused cache found, type: %s, prompt: %s", type, prompt);
|
1791
1824
|
return void 0;
|
1792
1825
|
}
|
1793
|
-
|
1794
|
-
|
1795
|
-
const stableString = sortedKeys.map((key) => `${key}:${JSON.stringify(contextData[key])}`).join("|");
|
1796
|
-
let hash = 0;
|
1797
|
-
for (let i = 0; i < stableString.length; i++) {
|
1798
|
-
const char = stableString.charCodeAt(i);
|
1799
|
-
hash = (hash << 5) - hash + char;
|
1800
|
-
hash = hash & hash;
|
1801
|
-
}
|
1802
|
-
return hash.toString(36);
|
1803
|
-
}
|
1804
|
-
matchPlanCache(prompt, contextData) {
|
1805
|
-
return this.matchCache(prompt, "plan", contextData);
|
1826
|
+
matchPlanCache(prompt) {
|
1827
|
+
return this.matchCache(prompt, "plan");
|
1806
1828
|
}
|
1807
1829
|
matchLocateCache(prompt) {
|
1808
1830
|
return this.matchCache(prompt, "locate");
|
@@ -1868,8 +1890,14 @@ cache file: ${cacheFile}`
|
|
1868
1890
|
return;
|
1869
1891
|
}
|
1870
1892
|
try {
|
1893
|
+
const dir = (0, import_node_path2.dirname)(this.cacheFilePath);
|
1894
|
+
if (!(0, import_node_fs2.existsSync)(dir)) {
|
1895
|
+
(0, import_node_fs2.mkdirSync)(dir, { recursive: true });
|
1896
|
+
debug3("created cache directory: %s", dir);
|
1897
|
+
}
|
1871
1898
|
const yamlData = import_js_yaml3.default.dump(this.cache);
|
1872
1899
|
(0, import_node_fs2.writeFileSync)(this.cacheFilePath, yamlData);
|
1900
|
+
debug3("cache flushed to file: %s", this.cacheFilePath);
|
1873
1901
|
} catch (err) {
|
1874
1902
|
debug3(
|
1875
1903
|
"write cache to file failed, path: %s, error: %s",
|
@@ -1878,16 +1906,11 @@ cache file: ${cacheFile}`
|
|
1878
1906
|
);
|
1879
1907
|
}
|
1880
1908
|
}
|
1881
|
-
updateOrAppendCacheRecord(newRecord, cachedRecord
|
1909
|
+
updateOrAppendCacheRecord(newRecord, cachedRecord) {
|
1882
1910
|
if (cachedRecord) {
|
1883
1911
|
if (newRecord.type === "plan") {
|
1884
1912
|
cachedRecord.updateFn((cache) => {
|
1885
|
-
|
1886
|
-
planCache.yamlWorkflow = newRecord.yamlWorkflow;
|
1887
|
-
if (contextData) {
|
1888
|
-
planCache.contextHash = this.generateContextHash(contextData);
|
1889
|
-
planCache.contextData = { ...contextData };
|
1890
|
-
}
|
1913
|
+
cache.yamlWorkflow = newRecord.yamlWorkflow;
|
1891
1914
|
});
|
1892
1915
|
} else {
|
1893
1916
|
cachedRecord.updateFn((cache) => {
|
@@ -1895,11 +1918,6 @@ cache file: ${cacheFile}`
|
|
1895
1918
|
});
|
1896
1919
|
}
|
1897
1920
|
} else {
|
1898
|
-
if (newRecord.type === "plan" && contextData) {
|
1899
|
-
const planRecord = newRecord;
|
1900
|
-
planRecord.contextHash = this.generateContextHash(contextData);
|
1901
|
-
planRecord.contextData = { ...contextData };
|
1902
|
-
}
|
1903
1921
|
this.appendCache(newRecord);
|
1904
1922
|
}
|
1905
1923
|
}
|
@@ -1929,13 +1947,10 @@ var PageAgent = class {
|
|
1929
1947
|
generateReport: true,
|
1930
1948
|
autoPrintReportMsg: true,
|
1931
1949
|
groupName: "Midscene Report",
|
1932
|
-
groupDescription: ""
|
1933
|
-
enableCumulativeContext: true,
|
1934
|
-
autoClearContext: false
|
1950
|
+
groupDescription: ""
|
1935
1951
|
},
|
1936
1952
|
opts || {}
|
1937
1953
|
);
|
1938
|
-
this.initializeContextStore();
|
1939
1954
|
if (this.page.pageType === "puppeteer" || this.page.pageType === "playwright") {
|
1940
1955
|
this.page.waitForNavigationTimeout = this.opts.waitForNavigationTimeout || import_constants2.DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;
|
1941
1956
|
this.page.waitForNetworkIdleTimeout = this.opts.waitForNetworkIdleTimeout || import_constants2.DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;
|
@@ -1962,69 +1977,6 @@ var PageAgent = class {
|
|
1962
1977
|
opts?.testId || this.page.pageType || "web"
|
1963
1978
|
);
|
1964
1979
|
}
|
1965
|
-
/**
|
1966
|
-
* Initialize context store for cumulative context functionality
|
1967
|
-
*/
|
1968
|
-
async initializeContextStore() {
|
1969
|
-
if (!this.opts.enableCumulativeContext) {
|
1970
|
-
debug4("Cumulative context disabled via options");
|
1971
|
-
return;
|
1972
|
-
}
|
1973
|
-
try {
|
1974
|
-
const aiModel = await import("misoai-core/ai-model");
|
1975
|
-
this.contextStore = aiModel.getContextStore();
|
1976
|
-
debug4("Context store initialized successfully", {
|
1977
|
-
autoClearContext: this.opts.autoClearContext,
|
1978
|
-
testId: this.opts.testId
|
1979
|
-
});
|
1980
|
-
if (this.opts.autoClearContext) {
|
1981
|
-
this.contextStore.clear();
|
1982
|
-
debug4("Context store cleared due to autoClearContext option");
|
1983
|
-
} else {
|
1984
|
-
const existingData = this.contextStore.getAllData();
|
1985
|
-
const existingSteps = this.contextStore.getRecentSteps(100).length;
|
1986
|
-
debug4("Context store preserving existing data", {
|
1987
|
-
existingDataKeys: Object.keys(existingData),
|
1988
|
-
existingStepsCount: existingSteps
|
1989
|
-
});
|
1990
|
-
}
|
1991
|
-
} catch (error) {
|
1992
|
-
debug4("Failed to initialize context store:", error);
|
1993
|
-
console.warn("⚠️ Could not initialize context store:", error);
|
1994
|
-
}
|
1995
|
-
}
|
1996
|
-
/**
|
1997
|
-
* Get the context store instance
|
1998
|
-
*/
|
1999
|
-
getContextStore() {
|
2000
|
-
return this.contextStore;
|
2001
|
-
}
|
2002
|
-
/**
|
2003
|
-
* Clear the context store
|
2004
|
-
*/
|
2005
|
-
clearContext() {
|
2006
|
-
if (this.contextStore) {
|
2007
|
-
this.contextStore.clear();
|
2008
|
-
}
|
2009
|
-
}
|
2010
|
-
/**
|
2011
|
-
* Get all stored data from context store
|
2012
|
-
*/
|
2013
|
-
getStoredData() {
|
2014
|
-
if (this.contextStore) {
|
2015
|
-
return this.contextStore.getAllData();
|
2016
|
-
}
|
2017
|
-
return {};
|
2018
|
-
}
|
2019
|
-
/**
|
2020
|
-
* Get step summary from context store
|
2021
|
-
*/
|
2022
|
-
getStepSummary() {
|
2023
|
-
if (this.contextStore) {
|
2024
|
-
return this.contextStore.getStepSummary();
|
2025
|
-
}
|
2026
|
-
return "";
|
2027
|
-
}
|
2028
1980
|
async getUIContext(action) {
|
2029
1981
|
if (action && (action === "extract" || action === "assert" || action === "captcha")) {
|
2030
1982
|
return await parseContextFromWebPage(this.page, {
|
@@ -2203,6 +2155,23 @@ var PageAgent = class {
|
|
2203
2155
|
metadata
|
2204
2156
|
};
|
2205
2157
|
}
|
2158
|
+
async aiRightClick(locatePrompt, opt) {
|
2159
|
+
const detailedLocateParam = this.buildDetailedLocateParam(
|
2160
|
+
locatePrompt,
|
2161
|
+
opt
|
2162
|
+
);
|
2163
|
+
const plans = buildPlans("RightClick", detailedLocateParam);
|
2164
|
+
const { executor, output } = await this.taskExecutor.runPlans(
|
2165
|
+
taskTitleStr("RightClick", locateParamStr(detailedLocateParam)),
|
2166
|
+
plans,
|
2167
|
+
{ cacheable: opt?.cacheable }
|
2168
|
+
);
|
2169
|
+
const metadata = this.afterTaskRunning(executor);
|
2170
|
+
return {
|
2171
|
+
result: output,
|
2172
|
+
metadata
|
2173
|
+
};
|
2174
|
+
}
|
2206
2175
|
async aiInput(value, locatePrompt, opt) {
|
2207
2176
|
(0, import_utils12.assert)(
|
2208
2177
|
typeof value === "string",
|
@@ -2260,35 +2229,9 @@ var PageAgent = class {
|
|
2260
2229
|
};
|
2261
2230
|
}
|
2262
2231
|
async aiAction(taskPrompt, opt) {
|
2263
|
-
const originalPrompt = taskPrompt;
|
2264
|
-
let processedPrompt = taskPrompt;
|
2265
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2266
|
-
try {
|
2267
|
-
const storedData = this.contextStore.getAllData();
|
2268
|
-
if (Object.keys(storedData).length > 0) {
|
2269
|
-
debug4("Available data for aiAction:", {
|
2270
|
-
prompt: taskPrompt,
|
2271
|
-
availableData: storedData
|
2272
|
-
});
|
2273
|
-
}
|
2274
|
-
} catch (error) {
|
2275
|
-
debug4("Context store operation failed:", error);
|
2276
|
-
}
|
2277
|
-
}
|
2278
2232
|
const cacheable = opt?.cacheable;
|
2279
2233
|
const isVlmUiTars = (0, import_env2.vlLocateMode)() === "vlm-ui-tars";
|
2280
|
-
|
2281
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2282
|
-
try {
|
2283
|
-
contextData = this.contextStore.getAllData();
|
2284
|
-
if (contextData && Object.keys(contextData).length === 0) {
|
2285
|
-
contextData = void 0;
|
2286
|
-
}
|
2287
|
-
} catch (error) {
|
2288
|
-
debug4("Failed to get context data for cache:", error);
|
2289
|
-
}
|
2290
|
-
}
|
2291
|
-
const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt, contextData);
|
2234
|
+
const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt);
|
2292
2235
|
if (matchedCache && this.taskCache?.isCacheResultUsed) {
|
2293
2236
|
const { executor: executor2 } = await this.taskExecutor.loadYamlFlowAsPlanning(
|
2294
2237
|
taskPrompt,
|
@@ -2298,28 +2241,6 @@ var PageAgent = class {
|
|
2298
2241
|
debug4("matched cache, will call .runYaml to run the action");
|
2299
2242
|
const yaml5 = matchedCache.cacheContent?.yamlWorkflow;
|
2300
2243
|
const result = await this.runYaml(yaml5);
|
2301
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2302
|
-
try {
|
2303
|
-
const executionResult = {
|
2304
|
-
success: true,
|
2305
|
-
actionType: "cached",
|
2306
|
-
description: `Executed cached action: ${processedPrompt}`,
|
2307
|
-
timing: result.metadata?.totalTime
|
2308
|
-
};
|
2309
|
-
this.contextStore.addStep({
|
2310
|
-
type: "action",
|
2311
|
-
summary: `Action: ${processedPrompt} (cached)`,
|
2312
|
-
prompt: processedPrompt,
|
2313
|
-
executionResult
|
2314
|
-
});
|
2315
|
-
debug4("Added cached action step to context store:", {
|
2316
|
-
stepNumber: this.contextStore.getRecentSteps(1)[0]?.stepNumber,
|
2317
|
-
totalSteps: this.contextStore.getRecentSteps(100).length
|
2318
|
-
});
|
2319
|
-
} catch (error) {
|
2320
|
-
debug4("Failed to add cached action step:", error);
|
2321
|
-
}
|
2322
|
-
}
|
2323
2244
|
return {
|
2324
2245
|
result: result.result,
|
2325
2246
|
metadata: metadata2
|
@@ -2344,114 +2265,17 @@ var PageAgent = class {
|
|
2344
2265
|
prompt: taskPrompt,
|
2345
2266
|
yamlWorkflow: yamlFlowStr
|
2346
2267
|
},
|
2347
|
-
matchedCache
|
2348
|
-
contextData
|
2349
|
-
// Pass context data for cache creation
|
2268
|
+
matchedCache
|
2350
2269
|
);
|
2351
2270
|
}
|
2352
2271
|
const metadata = this.afterTaskRunning(executor);
|
2353
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2354
|
-
try {
|
2355
|
-
const executionResult = this.analyzeExecutionResults(executor, originalPrompt);
|
2356
|
-
this.contextStore.addStep({
|
2357
|
-
type: "action",
|
2358
|
-
summary: `Action: ${processedPrompt}`,
|
2359
|
-
prompt: processedPrompt,
|
2360
|
-
executionResult
|
2361
|
-
});
|
2362
|
-
debug4("Added action step with execution result to context store:", {
|
2363
|
-
stepNumber: this.contextStore.getRecentSteps(1)[0]?.stepNumber,
|
2364
|
-
totalSteps: this.contextStore.getRecentSteps(100).length,
|
2365
|
-
executionResult
|
2366
|
-
});
|
2367
|
-
} catch (error) {
|
2368
|
-
debug4("Failed to analyze execution results, adding step without execution result:", error);
|
2369
|
-
try {
|
2370
|
-
this.contextStore.addStep({
|
2371
|
-
type: "action",
|
2372
|
-
summary: `Action: ${processedPrompt}`,
|
2373
|
-
prompt: processedPrompt
|
2374
|
-
});
|
2375
|
-
} catch (stepError) {
|
2376
|
-
debug4("Failed to add action step:", stepError);
|
2377
|
-
}
|
2378
|
-
}
|
2379
|
-
}
|
2380
2272
|
return {
|
2381
2273
|
result: output,
|
2382
2274
|
metadata
|
2383
2275
|
};
|
2384
2276
|
}
|
2385
2277
|
async aiQuery(demand) {
|
2386
|
-
|
2387
|
-
let storageKey;
|
2388
|
-
try {
|
2389
|
-
const aiModel = await import("misoai-core/ai-model");
|
2390
|
-
const contextStore = aiModel.getContextStore();
|
2391
|
-
if (typeof demand === "string") {
|
2392
|
-
const storageInstruction = contextStore.parseStorageInstruction(demand);
|
2393
|
-
if (storageInstruction) {
|
2394
|
-
storageKey = storageInstruction.key;
|
2395
|
-
processedDemand = storageInstruction.cleanText;
|
2396
|
-
contextStore._pendingAliases = storageInstruction.aliases;
|
2397
|
-
} else {
|
2398
|
-
const storageMatch = demand.match(/store\s+(?:as\s+)?(\w+)/i);
|
2399
|
-
if (storageMatch) {
|
2400
|
-
storageKey = storageMatch[1];
|
2401
|
-
processedDemand = demand.replace(/,?\s*store\s+(?:as\s+)?\w+/i, "").trim();
|
2402
|
-
}
|
2403
|
-
}
|
2404
|
-
}
|
2405
|
-
} catch (error) {
|
2406
|
-
debug4("Context store not available:", error);
|
2407
|
-
}
|
2408
|
-
const { output, executor } = await this.taskExecutor.query(processedDemand);
|
2409
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2410
|
-
if (storageKey && output) {
|
2411
|
-
try {
|
2412
|
-
const pendingAliases = this.contextStore._pendingAliases;
|
2413
|
-
if (pendingAliases) {
|
2414
|
-
this.contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
|
2415
|
-
delete this.contextStore._pendingAliases;
|
2416
|
-
debug4("Stored query result with aliases:", {
|
2417
|
-
key: storageKey,
|
2418
|
-
value: output,
|
2419
|
-
aliases: pendingAliases
|
2420
|
-
});
|
2421
|
-
} else {
|
2422
|
-
this.contextStore.storeData(storageKey, output);
|
2423
|
-
debug4("Stored query result:", {
|
2424
|
-
key: storageKey,
|
2425
|
-
value: output
|
2426
|
-
});
|
2427
|
-
}
|
2428
|
-
this.contextStore.addStep({
|
2429
|
-
type: "query",
|
2430
|
-
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
|
2431
|
-
data: output,
|
2432
|
-
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2433
|
-
});
|
2434
|
-
debug4("Added query step to context store:", {
|
2435
|
-
storageKey,
|
2436
|
-
totalStoredItems: Object.keys(this.contextStore.getAllData()).length,
|
2437
|
-
totalSteps: this.contextStore.getRecentSteps(100).length
|
2438
|
-
});
|
2439
|
-
} catch (error) {
|
2440
|
-
debug4("Failed to store query result:", error);
|
2441
|
-
}
|
2442
|
-
} else {
|
2443
|
-
try {
|
2444
|
-
this.contextStore.addStep({
|
2445
|
-
type: "query",
|
2446
|
-
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
|
2447
|
-
data: output,
|
2448
|
-
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2449
|
-
});
|
2450
|
-
} catch (error) {
|
2451
|
-
debug4("Failed to add query step:", error);
|
2452
|
-
}
|
2453
|
-
}
|
2454
|
-
}
|
2278
|
+
const { output, executor } = await this.taskExecutor.query(demand);
|
2455
2279
|
const metadata = this.afterTaskRunning(executor);
|
2456
2280
|
return {
|
2457
2281
|
result: output,
|
@@ -2561,48 +2385,6 @@ var PageAgent = class {
|
|
2561
2385
|
};
|
2562
2386
|
}
|
2563
2387
|
async aiAssert(assertion, msg, opt) {
|
2564
|
-
let executionContext = "";
|
2565
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2566
|
-
try {
|
2567
|
-
const recentSteps = this.contextStore.getRecentSteps(3);
|
2568
|
-
const stepsWithExecutionResults = recentSteps.filter((step) => step.executionResult);
|
2569
|
-
const storedData = this.contextStore.getAllData();
|
2570
|
-
if (stepsWithExecutionResults.length > 0) {
|
2571
|
-
const recentActions = stepsWithExecutionResults.map((step) => {
|
2572
|
-
const result = step.executionResult;
|
2573
|
-
return `- ${result.description}${result.success ? "" : " (FAILED)"}`;
|
2574
|
-
}).join("\n");
|
2575
|
-
executionContext = `
|
2576
|
-
|
2577
|
-
Recent actions performed:
|
2578
|
-
${recentActions}
|
2579
|
-
|
2580
|
-
This context may help verify the assertion.`;
|
2581
|
-
}
|
2582
|
-
if (storedData && Object.keys(storedData).length > 0) {
|
2583
|
-
executionContext += `
|
2584
|
-
|
2585
|
-
Available data for reference:
|
2586
|
-
${JSON.stringify(storedData, null, 2)}
|
2587
|
-
|
2588
|
-
Note: If the assertion references any data keys or natural language equivalents, consider the stored values when verifying.`;
|
2589
|
-
debug4("Available data for aiAssert:", {
|
2590
|
-
assertion,
|
2591
|
-
availableData: storedData
|
2592
|
-
});
|
2593
|
-
}
|
2594
|
-
this.contextStore.addStep({
|
2595
|
-
type: "assertion",
|
2596
|
-
summary: `Assertion: ${assertion}`,
|
2597
|
-
prompt: assertion
|
2598
|
-
});
|
2599
|
-
debug4("Added assertion step to context store:", {
|
2600
|
-
totalSteps: this.contextStore.getRecentSteps(100).length
|
2601
|
-
});
|
2602
|
-
} catch (error) {
|
2603
|
-
debug4("Context store operation failed:", error);
|
2604
|
-
}
|
2605
|
-
}
|
2606
2388
|
let currentUrl = "";
|
2607
2389
|
if (this.page.url) {
|
2608
2390
|
try {
|
@@ -2610,13 +2392,7 @@ Note: If the assertion references any data keys or natural language equivalents,
|
|
2610
2392
|
} catch (e) {
|
2611
2393
|
}
|
2612
2394
|
}
|
2613
|
-
|
2614
|
-
if (currentUrl) {
|
2615
|
-
assertionWithContext = `For the page at URL "${currentUrl}", ${assertion}`;
|
2616
|
-
}
|
2617
|
-
if (executionContext) {
|
2618
|
-
assertionWithContext += executionContext;
|
2619
|
-
}
|
2395
|
+
const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
|
2620
2396
|
const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
|
2621
2397
|
const metadata = this.afterTaskRunning(executor, true);
|
2622
2398
|
if (output && opt?.keepRawResponse) {
|
@@ -2827,81 +2603,42 @@ ${errors}`);
|
|
2827
2603
|
}
|
2828
2604
|
throw new Error("evaluateJavaScript is not supported in current agent");
|
2829
2605
|
}
|
2830
|
-
async
|
2831
|
-
|
2832
|
-
|
2833
|
-
|
2834
|
-
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
2838
|
-
|
2839
|
-
|
2840
|
-
|
2841
|
-
|
2842
|
-
|
2843
|
-
|
2844
|
-
|
2845
|
-
|
2846
|
-
|
2847
|
-
|
2848
|
-
|
2849
|
-
|
2850
|
-
|
2851
|
-
|
2852
|
-
|
2853
|
-
|
2854
|
-
|
2855
|
-
|
2856
|
-
|
2606
|
+
async logScreenshot(title, options) {
|
2607
|
+
const screenshotTitle = title || "untitled";
|
2608
|
+
const content = options?.content || "";
|
2609
|
+
const screenshot = await this.page.screenshotBase64?.();
|
2610
|
+
if (screenshot) {
|
2611
|
+
const executionDump = {
|
2612
|
+
name: screenshotTitle,
|
2613
|
+
description: content,
|
2614
|
+
tasks: [{
|
2615
|
+
type: "Screenshot",
|
2616
|
+
subType: "log",
|
2617
|
+
status: "finished",
|
2618
|
+
executor: null,
|
2619
|
+
param: {
|
2620
|
+
title: screenshotTitle,
|
2621
|
+
content
|
2622
|
+
},
|
2623
|
+
output: {
|
2624
|
+
screenshot
|
2625
|
+
},
|
2626
|
+
thought: `Logged screenshot: ${screenshotTitle}`,
|
2627
|
+
timing: {
|
2628
|
+
start: Date.now(),
|
2629
|
+
end: Date.now(),
|
2630
|
+
cost: 0
|
2631
|
+
}
|
2632
|
+
}],
|
2633
|
+
sdkVersion: "1.0.0",
|
2634
|
+
logTime: Date.now(),
|
2635
|
+
model_name: "screenshot"
|
2857
2636
|
};
|
2637
|
+
this.appendExecutionDump(executionDump);
|
2858
2638
|
}
|
2859
|
-
const actionType = lastAction.subType || "unknown";
|
2860
|
-
const elementInfo = this.extractElementInfo(lastLocate, lastAction);
|
2861
|
-
const description = this.generateActionDescription(actionType, lastAction.param, elementInfo);
|
2862
|
-
return {
|
2863
|
-
success: true,
|
2864
|
-
actionType,
|
2865
|
-
description,
|
2866
|
-
elementInfo,
|
2867
|
-
timing: lastAction.timing?.cost
|
2868
|
-
};
|
2869
2639
|
}
|
2870
|
-
|
2871
|
-
|
2872
|
-
*/
|
2873
|
-
extractElementInfo(locateTask, _actionTask) {
|
2874
|
-
if (!locateTask?.output?.element)
|
2875
|
-
return void 0;
|
2876
|
-
const element = locateTask.output.element;
|
2877
|
-
return {
|
2878
|
-
type: element.attributes?.nodeType || "unknown",
|
2879
|
-
text: element.content || element.attributes?.placeholder || element.attributes?.title || "",
|
2880
|
-
location: `(${element.center[0]}, ${element.center[1]})`
|
2881
|
-
};
|
2882
|
-
}
|
2883
|
-
/**
|
2884
|
-
* Generate natural language description for actions
|
2885
|
-
*/
|
2886
|
-
generateActionDescription(actionType, param, elementInfo) {
|
2887
|
-
const elementDesc = elementInfo ? `'${elementInfo.text || elementInfo.type}' element` : "element";
|
2888
|
-
switch (actionType) {
|
2889
|
-
case "Tap":
|
2890
|
-
return `Clicked on ${elementDesc}`;
|
2891
|
-
case "Input":
|
2892
|
-
const inputValue = param?.value || "";
|
2893
|
-
return `Entered "${inputValue}" into ${elementDesc}`;
|
2894
|
-
case "KeyboardPress":
|
2895
|
-
return `Pressed ${param?.value || "key"}`;
|
2896
|
-
case "Scroll":
|
2897
|
-
return `Scrolled ${param?.direction || "on page"}`;
|
2898
|
-
case "Hover":
|
2899
|
-
return `Hovered over ${elementDesc}`;
|
2900
|
-
case "Drag":
|
2901
|
-
return `Dragged ${elementDesc}`;
|
2902
|
-
default:
|
2903
|
-
return `Performed ${actionType} action on ${elementDesc}`;
|
2904
|
-
}
|
2640
|
+
async destroy() {
|
2641
|
+
await this.page.destroy();
|
2905
2642
|
}
|
2906
2643
|
};
|
2907
2644
|
|
@@ -2918,7 +2655,7 @@ var Page = class {
|
|
2918
2655
|
this.everMoved = false;
|
2919
2656
|
this.underlyingPage = underlyingPage;
|
2920
2657
|
this.pageType = pageType;
|
2921
|
-
this.waitForNavigationTimeout = opts?.waitForNavigationTimeout
|
2658
|
+
this.waitForNavigationTimeout = opts?.waitForNavigationTimeout ?? import_constants3.DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;
|
2922
2659
|
}
|
2923
2660
|
async evaluate(pageFunction, arg) {
|
2924
2661
|
let result;
|
@@ -3323,6 +3060,14 @@ var PlaywrightAiFixture = (options) => {
|
|
3323
3060
|
aiActionType: "aiTap"
|
3324
3061
|
});
|
3325
3062
|
},
|
3063
|
+
aiRightClick: async ({ page }, use, testInfo) => {
|
3064
|
+
await generateAiFunction({
|
3065
|
+
page,
|
3066
|
+
testInfo,
|
3067
|
+
use,
|
3068
|
+
aiActionType: "aiRightClick"
|
3069
|
+
});
|
3070
|
+
},
|
3326
3071
|
aiHover: async ({ page }, use, testInfo) => {
|
3327
3072
|
await generateAiFunction({
|
3328
3073
|
page,
|
@@ -3410,6 +3155,14 @@ var PlaywrightAiFixture = (options) => {
|
|
3410
3155
|
use,
|
3411
3156
|
aiActionType: "aiBoolean"
|
3412
3157
|
});
|
3158
|
+
},
|
3159
|
+
logScreenshot: async ({ page }, use, testInfo) => {
|
3160
|
+
await generateAiFunction({
|
3161
|
+
page,
|
3162
|
+
testInfo,
|
3163
|
+
use,
|
3164
|
+
aiActionType: "logScreenshot"
|
3165
|
+
});
|
3413
3166
|
}
|
3414
3167
|
};
|
3415
3168
|
};
|
@@ -3449,9 +3202,9 @@ var WebPage2 = class extends Page {
|
|
3449
3202
|
}
|
3450
3203
|
async waitUntilNetworkIdle(options) {
|
3451
3204
|
await this.underlyingPage.waitForNetworkIdle({
|
3452
|
-
idleTime: options?.idleTime
|
3453
|
-
concurrency: options?.concurrency
|
3454
|
-
timeout: options?.timeout
|
3205
|
+
idleTime: options?.idleTime ?? import_constants4.DEFAULT_WAIT_FOR_NETWORK_IDLE_TIME,
|
3206
|
+
concurrency: options?.concurrency ?? import_constants4.DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY,
|
3207
|
+
timeout: options?.timeout ?? this.waitForNetworkIdleTimeout
|
3455
3208
|
});
|
3456
3209
|
}
|
3457
3210
|
};
|