@midscene/cli 1.13.1-beta-20260922030100.0 → 1.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/framework/index.mjs +51 -31
- package/dist/es/framework/index.mjs.map +1 -1
- package/dist/es/index.mjs +66 -33
- package/dist/es/index.mjs.map +1 -1
- package/dist/lib/framework/index.js +51 -31
- package/dist/lib/framework/index.js.map +1 -1
- package/dist/lib/index.js +66 -33
- package/dist/lib/index.js.map +1 -1
- package/dist/types/framework/index.d.ts +2 -0
- package/package.json +10 -10
package/dist/lib/index.js
CHANGED
|
@@ -3270,6 +3270,7 @@ var __webpack_modules__ = {
|
|
|
3270
3270
|
console.log(` Continue on error: ${config.continueOnError}`);
|
|
3271
3271
|
console.log(` Retry: ${config.retry ?? 0}`);
|
|
3272
3272
|
console.log(` Share browser context: ${config.shareBrowserContext ?? false}`);
|
|
3273
|
+
console.log(` Reuse browser page: ${config.reusePage ?? false}`);
|
|
3273
3274
|
console.log(` Summary output: ${config.summary}`);
|
|
3274
3275
|
}
|
|
3275
3276
|
function printExecutionFinished() {
|
|
@@ -3973,11 +3974,22 @@ var __webpack_modules__ = {
|
|
|
3973
3974
|
}
|
|
3974
3975
|
if (setupContext && !shareBrowserContext && 'puppeteer-web' === resolveBatchRuntimeTarget(setupContext.executionConfig)) throw new Error(`Puppeteer Web setup "${setupContext.file}" requires shareBrowserContext: true so its browser state can be shared with the main files.`);
|
|
3975
3976
|
};
|
|
3976
|
-
const createSharedBrowserRuntime = async (browser, browserContextOptions)=>{
|
|
3977
|
+
const createSharedBrowserRuntime = async (browser, browserContextOptions, reusePage = false)=>{
|
|
3977
3978
|
const browserContext = await browser.createBrowserContext(browserContextOptions);
|
|
3978
|
-
|
|
3979
|
-
browserContext
|
|
3980
|
-
|
|
3979
|
+
try {
|
|
3980
|
+
const page = reusePage ? await browserContext.newPage() : void 0;
|
|
3981
|
+
return {
|
|
3982
|
+
browserContext,
|
|
3983
|
+
page
|
|
3984
|
+
};
|
|
3985
|
+
} catch (error) {
|
|
3986
|
+
try {
|
|
3987
|
+
await browserContext.close();
|
|
3988
|
+
} catch (cleanupError) {
|
|
3989
|
+
batchWarning('failed to close the shared browser context after page creation failed; preserving the original error', cleanupError);
|
|
3990
|
+
}
|
|
3991
|
+
throw error;
|
|
3992
|
+
}
|
|
3981
3993
|
};
|
|
3982
3994
|
class YamlBatchExecutor {
|
|
3983
3995
|
async run(options = {}) {
|
|
@@ -4062,10 +4074,11 @@ var __webpack_modules__ = {
|
|
|
4062
4074
|
sharedRuntime.current = null;
|
|
4063
4075
|
await staleRuntime.browserContext.close();
|
|
4064
4076
|
}
|
|
4065
|
-
sharedRuntime.current = await createSharedBrowserRuntime(browser, browserContextOptions);
|
|
4077
|
+
sharedRuntime.current = await createSharedBrowserRuntime(browser, browserContextOptions, this.config.reusePage);
|
|
4066
4078
|
for (const context of allContexts){
|
|
4067
4079
|
context.options.browser = browser;
|
|
4068
4080
|
context.options.browserContext = sharedRuntime.current.browserContext;
|
|
4081
|
+
if (sharedRuntime.current.page) context.options.page = sharedRuntime.current.page;
|
|
4069
4082
|
}
|
|
4070
4083
|
};
|
|
4071
4084
|
await resetSetupRuntime();
|
|
@@ -4345,6 +4358,8 @@ var __webpack_modules__ = {
|
|
|
4345
4358
|
}, (_, index)=>`batch-occurrence-${index + 1}`);
|
|
4346
4359
|
if (this.caseIds.length !== occurrenceCount) throw new Error(`Batch occurrence identity mismatch: expected ${occurrenceCount} case ID(s), received ${this.caseIds.length}`);
|
|
4347
4360
|
if (new Set(this.caseIds).size !== this.caseIds.length) throw new Error('Batch occurrence case IDs must be unique');
|
|
4361
|
+
if (config.reusePage && !config.shareBrowserContext) throw new Error('reusePage requires shareBrowserContext: true');
|
|
4362
|
+
if (config.reusePage && 1 !== config.concurrent) throw new Error('reusePage requires concurrent: 1');
|
|
4348
4363
|
}
|
|
4349
4364
|
}
|
|
4350
4365
|
async function runYamlBatch(config, options = {}) {
|
|
@@ -4577,29 +4592,26 @@ defineYamlBatchTest(test, testOptions);
|
|
|
4577
4592
|
};
|
|
4578
4593
|
}
|
|
4579
4594
|
var external_node_url_ = __webpack_require__("node:url");
|
|
4595
|
+
const error_formatter_namespaceObject = require("@midscene/shared/agent-tools/error-formatter");
|
|
4580
4596
|
var progress_reporter = __webpack_require__("./src/framework/progress-reporter.ts");
|
|
4581
4597
|
var rstest_contract = __webpack_require__("./src/framework/rstest-contract.ts");
|
|
4582
|
-
const formatRunError = (error)=>error.stack || `${error.name}: ${error.message}`;
|
|
4598
|
+
const formatRunError = (error)=>error.stack || `${error.name || 'Error'}: ${error.message}`;
|
|
4583
4599
|
const collectRunErrors = (result)=>{
|
|
4584
4600
|
const messages = [];
|
|
4585
4601
|
const push = (error, label)=>{
|
|
4586
4602
|
const formatted = formatRunError(error);
|
|
4587
4603
|
messages.push(label ? `${label}: ${formatted}` : formatted);
|
|
4588
4604
|
};
|
|
4589
|
-
for (const file of result.
|
|
4605
|
+
for (const file of result.results){
|
|
4590
4606
|
for (const error of file.errors ?? [])push(error, file.name || file.testPath);
|
|
4591
4607
|
for (const testResult of file.results ?? [])for (const error of testResult.errors ?? [])push(error, testResult.name);
|
|
4592
4608
|
}
|
|
4593
|
-
for (const error of result.unhandledErrors
|
|
4609
|
+
for (const error of result.unhandledErrors)push(error);
|
|
4594
4610
|
return Array.from(new Set(messages));
|
|
4595
4611
|
};
|
|
4596
4612
|
const rstest_runner_errorMessage = (error)=>error.message || error.name || 'YAML case failed';
|
|
4597
4613
|
const mapRunErrorsToCases = (project, result)=>{
|
|
4598
|
-
const
|
|
4599
|
-
item.caseId,
|
|
4600
|
-
item
|
|
4601
|
-
]));
|
|
4602
|
-
const knownCaseIds = new Set(casesById.keys());
|
|
4614
|
+
const knownCaseIds = new Set(project.cases.map((item)=>item.caseId));
|
|
4603
4615
|
const errors = new Map();
|
|
4604
4616
|
const add = (caseId, message)=>{
|
|
4605
4617
|
if (knownCaseIds.has(caseId) && message && !errors.has(caseId)) errors.set(caseId, message);
|
|
@@ -4622,7 +4634,7 @@ defineYamlBatchTest(test, testOptions);
|
|
|
4622
4634
|
const value = testResult.meta?.[rstest_contract.k];
|
|
4623
4635
|
return Array.isArray(value) ? value.filter((item)=>'string' == typeof item) : [];
|
|
4624
4636
|
};
|
|
4625
|
-
for (const file of result.
|
|
4637
|
+
for (const file of result.results){
|
|
4626
4638
|
const moduleCaseIds = findModuleCaseIds(file);
|
|
4627
4639
|
for (const error of file.errors ?? [])addCases(moduleCaseIds, rstest_runner_errorMessage(error));
|
|
4628
4640
|
for (const testResult of file.results ?? []){
|
|
@@ -4630,18 +4642,13 @@ defineYamlBatchTest(test, testOptions);
|
|
|
4630
4642
|
for (const error of testResult.errors ?? [])addCases(caseIds.length ? caseIds : moduleCaseIds, rstest_runner_errorMessage(error));
|
|
4631
4643
|
}
|
|
4632
4644
|
}
|
|
4633
|
-
if (
|
|
4645
|
+
if (result.unhandledErrors.length) {
|
|
4634
4646
|
const message = rstest_runner_errorMessage(result.unhandledErrors[0]);
|
|
4635
|
-
for (const
|
|
4636
|
-
const item = casesById.get(caseId);
|
|
4637
|
-
if (!errors.has(caseId) || item && !(0, external_node_fs_.existsSync)(item.resultFile)) errors.set(caseId, message);
|
|
4638
|
-
}
|
|
4647
|
+
for (const item of project.cases)if (!errors.has(item.caseId) && !(0, external_node_fs_.existsSync)(item.resultFile)) errors.set(item.caseId, message);
|
|
4639
4648
|
}
|
|
4640
4649
|
return errors;
|
|
4641
4650
|
};
|
|
4642
|
-
const
|
|
4643
|
-
if (!project.cases.length) return;
|
|
4644
|
-
const caseErrors = mapRunErrorsToCases(project, result);
|
|
4651
|
+
const writePendingCaseFailures = (project, caseErrors)=>{
|
|
4645
4652
|
for (const item of project.cases){
|
|
4646
4653
|
if ((0, external_node_fs_.existsSync)(item.resultFile)) continue;
|
|
4647
4654
|
const error = caseErrors.get(item.caseId);
|
|
@@ -4663,13 +4670,13 @@ defineYamlBatchTest(test, testOptions);
|
|
|
4663
4670
|
}
|
|
4664
4671
|
};
|
|
4665
4672
|
async function runRstestYamlProject(options) {
|
|
4666
|
-
const [{
|
|
4673
|
+
const [{ createRstest }, { rspack }] = await Promise.all([
|
|
4667
4674
|
import("@rstest/core/api"),
|
|
4668
4675
|
import((0, external_node_url_.pathToFileURL)(resolvePackageFromRstestCore('@rsbuild/core')).href)
|
|
4669
4676
|
]);
|
|
4670
4677
|
const { project } = options;
|
|
4671
4678
|
const maxConcurrency = void 0 !== project.maxConcurrency ? Math.max(1, project.maxConcurrency) : void 0;
|
|
4672
|
-
const
|
|
4679
|
+
const config = {
|
|
4673
4680
|
root: project.projectDir,
|
|
4674
4681
|
include: project.modules.map((item)=>item.id),
|
|
4675
4682
|
testEnvironment: 'node',
|
|
@@ -4700,18 +4707,31 @@ defineYamlBatchTest(test, testOptions);
|
|
|
4700
4707
|
}
|
|
4701
4708
|
}
|
|
4702
4709
|
};
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4710
|
+
let result;
|
|
4711
|
+
try {
|
|
4712
|
+
const rstest = await createRstest({
|
|
4713
|
+
cwd: options.cwd || project.projectDir,
|
|
4714
|
+
config
|
|
4715
|
+
});
|
|
4716
|
+
result = await rstest.run();
|
|
4717
|
+
} catch (error) {
|
|
4718
|
+
const serialized = (0, error_formatter_namespaceObject.serializeError)(error);
|
|
4719
|
+
writePendingCaseFailures(project, new Map(project.cases.map((item)=>[
|
|
4720
|
+
item.caseId,
|
|
4721
|
+
serialized.message
|
|
4722
|
+
])));
|
|
4723
|
+
if ('pipe' !== options.stdio) console.error(`\nYAML execution failed:\n${formatRunError(serialized)}`);
|
|
4724
|
+
return 1;
|
|
4725
|
+
}
|
|
4726
|
+
const ok = 'pass' === result.status;
|
|
4727
|
+
if (!ok) {
|
|
4728
|
+
writePendingCaseFailures(project, mapRunErrorsToCases(project, result));
|
|
4709
4729
|
if ('pipe' !== options.stdio) {
|
|
4710
4730
|
const runErrors = collectRunErrors(result);
|
|
4711
4731
|
if (runErrors.length) console.error(`\nYAML execution failed:\n${runErrors.join('\n\n')}`);
|
|
4712
4732
|
}
|
|
4713
4733
|
}
|
|
4714
|
-
return
|
|
4734
|
+
return ok ? 0 : 1;
|
|
4715
4735
|
}
|
|
4716
4736
|
const defaultInProcessRunner = (config)=>new BatchRunner(config).run();
|
|
4717
4737
|
async function runConfigInMainProcess(config, commandOptions) {
|
|
@@ -4793,7 +4813,9 @@ defineYamlBatchTest(test, testOptions);
|
|
|
4793
4813
|
"use strict";
|
|
4794
4814
|
var core_ = __webpack_require__("@midscene/core");
|
|
4795
4815
|
const cli_namespaceObject = require("@midscene/shared/cli");
|
|
4796
|
-
var package_namespaceObject =
|
|
4816
|
+
var package_namespaceObject = {
|
|
4817
|
+
rE: "1.13.1"
|
|
4818
|
+
};
|
|
4797
4819
|
var external_node_fs_ = __webpack_require__("node:fs");
|
|
4798
4820
|
var external_node_fs_namespaceObject = /*#__PURE__*/ __webpack_require__.t(external_node_fs_, 2);
|
|
4799
4821
|
var external_node_path_ = __webpack_require__("node:path");
|
|
@@ -10384,6 +10406,7 @@ defineYamlBatchTest(test, testOptions);
|
|
|
10384
10406
|
continueOnError: false,
|
|
10385
10407
|
retry: 0,
|
|
10386
10408
|
shareBrowserContext: false,
|
|
10409
|
+
reusePage: false,
|
|
10387
10410
|
headed: false,
|
|
10388
10411
|
keepWindow: false,
|
|
10389
10412
|
dotenvOverride: false,
|
|
@@ -10458,6 +10481,10 @@ Usage:
|
|
|
10458
10481
|
type: 'boolean',
|
|
10459
10482
|
description: `Share a Puppeteer Web browser context across multiple yaml files, default is ${config_options_defaultConfig.shareBrowserContext}`
|
|
10460
10483
|
},
|
|
10484
|
+
'reuse-page': {
|
|
10485
|
+
type: 'boolean',
|
|
10486
|
+
description: `Reuse one Puppeteer Web page across sequential yaml files; requires --share-browser-context and --concurrent 1, default is ${config_options_defaultConfig.reusePage}`
|
|
10487
|
+
},
|
|
10461
10488
|
'dotenv-override': {
|
|
10462
10489
|
type: 'boolean',
|
|
10463
10490
|
description: `Whether the variables in the .env file override the global variables, the default is ${config_options_defaultConfig.dotenvOverride}`
|
|
@@ -10470,7 +10497,7 @@ Usage:
|
|
|
10470
10497
|
type: 'boolean',
|
|
10471
10498
|
description: 'Whether to dismiss the HarmonyOS keyboard after text input'
|
|
10472
10499
|
}
|
|
10473
|
-
}).version('version', 'Show version number', "1.13.1
|
|
10500
|
+
}).version('version', 'Show version number', "1.13.1").help().epilogue(`For complete list of configuration options, please visit:
|
|
10474
10501
|
• Web options: https://midscenejs.com/automate-with-scripts-in-yaml#the-web-part
|
|
10475
10502
|
• Android options: https://midscenejs.com/automate-with-scripts-in-yaml#the-android-part
|
|
10476
10503
|
• HarmonyOS options: https://midscenejs.com/automate-with-scripts-in-yaml#the-harmony-part
|
|
@@ -12649,6 +12676,7 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12649
12676
|
retry: configYaml.retry ?? config_options_defaultConfig.retry,
|
|
12650
12677
|
summary: configYaml.summary ?? defaultSummary,
|
|
12651
12678
|
shareBrowserContext: configYaml.shareBrowserContext ?? config_options_defaultConfig.shareBrowserContext,
|
|
12679
|
+
reusePage: configYaml.reusePage ?? config_options_defaultConfig.reusePage,
|
|
12652
12680
|
patterns: configYaml.files,
|
|
12653
12681
|
files,
|
|
12654
12682
|
setup,
|
|
@@ -12676,6 +12704,7 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12676
12704
|
setup = await resolveSetupFile(options.setup, basePath);
|
|
12677
12705
|
}
|
|
12678
12706
|
const shareBrowserContext = options?.shareBrowserContext ?? parsedConfig.shareBrowserContext;
|
|
12707
|
+
const reusePage = options?.reusePage ?? parsedConfig.reusePage;
|
|
12679
12708
|
return {
|
|
12680
12709
|
files,
|
|
12681
12710
|
setup,
|
|
@@ -12684,6 +12713,7 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12684
12713
|
retry: options?.retry ?? parsedConfig.retry,
|
|
12685
12714
|
summary: options?.summary ?? parsedConfig.summary,
|
|
12686
12715
|
shareBrowserContext,
|
|
12716
|
+
reusePage,
|
|
12687
12717
|
headed: finalHeaded,
|
|
12688
12718
|
keepWindow: keepWindow,
|
|
12689
12719
|
dotenvOverride: options?.dotenvOverride ?? parsedConfig.dotenvOverride,
|
|
@@ -12700,6 +12730,7 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12700
12730
|
const headed = options.headed ?? config_options_defaultConfig.headed;
|
|
12701
12731
|
const finalHeaded = keepWindow || headed;
|
|
12702
12732
|
const shareBrowserContext = options.shareBrowserContext ?? config_options_defaultConfig.shareBrowserContext;
|
|
12733
|
+
const reusePage = options.reusePage ?? config_options_defaultConfig.reusePage;
|
|
12703
12734
|
return {
|
|
12704
12735
|
files,
|
|
12705
12736
|
setup,
|
|
@@ -12708,6 +12739,7 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12708
12739
|
retry: options.retry ?? config_options_defaultConfig.retry,
|
|
12709
12740
|
summary: options.summary ?? defaultSummary,
|
|
12710
12741
|
shareBrowserContext,
|
|
12742
|
+
reusePage,
|
|
12711
12743
|
headed: finalHeaded,
|
|
12712
12744
|
keepWindow: keepWindow,
|
|
12713
12745
|
dotenvOverride: options.dotenvOverride ?? config_options_defaultConfig.dotenvOverride,
|
|
@@ -12969,6 +13001,7 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12969
13001
|
retry: options.retry,
|
|
12970
13002
|
summary: options.summary,
|
|
12971
13003
|
shareBrowserContext: options['share-browser-context'],
|
|
13004
|
+
reusePage: options['reuse-page'],
|
|
12972
13005
|
headed: options.headed,
|
|
12973
13006
|
keepWindow: options['keep-window'],
|
|
12974
13007
|
dotenvOverride: options['dotenv-override'],
|