@midscene/core 0.16.3-beta-20250428133510.0 → 0.16.4-beta-20250429033218.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/{chunk-ELJ2V35J.js → chunk-PSGMMDLS.js} +47 -29
- package/dist/es/chunk-PSGMMDLS.js.map +1 -0
- package/dist/es/index.js +1 -1
- package/dist/es/utils.d.ts +1 -1
- package/dist/es/utils.js +1 -1
- package/dist/lib/{chunk-ELJ2V35J.js → chunk-PSGMMDLS.js} +47 -29
- package/dist/lib/chunk-PSGMMDLS.js.map +1 -0
- package/dist/lib/index.js +4 -4
- package/dist/lib/utils.d.ts +1 -1
- package/dist/lib/utils.js +2 -2
- package/dist/types/utils.d.ts +1 -1
- package/package.json +2 -2
- package/report/index.html +83 -81
- package/dist/es/chunk-ELJ2V35J.js.map +0 -1
- package/dist/lib/chunk-ELJ2V35J.js.map +0 -1
|
@@ -52,43 +52,66 @@ function replaceStringWithFirstAppearance(str, target, replacement) {
|
|
|
52
52
|
const index = str.indexOf(target);
|
|
53
53
|
return str.slice(0, index) + replacement + str.slice(index + target.length);
|
|
54
54
|
}
|
|
55
|
-
function reportHTMLContent(dumpData) {
|
|
55
|
+
function reportHTMLContent(dumpData, reportPath) {
|
|
56
56
|
const tpl = getReportTpl();
|
|
57
57
|
if (!tpl) {
|
|
58
58
|
console.warn("reportTpl is not set, will not write report");
|
|
59
59
|
return "";
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
const dumpPlaceholder = "{{dump}}";
|
|
62
|
+
if (!tpl.includes(dumpPlaceholder)) {
|
|
63
|
+
console.warn("Template does not contain {{dump}} placeholder");
|
|
64
|
+
return "";
|
|
65
|
+
}
|
|
66
|
+
const placeholderIndex = tpl.indexOf(dumpPlaceholder);
|
|
67
|
+
const firstPart = tpl.substring(0, placeholderIndex);
|
|
68
|
+
const secondPart = tpl.substring(placeholderIndex + dumpPlaceholder.length);
|
|
69
|
+
const writeToFile = reportPath && !ifInBrowser;
|
|
70
|
+
let resultContent = "";
|
|
71
|
+
const appendOrWrite = (content) => {
|
|
72
|
+
if (writeToFile) {
|
|
73
|
+
writeFileSync(reportPath, `${content}
|
|
74
|
+
`, {
|
|
75
|
+
flag: "a"
|
|
76
|
+
});
|
|
77
|
+
} else {
|
|
78
|
+
resultContent += `${content}
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
if (writeToFile) {
|
|
83
|
+
writeFileSync(reportPath, firstPart, { flag: "w" });
|
|
84
|
+
} else {
|
|
85
|
+
resultContent = firstPart;
|
|
86
|
+
}
|
|
62
87
|
if (Array.isArray(dumpData) && dumpData.length === 0 || typeof dumpData === "undefined") {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"{{dump}}",
|
|
66
|
-
'<script type="midscene_web_dump" type="application/json"></script>'
|
|
67
|
-
);
|
|
88
|
+
const dumpContent = '<script type="midscene_web_dump" type="application/json"></script>';
|
|
89
|
+
appendOrWrite(dumpContent);
|
|
68
90
|
} else if (typeof dumpData === "string") {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"{{dump}}",
|
|
72
|
-
// biome-ignore lint/style/useTemplate: <explanation>
|
|
91
|
+
const dumpContent = (
|
|
92
|
+
// biome-ignore lint/style/useTemplate: <explanation> do not use template string here, will cause bundle error
|
|
73
93
|
'<script type="midscene_web_dump" type="application/json">\n' + dumpData + "\n</script>"
|
|
74
94
|
);
|
|
95
|
+
appendOrWrite(dumpContent);
|
|
75
96
|
} else {
|
|
76
|
-
|
|
97
|
+
for (let i = 0; i < dumpData.length; i++) {
|
|
98
|
+
const { dumpString, attributes } = dumpData[i];
|
|
77
99
|
const attributesArr = Object.keys(attributes || {}).map((key) => {
|
|
78
100
|
return `${key}="${encodeURIComponent(attributes[key])}"`;
|
|
79
101
|
});
|
|
80
|
-
|
|
81
|
-
// biome-ignore lint/style/useTemplate: <explanation>
|
|
102
|
+
const dumpContent = (
|
|
103
|
+
// biome-ignore lint/style/useTemplate: <explanation> do not use template string here, will cause bundle error
|
|
82
104
|
'<script type="midscene_web_dump" type="application/json" ' + attributesArr.join(" ") + ">\n" + dumpString + "\n</script>"
|
|
83
105
|
);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
tpl,
|
|
87
|
-
"{{dump}}",
|
|
88
|
-
dumps.join("\n")
|
|
89
|
-
);
|
|
106
|
+
appendOrWrite(dumpContent);
|
|
107
|
+
}
|
|
90
108
|
}
|
|
91
|
-
|
|
109
|
+
if (writeToFile) {
|
|
110
|
+
writeFileSync(reportPath, secondPart, { flag: "a" });
|
|
111
|
+
return reportPath;
|
|
112
|
+
}
|
|
113
|
+
resultContent += secondPart;
|
|
114
|
+
return resultContent;
|
|
92
115
|
}
|
|
93
116
|
function writeDumpReport(fileName, dumpData) {
|
|
94
117
|
if (ifInBrowser) {
|
|
@@ -105,12 +128,7 @@ function writeDumpReport(fileName, dumpData) {
|
|
|
105
128
|
getMidsceneRunSubDir("report"),
|
|
106
129
|
`${fileName}.html`
|
|
107
130
|
);
|
|
108
|
-
|
|
109
|
-
if (!reportContent) {
|
|
110
|
-
console.warn("reportContent is empty, will not write report");
|
|
111
|
-
return null;
|
|
112
|
-
}
|
|
113
|
-
writeFileSync(reportPath, reportContent);
|
|
131
|
+
reportHTMLContent(dumpData, reportPath);
|
|
114
132
|
if (process.env.MIDSCENE_DEBUG_LOG_JSON) {
|
|
115
133
|
writeFileSync(
|
|
116
134
|
`${reportPath}.json`,
|
|
@@ -200,7 +218,7 @@ function stringifyDumpData(data, indents) {
|
|
|
200
218
|
return JSON.stringify(data, replacerForPageObject, indents);
|
|
201
219
|
}
|
|
202
220
|
function getVersion() {
|
|
203
|
-
return "0.16.
|
|
221
|
+
return "0.16.4-beta-20250429033218.0";
|
|
204
222
|
}
|
|
205
223
|
function debugLog(...message) {
|
|
206
224
|
const debugMode = getAIConfig(MIDSCENE_DEBUG_MODE);
|
|
@@ -264,4 +282,4 @@ export {
|
|
|
264
282
|
uploadTestInfoToServer
|
|
265
283
|
};
|
|
266
284
|
|
|
267
|
-
//# sourceMappingURL=chunk-
|
|
285
|
+
//# sourceMappingURL=chunk-PSGMMDLS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"mappings":"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","names":[],"ignoreList":[],"sources":["../../src/utils.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport * as path from 'node:path';\nimport { dirname } from 'node:path';\nimport {\n defaultRunDirName,\n getMidsceneRunSubDir,\n logDir,\n} from '@midscene/shared/common';\nimport {\n MIDSCENE_DEBUG_MODE,\n MIDSCENE_OPENAI_INIT_CONFIG_JSON,\n getAIConfig,\n getAIConfigInJson,\n} from '@midscene/shared/env';\nimport { getRunningPkgInfo } from '@midscene/shared/fs';\nimport { assert, getGlobalScope } from '@midscene/shared/utils';\nimport { ifInBrowser, uuid } from '@midscene/shared/utils';\nimport type { Rect, ReportDumpWithAttributes } from './types';\n\nlet logEnvReady = false;\n\nexport const groupedActionDumpFileExt = 'web-dump.json';\n\nexport function getLogDir() {\n return logDir;\n}\n\nlet reportTpl: string | null = null;\nexport function setReportTpl(tpl: string) {\n reportTpl = tpl;\n}\n\nfunction getReportTpl() {\n const globalScope = getGlobalScope();\n if (\n !reportTpl &&\n globalScope &&\n typeof (globalScope as any).get_midscene_report_tpl === 'function'\n ) {\n reportTpl = (globalScope as any).get_midscene_report_tpl();\n return reportTpl;\n }\n\n const __dirname = dirname(__filename);\n if (!reportTpl && !ifInBrowser) {\n const possiblePaths = [\n path.join(__dirname, '../../report/index.html'),\n path.join(__dirname, '../report/index.html'),\n ];\n\n for (const reportPath of possiblePaths) {\n if (existsSync(reportPath)) {\n reportTpl = readFileSync(reportPath, 'utf-8');\n break;\n }\n }\n }\n return reportTpl;\n}\n\nexport function replaceStringWithFirstAppearance(\n str: string,\n target: string,\n replacement: string,\n) {\n const index = str.indexOf(target);\n return str.slice(0, index) + replacement + str.slice(index + target.length);\n}\n\nexport function reportHTMLContent(\n dumpData: string | ReportDumpWithAttributes[],\n reportPath?: string,\n): string {\n const tpl = getReportTpl();\n if (!tpl) {\n console.warn('reportTpl is not set, will not write report');\n return '';\n }\n\n const dumpPlaceholder = '{{dump}}';\n\n // verify the template contains the placeholder\n if (!tpl.includes(dumpPlaceholder)) {\n console.warn('Template does not contain {{dump}} placeholder');\n return '';\n }\n\n // find the first placeholder position\n const placeholderIndex = tpl.indexOf(dumpPlaceholder);\n\n // split the template into two parts before and after the placeholder\n const firstPart = tpl.substring(0, placeholderIndex);\n const secondPart = tpl.substring(placeholderIndex + dumpPlaceholder.length);\n\n // if reportPath is set, it means we are in write to file mode\n const writeToFile = reportPath && !ifInBrowser;\n let resultContent = '';\n\n // helper function: decide to write to file or append to resultContent\n const appendOrWrite = (content: string): void => {\n if (writeToFile) {\n writeFileSync(reportPath!, `${content}\\n`, {\n flag: 'a',\n });\n } else {\n resultContent += `${content}\\n`;\n }\n };\n\n // if writeToFile is true, write the first part to file, otherwise set the first part to the initial value of resultContent\n if (writeToFile) {\n writeFileSync(reportPath!, firstPart, { flag: 'w' }); // use 'w' flag to overwrite the existing file\n } else {\n resultContent = firstPart;\n }\n\n // generate dump content\n // handle empty data or undefined\n if (\n (Array.isArray(dumpData) && dumpData.length === 0) ||\n typeof dumpData === 'undefined'\n ) {\n const dumpContent =\n '<script type=\"midscene_web_dump\" type=\"application/json\"></script>';\n appendOrWrite(dumpContent);\n }\n // handle string type dumpData\n else if (typeof dumpData === 'string') {\n const dumpContent =\n // biome-ignore lint/style/useTemplate: <explanation> do not use template string here, will cause bundle error\n '<script type=\"midscene_web_dump\" type=\"application/json\">\\n' +\n dumpData +\n '\\n</script>';\n appendOrWrite(dumpContent);\n }\n // handle array type dumpData\n else {\n // for array, handle each item\n for (let i = 0; i < dumpData.length; i++) {\n const { dumpString, attributes } = dumpData[i];\n const attributesArr = Object.keys(attributes || {}).map((key) => {\n return `${key}=\"${encodeURIComponent(attributes![key])}\"`;\n });\n\n const dumpContent =\n // biome-ignore lint/style/useTemplate: <explanation> do not use template string here, will cause bundle error\n '<script type=\"midscene_web_dump\" type=\"application/json\" ' +\n attributesArr.join(' ') +\n '>\\n' +\n dumpString +\n '\\n</script>';\n appendOrWrite(dumpContent);\n }\n }\n\n // add the second part\n if (writeToFile) {\n writeFileSync(reportPath!, secondPart, { flag: 'a' });\n return reportPath!;\n }\n\n resultContent += secondPart;\n return resultContent;\n}\n\nexport function writeDumpReport(\n fileName: string,\n dumpData: string | ReportDumpWithAttributes[],\n): string | null {\n if (ifInBrowser) {\n console.log('will not write report in browser');\n return null;\n }\n\n const __dirname = dirname(__filename);\n const midscenePkgInfo = getRunningPkgInfo(__dirname);\n if (!midscenePkgInfo) {\n console.warn('midscenePkgInfo not found, will not write report');\n return null;\n }\n\n const reportPath = path.join(\n getMidsceneRunSubDir('report'),\n `${fileName}.html`,\n );\n\n reportHTMLContent(dumpData, reportPath);\n\n if (process.env.MIDSCENE_DEBUG_LOG_JSON) {\n writeFileSync(\n `${reportPath}.json`,\n typeof dumpData === 'string'\n ? dumpData\n : JSON.stringify(dumpData, null, 2),\n );\n }\n\n return reportPath;\n}\n\nexport function writeLogFile(opts: {\n fileName: string;\n fileExt: string;\n fileContent: string;\n type: 'dump' | 'cache' | 'report' | 'tmp';\n generateReport?: boolean;\n}) {\n if (ifInBrowser) {\n return '/mock/report.html';\n }\n const { fileName, fileExt, fileContent, type = 'dump' } = opts;\n const targetDir = getMidsceneRunSubDir(type);\n // Ensure directory exists\n if (!logEnvReady) {\n assert(targetDir, 'logDir should be set before writing dump file');\n\n // gitIgnore in the parent directory\n const gitIgnorePath = path.join(targetDir, '../../.gitignore');\n const gitPath = path.join(targetDir, '../../.git');\n let gitIgnoreContent = '';\n\n if (existsSync(gitPath)) {\n // if the git path exists, we need to add the log folder to the git ignore file\n if (existsSync(gitIgnorePath)) {\n gitIgnoreContent = readFileSync(gitIgnorePath, 'utf-8');\n }\n\n // ignore the log folder\n if (!gitIgnoreContent.includes(`${defaultRunDirName}/`)) {\n writeFileSync(\n gitIgnorePath,\n `${gitIgnoreContent}\\n# Midscene.js dump files\\n${defaultRunDirName}/dump\\n${defaultRunDirName}/report\\n${defaultRunDirName}/tmp\\n${defaultRunDirName}/log\\n`,\n 'utf-8',\n );\n }\n }\n\n logEnvReady = true;\n }\n\n const filePath = path.join(targetDir, `${fileName}.${fileExt}`);\n\n if (type !== 'dump') {\n // do not write dump file any more\n writeFileSync(filePath, fileContent);\n }\n\n if (opts?.generateReport) {\n return writeDumpReport(fileName, fileContent);\n }\n\n return filePath;\n}\n\nexport function getTmpDir(): string | null {\n try {\n const runningPkgInfo = getRunningPkgInfo();\n if (!runningPkgInfo) {\n return null;\n }\n const { name } = runningPkgInfo;\n const tmpPath = path.join(tmpdir(), name);\n mkdirSync(tmpPath, { recursive: true });\n return tmpPath;\n } catch (e) {\n return null;\n }\n}\n\nexport function getTmpFile(fileExtWithoutDot: string): string | null {\n if (ifInBrowser) {\n return null;\n }\n const tmpDir = getTmpDir();\n const filename = `${uuid()}.${fileExtWithoutDot}`;\n return path.join(tmpDir!, filename);\n}\n\nexport function overlapped(container: Rect, target: Rect) {\n // container and the target have some part overlapped\n return (\n container.left < target.left + target.width &&\n container.left + container.width > target.left &&\n container.top < target.top + target.height &&\n container.top + container.height > target.top\n );\n}\n\nexport async function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function replacerForPageObject(key: string, value: any) {\n if (value && value.constructor?.name === 'Page') {\n return '[Page object]';\n }\n if (value && value.constructor?.name === 'Browser') {\n return '[Browser object]';\n }\n return value;\n}\n\nexport function stringifyDumpData(data: any, indents?: number) {\n return JSON.stringify(data, replacerForPageObject, indents);\n}\n\ndeclare const __VERSION__: string;\n\nexport function getVersion() {\n return __VERSION__;\n}\n\nfunction debugLog(...message: any[]) {\n const debugMode = getAIConfig(MIDSCENE_DEBUG_MODE);\n if (debugMode) {\n console.log('[Midscene]', ...message);\n }\n}\n\nlet lastReportedRepoUrl = '';\nexport function uploadTestInfoToServer({ testUrl }: { testUrl: string }) {\n let repoUrl = '';\n let userEmail = '';\n\n const extraConfig = getAIConfigInJson(MIDSCENE_OPENAI_INIT_CONFIG_JSON);\n const serverUrl = extraConfig?.REPORT_SERVER_URL;\n\n try {\n repoUrl = execSync('git config --get remote.origin.url').toString().trim();\n userEmail = execSync('git config --get user.email').toString().trim();\n } catch (error) {\n debugLog('Failed to get git info:', error);\n }\n\n // Only upload test info if:\n // 1. Server URL is configured AND\n // 2. Either:\n // - We have a repo URL that's different from last reported one (to avoid duplicate reports)\n // - OR we don't have a repo URL but have a test URL (for non-git environments)\n if (\n serverUrl &&\n ((repoUrl && repoUrl !== lastReportedRepoUrl) || (!repoUrl && testUrl))\n ) {\n debugLog('Uploading test info to server', {\n serverUrl,\n repoUrl,\n testUrl,\n userEmail,\n });\n\n fetch(serverUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n repo_url: repoUrl,\n test_url: testUrl,\n user_email: userEmail,\n }),\n })\n .then((response) => response.json())\n .then((data) => {\n debugLog('Successfully uploaded test info to server:', data);\n })\n .catch((error) =>\n debugLog('Failed to upload test info to server:', error),\n );\n lastReportedRepoUrl = repoUrl;\n }\n}\n"]}
|
package/dist/es/index.js
CHANGED
package/dist/es/utils.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ declare const groupedActionDumpFileExt = "web-dump.json";
|
|
|
6
6
|
declare function getLogDir(): string;
|
|
7
7
|
declare function setReportTpl(tpl: string): void;
|
|
8
8
|
declare function replaceStringWithFirstAppearance(str: string, target: string, replacement: string): string;
|
|
9
|
-
declare function reportHTMLContent(dumpData: string | ReportDumpWithAttributes[]): string;
|
|
9
|
+
declare function reportHTMLContent(dumpData: string | ReportDumpWithAttributes[], reportPath?: string): string;
|
|
10
10
|
declare function writeDumpReport(fileName: string, dumpData: string | ReportDumpWithAttributes[]): string | null;
|
|
11
11
|
declare function writeLogFile(opts: {
|
|
12
12
|
fileName: string;
|
package/dist/es/utils.js
CHANGED
|
@@ -52,43 +52,66 @@ function replaceStringWithFirstAppearance(str, target, replacement) {
|
|
|
52
52
|
const index = str.indexOf(target);
|
|
53
53
|
return str.slice(0, index) + replacement + str.slice(index + target.length);
|
|
54
54
|
}
|
|
55
|
-
function reportHTMLContent(dumpData) {
|
|
55
|
+
function reportHTMLContent(dumpData, reportPath) {
|
|
56
56
|
const tpl = getReportTpl();
|
|
57
57
|
if (!tpl) {
|
|
58
58
|
console.warn("reportTpl is not set, will not write report");
|
|
59
59
|
return "";
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
const dumpPlaceholder = "{{dump}}";
|
|
62
|
+
if (!tpl.includes(dumpPlaceholder)) {
|
|
63
|
+
console.warn("Template does not contain {{dump}} placeholder");
|
|
64
|
+
return "";
|
|
65
|
+
}
|
|
66
|
+
const placeholderIndex = tpl.indexOf(dumpPlaceholder);
|
|
67
|
+
const firstPart = tpl.substring(0, placeholderIndex);
|
|
68
|
+
const secondPart = tpl.substring(placeholderIndex + dumpPlaceholder.length);
|
|
69
|
+
const writeToFile = reportPath && !_utils.ifInBrowser;
|
|
70
|
+
let resultContent = "";
|
|
71
|
+
const appendOrWrite = (content) => {
|
|
72
|
+
if (writeToFile) {
|
|
73
|
+
_fs.writeFileSync.call(void 0, reportPath, `${content}
|
|
74
|
+
`, {
|
|
75
|
+
flag: "a"
|
|
76
|
+
});
|
|
77
|
+
} else {
|
|
78
|
+
resultContent += `${content}
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
if (writeToFile) {
|
|
83
|
+
_fs.writeFileSync.call(void 0, reportPath, firstPart, { flag: "w" });
|
|
84
|
+
} else {
|
|
85
|
+
resultContent = firstPart;
|
|
86
|
+
}
|
|
62
87
|
if (Array.isArray(dumpData) && dumpData.length === 0 || typeof dumpData === "undefined") {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"{{dump}}",
|
|
66
|
-
'<script type="midscene_web_dump" type="application/json"></script>'
|
|
67
|
-
);
|
|
88
|
+
const dumpContent = '<script type="midscene_web_dump" type="application/json"></script>';
|
|
89
|
+
appendOrWrite(dumpContent);
|
|
68
90
|
} else if (typeof dumpData === "string") {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"{{dump}}",
|
|
72
|
-
// biome-ignore lint/style/useTemplate: <explanation>
|
|
91
|
+
const dumpContent = (
|
|
92
|
+
// biome-ignore lint/style/useTemplate: <explanation> do not use template string here, will cause bundle error
|
|
73
93
|
'<script type="midscene_web_dump" type="application/json">\n' + dumpData + "\n</script>"
|
|
74
94
|
);
|
|
95
|
+
appendOrWrite(dumpContent);
|
|
75
96
|
} else {
|
|
76
|
-
|
|
97
|
+
for (let i = 0; i < dumpData.length; i++) {
|
|
98
|
+
const { dumpString, attributes } = dumpData[i];
|
|
77
99
|
const attributesArr = Object.keys(attributes || {}).map((key) => {
|
|
78
100
|
return `${key}="${encodeURIComponent(attributes[key])}"`;
|
|
79
101
|
});
|
|
80
|
-
|
|
81
|
-
// biome-ignore lint/style/useTemplate: <explanation>
|
|
102
|
+
const dumpContent = (
|
|
103
|
+
// biome-ignore lint/style/useTemplate: <explanation> do not use template string here, will cause bundle error
|
|
82
104
|
'<script type="midscene_web_dump" type="application/json" ' + attributesArr.join(" ") + ">\n" + dumpString + "\n</script>"
|
|
83
105
|
);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
tpl,
|
|
87
|
-
"{{dump}}",
|
|
88
|
-
dumps.join("\n")
|
|
89
|
-
);
|
|
106
|
+
appendOrWrite(dumpContent);
|
|
107
|
+
}
|
|
90
108
|
}
|
|
91
|
-
|
|
109
|
+
if (writeToFile) {
|
|
110
|
+
_fs.writeFileSync.call(void 0, reportPath, secondPart, { flag: "a" });
|
|
111
|
+
return reportPath;
|
|
112
|
+
}
|
|
113
|
+
resultContent += secondPart;
|
|
114
|
+
return resultContent;
|
|
92
115
|
}
|
|
93
116
|
function writeDumpReport(fileName, dumpData) {
|
|
94
117
|
if (_utils.ifInBrowser) {
|
|
@@ -105,12 +128,7 @@ function writeDumpReport(fileName, dumpData) {
|
|
|
105
128
|
_common.getMidsceneRunSubDir.call(void 0, "report"),
|
|
106
129
|
`${fileName}.html`
|
|
107
130
|
);
|
|
108
|
-
|
|
109
|
-
if (!reportContent) {
|
|
110
|
-
console.warn("reportContent is empty, will not write report");
|
|
111
|
-
return null;
|
|
112
|
-
}
|
|
113
|
-
_fs.writeFileSync.call(void 0, reportPath, reportContent);
|
|
131
|
+
reportHTMLContent(dumpData, reportPath);
|
|
114
132
|
if (process.env.MIDSCENE_DEBUG_LOG_JSON) {
|
|
115
133
|
_fs.writeFileSync.call(void 0,
|
|
116
134
|
`${reportPath}.json`,
|
|
@@ -200,7 +218,7 @@ function stringifyDumpData(data, indents) {
|
|
|
200
218
|
return JSON.stringify(data, replacerForPageObject, indents);
|
|
201
219
|
}
|
|
202
220
|
function getVersion() {
|
|
203
|
-
return "0.16.
|
|
221
|
+
return "0.16.4-beta-20250429033218.0";
|
|
204
222
|
}
|
|
205
223
|
function debugLog(...message) {
|
|
206
224
|
const debugMode = _env.getAIConfig.call(void 0, _env.MIDSCENE_DEBUG_MODE);
|
|
@@ -264,4 +282,4 @@ function uploadTestInfoToServer({ testUrl }) {
|
|
|
264
282
|
|
|
265
283
|
exports.groupedActionDumpFileExt = groupedActionDumpFileExt; exports.getLogDir = getLogDir; exports.setReportTpl = setReportTpl; exports.replaceStringWithFirstAppearance = replaceStringWithFirstAppearance; exports.reportHTMLContent = reportHTMLContent; exports.writeDumpReport = writeDumpReport; exports.writeLogFile = writeLogFile; exports.getTmpDir = getTmpDir; exports.getTmpFile = getTmpFile; exports.overlapped = overlapped; exports.sleep = sleep; exports.replacerForPageObject = replacerForPageObject; exports.stringifyDumpData = stringifyDumpData; exports.getVersion = getVersion; exports.uploadTestInfoToServer = uploadTestInfoToServer;
|
|
266
284
|
|
|
267
|
-
//# sourceMappingURL=chunk-
|
|
285
|
+
//# sourceMappingURL=chunk-PSGMMDLS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"mappings":"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","names":[],"ignoreList":[],"sources":["../../src/utils.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport * as path from 'node:path';\nimport { dirname } from 'node:path';\nimport {\n defaultRunDirName,\n getMidsceneRunSubDir,\n logDir,\n} from '@midscene/shared/common';\nimport {\n MIDSCENE_DEBUG_MODE,\n MIDSCENE_OPENAI_INIT_CONFIG_JSON,\n getAIConfig,\n getAIConfigInJson,\n} from '@midscene/shared/env';\nimport { getRunningPkgInfo } from '@midscene/shared/fs';\nimport { assert, getGlobalScope } from '@midscene/shared/utils';\nimport { ifInBrowser, uuid } from '@midscene/shared/utils';\nimport type { Rect, ReportDumpWithAttributes } from './types';\n\nlet logEnvReady = false;\n\nexport const groupedActionDumpFileExt = 'web-dump.json';\n\nexport function getLogDir() {\n return logDir;\n}\n\nlet reportTpl: string | null = null;\nexport function setReportTpl(tpl: string) {\n reportTpl = tpl;\n}\n\nfunction getReportTpl() {\n const globalScope = getGlobalScope();\n if (\n !reportTpl &&\n globalScope &&\n typeof (globalScope as any).get_midscene_report_tpl === 'function'\n ) {\n reportTpl = (globalScope as any).get_midscene_report_tpl();\n return reportTpl;\n }\n\n const __dirname = dirname(__filename);\n if (!reportTpl && !ifInBrowser) {\n const possiblePaths = [\n path.join(__dirname, '../../report/index.html'),\n path.join(__dirname, '../report/index.html'),\n ];\n\n for (const reportPath of possiblePaths) {\n if (existsSync(reportPath)) {\n reportTpl = readFileSync(reportPath, 'utf-8');\n break;\n }\n }\n }\n return reportTpl;\n}\n\nexport function replaceStringWithFirstAppearance(\n str: string,\n target: string,\n replacement: string,\n) {\n const index = str.indexOf(target);\n return str.slice(0, index) + replacement + str.slice(index + target.length);\n}\n\nexport function reportHTMLContent(\n dumpData: string | ReportDumpWithAttributes[],\n reportPath?: string,\n): string {\n const tpl = getReportTpl();\n if (!tpl) {\n console.warn('reportTpl is not set, will not write report');\n return '';\n }\n\n const dumpPlaceholder = '{{dump}}';\n\n // verify the template contains the placeholder\n if (!tpl.includes(dumpPlaceholder)) {\n console.warn('Template does not contain {{dump}} placeholder');\n return '';\n }\n\n // find the first placeholder position\n const placeholderIndex = tpl.indexOf(dumpPlaceholder);\n\n // split the template into two parts before and after the placeholder\n const firstPart = tpl.substring(0, placeholderIndex);\n const secondPart = tpl.substring(placeholderIndex + dumpPlaceholder.length);\n\n // if reportPath is set, it means we are in write to file mode\n const writeToFile = reportPath && !ifInBrowser;\n let resultContent = '';\n\n // helper function: decide to write to file or append to resultContent\n const appendOrWrite = (content: string): void => {\n if (writeToFile) {\n writeFileSync(reportPath!, `${content}\\n`, {\n flag: 'a',\n });\n } else {\n resultContent += `${content}\\n`;\n }\n };\n\n // if writeToFile is true, write the first part to file, otherwise set the first part to the initial value of resultContent\n if (writeToFile) {\n writeFileSync(reportPath!, firstPart, { flag: 'w' }); // use 'w' flag to overwrite the existing file\n } else {\n resultContent = firstPart;\n }\n\n // generate dump content\n // handle empty data or undefined\n if (\n (Array.isArray(dumpData) && dumpData.length === 0) ||\n typeof dumpData === 'undefined'\n ) {\n const dumpContent =\n '<script type=\"midscene_web_dump\" type=\"application/json\"></script>';\n appendOrWrite(dumpContent);\n }\n // handle string type dumpData\n else if (typeof dumpData === 'string') {\n const dumpContent =\n // biome-ignore lint/style/useTemplate: <explanation> do not use template string here, will cause bundle error\n '<script type=\"midscene_web_dump\" type=\"application/json\">\\n' +\n dumpData +\n '\\n</script>';\n appendOrWrite(dumpContent);\n }\n // handle array type dumpData\n else {\n // for array, handle each item\n for (let i = 0; i < dumpData.length; i++) {\n const { dumpString, attributes } = dumpData[i];\n const attributesArr = Object.keys(attributes || {}).map((key) => {\n return `${key}=\"${encodeURIComponent(attributes![key])}\"`;\n });\n\n const dumpContent =\n // biome-ignore lint/style/useTemplate: <explanation> do not use template string here, will cause bundle error\n '<script type=\"midscene_web_dump\" type=\"application/json\" ' +\n attributesArr.join(' ') +\n '>\\n' +\n dumpString +\n '\\n</script>';\n appendOrWrite(dumpContent);\n }\n }\n\n // add the second part\n if (writeToFile) {\n writeFileSync(reportPath!, secondPart, { flag: 'a' });\n return reportPath!;\n }\n\n resultContent += secondPart;\n return resultContent;\n}\n\nexport function writeDumpReport(\n fileName: string,\n dumpData: string | ReportDumpWithAttributes[],\n): string | null {\n if (ifInBrowser) {\n console.log('will not write report in browser');\n return null;\n }\n\n const __dirname = dirname(__filename);\n const midscenePkgInfo = getRunningPkgInfo(__dirname);\n if (!midscenePkgInfo) {\n console.warn('midscenePkgInfo not found, will not write report');\n return null;\n }\n\n const reportPath = path.join(\n getMidsceneRunSubDir('report'),\n `${fileName}.html`,\n );\n\n reportHTMLContent(dumpData, reportPath);\n\n if (process.env.MIDSCENE_DEBUG_LOG_JSON) {\n writeFileSync(\n `${reportPath}.json`,\n typeof dumpData === 'string'\n ? dumpData\n : JSON.stringify(dumpData, null, 2),\n );\n }\n\n return reportPath;\n}\n\nexport function writeLogFile(opts: {\n fileName: string;\n fileExt: string;\n fileContent: string;\n type: 'dump' | 'cache' | 'report' | 'tmp';\n generateReport?: boolean;\n}) {\n if (ifInBrowser) {\n return '/mock/report.html';\n }\n const { fileName, fileExt, fileContent, type = 'dump' } = opts;\n const targetDir = getMidsceneRunSubDir(type);\n // Ensure directory exists\n if (!logEnvReady) {\n assert(targetDir, 'logDir should be set before writing dump file');\n\n // gitIgnore in the parent directory\n const gitIgnorePath = path.join(targetDir, '../../.gitignore');\n const gitPath = path.join(targetDir, '../../.git');\n let gitIgnoreContent = '';\n\n if (existsSync(gitPath)) {\n // if the git path exists, we need to add the log folder to the git ignore file\n if (existsSync(gitIgnorePath)) {\n gitIgnoreContent = readFileSync(gitIgnorePath, 'utf-8');\n }\n\n // ignore the log folder\n if (!gitIgnoreContent.includes(`${defaultRunDirName}/`)) {\n writeFileSync(\n gitIgnorePath,\n `${gitIgnoreContent}\\n# Midscene.js dump files\\n${defaultRunDirName}/dump\\n${defaultRunDirName}/report\\n${defaultRunDirName}/tmp\\n${defaultRunDirName}/log\\n`,\n 'utf-8',\n );\n }\n }\n\n logEnvReady = true;\n }\n\n const filePath = path.join(targetDir, `${fileName}.${fileExt}`);\n\n if (type !== 'dump') {\n // do not write dump file any more\n writeFileSync(filePath, fileContent);\n }\n\n if (opts?.generateReport) {\n return writeDumpReport(fileName, fileContent);\n }\n\n return filePath;\n}\n\nexport function getTmpDir(): string | null {\n try {\n const runningPkgInfo = getRunningPkgInfo();\n if (!runningPkgInfo) {\n return null;\n }\n const { name } = runningPkgInfo;\n const tmpPath = path.join(tmpdir(), name);\n mkdirSync(tmpPath, { recursive: true });\n return tmpPath;\n } catch (e) {\n return null;\n }\n}\n\nexport function getTmpFile(fileExtWithoutDot: string): string | null {\n if (ifInBrowser) {\n return null;\n }\n const tmpDir = getTmpDir();\n const filename = `${uuid()}.${fileExtWithoutDot}`;\n return path.join(tmpDir!, filename);\n}\n\nexport function overlapped(container: Rect, target: Rect) {\n // container and the target have some part overlapped\n return (\n container.left < target.left + target.width &&\n container.left + container.width > target.left &&\n container.top < target.top + target.height &&\n container.top + container.height > target.top\n );\n}\n\nexport async function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function replacerForPageObject(key: string, value: any) {\n if (value && value.constructor?.name === 'Page') {\n return '[Page object]';\n }\n if (value && value.constructor?.name === 'Browser') {\n return '[Browser object]';\n }\n return value;\n}\n\nexport function stringifyDumpData(data: any, indents?: number) {\n return JSON.stringify(data, replacerForPageObject, indents);\n}\n\ndeclare const __VERSION__: string;\n\nexport function getVersion() {\n return __VERSION__;\n}\n\nfunction debugLog(...message: any[]) {\n const debugMode = getAIConfig(MIDSCENE_DEBUG_MODE);\n if (debugMode) {\n console.log('[Midscene]', ...message);\n }\n}\n\nlet lastReportedRepoUrl = '';\nexport function uploadTestInfoToServer({ testUrl }: { testUrl: string }) {\n let repoUrl = '';\n let userEmail = '';\n\n const extraConfig = getAIConfigInJson(MIDSCENE_OPENAI_INIT_CONFIG_JSON);\n const serverUrl = extraConfig?.REPORT_SERVER_URL;\n\n try {\n repoUrl = execSync('git config --get remote.origin.url').toString().trim();\n userEmail = execSync('git config --get user.email').toString().trim();\n } catch (error) {\n debugLog('Failed to get git info:', error);\n }\n\n // Only upload test info if:\n // 1. Server URL is configured AND\n // 2. Either:\n // - We have a repo URL that's different from last reported one (to avoid duplicate reports)\n // - OR we don't have a repo URL but have a test URL (for non-git environments)\n if (\n serverUrl &&\n ((repoUrl && repoUrl !== lastReportedRepoUrl) || (!repoUrl && testUrl))\n ) {\n debugLog('Uploading test info to server', {\n serverUrl,\n repoUrl,\n testUrl,\n userEmail,\n });\n\n fetch(serverUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n repo_url: repoUrl,\n test_url: testUrl,\n user_email: userEmail,\n }),\n })\n .then((response) => response.json())\n .then((data) => {\n debugLog('Successfully uploaded test info to server:', data);\n })\n .catch((error) =>\n debugLog('Failed to upload test info to server:', error),\n );\n lastReportedRepoUrl = repoUrl;\n }\n}\n"]}
|
package/dist/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkPSGMMDLSjs = require('./chunk-PSGMMDLS.js');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
@@ -156,7 +156,7 @@ ${_optionalChain([this, 'access', _7 => _7.latestErrorTask, 'call', _8 => _8(),
|
|
|
156
156
|
}
|
|
157
157
|
dump() {
|
|
158
158
|
const dumpData = {
|
|
159
|
-
sdkVersion:
|
|
159
|
+
sdkVersion: _chunkPSGMMDLSjs.getVersion.call(void 0, ),
|
|
160
160
|
model_name: _env.getAIConfig.call(void 0, _env.MIDSCENE_MODEL_NAME) || "",
|
|
161
161
|
logTime: Date.now(),
|
|
162
162
|
name: this.name,
|
|
@@ -194,7 +194,7 @@ function emitInsightDump(data, dumpSubscriber) {
|
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
const baseData = {
|
|
197
|
-
sdkVersion:
|
|
197
|
+
sdkVersion: _chunkPSGMMDLSjs.getVersion.call(void 0, ),
|
|
198
198
|
logTime: Date.now(),
|
|
199
199
|
model_name: _env.getAIConfig.call(void 0, _env.MIDSCENE_MODEL_NAME) || "",
|
|
200
200
|
model_description: modelDescription
|
|
@@ -455,6 +455,6 @@ var src_default = Insight;
|
|
|
455
455
|
|
|
456
456
|
|
|
457
457
|
|
|
458
|
-
exports.AiAssert = _chunkQOGJ5YDSjs.AiAssert; exports.AiLocateElement = _chunkQOGJ5YDSjs.AiLocateElement; exports.Executor = Executor; exports.Insight = Insight; exports.MIDSCENE_MODEL_NAME = _env.MIDSCENE_MODEL_NAME; exports.default = src_default; exports.describeUserPage = _chunkQOGJ5YDSjs.describeUserPage; exports.getAIConfig = _env.getAIConfig; exports.getVersion =
|
|
458
|
+
exports.AiAssert = _chunkQOGJ5YDSjs.AiAssert; exports.AiLocateElement = _chunkQOGJ5YDSjs.AiLocateElement; exports.Executor = Executor; exports.Insight = Insight; exports.MIDSCENE_MODEL_NAME = _env.MIDSCENE_MODEL_NAME; exports.default = src_default; exports.describeUserPage = _chunkQOGJ5YDSjs.describeUserPage; exports.getAIConfig = _env.getAIConfig; exports.getVersion = _chunkPSGMMDLSjs.getVersion; exports.plan = _chunkQOGJ5YDSjs.plan;
|
|
459
459
|
|
|
460
460
|
//# sourceMappingURL=index.js.map
|
package/dist/lib/utils.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ declare const groupedActionDumpFileExt = "web-dump.json";
|
|
|
6
6
|
declare function getLogDir(): string;
|
|
7
7
|
declare function setReportTpl(tpl: string): void;
|
|
8
8
|
declare function replaceStringWithFirstAppearance(str: string, target: string, replacement: string): string;
|
|
9
|
-
declare function reportHTMLContent(dumpData: string | ReportDumpWithAttributes[]): string;
|
|
9
|
+
declare function reportHTMLContent(dumpData: string | ReportDumpWithAttributes[], reportPath?: string): string;
|
|
10
10
|
declare function writeDumpReport(fileName: string, dumpData: string | ReportDumpWithAttributes[]): string | null;
|
|
11
11
|
declare function writeLogFile(opts: {
|
|
12
12
|
fileName: string;
|
package/dist/lib/utils.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
var
|
|
17
|
+
var _chunkPSGMMDLSjs = require('./chunk-PSGMMDLS.js');
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
|
|
@@ -31,4 +31,4 @@ var _chunkELJ2V35Jjs = require('./chunk-ELJ2V35J.js');
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
exports.getLogDir =
|
|
34
|
+
exports.getLogDir = _chunkPSGMMDLSjs.getLogDir; exports.getTmpDir = _chunkPSGMMDLSjs.getTmpDir; exports.getTmpFile = _chunkPSGMMDLSjs.getTmpFile; exports.getVersion = _chunkPSGMMDLSjs.getVersion; exports.groupedActionDumpFileExt = _chunkPSGMMDLSjs.groupedActionDumpFileExt; exports.overlapped = _chunkPSGMMDLSjs.overlapped; exports.replaceStringWithFirstAppearance = _chunkPSGMMDLSjs.replaceStringWithFirstAppearance; exports.replacerForPageObject = _chunkPSGMMDLSjs.replacerForPageObject; exports.reportHTMLContent = _chunkPSGMMDLSjs.reportHTMLContent; exports.setReportTpl = _chunkPSGMMDLSjs.setReportTpl; exports.sleep = _chunkPSGMMDLSjs.sleep; exports.stringifyDumpData = _chunkPSGMMDLSjs.stringifyDumpData; exports.uploadTestInfoToServer = _chunkPSGMMDLSjs.uploadTestInfoToServer; exports.writeDumpReport = _chunkPSGMMDLSjs.writeDumpReport; exports.writeLogFile = _chunkPSGMMDLSjs.writeLogFile;
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ declare const groupedActionDumpFileExt = "web-dump.json";
|
|
|
6
6
|
declare function getLogDir(): string;
|
|
7
7
|
declare function setReportTpl(tpl: string): void;
|
|
8
8
|
declare function replaceStringWithFirstAppearance(str: string, target: string, replacement: string): string;
|
|
9
|
-
declare function reportHTMLContent(dumpData: string | ReportDumpWithAttributes[]): string;
|
|
9
|
+
declare function reportHTMLContent(dumpData: string | ReportDumpWithAttributes[], reportPath?: string): string;
|
|
10
10
|
declare function writeDumpReport(fileName: string, dumpData: string | ReportDumpWithAttributes[]): string | null;
|
|
11
11
|
declare function writeLogFile(opts: {
|
|
12
12
|
fileName: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midscene/core",
|
|
3
3
|
"description": "Automate browser actions, extract data, and perform assertions using AI. It offers JavaScript SDK, Chrome extension, and support for scripting in YAML. See https://midscenejs.com/ for details.",
|
|
4
|
-
"version": "0.16.
|
|
4
|
+
"version": "0.16.4-beta-20250429033218.0",
|
|
5
5
|
"repository": "https://github.com/web-infra-dev/midscene",
|
|
6
6
|
"homepage": "https://midscenejs.com/",
|
|
7
7
|
"jsnext:source": "./src/index.ts",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"dirty-json": "0.9.2",
|
|
45
45
|
"dotenv": "16.4.5",
|
|
46
46
|
"langsmith": "0.3.7",
|
|
47
|
-
"@midscene/shared": "0.16.
|
|
47
|
+
"@midscene/shared": "0.16.4-beta-20250429033218.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@modern-js/module-tools": "2.60.6",
|