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/ui-utils.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,SAAS,QAAQ,MAAqB;AAC3C,SAAO,KAAK,WAAW,KAAK,YAAY,SACpC,GAAG,KAAK,IAAI,MAAM,KAAK,WAAW,EAAE,KACpC,KAAK;AACX;AAEO,SAAS,eACd,OAC0C;AAE1C,QAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAIlD,SAAO,KAAK,OAAO,CAAC,KAA+C,MAAM;AACvE,UAAM,cAAc,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,SAAS;AACpE,QAAI,gBAAgB,MAAM,OAAO,MAAM,MAAM;AAC3C,aAAO,IAAI,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,YAAY,CAAC,CAAC;AAAA,IACtD;AACA,QAAI,gBAAgB,MAAM,OAAO,MAAM,MAAM;AAC3C,aAAO,IAAI,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,OAAO,CAAC,CAAC;AAAA,IACjD;AACA,QAAI,gBAAgB,MAAM,OAAO,MAAM,MAAM;AAC3C,aAAO,IAAI,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,QAAQ,CAAC,CAAC;AAAA,IAClD;AACA,WAAO,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAAA,EAChC,GAAG,CAAC,CAAC;AACP;AAEO,SAAS,eAAe,QAA8B;AAC3D,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO,OAAO;AAChB;AAEO,SAAS,eAAe,aAAyC;AACtE,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AACA,SAAO,GAAG,YAAY,aAAa,MAAM,KAAK,YAAY,cAAc,MAAM,KAAK,YAAY,YAAY,kBAAkB;AAC/H;AAEO,SAAS,aACd,
|
1
|
+
{"version":3,"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,SAAS,QAAQ,MAAqB;AAC3C,SAAO,KAAK,WAAW,KAAK,YAAY,SACpC,GAAG,KAAK,IAAI,MAAM,KAAK,WAAW,EAAE,KACpC,KAAK;AACX;AAEO,SAAS,eACd,OAC0C;AAE1C,QAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAIlD,SAAO,KAAK,OAAO,CAAC,KAA+C,MAAM;AACvE,UAAM,cAAc,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,SAAS;AACpE,QAAI,gBAAgB,MAAM,OAAO,MAAM,MAAM;AAC3C,aAAO,IAAI,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,YAAY,CAAC,CAAC;AAAA,IACtD;AACA,QAAI,gBAAgB,MAAM,OAAO,MAAM,MAAM;AAC3C,aAAO,IAAI,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,OAAO,CAAC,CAAC;AAAA,IACjD;AACA,QAAI,gBAAgB,MAAM,OAAO,MAAM,MAAM;AAC3C,aAAO,IAAI,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,QAAQ,CAAC,CAAC;AAAA,IAClD;AACA,WAAO,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAAA,EAChC,GAAG,CAAC,CAAC;AACP;AAEO,SAAS,eAAe,QAA8B;AAC3D,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO,OAAO;AAChB;AAEO,SAAS,eAAe,aAAyC;AACtE,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AACA,SAAO,GAAG,YAAY,aAAa,MAAM,KAAK,YAAY,cAAc,MAAM,KAAK,YAAY,YAAY,kBAAkB;AAC/H;AAEO,SAAS,aACd,MAeA,QACA;AACA,MAAI,QAAQ;AACV,WAAO,GAAG,IAAI,MAAM,MAAM;AAAA,EAC5B;AACA,SAAO;AACT;AAEO,SAAS,SAAS,MAAqB;AAC5C,MAAI;AACJ,MAAI,KAAK,SAAS,YAAY;AAC5B,YAAS,MAAgC,OAAO;AAAA,EAClD;AAEA,MAAI,KAAK,SAAS,WAAW;AAC3B,YACG,MAAqC,OAAO,UAC5C,MAAqC,OAAO,MAC5C,MAAoC,OAAO,cAC3C,MAAwC,OAAO;AAAA,EACpD;AAEA,MAAI,KAAK,SAAS,UAAU;AAC1B,UAAM,SAAU,MAA8B;AAC9C,UAAM,YAAY,SAAS,eAAe,MAAM,IAAI;AAEpD,YAAQ,KAAK,WAAW;AACxB,QAAI,OAAQ,MAA8B,OAAO,WAAW,UAAU;AACpE,cAAQ,GAAI,MAA8B,OAAO,MAAM;AAAA,IACzD,WACE,OAAQ,MAA8B,OAAO,eAAe,UAC5D;AACA,cAAQ,eAAgB,MAA8B,KAAK;AAAA,IAC7D,WACE,OAAQ,MAA8B,OAAO,UAAU,aACvD;AACA,cAAS,MAA8B,OAAO;AAAA,IAChD;AAEA,QAAI,WAAW;AACb,UAAI,OAAO;AACT,gBAAQ,GAAG,SAAS,MAAM,KAAK;AAAA,MACjC,OAAO;AACL,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,UAAU;AAAa,WAAO;AACzC,SAAO,OAAO,UAAU,WACpB,QACA,KAAK,UAAU,OAAO,QAAW,CAAC;AACxC;AAEO,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","names":[],"ignoreList":[],"sources":["../../src/common/ui-utils.ts"],"sourcesContent":["import type {\n DetailedLocateParam,\n ExecutionTask,\n ExecutionTaskAction,\n ExecutionTaskInsightAssertion,\n ExecutionTaskInsightLocate,\n ExecutionTaskInsightQuery,\n ExecutionTaskPlanning,\n PlanningActionParamScroll,\n} from 'misoai-core';\n\nexport function typeStr(task: ExecutionTask) {\n return task.subType && task.subType !== 'Plan'\n ? `${task.type} / ${task.subType || ''}`\n : task.type;\n}\n\nexport function getKeyCommands(\n value: string | string[],\n): Array<{ key: string; command?: string }> {\n // Ensure value is an array of keys\n const keys = Array.isArray(value) ? value : [value];\n\n // Process each key to attach a corresponding command if needed, based on the presence of 'Meta' or 'Control' in the keys array.\n // ref: https://github.com/puppeteer/puppeteer/pull/9357/files#diff-32cf475237b000f980eb214a0a823e45a902bddb7d2426d677cae96397aa0ae4R94\n return keys.reduce((acc: Array<{ key: string; command?: string }>, k) => {\n const includeMeta = keys.includes('Meta') || keys.includes('Control');\n if (includeMeta && (k === 'a' || k === 'A')) {\n return acc.concat([{ key: k, command: 'SelectAll' }]);\n }\n if (includeMeta && (k === 'c' || k === 'C')) {\n return acc.concat([{ key: k, command: 'Copy' }]);\n }\n if (includeMeta && (k === 'v' || k === 'V')) {\n return acc.concat([{ key: k, command: 'Paste' }]);\n }\n return acc.concat([{ key: k }]);\n }, []);\n}\n\nexport function locateParamStr(locate?: DetailedLocateParam) {\n if (!locate) {\n return '';\n }\n\n if (typeof locate === 'string') {\n return locate;\n }\n\n return locate.prompt;\n}\n\nexport function scrollParamStr(scrollParam?: PlanningActionParamScroll) {\n if (!scrollParam) {\n return '';\n }\n return `${scrollParam.direction || 'down'}, ${scrollParam.scrollType || 'once'}, ${scrollParam.distance || 'distance-not-set'}`;\n}\n\nexport function taskTitleStr(\n type:\n | 'Tap'\n | 'Hover'\n | 'Input'\n | 'RightClick'\n | 'KeyboardPress'\n | 'Scroll'\n | 'Action'\n | 'Query'\n | 'Assert'\n | 'WaitFor'\n | 'Locate'\n | 'Boolean'\n | 'Number'\n | 'String',\n prompt: string,\n) {\n if (prompt) {\n return `${type} - ${prompt}`;\n }\n return type;\n}\n\nexport function paramStr(task: ExecutionTask) {\n let value: string | undefined | object;\n if (task.type === 'Planning') {\n value = (task as ExecutionTaskPlanning)?.param?.userInstruction;\n }\n\n if (task.type === 'Insight') {\n value =\n (task as ExecutionTaskInsightLocate)?.param?.prompt ||\n (task as ExecutionTaskInsightLocate)?.param?.id ||\n (task as ExecutionTaskInsightQuery)?.param?.dataDemand ||\n (task as ExecutionTaskInsightAssertion)?.param?.assertion;\n }\n\n if (task.type === 'Action') {\n const locate = (task as ExecutionTaskAction)?.locate;\n const locateStr = locate ? locateParamStr(locate) : '';\n\n value = task.thought || '';\n if (typeof (task as ExecutionTaskAction)?.param?.timeMs === 'number') {\n value = `${(task as ExecutionTaskAction)?.param?.timeMs}ms`;\n } else if (\n typeof (task as ExecutionTaskAction)?.param?.scrollType === 'string'\n ) {\n value = scrollParamStr((task as ExecutionTaskAction)?.param);\n } else if (\n typeof (task as ExecutionTaskAction)?.param?.value !== 'undefined'\n ) {\n value = (task as ExecutionTaskAction)?.param?.value;\n }\n\n if (locateStr) {\n if (value) {\n value = `${locateStr} - ${value}`;\n } else {\n value = locateStr;\n }\n }\n }\n\n if (typeof value === 'undefined') return '';\n return typeof value === 'string'\n ? value\n : JSON.stringify(value, undefined, 2);\n}\n\nexport const limitOpenNewTabScript = `\nif (!window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__) {\n window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__ = true;\n\n // Intercept the window.open method (only once)\n window.open = function(url) {\n console.log('Blocked window.open:', url);\n window.location.href = url;\n return null;\n };\n\n // Block all a tag clicks with target=\"_blank\" (only once)\n document.addEventListener('click', function(e) {\n const target = e.target.closest('a');\n if (target && target.target === '_blank') {\n e.preventDefault();\n console.log('Blocked new tab:', target.href);\n window.location.href = target.href;\n target.removeAttribute('target');\n }\n }, true);\n}\n`;\n"]}
|
package/dist/lib/utils.js
CHANGED
@@ -59,7 +59,8 @@ var WebElementInfo = class {
|
|
59
59
|
id,
|
60
60
|
attributes,
|
61
61
|
indexId,
|
62
|
-
xpaths
|
62
|
+
xpaths,
|
63
|
+
isVisible
|
63
64
|
}) {
|
64
65
|
this.content = content;
|
65
66
|
this.rect = rect;
|
@@ -72,6 +73,7 @@ var WebElementInfo = class {
|
|
72
73
|
this.attributes = attributes;
|
73
74
|
this.indexId = indexId;
|
74
75
|
this.xpaths = xpaths;
|
76
|
+
this.isVisible = isVisible;
|
75
77
|
}
|
76
78
|
};
|
77
79
|
|
@@ -94,14 +96,15 @@ async function parseContextFromWebPage(page, _opt) {
|
|
94
96
|
})
|
95
97
|
]);
|
96
98
|
const webTree = (0, import_extractor.traverseTree)(tree, (elementInfo) => {
|
97
|
-
const { rect, id, content, attributes, locator, indexId } = elementInfo;
|
99
|
+
const { rect, id, content, attributes, locator, indexId, isVisible } = elementInfo;
|
98
100
|
return new WebElementInfo({
|
99
101
|
rect,
|
100
102
|
locator,
|
101
103
|
id,
|
102
104
|
content,
|
103
105
|
attributes,
|
104
|
-
indexId
|
106
|
+
indexId,
|
107
|
+
isVisible
|
105
108
|
});
|
106
109
|
});
|
107
110
|
(0, import_utils2.assert)(screenshotBase64, "screenshotBase64 is required");
|
@@ -169,7 +172,7 @@ function generateCacheId(fileName) {
|
|
169
172
|
}
|
170
173
|
var ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED = "NOT_IMPLEMENTED_AS_DESIGNED";
|
171
174
|
function replaceIllegalPathCharsAndSpace(str) {
|
172
|
-
return str.replace(/[
|
175
|
+
return str.replace(/[:*?"<>| ]/g, "-");
|
173
176
|
}
|
174
177
|
function forceClosePopup(page, debug) {
|
175
178
|
page.on("popup", async (popup) => {
|
package/dist/lib/utils.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"mappings":"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","names":["import_utils","dayjs"],"ignoreList":[],"sources":["../../src/common/utils.ts","../../src/web-element.ts"],"sourcesContent":["import type { StaticPage } from '@/playground';\nimport type {\n BaseElement,\n ElementTreeNode,\n PlanningLocateParam,\n PlaywrightParserOpt,\n UIContext,\n} from 'misoai-core';\nimport { elementByPositionWithElementInfo } from 'misoai-core/ai-model';\nimport { uploadTestInfoToServer } from 'misoai-core/utils';\nimport { MIDSCENE_REPORT_TAG_NAME, getAIConfig } from 'misoai-shared/env';\nimport type { ElementInfo } from 'misoai-shared/extractor';\nimport {\n generateElementByPosition,\n getNodeFromCacheList,\n traverseTree,\n treeToList,\n} from 'misoai-shared/extractor';\nimport { resizeImgBase64 } from 'misoai-shared/img';\nimport type { DebugFunction } from 'misoai-shared/logger';\nimport { assert, logMsg, uuid } from 'misoai-shared/utils';\nimport dayjs from 'dayjs';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport type { Page as PuppeteerPage } from 'puppeteer';\nimport { WebElementInfo } from '../web-element';\nimport type { WebPage } from './page';\n\nexport type WebUIContext = UIContext<WebElementInfo> & {\n url: string;\n};\n\nexport async function parseContextFromWebPage(\n page: WebPage,\n _opt?: PlaywrightParserOpt,\n): Promise<WebUIContext> {\n assert(page, 'page is required');\n if ((page as StaticPage)._forceUsePageContext) {\n return await (page as any)._forceUsePageContext();\n }\n const url = await page.url();\n uploadTestInfoToServer({ testUrl: url });\n\n let screenshotBase64: string;\n let tree: ElementTreeNode<ElementInfo>;\n\n await Promise.all([\n page.screenshotBase64().then((base64) => {\n screenshotBase64 = base64;\n }),\n page.getElementsNodeTree().then(async (treeRoot) => {\n tree = treeRoot;\n }),\n ]);\n\n const webTree = traverseTree(tree!, (elementInfo) => {\n const { rect, id, content, attributes, locator, indexId } = elementInfo;\n return new WebElementInfo({\n rect,\n locator,\n id,\n content,\n attributes,\n indexId,\n });\n });\n\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n const elementsInfo = treeToList(webTree);\n const size = await page.size();\n\n if (size.dpr && size.dpr > 1) {\n // console.time('resizeImgBase64');\n screenshotBase64 = await resizeImgBase64(screenshotBase64, {\n width: size.width,\n height: size.height,\n });\n // console.timeEnd('resizeImgBase64');\n }\n\n return {\n content: elementsInfo!,\n tree: webTree,\n size,\n screenshotBase64: screenshotBase64!,\n url,\n };\n}\n\nexport function reportFileName(tag = 'web') {\n const reportTagName = getAIConfig(MIDSCENE_REPORT_TAG_NAME);\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss');\n // ensure uniqueness at the same time\n const uniqueId = uuid().substring(0, 8);\n return `${reportTagName || tag}-${dateTimeInFileName}-${uniqueId}`;\n}\n\nexport function printReportMsg(filepath: string) {\n logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\n/**\n * Get the current execution file name\n * @returns The name of the current execution file\n */\nexport function getCurrentExecutionFile(trace?: string): string | false {\n const error = new Error();\n const stackTrace = trace || error.stack;\n const pkgDir = process.cwd() || '';\n if (stackTrace) {\n const stackLines = stackTrace.split('\\n');\n for (const line of stackLines) {\n if (\n line.includes('.spec.') ||\n line.includes('.test.') ||\n line.includes('.ts') ||\n line.includes('.js')\n ) {\n const match = line.match(/(?:at\\s+)?(.*?\\.(?:spec|test)\\.[jt]s)/);\n if (match?.[1]) {\n const targetFileName = match[1]\n .replace(pkgDir, '')\n .trim()\n .replace('at ', '');\n return targetFileName;\n }\n }\n }\n }\n return false;\n}\n\nconst testFileIndex = new Map<string, number>();\n\nexport function generateCacheId(fileName?: string): string {\n let taskFile = fileName || getCurrentExecutionFile();\n if (!taskFile) {\n taskFile = uuid();\n console.warn(\n 'Midscene - using random UUID for cache id. Cache may be invalid.',\n );\n }\n\n if (testFileIndex.has(taskFile)) {\n const currentIndex = testFileIndex.get(taskFile);\n if (currentIndex !== undefined) {\n testFileIndex.set(taskFile, currentIndex + 1);\n }\n } else {\n testFileIndex.set(taskFile, 1);\n }\n return `${taskFile}-${testFileIndex.get(taskFile)}`;\n}\n\nexport const ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED =\n 'NOT_IMPLEMENTED_AS_DESIGNED';\n\nexport function replaceIllegalPathCharsAndSpace(str: string) {\n return str.replace(/[/\\\\:*?\"<>| ]/g, '-');\n}\n\nexport function forceClosePopup(\n page: PuppeteerPage | PlaywrightPage,\n debug: DebugFunction,\n) {\n page.on('popup', async (popup) => {\n if (!popup) {\n console.warn('got a popup event, but the popup is not ready yet, skip');\n return;\n }\n const url = await (popup as PuppeteerPage).url();\n console.log(`Popup opened: ${url}`);\n if (!(popup as PuppeteerPage).isClosed()) {\n try {\n await (popup as PuppeteerPage).close(); // Close the newly opened TAB\n } catch (error) {\n debug(`failed to close popup ${url}, error: ${error}`);\n }\n } else {\n debug(`popup is already closed, skip close ${url}`);\n }\n\n if (!page.isClosed()) {\n try {\n await page.goto(url);\n } catch (error) {\n debug(`failed to goto ${url}, error: ${error}`);\n }\n } else {\n debug(`page is already closed, skip goto ${url}`);\n }\n });\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n tree: ElementTreeNode<BaseElement>,\n) {\n if (!planLocateParam) {\n return undefined;\n }\n if (planLocateParam.id) {\n return getNodeFromCacheList(planLocateParam.id);\n }\n\n if (planLocateParam.bbox) {\n const centerPosition = {\n x: Math.floor((planLocateParam.bbox[0] + planLocateParam.bbox[2]) / 2),\n y: Math.floor((planLocateParam.bbox[1] + planLocateParam.bbox[3]) / 2),\n };\n let element = elementByPositionWithElementInfo(tree, centerPosition);\n\n if (!element) {\n element = generateElementByPosition(centerPosition) as BaseElement;\n }\n\n return element;\n }\n\n return undefined;\n}\n","import type { BaseElement, Rect } from 'misoai-core';\nimport type { NodeType } from 'misoai-shared/constants';\nexport interface WebElementInfoType extends BaseElement {\n id: string;\n locator: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n}\n\nexport class WebElementInfo implements BaseElement {\n content: string;\n\n locator?: string;\n\n rect: Rect;\n\n center: [number, number];\n\n // page: WebPage;\n\n id: string;\n\n indexId: number;\n\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n\n xpaths?: string[];\n\n constructor({\n content,\n rect,\n // page,\n locator,\n id,\n attributes,\n indexId,\n xpaths,\n }: {\n content: string;\n rect: Rect;\n // page: WebPage;\n locator?: string;\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n indexId: number;\n xpaths?: string[];\n }) {\n this.content = content;\n this.rect = rect;\n this.center = [\n Math.floor(rect.left + rect.width / 2),\n Math.floor(rect.top + rect.height / 2),\n ];\n // this.page = page;\n this.locator = locator;\n this.id = id;\n this.attributes = attributes;\n this.indexId = indexId;\n this.xpaths = xpaths;\n }\n}\n"]}
|
1
|
+
{"version":3,"mappings":"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","names":["import_utils","dayjs"],"ignoreList":[],"sources":["../../src/common/utils.ts","../../src/web-element.ts"],"sourcesContent":["import type { StaticPage } from '@/playground';\nimport type {\n BaseElement,\n ElementTreeNode,\n PlanningLocateParam,\n PlaywrightParserOpt,\n UIContext,\n} from 'misoai-core';\nimport { elementByPositionWithElementInfo } from 'misoai-core/ai-model';\nimport { uploadTestInfoToServer } from 'misoai-core/utils';\nimport { MIDSCENE_REPORT_TAG_NAME, getAIConfig } from 'misoai-shared/env';\nimport type { ElementInfo } from 'misoai-shared/extractor';\nimport {\n generateElementByPosition,\n getNodeFromCacheList,\n traverseTree,\n treeToList,\n} from 'misoai-shared/extractor';\nimport { resizeImgBase64 } from 'misoai-shared/img';\nimport type { DebugFunction } from 'misoai-shared/logger';\nimport { assert, logMsg, uuid } from 'misoai-shared/utils';\nimport dayjs from 'dayjs';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport type { Page as PuppeteerPage } from 'puppeteer';\nimport { WebElementInfo } from '../web-element';\nimport type { WebPage } from './page';\n\nexport type WebUIContext = UIContext<WebElementInfo> & {\n url: string;\n};\n\nexport async function parseContextFromWebPage(\n page: WebPage,\n _opt?: PlaywrightParserOpt,\n): Promise<WebUIContext> {\n assert(page, 'page is required');\n if ((page as StaticPage)._forceUsePageContext) {\n return await (page as any)._forceUsePageContext();\n }\n const url = await page.url();\n uploadTestInfoToServer({ testUrl: url });\n\n let screenshotBase64: string;\n let tree: ElementTreeNode<ElementInfo>;\n\n await Promise.all([\n page.screenshotBase64().then((base64) => {\n screenshotBase64 = base64;\n }),\n page.getElementsNodeTree().then(async (treeRoot) => {\n tree = treeRoot;\n }),\n ]);\n\n const webTree = traverseTree(tree!, (elementInfo) => {\n const { rect, id, content, attributes, locator, indexId, isVisible } =\n elementInfo;\n return new WebElementInfo({\n rect,\n locator,\n id,\n content,\n attributes,\n indexId,\n isVisible,\n });\n });\n\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n const elementsInfo = treeToList(webTree);\n const size = await page.size();\n\n if (size.dpr && size.dpr > 1) {\n // console.time('resizeImgBase64');\n screenshotBase64 = await resizeImgBase64(screenshotBase64, {\n width: size.width,\n height: size.height,\n });\n // console.timeEnd('resizeImgBase64');\n }\n\n return {\n content: elementsInfo!,\n tree: webTree,\n size,\n screenshotBase64: screenshotBase64!,\n url,\n };\n}\n\nexport function reportFileName(tag = 'web') {\n const reportTagName = getAIConfig(MIDSCENE_REPORT_TAG_NAME);\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss');\n // ensure uniqueness at the same time\n const uniqueId = uuid().substring(0, 8);\n return `${reportTagName || tag}-${dateTimeInFileName}-${uniqueId}`;\n}\n\nexport function printReportMsg(filepath: string) {\n logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\n/**\n * Get the current execution file name\n * @returns The name of the current execution file\n */\nexport function getCurrentExecutionFile(trace?: string): string | false {\n const error = new Error();\n const stackTrace = trace || error.stack;\n const pkgDir = process.cwd() || '';\n if (stackTrace) {\n const stackLines = stackTrace.split('\\n');\n for (const line of stackLines) {\n if (\n line.includes('.spec.') ||\n line.includes('.test.') ||\n line.includes('.ts') ||\n line.includes('.js')\n ) {\n const match = line.match(/(?:at\\s+)?(.*?\\.(?:spec|test)\\.[jt]s)/);\n if (match?.[1]) {\n const targetFileName = match[1]\n .replace(pkgDir, '')\n .trim()\n .replace('at ', '');\n return targetFileName;\n }\n }\n }\n }\n return false;\n}\n\nconst testFileIndex = new Map<string, number>();\n\nexport function generateCacheId(fileName?: string): string {\n let taskFile = fileName || getCurrentExecutionFile();\n if (!taskFile) {\n taskFile = uuid();\n console.warn(\n 'Midscene - using random UUID for cache id. Cache may be invalid.',\n );\n }\n\n if (testFileIndex.has(taskFile)) {\n const currentIndex = testFileIndex.get(taskFile);\n if (currentIndex !== undefined) {\n testFileIndex.set(taskFile, currentIndex + 1);\n }\n } else {\n testFileIndex.set(taskFile, 1);\n }\n return `${taskFile}-${testFileIndex.get(taskFile)}`;\n}\n\nexport const ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED =\n 'NOT_IMPLEMENTED_AS_DESIGNED';\n\nexport function replaceIllegalPathCharsAndSpace(str: string) {\n // Only replace characters that are illegal in filenames, but preserve path separators\n return str.replace(/[:*?\"<>| ]/g, '-');\n}\n\nexport function forceClosePopup(\n page: PuppeteerPage | PlaywrightPage,\n debug: DebugFunction,\n) {\n page.on('popup', async (popup) => {\n if (!popup) {\n console.warn('got a popup event, but the popup is not ready yet, skip');\n return;\n }\n const url = await (popup as PuppeteerPage).url();\n console.log(`Popup opened: ${url}`);\n if (!(popup as PuppeteerPage).isClosed()) {\n try {\n await (popup as PuppeteerPage).close(); // Close the newly opened TAB\n } catch (error) {\n debug(`failed to close popup ${url}, error: ${error}`);\n }\n } else {\n debug(`popup is already closed, skip close ${url}`);\n }\n\n if (!page.isClosed()) {\n try {\n await page.goto(url);\n } catch (error) {\n debug(`failed to goto ${url}, error: ${error}`);\n }\n } else {\n debug(`page is already closed, skip goto ${url}`);\n }\n });\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n tree: ElementTreeNode<BaseElement>,\n) {\n if (!planLocateParam) {\n return undefined;\n }\n if (planLocateParam.id) {\n return getNodeFromCacheList(planLocateParam.id);\n }\n\n if (planLocateParam.bbox) {\n const centerPosition = {\n x: Math.floor((planLocateParam.bbox[0] + planLocateParam.bbox[2]) / 2),\n y: Math.floor((planLocateParam.bbox[1] + planLocateParam.bbox[3]) / 2),\n };\n let element = elementByPositionWithElementInfo(tree, centerPosition);\n\n if (!element) {\n element = generateElementByPosition(centerPosition) as BaseElement;\n }\n\n return element;\n }\n\n return undefined;\n}\n","import type { BaseElement, Rect } from 'misoai-core';\nimport type { NodeType } from 'misoai-shared/constants';\nexport interface WebElementInfoType extends BaseElement {\n id: string;\n locator: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n}\n\nexport class WebElementInfo implements BaseElement {\n content: string;\n\n locator?: string;\n\n rect: Rect;\n\n center: [number, number];\n\n id: string;\n\n indexId: number;\n\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n\n xpaths?: string[];\n\n isVisible: boolean;\n\n constructor({\n content,\n rect,\n // page,\n locator,\n id,\n attributes,\n indexId,\n xpaths,\n isVisible,\n }: {\n content: string;\n rect: Rect;\n // page: WebPage;\n locator?: string;\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n indexId: number;\n xpaths?: string[];\n isVisible: boolean;\n }) {\n this.content = content;\n this.rect = rect;\n this.center = [\n Math.floor(rect.left + rect.width / 2),\n Math.floor(rect.top + rect.height / 2),\n ];\n // this.page = page;\n this.locator = locator;\n this.id = id;\n this.attributes = attributes;\n this.indexId = indexId;\n this.xpaths = xpaths;\n this.isVisible = isVisible;\n }\n}\n"]}
|
package/dist/lib/yaml.js
CHANGED
@@ -51,10 +51,11 @@ var ScriptPlayer = class {
|
|
51
51
|
this.unnamedResultIndex = 0;
|
52
52
|
this.pageAgent = null;
|
53
53
|
this.result = {};
|
54
|
+
const target = script.target || script.web || script.android;
|
54
55
|
if (import_utils.ifInBrowser) {
|
55
56
|
this.output = void 0;
|
56
|
-
} else if (
|
57
|
-
this.output = (0, import_node_path.resolve)(process.cwd(),
|
57
|
+
} else if (target?.output) {
|
58
|
+
this.output = (0, import_node_path.resolve)(process.cwd(), target.output);
|
58
59
|
} else {
|
59
60
|
this.output = (0, import_node_path.join)((0, import_common.getMidsceneRunSubDir)("output"), `${process.pid}.json`);
|
60
61
|
}
|
@@ -128,15 +129,20 @@ var ScriptPlayer = class {
|
|
128
129
|
} else if ("aiAssert" in flowItem) {
|
129
130
|
const assertTask = flowItem;
|
130
131
|
const prompt = assertTask.aiAssert;
|
132
|
+
const msg = assertTask.errorMessage;
|
131
133
|
(0, import_utils.assert)(prompt, "missing prompt for aiAssert");
|
132
134
|
(0, import_utils.assert)(
|
133
135
|
typeof prompt === "string",
|
134
136
|
"prompt for aiAssert must be a string"
|
135
137
|
);
|
136
|
-
await agent.aiAssert(prompt);
|
138
|
+
await agent.aiAssert(prompt, msg);
|
137
139
|
} else if ("aiQuery" in flowItem) {
|
138
140
|
const queryTask = flowItem;
|
139
141
|
const prompt = queryTask.aiQuery;
|
142
|
+
const options = {
|
143
|
+
domIncluded: queryTask.domIncluded,
|
144
|
+
screenshotIncluded: queryTask.screenshotIncluded
|
145
|
+
};
|
140
146
|
(0, import_utils.assert)(prompt, "missing prompt for aiQuery");
|
141
147
|
(0, import_utils.assert)(
|
142
148
|
typeof prompt === "string",
|
@@ -147,6 +153,10 @@ var ScriptPlayer = class {
|
|
147
153
|
} else if ("aiNumber" in flowItem) {
|
148
154
|
const numberTask = flowItem;
|
149
155
|
const prompt = numberTask.aiNumber;
|
156
|
+
const options = {
|
157
|
+
domIncluded: numberTask.domIncluded,
|
158
|
+
screenshotIncluded: numberTask.screenshotIncluded
|
159
|
+
};
|
150
160
|
(0, import_utils.assert)(prompt, "missing prompt for number");
|
151
161
|
(0, import_utils.assert)(
|
152
162
|
typeof prompt === "string",
|
@@ -157,6 +167,10 @@ var ScriptPlayer = class {
|
|
157
167
|
} else if ("aiString" in flowItem) {
|
158
168
|
const stringTask = flowItem;
|
159
169
|
const prompt = stringTask.aiString;
|
170
|
+
const options = {
|
171
|
+
domIncluded: stringTask.domIncluded,
|
172
|
+
screenshotIncluded: stringTask.screenshotIncluded
|
173
|
+
};
|
160
174
|
(0, import_utils.assert)(prompt, "missing prompt for string");
|
161
175
|
(0, import_utils.assert)(
|
162
176
|
typeof prompt === "string",
|
@@ -167,6 +181,10 @@ var ScriptPlayer = class {
|
|
167
181
|
} else if ("aiBoolean" in flowItem) {
|
168
182
|
const booleanTask = flowItem;
|
169
183
|
const prompt = booleanTask.aiBoolean;
|
184
|
+
const options = {
|
185
|
+
domIncluded: booleanTask.domIncluded,
|
186
|
+
screenshotIncluded: booleanTask.screenshotIncluded
|
187
|
+
};
|
170
188
|
(0, import_utils.assert)(prompt, "missing prompt for boolean");
|
171
189
|
(0, import_utils.assert)(
|
172
190
|
typeof prompt === "string",
|
@@ -209,6 +227,9 @@ var ScriptPlayer = class {
|
|
209
227
|
} else if ("aiTap" in flowItem) {
|
210
228
|
const tapTask = flowItem;
|
211
229
|
await agent.aiTap(tapTask.aiTap, tapTask);
|
230
|
+
} else if ("aiRightClick" in flowItem) {
|
231
|
+
const rightClickTask = flowItem;
|
232
|
+
await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);
|
212
233
|
} else if ("aiHover" in flowItem) {
|
213
234
|
const hoverTask = flowItem;
|
214
235
|
await agent.aiHover(hoverTask.aiHover, hoverTask);
|
@@ -231,6 +252,11 @@ var ScriptPlayer = class {
|
|
231
252
|
evaluateJavaScriptTask.javascript
|
232
253
|
);
|
233
254
|
this.setResult(evaluateJavaScriptTask.name, result);
|
255
|
+
} else if ("logScreenshot" in flowItem) {
|
256
|
+
const logScreenshotTask = flowItem;
|
257
|
+
await agent.logScreenshot(logScreenshotTask.logScreenshot, {
|
258
|
+
content: logScreenshotTask.content || ""
|
259
|
+
});
|
234
260
|
} else {
|
235
261
|
throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);
|
236
262
|
}
|
package/dist/lib/yaml.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"mappings":"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","names":["resolve","yaml","import_utils","import_js_yaml"],"ignoreList":[],"sources":["../../src/yaml/index.ts","../../src/yaml/player.ts","../../src/yaml/builder.ts","../../src/yaml/utils.ts"],"sourcesContent":["export * from './player';\nexport * from './builder';\nexport * from './utils';\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { assert, ifInBrowser } from 'misoai-shared/utils';\n\nimport type { PageAgent } from '@/common/agent';\nimport type {\n FreeFn,\n MidsceneYamlFlowItemAIAction,\n MidsceneYamlFlowItemAIAssert,\n MidsceneYamlFlowItemAIBoolean,\n MidsceneYamlFlowItemAIHover,\n MidsceneYamlFlowItemAIInput,\n MidsceneYamlFlowItemAIKeyboardPress,\n MidsceneYamlFlowItemAILocate,\n MidsceneYamlFlowItemAINString,\n MidsceneYamlFlowItemAINumber,\n MidsceneYamlFlowItemAIQuery,\n MidsceneYamlFlowItemAIScroll,\n MidsceneYamlFlowItemAITap,\n MidsceneYamlFlowItemAIWaitFor,\n MidsceneYamlFlowItemEvaluateJavaScript,\n MidsceneYamlFlowItemSleep,\n MidsceneYamlScript,\n MidsceneYamlScriptEnv,\n ScriptPlayerStatusValue,\n ScriptPlayerTaskStatus,\n} from 'misoai-core';\nimport { getMidsceneRunSubDir } from 'misoai-shared/common';\n\nexport class ScriptPlayer<T extends MidsceneYamlScriptEnv> {\n public currentTaskIndex?: number;\n public taskStatusList: ScriptPlayerTaskStatus[] = [];\n public status: ScriptPlayerStatusValue = 'init';\n public reportFile?: string | null;\n public result: Record<string, any>;\n private unnamedResultIndex = 0;\n public output?: string | null;\n public errorInSetup?: Error;\n private pageAgent: PageAgent | null = null;\n public agentStatusTip?: string;\n constructor(\n private script: MidsceneYamlScript,\n private setupAgent: (platform: T) => Promise<{\n agent: PageAgent;\n freeFn: FreeFn[];\n }>,\n public onTaskStatusChange?: (taskStatus: ScriptPlayerTaskStatus) => void,\n ) {\n this.result = {};\n\n if (ifInBrowser) {\n this.output = undefined;\n } else if (script.target?.output) {\n this.output = resolve(process.cwd(), script.target.output);\n } else {\n this.output = join(getMidsceneRunSubDir('output'), `${process.pid}.json`);\n }\n\n this.taskStatusList = (script.tasks || []).map((task, taskIndex) => ({\n ...task,\n index: taskIndex,\n status: 'init',\n totalSteps: task.flow?.length || 0,\n }));\n }\n\n private setResult(key: string | undefined, value: any) {\n const keyToUse = key || this.unnamedResultIndex++;\n if (this.result[keyToUse]) {\n console.warn(`result key ${keyToUse} already exists, will overwrite`);\n }\n this.result[keyToUse] = value;\n\n this.flushResult();\n }\n\n private setPlayerStatus(status: ScriptPlayerStatusValue, error?: Error) {\n this.status = status;\n this.errorInSetup = error;\n }\n\n private notifyCurrentTaskStatusChange(taskIndex?: number) {\n const taskIndexToNotify =\n typeof taskIndex === 'number' ? taskIndex : this.currentTaskIndex;\n\n if (typeof taskIndexToNotify !== 'number') {\n return;\n }\n\n const taskStatus = this.taskStatusList[taskIndexToNotify];\n if (this.onTaskStatusChange) {\n this.onTaskStatusChange(taskStatus);\n }\n }\n\n private async setTaskStatus(\n index: number,\n statusValue: ScriptPlayerStatusValue,\n error?: Error,\n ) {\n this.taskStatusList[index].status = statusValue;\n if (error) {\n this.taskStatusList[index].error = error;\n }\n\n this.notifyCurrentTaskStatusChange(index);\n }\n\n private setTaskIndex(taskIndex: number) {\n this.currentTaskIndex = taskIndex;\n }\n\n private flushResult() {\n if (Object.keys(this.result).length && this.output) {\n const output = resolve(process.cwd(), this.output);\n const outputDir = dirname(output);\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(output, JSON.stringify(this.result, undefined, 2));\n }\n }\n\n async playTask(taskStatus: ScriptPlayerTaskStatus, agent: PageAgent) {\n const { flow } = taskStatus;\n assert(flow, 'missing flow in task');\n\n for (const flowItemIndex in flow) {\n const currentStep = Number.parseInt(flowItemIndex, 10);\n taskStatus.currentStep = currentStep;\n const flowItem = flow[flowItemIndex];\n if (\n 'aiAction' in (flowItem as MidsceneYamlFlowItemAIAction) ||\n 'ai' in (flowItem as MidsceneYamlFlowItemAIAction)\n ) {\n const actionTask = flowItem as MidsceneYamlFlowItemAIAction;\n const prompt = actionTask.aiAction || actionTask.ai;\n assert(prompt, 'missing prompt for ai (aiAction)');\n assert(\n typeof prompt === 'string',\n 'prompt for aiAction must be a string',\n );\n await agent.aiAction(prompt, {\n cacheable: actionTask.cacheable,\n });\n } else if ('aiAssert' in (flowItem as MidsceneYamlFlowItemAIAssert)) {\n const assertTask = flowItem as MidsceneYamlFlowItemAIAssert;\n const prompt = assertTask.aiAssert;\n assert(prompt, 'missing prompt for aiAssert');\n assert(\n typeof prompt === 'string',\n 'prompt for aiAssert must be a string',\n );\n await agent.aiAssert(prompt);\n } else if ('aiQuery' in (flowItem as MidsceneYamlFlowItemAIQuery)) {\n const queryTask = flowItem as MidsceneYamlFlowItemAIQuery;\n const prompt = queryTask.aiQuery;\n assert(prompt, 'missing prompt for aiQuery');\n assert(\n typeof prompt === 'string',\n 'prompt for aiQuery must be a string',\n );\n const queryResult = await agent.aiQuery(prompt);\n this.setResult(queryTask.name, queryResult);\n } else if ('aiNumber' in (flowItem as MidsceneYamlFlowItemAINumber)) {\n const numberTask = flowItem as MidsceneYamlFlowItemAINumber;\n const prompt = numberTask.aiNumber;\n assert(prompt, 'missing prompt for number');\n assert(\n typeof prompt === 'string',\n 'prompt for number must be a string',\n );\n const numberResult = await agent.aiNumber(prompt);\n this.setResult(numberTask.name, numberResult);\n } else if ('aiString' in (flowItem as MidsceneYamlFlowItemAINString)) {\n const stringTask = flowItem as MidsceneYamlFlowItemAINString;\n const prompt = stringTask.aiString;\n assert(prompt, 'missing prompt for string');\n assert(\n typeof prompt === 'string',\n 'prompt for string must be a string',\n );\n const stringResult = await agent.aiString(prompt);\n this.setResult(stringTask.name, stringResult);\n } else if ('aiBoolean' in (flowItem as MidsceneYamlFlowItemAIBoolean)) {\n const booleanTask = flowItem as MidsceneYamlFlowItemAIBoolean;\n const prompt = booleanTask.aiBoolean;\n assert(prompt, 'missing prompt for boolean');\n assert(\n typeof prompt === 'string',\n 'prompt for boolean must be a string',\n );\n const booleanResult = await agent.aiBoolean(prompt);\n this.setResult(booleanTask.name, booleanResult);\n } else if ('aiLocate' in (flowItem as MidsceneYamlFlowItemAILocate)) {\n const locateTask = flowItem as MidsceneYamlFlowItemAILocate;\n const prompt = locateTask.aiLocate;\n assert(prompt, 'missing prompt for aiLocate');\n assert(\n typeof prompt === 'string',\n 'prompt for aiLocate must be a string',\n );\n const locateResult = await agent.aiLocate(prompt);\n this.setResult(locateTask.name, locateResult);\n } else if ('aiWaitFor' in (flowItem as MidsceneYamlFlowItemAIWaitFor)) {\n const waitForTask = flowItem as MidsceneYamlFlowItemAIWaitFor;\n const prompt = waitForTask.aiWaitFor;\n assert(prompt, 'missing prompt for aiWaitFor');\n assert(\n typeof prompt === 'string',\n 'prompt for aiWaitFor must be a string',\n );\n const timeout = waitForTask.timeout;\n await agent.aiWaitFor(prompt, { timeoutMs: timeout });\n } else if ('sleep' in (flowItem as MidsceneYamlFlowItemSleep)) {\n const sleepTask = flowItem as MidsceneYamlFlowItemSleep;\n const ms = sleepTask.sleep;\n let msNumber = ms;\n if (typeof ms === 'string') {\n msNumber = Number.parseInt(ms, 10);\n }\n assert(\n msNumber && msNumber > 0,\n `ms for sleep must be greater than 0, but got ${ms}`,\n );\n await new Promise((resolve) => setTimeout(resolve, msNumber));\n } else if ('aiTap' in (flowItem as MidsceneYamlFlowItemAITap)) {\n const tapTask = flowItem as MidsceneYamlFlowItemAITap;\n await agent.aiTap(tapTask.aiTap, tapTask);\n } else if ('aiHover' in (flowItem as MidsceneYamlFlowItemAIHover)) {\n const hoverTask = flowItem as MidsceneYamlFlowItemAIHover;\n await agent.aiHover(hoverTask.aiHover, hoverTask);\n } else if ('aiInput' in (flowItem as MidsceneYamlFlowItemAIInput)) {\n // may be input empty string ''\n const inputTask = flowItem as MidsceneYamlFlowItemAIInput;\n await agent.aiInput(inputTask.aiInput, inputTask.locate, inputTask);\n } else if (\n 'aiKeyboardPress' in (flowItem as MidsceneYamlFlowItemAIKeyboardPress)\n ) {\n const keyboardPressTask =\n flowItem as MidsceneYamlFlowItemAIKeyboardPress;\n await agent.aiKeyboardPress(\n keyboardPressTask.aiKeyboardPress,\n keyboardPressTask.locate,\n keyboardPressTask,\n );\n } else if ('aiScroll' in (flowItem as MidsceneYamlFlowItemAIScroll)) {\n const scrollTask = flowItem as MidsceneYamlFlowItemAIScroll;\n await agent.aiScroll(scrollTask, scrollTask.locate, scrollTask);\n } else if (\n 'javascript' in (flowItem as MidsceneYamlFlowItemEvaluateJavaScript)\n ) {\n const evaluateJavaScriptTask =\n flowItem as MidsceneYamlFlowItemEvaluateJavaScript;\n\n const result = await agent.evaluateJavaScript(\n evaluateJavaScriptTask.javascript,\n );\n this.setResult(evaluateJavaScriptTask.name, result);\n } else {\n throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);\n }\n }\n this.reportFile = agent.reportFile;\n }\n\n async run() {\n const { target, web, android, tasks } = this.script;\n const webEnv = web || target;\n const androidEnv = android;\n const platform = webEnv || androidEnv;\n\n this.setPlayerStatus('running');\n\n let agent: PageAgent | null = null;\n let freeFn: FreeFn[] = [];\n try {\n const { agent: newAgent, freeFn: newFreeFn } = await this.setupAgent(\n platform as T,\n );\n agent = newAgent;\n const originalOnTaskStartTip = agent.onTaskStartTip;\n agent.onTaskStartTip = (tip) => {\n if (this.status === 'running') {\n this.agentStatusTip = tip;\n }\n originalOnTaskStartTip?.(tip);\n };\n freeFn = [\n ...(newFreeFn || []),\n {\n name: 'restore-agent-onTaskStartTip',\n fn: () => {\n if (agent) {\n agent.onTaskStartTip = originalOnTaskStartTip;\n }\n },\n },\n ];\n } catch (e) {\n this.setPlayerStatus('error', e as Error);\n return;\n }\n this.pageAgent = agent;\n\n let taskIndex = 0;\n this.setPlayerStatus('running');\n let errorFlag = false;\n while (taskIndex < tasks.length) {\n const taskStatus = this.taskStatusList[taskIndex];\n this.setTaskStatus(taskIndex, 'running' as any);\n this.setTaskIndex(taskIndex);\n\n try {\n await this.playTask(taskStatus, this.pageAgent);\n this.setTaskStatus(taskIndex, 'done' as any);\n } catch (e) {\n this.setTaskStatus(taskIndex, 'error' as any, e as Error);\n\n if (taskStatus.continueOnError) {\n // nothing more to do\n } else {\n this.reportFile = agent.reportFile;\n errorFlag = true;\n break;\n }\n }\n this.reportFile = agent.reportFile;\n taskIndex++;\n }\n\n if (errorFlag) {\n this.setPlayerStatus('error');\n } else {\n this.setPlayerStatus('done');\n }\n this.agentStatusTip = '';\n\n // free the resources\n for (const fn of freeFn) {\n try {\n // console.log('freeing', fn.name);\n await fn.fn();\n // console.log('freed', fn.name);\n } catch (e) {\n // console.error('error freeing', fn.name, e);\n }\n }\n }\n}\n","import type {\n MidsceneYamlScript,\n MidsceneYamlScriptWebEnv,\n MidsceneYamlTask,\n} from 'misoai-core';\nimport yaml from 'js-yaml';\n\nexport function buildYaml(\n env: MidsceneYamlScriptWebEnv,\n tasks: MidsceneYamlTask[],\n) {\n const result: MidsceneYamlScript = {\n target: env,\n tasks,\n };\n\n return yaml.dump(result, {\n indent: 2,\n });\n}\n","import { assert } from 'misoai-shared/utils';\nimport yaml from 'js-yaml';\n\nimport type { MidsceneYamlScript } from 'misoai-core';\n\nfunction interpolateEnvVars(content: string): string {\n return content.replace(/\\$\\{([^}]+)\\}/g, (_, envVar) => {\n const value = process.env[envVar.trim()];\n if (value === undefined) {\n throw new Error(`Environment variable \"${envVar.trim()}\" is not defined`);\n }\n return value;\n });\n}\n\nexport function parseYamlScript(\n content: string,\n filePath?: string,\n ignoreCheckingTarget?: boolean,\n): MidsceneYamlScript {\n let processedContent = content;\n if (content.indexOf('android') !== -1 && content.match(/deviceId:\\s*(\\d+)/)) {\n let matchedDeviceId;\n processedContent = content.replace(\n /deviceId:\\s*(\\d+)/g,\n (match, deviceId) => {\n matchedDeviceId = deviceId;\n return `deviceId: '${deviceId}'`;\n },\n );\n console.warn(\n `please use string-style deviceId in yaml script, for example: deviceId: \"${matchedDeviceId}\"`,\n );\n }\n const interpolatedContent = interpolateEnvVars(processedContent);\n const obj = yaml.load(interpolatedContent, {\n schema: yaml.JSON_SCHEMA,\n }) as MidsceneYamlScript;\n\n const pathTip = filePath ? `, failed to load ${filePath}` : '';\n const android =\n typeof obj.android !== 'undefined'\n ? Object.assign({}, obj.android || {})\n : undefined;\n const webConfig = obj.web || obj.target; // no need to handle null case, because web has required parameters url\n const web =\n typeof webConfig !== 'undefined'\n ? Object.assign({}, webConfig || {})\n : undefined;\n\n if (!ignoreCheckingTarget) {\n // make sure at least one of target/web/android is provided\n assert(\n web || android,\n `at least one of \"target\", \"web\", or \"android\" properties is required in yaml script${pathTip}`,\n );\n\n // make sure only one of target/web/android is provided\n assert(\n (web && !android) || (!web && android),\n `only one of \"target\", \"web\", or \"android\" properties is allowed in yaml script${pathTip}`,\n );\n\n // make sure the config is valid\n if (web || android) {\n assert(\n typeof web === 'object' || typeof android === 'object',\n `property \"target/web/android\" must be an object${pathTip}`,\n );\n }\n }\n\n assert(obj.tasks, `property \"tasks\" is required in yaml script ${pathTip}`);\n assert(\n Array.isArray(obj.tasks),\n `property \"tasks\" must be an array in yaml script, but got ${obj.tasks}`,\n );\n return obj;\n}\n"]}
|
1
|
+
{"version":3,"mappings":"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","names":["resolve","yaml","import_utils","import_js_yaml"],"ignoreList":[],"sources":["../../src/yaml/index.ts","../../src/yaml/player.ts","../../src/yaml/builder.ts","../../src/yaml/utils.ts"],"sourcesContent":["export * from './player';\nexport * from './builder';\nexport * from './utils';\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { assert, ifInBrowser } from 'misoai-shared/utils';\n\nimport type { PageAgent } from '@/common/agent';\nimport type {\n FreeFn,\n MidsceneYamlFlowItemAIAction,\n MidsceneYamlFlowItemAIAssert,\n MidsceneYamlFlowItemAIBoolean,\n MidsceneYamlFlowItemAIHover,\n MidsceneYamlFlowItemAIInput,\n MidsceneYamlFlowItemAIKeyboardPress,\n MidsceneYamlFlowItemAILocate,\n MidsceneYamlFlowItemAINString,\n MidsceneYamlFlowItemAINumber,\n MidsceneYamlFlowItemAIQuery,\n MidsceneYamlFlowItemAIRightClick,\n MidsceneYamlFlowItemAIScroll,\n MidsceneYamlFlowItemAITap,\n MidsceneYamlFlowItemAIWaitFor,\n MidsceneYamlFlowItemEvaluateJavaScript,\n MidsceneYamlFlowItemLogScreenshot,\n MidsceneYamlFlowItemSleep,\n MidsceneYamlScript,\n MidsceneYamlScriptEnv,\n ScriptPlayerStatusValue,\n ScriptPlayerTaskStatus,\n} from 'misoai-core';\nimport { getMidsceneRunSubDir } from 'misoai-shared/common';\n\nexport class ScriptPlayer<T extends MidsceneYamlScriptEnv> {\n public currentTaskIndex?: number;\n public taskStatusList: ScriptPlayerTaskStatus[] = [];\n public status: ScriptPlayerStatusValue = 'init';\n public reportFile?: string | null;\n public result: Record<string, any>;\n private unnamedResultIndex = 0;\n public output?: string | null;\n public errorInSetup?: Error;\n private pageAgent: PageAgent | null = null;\n public agentStatusTip?: string;\n constructor(\n private script: MidsceneYamlScript,\n private setupAgent: (platform: T) => Promise<{\n agent: PageAgent;\n freeFn: FreeFn[];\n }>,\n public onTaskStatusChange?: (taskStatus: ScriptPlayerTaskStatus) => void,\n ) {\n this.result = {};\n\n const target = script.target || script.web || script.android;\n\n if (ifInBrowser) {\n this.output = undefined;\n } else if (target?.output) {\n this.output = resolve(process.cwd(), target.output);\n } else {\n this.output = join(getMidsceneRunSubDir('output'), `${process.pid}.json`);\n }\n\n this.taskStatusList = (script.tasks || []).map((task, taskIndex) => ({\n ...task,\n index: taskIndex,\n status: 'init',\n totalSteps: task.flow?.length || 0,\n }));\n }\n\n private setResult(key: string | undefined, value: any) {\n const keyToUse = key || this.unnamedResultIndex++;\n if (this.result[keyToUse]) {\n console.warn(`result key ${keyToUse} already exists, will overwrite`);\n }\n this.result[keyToUse] = value;\n\n this.flushResult();\n }\n\n private setPlayerStatus(status: ScriptPlayerStatusValue, error?: Error) {\n this.status = status;\n this.errorInSetup = error;\n }\n\n private notifyCurrentTaskStatusChange(taskIndex?: number) {\n const taskIndexToNotify =\n typeof taskIndex === 'number' ? taskIndex : this.currentTaskIndex;\n\n if (typeof taskIndexToNotify !== 'number') {\n return;\n }\n\n const taskStatus = this.taskStatusList[taskIndexToNotify];\n if (this.onTaskStatusChange) {\n this.onTaskStatusChange(taskStatus);\n }\n }\n\n private async setTaskStatus(\n index: number,\n statusValue: ScriptPlayerStatusValue,\n error?: Error,\n ) {\n this.taskStatusList[index].status = statusValue;\n if (error) {\n this.taskStatusList[index].error = error;\n }\n\n this.notifyCurrentTaskStatusChange(index);\n }\n\n private setTaskIndex(taskIndex: number) {\n this.currentTaskIndex = taskIndex;\n }\n\n private flushResult() {\n if (Object.keys(this.result).length && this.output) {\n const output = resolve(process.cwd(), this.output);\n const outputDir = dirname(output);\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(output, JSON.stringify(this.result, undefined, 2));\n }\n }\n\n async playTask(taskStatus: ScriptPlayerTaskStatus, agent: PageAgent) {\n const { flow } = taskStatus;\n assert(flow, 'missing flow in task');\n\n for (const flowItemIndex in flow) {\n const currentStep = Number.parseInt(flowItemIndex, 10);\n taskStatus.currentStep = currentStep;\n const flowItem = flow[flowItemIndex];\n if (\n 'aiAction' in (flowItem as MidsceneYamlFlowItemAIAction) ||\n 'ai' in (flowItem as MidsceneYamlFlowItemAIAction)\n ) {\n const actionTask = flowItem as MidsceneYamlFlowItemAIAction;\n const prompt = actionTask.aiAction || actionTask.ai;\n assert(prompt, 'missing prompt for ai (aiAction)');\n assert(\n typeof prompt === 'string',\n 'prompt for aiAction must be a string',\n );\n await agent.aiAction(prompt, {\n cacheable: actionTask.cacheable,\n });\n } else if ('aiAssert' in (flowItem as MidsceneYamlFlowItemAIAssert)) {\n const assertTask = flowItem as MidsceneYamlFlowItemAIAssert;\n const prompt = assertTask.aiAssert;\n const msg = assertTask.errorMessage;\n assert(prompt, 'missing prompt for aiAssert');\n assert(\n typeof prompt === 'string',\n 'prompt for aiAssert must be a string',\n );\n await agent.aiAssert(prompt, msg);\n } else if ('aiQuery' in (flowItem as MidsceneYamlFlowItemAIQuery)) {\n const queryTask = flowItem as MidsceneYamlFlowItemAIQuery;\n const prompt = queryTask.aiQuery;\n const options = {\n domIncluded: queryTask.domIncluded,\n screenshotIncluded: queryTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiQuery');\n assert(\n typeof prompt === 'string',\n 'prompt for aiQuery must be a string',\n );\n const queryResult = await agent.aiQuery(prompt);\n this.setResult(queryTask.name, queryResult);\n } else if ('aiNumber' in (flowItem as MidsceneYamlFlowItemAINumber)) {\n const numberTask = flowItem as MidsceneYamlFlowItemAINumber;\n const prompt = numberTask.aiNumber;\n const options = {\n domIncluded: numberTask.domIncluded,\n screenshotIncluded: numberTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for number');\n assert(\n typeof prompt === 'string',\n 'prompt for number must be a string',\n );\n const numberResult = await agent.aiNumber(prompt);\n this.setResult(numberTask.name, numberResult);\n } else if ('aiString' in (flowItem as MidsceneYamlFlowItemAINString)) {\n const stringTask = flowItem as MidsceneYamlFlowItemAINString;\n const prompt = stringTask.aiString;\n const options = {\n domIncluded: stringTask.domIncluded,\n screenshotIncluded: stringTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for string');\n assert(\n typeof prompt === 'string',\n 'prompt for string must be a string',\n );\n const stringResult = await agent.aiString(prompt);\n this.setResult(stringTask.name, stringResult);\n } else if ('aiBoolean' in (flowItem as MidsceneYamlFlowItemAIBoolean)) {\n const booleanTask = flowItem as MidsceneYamlFlowItemAIBoolean;\n const prompt = booleanTask.aiBoolean;\n const options = {\n domIncluded: booleanTask.domIncluded,\n screenshotIncluded: booleanTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for boolean');\n assert(\n typeof prompt === 'string',\n 'prompt for boolean must be a string',\n );\n const booleanResult = await agent.aiBoolean(prompt);\n this.setResult(booleanTask.name, booleanResult);\n } else if ('aiLocate' in (flowItem as MidsceneYamlFlowItemAILocate)) {\n const locateTask = flowItem as MidsceneYamlFlowItemAILocate;\n const prompt = locateTask.aiLocate;\n assert(prompt, 'missing prompt for aiLocate');\n assert(\n typeof prompt === 'string',\n 'prompt for aiLocate must be a string',\n );\n const locateResult = await agent.aiLocate(prompt);\n this.setResult(locateTask.name, locateResult);\n } else if ('aiWaitFor' in (flowItem as MidsceneYamlFlowItemAIWaitFor)) {\n const waitForTask = flowItem as MidsceneYamlFlowItemAIWaitFor;\n const prompt = waitForTask.aiWaitFor;\n assert(prompt, 'missing prompt for aiWaitFor');\n assert(\n typeof prompt === 'string',\n 'prompt for aiWaitFor must be a string',\n );\n const timeout = waitForTask.timeout;\n await agent.aiWaitFor(prompt, { timeoutMs: timeout });\n } else if ('sleep' in (flowItem as MidsceneYamlFlowItemSleep)) {\n const sleepTask = flowItem as MidsceneYamlFlowItemSleep;\n const ms = sleepTask.sleep;\n let msNumber = ms;\n if (typeof ms === 'string') {\n msNumber = Number.parseInt(ms, 10);\n }\n assert(\n msNumber && msNumber > 0,\n `ms for sleep must be greater than 0, but got ${ms}`,\n );\n await new Promise((resolve) => setTimeout(resolve, msNumber));\n } else if ('aiTap' in (flowItem as MidsceneYamlFlowItemAITap)) {\n const tapTask = flowItem as MidsceneYamlFlowItemAITap;\n await agent.aiTap(tapTask.aiTap, tapTask);\n } else if (\n 'aiRightClick' in (flowItem as MidsceneYamlFlowItemAIRightClick)\n ) {\n const rightClickTask = flowItem as MidsceneYamlFlowItemAIRightClick;\n await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);\n } else if ('aiHover' in (flowItem as MidsceneYamlFlowItemAIHover)) {\n const hoverTask = flowItem as MidsceneYamlFlowItemAIHover;\n await agent.aiHover(hoverTask.aiHover, hoverTask);\n } else if ('aiInput' in (flowItem as MidsceneYamlFlowItemAIInput)) {\n // may be input empty string ''\n const inputTask = flowItem as MidsceneYamlFlowItemAIInput;\n await agent.aiInput(inputTask.aiInput, inputTask.locate, inputTask);\n } else if (\n 'aiKeyboardPress' in (flowItem as MidsceneYamlFlowItemAIKeyboardPress)\n ) {\n const keyboardPressTask =\n flowItem as MidsceneYamlFlowItemAIKeyboardPress;\n await agent.aiKeyboardPress(\n keyboardPressTask.aiKeyboardPress,\n keyboardPressTask.locate,\n keyboardPressTask,\n );\n } else if ('aiScroll' in (flowItem as MidsceneYamlFlowItemAIScroll)) {\n const scrollTask = flowItem as MidsceneYamlFlowItemAIScroll;\n await agent.aiScroll(scrollTask, scrollTask.locate, scrollTask);\n } else if (\n 'javascript' in (flowItem as MidsceneYamlFlowItemEvaluateJavaScript)\n ) {\n const evaluateJavaScriptTask =\n flowItem as MidsceneYamlFlowItemEvaluateJavaScript;\n\n const result = await agent.evaluateJavaScript(\n evaluateJavaScriptTask.javascript,\n );\n this.setResult(evaluateJavaScriptTask.name, result);\n } else if (\n 'logScreenshot' in (flowItem as MidsceneYamlFlowItemLogScreenshot)\n ) {\n const logScreenshotTask = flowItem as MidsceneYamlFlowItemLogScreenshot;\n await agent.logScreenshot(logScreenshotTask.logScreenshot, {\n content: logScreenshotTask.content || '',\n });\n } else {\n throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);\n }\n }\n this.reportFile = agent.reportFile;\n }\n\n async run() {\n const { target, web, android, tasks } = this.script;\n const webEnv = web || target;\n const androidEnv = android;\n const platform = webEnv || androidEnv;\n\n this.setPlayerStatus('running');\n\n let agent: PageAgent | null = null;\n let freeFn: FreeFn[] = [];\n try {\n const { agent: newAgent, freeFn: newFreeFn } = await this.setupAgent(\n platform as T,\n );\n agent = newAgent;\n const originalOnTaskStartTip = agent.onTaskStartTip;\n agent.onTaskStartTip = (tip) => {\n if (this.status === 'running') {\n this.agentStatusTip = tip;\n }\n originalOnTaskStartTip?.(tip);\n };\n freeFn = [\n ...(newFreeFn || []),\n {\n name: 'restore-agent-onTaskStartTip',\n fn: () => {\n if (agent) {\n agent.onTaskStartTip = originalOnTaskStartTip;\n }\n },\n },\n ];\n } catch (e) {\n this.setPlayerStatus('error', e as Error);\n return;\n }\n this.pageAgent = agent;\n\n let taskIndex = 0;\n this.setPlayerStatus('running');\n let errorFlag = false;\n while (taskIndex < tasks.length) {\n const taskStatus = this.taskStatusList[taskIndex];\n this.setTaskStatus(taskIndex, 'running' as any);\n this.setTaskIndex(taskIndex);\n\n try {\n await this.playTask(taskStatus, this.pageAgent);\n this.setTaskStatus(taskIndex, 'done' as any);\n } catch (e) {\n this.setTaskStatus(taskIndex, 'error' as any, e as Error);\n\n if (taskStatus.continueOnError) {\n // nothing more to do\n } else {\n this.reportFile = agent.reportFile;\n errorFlag = true;\n break;\n }\n }\n this.reportFile = agent.reportFile;\n taskIndex++;\n }\n\n if (errorFlag) {\n this.setPlayerStatus('error');\n } else {\n this.setPlayerStatus('done');\n }\n this.agentStatusTip = '';\n\n // free the resources\n for (const fn of freeFn) {\n try {\n // console.log('freeing', fn.name);\n await fn.fn();\n // console.log('freed', fn.name);\n } catch (e) {\n // console.error('error freeing', fn.name, e);\n }\n }\n }\n}\n","import type {\n MidsceneYamlScript,\n MidsceneYamlScriptWebEnv,\n MidsceneYamlTask,\n} from 'misoai-core';\nimport yaml from 'js-yaml';\n\nexport function buildYaml(\n env: MidsceneYamlScriptWebEnv,\n tasks: MidsceneYamlTask[],\n) {\n const result: MidsceneYamlScript = {\n target: env,\n tasks,\n };\n\n return yaml.dump(result, {\n indent: 2,\n });\n}\n","import { assert } from 'misoai-shared/utils';\nimport yaml from 'js-yaml';\n\nimport type { MidsceneYamlScript } from 'misoai-core';\n\nfunction interpolateEnvVars(content: string): string {\n return content.replace(/\\$\\{([^}]+)\\}/g, (_, envVar) => {\n const value = process.env[envVar.trim()];\n if (value === undefined) {\n throw new Error(`Environment variable \"${envVar.trim()}\" is not defined`);\n }\n return value;\n });\n}\n\nexport function parseYamlScript(\n content: string,\n filePath?: string,\n ignoreCheckingTarget?: boolean,\n): MidsceneYamlScript {\n let processedContent = content;\n if (content.indexOf('android') !== -1 && content.match(/deviceId:\\s*(\\d+)/)) {\n let matchedDeviceId;\n processedContent = content.replace(\n /deviceId:\\s*(\\d+)/g,\n (match, deviceId) => {\n matchedDeviceId = deviceId;\n return `deviceId: '${deviceId}'`;\n },\n );\n console.warn(\n `please use string-style deviceId in yaml script, for example: deviceId: \"${matchedDeviceId}\"`,\n );\n }\n const interpolatedContent = interpolateEnvVars(processedContent);\n const obj = yaml.load(interpolatedContent, {\n schema: yaml.JSON_SCHEMA,\n }) as MidsceneYamlScript;\n\n const pathTip = filePath ? `, failed to load ${filePath}` : '';\n const android =\n typeof obj.android !== 'undefined'\n ? Object.assign({}, obj.android || {})\n : undefined;\n const webConfig = obj.web || obj.target; // no need to handle null case, because web has required parameters url\n const web =\n typeof webConfig !== 'undefined'\n ? Object.assign({}, webConfig || {})\n : undefined;\n\n if (!ignoreCheckingTarget) {\n // make sure at least one of target/web/android is provided\n assert(\n web || android,\n `at least one of \"target\", \"web\", or \"android\" properties is required in yaml script${pathTip}`,\n );\n\n // make sure only one of target/web/android is provided\n assert(\n (web && !android) || (!web && android),\n `only one of \"target\", \"web\", or \"android\" properties is allowed in yaml script${pathTip}`,\n );\n\n // make sure the config is valid\n if (web || android) {\n assert(\n typeof web === 'object' || typeof android === 'object',\n `property \"target/web/android\" must be an object${pathTip}`,\n );\n }\n }\n\n assert(obj.tasks, `property \"tasks\" is required in yaml script ${pathTip}`);\n assert(\n Array.isArray(obj.tasks),\n `property \"tasks\" must be an array in yaml script, but got ${obj.tasks}`,\n );\n return obj;\n}\n"]}
|
package/dist/types/agent.d.ts
CHANGED
@@ -1,19 +1,16 @@
|
|
1
|
-
import { W as WebPage,
|
2
|
-
import { Insight, ExecutionTaskProgressOptions, PlanningAction, ExecutionTaskApply, Executor, MidsceneYamlFlowItem, InsightExtractParam, InsightAssertionResponse, PlanningActionParamWaitFor, OnTaskStartTip, GroupedActionDump, InsightAction, ExecutionDump, LocateOption, PlanningActionParamScroll, LocatorValidatorOption, AgentDescribeElementAtPointResult, LocateValidatorResult, LocateResultElement, AgentAssertOpt, AgentWaitForOpt } from 'misoai-core';
|
1
|
+
import { W as WebPage, e as WebElementInfo, f as WebUIContext } from './page-ed0ecb44.js';
|
2
|
+
import { Insight, ExecutionTaskProgressOptions, PlanningAction, ExecutionTaskApply, Executor, MidsceneYamlFlowItem, InsightExtractParam, InsightExtractOption, InsightAssertionResponse, PlanningActionParamWaitFor, OnTaskStartTip, GroupedActionDump, InsightAction, ExecutionDump, LocateOption, PlanningActionParamScroll, LocatorValidatorOption, AgentDescribeElementAtPointResult, LocateValidatorResult, LocateResultElement, AgentAssertOpt, AgentWaitForOpt } from 'misoai-core';
|
3
3
|
import { ChatCompletionMessageParam } from 'misoai-core/ai-model';
|
4
4
|
import 'playwright';
|
5
5
|
import 'misoai-shared/extractor';
|
6
6
|
import 'puppeteer';
|
7
7
|
import 'misoai-shared/logger';
|
8
8
|
import 'misoai-shared/constants';
|
9
|
-
import 'misoai-core/.';
|
10
9
|
|
11
10
|
interface PlanningCache {
|
12
11
|
type: 'plan';
|
13
12
|
prompt: string;
|
14
13
|
yamlWorkflow: string;
|
15
|
-
contextHash?: string;
|
16
|
-
contextData?: Record<string, any>;
|
17
14
|
}
|
18
15
|
interface LocateCache {
|
19
16
|
type: 'locate';
|
@@ -37,14 +34,13 @@ declare class TaskCache {
|
|
37
34
|
cacheOriginalLength: number;
|
38
35
|
private matchedCacheIndices;
|
39
36
|
constructor(cacheId: string, isCacheResultUsed: boolean, cacheFilePath?: string);
|
40
|
-
matchCache(prompt: string, type: 'plan' | 'locate'
|
41
|
-
|
42
|
-
matchPlanCache(prompt: string, contextData?: Record<string, any>): MatchCacheResult<PlanningCache> | undefined;
|
37
|
+
matchCache(prompt: string, type: 'plan' | 'locate'): MatchCacheResult<PlanningCache | LocateCache> | undefined;
|
38
|
+
matchPlanCache(prompt: string): MatchCacheResult<PlanningCache> | undefined;
|
43
39
|
matchLocateCache(prompt: string): MatchCacheResult<LocateCache> | undefined;
|
44
40
|
appendCache(cache: PlanningCache | LocateCache): void;
|
45
41
|
loadCacheFromFile(): CacheFileContent | undefined;
|
46
42
|
flushCacheToFile(): void;
|
47
|
-
updateOrAppendCacheRecord(newRecord: PlanningCache | LocateCache, cachedRecord?: MatchCacheResult<PlanningCache | LocateCache
|
43
|
+
updateOrAppendCacheRecord(newRecord: PlanningCache | LocateCache, cachedRecord?: MatchCacheResult<PlanningCache | LocateCache>): void;
|
48
44
|
}
|
49
45
|
|
50
46
|
interface ExecutionResult<OutputType = any> {
|
@@ -89,10 +85,10 @@ declare class PageTaskExecutor {
|
|
89
85
|
yamlFlow?: MidsceneYamlFlowItem[];
|
90
86
|
} | undefined>>;
|
91
87
|
private createTypeQueryTask;
|
92
|
-
query(demand: InsightExtractParam): Promise<ExecutionResult>;
|
93
|
-
boolean(prompt: string): Promise<ExecutionResult<boolean>>;
|
94
|
-
number(prompt: string): Promise<ExecutionResult<number>>;
|
95
|
-
string(prompt: string): Promise<ExecutionResult<string>>;
|
88
|
+
query(demand: InsightExtractParam, opt?: InsightExtractOption): Promise<ExecutionResult>;
|
89
|
+
boolean(prompt: string, opt?: InsightExtractOption): Promise<ExecutionResult<boolean>>;
|
90
|
+
number(prompt: string, opt?: InsightExtractOption): Promise<ExecutionResult<number>>;
|
91
|
+
string(prompt: string, opt?: InsightExtractOption): Promise<ExecutionResult<string>>;
|
96
92
|
assert(assertion: string): Promise<ExecutionResult<InsightAssertionResponse>>;
|
97
93
|
/**
|
98
94
|
* Append a message to the conversation history
|
@@ -203,8 +199,6 @@ interface PageAgentOpt {
|
|
203
199
|
aiActionContext?: string;
|
204
200
|
waitForNavigationTimeout?: number;
|
205
201
|
waitForNetworkIdleTimeout?: number;
|
206
|
-
enableCumulativeContext?: boolean;
|
207
|
-
autoClearContext?: boolean;
|
208
202
|
}
|
209
203
|
declare class PageAgent<PageType extends WebPage = WebPage> {
|
210
204
|
page: PageType;
|
@@ -220,31 +214,7 @@ declare class PageAgent<PageType extends WebPage = WebPage> {
|
|
220
214
|
dryMode: boolean;
|
221
215
|
onTaskStartTip?: OnTaskStartTip;
|
222
216
|
taskCache?: TaskCache;
|
223
|
-
/**
|
224
|
-
* Context store for cumulative context functionality
|
225
|
-
*/
|
226
|
-
private contextStore?;
|
227
217
|
constructor(page: PageType, opts?: PageAgentOpt);
|
228
|
-
/**
|
229
|
-
* Initialize context store for cumulative context functionality
|
230
|
-
*/
|
231
|
-
private initializeContextStore;
|
232
|
-
/**
|
233
|
-
* Get the context store instance
|
234
|
-
*/
|
235
|
-
getContextStore(): any;
|
236
|
-
/**
|
237
|
-
* Clear the context store
|
238
|
-
*/
|
239
|
-
clearContext(): void;
|
240
|
-
/**
|
241
|
-
* Get all stored data from context store
|
242
|
-
*/
|
243
|
-
getStoredData(): any;
|
244
|
-
/**
|
245
|
-
* Get step summary from context store
|
246
|
-
*/
|
247
|
-
getStepSummary(): any;
|
248
218
|
getUIContext(action?: InsightAction): Promise<WebUIContext>;
|
249
219
|
private _callInsightCaptcha;
|
250
220
|
setAIActionContext(prompt: string): Promise<void>;
|
@@ -258,6 +228,7 @@ declare class PageAgent<PageType extends WebPage = WebPage> {
|
|
258
228
|
private buildDetailedLocateParam;
|
259
229
|
aiTap(locatePrompt: string, opt?: LocateOption): Promise<AITaskResult>;
|
260
230
|
aiHover(locatePrompt: string, opt?: LocateOption): Promise<AITaskResult>;
|
231
|
+
aiRightClick(locatePrompt: string, opt?: LocateOption): Promise<AITaskResult>;
|
261
232
|
aiInput(value: string, locatePrompt: string, opt?: LocateOption): Promise<AITaskResult>;
|
262
233
|
aiKeyboardPress(keyName: string, locatePrompt?: string, opt?: LocateOption): Promise<AITaskResult>;
|
263
234
|
aiScroll(scrollParam: PlanningActionParamScroll, locatePrompt?: string, opt?: LocateOption): Promise<AITaskResult>;
|
@@ -287,19 +258,10 @@ declare class PageAgent<PageType extends WebPage = WebPage> {
|
|
287
258
|
}): Promise<AITaskResult>;
|
288
259
|
runYaml(yamlScriptContent: string): Promise<AITaskResult<Record<string, any>>>;
|
289
260
|
evaluateJavaScript(script: string): Promise<any>;
|
261
|
+
logScreenshot(title?: string, options?: {
|
262
|
+
content?: string;
|
263
|
+
}): Promise<void>;
|
290
264
|
destroy(): Promise<void>;
|
291
|
-
/**
|
292
|
-
* Analyze execution results from executor to generate meaningful descriptions
|
293
|
-
*/
|
294
|
-
private analyzeExecutionResults;
|
295
|
-
/**
|
296
|
-
* Extract element information from locate task
|
297
|
-
*/
|
298
|
-
private extractElementInfo;
|
299
|
-
/**
|
300
|
-
* Generate natural language description for actions
|
301
|
-
*/
|
302
|
-
private generateActionDescription;
|
303
265
|
}
|
304
266
|
|
305
267
|
export { type AITaskMetadata, type AITaskResult, PageAgent, type PageAgentOpt };
|
@@ -1,9 +1,8 @@
|
|
1
|
-
export { E as ExtensionBridgePageBrowserSide } from './browser-
|
2
|
-
import './page-
|
1
|
+
export { E as ExtensionBridgePageBrowserSide } from './browser-9b472ffb.js';
|
2
|
+
import './page-ed0ecb44.js';
|
3
3
|
import 'playwright';
|
4
4
|
import 'misoai-core';
|
5
5
|
import 'misoai-shared/extractor';
|
6
6
|
import 'puppeteer';
|
7
7
|
import 'misoai-shared/logger';
|
8
8
|
import 'misoai-shared/constants';
|
9
|
-
import 'misoai-core/.';
|
@@ -1,14 +1,13 @@
|
|
1
1
|
import { PageAgent, PageAgentOpt, AITaskResult } from './agent.js';
|
2
|
-
import { B as BridgeConnectTabOptions, E as ExtensionBridgePageBrowserSide } from './browser-
|
2
|
+
import { B as BridgeConnectTabOptions, E as ExtensionBridgePageBrowserSide } from './browser-9b472ffb.js';
|
3
3
|
export { allConfigFromEnv, overrideAIConfig } from 'misoai-shared/env';
|
4
|
-
import './page-
|
4
|
+
import './page-ed0ecb44.js';
|
5
5
|
import 'playwright';
|
6
6
|
import 'misoai-core';
|
7
7
|
import 'misoai-shared/extractor';
|
8
8
|
import 'puppeteer';
|
9
9
|
import 'misoai-shared/logger';
|
10
10
|
import 'misoai-shared/constants';
|
11
|
-
import 'misoai-core/.';
|
12
11
|
import 'misoai-core/ai-model';
|
13
12
|
|
14
13
|
interface ChromeExtensionPageCliSide extends ExtensionBridgePageBrowserSide {
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { C as ChromeExtensionProxyPage } from './page-
|
2
|
-
export { E as ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from './page-
|
1
|
+
import { C as ChromeExtensionProxyPage } from './page-ed0ecb44.js';
|
2
|
+
export { E as ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from './page-ed0ecb44.js';
|
3
3
|
import { PageAgent, PageAgentOpt } from './agent.js';
|
4
4
|
export { overrideAIConfig } from 'misoai-shared/env';
|
5
5
|
import 'playwright';
|
@@ -8,7 +8,6 @@ import 'misoai-shared/extractor';
|
|
8
8
|
import 'puppeteer';
|
9
9
|
import 'misoai-shared/logger';
|
10
10
|
import 'misoai-shared/constants';
|
11
|
-
import 'misoai-core/.';
|
12
11
|
import 'misoai-core/ai-model';
|
13
12
|
|
14
13
|
declare class ChromeExtensionProxyPageAgent extends PageAgent {
|
package/dist/types/index.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
export { PlayWrightAiFixtureType, PlaywrightAgent, PlaywrightAiFixture } from './playwright.js';
|
2
|
-
export {
|
2
|
+
export { b as AbstractPage, a as AndroidDeviceInputOpt, A as AndroidDevicePage, W as WebPage, p as parseContextFromWebPage } from './page-ed0ecb44.js';
|
3
3
|
export { PageAgent, PageAgentOpt } from './agent.js';
|
4
4
|
export { PuppeteerAgent } from './puppeteer.js';
|
5
5
|
export { StaticPageAgent } from './playground.js';
|
@@ -12,5 +12,4 @@ import 'misoai-shared/extractor';
|
|
12
12
|
import 'puppeteer';
|
13
13
|
import 'misoai-shared/logger';
|
14
14
|
import 'misoai-shared/constants';
|
15
|
-
import 'misoai-core/.';
|
16
15
|
import 'misoai-core/ai-model';
|
@@ -2,7 +2,7 @@ import * as http from 'http';
|
|
2
2
|
import { Server } from 'node:http';
|
3
3
|
import express from 'express';
|
4
4
|
import { PageAgent } from './agent.js';
|
5
|
-
import {
|
5
|
+
import { b as AbstractPage } from './page-ed0ecb44.js';
|
6
6
|
import 'misoai-core';
|
7
7
|
import 'misoai-core/ai-model';
|
8
8
|
import 'playwright';
|
@@ -10,7 +10,6 @@ import 'misoai-shared/extractor';
|
|
10
10
|
import 'puppeteer';
|
11
11
|
import 'misoai-shared/logger';
|
12
12
|
import 'misoai-shared/constants';
|
13
|
-
import 'misoai-core/.';
|
14
13
|
|
15
14
|
declare class PlaygroundServer {
|
16
15
|
app: express.Application;
|