From 1883976151f97828c03c291adad6854bbf867be9 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Thu, 18 Jun 2026 18:47:16 +0300 Subject: [PATCH 1/9] fix: do not use registerHooks on node < 24.13 --- .github/workflows/repl-e2e.yml | 2 +- src/utils/repl-module-hooks.ts | 10 ++++++++- test/e2e/repl/conflicting-async-loader.mjs | 3 +++ test/e2e/repl/repl.test.js | 10 ++++++++- test/src/utils/repl-module-hooks.ts | 24 +++++++++++++++++++++- 5 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 test/e2e/repl/conflicting-async-loader.mjs diff --git a/.github/workflows/repl-e2e.yml b/.github/workflows/repl-e2e.yml index baab6d0dd..33777c85e 100644 --- a/.github/workflows/repl-e2e.yml +++ b/.github/workflows/repl-e2e.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [24.x] + node-version: [22.18.0, 24.13.0] steps: - uses: actions/checkout@v4 diff --git a/src/utils/repl-module-hooks.ts b/src/utils/repl-module-hooks.ts index 0f3d8aad0..fdc8da9c6 100644 --- a/src/utils/repl-module-hooks.ts +++ b/src/utils/repl-module-hooks.ts @@ -28,7 +28,7 @@ export const registerReplModuleHooks = (): void => { function registerNodeModuleHooks(): { revert: () => void } | null { const registerHooks = nodeModule.registerHooks; - if (typeof registerHooks !== "function") { + if (typeof registerHooks !== "function" || hasBrokenMixedModuleHookValidation()) { return null; } @@ -43,6 +43,14 @@ function registerNodeModuleHooks(): { revert: () => void } | null { return { revert: () => hooks.deregister() }; } +function hasBrokenMixedModuleHookValidation(): boolean { + const [major, minor] = process.versions.node.split(".").map(Number); + + // https://github.com/nodejs/node/issues/57327 + // Fixed for REPL instrumentation in Node 24.13.0; older versions mishandle CJS sources with mixed sync/async hooks. + return major < 24 || (major === 24 && minor < 13); +} + function registerPiratesHook(): { revert: () => void } { const revert = addHook((code, sourceFile) => safeInstrumentRepl(code, sourceFile), { exts: TRANSFORM_CODE_EXTENSIONS, diff --git a/test/e2e/repl/conflicting-async-loader.mjs b/test/e2e/repl/conflicting-async-loader.mjs new file mode 100644 index 000000000..eea1f8989 --- /dev/null +++ b/test/e2e/repl/conflicting-async-loader.mjs @@ -0,0 +1,3 @@ +import { register } from "node:module"; + +register("data:text/javascript,export async function load(url, context, nextLoad) { return nextLoad(url, context); }"); diff --git a/test/e2e/repl/repl.test.js b/test/e2e/repl/repl.test.js index 52bdce161..cfa3b5e9b 100644 --- a/test/e2e/repl/repl.test.js +++ b/test/e2e/repl/repl.test.js @@ -3,12 +3,14 @@ const path = require("node:path"); const { spawn } = require("node:child_process"); const assert = require("node:assert/strict"); +const { pathToFileURL } = require("node:url"); const getPort = require("get-port"); const { runReplCommand, exitRepl } = require("./repl-client"); const ROOT_DIR = path.resolve(__dirname, "../../.."); const FIXTURE_DIR = path.join(__dirname, "fixture-project"); const TESTPLANE_BIN = path.join(ROOT_DIR, "bin", "testplane"); +const CONFLICTING_ASYNC_LOADER = path.join(__dirname, "conflicting-async-loader.mjs"); const REPL_WAIT_TIMEOUT = 60000; const EXIT_TIMEOUT = 60000; const runningProcesses = new Set(); @@ -86,7 +88,13 @@ async function startTestplane(args) { [TESTPLANE_BIN, "--config", "testplane.config.js", "--local", "--repl-port", String(port), ...args], { cwd: FIXTURE_DIR, - env: { ...process.env, FORCE_COLOR: "0" }, + env: { + ...process.env, + FORCE_COLOR: "0", + NODE_OPTIONS: [process.env.NODE_OPTIONS, `--import=${pathToFileURL(CONFLICTING_ASYNC_LOADER).href}`] + .filter(Boolean) + .join(" "), + }, stdio: ["ignore", "pipe", "pipe"], }, ); diff --git a/test/src/utils/repl-module-hooks.ts b/test/src/utils/repl-module-hooks.ts index 099fffbb7..d246e0b1c 100644 --- a/test/src/utils/repl-module-hooks.ts +++ b/test/src/utils/repl-module-hooks.ts @@ -20,8 +20,12 @@ describe("utils/repl-module-hooks", () => { delete processWithHook[TESTPLANE_REPL_MODULE_HOOK]; }; - const loadModule_ = ({ hasRegisterHooks = false }: { hasRegisterHooks?: boolean } = {}): void => { + const loadModule_ = ({ + hasRegisterHooks = false, + nodeVersion = "24.13.0", + }: { hasRegisterHooks?: boolean; nodeVersion?: string } = {}): void => { cleanupHook_(); + sinon.stub(process.versions, "node").value(nodeVersion); deregisterStub = sinon.stub(); registerHooksStub = sinon.stub().returns({ deregister: deregisterStub }); @@ -82,6 +86,24 @@ describe("utils/repl-module-hooks", () => { assert.calledOnceWith(instrumentStub, "it('a', () => {})", "/tmp/spec.hermione.ts"); }); + it("should fallback to pirates when registerHooks has broken mixed hook validation", () => { + loadModule_({ hasRegisterHooks: true, nodeVersion: "22.18.0" }); + + replModuleHooks.registerReplModuleHooks(); + + assert.notCalled(registerHooksStub); + assert.calledOnce(addHookStub); + }); + + it("should fallback to pirates on Node 24 versions before the instrumentation fix", () => { + loadModule_({ hasRegisterHooks: true, nodeVersion: "24.12.0" }); + + replModuleHooks.registerReplModuleHooks(); + + assert.notCalled(registerHooksStub); + assert.calledOnce(addHookStub); + }); + it("should not instrument sources outside repl mode", () => { loadModule_(); isReplModeEnabled = false; From 367f792ae4ddfede09f68340ada8738fd762343e Mon Sep 17 00:00:00 2001 From: shadowusr Date: Thu, 18 Jun 2026 18:49:19 +0300 Subject: [PATCH 2/9] fix: do not register any instrumentation hooks if repl is not used --- src/cli/index.ts | 38 +++++++++-------------------- src/cli/repl-options.ts | 23 +++++++++++++++++ src/utils/repl-module-hooks.ts | 10 ++++++++ test/src/utils/repl-module-hooks.ts | 15 +++++++++++- 4 files changed, 59 insertions(+), 27 deletions(-) create mode 100644 src/cli/repl-options.ts diff --git a/src/cli/index.ts b/src/cli/index.ts index 7aa48c1d8..faa3c3379 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -11,6 +11,7 @@ import { shouldIgnoreUnhandledRejection } from "../utils/errors"; import { utilInspectSafe } from "../utils/secret-replacer"; import { withCommonCliOptions, collectCliValues, handleRequires } from "../utils/cli"; import { CliCommands } from "./constants"; +import { addReplOptions, isReplModeEnabled } from "./repl-options"; export type TestplaneRunOpts = { cliName?: string }; @@ -60,7 +61,7 @@ export const run = async (opts: TestplaneRunOpts = {}): Promise => { const configPath = preparseOption(program, "config") as string; testplane = await Testplane.create(configPath); - withCommonCliOptions({ cmd: program, actionName: "run" }) + const runCommand = withCommonCliOptions({ cmd: program, actionName: "run" }) .on("--help", () => console.log(configOverriding(opts))) .description("Run tests") .option("--reporter ", "test reporters", collectCliValues) @@ -69,21 +70,11 @@ export const run = async (opts: TestplaneRunOpts = {}): Promise => { 'update screenshot references or gather them if they do not exist ("assertView" command)', ) .option("--inspect [inspect]", "nodejs inspector on [=[host:]port]") - .option("--inspect-brk [inspect-brk]", "nodejs inspector with break at the start") - .option( - "--repl [type]", - "run one test, call `browser.switchToRepl` in test code to open repl interface", - Boolean, - false, - ) - .option("--repl-before-test [type]", "open repl interface before test run", Boolean, false) - .option("--repl-on-fail [type]", "open repl interface on test fail only", Boolean, false) - .option( - "--repl-port ", - "run net server on port to exchange messages with repl (used free random port by default)", - Number, - 0, - ) + .option("--inspect-brk [inspect-brk]", "nodejs inspector with break at the start"); + + addReplOptions(runCommand); + + runCommand .option("--local", "use local browsers, managed by testplane (same as 'gridUrl': 'local')") .option("--keep-browser", "do not close browser session after test completion") .option("--keep-browser-on-fail", "do not close browser session when test fails") @@ -105,6 +96,7 @@ export const run = async (opts: TestplaneRunOpts = {}): Promise => { keepBrowser, keepBrowserOnFail, } = program; + const isReplEnabled = isReplModeEnabled(program); const isTestsSuccess = await testplane.run(paths, { reporters: reporters || defaults.reporters, @@ -116,10 +108,10 @@ export const run = async (opts: TestplaneRunOpts = {}): Promise => { requireModules, inspectMode: (inspect || inspectBrk) && { inspect, inspectBrk }, replMode: { - enabled: isReplModeEnabled(program), + enabled: isReplEnabled, beforeTest: replBeforeTest, onFail: replOnFail, - port: await getReplPort(program), + port: await getReplPort(program, isReplEnabled), }, local: local || false, keepBrowserMode: { @@ -157,16 +149,10 @@ function preparseOption(program: Command, option: string): unknown { return configFileParser[option]; } -function isReplModeEnabled(program: Command): boolean { - const { repl, replBeforeTest, replOnFail } = program; - - return repl || replBeforeTest || replOnFail; -} - -async function getReplPort(program: Command): Promise { +async function getReplPort(program: Command, isReplEnabled: boolean): Promise { let { replPort } = program; - if (isReplModeEnabled(program) && !replPort) { + if (isReplEnabled && !replPort) { replPort = await getPort(); } diff --git a/src/cli/repl-options.ts b/src/cli/repl-options.ts new file mode 100644 index 000000000..94a5b3e55 --- /dev/null +++ b/src/cli/repl-options.ts @@ -0,0 +1,23 @@ +import { Command } from "@gemini-testing/commander"; + +export const addReplOptions = (cmd: Command): Command => { + return cmd + .option( + "--repl [type]", + "run one test, call `browser.switchToRepl` in test code to open repl interface", + Boolean, + false, + ) + .option("--repl-before-test [type]", "open repl interface before test run", Boolean, false) + .option("--repl-on-fail [type]", "open repl interface on test fail only", Boolean, false) + .option( + "--repl-port ", + "run net server on port to exchange messages with repl (used free random port by default)", + Number, + 0, + ); +}; + +export const isReplModeEnabled = (program: Command): boolean => { + return Boolean(program.repl || program.replBeforeTest || program.replOnFail); +}; diff --git a/src/utils/repl-module-hooks.ts b/src/utils/repl-module-hooks.ts index fdc8da9c6..e07cef50a 100644 --- a/src/utils/repl-module-hooks.ts +++ b/src/utils/repl-module-hooks.ts @@ -1,8 +1,10 @@ import * as nodeModule from "node:module"; import type { LoadFnOutput, ModuleHooks, ModuleSource } from "node:module"; +import { Command } from "@gemini-testing/commander"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { addHook } from "pirates"; +import { addReplOptions, isReplModeEnabled } from "../cli/repl-options"; import { instrumentReplIfNeeded } from "./repl-instrumentation"; import * as logger from "./logger"; @@ -20,6 +22,14 @@ export const registerReplModuleHooks = (): void => { return; } + const program = addReplOptions(new Command("testplane").allowUnknownOption().option("-h, --help")); + + program.parse(process.argv); + + if (!isReplModeEnabled(program)) { + return; + } + const hook = registerNodeModuleHooks() || registerPiratesHook(); processWithHook[TESTPLANE_REPL_MODULE_HOOK] = hook; diff --git a/test/src/utils/repl-module-hooks.ts b/test/src/utils/repl-module-hooks.ts index d246e0b1c..b0529cffc 100644 --- a/test/src/utils/repl-module-hooks.ts +++ b/test/src/utils/repl-module-hooks.ts @@ -4,6 +4,7 @@ import sinon, { type SinonStub } from "sinon"; describe("utils/repl-module-hooks", () => { const TESTPLANE_REPL_MODULE_HOOK = Symbol.for("testplane.repl.module.hook"); + const originalArgv = process.argv; let registerHooksStub: SinonStub; let deregisterStub: SinonStub; @@ -23,8 +24,10 @@ describe("utils/repl-module-hooks", () => { const loadModule_ = ({ hasRegisterHooks = false, nodeVersion = "24.13.0", - }: { hasRegisterHooks?: boolean; nodeVersion?: string } = {}): void => { + argv = ["--repl"], + }: { hasRegisterHooks?: boolean; nodeVersion?: string; argv?: string[] } = {}): void => { cleanupHook_(); + process.argv = ["node", "testplane", ...argv]; sinon.stub(process.versions, "node").value(nodeVersion); deregisterStub = sinon.stub(); @@ -46,9 +49,19 @@ describe("utils/repl-module-hooks", () => { afterEach(() => { cleanupHook_(); + process.argv = originalArgv; sinon.restore(); }); + it("should not register hooks outside repl mode", () => { + loadModule_({ hasRegisterHooks: true, argv: [] }); + + replModuleHooks.registerReplModuleHooks(); + + assert.notCalled(registerHooksStub); + assert.notCalled(addHookStub); + }); + it("should use node module registerHooks when it is available", () => { loadModule_({ hasRegisterHooks: true }); From 23fc60e821d3ad9f450f2f12d6c347cbd5ae569f Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 19 Jun 2026 02:27:21 +0300 Subject: [PATCH 3/9] fix: read file in repl instrumentation when source is null as best-effort case --- src/utils/repl-module-hooks.ts | 17 +++++++++++-- test/src/utils/repl-module-hooks.ts | 38 +++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/utils/repl-module-hooks.ts b/src/utils/repl-module-hooks.ts index e07cef50a..ccd5e85d1 100644 --- a/src/utils/repl-module-hooks.ts +++ b/src/utils/repl-module-hooks.ts @@ -1,6 +1,7 @@ import * as nodeModule from "node:module"; import type { LoadFnOutput, ModuleHooks, ModuleSource } from "node:module"; import { Command } from "@gemini-testing/commander"; +import { readFileSync } from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { addHook } from "pirates"; @@ -73,11 +74,15 @@ function registerPiratesHook(): { revert: () => void } { function instrumentLoadResult(url: string, result: LoadFnOutput): LoadFnOutput { const sourceFile = getSourceFileFromUrl(url); - if (!sourceFile || !result.source || !shouldHandleSourceFile(sourceFile)) { + if (!sourceFile || !shouldHandleSourceFile(sourceFile)) { return result; } - const source = moduleSourceToString(result.source); + const resultSource = result.source as ModuleSource | null | undefined; + const source = + resultSource === null || resultSource === undefined + ? readSourceFile(sourceFile) + : moduleSourceToString(resultSource); if (source === null) { return result; @@ -95,6 +100,14 @@ function safeInstrumentRepl(source: string, sourceFile: string): string { } } +function readSourceFile(sourceFile: string): string | null { + try { + return readFileSync(sourceFile, "utf8"); + } catch { + return null; + } +} + function getSourceFileFromUrl(url: string): string | null { try { return url.startsWith("file:") ? fileURLToPath(url) : null; diff --git a/test/src/utils/repl-module-hooks.ts b/test/src/utils/repl-module-hooks.ts index b0529cffc..93296b41e 100644 --- a/test/src/utils/repl-module-hooks.ts +++ b/test/src/utils/repl-module-hooks.ts @@ -11,6 +11,7 @@ describe("utils/repl-module-hooks", () => { let addHookStub: SinonStub; let instrumentStub: SinonStub; let loggerWarnStub: SinonStub; + let readFileSyncStub: SinonStub; let replModuleHooks: typeof import("src/utils/repl-module-hooks"); let isReplModeEnabled: boolean; @@ -33,6 +34,7 @@ describe("utils/repl-module-hooks", () => { deregisterStub = sinon.stub(); registerHooksStub = sinon.stub().returns({ deregister: deregisterStub }); addHookStub = sinon.stub().returns(sinon.stub()); + readFileSyncStub = sinon.stub(); isReplModeEnabled = true; instrumentStub = sinon.stub().callsFake((code: string) => { return isReplModeEnabled ? `${code}\n/* instrumented */` : code; @@ -41,6 +43,7 @@ describe("utils/repl-module-hooks", () => { replModuleHooks = proxyquire.noCallThru().load("src/utils/repl-module-hooks", { "node:module": hasRegisterHooks ? { registerHooks: registerHooksStub } : {}, + "node:fs": { readFileSync: readFileSyncStub }, pirates: { addHook: addHookStub }, "./repl-instrumentation": { instrumentReplIfNeeded: instrumentStub }, "./logger": { warn: loggerWarnStub }, @@ -81,6 +84,41 @@ describe("utils/repl-module-hooks", () => { assert.calledOnceWith(instrumentStub, "it('a', () => {})", "/tmp/spec.hermione.mjs"); }); + it("should read file source when registerHooks returns null source", () => { + loadModule_({ hasRegisterHooks: true }); + readFileSyncStub.returns("it('a', () => {})"); + + replModuleHooks.registerReplModuleHooks(); + + const loadHook = registerHooksStub.firstCall.args[0].load; + const fileUrl = pathToFileURL("/tmp/spec.hermione.js").href; + const result = loadHook(fileUrl, { format: "commonjs" }, () => ({ + format: "commonjs", + source: null, + })); + + assert.equal(result.source, "it('a', () => {})\n/* instrumented */"); + assert.calledOnceWith(readFileSyncStub, "/tmp/spec.hermione.js", "utf8"); + assert.calledOnceWith(instrumentStub, "it('a', () => {})", "/tmp/spec.hermione.js"); + }); + + it("should keep original registerHooks result if null source cannot be read", () => { + loadModule_({ hasRegisterHooks: true }); + readFileSyncStub.throws(new Error("boom")); + + replModuleHooks.registerReplModuleHooks(); + + const loadHook = registerHooksStub.firstCall.args[0].load; + const fileUrl = pathToFileURL("/tmp/spec.hermione.js").href; + const result = loadHook(fileUrl, { format: "commonjs" }, () => ({ + format: "commonjs", + source: null, + })); + + assert.deepEqual(result, { format: "commonjs", source: null }); + assert.notCalled(instrumentStub); + }); + it("should fallback to pirates when registerHooks is not available", () => { loadModule_(); From 00f8e775c5f022753363705681b85f936749c059 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 19 Jun 2026 02:27:43 +0300 Subject: [PATCH 4/9] ci: make CI flows use correct npm scripts and node versions --- .github/workflows/e2e.yml | 6 +++--- .github/workflows/repl-e2e.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index fb26437ac..e92cc6608 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -22,10 +22,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Use Node.js 20 + - name: Use Node.js 24 uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 cache: "npm" - name: Install dependencies @@ -62,7 +62,7 @@ jobs: - name: "e2e: Run Testplane" id: "testplane" continue-on-error: true - run: npm run test-e2e + run: npm run test-e2e:run-tests - name: "e2e: Stop browser docker image" run: | diff --git a/.github/workflows/repl-e2e.yml b/.github/workflows/repl-e2e.yml index 33777c85e..7033b7057 100644 --- a/.github/workflows/repl-e2e.yml +++ b/.github/workflows/repl-e2e.yml @@ -36,4 +36,4 @@ jobs: run: npm run build - name: Run REPL e2e tests - run: npm run test-e2e -- --grep "REPL e2e" + run: npm run test-e2e-repl From 8adadc4c82042b0dcde321aaad1334df4ac04b5f Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 19 Jun 2026 13:55:50 +0300 Subject: [PATCH 5/9] fix: shift to best-effort instrumentation on node < 24.13 --- package-lock.json | 2 +- src/utils/repl-module-hooks.ts | 82 ++++++++++++++++--- .../repl/fixture-project/testplane.config.js | 2 +- .../tests/switch-to-repl.test.mts | 28 +++++++ 4 files changed, 99 insertions(+), 15 deletions(-) create mode 100644 test/e2e/repl/fixture-project/tests/switch-to-repl.test.mts diff --git a/package-lock.json b/package-lock.json index af76f235b..7c6b678c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -132,7 +132,7 @@ "uglifyify": "3.0.4" }, "engines": { - "node": ">= 18.17.0" + "node": ">= 22" }, "peerDependencies": { "@babel/parser": ">=7.0.0", diff --git a/src/utils/repl-module-hooks.ts b/src/utils/repl-module-hooks.ts index ccd5e85d1..ab4b5ad5c 100644 --- a/src/utils/repl-module-hooks.ts +++ b/src/utils/repl-module-hooks.ts @@ -1,5 +1,5 @@ import * as nodeModule from "node:module"; -import type { LoadFnOutput, ModuleHooks, ModuleSource } from "node:module"; +import type { LoadFnOutput, LoadHookContext, ModuleHooks, ModuleSource } from "node:module"; import { Command } from "@gemini-testing/commander"; import { readFileSync } from "node:fs"; import path from "node:path"; @@ -39,13 +39,21 @@ export const registerReplModuleHooks = (): void => { function registerNodeModuleHooks(): { revert: () => void } | null { const registerHooks = nodeModule.registerHooks; - if (typeof registerHooks !== "function" || hasBrokenMixedModuleHookValidation()) { + if (typeof registerHooks !== "function") { return null; } const hooks: ModuleHooks = registerHooks({ load(url, context, nextLoad) { - const result = nextLoad(url, context); + let result: LoadFnOutput; + + try { + result = nextLoad(url, context); + } catch (err) { + // https://github.com/nodejs/node/issues/57327 + // Fixed for REPL instrumentation in Node 24.13.0; older versions mishandle CJS sources with mixed sync/async hooks. + return instrumentLoadAfterFailedLoad(url, context, err); + } return instrumentLoadResult(url, result); }, @@ -54,14 +62,6 @@ function registerNodeModuleHooks(): { revert: () => void } | null { return { revert: () => hooks.deregister() }; } -function hasBrokenMixedModuleHookValidation(): boolean { - const [major, minor] = process.versions.node.split(".").map(Number); - - // https://github.com/nodejs/node/issues/57327 - // Fixed for REPL instrumentation in Node 24.13.0; older versions mishandle CJS sources with mixed sync/async hooks. - return major < 24 || (major === 24 && minor < 13); -} - function registerPiratesHook(): { revert: () => void } { const revert = addHook((code, sourceFile) => safeInstrumentRepl(code, sourceFile), { exts: TRANSFORM_CODE_EXTENSIONS, @@ -71,6 +71,26 @@ function registerPiratesHook(): { revert: () => void } { return { revert }; } +function instrumentLoadAfterFailedLoad(url: string, context: LoadHookContext, err: unknown): LoadFnOutput { + const sourceFile = getSourceFileFromUrl(url); + + if (!isInvalidLoadSourceError(err) || !sourceFile || !shouldReadSourceFile(sourceFile)) { + throw err; + } + + const source = readSourceFile(sourceFile); + + if (source === null) { + throw err; + } + + return { + format: getFallbackFormat(context, sourceFile), + shortCircuit: true, + source: shouldHandleSourceFile(sourceFile) ? safeInstrumentRepl(source, sourceFile) : source, + }; +} + function instrumentLoadResult(url: string, result: LoadFnOutput): LoadFnOutput { const sourceFile = getSourceFileFromUrl(url); @@ -108,6 +128,43 @@ function readSourceFile(sourceFile: string): string | null { } } +function isInvalidLoadSourceError(err: unknown): boolean { + if (!(err instanceof Error)) { + return false; + } + + const error = err as Error & { code?: string }; + + return ( + error.code === "ERR_INVALID_RETURN_PROPERTY_VALUE" && + error.message.includes('"source"') && + error.message.includes('"load" hook') + ); +} + +function shouldReadSourceFile(sourceFile: string): boolean { + return TRANSFORM_CODE_EXTENSIONS.includes(path.extname(sourceFile)); +} + +function getFallbackFormat(context: LoadHookContext, sourceFile: string): string { + if (context.format) { + return context.format; + } + + switch (path.extname(sourceFile)) { + case ".mjs": + return "module"; + case ".mts": + return "module-typescript"; + case ".ts": + case ".tsx": + case ".cts": + return "commonjs-typescript"; + default: + return "commonjs"; + } +} + function getSourceFileFromUrl(url: string): string | null { try { return url.startsWith("file:") ? fileURLToPath(url) : null; @@ -118,8 +175,7 @@ function getSourceFileFromUrl(url: string): string | null { function shouldHandleSourceFile(sourceFile: string): boolean { return ( - TRANSFORM_CODE_EXTENSIONS.includes(path.extname(sourceFile)) && - !sourceFile.includes(`${path.sep}node_modules${path.sep}`) + shouldReadSourceFile(sourceFile) && !sourceFile.includes(`${path.sep}node_modules${path.sep}`) ); } diff --git a/test/e2e/repl/fixture-project/testplane.config.js b/test/e2e/repl/fixture-project/testplane.config.js index c02105f24..0f41ca70f 100644 --- a/test/e2e/repl/fixture-project/testplane.config.js +++ b/test/e2e/repl/fixture-project/testplane.config.js @@ -4,7 +4,7 @@ module.exports = { gridUrl: "local", headless: "new", sets: { - default: { files: ["tests/**/*.test.[jt]s"] }, + default: { files: ["tests/**/*.test.[jt]s", "tests/**/*.test.cts"] }, }, browsers: { chrome: { diff --git a/test/e2e/repl/fixture-project/tests/switch-to-repl.test.mts b/test/e2e/repl/fixture-project/tests/switch-to-repl.test.mts new file mode 100644 index 000000000..72c5d5a1b --- /dev/null +++ b/test/e2e/repl/fixture-project/tests/switch-to-repl.test.mts @@ -0,0 +1,28 @@ +import assert from "node:assert/strict"; +import path from "node:path"; +import { pathToFileURL } from "node:url"; + +type TestContext = { + browser: any; +}; + +// Bound here so REPL e2e assertions can read it through generated context. +const rootValue: number = 1000; +void rootValue; + +const pageUrl: string = pathToFileURL(path.join(process.cwd(), "page.html")).href; + +// @ts-expect-error Testplane passes a context object into Mocha test callbacks. +it("opens repl from test code", async ({ browser }: TestContext): Promise => { + // Bound here so REPL e2e assertions can read it through generated context. + const localValue: number = 234; + void localValue; + + await browser.url(pageUrl); + await browser.switchToRepl(); + const anotherValue = 12222; + console.log(anotherValue); + await browser.$("#action").click(); + + assert.equal(await browser.$("#message").getText(), "Clicked from fixture"); +}); From 87a1f5e057e5f7a1d90e9aca914d5fb201cceec4 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 19 Jun 2026 14:11:20 +0300 Subject: [PATCH 6/9] test: fix formatting and unit tests --- src/utils/repl-module-hooks.ts | 4 +-- test/src/utils/repl-module-hooks.ts | 51 +++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/utils/repl-module-hooks.ts b/src/utils/repl-module-hooks.ts index ab4b5ad5c..6ec69d87d 100644 --- a/src/utils/repl-module-hooks.ts +++ b/src/utils/repl-module-hooks.ts @@ -174,9 +174,7 @@ function getSourceFileFromUrl(url: string): string | null { } function shouldHandleSourceFile(sourceFile: string): boolean { - return ( - shouldReadSourceFile(sourceFile) && !sourceFile.includes(`${path.sep}node_modules${path.sep}`) - ); + return shouldReadSourceFile(sourceFile) && !sourceFile.includes(`${path.sep}node_modules${path.sep}`); } function moduleSourceToString(source: ModuleSource): string | null { diff --git a/test/src/utils/repl-module-hooks.ts b/test/src/utils/repl-module-hooks.ts index 93296b41e..da2295420 100644 --- a/test/src/utils/repl-module-hooks.ts +++ b/test/src/utils/repl-module-hooks.ts @@ -50,6 +50,15 @@ describe("utils/repl-module-hooks", () => { }); }; + const createInvalidLoadSourceError_ = (): Error & { code: string } => { + return Object.assign( + new TypeError( + 'Expected a string, an ArrayBuffer, or a TypedArray to be returned for the "source" from the "load" hook but got null.', + ), + { code: "ERR_INVALID_RETURN_PROPERTY_VALUE" }, + ); + }; + afterEach(() => { cleanupHook_(); process.argv = originalArgv; @@ -137,22 +146,52 @@ describe("utils/repl-module-hooks", () => { assert.calledOnceWith(instrumentStub, "it('a', () => {})", "/tmp/spec.hermione.ts"); }); - it("should fallback to pirates when registerHooks has broken mixed hook validation", () => { + it("should recover from broken mixed hook validation on Node 22", () => { loadModule_({ hasRegisterHooks: true, nodeVersion: "22.18.0" }); + readFileSyncStub.returns("it('a', () => {})"); replModuleHooks.registerReplModuleHooks(); - assert.notCalled(registerHooksStub); - assert.calledOnce(addHookStub); + assert.calledOnce(registerHooksStub); + assert.notCalled(addHookStub); + + const loadHook = registerHooksStub.firstCall.args[0].load; + const fileUrl = pathToFileURL("/tmp/spec.hermione.ts").href; + const result = loadHook(fileUrl, { format: "commonjs-typescript" }, () => { + throw createInvalidLoadSourceError_(); + }); + + assert.deepEqual(result, { + format: "commonjs-typescript", + shortCircuit: true, + source: "it('a', () => {})\n/* instrumented */", + }); + assert.calledOnceWith(readFileSyncStub, "/tmp/spec.hermione.ts", "utf8"); + assert.calledOnceWith(instrumentStub, "it('a', () => {})", "/tmp/spec.hermione.ts"); }); - it("should fallback to pirates on Node 24 versions before the instrumentation fix", () => { + it("should recover from broken mixed hook validation on Node 24 versions before the validation fix", () => { loadModule_({ hasRegisterHooks: true, nodeVersion: "24.12.0" }); + readFileSyncStub.returns("it('a', () => {})"); replModuleHooks.registerReplModuleHooks(); - assert.notCalled(registerHooksStub); - assert.calledOnce(addHookStub); + assert.calledOnce(registerHooksStub); + assert.notCalled(addHookStub); + + const loadHook = registerHooksStub.firstCall.args[0].load; + const fileUrl = pathToFileURL("/tmp/spec.hermione.js").href; + const result = loadHook(fileUrl, { format: "commonjs" }, () => { + throw createInvalidLoadSourceError_(); + }); + + assert.deepEqual(result, { + format: "commonjs", + shortCircuit: true, + source: "it('a', () => {})\n/* instrumented */", + }); + assert.calledOnceWith(readFileSyncStub, "/tmp/spec.hermione.js", "utf8"); + assert.calledOnceWith(instrumentStub, "it('a', () => {})", "/tmp/spec.hermione.js"); }); it("should not instrument sources outside repl mode", () => { From 3467955bc3fba924d81394c58b3c49198c434cb7 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 19 Jun 2026 14:17:35 +0300 Subject: [PATCH 7/9] ci: fix CI flows --- .github/workflows/e2e.yml | 4 ++-- .github/workflows/{repl-e2e.yml => mocha-e2e.yml} | 4 ++-- package.json | 9 +++++---- 3 files changed, 9 insertions(+), 8 deletions(-) rename .github/workflows/{repl-e2e.yml => mocha-e2e.yml} (93%) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index e92cc6608..2d6fbeaa8 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -1,4 +1,4 @@ -name: Testplane E2E +name: E2E Tests (driven by Testplane) on: pull_request: @@ -62,7 +62,7 @@ jobs: - name: "e2e: Run Testplane" id: "testplane" continue-on-error: true - run: npm run test-e2e:run-tests + run: npm run test-e2e-testplane - name: "e2e: Stop browser docker image" run: | diff --git a/.github/workflows/repl-e2e.yml b/.github/workflows/mocha-e2e.yml similarity index 93% rename from .github/workflows/repl-e2e.yml rename to .github/workflows/mocha-e2e.yml index 7033b7057..ce9adc7dc 100644 --- a/.github/workflows/repl-e2e.yml +++ b/.github/workflows/mocha-e2e.yml @@ -1,4 +1,4 @@ -name: REPL E2E Tests +name: E2E Tests (driven by Mocha) on: pull_request: @@ -36,4 +36,4 @@ jobs: run: npm run build - name: Run REPL e2e tests - run: npm run test-e2e-repl + run: npm run test-e2e-mocha diff --git a/package.json b/package.json index 102368532..ae3dc5a1e 100644 --- a/package.json +++ b/package.json @@ -35,10 +35,11 @@ "test-unit:generate-fixtures": "TS_NODE_PROJECT=test/tsconfig.json node -r ts-node/register -r tsconfig-paths/register test/src/browser/screen-shooter/composite-image/fixtures/generate.ts generate", "test": "npm run test-unit && npm run check-types && npm run lint", "test-integration": "TS_NODE_TRANSPILE_ONLY=1 node scripts/run-node-without-type-stripping.js ./node_modules/mocha/bin/_mocha -r ts-node/register test/integration/*/**", - "test-e2e": "npm run test-e2e-repl && npm run test-e2e:generate-fixtures && npm run test-e2e:run-tests", - "test-e2e-repl": "_mocha \"test/e2e/**/*.test.js\" --ignore \"test/e2e/**/fixture-project/**\"", - "test-e2e:run-tests": "node bin/testplane --config test/e2e/testplane.config.ts", - "test-e2e:generate-fixtures": "node bin/testplane --config test/e2e/fixtures/basic-report/testplane.config.ts || true", + "test-e2e": "npm run test-e2e-mocha && npm run test-e2e-testplane", + "test-e2e-mocha": "_mocha \"test/e2e/**/*.test.js\" --ignore \"test/e2e/**/fixture-project/**\"", + "test-e2e-testplane": "npm run test-e2e-testplane:generate-fixtures && npm run test-e2e-testplane:run-tests", + "test-e2e-testplane:run-tests": "node bin/testplane --config test/e2e/testplane.config.ts", + "test-e2e-testplane:generate-fixtures": "node bin/testplane --config test/e2e/fixtures/basic-report/testplane.config.ts || true", "test-e2e:gui": "node bin/testplane --config test/e2e/testplane.config.ts gui", "test-browser-env": "TS_NODE_PROJECT=./test/browser-env/tsconfig.json node bin/testplane -r tsconfig-paths/register --config test/browser-env/testplane.config.ts", "test-browser-env:gui": "TS_NODE_PROJECT=./test/browser-env/tsconfig.json node bin/testplane gui -r tsconfig-paths/register --config test/browser-env/testplane.config.ts", From be74cb98248ec9cefc13ebbbe3e0f904c1169ba2 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Fri, 19 Jun 2026 14:58:23 +0300 Subject: [PATCH 8/9] ci: update standalone preload script --- .github/workflows/standalone-e2e.yml | 13 +- scripts/preload-standalone-browser.ts | 487 ++++++++++++++++++ test/integration/standalone/constants.ts | 3 +- .../standalone/preload-browser.fixture.ts | 8 - 4 files changed, 498 insertions(+), 13 deletions(-) create mode 100644 scripts/preload-standalone-browser.ts delete mode 100644 test/integration/standalone/preload-browser.fixture.ts diff --git a/.github/workflows/standalone-e2e.yml b/.github/workflows/standalone-e2e.yml index d7b773752..376ccc6e4 100644 --- a/.github/workflows/standalone-e2e.yml +++ b/.github/workflows/standalone-e2e.yml @@ -9,6 +9,7 @@ jobs: runs-on: ubuntu-latest env: DOCKER_IMAGE_NAME: html-reporter-browsers + INTEGRATION_BROWSER_VERSION: "138.0" strategy: matrix: @@ -28,10 +29,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.testplane - key: ${{ runner.os }}-testplane-${{ matrix.browser }} - restore-keys: | - ${{ runner.os }}-testplane-${{ matrix.browser }}- - ${{ runner.os }}-testplane- + key: ${{ runner.os }}-testplane-browsers-${{ matrix.browser }}-${{ env.INTEGRATION_BROWSER_VERSION }} - name: Install dependencies run: npm ci @@ -39,6 +37,13 @@ jobs: - name: Build project run: npm run build + - name: Preload Chrome browser + if: ${{ matrix.browser == 'chrome' }} + timeout-minutes: 10 + env: + BROWSER: ${{ matrix.browser }} + run: TS_NODE_TRANSPILE_ONLY=1 node scripts/run-node-without-type-stripping.js -r ts-node/register scripts/preload-standalone-browser.ts + - name: "Prepare screenshot tests: Cache browser docker image" if: ${{ matrix.browser == 'chrome' }} uses: actions/cache@v3 diff --git a/scripts/preload-standalone-browser.ts b/scripts/preload-standalone-browser.ts new file mode 100644 index 000000000..5e983820e --- /dev/null +++ b/scripts/preload-standalone-browser.ts @@ -0,0 +1,487 @@ +import path from "path"; +import { spawn } from "child_process"; +import fs from "fs-extra"; +import { + Browser as PuppeteerBrowser, + BrowserPlatform, + canDownload, + computeExecutablePath, + detectBrowserPlatform, + install as puppeteerInstall, + resolveBuildId, +} from "@puppeteer/browsers"; +import registry from "../src/browser-installer/registry"; +import { getUbuntuMilestone, installUbuntuPackageDependencies, isUbuntu } from "../src/browser-installer/ubuntu-packages"; +import { LINUX_UBUNTU_RELEASE_ID } from "../src/browser-installer/constants"; +import { + getBrowsersDir, + getChromeDriverDir, + getMilestone, + getOsPackagesDir, + getRegistryPath, + normalizeChromeVersion, + type DownloadProgressCallback, +} from "../src/browser-installer/utils"; +import { BROWSER_NAME, BROWSER_VERSION } from "../test/integration/standalone/constants"; + +const LOG_PREFIX = "[preload-standalone-browser]"; +const MAX_DIR_ENTRIES = 300; +const STEP_TIMEOUT_MS = 180_000; + +const log = (message: string): void => { + console.log(`${LOG_PREFIX} ${message}`); +}; + +const dumpJson = (label: string, value: unknown): void => { + log(`${label}: ${JSON.stringify(value, null, 2)}`); +}; + +const formatBytes = (bytes: number): string => { + if (!Number.isFinite(bytes) || bytes <= 0) { + return String(bytes); + } + + const units = ["B", "KiB", "MiB", "GiB"]; + let value = bytes; + let unitIndex = 0; + + while (value >= 1024 && unitIndex < units.length - 1) { + value /= 1024; + unitIndex++; + } + + return `${value.toFixed(unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}`; +}; + +const getInstallDir = (executablePath: string): string => path.dirname(path.dirname(executablePath)); + +const getArchivePath = (cacheRoot: string, browser: PuppeteerBrowser, buildId: string, downloadUrl: string): string => + path.join(cacheRoot, browser, `${buildId}-${downloadUrl.split("/").pop()}`); + +const getChromeForTestingPlatform = (platform: BrowserPlatform): string => { + switch (platform) { + case BrowserPlatform.LINUX: + return "linux64"; + case BrowserPlatform.MAC: + return "mac-x64"; + case BrowserPlatform.MAC_ARM: + return "mac-arm64"; + case BrowserPlatform.WIN32: + return "win32"; + case BrowserPlatform.WIN64: + return "win64"; + default: + return platform; + } +}; + +const getChromeForTestingUrl = (browser: PuppeteerBrowser, platform: BrowserPlatform, buildId: string): string => + `https://storage.googleapis.com/chrome-for-testing-public/${buildId}/${getChromeForTestingPlatform(platform)}/${browser}-${getChromeForTestingPlatform(platform)}.zip`; + +const runCommand = async (command: string, args: string[]): Promise => { + log(`running: ${command} ${args.join(" ")}`); + + await new Promise((resolve, reject) => { + const childProcess = spawn(command, args, { stdio: "inherit" }); + + childProcess.on("error", reject); + childProcess.on("exit", (code, signal) => { + if (code === 0) { + resolve(); + return; + } + + reject(new Error(`${command} exited with ${code === null ? `signal ${signal}` : `code ${code}`}`)); + }); + }); +}; + +const dumpPath = async (label: string, targetPath: string): Promise => { + if (!(await fs.pathExists(targetPath))) { + log(`${label}: missing at ${targetPath}`); + return; + } + + const stat = await fs.stat(targetPath); + + log( + `${label}: exists at ${targetPath} (${stat.isDirectory() ? "directory" : "file"}, size=${stat.size}, mode=${stat.mode.toString(8)})`, + ); +}; + +const dumpDir = async (label: string, dirPath: string, maxDepth = 3): Promise => { + log(`${label}: ${dirPath}`); + + if (!(await fs.pathExists(dirPath))) { + log(" "); + return; + } + + let entriesCount = 0; + + const walk = async (currentPath: string, depth: number, indent: string): Promise => { + if (entriesCount >= MAX_DIR_ENTRIES) { + return; + } + + const entries = (await fs.readdir(currentPath)).sort(); + + for (const entry of entries) { + if (entriesCount >= MAX_DIR_ENTRIES) { + log(`${indent}`); + return; + } + + const entryPath = path.join(currentPath, entry); + const stat = await fs.stat(entryPath); + const suffix = stat.isDirectory() ? "/" : ""; + + entriesCount++; + log(`${indent}${entry}${suffix} size=${stat.size} mode=${stat.mode.toString(8)}`); + + if (stat.isDirectory() && depth < maxDepth) { + await walk(entryPath, depth + 1, `${indent} `); + } + } + }; + + await walk(dirPath, 0, " "); + + if (entriesCount === 0) { + log(" "); + } +}; + +const dumpRegistry = async (): Promise => { + const registryPath = getRegistryPath(); + + await dumpPath("registry", registryPath); + + if (await fs.pathExists(registryPath)) { + log(`registry contents:\n${await fs.readFile(registryPath, "utf8")}`); + } +}; + +const runLoggedStep = async ( + label: string, + action: () => Promise, + dumpState: () => Promise, + timeoutMs = STEP_TIMEOUT_MS, +): Promise => { + const startedAt = Date.now(); + const progressTimer = setInterval(() => { + log(`${label}: still running (${Math.round((Date.now() - startedAt) / 1000)}s elapsed)`); + }, 10_000); + const timeoutTimer = setTimeout(() => { + clearInterval(progressTimer); + console.error(`${LOG_PREFIX} ${label}: timed out after ${timeoutMs}ms`); + + void (async (): Promise => { + try { + await dumpState(); + } finally { + process.exit(1); + } + })(); + }, timeoutMs); + + try { + log(`${label}: start`); + const result = await action(); + + log(`${label}: finished in ${Date.now() - startedAt}ms`); + + return result; + } catch (err) { + console.error(`${LOG_PREFIX} ${label}: failed after ${Date.now() - startedAt}ms`, err); + throw err; + } finally { + clearTimeout(timeoutTimer); + try { + await dumpState(); + } finally { + clearInterval(progressTimer); + } + } +}; + +const createDownloadProgressLogger = ( + label: string, + downloadProgressCallback: DownloadProgressCallback, +): DownloadProgressCallback => { + let lastLoggedPercent = -1; + let lastLoggedAt = 0; + + return (done, total = 0) => { + downloadProgressCallback(done, total); + + const now = Date.now(); + const percent = total > 0 ? Math.floor((done / total) * 100) : null; + const shouldLog = + percent === null + ? now - lastLoggedAt >= 10_000 + : percent === 100 || percent >= lastLoggedPercent + 10 || now - lastLoggedAt >= 10_000; + + if (!shouldLog) { + return; + } + + lastLoggedAt = now; + lastLoggedPercent = percent ?? lastLoggedPercent; + + log( + `${label}: downloaded ${formatBytes(done)}${total > 0 ? ` / ${formatBytes(total)} (${percent}%)` : ""}`, + ); + }; +}; + +const installWithNativeUnzip = async ({ + browser, + platform, + buildId, + cacheDir, + installDir, + executablePath, + label, + downloadProgressCallback, +}: { + browser: PuppeteerBrowser; + platform: BrowserPlatform; + buildId: string; + cacheDir: string; + installDir: string; + executablePath: string; + label: string; + downloadProgressCallback: DownloadProgressCallback; +}): Promise => { + const archivePath = await puppeteerInstall({ + browser, + platform, + buildId, + cacheDir, + unpack: false, + downloadProgressCallback: createDownloadProgressLogger(label, downloadProgressCallback), + }); + + log(`${label}: downloaded archive ${archivePath}`); + await fs.remove(installDir); + await fs.ensureDir(installDir); + await runCommand("unzip", ["-q", archivePath, "-d", installDir]); + await fs.chmod(executablePath, 0o755); + + return executablePath; +}; + +async function preloadStandaloneBrowser(): Promise { + const browser = { browserName: BROWSER_NAME, browserVersion: BROWSER_VERSION }; + const platform = detectBrowserPlatform(); + + if (!platform) { + throw new Error("Unable to detect browser platform"); + } + + const browserTag = `${browser.browserName}@${browser.browserVersion}`; + const chromeBuildId = await resolveBuildId( + PuppeteerBrowser.CHROME, + platform, + normalizeChromeVersion(BROWSER_VERSION), + ); + const chromeDriverBuildId = await resolveBuildId( + PuppeteerBrowser.CHROMEDRIVER, + platform, + getMilestone(BROWSER_VERSION), + ); + const chromeExecutablePath = computeExecutablePath({ + browser: PuppeteerBrowser.CHROME, + buildId: chromeBuildId, + cacheDir: getBrowsersDir(), + platform, + }); + const chromeDriverExecutablePath = computeExecutablePath({ + browser: PuppeteerBrowser.CHROMEDRIVER, + buildId: chromeDriverBuildId, + cacheDir: getChromeDriverDir(), + platform, + }); + const chromeInstallDir = getInstallDir(chromeExecutablePath); + const chromeDriverInstallDir = getInstallDir(chromeDriverExecutablePath); + const chromeCacheRoot = path.dirname(chromeInstallDir); + const chromeDriverCacheRoot = path.dirname(chromeDriverInstallDir); + const chromeDownloadUrl = getChromeForTestingUrl(PuppeteerBrowser.CHROME, platform, chromeBuildId); + const chromeDriverDownloadUrl = getChromeForTestingUrl( + PuppeteerBrowser.CHROMEDRIVER, + platform, + chromeDriverBuildId, + ); + const chromeArchivePath = getArchivePath(getBrowsersDir(), PuppeteerBrowser.CHROME, chromeBuildId, chromeDownloadUrl); + const chromeDriverArchivePath = getArchivePath( + getChromeDriverDir(), + PuppeteerBrowser.CHROMEDRIVER, + chromeDriverBuildId, + chromeDriverDownloadUrl, + ); + const ubuntu = await isUbuntu(); + const ubuntuMilestone = ubuntu ? await getUbuntuMilestone() : null; + const ubuntuPackagesDir = ubuntuMilestone ? getOsPackagesDir(LINUX_UBUNTU_RELEASE_ID, ubuntuMilestone) : null; + + dumpJson("environment", { + node: process.version, + cwd: process.cwd(), + home: process.env.HOME, + browser, + platform, + chromeBuildId, + chromeDriverBuildId, + browsersDir: getBrowsersDir(), + chromeDriverDir: getChromeDriverDir(), + registryPath: getRegistryPath(), + chromeExecutablePath, + chromeDriverExecutablePath, + chromeDownloadUrl, + chromeDriverDownloadUrl, + chromeArchivePath, + chromeDriverArchivePath, + ubuntu, + ubuntuMilestone, + ubuntuPackagesDir, + }); + + await dumpRegistry(); + if (ubuntuPackagesDir) { + await dumpDir("before ubuntu packages dir", ubuntuPackagesDir, 2); + } + await dumpDir("before chrome cache root", chromeCacheRoot, 2); + await dumpDir("before chromedriver cache root", chromeDriverCacheRoot, 2); + await dumpDir("before chrome install dir", chromeInstallDir); + await dumpDir("before chromedriver install dir", chromeDriverInstallDir); + await dumpPath("before chrome archive", chromeArchivePath); + await dumpPath("before chromedriver archive", chromeDriverArchivePath); + + if (ubuntuPackagesDir) { + await runLoggedStep( + "ubuntu packages", + installUbuntuPackageDependencies, + async () => { + await dumpRegistry(); + await dumpDir("after ubuntu packages dir", ubuntuPackagesDir, 2); + }, + ); + } else { + log("ubuntu packages: skipped, current OS is not Ubuntu"); + } + + log(`chrome binary ${chromeBuildId}: download URL ${chromeDownloadUrl}`); + const chromeCanDownload = await runLoggedStep( + `chrome binary ${chromeBuildId} availability`, + () => + canDownload({ + browser: PuppeteerBrowser.CHROME, + platform, + buildId: chromeBuildId, + cacheDir: getBrowsersDir(), + }), + async () => { + await dumpPath("chrome archive", chromeArchivePath); + await dumpDir("after chrome cache root", chromeCacheRoot, 2); + await dumpDir("after chrome install dir", chromeInstallDir); + }, + 60_000, + ); + + log(`chrome binary ${chromeBuildId} availability: ${chromeCanDownload}`); + + if (!chromeCanDownload) { + throw new Error(`Chrome binary ${chromeBuildId} is not downloadable from ${chromeDownloadUrl}`); + } + + const chromePath = await runLoggedStep( + `chrome binary ${chromeBuildId} download/extract`, + () => + registry.installBinary(PuppeteerBrowser.CHROME, platform, chromeBuildId, downloadProgressCallback => + installWithNativeUnzip({ + browser: PuppeteerBrowser.CHROME, + platform, + buildId: chromeBuildId, + cacheDir: getBrowsersDir(), + installDir: chromeInstallDir, + executablePath: chromeExecutablePath, + label: `chrome binary ${chromeBuildId}`, + downloadProgressCallback, + }), + ), + async () => { + await dumpRegistry(); + await dumpPath("chrome archive", chromeArchivePath); + await dumpPath("chrome executable", chromeExecutablePath); + await dumpDir("after chrome cache root", chromeCacheRoot, 2); + await dumpDir("after chrome install dir", chromeInstallDir); + }, + ); + + log(`chrome binary ${chromeBuildId}: installed path ${chromePath}`); + + log(`chromedriver binary ${chromeDriverBuildId}: download URL ${chromeDriverDownloadUrl}`); + const chromeDriverCanDownload = await runLoggedStep( + `chromedriver binary ${chromeDriverBuildId} availability`, + () => + canDownload({ + browser: PuppeteerBrowser.CHROMEDRIVER, + platform, + buildId: chromeDriverBuildId, + cacheDir: getChromeDriverDir(), + }), + async () => { + await dumpPath("chromedriver archive", chromeDriverArchivePath); + await dumpDir("after chromedriver cache root", chromeDriverCacheRoot, 2); + await dumpDir("after chromedriver install dir", chromeDriverInstallDir); + }, + 60_000, + ); + + log(`chromedriver binary ${chromeDriverBuildId} availability: ${chromeDriverCanDownload}`); + + if (!chromeDriverCanDownload) { + throw new Error(`Chromedriver binary ${chromeDriverBuildId} is not downloadable from ${chromeDriverDownloadUrl}`); + } + + const chromeDriverPath = await runLoggedStep( + `chromedriver binary ${chromeDriverBuildId} download/extract`, + () => + registry.installBinary( + PuppeteerBrowser.CHROMEDRIVER, + platform, + chromeDriverBuildId, + downloadProgressCallback => + installWithNativeUnzip({ + browser: PuppeteerBrowser.CHROMEDRIVER, + platform, + buildId: chromeDriverBuildId, + cacheDir: getChromeDriverDir(), + installDir: chromeDriverInstallDir, + executablePath: chromeDriverExecutablePath, + label: `chromedriver binary ${chromeDriverBuildId}`, + downloadProgressCallback, + }), + ), + async () => { + await dumpRegistry(); + await dumpPath("chromedriver archive", chromeDriverArchivePath); + await dumpPath("chromedriver executable", chromeDriverExecutablePath); + await dumpDir("after chromedriver cache root", chromeDriverCacheRoot, 2); + await dumpDir("after chromedriver install dir", chromeDriverInstallDir); + }, + ); + + log(`chromedriver binary ${chromeDriverBuildId}: installed path ${chromeDriverPath}`); + log(`finished installing ${browserTag}`); +} + +(async (): Promise => { + try { + await preloadStandaloneBrowser(); + log("preload completed"); + } catch (err) { + console.error(`${LOG_PREFIX} preload failed`, err); + process.exitCode = 1; + } +})(); diff --git a/test/integration/standalone/constants.ts b/test/integration/standalone/constants.ts index 7acab6565..948d21b8b 100644 --- a/test/integration/standalone/constants.ts +++ b/test/integration/standalone/constants.ts @@ -1,11 +1,12 @@ import _ from "lodash"; export const BROWSER_NAME = (process.env.BROWSER || "chrome").toLowerCase(); +export const BROWSER_VERSION = process.env.INTEGRATION_BROWSER_VERSION || "138.0"; export const BROWSER_CONFIG = { desiredCapabilities: { browserName: BROWSER_NAME, - browserVersion: "138.0", + browserVersion: BROWSER_VERSION, }, headless: true, system: { diff --git a/test/integration/standalone/preload-browser.fixture.ts b/test/integration/standalone/preload-browser.fixture.ts deleted file mode 100644 index 6dadebc0c..000000000 --- a/test/integration/standalone/preload-browser.fixture.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { launchBrowser } from "../../../src/browser/standalone"; -import { BROWSER_CONFIG } from "./constants"; - -exports.mochaGlobalSetup = async function (): Promise { - // Here we trigger downloading browsers before running tests - const browser = await launchBrowser(BROWSER_CONFIG); - await browser.deleteSession(); -}; From 5a7846b34b69e47c32a82dbb840700189dd6eed7 Mon Sep 17 00:00:00 2001 From: shadowusr Date: Sat, 20 Jun 2026 13:41:59 +0300 Subject: [PATCH 9/9] fix: use newer puppeteer/browsers and get rid of extract-zip that hangs on node 26 and 24 randomly --- package-lock.json | 2581 +++++++++++++++++------ package.json | 3 +- scripts/preload-standalone-browser.ts | 493 +---- src/browser-installer/chromium/utils.ts | 1 + src/browser-installer/utils.ts | 60 +- 5 files changed, 1964 insertions(+), 1174 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7c6b678c5..91e75fc3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@gemini-testing/commander": "2.15.4", "@jspm/core": "2.0.1", "@jsquash/png": "3.1.1", - "@puppeteer/browsers": "2.7.1", + "@puppeteer/browsers": "3.0.4", "@testplane/wdio-protocols": "9.4.7", "@testplane/wdio-utils": "9.5.4", "@testplane/webdriverio": "9.5.28", @@ -27,7 +27,6 @@ "error-stack-parser": "2.1.4", "esbuild": "0.25.8", "expect-webdriverio": "3.6.0", - "extract-zip": "2.0.1", "fs-extra": "7.0.1", "geckodriver": "4.5.0", "gemini-configparser": "1.4.2", @@ -1794,23 +1793,27 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.7.1.tgz", - "integrity": "sha512-MK7rtm8JjaxPN7Mf1JdZIZKPD2Z+W7osvrC1vjpvfOX1K0awDIHYbNi89f7eotp7eMUn2shWnt03HwVbriXtKQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.0.4.tgz", + "integrity": "sha512-HGM8iAmGTf+Y7t0373szVbTmt3d7vPkYL/1bpOkOFO0YUYLgSeuYBCzESklogNPvOBnZ/MRD5f07OkpqH1trtA==", + "license": "Apache-2.0", "dependencies": { - "debug": "^4.4.0", - "extract-zip": "^2.0.1", - "progress": "^2.0.3", - "proxy-agent": "^6.5.0", - "semver": "^7.7.0", - "tar-fs": "^3.0.8", + "modern-tar": "^0.7.6", "yargs": "^17.7.2" }, "bin": { - "browsers": "lib/cjs/main-cli.js" + "browsers": "lib/main-cli.js" }, "engines": { - "node": ">=18" + "node": ">=22.12.0" + }, + "peerDependencies": { + "proxy-agent": ">=8.0.1" + }, + "peerDependenciesMeta": { + "proxy-agent": { + "optional": true + } } }, "node_modules/@puppeteer/browsers/node_modules/cliui": { @@ -1826,76 +1829,6 @@ "node": ">=12" } }, - "node_modules/@puppeteer/browsers/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@puppeteer/browsers/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/@puppeteer/browsers/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/@puppeteer/browsers/node_modules/proxy-agent": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", - "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.6", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.1.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@puppeteer/browsers/node_modules/tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0" - } - }, - "node_modules/@puppeteer/browsers/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/@puppeteer/browsers/node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -2625,29 +2558,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@testplane/geckodriver/node_modules/tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0" - } - }, - "node_modules/@testplane/geckodriver/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/@testplane/wdio-config": { "version": "9.5.4", "resolved": "https://registry.npmjs.org/@testplane/wdio-config/-/wdio-config-9.5.4.tgz", @@ -2889,6 +2799,27 @@ "node": ">=18.0.0" } }, + "node_modules/@testplane/wdio-utils/node_modules/@puppeteer/browsers": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz", + "integrity": "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.4.3", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.4", + "tar-fs": "^3.1.1", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@testplane/wdio-utils/node_modules/@testplane/wdio-types": { "version": "9.5.4", "resolved": "https://registry.npmjs.org/@testplane/wdio-types/-/wdio-types-9.5.4.tgz", @@ -2909,6 +2840,46 @@ "undici-types": "~6.21.0" } }, + "node_modules/@testplane/wdio-utils/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testplane/wdio-utils/node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@testplane/wdio-utils/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@testplane/wdio-utils/node_modules/decamelize": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", @@ -2920,6 +2891,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@testplane/wdio-utils/node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@testplane/wdio-utils/node_modules/get-port": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", @@ -2931,90 +2916,232 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@testplane/wdio-utils/node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" - }, - "node_modules/@testplane/webdriver": { - "version": "9.5.17", - "resolved": "https://registry.npmjs.org/@testplane/webdriver/-/webdriver-9.5.17.tgz", - "integrity": "sha512-ecmgc4MuLVv+XH49tGDq59TMzSzFkB5yOMOKv5xXDEMKqLwuEssWd1UmHuWYsJwTvIjbDHXto2lvfGrDRKaoPQ==", + "node_modules/@testplane/wdio-utils/node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "license": "MIT", "dependencies": { - "@testplane/wdio-config": "9.5.3", - "@testplane/wdio-logger": "9.4.6", - "@testplane/wdio-protocols": "9.4.6", - "@testplane/wdio-types": "9.5.5", - "@testplane/wdio-utils": "9.5.3", - "@types/node": "^20.1.0", - "@types/ws": "^8.5.3", - "deepmerge-ts": "^7.0.3", - "got": "12.6.1", - "ky": "0.33.0", - "undici": "6.12.0", - "ws": "^8.8.0" + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" }, "engines": { - "node": ">=18.0.0" + "node": ">= 14" } }, - "node_modules/@testplane/webdriver/node_modules/@testplane/wdio-config": { - "version": "9.5.3", - "resolved": "https://registry.npmjs.org/@testplane/wdio-config/-/wdio-config-9.5.3.tgz", - "integrity": "sha512-329lufaem6vxLq5Govv9lRzue1o2571HsFhI5TpiSH3C1x3SxQ2kQokCN2nGMS4IIEbSPjRQDuKNUuSWhS4hVA==", - "dependencies": { - "@testplane/wdio-logger": "9.4.6", - "@testplane/wdio-types": "9.5.2", - "@testplane/wdio-utils": "9.5.3", - "deepmerge-ts": "^7.0.3", - "glob": "^10.2.2", - "import-meta-resolve": "^4.0.0" - }, + "node_modules/@testplane/wdio-utils/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", "engines": { - "node": ">=18.0.0" + "node": ">=12" } }, - "node_modules/@testplane/webdriver/node_modules/@testplane/wdio-config/node_modules/@testplane/wdio-types": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/@testplane/wdio-types/-/wdio-types-9.5.2.tgz", - "integrity": "sha512-D7ge7qJmcR2CG39YBlZ8lZRSeM/yOeBmQXsFxE0LlKurG3h+pEVWiuLhFW6ow2lZvR2jR2tHXI16IRvpXz3BKQ==", + "node_modules/@testplane/wdio-utils/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/@testplane/wdio-utils/node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "license": "MIT", "dependencies": { - "@types/node": "^20.1.0" + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" }, "engines": { - "node": ">=18.0.0" + "node": ">= 14" } }, - "node_modules/@testplane/webdriver/node_modules/@testplane/wdio-protocols": { - "version": "9.4.6", - "resolved": "https://registry.npmjs.org/@testplane/wdio-protocols/-/wdio-protocols-9.4.6.tgz", - "integrity": "sha512-r++AmapEhXpShtNsYbqhX71iZSyUp7YyZV+RoamWVyvgP3ljpeU9cLksz2imyZJ5fCas1qcx9xElPKHRF/zcxw==" - }, - "node_modules/@testplane/webdriver/node_modules/@testplane/wdio-utils": { - "version": "9.5.3", - "resolved": "https://registry.npmjs.org/@testplane/wdio-utils/-/wdio-utils-9.5.3.tgz", - "integrity": "sha512-xZQqXn3ga1aY1JTTnF137lT6Evmn7Dtxs6TSlSEAG3dY+eLIZNz7n0tLNG49BYZY3l8F2k+0TdU6SZ0p28L7qA==", + "node_modules/@testplane/wdio-utils/node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", "dependencies": { - "@puppeteer/browsers": "^2.2.0", - "@testplane/edgedriver": "^6.1.4", - "@testplane/geckodriver": "^5.0.2", - "@testplane/wdio-logger": "9.4.6", - "@testplane/wdio-types": "9.5.2", - "decamelize": "^6.0.0", - "deepmerge-ts": "^7.0.3", - "get-port": "^7.0.0", - "import-meta-resolve": "^4.0.0", - "locate-app": "^2.2.24", - "safaridriver": "^1.0.0", - "split2": "^4.2.0", - "wait-port": "^1.1.0" + "degenerator": "^5.0.0", + "netmask": "^2.0.2" }, "engines": { - "node": ">=18.0.0" + "node": ">= 14" } }, - "node_modules/@testplane/webdriver/node_modules/@testplane/wdio-utils/node_modules/@testplane/wdio-types": { + "node_modules/@testplane/wdio-utils/node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@testplane/wdio-utils/node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@testplane/wdio-utils/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/@testplane/wdio-utils/node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testplane/wdio-utils/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@testplane/webdriver": { + "version": "9.5.17", + "resolved": "https://registry.npmjs.org/@testplane/webdriver/-/webdriver-9.5.17.tgz", + "integrity": "sha512-ecmgc4MuLVv+XH49tGDq59TMzSzFkB5yOMOKv5xXDEMKqLwuEssWd1UmHuWYsJwTvIjbDHXto2lvfGrDRKaoPQ==", + "dependencies": { + "@testplane/wdio-config": "9.5.3", + "@testplane/wdio-logger": "9.4.6", + "@testplane/wdio-protocols": "9.4.6", + "@testplane/wdio-types": "9.5.5", + "@testplane/wdio-utils": "9.5.3", + "@types/node": "^20.1.0", + "@types/ws": "^8.5.3", + "deepmerge-ts": "^7.0.3", + "got": "12.6.1", + "ky": "0.33.0", + "undici": "6.12.0", + "ws": "^8.8.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@testplane/webdriver/node_modules/@puppeteer/browsers": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz", + "integrity": "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.4.3", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.4", + "tar-fs": "^3.1.1", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testplane/webdriver/node_modules/@testplane/wdio-config": { + "version": "9.5.3", + "resolved": "https://registry.npmjs.org/@testplane/wdio-config/-/wdio-config-9.5.3.tgz", + "integrity": "sha512-329lufaem6vxLq5Govv9lRzue1o2571HsFhI5TpiSH3C1x3SxQ2kQokCN2nGMS4IIEbSPjRQDuKNUuSWhS4hVA==", + "dependencies": { + "@testplane/wdio-logger": "9.4.6", + "@testplane/wdio-types": "9.5.2", + "@testplane/wdio-utils": "9.5.3", + "deepmerge-ts": "^7.0.3", + "glob": "^10.2.2", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@testplane/webdriver/node_modules/@testplane/wdio-config/node_modules/@testplane/wdio-types": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/@testplane/wdio-types/-/wdio-types-9.5.2.tgz", + "integrity": "sha512-D7ge7qJmcR2CG39YBlZ8lZRSeM/yOeBmQXsFxE0LlKurG3h+pEVWiuLhFW6ow2lZvR2jR2tHXI16IRvpXz3BKQ==", + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@testplane/webdriver/node_modules/@testplane/wdio-protocols": { + "version": "9.4.6", + "resolved": "https://registry.npmjs.org/@testplane/wdio-protocols/-/wdio-protocols-9.4.6.tgz", + "integrity": "sha512-r++AmapEhXpShtNsYbqhX71iZSyUp7YyZV+RoamWVyvgP3ljpeU9cLksz2imyZJ5fCas1qcx9xElPKHRF/zcxw==" + }, + "node_modules/@testplane/webdriver/node_modules/@testplane/wdio-utils": { + "version": "9.5.3", + "resolved": "https://registry.npmjs.org/@testplane/wdio-utils/-/wdio-utils-9.5.3.tgz", + "integrity": "sha512-xZQqXn3ga1aY1JTTnF137lT6Evmn7Dtxs6TSlSEAG3dY+eLIZNz7n0tLNG49BYZY3l8F2k+0TdU6SZ0p28L7qA==", + "dependencies": { + "@puppeteer/browsers": "^2.2.0", + "@testplane/edgedriver": "^6.1.4", + "@testplane/geckodriver": "^5.0.2", + "@testplane/wdio-logger": "9.4.6", + "@testplane/wdio-types": "9.5.2", + "decamelize": "^6.0.0", + "deepmerge-ts": "^7.0.3", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.2.24", + "safaridriver": "^1.0.0", + "split2": "^4.2.0", + "wait-port": "^1.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@testplane/webdriver/node_modules/@testplane/wdio-utils/node_modules/@testplane/wdio-types": { "version": "9.5.2", "resolved": "https://registry.npmjs.org/@testplane/wdio-types/-/wdio-types-9.5.2.tgz", "integrity": "sha512-D7ge7qJmcR2CG39YBlZ8lZRSeM/yOeBmQXsFxE0LlKurG3h+pEVWiuLhFW6ow2lZvR2jR2tHXI16IRvpXz3BKQ==", @@ -3042,6 +3169,46 @@ "balanced-match": "^1.0.0" } }, + "node_modules/@testplane/webdriver/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testplane/webdriver/node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@testplane/webdriver/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@testplane/webdriver/node_modules/decamelize": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.1.tgz", @@ -3053,6 +3220,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@testplane/webdriver/node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@testplane/webdriver/node_modules/get-port": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.2.0.tgz", @@ -3064,6 +3245,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@testplane/webdriver/node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@testplane/webdriver/node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -3084,6 +3279,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@testplane/webdriver/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/@testplane/webdriver/node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", @@ -3098,12 +3302,110 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@testplane/webdriver/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/@testplane/webdriver/node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@testplane/webdriver/node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@testplane/webdriver/node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@testplane/webdriver/node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@testplane/webdriver/node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "license": "MIT" }, + "node_modules/@testplane/webdriver/node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testplane/webdriver/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/@testplane/webdriverio": { "version": "9.5.28", "resolved": "https://registry.npmjs.org/@testplane/webdriverio/-/webdriverio-9.5.28.tgz", @@ -3150,6 +3452,27 @@ } } }, + "node_modules/@testplane/webdriverio/node_modules/@puppeteer/browsers": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz", + "integrity": "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.4.3", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.4", + "tar-fs": "^3.1.1", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@testplane/webdriverio/node_modules/@testplane/wdio-config": { "version": "9.5.3", "resolved": "https://registry.npmjs.org/@testplane/wdio-config/-/wdio-config-9.5.3.tgz", @@ -3235,7 +3558,47 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^1.0.0" + } + }, + "node_modules/@testplane/webdriverio/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testplane/webdriverio/node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@testplane/webdriverio/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/@testplane/webdriverio/node_modules/decamelize": { @@ -3249,6 +3612,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@testplane/webdriverio/node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@testplane/webdriverio/node_modules/get-port": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.2.0.tgz", @@ -3260,6 +3637,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@testplane/webdriverio/node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@testplane/webdriverio/node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -3305,6 +3696,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@testplane/webdriverio/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/@testplane/webdriverio/node_modules/minimatch": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", @@ -3319,12 +3719,110 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@testplane/webdriverio/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/@testplane/webdriverio/node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@testplane/webdriverio/node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@testplane/webdriverio/node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@testplane/webdriverio/node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@testplane/webdriverio/node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "license": "MIT" }, + "node_modules/@testplane/webdriverio/node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testplane/webdriverio/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/@textlint/ast-node-types": { "version": "12.2.1", "dev": true, @@ -3371,7 +3869,8 @@ "node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "license": "MIT" }, "node_modules/@tsconfig/node10": { "version": "1.0.9", @@ -4471,16 +4970,6 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/archiver/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/arg": { "version": "4.1.3", "dev": true, @@ -4563,6 +5052,7 @@ "version": "0.13.4", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, @@ -4612,18 +5102,19 @@ "node_modules/bare-events": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.6.0.tgz", - "integrity": "sha512-EKZ5BTXYExaNqi3I3f9RtEsaI/xBSGjE0XZCZilPzFAV/goswFHuPd9jEZlPIZ/iNZJwDSao9qRiScySz7MbQg==", - "optional": true + "integrity": "sha512-EKZ5BTXYExaNqi3I3f9RtEsaI/xBSGjE0XZCZilPzFAV/goswFHuPd9jEZlPIZ/iNZJwDSao9qRiScySz7MbQg==" }, "node_modules/bare-fs": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.6.tgz", - "integrity": "sha512-25RsLF33BqooOEFNdMcEhMpJy8EoR88zSMrnOQOaM3USnOK2VmaJ1uaQEwPA6AQjrv1lXChScosN6CzbwbO9OQ==", - "optional": true, + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.2.tgz", + "integrity": "sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg==", + "license": "Apache-2.0", "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", - "bare-stream": "^2.6.4" + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" }, "engines": { "bare": ">=1.16.0" @@ -4641,7 +5132,6 @@ "version": "3.6.1", "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", - "optional": true, "engines": { "bare": ">=1.14.0" } @@ -4650,7 +5140,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", - "optional": true, "dependencies": { "bare-os": "^3.0.1" } @@ -4659,7 +5148,6 @@ "version": "2.6.5", "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz", "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==", - "optional": true, "dependencies": { "streamx": "^2.21.0" }, @@ -4676,6 +5164,15 @@ } } }, + "node_modules/bare-url": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.5.tgz", + "integrity": "sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==", + "license": "Apache-2.0", + "dependencies": { + "bare-path": "^3.0.0" + } + }, "node_modules/base64-arraybuffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", @@ -4711,9 +5208,10 @@ } }, "node_modules/basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz", + "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==", + "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -7121,16 +7619,22 @@ "license": "MIT" }, "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-7.0.1.tgz", + "integrity": "sha512-ABErK0IefDSyHjlPH7WUEenIAX2rPPnrDcDM+TS3z3+zu9TfyKKi07BQM+8rmxpdE2y1v5fjjdoAS/x4D2U60w==", + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", "esprima": "^4.0.1" }, "engines": { - "node": ">= 14" + "node": ">= 20" + }, + "peerDependencies": { + "quickjs-wasi": "^2.2.0" } }, "node_modules/delayed-stream": { @@ -7835,6 +8339,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", @@ -7851,15 +8356,6 @@ "source-map": "~0.6.1" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/eslint": { "version": "8.25.0", "dev": true, @@ -8977,29 +9473,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/geckodriver/node_modules/tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0" - } - }, - "node_modules/geckodriver/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/geckodriver/node_modules/which": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", @@ -9123,31 +9596,39 @@ } }, "node_modules/get-uri": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", - "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-8.0.1.tgz", + "integrity": "sha512-/5N/P4Lrh0p/mDwlDRi7Y1+P2o/OyzZI3l6Iz1Ov6XXwwm1y3RlZLuo3gVgML99djrEDtV980bBxSuOeHLk8ww==", + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4", - "fs-extra": "^11.2.0" + "basic-ftp": "^5.3.1", + "data-uri-to-buffer": "8.0.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 14" + "node": ">= 20" } }, "node_modules/get-uri/node_modules/data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-8.0.0.tgz", + "integrity": "sha512-6UHfyCux51b8PTGDgveqtz1tvphBku5DrMKKJbFAZAJOI2zsjDpDoYE1+QGj7FOMS4BdTFNJsJiR3zEB0xH0yQ==", + "license": "MIT", + "optional": true, + "peer": true, "engines": { - "node": ">= 14" + "node": ">= 20" } }, "node_modules/get-uri/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -9160,42 +9641,13 @@ } } }, - "node_modules/get-uri/node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/get-uri/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/get-uri/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/get-uri/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.0" - } + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/git-raw-commits": { "version": "4.0.0", @@ -9472,14 +9924,6 @@ "uglify-js": "^3.1.4" } }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/handlebars/node_modules/uglify-js": { "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", @@ -10095,13 +10539,10 @@ } }, "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", + "license": "MIT", "engines": { "node": ">= 12" } @@ -10537,11 +10978,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" - }, "node_modules/jsdom": { "version": "24.0.0", "dev": true, @@ -11816,6 +12252,15 @@ "version": "6.2.1", "license": "Apache-2.0" }, + "node_modules/modern-tar": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.7.6.tgz", + "integrity": "sha512-sweCIVXzx1aIGTCdzcMlSZt1h8k5Tmk08VNAuRk3IU28XamGiOH5ypi11g6De2CH7PhYqSSnGy2A/EFhbWnVKg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/modify-values": { "version": "1.0.1", "dev": true, @@ -11947,9 +12392,10 @@ "license": "MIT" }, "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz", + "integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -12378,27 +12824,44 @@ } }, "node_modules/pac-proxy-agent": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", - "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-9.1.0.tgz", + "integrity": "sha512-1aU+1mpj3DrQPfo3gh+3Gap3G5x+axnMx1P/y0ZF2ch7kb2meyOCAH8K2k9d27ROsTE7TnAerzxqF9aon2jqnA==", + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.1.2", + "agent-base": "9.0.0", "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.6", - "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.5" + "get-uri": "8.0.1", + "http-proxy-agent": "9.1.0", + "https-proxy-agent": "9.1.0", + "pac-resolver": "9.0.1", + "quickjs-wasi": "^2.2.0", + "socks-proxy-agent": "10.1.0" }, "engines": { - "node": ">= 14" + "node": ">= 20" + } + }, + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 20" } }, "node_modules/pac-proxy-agent/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -12411,21 +12874,62 @@ } } }, + "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-9.1.0.tgz", + "integrity": "sha512-2NxoveTT58mjYT4n3RPTEfCZGLMbidoO8XEieXfpSYxu+PQJ1qpx4ypwH6N+uF9twBPIvRRgvkvW5HUTYWENig==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.1.0.tgz", + "integrity": "sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/pac-proxy-agent/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-9.0.1.tgz", + "integrity": "sha512-lJbS008tmkj08VhoM8Hzuv/VE5tK9MS0OIQ/7+s0lIF+BYhiQWFYzkSpML7lXs9iBu2jfmzBTLzhe9n6BX+dYw==", + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "degenerator": "^5.0.0", + "degenerator": "7.0.1", "netmask": "^2.0.2" }, "engines": { - "node": ">= 14" + "node": ">= 20" + }, + "peerDependencies": { + "quickjs-wasi": "^2.2.0" } }, "node_modules/package-json-from-dist": { @@ -12830,27 +13334,62 @@ } }, "node_modules/proxy-agent": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", - "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-8.0.2.tgz", + "integrity": "sha512-idLLRewuemWd7GH/BDJzGiB0dWGfT2SQs3jy6NtZtGWU9uPTTSdeC1/cdbqLwgzhfv027daGFuXX426e2Eg20A==", + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "9.0.0", "debug": "^4.3.4", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", + "http-proxy-agent": "9.1.0", + "https-proxy-agent": "9.1.0", "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.1" + "pac-proxy-agent": "9.1.0", + "proxy-from-env": "^2.0.0", + "socks-proxy-agent": "10.1.0" }, "engines": { - "node": ">= 14" + "node": ">= 20" + } + }, + "node_modules/proxy-agent-negotiate": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-agent-negotiate/-/proxy-agent-negotiate-1.1.0.tgz", + "integrity": "sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "kerberos": "^2.0.0" + }, + "peerDependenciesMeta": { + "kerberos": { + "optional": true + } + } + }, + "node_modules/proxy-agent/node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 20" } }, "node_modules/proxy-agent/node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "optional": true, + "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -12863,10 +13402,44 @@ } } }, + "node_modules/proxy-agent/node_modules/http-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-9.1.0.tgz", + "integrity": "sha512-2NxoveTT58mjYT4n3RPTEfCZGLMbidoO8XEieXfpSYxu+PQJ1qpx4ypwH6N+uF9twBPIvRRgvkvW5HUTYWENig==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.1.0.tgz", + "integrity": "sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/proxy-agent/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "optional": true, + "peer": true, "engines": { "node": ">=12" } @@ -12874,7 +13447,20 @@ "node_modules/proxy-agent/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "optional": true, + "peer": true + }, + "node_modules/proxy-agent/node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + } }, "node_modules/proxy-from-env": { "version": "1.1.0", @@ -12979,56 +13565,167 @@ "browsers": "lib/cjs/main-cli.js" }, "engines": { - "node": ">=16.3.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=16.3.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/puppeteer-core/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/puppeteer-core/node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/puppeteer-core/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/puppeteer-core/node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/puppeteer-core/node_modules/devtools-protocol": { + "version": "0.0.1147663", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", + "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==" + }, + "node_modules/puppeteer-core/node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/puppeteer-core/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/puppeteer-core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/puppeteer-core/node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/puppeteer-core/node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/puppeteer-core/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/puppeteer-core/node_modules/proxy-agent": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", + "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.1" }, "engines": { - "node": ">=12" + "node": ">= 14" } }, - "node_modules/puppeteer-core/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/puppeteer-core/node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 14" } }, - "node_modules/puppeteer-core/node_modules/devtools-protocol": { - "version": "0.0.1147663", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", - "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==" - }, - "node_modules/puppeteer-core/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/puppeteer-core/node_modules/tar-fs": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", @@ -13039,16 +13736,6 @@ "tar-stream": "^3.1.5" } }, - "node_modules/puppeteer-core/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/puppeteer-core/node_modules/ws": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", @@ -13180,6 +13867,14 @@ "node": ">=8" } }, + "node_modules/quickjs-wasi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/quickjs-wasi/-/quickjs-wasi-2.2.0.tgz", + "integrity": "sha512-zQxXmQMrEoD3S+jQdYsloq4qAuaxKFHZj6hHqOYGwB2iQZH+q9e/lf5zQPXCKOk0WJuAjzRFbO4KwHIp2D05Iw==", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/randombytes": { "version": "2.1.0", "license": "MIT", @@ -13393,14 +14088,6 @@ "node": ">=4" } }, - "node_modules/recast/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/redent": { "version": "3.0.0", "dev": true, @@ -13800,9 +14487,10 @@ } }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -14119,6 +14807,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -14276,11 +14965,12 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz", + "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==", + "license": "MIT", "dependencies": { - "ip-address": "^9.0.5", + "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -14289,22 +14979,39 @@ } }, "node_modules/socks-proxy-agent": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-10.1.0.tgz", + "integrity": "sha512-WlMj/67cEJ6MDI1OcsnjuYKDNDoyPCCYZ249kuuXPiMDw9F8PXkVaQ7YWu3siTydfQ/4BEZcvGzu+aYvz7dDCQ==", + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "agent-base": "^7.1.2", + "agent-base": "9.0.0", "debug": "^4.3.4", "socks": "^2.8.3" }, "engines": { - "node": ">= 14" + "node": ">= 20" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 20" } }, "node_modules/socks-proxy-agent/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -14320,7 +15027,19 @@ "node_modules/socks-proxy-agent/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } }, "node_modules/source-map-js": { "version": "1.2.1", @@ -14396,11 +15115,6 @@ "node": ">= 10.x" } }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" - }, "node_modules/stack-utils": { "version": "2.0.6", "license": "MIT", @@ -14747,6 +15461,32 @@ "acorn-node": "^1.2.0" } }, + "node_modules/tar-fs": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.2.tgz", + "integrity": "sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/tar-stream": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz", + "integrity": "sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==", + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "bare-fs": "^4.5.5", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/temp": { "version": "0.8.3", "engines": [ @@ -17567,16 +18307,11 @@ } }, "@puppeteer/browsers": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.7.1.tgz", - "integrity": "sha512-MK7rtm8JjaxPN7Mf1JdZIZKPD2Z+W7osvrC1vjpvfOX1K0awDIHYbNi89f7eotp7eMUn2shWnt03HwVbriXtKQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.0.4.tgz", + "integrity": "sha512-HGM8iAmGTf+Y7t0373szVbTmt3d7vPkYL/1bpOkOFO0YUYLgSeuYBCzESklogNPvOBnZ/MRD5f07OkpqH1trtA==", "requires": { - "debug": "^4.4.0", - "extract-zip": "^2.0.1", - "progress": "^2.0.3", - "proxy-agent": "^6.5.0", - "semver": "^7.7.0", - "tar-fs": "^3.0.8", + "modern-tar": "^0.7.6", "yargs": "^17.7.2" }, "dependencies": { @@ -17590,60 +18325,6 @@ "wrap-ansi": "^7.0.0" } }, - "debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "requires": { - "ms": "^2.1.3" - } - }, - "lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "proxy-agent": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", - "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", - "requires": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.6", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.1.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.5" - } - }, - "tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", - "requires": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -18083,27 +18764,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==" - }, - "tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", - "requires": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } } } }, @@ -18303,36 +18963,171 @@ "wait-port": "^1.1.0" }, "dependencies": { + "@puppeteer/browsers": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz", + "integrity": "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==", + "requires": { + "debug": "^4.4.3", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.4", + "tar-fs": "^3.1.1", + "yargs": "^17.7.2" + } + }, "@testplane/wdio-types": { "version": "9.5.4", "resolved": "https://registry.npmjs.org/@testplane/wdio-types/-/wdio-types-9.5.4.tgz", "integrity": "sha512-r6M7+T9lSEAiuM79XN3tc1/ARMayEINmvjjgroRgOKGv9Eks3KlzqJIjqhhHZcms9MtTueYvhrL/qUcAn4t9rA==", "requires": { - "@types/node": "^20.1.0" + "@types/node": "^20.1.0" + } + }, + "@types/node": { + "version": "20.19.42", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.42.tgz", + "integrity": "sha512-5L7SUaFC1RyDraj2yRhyBzHTobyXHmohD100CChNtyPyleoq37Mqab5Gn8XEKI04dfN/oqPdpHk38MgcQWHbZg==", + "requires": { + "undici-types": "~6.21.0" + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==" + }, + "debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "requires": { + "ms": "^2.1.3" + } + }, + "decamelize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", + "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==" + }, + "degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "requires": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + } + }, + "get-port": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", + "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==" + }, + "get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "requires": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + } + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "requires": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" } }, - "@types/node": { - "version": "20.19.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.42.tgz", - "integrity": "sha512-5L7SUaFC1RyDraj2yRhyBzHTobyXHmohD100CChNtyPyleoq37Mqab5Gn8XEKI04dfN/oqPdpHk38MgcQWHbZg==", + "pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "requires": { - "undici-types": "~6.21.0" + "degenerator": "^5.0.0", + "netmask": "^2.0.2" } }, - "decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==" + "proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "requires": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + } }, - "get-port": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", - "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==" + "socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "requires": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + } }, "undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" + }, + "yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" } } }, @@ -18355,6 +19150,20 @@ "ws": "^8.8.0" }, "dependencies": { + "@puppeteer/browsers": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz", + "integrity": "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==", + "requires": { + "debug": "^4.4.3", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.4", + "tar-fs": "^3.1.1", + "yargs": "^17.7.2" + } + }, "@testplane/wdio-config": { "version": "9.5.3", "resolved": "https://registry.npmjs.org/@testplane/wdio-config/-/wdio-config-9.5.3.tgz", @@ -18429,16 +19238,59 @@ "balanced-match": "^1.0.0" } }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==" + }, + "debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "requires": { + "ms": "^2.1.3" + } + }, "decamelize": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.1.tgz", "integrity": "sha512-G7Cqgaelq68XHJNGlZ7lrNQyhZGsFqpwtGFexqUv4IQdjKoSYF7ipZ9UuTJZUSQXFj/XaoBLuEVIVqr8EJngEQ==" }, + "degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "requires": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + } + }, "get-port": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.2.0.tgz", "integrity": "sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==" }, + "get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "requires": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + } + }, "glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -18452,6 +19304,11 @@ "path-scurry": "^1.11.1" } }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + }, "minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", @@ -18460,10 +19317,83 @@ "brace-expansion": "^2.0.2" } }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "requires": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + } + }, + "pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "requires": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + } + }, + "proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "requires": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + } + }, + "socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "requires": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + } + }, "undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" + }, + "yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" } } }, @@ -18501,6 +19431,20 @@ "urlpattern-polyfill": "^10.0.0" }, "dependencies": { + "@puppeteer/browsers": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz", + "integrity": "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==", + "requires": { + "debug": "^4.4.3", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.4", + "tar-fs": "^3.1.1", + "yargs": "^17.7.2" + } + }, "@testplane/wdio-config": { "version": "9.5.3", "resolved": "https://registry.npmjs.org/@testplane/wdio-config/-/wdio-config-9.5.3.tgz", @@ -18580,16 +19524,59 @@ "balanced-match": "^1.0.0" } }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==" + }, + "debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "requires": { + "ms": "^2.1.3" + } + }, "decamelize": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.1.tgz", "integrity": "sha512-G7Cqgaelq68XHJNGlZ7lrNQyhZGsFqpwtGFexqUv4IQdjKoSYF7ipZ9UuTJZUSQXFj/XaoBLuEVIVqr8EJngEQ==" }, + "degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "requires": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + } + }, "get-port": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.2.0.tgz", "integrity": "sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==" }, + "get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "requires": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + } + }, "glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -18618,6 +19605,11 @@ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + }, "minimatch": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", @@ -18626,10 +19618,83 @@ "brace-expansion": "^2.0.1" } }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "requires": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + } + }, + "pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "requires": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + } + }, + "proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "requires": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + } + }, + "socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "requires": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + } + }, "undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" + }, + "yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" } } }, @@ -19350,16 +20415,6 @@ "requires": { "safe-buffer": "~5.2.0" } - }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } } } }, @@ -19547,31 +20602,29 @@ "bare-events": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.6.0.tgz", - "integrity": "sha512-EKZ5BTXYExaNqi3I3f9RtEsaI/xBSGjE0XZCZilPzFAV/goswFHuPd9jEZlPIZ/iNZJwDSao9qRiScySz7MbQg==", - "optional": true + "integrity": "sha512-EKZ5BTXYExaNqi3I3f9RtEsaI/xBSGjE0XZCZilPzFAV/goswFHuPd9jEZlPIZ/iNZJwDSao9qRiScySz7MbQg==" }, "bare-fs": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.6.tgz", - "integrity": "sha512-25RsLF33BqooOEFNdMcEhMpJy8EoR88zSMrnOQOaM3USnOK2VmaJ1uaQEwPA6AQjrv1lXChScosN6CzbwbO9OQ==", - "optional": true, + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.2.tgz", + "integrity": "sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg==", "requires": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", - "bare-stream": "^2.6.4" + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" } }, "bare-os": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", - "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", - "optional": true + "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==" }, "bare-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", - "optional": true, "requires": { "bare-os": "^3.0.1" } @@ -19580,11 +20633,18 @@ "version": "2.6.5", "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz", "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==", - "optional": true, "requires": { "streamx": "^2.21.0" } }, + "bare-url": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.5.tgz", + "integrity": "sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==", + "requires": { + "bare-path": "^3.0.0" + } + }, "base64-arraybuffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", @@ -19598,9 +20658,9 @@ "version": "2.0.0" }, "basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==" + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz", + "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==" }, "binary-extensions": { "version": "2.2.0" @@ -21242,9 +22302,11 @@ "dev": true }, "degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-7.0.1.tgz", + "integrity": "sha512-ABErK0IefDSyHjlPH7WUEenIAX2rPPnrDcDM+TS3z3+zu9TfyKKi07BQM+8rmxpdE2y1v5fjjdoAS/x4D2U60w==", + "optional": true, + "peer": true, "requires": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", @@ -21724,14 +22786,6 @@ "estraverse": "^5.2.0", "esutils": "^2.0.2", "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true - } } }, "eslint": { @@ -22452,27 +23506,6 @@ "ansi-regex": "^6.0.1" } }, - "tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", - "requires": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "which": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", @@ -22552,57 +23585,40 @@ } }, "get-uri": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", - "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-8.0.1.tgz", + "integrity": "sha512-/5N/P4Lrh0p/mDwlDRi7Y1+P2o/OyzZI3l6Iz1Ov6XXwwm1y3RlZLuo3gVgML99djrEDtV980bBxSuOeHLk8ww==", + "optional": true, + "peer": true, "requires": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4", - "fs-extra": "^11.2.0" + "basic-ftp": "^5.3.1", + "data-uri-to-buffer": "8.0.0", + "debug": "^4.3.4" }, "dependencies": { "data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==" + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-8.0.0.tgz", + "integrity": "sha512-6UHfyCux51b8PTGDgveqtz1tvphBku5DrMKKJbFAZAJOI2zsjDpDoYE1+QGj7FOMS4BdTFNJsJiR3zEB0xH0yQ==", + "optional": true, + "peer": true }, "debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "optional": true, + "peer": true, "requires": { "ms": "^2.1.3" } }, - "fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "optional": true, + "peer": true } } }, @@ -22779,10 +23795,6 @@ "wordwrap": "^1.0.0" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "dev": true - }, "uglify-js": { "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", @@ -23176,13 +24188,9 @@ } }, "ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "requires": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - } + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==" }, "ipaddr.js": { "version": "1.9.1", @@ -23449,11 +24457,6 @@ "argparse": "^2.0.1" } }, - "jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" - }, "jsdom": { "version": "24.0.0", "dev": true, @@ -24278,6 +25281,11 @@ } } }, + "modern-tar": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.7.6.tgz", + "integrity": "sha512-sweCIVXzx1aIGTCdzcMlSZt1h8k5Tmk08VNAuRk3IU28XamGiOH5ypi11g6De2CH7PhYqSSnGy2A/EFhbWnVKg==" + }, "modify-values": { "version": "1.0.1", "dev": true @@ -24369,9 +25377,9 @@ "version": "2.1.1" }, "netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz", + "integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==" }, "nise": { "version": "5.1.9", @@ -24661,41 +25669,80 @@ "dev": true }, "pac-proxy-agent": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", - "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-9.1.0.tgz", + "integrity": "sha512-1aU+1mpj3DrQPfo3gh+3Gap3G5x+axnMx1P/y0ZF2ch7kb2meyOCAH8K2k9d27ROsTE7TnAerzxqF9aon2jqnA==", + "optional": true, + "peer": true, "requires": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.1.2", + "agent-base": "9.0.0", "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.6", - "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.5" + "get-uri": "8.0.1", + "http-proxy-agent": "9.1.0", + "https-proxy-agent": "9.1.0", + "pac-resolver": "9.0.1", + "quickjs-wasi": "^2.2.0", + "socks-proxy-agent": "10.1.0" }, "dependencies": { + "agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "optional": true, + "peer": true + }, "debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "optional": true, + "peer": true, "requires": { "ms": "^2.1.3" } }, + "http-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-9.1.0.tgz", + "integrity": "sha512-2NxoveTT58mjYT4n3RPTEfCZGLMbidoO8XEieXfpSYxu+PQJ1qpx4ypwH6N+uF9twBPIvRRgvkvW5HUTYWENig==", + "optional": true, + "peer": true, + "requires": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" + } + }, + "https-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.1.0.tgz", + "integrity": "sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==", + "optional": true, + "peer": true, + "requires": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" + } + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "optional": true, + "peer": true } } }, "pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-9.0.1.tgz", + "integrity": "sha512-lJbS008tmkj08VhoM8Hzuv/VE5tK9MS0OIQ/7+s0lIF+BYhiQWFYzkSpML7lXs9iBu2jfmzBTLzhe9n6BX+dYw==", + "optional": true, + "peer": true, "requires": { - "degenerator": "^5.0.0", + "degenerator": "7.0.1", "netmask": "^2.0.2" } }, @@ -24954,40 +26001,94 @@ } }, "proxy-agent": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", - "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-8.0.2.tgz", + "integrity": "sha512-idLLRewuemWd7GH/BDJzGiB0dWGfT2SQs3jy6NtZtGWU9uPTTSdeC1/cdbqLwgzhfv027daGFuXX426e2Eg20A==", + "optional": true, + "peer": true, "requires": { - "agent-base": "^7.0.2", + "agent-base": "9.0.0", "debug": "^4.3.4", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", + "http-proxy-agent": "9.1.0", + "https-proxy-agent": "9.1.0", "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.1" + "pac-proxy-agent": "9.1.0", + "proxy-from-env": "^2.0.0", + "socks-proxy-agent": "10.1.0" }, "dependencies": { + "agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "optional": true, + "peer": true + }, "debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "optional": true, + "peer": true, "requires": { "ms": "^2.1.3" } }, + "http-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-9.1.0.tgz", + "integrity": "sha512-2NxoveTT58mjYT4n3RPTEfCZGLMbidoO8XEieXfpSYxu+PQJ1qpx4ypwH6N+uF9twBPIvRRgvkvW5HUTYWENig==", + "optional": true, + "peer": true, + "requires": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" + } + }, + "https-proxy-agent": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.1.0.tgz", + "integrity": "sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==", + "optional": true, + "peer": true, + "requires": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" + } + }, "lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "optional": true, + "peer": true }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "optional": true, + "peer": true + }, + "proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "optional": true, + "peer": true } } }, + "proxy-agent-negotiate": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-agent-negotiate/-/proxy-agent-negotiate-1.1.0.tgz", + "integrity": "sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ==", + "optional": true, + "peer": true, + "requires": {} + }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -25085,6 +26186,11 @@ "wrap-ansi": "^7.0.0" } }, + "data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -25093,16 +26199,90 @@ "ms": "2.1.2" } }, + "degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "requires": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + } + }, "devtools-protocol": { "version": "0.0.1147663", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==" }, + "get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "requires": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + } + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "requires": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + } + }, + "pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "requires": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + } + }, + "proxy-agent": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", + "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", + "requires": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.1" + } + }, + "socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "requires": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + } + }, "tar-fs": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", @@ -25113,16 +26293,6 @@ "tar-stream": "^3.1.5" } }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "ws": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", @@ -25197,6 +26367,13 @@ "version": "4.0.1", "dev": true }, + "quickjs-wasi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/quickjs-wasi/-/quickjs-wasi-2.2.0.tgz", + "integrity": "sha512-zQxXmQMrEoD3S+jQdYsloq4qAuaxKFHZj6hHqOYGwB2iQZH+q9e/lf5zQPXCKOk0WJuAjzRFbO4KwHIp2D05Iw==", + "optional": true, + "peer": true + }, "randombytes": { "version": "2.1.0", "requires": { @@ -25362,11 +26539,6 @@ "requires": { "tslib": "^2.0.1" } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -25626,9 +26798,9 @@ } }, "semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==" + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==" }, "send": { "version": "0.19.2", @@ -25937,28 +27109,39 @@ } }, "socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz", + "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==", "requires": { - "ip-address": "^9.0.5", + "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" } }, "socks-proxy-agent": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-10.1.0.tgz", + "integrity": "sha512-WlMj/67cEJ6MDI1OcsnjuYKDNDoyPCCYZ249kuuXPiMDw9F8PXkVaQ7YWu3siTydfQ/4BEZcvGzu+aYvz7dDCQ==", + "optional": true, + "peer": true, "requires": { - "agent-base": "^7.1.2", + "agent-base": "9.0.0", "debug": "^4.3.4", "socks": "^2.8.3" }, "dependencies": { + "agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "optional": true, + "peer": true + }, "debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "optional": true, + "peer": true, "requires": { "ms": "^2.1.3" } @@ -25966,10 +27149,17 @@ "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "optional": true, + "peer": true } } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, "source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -26020,11 +27210,6 @@ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" }, - "sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" - }, "stack-utils": { "version": "2.0.6", "requires": { @@ -26255,6 +27440,28 @@ "acorn-node": "^1.2.0" } }, + "tar-fs": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.2.tgz", + "integrity": "sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==", + "requires": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "tar-stream": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz", + "integrity": "sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==", + "requires": { + "b4a": "^1.6.4", + "bare-fs": "^4.5.5", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "temp": { "version": "0.8.3", "requires": { diff --git a/package.json b/package.json index ae3dc5a1e..f0414cca4 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "@gemini-testing/commander": "2.15.4", "@jspm/core": "2.0.1", "@jsquash/png": "3.1.1", - "@puppeteer/browsers": "2.7.1", + "@puppeteer/browsers": "3.0.4", "@testplane/wdio-protocols": "9.4.7", "@testplane/wdio-utils": "9.5.4", "@testplane/webdriverio": "9.5.28", @@ -92,7 +92,6 @@ "error-stack-parser": "2.1.4", "esbuild": "0.25.8", "expect-webdriverio": "3.6.0", - "extract-zip": "2.0.1", "fs-extra": "7.0.1", "geckodriver": "4.5.0", "gemini-configparser": "1.4.2", diff --git a/scripts/preload-standalone-browser.ts b/scripts/preload-standalone-browser.ts index 5e983820e..0204f2e48 100644 --- a/scripts/preload-standalone-browser.ts +++ b/scripts/preload-standalone-browser.ts @@ -1,487 +1,16 @@ -import path from "path"; -import { spawn } from "child_process"; -import fs from "fs-extra"; -import { - Browser as PuppeteerBrowser, - BrowserPlatform, - canDownload, - computeExecutablePath, - detectBrowserPlatform, - install as puppeteerInstall, - resolveBuildId, -} from "@puppeteer/browsers"; -import registry from "../src/browser-installer/registry"; -import { getUbuntuMilestone, installUbuntuPackageDependencies, isUbuntu } from "../src/browser-installer/ubuntu-packages"; -import { LINUX_UBUNTU_RELEASE_ID } from "../src/browser-installer/constants"; -import { - getBrowsersDir, - getChromeDriverDir, - getMilestone, - getOsPackagesDir, - getRegistryPath, - normalizeChromeVersion, - type DownloadProgressCallback, -} from "../src/browser-installer/utils"; +import { BrowserInstallStatus, installBrowsersWithDrivers } from "../src/browser-installer"; import { BROWSER_NAME, BROWSER_VERSION } from "../test/integration/standalone/constants"; -const LOG_PREFIX = "[preload-standalone-browser]"; -const MAX_DIR_ENTRIES = 300; -const STEP_TIMEOUT_MS = 180_000; - -const log = (message: string): void => { - console.log(`${LOG_PREFIX} ${message}`); -}; - -const dumpJson = (label: string, value: unknown): void => { - log(`${label}: ${JSON.stringify(value, null, 2)}`); -}; - -const formatBytes = (bytes: number): string => { - if (!Number.isFinite(bytes) || bytes <= 0) { - return String(bytes); - } - - const units = ["B", "KiB", "MiB", "GiB"]; - let value = bytes; - let unitIndex = 0; - - while (value >= 1024 && unitIndex < units.length - 1) { - value /= 1024; - unitIndex++; - } - - return `${value.toFixed(unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}`; -}; - -const getInstallDir = (executablePath: string): string => path.dirname(path.dirname(executablePath)); - -const getArchivePath = (cacheRoot: string, browser: PuppeteerBrowser, buildId: string, downloadUrl: string): string => - path.join(cacheRoot, browser, `${buildId}-${downloadUrl.split("/").pop()}`); - -const getChromeForTestingPlatform = (platform: BrowserPlatform): string => { - switch (platform) { - case BrowserPlatform.LINUX: - return "linux64"; - case BrowserPlatform.MAC: - return "mac-x64"; - case BrowserPlatform.MAC_ARM: - return "mac-arm64"; - case BrowserPlatform.WIN32: - return "win32"; - case BrowserPlatform.WIN64: - return "win64"; - default: - return platform; - } -}; - -const getChromeForTestingUrl = (browser: PuppeteerBrowser, platform: BrowserPlatform, buildId: string): string => - `https://storage.googleapis.com/chrome-for-testing-public/${buildId}/${getChromeForTestingPlatform(platform)}/${browser}-${getChromeForTestingPlatform(platform)}.zip`; - -const runCommand = async (command: string, args: string[]): Promise => { - log(`running: ${command} ${args.join(" ")}`); - - await new Promise((resolve, reject) => { - const childProcess = spawn(command, args, { stdio: "inherit" }); - - childProcess.on("error", reject); - childProcess.on("exit", (code, signal) => { - if (code === 0) { - resolve(); - return; - } - - reject(new Error(`${command} exited with ${code === null ? `signal ${signal}` : `code ${code}`}`)); - }); - }); -}; - -const dumpPath = async (label: string, targetPath: string): Promise => { - if (!(await fs.pathExists(targetPath))) { - log(`${label}: missing at ${targetPath}`); - return; - } - - const stat = await fs.stat(targetPath); - - log( - `${label}: exists at ${targetPath} (${stat.isDirectory() ? "directory" : "file"}, size=${stat.size}, mode=${stat.mode.toString(8)})`, - ); -}; - -const dumpDir = async (label: string, dirPath: string, maxDepth = 3): Promise => { - log(`${label}: ${dirPath}`); - - if (!(await fs.pathExists(dirPath))) { - log(" "); - return; - } - - let entriesCount = 0; - - const walk = async (currentPath: string, depth: number, indent: string): Promise => { - if (entriesCount >= MAX_DIR_ENTRIES) { - return; - } - - const entries = (await fs.readdir(currentPath)).sort(); - - for (const entry of entries) { - if (entriesCount >= MAX_DIR_ENTRIES) { - log(`${indent}`); - return; - } - - const entryPath = path.join(currentPath, entry); - const stat = await fs.stat(entryPath); - const suffix = stat.isDirectory() ? "/" : ""; - - entriesCount++; - log(`${indent}${entry}${suffix} size=${stat.size} mode=${stat.mode.toString(8)}`); - - if (stat.isDirectory() && depth < maxDepth) { - await walk(entryPath, depth + 1, `${indent} `); - } - } - }; - - await walk(dirPath, 0, " "); - - if (entriesCount === 0) { - log(" "); - } -}; - -const dumpRegistry = async (): Promise => { - const registryPath = getRegistryPath(); - - await dumpPath("registry", registryPath); - - if (await fs.pathExists(registryPath)) { - log(`registry contents:\n${await fs.readFile(registryPath, "utf8")}`); - } -}; - -const runLoggedStep = async ( - label: string, - action: () => Promise, - dumpState: () => Promise, - timeoutMs = STEP_TIMEOUT_MS, -): Promise => { - const startedAt = Date.now(); - const progressTimer = setInterval(() => { - log(`${label}: still running (${Math.round((Date.now() - startedAt) / 1000)}s elapsed)`); - }, 10_000); - const timeoutTimer = setTimeout(() => { - clearInterval(progressTimer); - console.error(`${LOG_PREFIX} ${label}: timed out after ${timeoutMs}ms`); - - void (async (): Promise => { - try { - await dumpState(); - } finally { - process.exit(1); - } - })(); - }, timeoutMs); - - try { - log(`${label}: start`); - const result = await action(); - - log(`${label}: finished in ${Date.now() - startedAt}ms`); - - return result; - } catch (err) { - console.error(`${LOG_PREFIX} ${label}: failed after ${Date.now() - startedAt}ms`, err); - throw err; - } finally { - clearTimeout(timeoutTimer); - try { - await dumpState(); - } finally { - clearInterval(progressTimer); - } - } -}; - -const createDownloadProgressLogger = ( - label: string, - downloadProgressCallback: DownloadProgressCallback, -): DownloadProgressCallback => { - let lastLoggedPercent = -1; - let lastLoggedAt = 0; - - return (done, total = 0) => { - downloadProgressCallback(done, total); - - const now = Date.now(); - const percent = total > 0 ? Math.floor((done / total) * 100) : null; - const shouldLog = - percent === null - ? now - lastLoggedAt >= 10_000 - : percent === 100 || percent >= lastLoggedPercent + 10 || now - lastLoggedAt >= 10_000; - - if (!shouldLog) { - return; - } - - lastLoggedAt = now; - lastLoggedPercent = percent ?? lastLoggedPercent; - - log( - `${label}: downloaded ${formatBytes(done)}${total > 0 ? ` / ${formatBytes(total)} (${percent}%)` : ""}`, - ); - }; -}; - -const installWithNativeUnzip = async ({ - browser, - platform, - buildId, - cacheDir, - installDir, - executablePath, - label, - downloadProgressCallback, -}: { - browser: PuppeteerBrowser; - platform: BrowserPlatform; - buildId: string; - cacheDir: string; - installDir: string; - executablePath: string; - label: string; - downloadProgressCallback: DownloadProgressCallback; -}): Promise => { - const archivePath = await puppeteerInstall({ - browser, - platform, - buildId, - cacheDir, - unpack: false, - downloadProgressCallback: createDownloadProgressLogger(label, downloadProgressCallback), - }); - - log(`${label}: downloaded archive ${archivePath}`); - await fs.remove(installDir); - await fs.ensureDir(installDir); - await runCommand("unzip", ["-q", archivePath, "-d", installDir]); - await fs.chmod(executablePath, 0o755); - - return executablePath; -}; - -async function preloadStandaloneBrowser(): Promise { +(async (): Promise => { const browser = { browserName: BROWSER_NAME, browserVersion: BROWSER_VERSION }; - const platform = detectBrowserPlatform(); - - if (!platform) { - throw new Error("Unable to detect browser platform"); - } + const browserLabel = `${browser.browserName}@${browser.browserVersion}`; + const installResults = await installBrowsersWithDrivers([browser]); + const result = installResults[browserLabel]; - const browserTag = `${browser.browserName}@${browser.browserVersion}`; - const chromeBuildId = await resolveBuildId( - PuppeteerBrowser.CHROME, - platform, - normalizeChromeVersion(BROWSER_VERSION), - ); - const chromeDriverBuildId = await resolveBuildId( - PuppeteerBrowser.CHROMEDRIVER, - platform, - getMilestone(BROWSER_VERSION), - ); - const chromeExecutablePath = computeExecutablePath({ - browser: PuppeteerBrowser.CHROME, - buildId: chromeBuildId, - cacheDir: getBrowsersDir(), - platform, - }); - const chromeDriverExecutablePath = computeExecutablePath({ - browser: PuppeteerBrowser.CHROMEDRIVER, - buildId: chromeDriverBuildId, - cacheDir: getChromeDriverDir(), - platform, - }); - const chromeInstallDir = getInstallDir(chromeExecutablePath); - const chromeDriverInstallDir = getInstallDir(chromeDriverExecutablePath); - const chromeCacheRoot = path.dirname(chromeInstallDir); - const chromeDriverCacheRoot = path.dirname(chromeDriverInstallDir); - const chromeDownloadUrl = getChromeForTestingUrl(PuppeteerBrowser.CHROME, platform, chromeBuildId); - const chromeDriverDownloadUrl = getChromeForTestingUrl( - PuppeteerBrowser.CHROMEDRIVER, - platform, - chromeDriverBuildId, - ); - const chromeArchivePath = getArchivePath(getBrowsersDir(), PuppeteerBrowser.CHROME, chromeBuildId, chromeDownloadUrl); - const chromeDriverArchivePath = getArchivePath( - getChromeDriverDir(), - PuppeteerBrowser.CHROMEDRIVER, - chromeDriverBuildId, - chromeDriverDownloadUrl, - ); - const ubuntu = await isUbuntu(); - const ubuntuMilestone = ubuntu ? await getUbuntuMilestone() : null; - const ubuntuPackagesDir = ubuntuMilestone ? getOsPackagesDir(LINUX_UBUNTU_RELEASE_ID, ubuntuMilestone) : null; - - dumpJson("environment", { - node: process.version, - cwd: process.cwd(), - home: process.env.HOME, - browser, - platform, - chromeBuildId, - chromeDriverBuildId, - browsersDir: getBrowsersDir(), - chromeDriverDir: getChromeDriverDir(), - registryPath: getRegistryPath(), - chromeExecutablePath, - chromeDriverExecutablePath, - chromeDownloadUrl, - chromeDriverDownloadUrl, - chromeArchivePath, - chromeDriverArchivePath, - ubuntu, - ubuntuMilestone, - ubuntuPackagesDir, - }); - - await dumpRegistry(); - if (ubuntuPackagesDir) { - await dumpDir("before ubuntu packages dir", ubuntuPackagesDir, 2); - } - await dumpDir("before chrome cache root", chromeCacheRoot, 2); - await dumpDir("before chromedriver cache root", chromeDriverCacheRoot, 2); - await dumpDir("before chrome install dir", chromeInstallDir); - await dumpDir("before chromedriver install dir", chromeDriverInstallDir); - await dumpPath("before chrome archive", chromeArchivePath); - await dumpPath("before chromedriver archive", chromeDriverArchivePath); - - if (ubuntuPackagesDir) { - await runLoggedStep( - "ubuntu packages", - installUbuntuPackageDependencies, - async () => { - await dumpRegistry(); - await dumpDir("after ubuntu packages dir", ubuntuPackagesDir, 2); - }, - ); - } else { - log("ubuntu packages: skipped, current OS is not Ubuntu"); - } - - log(`chrome binary ${chromeBuildId}: download URL ${chromeDownloadUrl}`); - const chromeCanDownload = await runLoggedStep( - `chrome binary ${chromeBuildId} availability`, - () => - canDownload({ - browser: PuppeteerBrowser.CHROME, - platform, - buildId: chromeBuildId, - cacheDir: getBrowsersDir(), - }), - async () => { - await dumpPath("chrome archive", chromeArchivePath); - await dumpDir("after chrome cache root", chromeCacheRoot, 2); - await dumpDir("after chrome install dir", chromeInstallDir); - }, - 60_000, - ); - - log(`chrome binary ${chromeBuildId} availability: ${chromeCanDownload}`); - - if (!chromeCanDownload) { - throw new Error(`Chrome binary ${chromeBuildId} is not downloadable from ${chromeDownloadUrl}`); - } - - const chromePath = await runLoggedStep( - `chrome binary ${chromeBuildId} download/extract`, - () => - registry.installBinary(PuppeteerBrowser.CHROME, platform, chromeBuildId, downloadProgressCallback => - installWithNativeUnzip({ - browser: PuppeteerBrowser.CHROME, - platform, - buildId: chromeBuildId, - cacheDir: getBrowsersDir(), - installDir: chromeInstallDir, - executablePath: chromeExecutablePath, - label: `chrome binary ${chromeBuildId}`, - downloadProgressCallback, - }), - ), - async () => { - await dumpRegistry(); - await dumpPath("chrome archive", chromeArchivePath); - await dumpPath("chrome executable", chromeExecutablePath); - await dumpDir("after chrome cache root", chromeCacheRoot, 2); - await dumpDir("after chrome install dir", chromeInstallDir); - }, - ); - - log(`chrome binary ${chromeBuildId}: installed path ${chromePath}`); - - log(`chromedriver binary ${chromeDriverBuildId}: download URL ${chromeDriverDownloadUrl}`); - const chromeDriverCanDownload = await runLoggedStep( - `chromedriver binary ${chromeDriverBuildId} availability`, - () => - canDownload({ - browser: PuppeteerBrowser.CHROMEDRIVER, - platform, - buildId: chromeDriverBuildId, - cacheDir: getChromeDriverDir(), - }), - async () => { - await dumpPath("chromedriver archive", chromeDriverArchivePath); - await dumpDir("after chromedriver cache root", chromeDriverCacheRoot, 2); - await dumpDir("after chromedriver install dir", chromeDriverInstallDir); - }, - 60_000, - ); - - log(`chromedriver binary ${chromeDriverBuildId} availability: ${chromeDriverCanDownload}`); - - if (!chromeDriverCanDownload) { - throw new Error(`Chromedriver binary ${chromeDriverBuildId} is not downloadable from ${chromeDriverDownloadUrl}`); - } - - const chromeDriverPath = await runLoggedStep( - `chromedriver binary ${chromeDriverBuildId} download/extract`, - () => - registry.installBinary( - PuppeteerBrowser.CHROMEDRIVER, - platform, - chromeDriverBuildId, - downloadProgressCallback => - installWithNativeUnzip({ - browser: PuppeteerBrowser.CHROMEDRIVER, - platform, - buildId: chromeDriverBuildId, - cacheDir: getChromeDriverDir(), - installDir: chromeDriverInstallDir, - executablePath: chromeDriverExecutablePath, - label: `chromedriver binary ${chromeDriverBuildId}`, - downloadProgressCallback, - }), - ), - async () => { - await dumpRegistry(); - await dumpPath("chromedriver archive", chromeDriverArchivePath); - await dumpPath("chromedriver executable", chromeDriverExecutablePath); - await dumpDir("after chromedriver cache root", chromeDriverCacheRoot, 2); - await dumpDir("after chromedriver install dir", chromeDriverInstallDir); - }, - ); - - log(`chromedriver binary ${chromeDriverBuildId}: installed path ${chromeDriverPath}`); - log(`finished installing ${browserTag}`); -} - -(async (): Promise => { - try { - await preloadStandaloneBrowser(); - log("preload completed"); - } catch (err) { - console.error(`${LOG_PREFIX} preload failed`, err); - process.exitCode = 1; + if (result?.status !== BrowserInstallStatus.Ok) { + throw new Error(`Failed to preload standalone browser ${browserLabel}`); } -})(); +})().catch(err => { + console.error(err); + process.exitCode = 1; +}); diff --git a/src/browser-installer/chromium/utils.ts b/src/browser-installer/chromium/utils.ts index e637bfdc8..c1b1742db 100644 --- a/src/browser-installer/chromium/utils.ts +++ b/src/browser-installer/chromium/utils.ts @@ -14,6 +14,7 @@ export const getChromiumBuildId = async (platform: BrowserPlatform, milestone: s export const getChromeDriverArchiveUrl = (version: string): string => { const chromeDriverArchiveName: Record = { linux: "linux64", + linux_arm: "linux64", // eslint-disable-line camelcase mac: "mac64", mac_arm: "mac64_m1", // eslint-disable-line camelcase win32: "win32", diff --git a/src/browser-installer/utils.ts b/src/browser-installer/utils.ts index 43cdd4fc6..b94d0f83b 100644 --- a/src/browser-installer/utils.ts +++ b/src/browser-installer/utils.ts @@ -1,10 +1,11 @@ import { detectBrowserPlatform, BrowserPlatform, Browser as PuppeteerBrowser } from "@puppeteer/browsers"; -import extractZip from "extract-zip"; import os from "os"; import path from "path"; import fs from "fs-extra"; +import { execFile } from "child_process"; import { Readable } from "stream"; import debug from "debug"; +import { promisify } from "util"; import { MIN_CHROMIUM_MAC_ARM_VERSION } from "./constants"; import type { BrowserName } from "../browser/types"; @@ -12,6 +13,8 @@ export type DownloadProgressCallback = (done: number, total?: number) => void; export const browserInstallerDebug = debug("testplane:browser-installer"); +const execFileAsync = promisify(execFile); + export const DriverName = { CHROMEDRIVER: PuppeteerBrowser.CHROMEDRIVER, GECKODRIVER: "geckodriver", @@ -153,7 +156,58 @@ export const downloadFile = async (url: string, filePath: string): Promise }; export const unzipFile = async (zipPath: string, outputDir: string): Promise => { - await extractZip(zipPath, { dir: outputDir }); + await fs.ensureDir(outputDir); + + const windowsSystemRoot = process.env.SystemRoot ?? process.env.SYSTEMROOT ?? "C:\\Windows"; + + // Mirrors @puppeteer/browsers native zip extraction: + // https://github.com/puppeteer/puppeteer/blob/main/packages/browsers/src/fileUtil.ts#L195-L233 + const attempts = + process.platform === "win32" + ? [ + { + command: path.win32.join(windowsSystemRoot, "System32", "tar.exe"), + args: ["-xf", zipPath, "-C", outputDir], + }, + { + command: "powershell.exe", + args: [ + "-NoProfile", + "-NonInteractive", + "-Command", + "& { Expand-Archive -LiteralPath $args[0] -DestinationPath $args[1] -Force }", + zipPath, + outputDir, + ], + }, + { + command: "pwsh.exe", + args: [ + "-NoProfile", + "-NonInteractive", + "-Command", + "& { Expand-Archive -LiteralPath $args[0] -DestinationPath $args[1] -Force }", + zipPath, + outputDir, + ], + }, + ] + : [{ command: "unzip", args: ["-o", zipPath, "-d", outputDir] }]; + + const errors: string[] = []; + + for (const attempt of attempts) { + try { + await execFileAsync(attempt.command, attempt.args, { windowsHide: true }); + + return outputDir; + } catch (err) { + const error = err as NodeJS.ErrnoException & { stderr?: string; stdout?: string }; + const output = [error.stdout, error.stderr].filter(Boolean).join("\n").trim(); + + errors.push(`${attempt.command} failed: ${error.message}${output ? `\n${output}` : ""}`); + } + } - return outputDir; + throw new Error(`Unable to unzip ${zipPath} to ${outputDir}:\n${errors.join("\n\n")}`); };