@midscene/testing-framework 0.0.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/LICENSE +21 -0
- package/README.md +47 -0
- package/dist/es/builtin-steps.mjs +30 -0
- package/dist/es/builtin-steps.mjs.map +1 -0
- package/dist/es/config.mjs +83 -0
- package/dist/es/config.mjs.map +1 -0
- package/dist/es/dotenv.mjs +50 -0
- package/dist/es/dotenv.mjs.map +1 -0
- package/dist/es/index.mjs +5 -0
- package/dist/es/runner-worker.mjs +86 -0
- package/dist/es/runner-worker.mjs.map +1 -0
- package/dist/es/runner.mjs +165 -0
- package/dist/es/runner.mjs.map +1 -0
- package/dist/es/runtime/index.mjs +86 -0
- package/dist/es/runtime/index.mjs.map +1 -0
- package/dist/es/runtime/setup.mjs +59 -0
- package/dist/es/runtime/setup.mjs.map +1 -0
- package/dist/es/runtime/source.mjs +27 -0
- package/dist/es/runtime/source.mjs.map +1 -0
- package/dist/es/runtime/yaml.mjs +88 -0
- package/dist/es/runtime/yaml.mjs.map +1 -0
- package/dist/es/types.mjs +0 -0
- package/dist/lib/builtin-steps.js +67 -0
- package/dist/lib/builtin-steps.js.map +1 -0
- package/dist/lib/config.js +126 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/dotenv.js +97 -0
- package/dist/lib/dotenv.js.map +1 -0
- package/dist/lib/index.js +65 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/runner-worker.js +92 -0
- package/dist/lib/runner-worker.js.map +1 -0
- package/dist/lib/runner.js +199 -0
- package/dist/lib/runner.js.map +1 -0
- package/dist/lib/runtime/index.js +141 -0
- package/dist/lib/runtime/index.js.map +1 -0
- package/dist/lib/runtime/setup.js +96 -0
- package/dist/lib/runtime/setup.js.map +1 -0
- package/dist/lib/runtime/source.js +61 -0
- package/dist/lib/runtime/source.js.map +1 -0
- package/dist/lib/runtime/yaml.js +138 -0
- package/dist/lib/runtime/yaml.js.map +1 -0
- package/dist/lib/types.js +20 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/types/builtin-steps.d.ts +11 -0
- package/dist/types/config.d.ts +18 -0
- package/dist/types/dotenv.d.ts +28 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/runner-worker.d.ts +1 -0
- package/dist/types/runner.d.ts +33 -0
- package/dist/types/runtime/index.d.ts +24 -0
- package/dist/types/runtime/setup.d.ts +14 -0
- package/dist/types/runtime/source.d.ts +21 -0
- package/dist/types/runtime/yaml.d.ts +30 -0
- package/dist/types/types.d.ts +105 -0
- package/package.json +76 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dotenv.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/dotenv.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport dotenv from 'dotenv';\nimport type { MidsceneFrameworkConfig } from './types';\n\nexport interface LoadedDotenvFile {\n path: string;\n loaded: boolean;\n}\n\nconst toAbsolutePath = (cwd: string, candidate: string): string =>\n resolve(cwd, candidate);\n\nconst dedupePaths = (paths: string[]): string[] => {\n const seen = new Set<string>();\n const result: string[] = [];\n for (const path of paths) {\n if (!seen.has(path)) {\n seen.add(path);\n result.push(path);\n }\n }\n return result;\n};\n\n/**\n * Resolve the ordered list of `.env` files to consider for a suite run.\n * Defaults to `[<cwd>/.env, <configDir>/.env]` so a project can keep its env\n * either next to the config or at the working directory it was invoked from.\n * Explicit `env.path` overrides the default lookup entirely.\n */\nexport function resolveDotenvCandidates(input: {\n cwd: string;\n configDir: string;\n envConfig?: MidsceneFrameworkConfig['env'];\n}): string[] {\n const { cwd, configDir, envConfig } = input;\n\n if (envConfig?.path) {\n const list = Array.isArray(envConfig.path)\n ? envConfig.path\n : [envConfig.path];\n return dedupePaths(list.map((entry) => toAbsolutePath(cwd, entry)));\n }\n\n return dedupePaths([\n toAbsolutePath(cwd, '.env'),\n toAbsolutePath(configDir, '.env'),\n ]);\n}\n\n/**\n * Load `.env` files for a suite run. Mirrors `@midscene/cli` semantics:\n * existing `process.env` values are preserved unless `override` is set, and\n * missing files are skipped silently so a project without a `.env` keeps\n * working. Returns the considered files so the caller can log what was\n * actually applied.\n */\nexport function loadFrameworkDotenv(input: {\n cwd: string;\n configDir: string;\n envConfig?: MidsceneFrameworkConfig['env'];\n}): LoadedDotenvFile[] {\n if (input.envConfig?.enabled === false) {\n return [];\n }\n\n const candidates = resolveDotenvCandidates(input);\n const override = input.envConfig?.override === true;\n const debug = input.envConfig?.debug === true;\n\n return candidates.map((path) => {\n if (!existsSync(path)) {\n return { path, loaded: false };\n }\n dotenv.config({ path, override, debug });\n return { path, loaded: true };\n });\n}\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","toAbsolutePath","cwd","candidate","resolve","dedupePaths","paths","seen","Set","result","path","resolveDotenvCandidates","input","configDir","envConfig","list","Array","entry","loadFrameworkDotenv","candidates","override","debug","existsSync","dotenv"],"mappings":";;;IACAA,oBAAoB,CAAC,GAAG,CAACC;QACxB,IAAIC,SAASD,UAAUA,OAAO,UAAU,GACvC,IAAOA,MAAM,CAAC,UAAU,GACxB,IAAOA;QACRD,oBAAoB,CAAC,CAACE,QAAQ;YAAE,GAAGA;QAAO;QAC1C,OAAOA;IACR;;;ICPAF,oBAAoB,CAAC,GAAG,CAAC,UAASG;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGH,oBAAoB,CAAC,CAACG,YAAYC,QAAQ,CAACJ,oBAAoB,CAAC,CAAC,UAASI,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAJ,oBAAoB,CAAC,GAAG,CAACM,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFP,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOQ,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;ACIA,MAAMI,iBAAiB,CAACC,KAAaC,YACnCC,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQF,KAAKC;AAEf,MAAME,cAAc,CAACC;IACnB,MAAMC,OAAO,IAAIC;IACjB,MAAMC,SAAmB,EAAE;IAC3B,KAAK,MAAMC,QAAQJ,MACjB,IAAI,CAACC,KAAK,GAAG,CAACG,OAAO;QACnBH,KAAK,GAAG,CAACG;QACTD,OAAO,IAAI,CAACC;IACd;IAEF,OAAOD;AACT;AAQO,SAASE,wBAAwBC,KAIvC;IACC,MAAM,EAAEV,GAAG,EAAEW,SAAS,EAAEC,SAAS,EAAE,GAAGF;IAEtC,IAAIE,WAAW,MAAM;QACnB,MAAMC,OAAOC,MAAM,OAAO,CAACF,UAAU,IAAI,IACrCA,UAAU,IAAI,GACd;YAACA,UAAU,IAAI;SAAC;QACpB,OAAOT,YAAYU,KAAK,GAAG,CAAC,CAACE,QAAUhB,eAAeC,KAAKe;IAC7D;IAEA,OAAOZ,YAAY;QACjBJ,eAAeC,KAAK;QACpBD,eAAeY,WAAW;KAC3B;AACH;AASO,SAASK,oBAAoBN,KAInC;IACC,IAAIA,MAAM,SAAS,EAAE,YAAY,OAC/B,OAAO,EAAE;IAGX,MAAMO,aAAaR,wBAAwBC;IAC3C,MAAMQ,WAAWR,MAAM,SAAS,EAAE,aAAa;IAC/C,MAAMS,QAAQT,MAAM,SAAS,EAAE,UAAU;IAEzC,OAAOO,WAAW,GAAG,CAAC,CAACT;QACrB,IAAI,CAACY,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWZ,OACd,OAAO;YAAEA;YAAM,QAAQ;QAAM;QAE/Ba,0BAAAA,MAAa,CAAC;YAAEb;YAAMU;YAAUC;QAAM;QACtC,OAAO;YAAEX;YAAM,QAAQ;QAAK;IAC9B;AACF"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
loadFrameworkDotenv: ()=>external_dotenv_js_namespaceObject.loadFrameworkDotenv,
|
|
28
|
+
validateMidsceneConfig: ()=>external_config_js_namespaceObject.validateMidsceneConfig,
|
|
29
|
+
defineMidsceneConfig: ()=>external_config_js_namespaceObject.defineMidsceneConfig,
|
|
30
|
+
loadMidsceneConfig: ()=>external_config_js_namespaceObject.loadMidsceneConfig,
|
|
31
|
+
resolveDotenvCandidates: ()=>external_dotenv_js_namespaceObject.resolveDotenvCandidates,
|
|
32
|
+
runMidsceneSuite: ()=>external_runner_js_namespaceObject.runMidsceneSuite,
|
|
33
|
+
isBuiltinYamlStep: ()=>external_builtin_steps_js_namespaceObject.isBuiltinYamlStep,
|
|
34
|
+
collectFrameworkTestFiles: ()=>external_config_js_namespaceObject.collectFrameworkTestFiles,
|
|
35
|
+
BUILTIN_YAML_STEP_NAMES: ()=>external_builtin_steps_js_namespaceObject.BUILTIN_YAML_STEP_NAMES
|
|
36
|
+
});
|
|
37
|
+
const external_config_js_namespaceObject = require("./config.js");
|
|
38
|
+
const external_builtin_steps_js_namespaceObject = require("./builtin-steps.js");
|
|
39
|
+
const external_dotenv_js_namespaceObject = require("./dotenv.js");
|
|
40
|
+
const external_runner_js_namespaceObject = require("./runner.js");
|
|
41
|
+
exports.BUILTIN_YAML_STEP_NAMES = __webpack_exports__.BUILTIN_YAML_STEP_NAMES;
|
|
42
|
+
exports.collectFrameworkTestFiles = __webpack_exports__.collectFrameworkTestFiles;
|
|
43
|
+
exports.defineMidsceneConfig = __webpack_exports__.defineMidsceneConfig;
|
|
44
|
+
exports.isBuiltinYamlStep = __webpack_exports__.isBuiltinYamlStep;
|
|
45
|
+
exports.loadFrameworkDotenv = __webpack_exports__.loadFrameworkDotenv;
|
|
46
|
+
exports.loadMidsceneConfig = __webpack_exports__.loadMidsceneConfig;
|
|
47
|
+
exports.resolveDotenvCandidates = __webpack_exports__.resolveDotenvCandidates;
|
|
48
|
+
exports.runMidsceneSuite = __webpack_exports__.runMidsceneSuite;
|
|
49
|
+
exports.validateMidsceneConfig = __webpack_exports__.validateMidsceneConfig;
|
|
50
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
51
|
+
"BUILTIN_YAML_STEP_NAMES",
|
|
52
|
+
"collectFrameworkTestFiles",
|
|
53
|
+
"defineMidsceneConfig",
|
|
54
|
+
"isBuiltinYamlStep",
|
|
55
|
+
"loadFrameworkDotenv",
|
|
56
|
+
"loadMidsceneConfig",
|
|
57
|
+
"resolveDotenvCandidates",
|
|
58
|
+
"runMidsceneSuite",
|
|
59
|
+
"validateMidsceneConfig"
|
|
60
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
61
|
+
Object.defineProperty(exports, '__esModule', {
|
|
62
|
+
value: true
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_exports__ = {};
|
|
3
|
+
const external_node_module_namespaceObject = require("node:module");
|
|
4
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
5
|
+
const external_node_url_namespaceObject = require("node:url");
|
|
6
|
+
const readStdin = ()=>new Promise((resolveStdin, reject)=>{
|
|
7
|
+
let data = '';
|
|
8
|
+
process.stdin.setEncoding('utf8');
|
|
9
|
+
process.stdin.on('data', (chunk)=>{
|
|
10
|
+
data += chunk;
|
|
11
|
+
});
|
|
12
|
+
process.stdin.on('end', ()=>resolveStdin(data));
|
|
13
|
+
process.stdin.on('error', reject);
|
|
14
|
+
});
|
|
15
|
+
const writeOutput = (output)=>{
|
|
16
|
+
process.stdout.write(`__MIDSCENE_RUNNER_WORKER_RESULT__${JSON.stringify(output)}\n`);
|
|
17
|
+
};
|
|
18
|
+
const main = async ()=>{
|
|
19
|
+
const raw = await readStdin();
|
|
20
|
+
const input = JSON.parse(raw);
|
|
21
|
+
const projectRequire = (0, external_node_module_namespaceObject.createRequire)((0, external_node_path_namespaceObject.resolve)(input.root, 'package.json'));
|
|
22
|
+
const rstestPkgJson = projectRequire.resolve('@rstest/core/package.json');
|
|
23
|
+
const rsbuildEntry = (0, external_node_module_namespaceObject.createRequire)(rstestPkgJson).resolve('@rsbuild/core');
|
|
24
|
+
const [{ runRstest }, { rspack }] = await Promise.all([
|
|
25
|
+
import("@rstest/core/api"),
|
|
26
|
+
import((0, external_node_url_namespaceObject.pathToFileURL)(rsbuildEntry).href)
|
|
27
|
+
]);
|
|
28
|
+
const maxConcurrency = void 0 !== input.maxConcurrency ? Math.max(1, input.maxConcurrency) : void 0;
|
|
29
|
+
const inlineConfig = {
|
|
30
|
+
root: input.root,
|
|
31
|
+
include: input.include,
|
|
32
|
+
testEnvironment: 'node',
|
|
33
|
+
reporters: [],
|
|
34
|
+
...void 0 !== input.testTimeout ? {
|
|
35
|
+
testTimeout: input.testTimeout
|
|
36
|
+
} : {},
|
|
37
|
+
...void 0 !== maxConcurrency ? {
|
|
38
|
+
maxConcurrency
|
|
39
|
+
} : {},
|
|
40
|
+
...void 0 !== maxConcurrency ? {
|
|
41
|
+
pool: {
|
|
42
|
+
maxWorkers: maxConcurrency,
|
|
43
|
+
minWorkers: maxConcurrency
|
|
44
|
+
}
|
|
45
|
+
} : {},
|
|
46
|
+
...void 0 !== input.bail ? {
|
|
47
|
+
bail: input.bail
|
|
48
|
+
} : {},
|
|
49
|
+
...void 0 !== input.retry ? {
|
|
50
|
+
retry: input.retry
|
|
51
|
+
} : {},
|
|
52
|
+
tools: {
|
|
53
|
+
rspack: (_config, { appendPlugins })=>{
|
|
54
|
+
appendPlugins(new rspack.experiments.VirtualModulesPlugin(input.virtualModules));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const result = await runRstest({
|
|
59
|
+
cwd: input.cwd,
|
|
60
|
+
inlineConfig
|
|
61
|
+
});
|
|
62
|
+
const unhandled = result?.unhandledErrors ?? [];
|
|
63
|
+
writeOutput({
|
|
64
|
+
ok: Boolean(result?.ok),
|
|
65
|
+
unhandledErrors: unhandled.map((error)=>({
|
|
66
|
+
name: error.name,
|
|
67
|
+
message: error.message,
|
|
68
|
+
stack: error.stack
|
|
69
|
+
}))
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
main().catch((error)=>{
|
|
73
|
+
const message = error instanceof Error ? error.stack || error.message : String(error);
|
|
74
|
+
process.stderr.write(`runner-worker fatal: ${message}\n`);
|
|
75
|
+
writeOutput({
|
|
76
|
+
ok: false,
|
|
77
|
+
unhandledErrors: [
|
|
78
|
+
{
|
|
79
|
+
name: error instanceof Error ? error.name : 'WorkerError',
|
|
80
|
+
message: error instanceof Error ? error.message : String(error),
|
|
81
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
});
|
|
85
|
+
process.exit(1);
|
|
86
|
+
});
|
|
87
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
88
|
+
Object.defineProperty(exports, '__esModule', {
|
|
89
|
+
value: true
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=runner-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner-worker.js","sources":["../../src/runner-worker.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\ninterface WorkerInput {\n cwd: string;\n root: string;\n include: string[];\n virtualModules: Record<string, string>;\n maxConcurrency?: number;\n testTimeout?: number;\n bail?: number;\n retry?: number;\n}\n\ninterface WorkerOutput {\n ok: boolean;\n unhandledErrors: Array<{\n name?: string;\n message?: string;\n stack?: string;\n }>;\n}\n\nconst readStdin = (): Promise<string> =>\n new Promise((resolveStdin, reject) => {\n let data = '';\n process.stdin.setEncoding('utf8');\n process.stdin.on('data', (chunk) => {\n data += chunk;\n });\n process.stdin.on('end', () => resolveStdin(data));\n process.stdin.on('error', reject);\n });\n\nconst writeOutput = (output: WorkerOutput): void => {\n process.stdout.write(\n `__MIDSCENE_RUNNER_WORKER_RESULT__${JSON.stringify(output)}\\n`,\n );\n};\n\nconst main = async (): Promise<void> => {\n const raw = await readStdin();\n const input = JSON.parse(raw) as WorkerInput;\n\n const projectRequire = createRequire(resolve(input.root, 'package.json'));\n const rstestPkgJson = projectRequire.resolve('@rstest/core/package.json');\n const rsbuildEntry = createRequire(rstestPkgJson).resolve('@rsbuild/core');\n\n const [{ runRstest }, { rspack }] = await Promise.all([\n import('@rstest/core/api'),\n import(pathToFileURL(rsbuildEntry).href),\n ]);\n\n const maxConcurrency =\n input.maxConcurrency !== undefined\n ? Math.max(1, input.maxConcurrency)\n : undefined;\n\n const inlineConfig: Record<string, unknown> = {\n root: input.root,\n include: input.include,\n testEnvironment: 'node',\n reporters: [],\n ...(input.testTimeout !== undefined\n ? { testTimeout: input.testTimeout }\n : {}),\n ...(maxConcurrency !== undefined ? { maxConcurrency } : {}),\n ...(maxConcurrency !== undefined\n ? { pool: { maxWorkers: maxConcurrency, minWorkers: maxConcurrency } }\n : {}),\n ...(input.bail !== undefined ? { bail: input.bail } : {}),\n ...(input.retry !== undefined ? { retry: input.retry } : {}),\n tools: {\n rspack: (\n _config: unknown,\n { appendPlugins }: { appendPlugins: (plugin: unknown) => void },\n ) => {\n appendPlugins(\n new rspack.experiments.VirtualModulesPlugin(input.virtualModules),\n );\n },\n },\n };\n\n const result = await runRstest({ cwd: input.cwd, inlineConfig });\n\n type UnhandledError = { name?: string; message?: string; stack?: string };\n const unhandled =\n (result as { unhandledErrors?: UnhandledError[] } | undefined)\n ?.unhandledErrors ?? [];\n\n writeOutput({\n ok: Boolean(result?.ok),\n unhandledErrors: unhandled.map((error) => ({\n name: error.name,\n message: error.message,\n stack: error.stack,\n })),\n });\n};\n\nmain().catch((error) => {\n const message =\n error instanceof Error ? error.stack || error.message : String(error);\n process.stderr.write(`runner-worker fatal: ${message}\\n`);\n writeOutput({\n ok: false,\n unhandledErrors: [\n {\n name: error instanceof Error ? error.name : 'WorkerError',\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n },\n ],\n });\n process.exit(1);\n});\n"],"names":["readStdin","Promise","resolveStdin","reject","data","process","chunk","writeOutput","output","JSON","main","raw","input","projectRequire","createRequire","resolve","rstestPkgJson","rsbuildEntry","runRstest","rspack","pathToFileURL","maxConcurrency","undefined","Math","inlineConfig","_config","appendPlugins","result","unhandled","Boolean","error","message","Error","String"],"mappings":"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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
runMidsceneSuite: ()=>runMidsceneSuite
|
|
28
|
+
});
|
|
29
|
+
const external_node_child_process_namespaceObject = require("node:child_process");
|
|
30
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
31
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
32
|
+
const external_node_url_namespaceObject = require("node:url");
|
|
33
|
+
const external_config_js_namespaceObject = require("./config.js");
|
|
34
|
+
const external_dotenv_js_namespaceObject = require("./dotenv.js");
|
|
35
|
+
const source_js_namespaceObject = require("./runtime/source.js");
|
|
36
|
+
const RUNNER_WORKER_RESULT_PREFIX = '__MIDSCENE_RUNNER_WORKER_RESULT__';
|
|
37
|
+
const SUITE_MODULE_ID = 'virtual:midscene-framework/suite.test.ts';
|
|
38
|
+
const safeStem = (relativePath, index)=>{
|
|
39
|
+
const base = relativePath.replace(/\.[^.]+$/, '').replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '');
|
|
40
|
+
return `${String(index + 1).padStart(3, '0')}-${base || 'case'}`;
|
|
41
|
+
};
|
|
42
|
+
const resolveWorkerEntry = ()=>{
|
|
43
|
+
const moduleUrl = null;
|
|
44
|
+
const here = moduleUrl ? (0, external_node_url_namespaceObject.fileURLToPath)(moduleUrl) : __filename;
|
|
45
|
+
const ext = here.endsWith('.mjs') ? '.mjs' : '.js';
|
|
46
|
+
return (0, external_node_path_namespaceObject.resolve)((0, external_node_path_namespaceObject.dirname)(here), `runner-worker${ext}`);
|
|
47
|
+
};
|
|
48
|
+
const defaultRstestRunner = async (project)=>{
|
|
49
|
+
const workerEntry = resolveWorkerEntry();
|
|
50
|
+
const input = {
|
|
51
|
+
cwd: project.root,
|
|
52
|
+
root: project.root,
|
|
53
|
+
include: project.include,
|
|
54
|
+
virtualModules: project.virtualModules,
|
|
55
|
+
maxConcurrency: project.maxConcurrency,
|
|
56
|
+
testTimeout: project.testTimeout,
|
|
57
|
+
bail: project.bail,
|
|
58
|
+
retry: project.retry
|
|
59
|
+
};
|
|
60
|
+
return await new Promise((resolveRunner, rejectRunner)=>{
|
|
61
|
+
const child = (0, external_node_child_process_namespaceObject.fork)(workerEntry, [], {
|
|
62
|
+
cwd: project.root,
|
|
63
|
+
env: process.env,
|
|
64
|
+
stdio: [
|
|
65
|
+
'pipe',
|
|
66
|
+
'pipe',
|
|
67
|
+
'inherit',
|
|
68
|
+
'ipc'
|
|
69
|
+
]
|
|
70
|
+
});
|
|
71
|
+
let stdoutBuffer = '';
|
|
72
|
+
let parsedResult;
|
|
73
|
+
child.stdout?.setEncoding('utf8');
|
|
74
|
+
child.stdout?.on('data', (chunk)=>{
|
|
75
|
+
stdoutBuffer += chunk;
|
|
76
|
+
let newlineIndex = stdoutBuffer.indexOf('\n');
|
|
77
|
+
while(-1 !== newlineIndex){
|
|
78
|
+
const line = stdoutBuffer.slice(0, newlineIndex);
|
|
79
|
+
stdoutBuffer = stdoutBuffer.slice(newlineIndex + 1);
|
|
80
|
+
if (line.startsWith(RUNNER_WORKER_RESULT_PREFIX)) try {
|
|
81
|
+
parsedResult = JSON.parse(line.slice(RUNNER_WORKER_RESULT_PREFIX.length));
|
|
82
|
+
} catch (error) {
|
|
83
|
+
rejectRunner(new Error(`Failed to parse runner-worker result: ${error instanceof Error ? error.message : String(error)}`));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
else if (line.length > 0) process.stdout.write(`${line}\n`);
|
|
87
|
+
newlineIndex = stdoutBuffer.indexOf('\n');
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
child.on('error', (error)=>{
|
|
91
|
+
rejectRunner(error);
|
|
92
|
+
});
|
|
93
|
+
child.on('exit', (code, signal)=>{
|
|
94
|
+
if (stdoutBuffer.length > 0 && !stdoutBuffer.startsWith(RUNNER_WORKER_RESULT_PREFIX)) process.stdout.write(stdoutBuffer);
|
|
95
|
+
if (!parsedResult) return void rejectRunner(new Error(`runner-worker exited (code=${code ?? 'null'}, signal=${signal ?? 'null'}) without producing a result`));
|
|
96
|
+
if (parsedResult.unhandledErrors.length > 0) for (const error of parsedResult.unhandledErrors)console.error(error.stack || `${error.name}: ${error.message}`);
|
|
97
|
+
resolveRunner({
|
|
98
|
+
ok: parsedResult.ok
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
child.stdin?.write(JSON.stringify(input));
|
|
102
|
+
child.stdin?.end();
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
const readCaseResult = (item)=>{
|
|
106
|
+
if ((0, external_node_fs_namespaceObject.existsSync)(item.resultFile)) return JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(item.resultFile, 'utf8'));
|
|
107
|
+
return {
|
|
108
|
+
file: item.filePath,
|
|
109
|
+
testName: item.testName,
|
|
110
|
+
success: false,
|
|
111
|
+
duration: 0,
|
|
112
|
+
error: 'Not executed'
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
const writeSummaryFile = (loaded, summary)=>{
|
|
116
|
+
const target = loaded.config.output?.summary;
|
|
117
|
+
if (!target) return;
|
|
118
|
+
const summaryPath = (0, external_node_path_namespaceObject.resolve)(loaded.root, target);
|
|
119
|
+
(0, external_node_fs_namespaceObject.mkdirSync)((0, external_node_path_namespaceObject.dirname)(summaryPath), {
|
|
120
|
+
recursive: true
|
|
121
|
+
});
|
|
122
|
+
(0, external_node_fs_namespaceObject.writeFileSync)(summaryPath, JSON.stringify(summary, null, 2));
|
|
123
|
+
return summaryPath;
|
|
124
|
+
};
|
|
125
|
+
const printSummary = (summary, summaryPath)=>{
|
|
126
|
+
console.log('\n📊 Midscene suite summary');
|
|
127
|
+
console.log(` Total: ${summary.total}`);
|
|
128
|
+
console.log(` Passed: ${summary.passed}`);
|
|
129
|
+
console.log(` Failed: ${summary.failed}`);
|
|
130
|
+
console.log(` Duration: ${(summary.durationMs / 1000).toFixed(2)}s`);
|
|
131
|
+
if (summaryPath) console.log(` Summary: ${summaryPath}`);
|
|
132
|
+
for (const result of summary.results)if (!result.success) console.log(` ❌ ${result.testName}: ${result.error ?? 'failed'}`);
|
|
133
|
+
};
|
|
134
|
+
async function runMidsceneSuite(options = {}) {
|
|
135
|
+
const loaded = await (0, external_config_js_namespaceObject.loadMidsceneConfig)(options.configPath);
|
|
136
|
+
const dotenvFiles = (0, external_dotenv_js_namespaceObject.loadFrameworkDotenv)({
|
|
137
|
+
cwd: process.cwd(),
|
|
138
|
+
configDir: loaded.root,
|
|
139
|
+
envConfig: loaded.config.env
|
|
140
|
+
});
|
|
141
|
+
for (const entry of dotenvFiles)if (entry.loaded) console.log(` Env file: ${entry.path}`);
|
|
142
|
+
const files = await (0, external_config_js_namespaceObject.collectFrameworkTestFiles)({
|
|
143
|
+
root: loaded.root,
|
|
144
|
+
config: loaded.config
|
|
145
|
+
});
|
|
146
|
+
if (0 === files.length) throw new Error(`No test files found in ${(0, external_node_path_namespaceObject.resolve)(loaded.root, loaded.config.testDir || './e2e')}`);
|
|
147
|
+
const outputDir = options.outputDir || (0, external_node_path_namespaceObject.join)(loaded.root, 'midscene_run', 'tmp', `framework-${Date.now()}`);
|
|
148
|
+
const resultDir = (0, external_node_path_namespaceObject.join)(outputDir, 'results');
|
|
149
|
+
(0, external_node_fs_namespaceObject.mkdirSync)(resultDir, {
|
|
150
|
+
recursive: true
|
|
151
|
+
});
|
|
152
|
+
const yamlCases = files.filter((file)=>'yaml' === file.type).map((file, index)=>({
|
|
153
|
+
filePath: file.filePath,
|
|
154
|
+
testName: file.relativePath,
|
|
155
|
+
resultFile: (0, external_node_path_namespaceObject.join)(resultDir, `${safeStem(file.relativePath, index)}.json`)
|
|
156
|
+
}));
|
|
157
|
+
const virtualModules = {};
|
|
158
|
+
const include = [];
|
|
159
|
+
if (yamlCases.length > 0) {
|
|
160
|
+
virtualModules[SUITE_MODULE_ID] = (0, source_js_namespaceObject.createYamlFrameworkSuiteSource)({
|
|
161
|
+
configPath: loaded.path,
|
|
162
|
+
projectDir: loaded.root,
|
|
163
|
+
cases: yamlCases
|
|
164
|
+
});
|
|
165
|
+
include.push(SUITE_MODULE_ID);
|
|
166
|
+
}
|
|
167
|
+
for (const file of files)if ('test' === file.type) include.push(file.filePath);
|
|
168
|
+
const runner = options.rstestRunner || defaultRstestRunner;
|
|
169
|
+
const runResult = await runner({
|
|
170
|
+
root: loaded.root,
|
|
171
|
+
include,
|
|
172
|
+
virtualModules,
|
|
173
|
+
maxConcurrency: loaded.config.testRunner?.maxConcurrency,
|
|
174
|
+
testTimeout: loaded.config.testRunner?.testTimeout,
|
|
175
|
+
bail: loaded.config.testRunner?.bail,
|
|
176
|
+
retry: loaded.config.testRunner?.retry
|
|
177
|
+
});
|
|
178
|
+
const results = yamlCases.map(readCaseResult);
|
|
179
|
+
const summary = {
|
|
180
|
+
total: results.length,
|
|
181
|
+
passed: results.filter((result)=>result.success).length,
|
|
182
|
+
failed: results.filter((result)=>!result.success).length,
|
|
183
|
+
durationMs: results.reduce((sum, result)=>sum + (result.duration || 0), 0),
|
|
184
|
+
results
|
|
185
|
+
};
|
|
186
|
+
const summaryPath = writeSummaryFile(loaded, summary);
|
|
187
|
+
printSummary(summary, summaryPath);
|
|
188
|
+
if (!runResult.ok || summary.failed > 0) process.exitCode = 1;
|
|
189
|
+
return summary;
|
|
190
|
+
}
|
|
191
|
+
exports.runMidsceneSuite = __webpack_exports__.runMidsceneSuite;
|
|
192
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
193
|
+
"runMidsceneSuite"
|
|
194
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
195
|
+
Object.defineProperty(exports, '__esModule', {
|
|
196
|
+
value: true
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/runner.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { fork } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { collectFrameworkTestFiles, loadMidsceneConfig } from './config';\nimport { loadFrameworkDotenv } from './dotenv';\nimport { createYamlFrameworkSuiteSource } from './runtime/source';\nimport type {\n FrameworkCaseResult,\n FrameworkSuiteSummary,\n LoadedMidsceneConfig,\n} from './types';\n\nconst RUNNER_WORKER_RESULT_PREFIX = '__MIDSCENE_RUNNER_WORKER_RESULT__';\n\nconst SUITE_MODULE_ID = 'virtual:midscene-framework/suite.test.ts';\n\nexport interface FrameworkRstestProject {\n root: string;\n include: string[];\n virtualModules: Record<string, string>;\n maxConcurrency?: number;\n testTimeout?: number;\n bail?: number;\n retry?: number;\n}\n\nexport type FrameworkRstestRunner = (\n project: FrameworkRstestProject,\n) => Promise<{ ok: boolean }>;\n\nexport interface RunMidsceneSuiteOptions {\n /** Path to `midscene.config.ts`. Defaults to the one in `cwd`. */\n configPath?: string;\n /** Directory for generated wiring and per-case result files. */\n outputDir?: string;\n /** Override the Rstest runner. Mainly for tests. */\n rstestRunner?: FrameworkRstestRunner;\n stdio?: 'inherit' | 'pipe';\n}\n\ninterface SuiteCase {\n filePath: string;\n testName: string;\n resultFile: string;\n}\n\nconst safeStem = (relativePath: string, index: number): string => {\n const base = relativePath\n .replace(/\\.[^.]+$/, '')\n .replace(/[^a-zA-Z0-9._-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return `${String(index + 1).padStart(3, '0')}-${base || 'case'}`;\n};\n\ninterface WorkerInput {\n cwd: string;\n root: string;\n include: string[];\n virtualModules: Record<string, string>;\n maxConcurrency?: number;\n testTimeout?: number;\n bail?: number;\n retry?: number;\n}\n\ninterface WorkerOutput {\n ok: boolean;\n unhandledErrors: Array<{\n name?: string;\n message?: string;\n stack?: string;\n }>;\n}\n\nconst resolveWorkerEntry = (): string => {\n // `runner.js` and `runner-worker.js` ship side-by-side in both the CJS and\n // ESM bundles, so resolving relative to the current module works in both\n // formats. Use `__filename` for CJS and `import.meta.url` for ESM. The ESM\n // build emits `.mjs` files; pick the matching extension.\n const moduleUrl =\n typeof __filename === 'string'\n ? null\n : (import.meta as { url?: string } | undefined)?.url;\n const here = moduleUrl ? fileURLToPath(moduleUrl) : __filename;\n const ext = here.endsWith('.mjs') ? '.mjs' : '.js';\n return resolve(dirname(here), `runner-worker${ext}`);\n};\n\n/**\n * Default Rstest driver. We deliberately spawn `runRstest` in a child process:\n * the user's `midscene.config.ts` typically imports playwright (or\n * `@midscene/web/playwright`), which transitively initializes a bundled\n * `@vitest/expect` copy and defines `Symbol.for('$$jest-matchers-object')` on\n * `globalThis` non-configurably. Calling `runRstest` in the same process then\n * fails with `TypeError: Cannot redefine property: Symbol($$jest-matchers-object)`\n * because Rstest's own `@vitest/expect` copy tries to redefine the same global.\n * Forking sidesteps the collision: the child has never imported playwright.\n */\nconst defaultRstestRunner: FrameworkRstestRunner = async (project) => {\n const workerEntry = resolveWorkerEntry();\n\n const input: WorkerInput = {\n cwd: project.root,\n root: project.root,\n include: project.include,\n virtualModules: project.virtualModules,\n maxConcurrency: project.maxConcurrency,\n testTimeout: project.testTimeout,\n bail: project.bail,\n retry: project.retry,\n };\n\n return await new Promise<{ ok: boolean }>((resolveRunner, rejectRunner) => {\n const child = fork(workerEntry, [], {\n cwd: project.root,\n env: process.env,\n stdio: ['pipe', 'pipe', 'inherit', 'ipc'],\n });\n\n let stdoutBuffer = '';\n let parsedResult: WorkerOutput | undefined;\n\n child.stdout?.setEncoding('utf8');\n child.stdout?.on('data', (chunk: string) => {\n stdoutBuffer += chunk;\n let newlineIndex = stdoutBuffer.indexOf('\\n');\n while (newlineIndex !== -1) {\n const line = stdoutBuffer.slice(0, newlineIndex);\n stdoutBuffer = stdoutBuffer.slice(newlineIndex + 1);\n if (line.startsWith(RUNNER_WORKER_RESULT_PREFIX)) {\n try {\n parsedResult = JSON.parse(\n line.slice(RUNNER_WORKER_RESULT_PREFIX.length),\n ) as WorkerOutput;\n } catch (error) {\n rejectRunner(\n new Error(\n `Failed to parse runner-worker result: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ),\n );\n return;\n }\n } else if (line.length > 0) {\n process.stdout.write(`${line}\\n`);\n }\n newlineIndex = stdoutBuffer.indexOf('\\n');\n }\n });\n\n child.on('error', (error) => {\n rejectRunner(error);\n });\n\n child.on('exit', (code, signal) => {\n if (\n stdoutBuffer.length > 0 &&\n !stdoutBuffer.startsWith(RUNNER_WORKER_RESULT_PREFIX)\n ) {\n process.stdout.write(stdoutBuffer);\n }\n\n if (!parsedResult) {\n rejectRunner(\n new Error(\n `runner-worker exited (code=${code ?? 'null'}, signal=${\n signal ?? 'null'\n }) without producing a result`,\n ),\n );\n return;\n }\n\n if (parsedResult.unhandledErrors.length > 0) {\n for (const error of parsedResult.unhandledErrors) {\n console.error(error.stack || `${error.name}: ${error.message}`);\n }\n }\n\n resolveRunner({ ok: parsedResult.ok });\n });\n\n child.stdin?.write(JSON.stringify(input));\n child.stdin?.end();\n });\n};\n\nconst readCaseResult = (item: SuiteCase): FrameworkCaseResult => {\n if (existsSync(item.resultFile)) {\n return JSON.parse(\n readFileSync(item.resultFile, 'utf8'),\n ) as FrameworkCaseResult;\n }\n\n return {\n file: item.filePath,\n testName: item.testName,\n success: false,\n duration: 0,\n error: 'Not executed',\n };\n};\n\nconst writeSummaryFile = (\n loaded: LoadedMidsceneConfig,\n summary: FrameworkSuiteSummary,\n): string | undefined => {\n const target = loaded.config.output?.summary;\n if (!target) {\n return undefined;\n }\n const summaryPath = resolve(loaded.root, target);\n mkdirSync(dirname(summaryPath), { recursive: true });\n writeFileSync(summaryPath, JSON.stringify(summary, null, 2));\n return summaryPath;\n};\n\nconst printSummary = (summary: FrameworkSuiteSummary, summaryPath?: string) => {\n console.log('\\n📊 Midscene suite summary');\n console.log(` Total: ${summary.total}`);\n console.log(` Passed: ${summary.passed}`);\n console.log(` Failed: ${summary.failed}`);\n console.log(` Duration: ${(summary.durationMs / 1000).toFixed(2)}s`);\n if (summaryPath) {\n console.log(` Summary: ${summaryPath}`);\n }\n for (const result of summary.results) {\n if (!result.success) {\n console.log(` ❌ ${result.testName}: ${result.error ?? 'failed'}`);\n }\n }\n};\n\n/**\n * Load `midscene.config.ts`, discover cases, run them through Rstest, and write\n * the suite summary. Intended to be the entire body of a project's\n * `run-suite.ts`:\n *\n * ```ts\n * import { runMidsceneSuite } from '@midscene/testing-framework';\n * await runMidsceneSuite();\n * ```\n */\nexport async function runMidsceneSuite(\n options: RunMidsceneSuiteOptions = {},\n): Promise<FrameworkSuiteSummary> {\n const loaded = await loadMidsceneConfig(options.configPath);\n\n const dotenvFiles = loadFrameworkDotenv({\n cwd: process.cwd(),\n configDir: loaded.root,\n envConfig: loaded.config.env,\n });\n for (const entry of dotenvFiles) {\n if (entry.loaded) {\n console.log(` Env file: ${entry.path}`);\n }\n }\n\n const files = await collectFrameworkTestFiles({\n root: loaded.root,\n config: loaded.config,\n });\n\n if (files.length === 0) {\n throw new Error(\n `No test files found in ${resolve(loaded.root, loaded.config.testDir || './e2e')}`,\n );\n }\n\n const outputDir =\n options.outputDir ||\n join(loaded.root, 'midscene_run', 'tmp', `framework-${Date.now()}`);\n const resultDir = join(outputDir, 'results');\n mkdirSync(resultDir, { recursive: true });\n\n const yamlCases: SuiteCase[] = files\n .filter((file) => file.type === 'yaml')\n .map((file, index) => ({\n filePath: file.filePath,\n testName: file.relativePath,\n resultFile: join(resultDir, `${safeStem(file.relativePath, index)}.json`),\n }));\n\n const virtualModules: Record<string, string> = {};\n const include: string[] = [];\n\n if (yamlCases.length > 0) {\n virtualModules[SUITE_MODULE_ID] = createYamlFrameworkSuiteSource({\n configPath: loaded.path,\n projectDir: loaded.root,\n cases: yamlCases,\n });\n include.push(SUITE_MODULE_ID);\n }\n\n for (const file of files) {\n if (file.type === 'test') {\n include.push(file.filePath);\n }\n }\n\n const runner = options.rstestRunner || defaultRstestRunner;\n const runResult = await runner({\n root: loaded.root,\n include,\n virtualModules,\n maxConcurrency: loaded.config.testRunner?.maxConcurrency,\n testTimeout: loaded.config.testRunner?.testTimeout,\n bail: loaded.config.testRunner?.bail,\n retry: loaded.config.testRunner?.retry,\n });\n\n const results = yamlCases.map(readCaseResult);\n const summary: FrameworkSuiteSummary = {\n total: results.length,\n passed: results.filter((result) => result.success).length,\n failed: results.filter((result) => !result.success).length,\n durationMs: results.reduce(\n (sum, result) => sum + (result.duration || 0),\n 0,\n ),\n results,\n };\n\n const summaryPath = writeSummaryFile(loaded, summary);\n printSummary(summary, summaryPath);\n\n if (!runResult.ok || summary.failed > 0) {\n process.exitCode = 1;\n }\n\n return summary;\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","RUNNER_WORKER_RESULT_PREFIX","SUITE_MODULE_ID","safeStem","relativePath","index","base","String","resolveWorkerEntry","moduleUrl","here","fileURLToPath","__filename","ext","resolve","dirname","defaultRstestRunner","project","workerEntry","input","Promise","resolveRunner","rejectRunner","child","fork","process","stdoutBuffer","parsedResult","chunk","newlineIndex","line","JSON","error","Error","code","signal","console","readCaseResult","item","existsSync","readFileSync","writeSummaryFile","loaded","summary","target","summaryPath","mkdirSync","writeFileSync","printSummary","result","runMidsceneSuite","options","loadMidsceneConfig","dotenvFiles","loadFrameworkDotenv","entry","files","collectFrameworkTestFiles","outputDir","join","Date","resultDir","yamlCases","file","virtualModules","include","createYamlFrameworkSuiteSource","runner","runResult","results","sum"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;;;ACOA,MAAMI,8BAA8B;AAEpC,MAAMC,kBAAkB;AAgCxB,MAAMC,WAAW,CAACC,cAAsBC;IACtC,MAAMC,OAAOF,aACV,OAAO,CAAC,YAAY,IACpB,OAAO,CAAC,qBAAqB,KAC7B,OAAO,CAAC,YAAY;IACvB,OAAO,GAAGG,OAAOF,QAAQ,GAAG,QAAQ,CAAC,GAAG,KAAK,CAAC,EAAEC,QAAQ,QAAQ;AAClE;AAsBA,MAAME,qBAAqB;IAKzB,MAAMC,YAEA;IAEN,MAAMC,OAAOD,YAAYE,AAAAA,IAAAA,kCAAAA,aAAAA,AAAAA,EAAcF,aAAaG;IACpD,MAAMC,MAAMH,KAAK,QAAQ,CAAC,UAAU,SAAS;IAC7C,OAAOI,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQC,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQL,OAAO,CAAC,aAAa,EAAEG,KAAK;AACrD;AAYA,MAAMG,sBAA6C,OAAOC;IACxD,MAAMC,cAAcV;IAEpB,MAAMW,QAAqB;QACzB,KAAKF,QAAQ,IAAI;QACjB,MAAMA,QAAQ,IAAI;QAClB,SAASA,QAAQ,OAAO;QACxB,gBAAgBA,QAAQ,cAAc;QACtC,gBAAgBA,QAAQ,cAAc;QACtC,aAAaA,QAAQ,WAAW;QAChC,MAAMA,QAAQ,IAAI;QAClB,OAAOA,QAAQ,KAAK;IACtB;IAEA,OAAO,MAAM,IAAIG,QAAyB,CAACC,eAAeC;QACxD,MAAMC,QAAQC,AAAAA,IAAAA,4CAAAA,IAAAA,AAAAA,EAAKN,aAAa,EAAE,EAAE;YAClC,KAAKD,QAAQ,IAAI;YACjB,KAAKQ,QAAQ,GAAG;YAChB,OAAO;gBAAC;gBAAQ;gBAAQ;gBAAW;aAAM;QAC3C;QAEA,IAAIC,eAAe;QACnB,IAAIC;QAEJJ,MAAM,MAAM,EAAE,YAAY;QAC1BA,MAAM,MAAM,EAAE,GAAG,QAAQ,CAACK;YACxBF,gBAAgBE;YAChB,IAAIC,eAAeH,aAAa,OAAO,CAAC;YACxC,MAAOG,AAAiB,OAAjBA,aAAqB;gBAC1B,MAAMC,OAAOJ,aAAa,KAAK,CAAC,GAAGG;gBACnCH,eAAeA,aAAa,KAAK,CAACG,eAAe;gBACjD,IAAIC,KAAK,UAAU,CAAC7B,8BAClB,IAAI;oBACF0B,eAAeI,KAAK,KAAK,CACvBD,KAAK,KAAK,CAAC7B,4BAA4B,MAAM;gBAEjD,EAAE,OAAO+B,OAAO;oBACdV,aACE,IAAIW,MACF,CAAC,sCAAsC,EACrCD,iBAAiBC,QAAQD,MAAM,OAAO,GAAGzB,OAAOyB,QAChD;oBAGN;gBACF;qBACK,IAAIF,KAAK,MAAM,GAAG,GACvBL,QAAQ,MAAM,CAAC,KAAK,CAAC,GAAGK,KAAK,EAAE,CAAC;gBAElCD,eAAeH,aAAa,OAAO,CAAC;YACtC;QACF;QAEAH,MAAM,EAAE,CAAC,SAAS,CAACS;YACjBV,aAAaU;QACf;QAEAT,MAAM,EAAE,CAAC,QAAQ,CAACW,MAAMC;YACtB,IACET,aAAa,MAAM,GAAG,KACtB,CAACA,aAAa,UAAU,CAACzB,8BAEzBwB,QAAQ,MAAM,CAAC,KAAK,CAACC;YAGvB,IAAI,CAACC,cAAc,YACjBL,aACE,IAAIW,MACF,CAAC,2BAA2B,EAAEC,QAAQ,OAAO,SAAS,EACpDC,UAAU,OACX,4BAA4B,CAAC;YAMpC,IAAIR,aAAa,eAAe,CAAC,MAAM,GAAG,GACxC,KAAK,MAAMK,SAASL,aAAa,eAAe,CAC9CS,QAAQ,KAAK,CAACJ,MAAM,KAAK,IAAI,GAAGA,MAAM,IAAI,CAAC,EAAE,EAAEA,MAAM,OAAO,EAAE;YAIlEX,cAAc;gBAAE,IAAIM,aAAa,EAAE;YAAC;QACtC;QAEAJ,MAAM,KAAK,EAAE,MAAMQ,KAAK,SAAS,CAACZ;QAClCI,MAAM,KAAK,EAAE;IACf;AACF;AAEA,MAAMc,iBAAiB,CAACC;IACtB,IAAIC,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWD,KAAK,UAAU,GAC5B,OAAOP,KAAK,KAAK,CACfS,AAAAA,IAAAA,iCAAAA,YAAAA,AAAAA,EAAaF,KAAK,UAAU,EAAE;IAIlC,OAAO;QACL,MAAMA,KAAK,QAAQ;QACnB,UAAUA,KAAK,QAAQ;QACvB,SAAS;QACT,UAAU;QACV,OAAO;IACT;AACF;AAEA,MAAMG,mBAAmB,CACvBC,QACAC;IAEA,MAAMC,SAASF,OAAO,MAAM,CAAC,MAAM,EAAE;IACrC,IAAI,CAACE,QACH;IAEF,MAAMC,cAAc/B,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQ4B,OAAO,IAAI,EAAEE;IACzCE,IAAAA,iCAAAA,SAAAA,AAAAA,EAAU/B,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQ8B,cAAc;QAAE,WAAW;IAAK;IAClDE,IAAAA,iCAAAA,aAAAA,AAAAA,EAAcF,aAAad,KAAK,SAAS,CAACY,SAAS,MAAM;IACzD,OAAOE;AACT;AAEA,MAAMG,eAAe,CAACL,SAAgCE;IACpDT,QAAQ,GAAG,CAAC;IACZA,QAAQ,GAAG,CAAC,CAAC,UAAU,EAAEO,QAAQ,KAAK,EAAE;IACxCP,QAAQ,GAAG,CAAC,CAAC,WAAW,EAAEO,QAAQ,MAAM,EAAE;IAC1CP,QAAQ,GAAG,CAAC,CAAC,WAAW,EAAEO,QAAQ,MAAM,EAAE;IAC1CP,QAAQ,GAAG,CAAC,CAAC,aAAa,EAAGO,AAAAA,CAAAA,QAAQ,UAAU,GAAG,IAAG,EAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACrE,IAAIE,aACFT,QAAQ,GAAG,CAAC,CAAC,YAAY,EAAES,aAAa;IAE1C,KAAK,MAAMI,UAAUN,QAAQ,OAAO,CAClC,IAAI,CAACM,OAAO,OAAO,EACjBb,QAAQ,GAAG,CAAC,CAAC,KAAK,EAAEa,OAAO,QAAQ,CAAC,EAAE,EAAEA,OAAO,KAAK,IAAI,UAAU;AAGxE;AAYO,eAAeC,iBACpBC,UAAmC,CAAC,CAAC;IAErC,MAAMT,SAAS,MAAMU,AAAAA,IAAAA,mCAAAA,kBAAAA,AAAAA,EAAmBD,QAAQ,UAAU;IAE1D,MAAME,cAAcC,AAAAA,IAAAA,mCAAAA,mBAAAA,AAAAA,EAAoB;QACtC,KAAK7B,QAAQ,GAAG;QAChB,WAAWiB,OAAO,IAAI;QACtB,WAAWA,OAAO,MAAM,CAAC,GAAG;IAC9B;IACA,KAAK,MAAMa,SAASF,YAClB,IAAIE,MAAM,MAAM,EACdnB,QAAQ,GAAG,CAAC,CAAC,aAAa,EAAEmB,MAAM,IAAI,EAAE;IAI5C,MAAMC,QAAQ,MAAMC,AAAAA,IAAAA,mCAAAA,yBAAAA,AAAAA,EAA0B;QAC5C,MAAMf,OAAO,IAAI;QACjB,QAAQA,OAAO,MAAM;IACvB;IAEA,IAAIc,AAAiB,MAAjBA,MAAM,MAAM,EACd,MAAM,IAAIvB,MACR,CAAC,uBAAuB,EAAEnB,AAAAA,IAAAA,mCAAAA,OAAAA,AAAAA,EAAQ4B,OAAO,IAAI,EAAEA,OAAO,MAAM,CAAC,OAAO,IAAI,UAAU;IAItF,MAAMgB,YACJP,QAAQ,SAAS,IACjBQ,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAKjB,OAAO,IAAI,EAAE,gBAAgB,OAAO,CAAC,UAAU,EAAEkB,KAAK,GAAG,IAAI;IACpE,MAAMC,YAAYF,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAKD,WAAW;IAClCZ,IAAAA,iCAAAA,SAAAA,AAAAA,EAAUe,WAAW;QAAE,WAAW;IAAK;IAEvC,MAAMC,YAAyBN,MAC5B,MAAM,CAAC,CAACO,OAASA,AAAc,WAAdA,KAAK,IAAI,EAC1B,GAAG,CAAC,CAACA,MAAM1D,QAAW;YACrB,UAAU0D,KAAK,QAAQ;YACvB,UAAUA,KAAK,YAAY;YAC3B,YAAYJ,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAKE,WAAW,GAAG1D,SAAS4D,KAAK,YAAY,EAAE1D,OAAO,KAAK,CAAC;QAC1E;IAEF,MAAM2D,iBAAyC,CAAC;IAChD,MAAMC,UAAoB,EAAE;IAE5B,IAAIH,UAAU,MAAM,GAAG,GAAG;QACxBE,cAAc,CAAC9D,gBAAgB,GAAGgE,AAAAA,IAAAA,0BAAAA,8BAAAA,AAAAA,EAA+B;YAC/D,YAAYxB,OAAO,IAAI;YACvB,YAAYA,OAAO,IAAI;YACvB,OAAOoB;QACT;QACAG,QAAQ,IAAI,CAAC/D;IACf;IAEA,KAAK,MAAM6D,QAAQP,MACjB,IAAIO,AAAc,WAAdA,KAAK,IAAI,EACXE,QAAQ,IAAI,CAACF,KAAK,QAAQ;IAI9B,MAAMI,SAAShB,QAAQ,YAAY,IAAInC;IACvC,MAAMoD,YAAY,MAAMD,OAAO;QAC7B,MAAMzB,OAAO,IAAI;QACjBuB;QACAD;QACA,gBAAgBtB,OAAO,MAAM,CAAC,UAAU,EAAE;QAC1C,aAAaA,OAAO,MAAM,CAAC,UAAU,EAAE;QACvC,MAAMA,OAAO,MAAM,CAAC,UAAU,EAAE;QAChC,OAAOA,OAAO,MAAM,CAAC,UAAU,EAAE;IACnC;IAEA,MAAM2B,UAAUP,UAAU,GAAG,CAACzB;IAC9B,MAAMM,UAAiC;QACrC,OAAO0B,QAAQ,MAAM;QACrB,QAAQA,QAAQ,MAAM,CAAC,CAACpB,SAAWA,OAAO,OAAO,EAAE,MAAM;QACzD,QAAQoB,QAAQ,MAAM,CAAC,CAACpB,SAAW,CAACA,OAAO,OAAO,EAAE,MAAM;QAC1D,YAAYoB,QAAQ,MAAM,CACxB,CAACC,KAAKrB,SAAWqB,MAAOrB,CAAAA,OAAO,QAAQ,IAAI,IAC3C;QAEFoB;IACF;IAEA,MAAMxB,cAAcJ,iBAAiBC,QAAQC;IAC7CK,aAAaL,SAASE;IAEtB,IAAI,CAACuB,UAAU,EAAE,IAAIzB,QAAQ,MAAM,GAAG,GACpClB,QAAQ,QAAQ,GAAG;IAGrB,OAAOkB;AACT"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
createDefaultSetup: ()=>external_setup_js_namespaceObject.createDefaultSetup,
|
|
28
|
+
setupFrameworkAgent: ()=>external_setup_js_namespaceObject.setupFrameworkAgent,
|
|
29
|
+
createSuiteRuntime: ()=>createSuiteRuntime,
|
|
30
|
+
createYamlFrameworkSuiteSource: ()=>external_source_js_namespaceObject.createYamlFrameworkSuiteSource,
|
|
31
|
+
FrameworkSuiteRuntime: ()=>FrameworkSuiteRuntime,
|
|
32
|
+
runBuiltinYamlCase: ()=>external_yaml_js_namespaceObject.runBuiltinYamlCase,
|
|
33
|
+
normalizeYamlCase: ()=>external_yaml_js_namespaceObject.normalizeYamlCase,
|
|
34
|
+
runYamlFlowWithCustomSteps: ()=>external_yaml_js_namespaceObject.runYamlFlowWithCustomSteps
|
|
35
|
+
});
|
|
36
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
37
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
38
|
+
const external_setup_js_namespaceObject = require("./setup.js");
|
|
39
|
+
const external_yaml_js_namespaceObject = require("./yaml.js");
|
|
40
|
+
const external_source_js_namespaceObject = require("./source.js");
|
|
41
|
+
function _define_property(obj, key, value) {
|
|
42
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
43
|
+
value: value,
|
|
44
|
+
enumerable: true,
|
|
45
|
+
configurable: true,
|
|
46
|
+
writable: true
|
|
47
|
+
});
|
|
48
|
+
else obj[key] = value;
|
|
49
|
+
return obj;
|
|
50
|
+
}
|
|
51
|
+
const errorMessageOf = (error)=>error instanceof Error ? error.message : String(error);
|
|
52
|
+
const writeResultFile = (resultFile, result)=>{
|
|
53
|
+
(0, external_node_fs_namespaceObject.mkdirSync)((0, external_node_path_namespaceObject.dirname)(resultFile), {
|
|
54
|
+
recursive: true
|
|
55
|
+
});
|
|
56
|
+
(0, external_node_fs_namespaceObject.writeFileSync)(resultFile, JSON.stringify(result, null, 2));
|
|
57
|
+
};
|
|
58
|
+
class FrameworkSuiteRuntime {
|
|
59
|
+
async setup() {
|
|
60
|
+
this.setupResult = await (0, external_setup_js_namespaceObject.setupFrameworkAgent)(this.config, {
|
|
61
|
+
projectDir: this.projectDir,
|
|
62
|
+
agentOptions: this.config.agentOptions || {}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async teardown() {
|
|
66
|
+
await this.setupResult?.teardown?.();
|
|
67
|
+
this.setupResult = void 0;
|
|
68
|
+
}
|
|
69
|
+
async runCase(filePath, resultFile) {
|
|
70
|
+
if (!this.setupResult) throw new Error('Suite agent is not ready; setup() must run first');
|
|
71
|
+
const agent = this.setupResult.agent;
|
|
72
|
+
const startTime = Date.now();
|
|
73
|
+
const testName = (0, external_node_path_namespaceObject.relative)(this.projectDir, filePath) || filePath;
|
|
74
|
+
const normalizedCase = (0, external_yaml_js_namespaceObject.normalizeYamlCase)((0, external_node_fs_namespaceObject.readFileSync)(filePath, 'utf8'), filePath);
|
|
75
|
+
try {
|
|
76
|
+
if (this.config.yamlSteps) await (0, external_yaml_js_namespaceObject.runYamlFlowWithCustomSteps)({
|
|
77
|
+
agent,
|
|
78
|
+
filePath,
|
|
79
|
+
caseName: normalizedCase.name,
|
|
80
|
+
flow: normalizedCase.flow,
|
|
81
|
+
yamlSteps: this.config.yamlSteps,
|
|
82
|
+
state: this.state
|
|
83
|
+
});
|
|
84
|
+
else await (0, external_yaml_js_namespaceObject.runBuiltinYamlCase)({
|
|
85
|
+
agent,
|
|
86
|
+
normalizedCase
|
|
87
|
+
});
|
|
88
|
+
if (resultFile) writeResultFile(resultFile, {
|
|
89
|
+
file: filePath,
|
|
90
|
+
testName,
|
|
91
|
+
success: true,
|
|
92
|
+
duration: Date.now() - startTime,
|
|
93
|
+
report: 'string' == typeof agent.reportFile ? agent.reportFile : void 0
|
|
94
|
+
});
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (resultFile) writeResultFile(resultFile, {
|
|
97
|
+
file: filePath,
|
|
98
|
+
testName,
|
|
99
|
+
success: false,
|
|
100
|
+
duration: Date.now() - startTime,
|
|
101
|
+
error: errorMessageOf(error),
|
|
102
|
+
report: 'string' == typeof agent.reportFile ? agent.reportFile : void 0
|
|
103
|
+
});
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
constructor(options){
|
|
108
|
+
_define_property(this, "config", void 0);
|
|
109
|
+
_define_property(this, "projectDir", void 0);
|
|
110
|
+
_define_property(this, "state", {});
|
|
111
|
+
_define_property(this, "setupResult", void 0);
|
|
112
|
+
this.config = options.config;
|
|
113
|
+
this.projectDir = options.projectDir;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function createSuiteRuntime(options) {
|
|
117
|
+
return new FrameworkSuiteRuntime(options);
|
|
118
|
+
}
|
|
119
|
+
exports.FrameworkSuiteRuntime = __webpack_exports__.FrameworkSuiteRuntime;
|
|
120
|
+
exports.createDefaultSetup = __webpack_exports__.createDefaultSetup;
|
|
121
|
+
exports.createSuiteRuntime = __webpack_exports__.createSuiteRuntime;
|
|
122
|
+
exports.createYamlFrameworkSuiteSource = __webpack_exports__.createYamlFrameworkSuiteSource;
|
|
123
|
+
exports.normalizeYamlCase = __webpack_exports__.normalizeYamlCase;
|
|
124
|
+
exports.runBuiltinYamlCase = __webpack_exports__.runBuiltinYamlCase;
|
|
125
|
+
exports.runYamlFlowWithCustomSteps = __webpack_exports__.runYamlFlowWithCustomSteps;
|
|
126
|
+
exports.setupFrameworkAgent = __webpack_exports__.setupFrameworkAgent;
|
|
127
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
128
|
+
"FrameworkSuiteRuntime",
|
|
129
|
+
"createDefaultSetup",
|
|
130
|
+
"createSuiteRuntime",
|
|
131
|
+
"createYamlFrameworkSuiteSource",
|
|
132
|
+
"normalizeYamlCase",
|
|
133
|
+
"runBuiltinYamlCase",
|
|
134
|
+
"runYamlFlowWithCustomSteps",
|
|
135
|
+
"setupFrameworkAgent"
|
|
136
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
137
|
+
Object.defineProperty(exports, '__esModule', {
|
|
138
|
+
value: true
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime/index.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/runtime/index.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, relative } from 'node:path';\nimport type {\n FrameworkCaseResult,\n FrameworkSetupResult,\n MidsceneFrameworkConfig,\n} from '../types';\nimport { setupFrameworkAgent } from './setup';\nimport {\n normalizeYamlCase,\n runBuiltinYamlCase,\n runYamlFlowWithCustomSteps,\n} from './yaml';\n\nexport { createYamlFrameworkSuiteSource } from './source';\nexport {\n normalizeYamlCase,\n runBuiltinYamlCase,\n runYamlFlowWithCustomSteps,\n} from './yaml';\nexport { createDefaultSetup, setupFrameworkAgent } from './setup';\n\nexport interface SuiteRuntimeOptions {\n config: MidsceneFrameworkConfig;\n projectDir: string;\n}\n\nconst errorMessageOf = (error: unknown): string =>\n error instanceof Error ? error.message : String(error);\n\nconst writeResultFile = (resultFile: string, result: FrameworkCaseResult) => {\n mkdirSync(dirname(resultFile), { recursive: true });\n writeFileSync(resultFile, JSON.stringify(result, null, 2));\n};\n\n/**\n * Suite-level runtime shared by every generated case in a single Rstest module.\n * The agent and `state` are created once (`beforeAll`) and torn down once\n * (`afterAll`), so seeded data and cross-step state stay shared across cases.\n */\nexport class FrameworkSuiteRuntime {\n private readonly config: MidsceneFrameworkConfig;\n private readonly projectDir: string;\n private readonly state: Record<string, unknown> = {};\n private setupResult?: FrameworkSetupResult;\n\n constructor(options: SuiteRuntimeOptions) {\n this.config = options.config;\n this.projectDir = options.projectDir;\n }\n\n async setup(): Promise<void> {\n this.setupResult = await setupFrameworkAgent(this.config, {\n projectDir: this.projectDir,\n agentOptions: this.config.agentOptions || {},\n });\n }\n\n async teardown(): Promise<void> {\n await this.setupResult?.teardown?.();\n this.setupResult = undefined;\n }\n\n async runCase(filePath: string, resultFile?: string): Promise<void> {\n if (!this.setupResult) {\n throw new Error('Suite agent is not ready; setup() must run first');\n }\n\n const agent = this.setupResult.agent;\n const startTime = Date.now();\n const testName = relative(this.projectDir, filePath) || filePath;\n const normalizedCase = normalizeYamlCase(\n readFileSync(filePath, 'utf8'),\n filePath,\n );\n\n try {\n if (this.config.yamlSteps) {\n await runYamlFlowWithCustomSteps({\n agent,\n filePath,\n caseName: normalizedCase.name,\n flow: normalizedCase.flow,\n yamlSteps: this.config.yamlSteps,\n state: this.state,\n });\n } else {\n await runBuiltinYamlCase({ agent, normalizedCase });\n }\n\n if (resultFile) {\n writeResultFile(resultFile, {\n file: filePath,\n testName,\n success: true,\n duration: Date.now() - startTime,\n report:\n typeof agent.reportFile === 'string' ? agent.reportFile : undefined,\n });\n }\n } catch (error) {\n if (resultFile) {\n writeResultFile(resultFile, {\n file: filePath,\n testName,\n success: false,\n duration: Date.now() - startTime,\n error: errorMessageOf(error),\n report:\n typeof agent.reportFile === 'string' ? agent.reportFile : undefined,\n });\n }\n throw error;\n }\n }\n}\n\nexport function createSuiteRuntime(\n options: SuiteRuntimeOptions,\n): FrameworkSuiteRuntime {\n return new FrameworkSuiteRuntime(options);\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","errorMessageOf","error","Error","String","writeResultFile","resultFile","result","mkdirSync","dirname","writeFileSync","JSON","FrameworkSuiteRuntime","setupFrameworkAgent","undefined","filePath","agent","startTime","Date","testName","relative","normalizedCase","normalizeYamlCase","readFileSync","runYamlFlowWithCustomSteps","runBuiltinYamlCase","options","createSuiteRuntime"],"mappings":"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"}
|