@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,96 @@
|
|
|
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: ()=>createDefaultSetup,
|
|
28
|
+
setupFrameworkAgent: ()=>setupFrameworkAgent
|
|
29
|
+
});
|
|
30
|
+
async function createAndroidSetup(config, context) {
|
|
31
|
+
const { agentFromAdbDevice } = await import("@midscene/android");
|
|
32
|
+
const options = config.target?.options || {};
|
|
33
|
+
const { deviceId, launch, ...deviceOptions } = options;
|
|
34
|
+
const agent = await agentFromAdbDevice('string' == typeof deviceId ? deviceId : void 0, {
|
|
35
|
+
...context.agentOptions,
|
|
36
|
+
...deviceOptions
|
|
37
|
+
});
|
|
38
|
+
if ('string' == typeof launch && launch) await agent.launch(launch);
|
|
39
|
+
return {
|
|
40
|
+
agent,
|
|
41
|
+
async teardown () {
|
|
42
|
+
if ('string' == typeof launch && launch && !launch.startsWith('http')) await agent.terminate(launch);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async function createWebSetup(config, context) {
|
|
47
|
+
const [{ PlaywrightAgent }, { chromium }] = await Promise.all([
|
|
48
|
+
import("@midscene/web/playwright"),
|
|
49
|
+
import("playwright")
|
|
50
|
+
]);
|
|
51
|
+
const options = config.target?.options || {};
|
|
52
|
+
if (!options.url) throw new Error('target.options.url is required for the web target');
|
|
53
|
+
const browser = await chromium.launch({
|
|
54
|
+
headless: options.headless ?? true,
|
|
55
|
+
args: [
|
|
56
|
+
'--no-sandbox',
|
|
57
|
+
'--disable-setuid-sandbox'
|
|
58
|
+
]
|
|
59
|
+
});
|
|
60
|
+
const browserContext = await browser.newContext({
|
|
61
|
+
viewport: options.viewport
|
|
62
|
+
});
|
|
63
|
+
const page = await browserContext.newPage();
|
|
64
|
+
await page.goto(options.url);
|
|
65
|
+
return {
|
|
66
|
+
agent: new PlaywrightAgent(page, context.agentOptions),
|
|
67
|
+
browser,
|
|
68
|
+
context: browserContext,
|
|
69
|
+
page,
|
|
70
|
+
async teardown () {
|
|
71
|
+
await browserContext.close();
|
|
72
|
+
await browser.close();
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async function createDefaultSetup(config, context) {
|
|
77
|
+
if (!config.target) throw new Error('midscene config must provide "target" or "setup"');
|
|
78
|
+
if ('android' === config.target.type) return createAndroidSetup(config, context);
|
|
79
|
+
if ('web' === config.target.type) return createWebSetup(config, context);
|
|
80
|
+
throw new Error(`Unsupported target.type: ${config.target.type}`);
|
|
81
|
+
}
|
|
82
|
+
async function setupFrameworkAgent(config, context) {
|
|
83
|
+
if (config.setup) return config.setup(context);
|
|
84
|
+
return createDefaultSetup(config, context);
|
|
85
|
+
}
|
|
86
|
+
exports.createDefaultSetup = __webpack_exports__.createDefaultSetup;
|
|
87
|
+
exports.setupFrameworkAgent = __webpack_exports__.setupFrameworkAgent;
|
|
88
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
89
|
+
"createDefaultSetup",
|
|
90
|
+
"setupFrameworkAgent"
|
|
91
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
92
|
+
Object.defineProperty(exports, '__esModule', {
|
|
93
|
+
value: true
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime/setup.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/runtime/setup.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 type {\n FrameworkSetupResult,\n MidsceneFrameworkConfig,\n SetupContext,\n} from '../types';\n\ninterface DefaultSetupContext extends SetupContext {}\n\nasync function createAndroidSetup(\n config: MidsceneFrameworkConfig,\n context: DefaultSetupContext,\n): Promise<FrameworkSetupResult> {\n const { agentFromAdbDevice } = await import('@midscene/android');\n const options = (config.target?.options || {}) as Record<string, unknown>;\n const { deviceId, launch, ...deviceOptions } = options;\n\n const agent = await agentFromAdbDevice(\n typeof deviceId === 'string' ? deviceId : undefined,\n {\n ...context.agentOptions,\n ...deviceOptions,\n },\n );\n\n if (typeof launch === 'string' && launch) {\n await agent.launch(launch);\n }\n\n return {\n agent,\n async teardown() {\n // Only terminate launched apps, not URLs opened in the default browser.\n if (typeof launch === 'string' && launch && !launch.startsWith('http')) {\n await agent.terminate(launch);\n }\n },\n };\n}\n\nasync function createWebSetup(\n config: MidsceneFrameworkConfig,\n context: DefaultSetupContext,\n): Promise<FrameworkSetupResult> {\n const [{ PlaywrightAgent }, { chromium }] = await Promise.all([\n import('@midscene/web/playwright'),\n import('playwright'),\n ]);\n\n const options = (config.target?.options || {}) as {\n url?: string;\n viewport?: { width: number; height: number };\n headless?: boolean;\n };\n\n if (!options.url) {\n throw new Error('target.options.url is required for the web target');\n }\n\n const browser = await chromium.launch({\n headless: options.headless ?? true,\n args: ['--no-sandbox', '--disable-setuid-sandbox'],\n });\n const browserContext = await browser.newContext({\n viewport: options.viewport,\n });\n const page = await browserContext.newPage();\n await page.goto(options.url);\n\n return {\n agent: new PlaywrightAgent(page, context.agentOptions),\n browser,\n context: browserContext,\n page,\n async teardown() {\n await browserContext.close();\n await browser.close();\n },\n };\n}\n\n/**\n * Create an agent from the default `target` config. Only the `web` and\n * `android` targets documented for the first version are supported.\n */\nexport async function createDefaultSetup(\n config: MidsceneFrameworkConfig,\n context: DefaultSetupContext,\n): Promise<FrameworkSetupResult> {\n if (!config.target) {\n throw new Error('midscene config must provide \"target\" or \"setup\"');\n }\n\n if (config.target.type === 'android') {\n return createAndroidSetup(config, context);\n }\n\n if (config.target.type === 'web') {\n return createWebSetup(config, context);\n }\n\n throw new Error(`Unsupported target.type: ${config.target.type}`);\n}\n\n/**\n * Resolve the suite agent. A custom `setup` takes precedence; otherwise the\n * default target setup is used.\n */\nexport async function setupFrameworkAgent(\n config: MidsceneFrameworkConfig,\n context: DefaultSetupContext,\n): Promise<FrameworkSetupResult> {\n if (config.setup) {\n return config.setup(context);\n }\n\n return createDefaultSetup(config, context);\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","createAndroidSetup","config","context","agentFromAdbDevice","options","deviceId","launch","deviceOptions","agent","undefined","createWebSetup","PlaywrightAgent","chromium","Promise","Error","browser","browserContext","page","createDefaultSetup","setupFrameworkAgent"],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
createYamlFrameworkSuiteSource: ()=>createYamlFrameworkSuiteSource
|
|
28
|
+
});
|
|
29
|
+
function createYamlFrameworkSuiteSource(options) {
|
|
30
|
+
const runtimeImport = options.runtimeImport || '@midscene/testing-framework/runtime';
|
|
31
|
+
const rstestImport = options.rstestImport || '@rstest/core';
|
|
32
|
+
const tests = options.cases.map((item)=>`test(${JSON.stringify(item.testName)}, async () => {\n await runtime.runCase(${JSON.stringify(item.filePath)}, ${JSON.stringify(item.resultFile)});\n});`).join('\n\n');
|
|
33
|
+
return `import { afterAll, beforeAll, test } from ${JSON.stringify(rstestImport)};
|
|
34
|
+
import config from ${JSON.stringify(options.configPath)};
|
|
35
|
+
import { createSuiteRuntime } from ${JSON.stringify(runtimeImport)};
|
|
36
|
+
|
|
37
|
+
const runtime = createSuiteRuntime({
|
|
38
|
+
config,
|
|
39
|
+
projectDir: ${JSON.stringify(options.projectDir)},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
beforeAll(async () => {
|
|
43
|
+
await runtime.setup();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
afterAll(async () => {
|
|
47
|
+
await runtime.teardown();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
${tests}
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
exports.createYamlFrameworkSuiteSource = __webpack_exports__.createYamlFrameworkSuiteSource;
|
|
54
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
55
|
+
"createYamlFrameworkSuiteSource"
|
|
56
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
57
|
+
Object.defineProperty(exports, '__esModule', {
|
|
58
|
+
value: true
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime/source.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/runtime/source.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};","export interface FrameworkSuiteSourceCase {\n filePath: string;\n testName: string;\n resultFile: string;\n}\n\nexport interface CreateYamlFrameworkSuiteSourceOptions {\n configPath: string;\n projectDir: string;\n cases: FrameworkSuiteSourceCase[];\n /** Import specifier for `@midscene/testing-framework/runtime`. */\n runtimeImport?: string;\n /** Import specifier for the Rstest test API. */\n rstestImport?: string;\n}\n\n/**\n * Generate the source of a single Rstest module that owns the whole YAML suite:\n * it sets the shared agent up once, registers one `test()` per YAML case, and\n * tears the agent down once. Each YAML case therefore maps to one Rstest test,\n * while suite-level setup/teardown and shared `state` are preserved.\n */\nexport function createYamlFrameworkSuiteSource(\n options: CreateYamlFrameworkSuiteSourceOptions,\n): string {\n const runtimeImport =\n options.runtimeImport || '@midscene/testing-framework/runtime';\n const rstestImport = options.rstestImport || '@rstest/core';\n\n const tests = options.cases\n .map(\n (item) =>\n `test(${JSON.stringify(item.testName)}, async () => {\\n await runtime.runCase(${JSON.stringify(\n item.filePath,\n )}, ${JSON.stringify(item.resultFile)});\\n});`,\n )\n .join('\\n\\n');\n\n return `import { afterAll, beforeAll, test } from ${JSON.stringify(rstestImport)};\nimport config from ${JSON.stringify(options.configPath)};\nimport { createSuiteRuntime } from ${JSON.stringify(runtimeImport)};\n\nconst runtime = createSuiteRuntime({\n config,\n projectDir: ${JSON.stringify(options.projectDir)},\n});\n\nbeforeAll(async () => {\n await runtime.setup();\n});\n\nafterAll(async () => {\n await runtime.teardown();\n});\n\n${tests}\n`;\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","createYamlFrameworkSuiteSource","options","runtimeImport","rstestImport","tests","item","JSON"],"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;;;;;;;ACgBO,SAASI,+BACdC,OAA8C;IAE9C,MAAMC,gBACJD,QAAQ,aAAa,IAAI;IAC3B,MAAME,eAAeF,QAAQ,YAAY,IAAI;IAE7C,MAAMG,QAAQH,QAAQ,KAAK,CACxB,GAAG,CACF,CAACI,OACC,CAAC,KAAK,EAAEC,KAAK,SAAS,CAACD,KAAK,QAAQ,EAAE,yCAAyC,EAAEC,KAAK,SAAS,CAC7FD,KAAK,QAAQ,EACb,EAAE,EAAEC,KAAK,SAAS,CAACD,KAAK,UAAU,EAAE,OAAO,CAAC,EAEjD,IAAI,CAAC;IAER,OAAO,CAAC,0CAA0C,EAAEC,KAAK,SAAS,CAACH,cAAc;mBAChE,EAAEG,KAAK,SAAS,CAACL,QAAQ,UAAU,EAAE;mCACrB,EAAEK,KAAK,SAAS,CAACJ,eAAe;;;;cAIrD,EAAEI,KAAK,SAAS,CAACL,QAAQ,UAAU,EAAE;;;;;;;;;;;AAWnD,EAAEG,MAAM;AACR,CAAC;AACD"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.n = (module)=>{
|
|
5
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
6
|
+
__webpack_require__.d(getter, {
|
|
7
|
+
a: getter
|
|
8
|
+
});
|
|
9
|
+
return getter;
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
(()=>{
|
|
13
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
14
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: definition[key]
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
})();
|
|
20
|
+
(()=>{
|
|
21
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
22
|
+
})();
|
|
23
|
+
(()=>{
|
|
24
|
+
__webpack_require__.r = (exports1)=>{
|
|
25
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
26
|
+
value: 'Module'
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
29
|
+
value: true
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
})();
|
|
33
|
+
var __webpack_exports__ = {};
|
|
34
|
+
__webpack_require__.r(__webpack_exports__);
|
|
35
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
36
|
+
normalizeYamlCase: ()=>normalizeYamlCase,
|
|
37
|
+
runBuiltinYamlCase: ()=>runBuiltinYamlCase,
|
|
38
|
+
runYamlFlowWithCustomSteps: ()=>runYamlFlowWithCustomSteps
|
|
39
|
+
});
|
|
40
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
41
|
+
const external_js_yaml_namespaceObject = require("js-yaml");
|
|
42
|
+
var external_js_yaml_default = /*#__PURE__*/ __webpack_require__.n(external_js_yaml_namespaceObject);
|
|
43
|
+
const external_builtin_steps_js_namespaceObject = require("../builtin-steps.js");
|
|
44
|
+
const caseNameFromPath = (filePath)=>(0, external_node_path_namespaceObject.basename)(filePath, (0, external_node_path_namespaceObject.extname)(filePath)) || 'case';
|
|
45
|
+
function normalizeYamlCase(content, filePath) {
|
|
46
|
+
const parsed = external_js_yaml_default().load(content);
|
|
47
|
+
if (!parsed || 'object' != typeof parsed || Array.isArray(parsed)) throw new Error(`${filePath} must be a YAML object`);
|
|
48
|
+
if (Array.isArray(parsed.flow)) {
|
|
49
|
+
const { flow, ...rest } = parsed;
|
|
50
|
+
return {
|
|
51
|
+
name: caseNameFromPath(filePath),
|
|
52
|
+
flow: flow,
|
|
53
|
+
raw: rest
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(parsed.tasks)) throw new Error(`${filePath} uses a full "tasks" document; framework cases must use a top-level "flow"`);
|
|
57
|
+
throw new Error(`${filePath} must include a top-level "flow" array`);
|
|
58
|
+
}
|
|
59
|
+
const dumpSingleStepTask = (caseName, step)=>external_js_yaml_default().dump({
|
|
60
|
+
tasks: [
|
|
61
|
+
{
|
|
62
|
+
name: caseName,
|
|
63
|
+
flow: [
|
|
64
|
+
step
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}, {
|
|
69
|
+
lineWidth: -1,
|
|
70
|
+
noRefs: true
|
|
71
|
+
});
|
|
72
|
+
const resolveStepName = (step, yamlSteps)=>{
|
|
73
|
+
const keys = Object.keys(step);
|
|
74
|
+
const customKey = keys.find((key)=>yamlSteps?.[key]);
|
|
75
|
+
if (customKey) return {
|
|
76
|
+
stepName: customKey,
|
|
77
|
+
kind: 'custom'
|
|
78
|
+
};
|
|
79
|
+
const builtinKey = keys.find((key)=>external_builtin_steps_js_namespaceObject.BUILTIN_YAML_STEP_NAMES.has(key));
|
|
80
|
+
if (builtinKey) return {
|
|
81
|
+
stepName: builtinKey,
|
|
82
|
+
kind: 'builtin'
|
|
83
|
+
};
|
|
84
|
+
return {
|
|
85
|
+
stepName: keys[0] ?? '',
|
|
86
|
+
kind: 'unknown'
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
async function runYamlFlowWithCustomSteps(options) {
|
|
90
|
+
for (const [stepIndex, step] of options.flow.entries()){
|
|
91
|
+
if (!step || 'object' != typeof step || Array.isArray(step)) throw new Error(`${options.filePath} step ${stepIndex + 1} must be an object`);
|
|
92
|
+
const stepRecord = step;
|
|
93
|
+
const { stepName, kind } = resolveStepName(stepRecord, options.yamlSteps);
|
|
94
|
+
if ('custom' === kind) {
|
|
95
|
+
const handler = options.yamlSteps[stepName];
|
|
96
|
+
await handler(stepRecord[stepName], {
|
|
97
|
+
agent: options.agent,
|
|
98
|
+
state: options.state,
|
|
99
|
+
filePath: options.filePath,
|
|
100
|
+
stepIndex,
|
|
101
|
+
stepName
|
|
102
|
+
});
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if ('builtin' === kind) {
|
|
106
|
+
await options.agent.runYaml(dumpSingleStepTask(`${options.caseName}:${stepName}`, step));
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
throw new Error(`${options.filePath} step ${stepIndex + 1} uses unknown step "${stepName}"`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function runBuiltinYamlCase(options) {
|
|
113
|
+
await options.agent.runYaml(external_js_yaml_default().dump({
|
|
114
|
+
...options.normalizedCase.raw,
|
|
115
|
+
tasks: [
|
|
116
|
+
{
|
|
117
|
+
name: options.normalizedCase.name,
|
|
118
|
+
flow: options.normalizedCase.flow
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}, {
|
|
122
|
+
lineWidth: -1,
|
|
123
|
+
noRefs: true
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
exports.normalizeYamlCase = __webpack_exports__.normalizeYamlCase;
|
|
127
|
+
exports.runBuiltinYamlCase = __webpack_exports__.runBuiltinYamlCase;
|
|
128
|
+
exports.runYamlFlowWithCustomSteps = __webpack_exports__.runYamlFlowWithCustomSteps;
|
|
129
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
130
|
+
"normalizeYamlCase",
|
|
131
|
+
"runBuiltinYamlCase",
|
|
132
|
+
"runYamlFlowWithCustomSteps"
|
|
133
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
134
|
+
Object.defineProperty(exports, '__esModule', {
|
|
135
|
+
value: true
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
//# sourceMappingURL=yaml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime/yaml.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/runtime/yaml.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 { basename, extname } from 'node:path';\nimport type { MidsceneYamlFlowItem } from '@midscene/core';\nimport yaml from 'js-yaml';\nimport { BUILTIN_YAML_STEP_NAMES } from '../builtin-steps';\nimport type {\n CustomYamlStepHandler,\n FrameworkAgent,\n NormalizedYamlCase,\n} from '../types';\n\nconst caseNameFromPath = (filePath: string): string =>\n basename(filePath, extname(filePath)) || 'case';\n\n/**\n * Convert a framework YAML case (top-level `flow`) into a normalized shape. The\n * first version intentionally requires the documented top-level `flow` form and\n * rejects full `tasks` documents.\n */\nexport function normalizeYamlCase(\n content: string,\n filePath: string,\n): NormalizedYamlCase {\n const parsed = yaml.load(content) as Record<string, unknown> | undefined;\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(`${filePath} must be a YAML object`);\n }\n\n if (Array.isArray(parsed.flow)) {\n const { flow, ...rest } = parsed;\n return {\n name: caseNameFromPath(filePath),\n flow: flow as MidsceneYamlFlowItem[],\n raw: rest,\n };\n }\n\n if (Array.isArray((parsed as { tasks?: unknown }).tasks)) {\n throw new Error(\n `${filePath} uses a full \"tasks\" document; framework cases must use a top-level \"flow\"`,\n );\n }\n\n throw new Error(`${filePath} must include a top-level \"flow\" array`);\n}\n\nconst dumpSingleStepTask = (caseName: string, step: unknown): string =>\n yaml.dump(\n {\n tasks: [\n {\n name: caseName,\n flow: [step],\n },\n ],\n },\n { lineWidth: -1, noRefs: true },\n );\n\nconst resolveStepName = (\n step: Record<string, unknown>,\n yamlSteps: Record<string, CustomYamlStepHandler> | undefined,\n): { stepName: string; kind: 'custom' | 'builtin' | 'unknown' } => {\n const keys = Object.keys(step);\n\n // A custom step is identified by the registered key; built-in steps may carry\n // extra sibling keys (e.g. `aiInput` + `value`), so we look the action key up\n // instead of requiring exactly one key.\n const customKey = keys.find((key) => yamlSteps?.[key]);\n if (customKey) {\n return { stepName: customKey, kind: 'custom' };\n }\n\n const builtinKey = keys.find((key) => BUILTIN_YAML_STEP_NAMES.has(key));\n if (builtinKey) {\n return { stepName: builtinKey, kind: 'builtin' };\n }\n\n return { stepName: keys[0] ?? '', kind: 'unknown' };\n};\n\n/**\n * Run a flow step by step so built-in steps and custom `yamlSteps` interleave in\n * the authored order. Built-in steps are forwarded to `agent.runYaml`; custom\n * steps invoke their handler with the YAML value and the current context.\n */\nexport async function runYamlFlowWithCustomSteps(options: {\n agent: FrameworkAgent;\n filePath: string;\n caseName: string;\n flow: MidsceneYamlFlowItem[];\n yamlSteps?: Record<string, CustomYamlStepHandler>;\n state: Record<string, unknown>;\n}): Promise<void> {\n for (const [stepIndex, step] of options.flow.entries()) {\n if (!step || typeof step !== 'object' || Array.isArray(step)) {\n throw new Error(\n `${options.filePath} step ${stepIndex + 1} must be an object`,\n );\n }\n\n const stepRecord = step as Record<string, unknown>;\n const { stepName, kind } = resolveStepName(stepRecord, options.yamlSteps);\n\n if (kind === 'custom') {\n const handler = options.yamlSteps![stepName];\n await handler(stepRecord[stepName], {\n agent: options.agent,\n state: options.state,\n filePath: options.filePath,\n stepIndex,\n stepName,\n });\n continue;\n }\n\n if (kind === 'builtin') {\n await options.agent.runYaml(\n dumpSingleStepTask(`${options.caseName}:${stepName}`, step),\n );\n continue;\n }\n\n throw new Error(\n `${options.filePath} step ${stepIndex + 1} uses unknown step \"${stepName}\"`,\n );\n }\n}\n\n/**\n * Run a whole built-in case in a single `agent.runYaml` invocation. Used when no\n * custom `yamlSteps` are registered, so the existing YAML runner handles the\n * complete flow at once.\n */\nexport async function runBuiltinYamlCase(options: {\n agent: FrameworkAgent;\n normalizedCase: NormalizedYamlCase;\n}): Promise<void> {\n await options.agent.runYaml(\n yaml.dump(\n {\n ...options.normalizedCase.raw,\n tasks: [\n {\n name: options.normalizedCase.name,\n flow: options.normalizedCase.flow,\n },\n ],\n },\n { lineWidth: -1, noRefs: true },\n ),\n );\n}\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","caseNameFromPath","filePath","basename","extname","normalizeYamlCase","content","parsed","yaml","Array","Error","flow","rest","dumpSingleStepTask","caseName","step","resolveStepName","yamlSteps","keys","customKey","builtinKey","BUILTIN_YAML_STEP_NAMES","runYamlFlowWithCustomSteps","options","stepIndex","stepRecord","stepName","kind","handler","runBuiltinYamlCase"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.r = (exports1)=>{
|
|
5
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
6
|
+
value: 'Module'
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
9
|
+
value: true
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
})();
|
|
13
|
+
var __webpack_exports__ = {};
|
|
14
|
+
__webpack_require__.r(__webpack_exports__);
|
|
15
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
16
|
+
Object.defineProperty(exports, '__esModule', {
|
|
17
|
+
value: true
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sources":["webpack/runtime/make_namespace_object"],"sourcesContent":["// 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__","Symbol","Object"],"mappings":";;;IACAA,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOC,UAA0BA,OAAO,WAAW,EACrDC,OAAO,cAAc,CAAC,UAASD,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEC,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in Midscene YAML step keys. When a `flow` step's action key matches one
|
|
3
|
+
* of these, the framework hands the step to the existing `agent.runYaml`
|
|
4
|
+
* runner. Custom `yamlSteps` are not allowed to reuse these names.
|
|
5
|
+
*
|
|
6
|
+
* The set covers the keys documented for #2509 plus the action keys that the
|
|
7
|
+
* example cases actually use (e.g. `aiWaitFor`, `value`-bearing steps). Extend
|
|
8
|
+
* it together with a test when a missing built-in key surfaces.
|
|
9
|
+
*/
|
|
10
|
+
export declare const BUILTIN_YAML_STEP_NAMES: ReadonlySet<string>;
|
|
11
|
+
export declare const isBuiltinYamlStep: (stepName: string) => boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FrameworkTestFile, LoadedMidsceneConfig, MidsceneFrameworkConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Type-only helper. It returns the config unchanged so the runtime stays
|
|
4
|
+
* explicit and the project keeps full control over its own configuration.
|
|
5
|
+
*/
|
|
6
|
+
export declare function defineMidsceneConfig<T extends MidsceneFrameworkConfig>(config: T): T;
|
|
7
|
+
export declare function loadMidsceneConfig(configPath?: string): Promise<LoadedMidsceneConfig>;
|
|
8
|
+
/**
|
|
9
|
+
* Validate the documented invariants of a `midscene.config.ts`:
|
|
10
|
+
* - `testDir` and `include` are required.
|
|
11
|
+
* - `target` and `setup` cannot be defined together (two runtime targets).
|
|
12
|
+
* - custom `yamlSteps` must not override built-in step names.
|
|
13
|
+
*/
|
|
14
|
+
export declare function validateMidsceneConfig(config: MidsceneFrameworkConfig, source?: string): void;
|
|
15
|
+
export declare function collectFrameworkTestFiles(input: {
|
|
16
|
+
root: string;
|
|
17
|
+
config: MidsceneFrameworkConfig;
|
|
18
|
+
}): Promise<FrameworkTestFile[]>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { MidsceneFrameworkConfig } from './types';
|
|
2
|
+
export interface LoadedDotenvFile {
|
|
3
|
+
path: string;
|
|
4
|
+
loaded: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the ordered list of `.env` files to consider for a suite run.
|
|
8
|
+
* Defaults to `[<cwd>/.env, <configDir>/.env]` so a project can keep its env
|
|
9
|
+
* either next to the config or at the working directory it was invoked from.
|
|
10
|
+
* Explicit `env.path` overrides the default lookup entirely.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveDotenvCandidates(input: {
|
|
13
|
+
cwd: string;
|
|
14
|
+
configDir: string;
|
|
15
|
+
envConfig?: MidsceneFrameworkConfig['env'];
|
|
16
|
+
}): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Load `.env` files for a suite run. Mirrors `@midscene/cli` semantics:
|
|
19
|
+
* existing `process.env` values are preserved unless `override` is set, and
|
|
20
|
+
* missing files are skipped silently so a project without a `.env` keeps
|
|
21
|
+
* working. Returns the considered files so the caller can log what was
|
|
22
|
+
* actually applied.
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadFrameworkDotenv(input: {
|
|
25
|
+
cwd: string;
|
|
26
|
+
configDir: string;
|
|
27
|
+
envConfig?: MidsceneFrameworkConfig['env'];
|
|
28
|
+
}): LoadedDotenvFile[];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { collectFrameworkTestFiles, defineMidsceneConfig, loadMidsceneConfig, validateMidsceneConfig, } from './config';
|
|
2
|
+
export { BUILTIN_YAML_STEP_NAMES, isBuiltinYamlStep } from './builtin-steps';
|
|
3
|
+
export { type LoadedDotenvFile, loadFrameworkDotenv, resolveDotenvCandidates, } from './dotenv';
|
|
4
|
+
export { type FrameworkRstestProject, type FrameworkRstestRunner, type RunMidsceneSuiteOptions, runMidsceneSuite, } from './runner';
|
|
5
|
+
export type { CustomYamlStepContext, CustomYamlStepHandler, FrameworkAgent, FrameworkCaseResult, FrameworkSetupResult, FrameworkSuiteSummary, FrameworkTargetConfig, FrameworkTargetType, FrameworkTestFile, LoadedMidsceneConfig, MidsceneFrameworkConfig, NormalizedYamlCase, SetupContext, } from './types';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { FrameworkSuiteSummary } from './types';
|
|
2
|
+
export interface FrameworkRstestProject {
|
|
3
|
+
root: string;
|
|
4
|
+
include: string[];
|
|
5
|
+
virtualModules: Record<string, string>;
|
|
6
|
+
maxConcurrency?: number;
|
|
7
|
+
testTimeout?: number;
|
|
8
|
+
bail?: number;
|
|
9
|
+
retry?: number;
|
|
10
|
+
}
|
|
11
|
+
export type FrameworkRstestRunner = (project: FrameworkRstestProject) => Promise<{
|
|
12
|
+
ok: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
export interface RunMidsceneSuiteOptions {
|
|
15
|
+
/** Path to `midscene.config.ts`. Defaults to the one in `cwd`. */
|
|
16
|
+
configPath?: string;
|
|
17
|
+
/** Directory for generated wiring and per-case result files. */
|
|
18
|
+
outputDir?: string;
|
|
19
|
+
/** Override the Rstest runner. Mainly for tests. */
|
|
20
|
+
rstestRunner?: FrameworkRstestRunner;
|
|
21
|
+
stdio?: 'inherit' | 'pipe';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Load `midscene.config.ts`, discover cases, run them through Rstest, and write
|
|
25
|
+
* the suite summary. Intended to be the entire body of a project's
|
|
26
|
+
* `run-suite.ts`:
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { runMidsceneSuite } from '@midscene/testing-framework';
|
|
30
|
+
* await runMidsceneSuite();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function runMidsceneSuite(options?: RunMidsceneSuiteOptions): Promise<FrameworkSuiteSummary>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { MidsceneFrameworkConfig } from '../types';
|
|
2
|
+
export { createYamlFrameworkSuiteSource } from './source';
|
|
3
|
+
export { normalizeYamlCase, runBuiltinYamlCase, runYamlFlowWithCustomSteps, } from './yaml';
|
|
4
|
+
export { createDefaultSetup, setupFrameworkAgent } from './setup';
|
|
5
|
+
export interface SuiteRuntimeOptions {
|
|
6
|
+
config: MidsceneFrameworkConfig;
|
|
7
|
+
projectDir: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Suite-level runtime shared by every generated case in a single Rstest module.
|
|
11
|
+
* The agent and `state` are created once (`beforeAll`) and torn down once
|
|
12
|
+
* (`afterAll`), so seeded data and cross-step state stay shared across cases.
|
|
13
|
+
*/
|
|
14
|
+
export declare class FrameworkSuiteRuntime {
|
|
15
|
+
private readonly config;
|
|
16
|
+
private readonly projectDir;
|
|
17
|
+
private readonly state;
|
|
18
|
+
private setupResult?;
|
|
19
|
+
constructor(options: SuiteRuntimeOptions);
|
|
20
|
+
setup(): Promise<void>;
|
|
21
|
+
teardown(): Promise<void>;
|
|
22
|
+
runCase(filePath: string, resultFile?: string): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export declare function createSuiteRuntime(options: SuiteRuntimeOptions): FrameworkSuiteRuntime;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { FrameworkSetupResult, MidsceneFrameworkConfig, SetupContext } from '../types';
|
|
2
|
+
interface DefaultSetupContext extends SetupContext {
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Create an agent from the default `target` config. Only the `web` and
|
|
6
|
+
* `android` targets documented for the first version are supported.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createDefaultSetup(config: MidsceneFrameworkConfig, context: DefaultSetupContext): Promise<FrameworkSetupResult>;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the suite agent. A custom `setup` takes precedence; otherwise the
|
|
11
|
+
* default target setup is used.
|
|
12
|
+
*/
|
|
13
|
+
export declare function setupFrameworkAgent(config: MidsceneFrameworkConfig, context: DefaultSetupContext): Promise<FrameworkSetupResult>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface FrameworkSuiteSourceCase {
|
|
2
|
+
filePath: string;
|
|
3
|
+
testName: string;
|
|
4
|
+
resultFile: string;
|
|
5
|
+
}
|
|
6
|
+
export interface CreateYamlFrameworkSuiteSourceOptions {
|
|
7
|
+
configPath: string;
|
|
8
|
+
projectDir: string;
|
|
9
|
+
cases: FrameworkSuiteSourceCase[];
|
|
10
|
+
/** Import specifier for `@midscene/testing-framework/runtime`. */
|
|
11
|
+
runtimeImport?: string;
|
|
12
|
+
/** Import specifier for the Rstest test API. */
|
|
13
|
+
rstestImport?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Generate the source of a single Rstest module that owns the whole YAML suite:
|
|
17
|
+
* it sets the shared agent up once, registers one `test()` per YAML case, and
|
|
18
|
+
* tears the agent down once. Each YAML case therefore maps to one Rstest test,
|
|
19
|
+
* while suite-level setup/teardown and shared `state` are preserved.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createYamlFrameworkSuiteSource(options: CreateYamlFrameworkSuiteSourceOptions): string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { MidsceneYamlFlowItem } from '@midscene/core';
|
|
2
|
+
import type { CustomYamlStepHandler, FrameworkAgent, NormalizedYamlCase } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Convert a framework YAML case (top-level `flow`) into a normalized shape. The
|
|
5
|
+
* first version intentionally requires the documented top-level `flow` form and
|
|
6
|
+
* rejects full `tasks` documents.
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeYamlCase(content: string, filePath: string): NormalizedYamlCase;
|
|
9
|
+
/**
|
|
10
|
+
* Run a flow step by step so built-in steps and custom `yamlSteps` interleave in
|
|
11
|
+
* the authored order. Built-in steps are forwarded to `agent.runYaml`; custom
|
|
12
|
+
* steps invoke their handler with the YAML value and the current context.
|
|
13
|
+
*/
|
|
14
|
+
export declare function runYamlFlowWithCustomSteps(options: {
|
|
15
|
+
agent: FrameworkAgent;
|
|
16
|
+
filePath: string;
|
|
17
|
+
caseName: string;
|
|
18
|
+
flow: MidsceneYamlFlowItem[];
|
|
19
|
+
yamlSteps?: Record<string, CustomYamlStepHandler>;
|
|
20
|
+
state: Record<string, unknown>;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Run a whole built-in case in a single `agent.runYaml` invocation. Used when no
|
|
24
|
+
* custom `yamlSteps` are registered, so the existing YAML runner handles the
|
|
25
|
+
* complete flow at once.
|
|
26
|
+
*/
|
|
27
|
+
export declare function runBuiltinYamlCase(options: {
|
|
28
|
+
agent: FrameworkAgent;
|
|
29
|
+
normalizedCase: NormalizedYamlCase;
|
|
30
|
+
}): Promise<void>;
|