@elliemae/encw-leak-runner 1.0.2 → 1.0.4
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/CHANGELOG.md +22 -0
- package/README.md +34 -17
- package/dist/.tsbuildinfo +1 -1
- package/dist/bin/leak-runner.js +80 -9
- package/dist/cjs/cli/commands/runCommand.js +7 -2
- package/dist/cjs/config/requiredEnvParams.js +14 -2
- package/dist/cjs/config/runnerConfigLoader.js +6 -3
- package/dist/cjs/config/runnerConfigSchema.js +5 -1
- package/dist/cjs/config/unknownEnvError.js +36 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/runner/scenarioRunner.js +9 -1
- package/dist/cjs/scenarios/one-admin/export-navigation.scenario.js +10 -1
- package/dist/cjs/scenarios/one-admin/page-models/AdminLandingPageModel.js +42 -0
- package/dist/cjs/scenarios/one-admin/page-models/index.js +2 -0
- package/dist/esm/cli/commands/runCommand.js +11 -3
- package/dist/esm/config/requiredEnvParams.js +14 -2
- package/dist/esm/config/runnerConfigLoader.js +6 -3
- package/dist/esm/config/runnerConfigSchema.js +5 -1
- package/dist/esm/config/unknownEnvError.js +16 -0
- package/dist/esm/index.js +3 -1
- package/dist/esm/runner/scenarioRunner.js +9 -1
- package/dist/esm/scenarios/one-admin/export-navigation.scenario.js +11 -1
- package/dist/esm/scenarios/one-admin/page-models/AdminLandingPageModel.js +22 -0
- package/dist/esm/scenarios/one-admin/page-models/index.js +2 -0
- package/dist/types/lib/config/requiredEnvParams.d.ts +4 -1
- package/dist/types/lib/config/runnerConfigLoader.d.ts +1 -0
- package/dist/types/lib/config/runnerConfigSchema.d.ts +7 -0
- package/dist/types/lib/config/unknownEnvError.d.ts +5 -0
- package/dist/types/lib/index.d.ts +1 -1
- package/dist/types/lib/runner/aiEnhancementStep.d.ts +4 -3
- package/dist/types/lib/scenarios/one-admin/page-models/AdminLandingPageModel.d.ts +8 -0
- package/dist/types/lib/scenarios/one-admin/page-models/index.d.ts +1 -0
- package/dist/types/lib/types/scenario.d.ts +1 -0
- package/leak-runner.config.json +18 -0
- package/leak-runner.schema.json +5 -0
- package/lib/cli/commands/runCommand.ts +15 -2
- package/lib/config/requiredEnvParams.ts +15 -2
- package/lib/config/runnerConfigLoader.ts +12 -5
- package/lib/config/runnerConfigSchema.ts +4 -0
- package/lib/config/tests/fileConfigSource.test.ts +26 -0
- package/lib/config/tests/requiredEnvParams.test.ts +90 -2
- package/lib/config/tests/runnerConfigLoader.test.ts +30 -0
- package/lib/config/unknownEnvError.ts +13 -0
- package/lib/index.ts +1 -0
- package/lib/runner/aiEnhancementStep.ts +4 -3
- package/lib/runner/scenarioRunner.ts +8 -1
- package/lib/scenarios/one-admin/export-navigation.scenario.ts +13 -1
- package/lib/scenarios/one-admin/page-models/AdminLandingPageModel.ts +24 -0
- package/lib/scenarios/one-admin/page-models/index.ts +1 -0
- package/lib/types/scenario.ts +1 -0
- package/package.json +3 -3
- package/reports/analysis/index.html +1 -1
- package/reports/analysis/thresholdEvaluator.ts.html +1 -1
- package/reports/browser/iframeHeapProfiler.ts.html +1 -1
- package/reports/browser/index.html +1 -1
- package/reports/cli/commands/index.html +3 -3
- package/reports/cli/commands/listCommand.ts.html +1 -1
- package/reports/cli/commands/runCommand.ts.html +44 -5
- package/reports/cli/index.html +1 -1
- package/reports/cli/index.ts.html +1 -1
- package/reports/config/index.html +36 -21
- package/reports/config/missingRequiredParamError.ts.html +4 -4
- package/reports/config/requiredEnvParams.ts.html +67 -28
- package/reports/config/runnerConfigLoader.ts.html +38 -17
- package/reports/config/runnerConfigSchema.ts.html +18 -6
- package/reports/config/sources/cliOverrideConfigSource.ts.html +1 -1
- package/reports/config/sources/configSource.ts.html +2 -2
- package/reports/config/sources/envVarConfigSource.ts.html +1 -1
- package/reports/config/sources/fileConfigSource.ts.html +13 -13
- package/reports/config/sources/index.html +1 -1
- package/reports/config/unknownEnvError.ts.html +124 -0
- package/reports/index.html +35 -35
- package/reports/lcov-report/analysis/index.html +1 -1
- package/reports/lcov-report/analysis/thresholdEvaluator.ts.html +1 -1
- package/reports/lcov-report/browser/iframeHeapProfiler.ts.html +1 -1
- package/reports/lcov-report/browser/index.html +1 -1
- package/reports/lcov-report/cli/commands/index.html +3 -3
- package/reports/lcov-report/cli/commands/listCommand.ts.html +1 -1
- package/reports/lcov-report/cli/commands/runCommand.ts.html +44 -5
- package/reports/lcov-report/cli/index.html +1 -1
- package/reports/lcov-report/cli/index.ts.html +1 -1
- package/reports/lcov-report/config/index.html +36 -21
- package/reports/lcov-report/config/missingRequiredParamError.ts.html +4 -4
- package/reports/lcov-report/config/requiredEnvParams.ts.html +67 -28
- package/reports/lcov-report/config/runnerConfigLoader.ts.html +38 -17
- package/reports/lcov-report/config/runnerConfigSchema.ts.html +18 -6
- package/reports/lcov-report/config/sources/cliOverrideConfigSource.ts.html +1 -1
- package/reports/lcov-report/config/sources/configSource.ts.html +2 -2
- package/reports/lcov-report/config/sources/envVarConfigSource.ts.html +1 -1
- package/reports/lcov-report/config/sources/fileConfigSource.ts.html +13 -13
- package/reports/lcov-report/config/sources/index.html +1 -1
- package/reports/lcov-report/config/unknownEnvError.ts.html +124 -0
- package/reports/lcov-report/index.html +35 -35
- package/reports/lcov-report/registry/index.html +1 -1
- package/reports/lcov-report/registry/scenarioRegistry.ts.html +1 -1
- package/reports/lcov-report/reporting/consoleReporter.ts.html +1 -1
- package/reports/lcov-report/reporting/index.html +1 -1
- package/reports/lcov-report/reporting/junitReporter.ts.html +1 -1
- package/reports/lcov-report/runner/aiEnhancementStep.ts.html +8 -5
- package/reports/lcov-report/runner/batchRunner.ts.html +1 -1
- package/reports/lcov-report/runner/index.html +15 -15
- package/reports/lcov-report/runner/scenarioRunner.ts.html +32 -11
- package/reports/lcov-report/scenarios/index.html +1 -1
- package/reports/lcov-report/scenarios/index.ts.html +1 -1
- package/reports/lcov-report/scenarios/one-admin/export-navigation.scenario.ts.html +44 -8
- package/reports/lcov-report/scenarios/one-admin/index.html +11 -11
- package/reports/lcov-report/scenarios/one-admin/index.ts.html +1 -1
- package/reports/lcov-report/scenarios/one-admin/page-models/AdminLandingPageModel.ts.html +157 -0
- package/reports/lcov-report/scenarios/one-admin/page-models/ExportPageModel.ts.html +1 -1
- package/reports/lcov-report/scenarios/one-admin/page-models/SelectSettingsPageModel.ts.html +1 -1
- package/reports/lcov-report/scenarios/one-admin/page-models/index.html +19 -4
- package/reports/lcov-report/types/config.ts.html +1 -1
- package/reports/lcov-report/types/index.html +1 -1
- package/reports/lcov.info +302 -230
- package/reports/registry/index.html +1 -1
- package/reports/registry/scenarioRegistry.ts.html +1 -1
- package/reports/reporting/consoleReporter.ts.html +1 -1
- package/reports/reporting/index.html +1 -1
- package/reports/reporting/junitReporter.ts.html +1 -1
- package/reports/runner/aiEnhancementStep.ts.html +8 -5
- package/reports/runner/batchRunner.ts.html +1 -1
- package/reports/runner/index.html +15 -15
- package/reports/runner/scenarioRunner.ts.html +32 -11
- package/reports/scenarios/index.html +1 -1
- package/reports/scenarios/index.ts.html +1 -1
- package/reports/scenarios/one-admin/export-navigation.scenario.ts.html +44 -8
- package/reports/scenarios/one-admin/index.html +11 -11
- package/reports/scenarios/one-admin/index.ts.html +1 -1
- package/reports/scenarios/one-admin/page-models/AdminLandingPageModel.ts.html +157 -0
- package/reports/scenarios/one-admin/page-models/ExportPageModel.ts.html +1 -1
- package/reports/scenarios/one-admin/page-models/SelectSettingsPageModel.ts.html +1 -1
- package/reports/scenarios/one-admin/page-models/index.html +19 -4
- package/reports/types/config.ts.html +1 -1
- package/reports/types/index.html +1 -1
- package/test-report.xml +75 -62
package/dist/bin/leak-runner.js
CHANGED
|
@@ -140,6 +140,7 @@ var ScenarioRunner = class {
|
|
|
140
140
|
scenario,
|
|
141
141
|
snapshotsDir
|
|
142
142
|
);
|
|
143
|
+
if (scenario.setup) await scenario.setup(page, frame);
|
|
143
144
|
paths.before = await profiler.captureSnapshot("before");
|
|
144
145
|
await this.repeatScenarioActions(scenario, page, frame);
|
|
145
146
|
await forceGarbageCollection(page);
|
|
@@ -156,12 +157,19 @@ var ScenarioRunner = class {
|
|
|
156
157
|
const auth = new AuthManager();
|
|
157
158
|
const pageSetup = new PageSetup();
|
|
158
159
|
await pageSetup.apply(page);
|
|
160
|
+
await page.unroute(PageSetup.BLOCKED_PATTERN);
|
|
159
161
|
await auth.login(page, {
|
|
160
162
|
username: this.config.env.userId,
|
|
161
163
|
password: this.config.env.password,
|
|
162
164
|
instanceId: this.config.env.instanceId
|
|
163
165
|
});
|
|
164
|
-
|
|
166
|
+
process.stderr.write(`[scenarioRunner] post-login URL = ${page.url()}
|
|
167
|
+
`);
|
|
168
|
+
await page.waitForURL(`**${scenario.url()}**`, { timeout: 3e4 });
|
|
169
|
+
process.stderr.write(
|
|
170
|
+
`[scenarioRunner] settled URL before iframe = ${page.url()}
|
|
171
|
+
`
|
|
172
|
+
);
|
|
165
173
|
const frame = await resolveIframe(page, scenario.microappSelector);
|
|
166
174
|
fs.mkdirSync(snapshotsDir, { recursive: true });
|
|
167
175
|
const profiler = new IframeHeapProfiler(page, frame, snapshotsDir);
|
|
@@ -403,9 +411,12 @@ var aiConfigFileSchema = z.object({
|
|
|
403
411
|
model: z.string().min(1),
|
|
404
412
|
temperature: z.number().min(0).max(2)
|
|
405
413
|
}).partial();
|
|
414
|
+
var envsSchema = z.record(z.string().min(1));
|
|
406
415
|
var runnerConfigFileSchema = z.object({
|
|
416
|
+
$schema: z.string().optional(),
|
|
407
417
|
runner: runnerOptionsSchema,
|
|
408
|
-
ai: aiConfigFileSchema
|
|
418
|
+
ai: aiConfigFileSchema,
|
|
419
|
+
envs: envsSchema
|
|
409
420
|
}).partial().strict();
|
|
410
421
|
|
|
411
422
|
// lib/config/sources/fileConfigSource.ts
|
|
@@ -469,7 +480,8 @@ function applySource(acc, source) {
|
|
|
469
480
|
const payload = source.load();
|
|
470
481
|
return {
|
|
471
482
|
runner: payload.runner ? applyRunnerPayload(acc.runner, payload.runner) : acc.runner,
|
|
472
|
-
ai: payload.ai ? applyAiPayload(acc.ai, payload.ai) : acc.ai
|
|
483
|
+
ai: payload.ai ? applyAiPayload(acc.ai, payload.ai) : acc.ai,
|
|
484
|
+
envs: payload.envs ? { ...acc.envs, ...payload.envs } : acc.envs
|
|
473
485
|
};
|
|
474
486
|
}
|
|
475
487
|
var RunnerConfigLoader = class {
|
|
@@ -488,14 +500,16 @@ var RunnerConfigLoader = class {
|
|
|
488
500
|
aiEnabled: BUILT_IN_DEFAULTS.ai.enabled ?? false,
|
|
489
501
|
aiModel: BUILT_IN_DEFAULTS.ai.model ?? "Claude3.7",
|
|
490
502
|
aiTemperature: BUILT_IN_DEFAULTS.ai.temperature ?? 0.3
|
|
491
|
-
}
|
|
503
|
+
},
|
|
504
|
+
envs: {}
|
|
492
505
|
};
|
|
493
506
|
const resolved = ordered.reduce(applySource, initial);
|
|
494
507
|
return {
|
|
495
508
|
runner: resolved.runner,
|
|
496
509
|
aiEnabled: resolved.ai.aiEnabled,
|
|
497
510
|
aiModel: resolved.ai.aiModel,
|
|
498
|
-
aiTemperature: resolved.ai.aiTemperature
|
|
511
|
+
aiTemperature: resolved.ai.aiTemperature,
|
|
512
|
+
envs: resolved.envs
|
|
499
513
|
};
|
|
500
514
|
}
|
|
501
515
|
};
|
|
@@ -512,6 +526,19 @@ Provide via CLI flag (--base-url / --instance-id / --user-id) or env var (BASE_U
|
|
|
512
526
|
}
|
|
513
527
|
};
|
|
514
528
|
|
|
529
|
+
// lib/config/unknownEnvError.ts
|
|
530
|
+
var UnknownEnvError = class extends Error {
|
|
531
|
+
constructor(name, knownEnvs) {
|
|
532
|
+
const knownList = knownEnvs.length > 0 ? knownEnvs.join(", ") : "(none defined)";
|
|
533
|
+
super(
|
|
534
|
+
`Unknown env "${name}". Known envs in leak-runner.config.json: ${knownList}.`
|
|
535
|
+
);
|
|
536
|
+
this.name = name;
|
|
537
|
+
this.knownEnvs = knownEnvs;
|
|
538
|
+
this.name = "UnknownEnvError";
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
|
|
515
542
|
// lib/config/requiredEnvParams.ts
|
|
516
543
|
var RequiredEnvParamsResolver = class {
|
|
517
544
|
resolve(cliOpts) {
|
|
@@ -524,8 +551,18 @@ var RequiredEnvParamsResolver = class {
|
|
|
524
551
|
if (missing.length > 0) throw new MissingRequiredParamError(missing);
|
|
525
552
|
return params;
|
|
526
553
|
}
|
|
554
|
+
// Precedence: --base-url > BASE_URL env > --env / ENCW_ENV map lookup.
|
|
555
|
+
// Throws UnknownEnvError when an env name is supplied but not in the map,
|
|
556
|
+
// so a typo fails loudly instead of silently falling through to "missing baseUrl".
|
|
527
557
|
resolveBaseUrl(cliOpts) {
|
|
528
|
-
|
|
558
|
+
if (cliOpts.baseUrl) return cliOpts.baseUrl;
|
|
559
|
+
if (process.env.BASE_URL) return process.env.BASE_URL;
|
|
560
|
+
const envName = cliOpts.env || process.env.ENCW_ENV;
|
|
561
|
+
if (!envName) return "";
|
|
562
|
+
const envs = cliOpts.envs ?? {};
|
|
563
|
+
const fromMap = envs[envName];
|
|
564
|
+
if (!fromMap) throw new UnknownEnvError(envName, Object.keys(envs));
|
|
565
|
+
return fromMap;
|
|
529
566
|
}
|
|
530
567
|
resolveInstanceId(cliOpts) {
|
|
531
568
|
return cliOpts.instanceId || process.env.ENCW_INSTANCE_ID || "";
|
|
@@ -551,7 +588,10 @@ var RunCommand = class {
|
|
|
551
588
|
register(program, deps) {
|
|
552
589
|
program.command("run [key]").description(
|
|
553
590
|
"Run a scenario by `<microapp>/<id>`, or use --all / --tag to run multiple"
|
|
554
|
-
).option("--all", "Run all registered scenarios").option("--tag <tag>", "Run all scenarios matching a tag").option("--base-url <url>", "Override base URL").option(
|
|
591
|
+
).option("--all", "Run all registered scenarios").option("--tag <tag>", "Run all scenarios matching a tag").option("--base-url <url>", "Override base URL").option(
|
|
592
|
+
"--env <name>",
|
|
593
|
+
"Select a named environment from leak-runner.config.json envs (also reads ENCW_ENV)"
|
|
594
|
+
).option("--instance-id <id>", "Override instance ID").option("--user-id <id>", "Override user ID").option("--output-dir <dir>", "Override output directory").option(
|
|
555
595
|
"--top-n <n>",
|
|
556
596
|
"Override top-N for heap comparison",
|
|
557
597
|
(v) => parseInt(v, 10)
|
|
@@ -568,7 +608,7 @@ var RunCommand = class {
|
|
|
568
608
|
await new JunitReporter().write(summary, config.runner.outputDir);
|
|
569
609
|
process.exit(summary.failCount > 0 ? 1 : 0);
|
|
570
610
|
} catch (err) {
|
|
571
|
-
if (err instanceof MissingRequiredParamError) {
|
|
611
|
+
if (err instanceof MissingRequiredParamError || err instanceof UnknownEnvError) {
|
|
572
612
|
process.stderr.write(`Configuration error: ${err.message}
|
|
573
613
|
`);
|
|
574
614
|
process.exit(2);
|
|
@@ -593,6 +633,8 @@ var RunCommand = class {
|
|
|
593
633
|
const resolved = loader.resolveOptions();
|
|
594
634
|
const env = deps.envParams.resolve({
|
|
595
635
|
baseUrl: options.baseUrl,
|
|
636
|
+
env: options.env,
|
|
637
|
+
envs: resolved.envs,
|
|
596
638
|
instanceId: options.instanceId,
|
|
597
639
|
userId: options.userId
|
|
598
640
|
});
|
|
@@ -684,6 +726,26 @@ var ScenarioRegistry = class {
|
|
|
684
726
|
}
|
|
685
727
|
};
|
|
686
728
|
|
|
729
|
+
// lib/scenarios/one-admin/page-models/AdminLandingPageModel.ts
|
|
730
|
+
var AdminLandingPageModel = class {
|
|
731
|
+
constructor(frame) {
|
|
732
|
+
this.frame = frame;
|
|
733
|
+
}
|
|
734
|
+
get oneAdminConsoleOption() {
|
|
735
|
+
return this.frame.getByText("ONE ADMIN CONSOLE");
|
|
736
|
+
}
|
|
737
|
+
async clickOneAdminConsole() {
|
|
738
|
+
await this.oneAdminConsoleOption.click();
|
|
739
|
+
}
|
|
740
|
+
static async acceptCookiesIfShown(page) {
|
|
741
|
+
try {
|
|
742
|
+
await page.locator("#onetrust-group-container").waitFor({ state: "visible", timeout: 5e3 });
|
|
743
|
+
await page.locator("button", { hasText: "Accept All Cookies" }).click();
|
|
744
|
+
} catch {
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
};
|
|
748
|
+
|
|
687
749
|
// lib/scenarios/one-admin/page-models/SelectSettingsPageModel.ts
|
|
688
750
|
var SelectSettingsPageModel = class {
|
|
689
751
|
constructor(frame) {
|
|
@@ -737,8 +799,17 @@ var exportNavigationScenario = {
|
|
|
737
799
|
description: "Navigate to export page and come back - verify iframe GC",
|
|
738
800
|
tags: ["critical"],
|
|
739
801
|
microappSelector: "iframe#pui-iframe-container-emAdminUI",
|
|
740
|
-
url: () => "/admin
|
|
802
|
+
url: () => "/admin",
|
|
803
|
+
async setup(page) {
|
|
804
|
+
await AdminLandingPageModel.acceptCookiesIfShown(page);
|
|
805
|
+
},
|
|
741
806
|
async action(page, frame) {
|
|
807
|
+
const path3 = new URL(page.url()).pathname.replace(/\/$/, "");
|
|
808
|
+
if (path3 === "/admin") {
|
|
809
|
+
const adminLanding = new AdminLandingPageModel(frame);
|
|
810
|
+
await adminLanding.oneAdminConsoleOption.waitFor({ state: "visible" });
|
|
811
|
+
await adminLanding.clickOneAdminConsole();
|
|
812
|
+
}
|
|
742
813
|
const settings = new SelectSettingsPageModel(frame);
|
|
743
814
|
await settings.container.waitFor({ state: "visible" });
|
|
744
815
|
await settings.expandTreeItem("eFolder");
|
|
@@ -33,7 +33,10 @@ class RunCommand {
|
|
|
33
33
|
register(program, deps) {
|
|
34
34
|
program.command("run [key]").description(
|
|
35
35
|
"Run a scenario by `<microapp>/<id>`, or use --all / --tag to run multiple"
|
|
36
|
-
).option("--all", "Run all registered scenarios").option("--tag <tag>", "Run all scenarios matching a tag").option("--base-url <url>", "Override base URL").option(
|
|
36
|
+
).option("--all", "Run all registered scenarios").option("--tag <tag>", "Run all scenarios matching a tag").option("--base-url <url>", "Override base URL").option(
|
|
37
|
+
"--env <name>",
|
|
38
|
+
"Select a named environment from leak-runner.config.json envs (also reads ENCW_ENV)"
|
|
39
|
+
).option("--instance-id <id>", "Override instance ID").option("--user-id <id>", "Override user ID").option("--output-dir <dir>", "Override output directory").option(
|
|
37
40
|
"--top-n <n>",
|
|
38
41
|
"Override top-N for heap comparison",
|
|
39
42
|
(v) => parseInt(v, 10)
|
|
@@ -50,7 +53,7 @@ class RunCommand {
|
|
|
50
53
|
await new import_junitReporter.JunitReporter().write(summary, config.runner.outputDir);
|
|
51
54
|
process.exit(summary.failCount > 0 ? 1 : 0);
|
|
52
55
|
} catch (err) {
|
|
53
|
-
if (err instanceof import_requiredEnvParams.MissingRequiredParamError) {
|
|
56
|
+
if (err instanceof import_requiredEnvParams.MissingRequiredParamError || err instanceof import_requiredEnvParams.UnknownEnvError) {
|
|
54
57
|
process.stderr.write(`Configuration error: ${err.message}
|
|
55
58
|
`);
|
|
56
59
|
process.exit(2);
|
|
@@ -75,6 +78,8 @@ class RunCommand {
|
|
|
75
78
|
const resolved = loader.resolveOptions();
|
|
76
79
|
const env = deps.envParams.resolve({
|
|
77
80
|
baseUrl: options.baseUrl,
|
|
81
|
+
env: options.env,
|
|
82
|
+
envs: resolved.envs,
|
|
78
83
|
instanceId: options.instanceId,
|
|
79
84
|
userId: options.userId
|
|
80
85
|
});
|
|
@@ -19,10 +19,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var requiredEnvParams_exports = {};
|
|
20
20
|
__export(requiredEnvParams_exports, {
|
|
21
21
|
MissingRequiredParamError: () => import_missingRequiredParamError.MissingRequiredParamError,
|
|
22
|
-
RequiredEnvParamsResolver: () => RequiredEnvParamsResolver
|
|
22
|
+
RequiredEnvParamsResolver: () => RequiredEnvParamsResolver,
|
|
23
|
+
UnknownEnvError: () => import_unknownEnvError.UnknownEnvError
|
|
23
24
|
});
|
|
24
25
|
module.exports = __toCommonJS(requiredEnvParams_exports);
|
|
25
26
|
var import_missingRequiredParamError = require("./missingRequiredParamError.js");
|
|
27
|
+
var import_unknownEnvError = require("./unknownEnvError.js");
|
|
26
28
|
class RequiredEnvParamsResolver {
|
|
27
29
|
resolve(cliOpts) {
|
|
28
30
|
const baseUrl = this.resolveBaseUrl(cliOpts);
|
|
@@ -34,8 +36,18 @@ class RequiredEnvParamsResolver {
|
|
|
34
36
|
if (missing.length > 0) throw new import_missingRequiredParamError.MissingRequiredParamError(missing);
|
|
35
37
|
return params;
|
|
36
38
|
}
|
|
39
|
+
// Precedence: --base-url > BASE_URL env > --env / ENCW_ENV map lookup.
|
|
40
|
+
// Throws UnknownEnvError when an env name is supplied but not in the map,
|
|
41
|
+
// so a typo fails loudly instead of silently falling through to "missing baseUrl".
|
|
37
42
|
resolveBaseUrl(cliOpts) {
|
|
38
|
-
|
|
43
|
+
if (cliOpts.baseUrl) return cliOpts.baseUrl;
|
|
44
|
+
if (process.env.BASE_URL) return process.env.BASE_URL;
|
|
45
|
+
const envName = cliOpts.env || process.env.ENCW_ENV;
|
|
46
|
+
if (!envName) return "";
|
|
47
|
+
const envs = cliOpts.envs ?? {};
|
|
48
|
+
const fromMap = envs[envName];
|
|
49
|
+
if (!fromMap) throw new import_unknownEnvError.UnknownEnvError(envName, Object.keys(envs));
|
|
50
|
+
return fromMap;
|
|
39
51
|
}
|
|
40
52
|
resolveInstanceId(cliOpts) {
|
|
41
53
|
return cliOpts.instanceId || process.env.ENCW_INSTANCE_ID || "";
|
|
@@ -40,7 +40,8 @@ function applySource(acc, source) {
|
|
|
40
40
|
const payload = source.load();
|
|
41
41
|
return {
|
|
42
42
|
runner: payload.runner ? applyRunnerPayload(acc.runner, payload.runner) : acc.runner,
|
|
43
|
-
ai: payload.ai ? applyAiPayload(acc.ai, payload.ai) : acc.ai
|
|
43
|
+
ai: payload.ai ? applyAiPayload(acc.ai, payload.ai) : acc.ai,
|
|
44
|
+
envs: payload.envs ? { ...acc.envs, ...payload.envs } : acc.envs
|
|
44
45
|
};
|
|
45
46
|
}
|
|
46
47
|
class RunnerConfigLoader {
|
|
@@ -60,14 +61,16 @@ class RunnerConfigLoader {
|
|
|
60
61
|
aiEnabled: import_configSource.BUILT_IN_DEFAULTS.ai.enabled ?? false,
|
|
61
62
|
aiModel: import_configSource.BUILT_IN_DEFAULTS.ai.model ?? "Claude3.7",
|
|
62
63
|
aiTemperature: import_configSource.BUILT_IN_DEFAULTS.ai.temperature ?? 0.3
|
|
63
|
-
}
|
|
64
|
+
},
|
|
65
|
+
envs: {}
|
|
64
66
|
};
|
|
65
67
|
const resolved = ordered.reduce(applySource, initial);
|
|
66
68
|
return {
|
|
67
69
|
runner: resolved.runner,
|
|
68
70
|
aiEnabled: resolved.ai.aiEnabled,
|
|
69
71
|
aiModel: resolved.ai.aiModel,
|
|
70
|
-
aiTemperature: resolved.ai.aiTemperature
|
|
72
|
+
aiTemperature: resolved.ai.aiTemperature,
|
|
73
|
+
envs: resolved.envs
|
|
71
74
|
};
|
|
72
75
|
}
|
|
73
76
|
}
|
|
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var runnerConfigSchema_exports = {};
|
|
20
20
|
__export(runnerConfigSchema_exports, {
|
|
21
21
|
aiConfigFileSchema: () => aiConfigFileSchema,
|
|
22
|
+
envsSchema: () => envsSchema,
|
|
22
23
|
runnerConfigFileSchema: () => runnerConfigFileSchema,
|
|
23
24
|
runnerOptionsSchema: () => runnerOptionsSchema
|
|
24
25
|
});
|
|
@@ -34,7 +35,10 @@ const aiConfigFileSchema = import_zod.z.object({
|
|
|
34
35
|
model: import_zod.z.string().min(1),
|
|
35
36
|
temperature: import_zod.z.number().min(0).max(2)
|
|
36
37
|
}).partial();
|
|
38
|
+
const envsSchema = import_zod.z.record(import_zod.z.string().min(1));
|
|
37
39
|
const runnerConfigFileSchema = import_zod.z.object({
|
|
40
|
+
$schema: import_zod.z.string().optional(),
|
|
38
41
|
runner: runnerOptionsSchema,
|
|
39
|
-
ai: aiConfigFileSchema
|
|
42
|
+
ai: aiConfigFileSchema,
|
|
43
|
+
envs: envsSchema
|
|
40
44
|
}).partial().strict();
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var unknownEnvError_exports = {};
|
|
20
|
+
__export(unknownEnvError_exports, {
|
|
21
|
+
UnknownEnvError: () => UnknownEnvError
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(unknownEnvError_exports);
|
|
24
|
+
class UnknownEnvError extends Error {
|
|
25
|
+
constructor(name, knownEnvs) {
|
|
26
|
+
const knownList = knownEnvs.length > 0 ? knownEnvs.join(", ") : "(none defined)";
|
|
27
|
+
super(
|
|
28
|
+
`Unknown env "${name}". Known envs in leak-runner.config.json: ${knownList}.`
|
|
29
|
+
);
|
|
30
|
+
this.name = name;
|
|
31
|
+
this.knownEnvs = knownEnvs;
|
|
32
|
+
this.name = "UnknownEnvError";
|
|
33
|
+
}
|
|
34
|
+
name;
|
|
35
|
+
knownEnvs;
|
|
36
|
+
}
|
package/dist/cjs/index.js
CHANGED
|
@@ -32,6 +32,7 @@ __export(index_exports, {
|
|
|
32
32
|
ScenarioRegistry: () => import_scenarioRegistry.ScenarioRegistry,
|
|
33
33
|
ScenarioRunner: () => import_scenarioRunner.ScenarioRunner,
|
|
34
34
|
ThresholdEvaluator: () => import_thresholdEvaluator.ThresholdEvaluator,
|
|
35
|
+
UnknownEnvError: () => import_requiredEnvParams.UnknownEnvError,
|
|
35
36
|
buildProgram: () => import_cli.buildProgram,
|
|
36
37
|
defaultDeps: () => import_cli.defaultDeps
|
|
37
38
|
});
|
|
@@ -93,6 +93,7 @@ class ScenarioRunner {
|
|
|
93
93
|
scenario,
|
|
94
94
|
snapshotsDir
|
|
95
95
|
);
|
|
96
|
+
if (scenario.setup) await scenario.setup(page, frame);
|
|
96
97
|
paths.before = await profiler.captureSnapshot("before");
|
|
97
98
|
await this.repeatScenarioActions(scenario, page, frame);
|
|
98
99
|
await forceGarbageCollection(page);
|
|
@@ -109,12 +110,19 @@ class ScenarioRunner {
|
|
|
109
110
|
const auth = new import_smoked_suite.AuthManager();
|
|
110
111
|
const pageSetup = new import_smoked_suite.PageSetup();
|
|
111
112
|
await pageSetup.apply(page);
|
|
113
|
+
await page.unroute(import_smoked_suite.PageSetup.BLOCKED_PATTERN);
|
|
112
114
|
await auth.login(page, {
|
|
113
115
|
username: this.config.env.userId,
|
|
114
116
|
password: this.config.env.password,
|
|
115
117
|
instanceId: this.config.env.instanceId
|
|
116
118
|
});
|
|
117
|
-
|
|
119
|
+
process.stderr.write(`[scenarioRunner] post-login URL = ${page.url()}
|
|
120
|
+
`);
|
|
121
|
+
await page.waitForURL(`**${scenario.url()}**`, { timeout: 3e4 });
|
|
122
|
+
process.stderr.write(
|
|
123
|
+
`[scenarioRunner] settled URL before iframe = ${page.url()}
|
|
124
|
+
`
|
|
125
|
+
);
|
|
118
126
|
const frame = await resolveIframe(page, scenario.microappSelector);
|
|
119
127
|
import_node_fs.default.mkdirSync(snapshotsDir, { recursive: true });
|
|
120
128
|
const profiler = new import_iframeHeapProfiler.IframeHeapProfiler(page, frame, snapshotsDir);
|
|
@@ -28,8 +28,17 @@ const exportNavigationScenario = {
|
|
|
28
28
|
description: "Navigate to export page and come back - verify iframe GC",
|
|
29
29
|
tags: ["critical"],
|
|
30
30
|
microappSelector: "iframe#pui-iframe-container-emAdminUI",
|
|
31
|
-
url: () => "/admin
|
|
31
|
+
url: () => "/admin",
|
|
32
|
+
async setup(page) {
|
|
33
|
+
await import_page_models.AdminLandingPageModel.acceptCookiesIfShown(page);
|
|
34
|
+
},
|
|
32
35
|
async action(page, frame) {
|
|
36
|
+
const path = new URL(page.url()).pathname.replace(/\/$/, "");
|
|
37
|
+
if (path === "/admin") {
|
|
38
|
+
const adminLanding = new import_page_models.AdminLandingPageModel(frame);
|
|
39
|
+
await adminLanding.oneAdminConsoleOption.waitFor({ state: "visible" });
|
|
40
|
+
await adminLanding.clickOneAdminConsole();
|
|
41
|
+
}
|
|
33
42
|
const settings = new import_page_models.SelectSettingsPageModel(frame);
|
|
34
43
|
await settings.container.waitFor({ state: "visible" });
|
|
35
44
|
await settings.expandTreeItem("eFolder");
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var AdminLandingPageModel_exports = {};
|
|
20
|
+
__export(AdminLandingPageModel_exports, {
|
|
21
|
+
AdminLandingPageModel: () => AdminLandingPageModel
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(AdminLandingPageModel_exports);
|
|
24
|
+
class AdminLandingPageModel {
|
|
25
|
+
constructor(frame) {
|
|
26
|
+
this.frame = frame;
|
|
27
|
+
}
|
|
28
|
+
frame;
|
|
29
|
+
get oneAdminConsoleOption() {
|
|
30
|
+
return this.frame.getByText("ONE ADMIN CONSOLE");
|
|
31
|
+
}
|
|
32
|
+
async clickOneAdminConsole() {
|
|
33
|
+
await this.oneAdminConsoleOption.click();
|
|
34
|
+
}
|
|
35
|
+
static async acceptCookiesIfShown(page) {
|
|
36
|
+
try {
|
|
37
|
+
await page.locator("#onetrust-group-container").waitFor({ state: "visible", timeout: 5e3 });
|
|
38
|
+
await page.locator("button", { hasText: "Accept All Cookies" }).click();
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -18,9 +18,11 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var page_models_exports = {};
|
|
20
20
|
__export(page_models_exports, {
|
|
21
|
+
AdminLandingPageModel: () => import_AdminLandingPageModel.AdminLandingPageModel,
|
|
21
22
|
ExportPageModel: () => import_ExportPageModel.ExportPageModel,
|
|
22
23
|
SelectSettingsPageModel: () => import_SelectSettingsPageModel.SelectSettingsPageModel
|
|
23
24
|
});
|
|
24
25
|
module.exports = __toCommonJS(page_models_exports);
|
|
26
|
+
var import_AdminLandingPageModel = require("./AdminLandingPageModel.js");
|
|
25
27
|
var import_SelectSettingsPageModel = require("./SelectSettingsPageModel.js");
|
|
26
28
|
var import_ExportPageModel = require("./ExportPageModel.js");
|
|
@@ -7,12 +7,18 @@ import {
|
|
|
7
7
|
import { EnvVarConfigSource } from "../../config/sources/envVarConfigSource.js";
|
|
8
8
|
import { FileConfigSource } from "../../config/sources/fileConfigSource.js";
|
|
9
9
|
import { RunnerConfigLoader } from "../../config/runnerConfigLoader.js";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
MissingRequiredParamError,
|
|
12
|
+
UnknownEnvError
|
|
13
|
+
} from "../../config/requiredEnvParams.js";
|
|
11
14
|
class RunCommand {
|
|
12
15
|
register(program, deps) {
|
|
13
16
|
program.command("run [key]").description(
|
|
14
17
|
"Run a scenario by `<microapp>/<id>`, or use --all / --tag to run multiple"
|
|
15
|
-
).option("--all", "Run all registered scenarios").option("--tag <tag>", "Run all scenarios matching a tag").option("--base-url <url>", "Override base URL").option(
|
|
18
|
+
).option("--all", "Run all registered scenarios").option("--tag <tag>", "Run all scenarios matching a tag").option("--base-url <url>", "Override base URL").option(
|
|
19
|
+
"--env <name>",
|
|
20
|
+
"Select a named environment from leak-runner.config.json envs (also reads ENCW_ENV)"
|
|
21
|
+
).option("--instance-id <id>", "Override instance ID").option("--user-id <id>", "Override user ID").option("--output-dir <dir>", "Override output directory").option(
|
|
16
22
|
"--top-n <n>",
|
|
17
23
|
"Override top-N for heap comparison",
|
|
18
24
|
(v) => parseInt(v, 10)
|
|
@@ -29,7 +35,7 @@ class RunCommand {
|
|
|
29
35
|
await new JunitReporter().write(summary, config.runner.outputDir);
|
|
30
36
|
process.exit(summary.failCount > 0 ? 1 : 0);
|
|
31
37
|
} catch (err) {
|
|
32
|
-
if (err instanceof MissingRequiredParamError) {
|
|
38
|
+
if (err instanceof MissingRequiredParamError || err instanceof UnknownEnvError) {
|
|
33
39
|
process.stderr.write(`Configuration error: ${err.message}
|
|
34
40
|
`);
|
|
35
41
|
process.exit(2);
|
|
@@ -54,6 +60,8 @@ class RunCommand {
|
|
|
54
60
|
const resolved = loader.resolveOptions();
|
|
55
61
|
const env = deps.envParams.resolve({
|
|
56
62
|
baseUrl: options.baseUrl,
|
|
63
|
+
env: options.env,
|
|
64
|
+
envs: resolved.envs,
|
|
57
65
|
instanceId: options.instanceId,
|
|
58
66
|
userId: options.userId
|
|
59
67
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MissingRequiredParamError } from "./missingRequiredParamError.js";
|
|
2
|
+
import { UnknownEnvError } from "./unknownEnvError.js";
|
|
2
3
|
class RequiredEnvParamsResolver {
|
|
3
4
|
resolve(cliOpts) {
|
|
4
5
|
const baseUrl = this.resolveBaseUrl(cliOpts);
|
|
@@ -10,8 +11,18 @@ class RequiredEnvParamsResolver {
|
|
|
10
11
|
if (missing.length > 0) throw new MissingRequiredParamError(missing);
|
|
11
12
|
return params;
|
|
12
13
|
}
|
|
14
|
+
// Precedence: --base-url > BASE_URL env > --env / ENCW_ENV map lookup.
|
|
15
|
+
// Throws UnknownEnvError when an env name is supplied but not in the map,
|
|
16
|
+
// so a typo fails loudly instead of silently falling through to "missing baseUrl".
|
|
13
17
|
resolveBaseUrl(cliOpts) {
|
|
14
|
-
|
|
18
|
+
if (cliOpts.baseUrl) return cliOpts.baseUrl;
|
|
19
|
+
if (process.env.BASE_URL) return process.env.BASE_URL;
|
|
20
|
+
const envName = cliOpts.env || process.env.ENCW_ENV;
|
|
21
|
+
if (!envName) return "";
|
|
22
|
+
const envs = cliOpts.envs ?? {};
|
|
23
|
+
const fromMap = envs[envName];
|
|
24
|
+
if (!fromMap) throw new UnknownEnvError(envName, Object.keys(envs));
|
|
25
|
+
return fromMap;
|
|
15
26
|
}
|
|
16
27
|
resolveInstanceId(cliOpts) {
|
|
17
28
|
return cliOpts.instanceId || process.env.ENCW_INSTANCE_ID || "";
|
|
@@ -33,5 +44,6 @@ class RequiredEnvParamsResolver {
|
|
|
33
44
|
}
|
|
34
45
|
export {
|
|
35
46
|
MissingRequiredParamError,
|
|
36
|
-
RequiredEnvParamsResolver
|
|
47
|
+
RequiredEnvParamsResolver,
|
|
48
|
+
UnknownEnvError
|
|
37
49
|
};
|
|
@@ -17,7 +17,8 @@ function applySource(acc, source) {
|
|
|
17
17
|
const payload = source.load();
|
|
18
18
|
return {
|
|
19
19
|
runner: payload.runner ? applyRunnerPayload(acc.runner, payload.runner) : acc.runner,
|
|
20
|
-
ai: payload.ai ? applyAiPayload(acc.ai, payload.ai) : acc.ai
|
|
20
|
+
ai: payload.ai ? applyAiPayload(acc.ai, payload.ai) : acc.ai,
|
|
21
|
+
envs: payload.envs ? { ...acc.envs, ...payload.envs } : acc.envs
|
|
21
22
|
};
|
|
22
23
|
}
|
|
23
24
|
class RunnerConfigLoader {
|
|
@@ -37,14 +38,16 @@ class RunnerConfigLoader {
|
|
|
37
38
|
aiEnabled: BUILT_IN_DEFAULTS.ai.enabled ?? false,
|
|
38
39
|
aiModel: BUILT_IN_DEFAULTS.ai.model ?? "Claude3.7",
|
|
39
40
|
aiTemperature: BUILT_IN_DEFAULTS.ai.temperature ?? 0.3
|
|
40
|
-
}
|
|
41
|
+
},
|
|
42
|
+
envs: {}
|
|
41
43
|
};
|
|
42
44
|
const resolved = ordered.reduce(applySource, initial);
|
|
43
45
|
return {
|
|
44
46
|
runner: resolved.runner,
|
|
45
47
|
aiEnabled: resolved.ai.aiEnabled,
|
|
46
48
|
aiModel: resolved.ai.aiModel,
|
|
47
|
-
aiTemperature: resolved.ai.aiTemperature
|
|
49
|
+
aiTemperature: resolved.ai.aiTemperature,
|
|
50
|
+
envs: resolved.envs
|
|
48
51
|
};
|
|
49
52
|
}
|
|
50
53
|
}
|
|
@@ -9,12 +9,16 @@ const aiConfigFileSchema = z.object({
|
|
|
9
9
|
model: z.string().min(1),
|
|
10
10
|
temperature: z.number().min(0).max(2)
|
|
11
11
|
}).partial();
|
|
12
|
+
const envsSchema = z.record(z.string().min(1));
|
|
12
13
|
const runnerConfigFileSchema = z.object({
|
|
14
|
+
$schema: z.string().optional(),
|
|
13
15
|
runner: runnerOptionsSchema,
|
|
14
|
-
ai: aiConfigFileSchema
|
|
16
|
+
ai: aiConfigFileSchema,
|
|
17
|
+
envs: envsSchema
|
|
15
18
|
}).partial().strict();
|
|
16
19
|
export {
|
|
17
20
|
aiConfigFileSchema,
|
|
21
|
+
envsSchema,
|
|
18
22
|
runnerConfigFileSchema,
|
|
19
23
|
runnerOptionsSchema
|
|
20
24
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class UnknownEnvError extends Error {
|
|
2
|
+
constructor(name, knownEnvs) {
|
|
3
|
+
const knownList = knownEnvs.length > 0 ? knownEnvs.join(", ") : "(none defined)";
|
|
4
|
+
super(
|
|
5
|
+
`Unknown env "${name}". Known envs in leak-runner.config.json: ${knownList}.`
|
|
6
|
+
);
|
|
7
|
+
this.name = name;
|
|
8
|
+
this.knownEnvs = knownEnvs;
|
|
9
|
+
this.name = "UnknownEnvError";
|
|
10
|
+
}
|
|
11
|
+
name;
|
|
12
|
+
knownEnvs;
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
UnknownEnvError
|
|
16
|
+
};
|
package/dist/esm/index.js
CHANGED
|
@@ -12,7 +12,8 @@ import { EnvVarConfigSource } from "./config/sources/envVarConfigSource.js";
|
|
|
12
12
|
import { CliOverrideConfigSource } from "./config/sources/cliOverrideConfigSource.js";
|
|
13
13
|
import {
|
|
14
14
|
RequiredEnvParamsResolver,
|
|
15
|
-
MissingRequiredParamError
|
|
15
|
+
MissingRequiredParamError,
|
|
16
|
+
UnknownEnvError
|
|
16
17
|
} from "./config/requiredEnvParams.js";
|
|
17
18
|
import { buildProgram, defaultDeps } from "./cli/index.js";
|
|
18
19
|
export {
|
|
@@ -30,6 +31,7 @@ export {
|
|
|
30
31
|
ScenarioRegistry,
|
|
31
32
|
ScenarioRunner,
|
|
32
33
|
ThresholdEvaluator,
|
|
34
|
+
UnknownEnvError,
|
|
33
35
|
buildProgram,
|
|
34
36
|
defaultDeps
|
|
35
37
|
};
|
|
@@ -62,6 +62,7 @@ class ScenarioRunner {
|
|
|
62
62
|
scenario,
|
|
63
63
|
snapshotsDir
|
|
64
64
|
);
|
|
65
|
+
if (scenario.setup) await scenario.setup(page, frame);
|
|
65
66
|
paths.before = await profiler.captureSnapshot("before");
|
|
66
67
|
await this.repeatScenarioActions(scenario, page, frame);
|
|
67
68
|
await forceGarbageCollection(page);
|
|
@@ -78,12 +79,19 @@ class ScenarioRunner {
|
|
|
78
79
|
const auth = new AuthManager();
|
|
79
80
|
const pageSetup = new PageSetup();
|
|
80
81
|
await pageSetup.apply(page);
|
|
82
|
+
await page.unroute(PageSetup.BLOCKED_PATTERN);
|
|
81
83
|
await auth.login(page, {
|
|
82
84
|
username: this.config.env.userId,
|
|
83
85
|
password: this.config.env.password,
|
|
84
86
|
instanceId: this.config.env.instanceId
|
|
85
87
|
});
|
|
86
|
-
|
|
88
|
+
process.stderr.write(`[scenarioRunner] post-login URL = ${page.url()}
|
|
89
|
+
`);
|
|
90
|
+
await page.waitForURL(`**${scenario.url()}**`, { timeout: 3e4 });
|
|
91
|
+
process.stderr.write(
|
|
92
|
+
`[scenarioRunner] settled URL before iframe = ${page.url()}
|
|
93
|
+
`
|
|
94
|
+
);
|
|
87
95
|
const frame = await resolveIframe(page, scenario.microappSelector);
|
|
88
96
|
fs.mkdirSync(snapshotsDir, { recursive: true });
|
|
89
97
|
const profiler = new IframeHeapProfiler(page, frame, snapshotsDir);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AdminLandingPageModel,
|
|
2
3
|
SelectSettingsPageModel,
|
|
3
4
|
ExportPageModel
|
|
4
5
|
} from "./page-models/index.js";
|
|
@@ -8,8 +9,17 @@ const exportNavigationScenario = {
|
|
|
8
9
|
description: "Navigate to export page and come back - verify iframe GC",
|
|
9
10
|
tags: ["critical"],
|
|
10
11
|
microappSelector: "iframe#pui-iframe-container-emAdminUI",
|
|
11
|
-
url: () => "/admin
|
|
12
|
+
url: () => "/admin",
|
|
13
|
+
async setup(page) {
|
|
14
|
+
await AdminLandingPageModel.acceptCookiesIfShown(page);
|
|
15
|
+
},
|
|
12
16
|
async action(page, frame) {
|
|
17
|
+
const path = new URL(page.url()).pathname.replace(/\/$/, "");
|
|
18
|
+
if (path === "/admin") {
|
|
19
|
+
const adminLanding = new AdminLandingPageModel(frame);
|
|
20
|
+
await adminLanding.oneAdminConsoleOption.waitFor({ state: "visible" });
|
|
21
|
+
await adminLanding.clickOneAdminConsole();
|
|
22
|
+
}
|
|
13
23
|
const settings = new SelectSettingsPageModel(frame);
|
|
14
24
|
await settings.container.waitFor({ state: "visible" });
|
|
15
25
|
await settings.expandTreeItem("eFolder");
|