From 7288a6dce4d4271dfc3c499f8764b6e7dc12c1ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BC=D1=8F=D0=BD=20=D0=9C=D0=B8=D0=BD=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Thu, 19 Dec 2024 07:12:14 -0600 Subject: [PATCH] feat(tests): AVModeration tests. (#15408) * feat(tests): Adds option to skip suite. * fix(tests): Rename context to ctx to avoid clashing mocha's one. * feat(tests): Moves room name generation in hooks. Move also the proxy connection in the hooks. * fix(tests): Avatar checks when using a token. Token has its avatar so we skip the token for avatar tests. * feat(tests): Renames avatars to drop Test from name. * feat(tests): Updates dependencies. * feat(tests): Fix end test log. * feat(tests): AVModeration tests. --- package-lock.json | 1795 ++++++++++------- package.json | 16 +- tests/env.example | 1 + tests/globals.d.ts | 2 +- tests/helpers/Participant.ts | 41 +- tests/helpers/participants.ts | 113 +- tests/helpers/types.ts | 6 + tests/pageobjects/AVModerationMenu.ts | 66 + tests/pageobjects/Filmstrip.ts | 56 +- tests/pageobjects/Notifications.ts | 54 + tests/pageobjects/ParticipantsPane.ts | 91 +- tests/pageobjects/Toolbar.ts | 10 + tests/specs/2way/audioOnly.spec.ts | 30 +- ... => iFrameApiParticipantsPresence.spec.ts} | 74 +- tests/specs/3way/activeSpeaker.spec.ts | 26 +- tests/specs/3way/audioVideoModeration.spec.ts | 284 +++ tests/specs/3way/avatarTest.spec.ts | 189 -- tests/specs/3way/avatars.spec.ts | 202 ++ tests/tsconfig.json | 4 +- tests/wdio.conf.ts | 53 +- 20 files changed, 2081 insertions(+), 1032 deletions(-) create mode 100644 tests/pageobjects/AVModerationMenu.ts create mode 100644 tests/pageobjects/Notifications.ts rename tests/specs/2way/{iFrameParticipantsPresence.spec.ts => iFrameApiParticipantsPresence.spec.ts} (86%) create mode 100644 tests/specs/3way/audioVideoModeration.spec.ts delete mode 100644 tests/specs/3way/avatarTest.spec.ts create mode 100644 tests/specs/3way/avatars.spec.ts diff --git a/package-lock.json b/package-lock.json index 773c83e093..8a438c3c8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -133,10 +133,10 @@ "@types/amplitude-js": "8.16.5", "@types/audioworklet": "0.0.29", "@types/dom-screen-wake-lock": "1.0.1", - "@types/jasmine": "5.1.4", "@types/js-md5": "0.4.3", "@types/jsonwebtoken": "9.0.7", "@types/lodash-es": "4.17.12", + "@types/mocha": "10.0.10", "@types/moment-duration-format": "2.2.6", "@types/offscreencanvas": "2019.7.2", "@types/pixelmatch": "5.2.5", @@ -156,12 +156,12 @@ "@types/zxcvbn": "4.4.1", "@typescript-eslint/eslint-plugin": "5.59.5", "@typescript-eslint/parser": "5.59.5", - "@wdio/allure-reporter": "9.2.14", - "@wdio/cli": "9.4.1", - "@wdio/globals": "9.4.1", - "@wdio/jasmine-framework": "9.4.1", - "@wdio/junit-reporter": "9.2.14", - "@wdio/local-runner": "9.4.1", + "@wdio/allure-reporter": "9.4.3", + "@wdio/cli": "9.4.3", + "@wdio/globals": "9.4.3", + "@wdio/junit-reporter": "9.4.3", + "@wdio/local-runner": "9.4.3", + "@wdio/mocha-framework": "9.4.3", "babel-loader": "9.1.0", "babel-plugin-optional-require": "0.3.1", "circular-dependency-plugin": "5.2.0", @@ -185,7 +185,7 @@ "ts-loader": "9.4.2", "typescript": "5.0.4", "unorm": "1.6.0", - "webdriverio": "9.4.1", + "webdriverio": "9.4.3", "webpack": "5.95.0", "webpack-bundle-analyzer": "4.4.2", "webpack-cli": "5.1.4", @@ -4709,20 +4709,22 @@ "url": "https://github.com/webgptorg/promptbook/blob/main/README.md#%EF%B8%8F-contributing" } ], + "license": "CC-BY-4.0", "dependencies": { "spacetrim": "0.11.59" } }, "node_modules/@puppeteer/browsers": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.1.tgz", - "integrity": "sha512-0kdAbmic3J09I6dT8e9vE2JOCSt13wHCW5x/ly8TSt2bDtuIWe2TgLZZDHdcziw9AVCzflMAXCrVyRIhIs44Ng==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.6.1.tgz", + "integrity": "sha512-aBSREisdsGH890S2rQqK82qmQYU3uFpSH8wcZWHgHzl3LfzsxAKbLNiAG9mO8v1Y0UICBeClICxPJvyr0rcuxg==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "debug": "^4.3.7", + "debug": "^4.4.0", "extract-zip": "^2.0.1", "progress": "^2.0.3", - "proxy-agent": "^6.4.0", + "proxy-agent": "^6.5.0", "semver": "^7.6.3", "tar-fs": "^3.0.6", "unbzip2-stream": "^1.4.3", @@ -4736,10 +4738,11 @@ } }, "node_modules/@puppeteer/browsers/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -4756,13 +4759,15 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@puppeteer/browsers/node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -6949,7 +6954,8 @@ "version": "0.23.0", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@trysound/sax": { "version": "0.2.0", @@ -7112,12 +7118,6 @@ "@types/istanbul-lib-report": "*" } }, - "node_modules/@types/jasmine": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.4.tgz", - "integrity": "sha512-px7OMFO/ncXxixDe1zR13V1iycqWae0MxTaw62RpFlksUi5QuNWgQJFkTQjIOvrmutJbI7Fp2Y2N1F6D2R4G6w==", - "dev": true - }, "node_modules/@types/js-cookie": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", @@ -7145,6 +7145,7 @@ "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", "integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -7175,6 +7176,13 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/moment-duration-format": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/@types/moment-duration-format/-/moment-duration-format-2.2.6.tgz", @@ -7414,7 +7422,8 @@ "version": "8.1.5", "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/sockjs": { "version": "0.3.36", @@ -7472,7 +7481,8 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/wrap-ansi": { "version": "3.0.0", @@ -7507,6 +7517,7 @@ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "@types/node": "*" @@ -7887,14 +7898,15 @@ } }, "node_modules/@wdio/allure-reporter": { - "version": "9.2.14", - "resolved": "https://registry.npmjs.org/@wdio/allure-reporter/-/allure-reporter-9.2.14.tgz", - "integrity": "sha512-ErIRuwEpc9a3BOGxQt+ypWwXgJA6hkFW57z6F5KHzmjEvXa24BsHY7dcQZOThf3RTun0upjMCQQlqY0loYVOmg==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/allure-reporter/-/allure-reporter-9.4.3.tgz", + "integrity": "sha512-VMSNzhsJz03K2/4tAklx/X/Wdn8c8HnEMBu+kcaBxeaExjw+/SWglCiH/NjR32XkGaopW9Mj8WlrnKq+G1vDaw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0", - "@wdio/reporter": "9.2.14", - "@wdio/types": "9.2.2", + "@wdio/reporter": "9.4.3", + "@wdio/types": "9.4.3", "allure-js-commons": "^2.5.0", "csv-stringify": "^6.0.4", "strip-ansi": "^7.1.0" @@ -7931,23 +7943,23 @@ } }, "node_modules/@wdio/cli": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-9.4.1.tgz", - "integrity": "sha512-GDyAer63WDsr2ckXmrpUyAcIZFd3pCRIpi85rL1ZjnWthRy/UtwY0EHPMDuSeUEJ28iYwW3esKgq2ZKlsdbMeA==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-9.4.3.tgz", + "integrity": "sha512-N5hVlpwFjmEvky0A/sKNj3879dzPZvFhUFSAE/g0588TFX0J3eD20TPV8T8eoIPk1vHmWda6V8DCJbWyqP4dlw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.1", "@vitest/snapshot": "^2.1.1", - "@wdio/config": "9.2.8", - "@wdio/globals": "9.4.1", + "@wdio/config": "9.4.3", + "@wdio/globals": "9.4.3", "@wdio/logger": "9.1.3", "@wdio/protocols": "9.2.2", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", "async-exit-hook": "^2.0.1", "chalk": "^5.2.0", "chokidar": "^4.0.0", - "cli-spinners": "^3.0.0", "dotenv": "^16.3.1", "ejs": "^3.1.9", "execa": "^9.2.0", @@ -7959,7 +7971,7 @@ "read-pkg-up": "^10.0.0", "recursive-readdir": "^2.2.3", "tsx": "^4.7.2", - "webdriverio": "9.4.1", + "webdriverio": "9.4.3", "yargs": "^17.7.2" }, "bin": { @@ -7996,18 +8008,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@wdio/cli/node_modules/cli-spinners": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.2.0.tgz", - "integrity": "sha512-pXftdQloMZzjCr3pCTIRniDcys6dDzgpgVhAHHk6TKBDbRuP1MkuetTF5KSv4YUutbOPa7+7ZrAJ2kVtbMqyXA==", - "dev": true, - "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@wdio/cli/node_modules/execa": { "version": "9.5.1", "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.1.tgz", @@ -8149,15 +8149,15 @@ } }, "node_modules/@wdio/config": { - "version": "9.2.8", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.2.8.tgz", - "integrity": "sha512-EGMmBPGJbz6RmgMjebRWkWu3fGyeTIRcusF4UA4f2tiUEKY8nbzUO/ZyDjVQNR+YVB40q0jcqAqpszYRrIzzeg==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.4.3.tgz", + "integrity": "sha512-8h3SO925efnyIOkKnaNbLbMnJpmvm4wfUWoo26kq8ZPU7DSQsEWvJ7EZ4Hw8RGu+kY4VO7r54ljicnnrFVh/ZA==", "dev": true, + "license": "MIT", "dependencies": { "@wdio/logger": "9.1.3", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", - "decamelize": "^6.0.0", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", "deepmerge-ts": "^7.0.3", "glob": "^10.2.2", "import-meta-resolve": "^4.0.0" @@ -8171,27 +8171,17 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, - "node_modules/@wdio/config/node_modules/decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@wdio/config/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -8212,6 +8202,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -8223,44 +8214,28 @@ } }, "node_modules/@wdio/globals": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-9.4.1.tgz", - "integrity": "sha512-CTVAVJ7iFyT54XF9iRmNvsDB+WSHoztJPG9XPL/mHzQ2LYfSyUR8E/j+3iHbTx3v/qRNucgPcGwhxiuY2RcaDg==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-9.4.3.tgz", + "integrity": "sha512-IyjiS6jtCMCbDedLZNUUaI9IpGAxkItfVKlGUgQ2kNcjOYUyKf/g8MEE0m8lR50yEEVENJ4rEn9IQ+foeFIZjQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18.20.0" }, "optionalDependencies": { "expect-webdriverio": "^5.0.1", - "webdriverio": "9.4.1" - } - }, - "node_modules/@wdio/jasmine-framework": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/@wdio/jasmine-framework/-/jasmine-framework-9.4.1.tgz", - "integrity": "sha512-N2X8MfsfX8JemD4DQwvSksXmBzYZxCKwuB7LaBiw+hH2YuFu+0L2ekR0Xvwtr8SpiENVEHAoiNFEj4i9dMTqlA==", - "dev": true, - "dependencies": { - "@types/node": "^20.1.0", - "@wdio/globals": "9.4.1", - "@wdio/logger": "9.1.3", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", - "expect-webdriverio": "^5.0.1", - "jasmine": "^5.0.0" - }, - "engines": { - "node": ">=18.20.0" + "webdriverio": "9.4.3" } }, "node_modules/@wdio/junit-reporter": { - "version": "9.2.14", - "resolved": "https://registry.npmjs.org/@wdio/junit-reporter/-/junit-reporter-9.2.14.tgz", - "integrity": "sha512-oyIAv+8pzImU4qBWHLdbKiMpHsa3t3LElEemuSQ5/t5dWNpwhQXVRvZzIGbse9GEKY+BBiguHwnwNYDyt+Qz9A==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/junit-reporter/-/junit-reporter-9.4.3.tgz", + "integrity": "sha512-ZV38g1NfmOY9U70vdX8RVxM2+r91lxF+wttbzk6zYVOEBVsq8/hF3J13ITtRGJ/XlGu09j25oc/xe3PtNTKF+A==", "dev": true, + "license": "MIT", "dependencies": { - "@wdio/reporter": "9.2.14", - "@wdio/types": "9.2.2", + "@wdio/reporter": "9.4.3", + "@wdio/types": "9.4.3", "json-stringify-safe": "^5.0.1", "junit-report-builder": "^5.1.1" }, @@ -8269,16 +8244,17 @@ } }, "node_modules/@wdio/local-runner": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-9.4.1.tgz", - "integrity": "sha512-MM5VM0V7zvajICr6eNROjkppRhGNpdV4nU5hrgSap92nou8G+zBgLxJ45P5BzLw67KQTOEa1E32b/zCBEkO+0g==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-9.4.3.tgz", + "integrity": "sha512-3dWTECgtiCm/D7Ws+jwS1MyG6SQKOnP1ssI+94YFJpNHVxgaXgdGi3jnILw+4tAhhWrW0PryDpO9EiEHGijEpQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0", "@wdio/logger": "9.1.3", "@wdio/repl": "9.0.8", - "@wdio/runner": "9.4.1", - "@wdio/types": "9.2.2", + "@wdio/runner": "9.4.3", + "@wdio/types": "9.4.3", "async-exit-hook": "^2.0.1", "split2": "^4.1.0", "stream-buffers": "^3.0.2" @@ -8341,6 +8317,24 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@wdio/mocha-framework": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-9.4.3.tgz", + "integrity": "sha512-+gkqtsbfjBCLZqfGwKQCscZJBayNidc7notyUryNo39mA3N4RMwCVmbRxiZu8hBxzYfinZgtJJ3URjLZsy9TlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mocha": "^10.0.6", + "@types/node": "^20.11.28", + "@wdio/logger": "9.1.3", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", + "mocha": "^10.3.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, "node_modules/@wdio/protocols": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-9.2.2.tgz", @@ -8352,6 +8346,7 @@ "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-9.0.8.tgz", "integrity": "sha512-3iubjl4JX5zD21aFxZwQghqC3lgu+mSs8c3NaiYYNCC+IT5cI/8QuKlgh9s59bu+N3gG988jqMJeCYlKuUv/iw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0" }, @@ -8360,14 +8355,15 @@ } }, "node_modules/@wdio/reporter": { - "version": "9.2.14", - "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-9.2.14.tgz", - "integrity": "sha512-njOqa9+w5zc9AY4fsUmW46EhZ2nzMFRXZPCmwnGZuYk81L3slVfAFhKk1wSTRhSbghjYAZndt9Yo3c4wFLh6Lg==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-9.4.3.tgz", + "integrity": "sha512-UOLPbAztlU7sDw6kp6ASz+6NxK5Dq1T1F0Zv21CGPQfluwoM0w9r/E1HQVvZtvYkwyMRABFEw0VHXgzl26Yp/g==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0", "@wdio/logger": "9.1.3", - "@wdio/types": "9.2.2", + "@wdio/types": "9.4.3", "diff": "^7.0.0", "object-inspect": "^1.12.0" }, @@ -8376,31 +8372,33 @@ } }, "node_modules/@wdio/runner": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-9.4.1.tgz", - "integrity": "sha512-WUpYamLafv+GUofGqvA2HO1kSVnwLyPO5ujq3TS/YaJLnUDOj4bjHiRo5+KDbKw1xhqjW0GjbfDupVU5LeL9iw==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-9.4.3.tgz", + "integrity": "sha512-Dmiz7ZbpNrNgCxqLAL/Y5s/e7cVkaUKhdDHY500kyyvzUKcMjOHxqDqyWzN+upiUO2X6db90gOu4rqBhrRqxdA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.11.28", - "@wdio/config": "9.2.8", - "@wdio/globals": "9.4.1", + "@wdio/config": "9.4.3", + "@wdio/globals": "9.4.3", "@wdio/logger": "9.1.3", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", "deepmerge-ts": "^7.0.3", "expect-webdriverio": "^5.0.1", - "webdriver": "9.4.1", - "webdriverio": "9.4.1" + "webdriver": "9.4.3", + "webdriverio": "9.4.3" }, "engines": { "node": ">=18.20.0" } }, "node_modules/@wdio/types": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.2.2.tgz", - "integrity": "sha512-nHZ9Ne9iRQFJ1TOYKUn4Fza69IshTTzk6RYmSZ51ImGs9uMZu0+S0Jm9REdly+VLN3FzxG6g2QSe0/F3uNVPdw==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.4.3.tgz", + "integrity": "sha512-ShXtWdtjmFUX1qT3c0Ldj7v9VB+2WnWpU3JxD0d+WL0W4TSQV8yFxVmwahRPvBsFO+ust4F38o6gOZEANCVhgA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0" }, @@ -8409,22 +8407,23 @@ } }, "node_modules/@wdio/utils": { - "version": "9.2.8", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.2.8.tgz", - "integrity": "sha512-rKm5FXkpsCyeqh8tdirtRUHvgNytWNMiaVKdctsvKOJvqnDVPAAQcz9Wmgo7bSwoLwtSHcDaRoxY7olV7J4QnA==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.4.3.tgz", + "integrity": "sha512-HIA9bzqADRsTmXZDbVAX3jI0vzFXI9RJ6a92emrkANVG27etEL0KEGXDgoTbdwn7lFLkvY6xp7vY3VR1+Dux0w==", "dev": true, + "license": "MIT", "dependencies": { "@puppeteer/browsers": "^2.2.0", "@wdio/logger": "9.1.3", - "@wdio/types": "9.2.2", + "@wdio/types": "9.4.3", "decamelize": "^6.0.0", "deepmerge-ts": "^7.0.3", - "edgedriver": "^5.6.1", - "geckodriver": "^4.3.3", + "edgedriver": "^6.1.1", + "geckodriver": "^5.0.0", "get-port": "^7.0.0", "import-meta-resolve": "^4.0.0", "locate-app": "^2.2.24", - "safaridriver": "^0.1.2", + "safaridriver": "^1.0.0", "split2": "^4.2.0", "wait-port": "^1.1.0" }, @@ -8437,6 +8436,7 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -8665,10 +8665,11 @@ "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" }, "node_modules/@zip.js/zip.js": { - "version": "2.7.53", - "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.53.tgz", - "integrity": "sha512-G6Bl5wN9EXXVaTUIox71vIX5Z454zEBe+akKpV4m1tUboIctT5h7ID3QXCJd/Lfy2rSvmkTmZIucf1jGRR4f5A==", + "version": "2.7.54", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.54.tgz", + "integrity": "sha512-qMrJVg2hoEsZJjMJez9yI2+nZlBUxgYzGV3mqcb2B/6T1ihXp0fWBDYlVHlHquuorgNUQP5a8qSmX6HF5rFJNg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "bun": ">=0.7.0", "deno": ">=1.0.0", @@ -8752,13 +8753,11 @@ } }, "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, + "license": "MIT", "engines": { "node": ">= 14" } @@ -8929,6 +8928,15 @@ "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==" }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -9050,6 +9058,7 @@ "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "dev": true, + "license": "MIT", "dependencies": { "archiver-utils": "^5.0.2", "async": "^3.2.4", @@ -9068,6 +9077,7 @@ "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, + "license": "MIT", "dependencies": { "glob": "^10.0.0", "graceful-fs": "^4.2.0", @@ -9086,6 +9096,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -9109,6 +9120,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -9119,6 +9131,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -9139,6 +9152,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -9154,6 +9168,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -9184,6 +9199,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -9194,6 +9210,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -9239,6 +9256,7 @@ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">= 0.4" } @@ -9425,7 +9443,8 @@ "version": "1.6.7", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/babel-core": { "version": "7.0.0-bridge.0", @@ -9652,6 +9671,7 @@ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", "dev": true, + "license": "Apache-2.0", "optional": true }, "node_modules/bare-fs": { @@ -9659,6 +9679,7 @@ "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "bare-events": "^2.0.0", @@ -9671,6 +9692,7 @@ "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", "dev": true, + "license": "Apache-2.0", "optional": true }, "node_modules/bare-path": { @@ -9678,19 +9700,21 @@ "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "bare-os": "^2.1.0" } }, "node_modules/bare-stream": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.2.tgz", - "integrity": "sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.1.tgz", + "integrity": "sha512-eVZbtKM+4uehzrsj49KtCy3Pbg7kO1pJ3SKZ1SFrIH/0pnj9scuGGgUlNDf/7qS8WKtGdiJY5Kyhs/ivYPTB/g==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { - "streamx": "^2.20.0" + "streamx": "^2.21.0" } }, "node_modules/base64-js": { @@ -9717,6 +9741,7 @@ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -9868,6 +9893,12 @@ "node": ">=8" } }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "node_modules/browserslist": { "version": "4.24.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", @@ -9937,6 +9968,7 @@ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -10109,6 +10141,7 @@ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", "dev": true, + "license": "MIT", "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", @@ -10134,6 +10167,7 @@ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", @@ -10151,6 +10185,7 @@ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -10167,6 +10202,7 @@ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -10181,6 +10217,7 @@ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -10196,6 +10233,7 @@ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -10210,6 +10248,7 @@ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -10224,6 +10263,7 @@ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -10239,6 +10279,7 @@ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -10558,6 +10599,7 @@ "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, + "license": "MIT", "dependencies": { "crc-32": "^1.2.0", "crc32-stream": "^6.0.0", @@ -10588,6 +10630,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -10598,6 +10641,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -10840,6 +10884,7 @@ "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "dev": true, + "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" }, @@ -10852,6 +10897,7 @@ "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, + "license": "MIT", "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^4.0.0" @@ -10879,6 +10925,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -10889,6 +10936,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -11005,7 +11053,8 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.2.tgz", "integrity": "sha512-C2AugXIpRGQTxaCW0N7n5jD/p5irUmCrwl03TrnMFBHDbdq44CFWR2zO7rK9xPN4Eo3pUxC4vQzQgbIpzrD1PQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/css-tree": { "version": "1.1.3", @@ -11088,6 +11137,7 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 14" } @@ -11156,6 +11206,7 @@ "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.3.tgz", "integrity": "sha512-qCSH6I0INPxd9Y1VtAiLpnYvz5O//6rCfJXKk0z66Up9/VOSr+1yS8XSKA5IWRxjocFGlzPyaZYe+jxq7OOLtQ==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=16.0.0" } @@ -11248,6 +11299,7 @@ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, + "license": "MIT", "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", @@ -11262,6 +11314,7 @@ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, @@ -11314,6 +11367,7 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -11493,6 +11547,7 @@ "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", "dev": true, + "license": "MIT", "dependencies": { "@types/which": "^2.0.1", "which": "^2.0.2" @@ -11505,61 +11560,28 @@ } }, "node_modules/edgedriver": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-5.6.1.tgz", - "integrity": "sha512-3Ve9cd5ziLByUdigw6zovVeWJjVs8QHVmqOB0sJ0WNeVPcwf4p18GnxMmVvlFmYRloUwf5suNuorea4QzwBIOA==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-6.1.1.tgz", + "integrity": "sha512-/dM/PoBf22Xg3yypMWkmRQrBKEnSyNaZ7wHGCT9+qqT14izwtFT+QvdR89rjNkMfXwW+bSFoqOfbcvM+2Cyc7w==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { - "@wdio/logger": "^8.38.0", - "@zip.js/zip.js": "^2.7.48", + "@wdio/logger": "^9.1.3", + "@zip.js/zip.js": "^2.7.53", "decamelize": "^6.0.0", "edge-paths": "^3.0.5", - "fast-xml-parser": "^4.4.1", + "fast-xml-parser": "^4.5.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "node-fetch": "^3.3.2", - "which": "^4.0.0" + "which": "^5.0.0" }, "bin": { "edgedriver": "bin/edgedriver.js" - } - }, - "node_modules/edgedriver/node_modules/@wdio/logger": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.38.0.tgz", - "integrity": "sha512-kcHL86RmNbcQP+Gq/vQUGlArfU6IIcbbnNp32rRIraitomZow+iEoc519rdQmSVusDozMS5DZthkgDdxK+vz6Q==", - "dev": true, - "dependencies": { - "chalk": "^5.1.2", - "loglevel": "^1.6.0", - "loglevel-plugin-prefix": "^0.8.4", - "strip-ansi": "^7.1.0" }, "engines": { - "node": "^16.13 || >=18" - } - }, - "node_modules/edgedriver/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/edgedriver/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=18.0.0" } }, "node_modules/edgedriver/node_modules/data-uri-to-buffer": { @@ -11567,6 +11589,7 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 12" } @@ -11576,6 +11599,7 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -11588,6 +11612,7 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=16" } @@ -11597,6 +11622,7 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dev": true, + "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -11610,26 +11636,12 @@ "url": "https://opencollective.com/node-fetch" } }, - "node_modules/edgedriver/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/edgedriver/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -11637,7 +11649,7 @@ "node-which": "bin/which.js" }, "engines": { - "node": "^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/editorconfig": { @@ -11753,6 +11765,7 @@ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", "dev": true, + "license": "MIT", "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" @@ -11766,6 +11779,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -11778,6 +11792,7 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, + "license": "MIT", "dependencies": { "once": "^1.4.0" } @@ -12058,6 +12073,7 @@ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", @@ -12079,6 +12095,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" @@ -13071,6 +13088,7 @@ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -13091,6 +13109,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, + "license": "MIT", "dependencies": { "pump": "^3.0.0" }, @@ -13115,7 +13134,8 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", @@ -13232,6 +13252,7 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, + "license": "MIT", "dependencies": { "pend": "~1.2.0" } @@ -13251,6 +13272,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" @@ -13432,6 +13454,15 @@ "micromatch": "^4.0.2" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -13543,6 +13574,7 @@ "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", "dev": true, + "license": "MIT", "dependencies": { "fetch-blob": "^3.1.2" }, @@ -13633,26 +13665,27 @@ } }, "node_modules/geckodriver": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.5.1.tgz", - "integrity": "sha512-lGCRqPMuzbRNDWJOQcUqhNqPvNsIFu6yzXF8J/6K3WCYFd2r5ckbeF7h1cxsnjA7YLSEiWzERCt6/gjZ3tW0ug==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-5.0.0.tgz", + "integrity": "sha512-vn7TtQ3b9VMJtVXsyWtQQl1fyBVFhQy7UvJF96kPuuJ0or5THH496AD3eUyaDD11+EqCxH9t6V+EP9soZQk4YQ==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { - "@wdio/logger": "^9.0.0", - "@zip.js/zip.js": "^2.7.48", + "@wdio/logger": "^9.1.3", + "@zip.js/zip.js": "^2.7.53", "decamelize": "^6.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.5", "node-fetch": "^3.3.2", "tar-fs": "^3.0.6", - "which": "^4.0.0" + "which": "^5.0.0" }, "bin": { "geckodriver": "bin/geckodriver.js" }, "engines": { - "node": "^16.13 || >=18 || >=20" + "node": ">=18.0.0" } }, "node_modules/geckodriver/node_modules/data-uri-to-buffer": { @@ -13660,6 +13693,7 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 12" } @@ -13669,6 +13703,7 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -13681,6 +13716,7 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=16" } @@ -13690,6 +13726,7 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dev": true, + "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -13704,10 +13741,11 @@ } }, "node_modules/geckodriver/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -13715,7 +13753,7 @@ "node-which": "bin/which.js" }, "engines": { - "node": "^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/gensync": { @@ -13766,6 +13804,7 @@ "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -13812,55 +13851,20 @@ } }, "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": "6.0.4", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", + "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", "dev": true, + "license": "MIT", "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4", - "fs-extra": "^11.2.0" + "debug": "^4.3.4" }, "engines": { "node": ">= 14" } }, - "node_modules/get-uri/node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "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==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -14077,6 +14081,15 @@ "node": ">= 0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, "node_modules/hermes-estree": { "version": "0.20.1", "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz", @@ -14193,7 +14206,8 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/htmlfy/-/htmlfy-0.3.2.tgz", "integrity": "sha512-FsxzfpeDYRqn1emox9VpxMPfGjADoUmmup8D604q497R0VNxiXs4ZZTN2QzkaMA5C9aHGUoe1iQRVSm+HK9xuA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/htmlparser2": { "version": "9.1.0", @@ -14207,6 +14221,7 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -14219,6 +14234,7 @@ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -14233,6 +14249,7 @@ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -14248,6 +14265,7 @@ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -14319,6 +14337,7 @@ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -14364,12 +14383,13 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, + "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -14506,7 +14526,8 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/import-fresh": { "version": "2.0.0", @@ -14663,6 +14684,7 @@ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", "dev": true, + "license": "MIT", "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" @@ -14675,7 +14697,8 @@ "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==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/ipaddr.js": { "version": "2.2.0", @@ -15293,69 +15316,6 @@ "node": ">=8" } }, - "node_modules/jasmine": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-5.4.0.tgz", - "integrity": "sha512-E2u4ylX5tgGYvbynImU6EUBKKrSVB1L72FEPjGh4M55ov1VsxR26RA2JU91L9YSPFgcjo4mCLyKn/QXvEYGBkA==", - "dev": true, - "dependencies": { - "glob": "^10.2.2", - "jasmine-core": "~5.4.0" - }, - "bin": { - "jasmine": "bin/jasmine.js" - } - }, - "node_modules/jasmine-core": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.4.0.tgz", - "integrity": "sha512-T4fio3W++llLd7LGSGsioriDHgWyhoL6YTu4k37uwJLF7DzOzspz7mNxRoM3cQdLWtL/ebazQpIf/yZGJx/gzg==", - "dev": true - }, - "node_modules/jasmine/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/jasmine/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jasmine/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", @@ -16025,7 +15985,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsc-android": { "version": "250231.0.0", @@ -16255,6 +16216,7 @@ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", @@ -16266,13 +16228,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jszip/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -16288,6 +16252,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -16387,6 +16352,7 @@ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "^2.0.5" }, @@ -16398,13 +16364,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lazystream/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -16420,6 +16388,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -16706,6 +16675,7 @@ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", "dev": true, + "license": "MIT", "dependencies": { "immediate": "~3.0.5" } @@ -16790,6 +16760,7 @@ "url": "https://github.com/hejny/locate-app/blob/main/README.md#%EF%B8%8F-contributing" } ], + "license": "Apache-2.0", "dependencies": { "@promptbook/utils": "0.69.5", "type-fest": "4.26.0", @@ -16801,6 +16772,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.0.tgz", "integrity": "sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" }, @@ -16834,7 +16806,8 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", @@ -16932,7 +16905,8 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", @@ -17942,6 +17916,264 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mocha": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/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==", + "dev": true + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -18057,6 +18289,7 @@ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -18117,6 +18350,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "engines": { "node": ">=10.5.0" } @@ -18635,19 +18869,20 @@ } }, "node_modules/pac-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", - "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz", + "integrity": "sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==", "dev": true, + "license": "MIT", "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", + "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.5", + "https-proxy-agent": "^7.0.6", "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.4" + "socks-proxy-agent": "^8.0.5" }, "engines": { "node": ">= 14" @@ -18658,6 +18893,7 @@ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "dev": true, + "license": "MIT", "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" @@ -18676,7 +18912,8 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "dev": true, + "license": "(MIT AND Zlib)" }, "node_modules/parent-module": { "version": "1.0.1", @@ -18727,6 +18964,7 @@ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "dev": true, + "license": "MIT", "dependencies": { "entities": "^4.5.0" }, @@ -18739,6 +18977,7 @@ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", "dev": true, + "license": "MIT", "dependencies": { "domhandler": "^5.0.3", "parse5": "^7.0.0" @@ -18752,6 +18991,7 @@ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -18767,6 +19007,7 @@ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", "dev": true, + "license": "MIT", "dependencies": { "parse5": "^7.0.0" }, @@ -18969,7 +19210,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/picocolors": { "version": "1.1.1", @@ -19229,6 +19471,7 @@ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -19326,19 +19569,20 @@ } }, "node_modules/proxy-agent": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", - "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", "dev": true, + "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.3", + "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", + "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" + "socks-proxy-agent": "^8.0.5" }, "engines": { "node": ">= 14" @@ -19349,6 +19593,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -19357,13 +19602,15 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pump": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -19395,7 +19642,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz", "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/query-string": { "version": "7.1.3", @@ -19447,7 +19695,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", @@ -21029,6 +21278,7 @@ "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "minimatch": "^5.1.0" } @@ -21038,6 +21288,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -21047,6 +21298,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -21313,6 +21565,7 @@ "resolved": "https://registry.npmjs.org/resq/-/resq-1.11.0.tgz", "integrity": "sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^2.0.1" } @@ -21321,7 +21574,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/restore-cursor": { "version": "3.1.0", @@ -21358,7 +21612,8 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.5.tgz", "integrity": "sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/rimraf": { "version": "3.0.2", @@ -21435,10 +21690,14 @@ } }, "node_modules/safaridriver": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/safaridriver/-/safaridriver-0.1.2.tgz", - "integrity": "sha512-4R309+gWflJktzPXBQCobbWEHlzC4aK3a+Ov3tz2Ib2aBxiwd11phkdIBH1l0EO22x24CJMUQkpKFumRriCSRg==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safaridriver/-/safaridriver-1.0.0.tgz", + "integrity": "sha512-J92IFbskyo7OYB3Dt4aTdyhag1GlInrfbPCmMteb7aBK7PwlnGz1HI0+oyNN97j7pV9DqUAVoVgkNRMrfY47mQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } }, "node_modules/safe-buffer": { "version": "5.1.2", @@ -21819,7 +22078,8 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/setprototypeof": { "version": "1.2.0", @@ -21951,6 +22211,7 @@ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -21981,6 +22242,7 @@ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, + "license": "MIT", "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" @@ -21991,12 +22253,13 @@ } }, "node_modules/socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "dev": true, + "license": "MIT", "dependencies": { - "agent-base": "^7.1.1", + "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" }, @@ -22057,7 +22320,8 @@ "type": "github", "url": "https://github.com/hejny/spacetrim/blob/main/README.md#%EF%B8%8F-contributing" } - ] + ], + "license": "Apache-2.0" }, "node_modules/spdx-correct": { "version": "3.2.0", @@ -22239,10 +22503,11 @@ } }, "node_modules/streamx": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", - "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", + "version": "2.21.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.1.tgz", + "integrity": "sha512-PhP9wUnFLa+91CPy3N6tiQsK+gnYyUNuk15S3YG/zjYE7RuPeCjJngqnzpC31ow0lzBHQ+QGO4cNJnd0djYUsw==", "dev": true, + "license": "MIT", "dependencies": { "fast-fifo": "^1.3.2", "queue-tick": "^1.0.1", @@ -22621,6 +22886,7 @@ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dev": true, + "license": "MIT", "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" @@ -22635,6 +22901,7 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, + "license": "MIT", "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", @@ -22736,10 +23003,14 @@ } }, "node_modules/text-decoder": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", - "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", - "dev": true + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } }, "node_modules/text-encoding": { "version": "0.7.0", @@ -22783,7 +23054,8 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/through2": { "version": "2.0.5", @@ -23221,6 +23493,7 @@ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -23231,6 +23504,7 @@ "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", "dev": true, + "license": "MIT", "engines": { "node": ">=18.17" } @@ -23359,7 +23633,8 @@ "version": "10.0.0", "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/use-callback-ref": { "version": "1.3.0", @@ -23453,6 +23728,7 @@ "resolved": "https://registry.npmjs.org/userhome/-/userhome-1.0.1.tgz", "integrity": "sha512-5cnLm4gseXjAclKowC4IjByaGsjtAoV6PrOQOljplNB54ReUYJP8HdAFq2muHinSDAh09PPX/uXDPfdxRHvuSA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -23527,6 +23803,7 @@ "resolved": "https://registry.npmjs.org/wait-port/-/wait-port-1.1.0.tgz", "integrity": "sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.2", "commander": "^9.3.0", @@ -23544,6 +23821,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -23559,6 +23837,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -23575,6 +23854,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -23586,13 +23866,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/wait-port/node_modules/commander": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || >=14" } @@ -23602,6 +23884,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -23611,6 +23894,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -23676,23 +23960,25 @@ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/webdriver": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.4.1.tgz", - "integrity": "sha512-vFDdxMj/9W1+6jhpHSiRYfO8dix23HjAUtLx7aOv9ejEsntC0EzCIAftJ59YsF3Ppu184+FkdDVhnivpkZPTFw==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.4.3.tgz", + "integrity": "sha512-aZrJq+FwJFrrSX18PHqFK3iEw+Pdu/cvJwgIiuur4/ffP47jrirwCqabCVaIV3eut+mJBc1nY7IV3Jd3i4MekQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", - "@wdio/config": "9.2.8", + "@wdio/config": "9.4.3", "@wdio/logger": "9.1.3", "@wdio/protocols": "9.2.2", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", "deepmerge-ts": "^7.0.3", "undici": "^6.20.1", "ws": "^8.8.0" @@ -23706,6 +23992,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -23723,19 +24010,20 @@ } }, "node_modules/webdriverio": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.4.1.tgz", - "integrity": "sha512-XIPtRnxSES4CoxH2BfUY/6QzNgEgJEUjMYu7t7SJR8bVfbLRVXAA1ie9kM0MtdLs4oZ2Pr8rR8fqytsA1CjEWw==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.4.3.tgz", + "integrity": "sha512-MdnMKVZCiC3oqC38pNAkvP5FPomMHK+Hk4bD0JMAKRt7WamQBmaxdObwZAcJMzpn7izYWoo0avZoGYbE/fHRXA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.11.30", "@types/sinonjs__fake-timers": "^8.1.5", - "@wdio/config": "9.2.8", + "@wdio/config": "9.4.3", "@wdio/logger": "9.1.3", "@wdio/protocols": "9.2.2", "@wdio/repl": "9.0.8", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", "archiver": "^7.0.1", "aria-query": "^5.3.0", "cheerio": "^1.0.0-rc.12", @@ -23754,7 +24042,7 @@ "rgb2hex": "0.2.5", "serialize-error": "^11.0.3", "urlpattern-polyfill": "^10.0.0", - "webdriver": "9.4.1" + "webdriver": "9.4.3" }, "engines": { "node": ">=18.20.0" @@ -23773,6 +24061,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -23782,6 +24071,7 @@ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -23794,6 +24084,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -23809,6 +24100,7 @@ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^2.12.2" }, @@ -23824,6 +24116,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -24343,6 +24636,7 @@ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "dev": true, + "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" }, @@ -24355,6 +24649,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -24372,6 +24667,7 @@ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" } @@ -24480,6 +24776,12 @@ "node": ">=0.10.0" } }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -24673,11 +24975,39 @@ "node": ">=12" } }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, + "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -24688,6 +25018,7 @@ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -24755,6 +25086,7 @@ "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, + "license": "MIT", "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", @@ -24783,6 +25115,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -24793,6 +25126,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -27742,15 +28076,15 @@ } }, "@puppeteer/browsers": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.1.tgz", - "integrity": "sha512-0kdAbmic3J09I6dT8e9vE2JOCSt13wHCW5x/ly8TSt2bDtuIWe2TgLZZDHdcziw9AVCzflMAXCrVyRIhIs44Ng==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.6.1.tgz", + "integrity": "sha512-aBSREisdsGH890S2rQqK82qmQYU3uFpSH8wcZWHgHzl3LfzsxAKbLNiAG9mO8v1Y0UICBeClICxPJvyr0rcuxg==", "dev": true, "requires": { - "debug": "^4.3.7", + "debug": "^4.4.0", "extract-zip": "^2.0.1", "progress": "^2.0.3", - "proxy-agent": "^6.4.0", + "proxy-agent": "^6.5.0", "semver": "^7.6.3", "tar-fs": "^3.0.6", "unbzip2-stream": "^1.4.3", @@ -27758,9 +28092,9 @@ }, "dependencies": { "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "requires": { "ms": "^2.1.3" @@ -29393,12 +29727,6 @@ "@types/istanbul-lib-report": "*" } }, - "@types/jasmine": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.4.tgz", - "integrity": "sha512-px7OMFO/ncXxixDe1zR13V1iycqWae0MxTaw62RpFlksUi5QuNWgQJFkTQjIOvrmutJbI7Fp2Y2N1F6D2R4G6w==", - "dev": true - }, "@types/js-cookie": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", @@ -29456,6 +29784,12 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true }, + "@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true + }, "@types/moment-duration-format": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/@types/moment-duration-format/-/moment-duration-format-2.2.6.tgz", @@ -30010,14 +30344,14 @@ } }, "@wdio/allure-reporter": { - "version": "9.2.14", - "resolved": "https://registry.npmjs.org/@wdio/allure-reporter/-/allure-reporter-9.2.14.tgz", - "integrity": "sha512-ErIRuwEpc9a3BOGxQt+ypWwXgJA6hkFW57z6F5KHzmjEvXa24BsHY7dcQZOThf3RTun0upjMCQQlqY0loYVOmg==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/allure-reporter/-/allure-reporter-9.4.3.tgz", + "integrity": "sha512-VMSNzhsJz03K2/4tAklx/X/Wdn8c8HnEMBu+kcaBxeaExjw+/SWglCiH/NjR32XkGaopW9Mj8WlrnKq+G1vDaw==", "dev": true, "requires": { "@types/node": "^20.1.0", - "@wdio/reporter": "9.2.14", - "@wdio/types": "9.2.2", + "@wdio/reporter": "9.4.3", + "@wdio/types": "9.4.3", "allure-js-commons": "^2.5.0", "csv-stringify": "^6.0.4", "strip-ansi": "^7.1.0" @@ -30041,23 +30375,22 @@ } }, "@wdio/cli": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-9.4.1.tgz", - "integrity": "sha512-GDyAer63WDsr2ckXmrpUyAcIZFd3pCRIpi85rL1ZjnWthRy/UtwY0EHPMDuSeUEJ28iYwW3esKgq2ZKlsdbMeA==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-9.4.3.tgz", + "integrity": "sha512-N5hVlpwFjmEvky0A/sKNj3879dzPZvFhUFSAE/g0588TFX0J3eD20TPV8T8eoIPk1vHmWda6V8DCJbWyqP4dlw==", "dev": true, "requires": { "@types/node": "^20.1.1", "@vitest/snapshot": "^2.1.1", - "@wdio/config": "9.2.8", - "@wdio/globals": "9.4.1", + "@wdio/config": "9.4.3", + "@wdio/globals": "9.4.3", "@wdio/logger": "9.1.3", "@wdio/protocols": "9.2.2", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", "async-exit-hook": "^2.0.1", "chalk": "^5.2.0", "chokidar": "^4.0.0", - "cli-spinners": "^3.0.0", "dotenv": "^16.3.1", "ejs": "^3.1.9", "execa": "^9.2.0", @@ -30069,7 +30402,7 @@ "read-pkg-up": "^10.0.0", "recursive-readdir": "^2.2.3", "tsx": "^4.7.2", - "webdriverio": "9.4.1", + "webdriverio": "9.4.3", "yargs": "^17.7.2" }, "dependencies": { @@ -30088,12 +30421,6 @@ "readdirp": "^4.0.1" } }, - "cli-spinners": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.2.0.tgz", - "integrity": "sha512-pXftdQloMZzjCr3pCTIRniDcys6dDzgpgVhAHHk6TKBDbRuP1MkuetTF5KSv4YUutbOPa7+7ZrAJ2kVtbMqyXA==", - "dev": true - }, "execa": { "version": "9.5.1", "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.1.tgz", @@ -30179,15 +30506,14 @@ } }, "@wdio/config": { - "version": "9.2.8", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.2.8.tgz", - "integrity": "sha512-EGMmBPGJbz6RmgMjebRWkWu3fGyeTIRcusF4UA4f2tiUEKY8nbzUO/ZyDjVQNR+YVB40q0jcqAqpszYRrIzzeg==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.4.3.tgz", + "integrity": "sha512-8h3SO925efnyIOkKnaNbLbMnJpmvm4wfUWoo26kq8ZPU7DSQsEWvJ7EZ4Hw8RGu+kY4VO7r54ljicnnrFVh/ZA==", "dev": true, "requires": { "@wdio/logger": "9.1.3", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", - "decamelize": "^6.0.0", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", "deepmerge-ts": "^7.0.3", "glob": "^10.2.2", "import-meta-resolve": "^4.0.0" @@ -30202,12 +30528,6 @@ "balanced-match": "^1.0.0" } }, - "decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", - "dev": true - }, "glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -30234,53 +30554,38 @@ } }, "@wdio/globals": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-9.4.1.tgz", - "integrity": "sha512-CTVAVJ7iFyT54XF9iRmNvsDB+WSHoztJPG9XPL/mHzQ2LYfSyUR8E/j+3iHbTx3v/qRNucgPcGwhxiuY2RcaDg==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-9.4.3.tgz", + "integrity": "sha512-IyjiS6jtCMCbDedLZNUUaI9IpGAxkItfVKlGUgQ2kNcjOYUyKf/g8MEE0m8lR50yEEVENJ4rEn9IQ+foeFIZjQ==", "dev": true, "requires": { "expect-webdriverio": "^5.0.1", - "webdriverio": "9.4.1" - } - }, - "@wdio/jasmine-framework": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/@wdio/jasmine-framework/-/jasmine-framework-9.4.1.tgz", - "integrity": "sha512-N2X8MfsfX8JemD4DQwvSksXmBzYZxCKwuB7LaBiw+hH2YuFu+0L2ekR0Xvwtr8SpiENVEHAoiNFEj4i9dMTqlA==", - "dev": true, - "requires": { - "@types/node": "^20.1.0", - "@wdio/globals": "9.4.1", - "@wdio/logger": "9.1.3", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", - "expect-webdriverio": "^5.0.1", - "jasmine": "^5.0.0" + "webdriverio": "9.4.3" } }, "@wdio/junit-reporter": { - "version": "9.2.14", - "resolved": "https://registry.npmjs.org/@wdio/junit-reporter/-/junit-reporter-9.2.14.tgz", - "integrity": "sha512-oyIAv+8pzImU4qBWHLdbKiMpHsa3t3LElEemuSQ5/t5dWNpwhQXVRvZzIGbse9GEKY+BBiguHwnwNYDyt+Qz9A==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/junit-reporter/-/junit-reporter-9.4.3.tgz", + "integrity": "sha512-ZV38g1NfmOY9U70vdX8RVxM2+r91lxF+wttbzk6zYVOEBVsq8/hF3J13ITtRGJ/XlGu09j25oc/xe3PtNTKF+A==", "dev": true, "requires": { - "@wdio/reporter": "9.2.14", - "@wdio/types": "9.2.2", + "@wdio/reporter": "9.4.3", + "@wdio/types": "9.4.3", "json-stringify-safe": "^5.0.1", "junit-report-builder": "^5.1.1" } }, "@wdio/local-runner": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-9.4.1.tgz", - "integrity": "sha512-MM5VM0V7zvajICr6eNROjkppRhGNpdV4nU5hrgSap92nou8G+zBgLxJ45P5BzLw67KQTOEa1E32b/zCBEkO+0g==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-9.4.3.tgz", + "integrity": "sha512-3dWTECgtiCm/D7Ws+jwS1MyG6SQKOnP1ssI+94YFJpNHVxgaXgdGi3jnILw+4tAhhWrW0PryDpO9EiEHGijEpQ==", "dev": true, "requires": { "@types/node": "^20.1.0", "@wdio/logger": "9.1.3", "@wdio/repl": "9.0.8", - "@wdio/runner": "9.4.1", - "@wdio/types": "9.2.2", + "@wdio/runner": "9.4.3", + "@wdio/types": "9.4.3", "async-exit-hook": "^2.0.1", "split2": "^4.1.0", "stream-buffers": "^3.0.2" @@ -30321,6 +30626,20 @@ } } }, + "@wdio/mocha-framework": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-9.4.3.tgz", + "integrity": "sha512-+gkqtsbfjBCLZqfGwKQCscZJBayNidc7notyUryNo39mA3N4RMwCVmbRxiZu8hBxzYfinZgtJJ3URjLZsy9TlA==", + "dev": true, + "requires": { + "@types/mocha": "^10.0.6", + "@types/node": "^20.11.28", + "@wdio/logger": "9.1.3", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", + "mocha": "^10.3.0" + } + }, "@wdio/protocols": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-9.2.2.tgz", @@ -30337,62 +30656,62 @@ } }, "@wdio/reporter": { - "version": "9.2.14", - "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-9.2.14.tgz", - "integrity": "sha512-njOqa9+w5zc9AY4fsUmW46EhZ2nzMFRXZPCmwnGZuYk81L3slVfAFhKk1wSTRhSbghjYAZndt9Yo3c4wFLh6Lg==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-9.4.3.tgz", + "integrity": "sha512-UOLPbAztlU7sDw6kp6ASz+6NxK5Dq1T1F0Zv21CGPQfluwoM0w9r/E1HQVvZtvYkwyMRABFEw0VHXgzl26Yp/g==", "dev": true, "requires": { "@types/node": "^20.1.0", "@wdio/logger": "9.1.3", - "@wdio/types": "9.2.2", + "@wdio/types": "9.4.3", "diff": "^7.0.0", "object-inspect": "^1.12.0" } }, "@wdio/runner": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-9.4.1.tgz", - "integrity": "sha512-WUpYamLafv+GUofGqvA2HO1kSVnwLyPO5ujq3TS/YaJLnUDOj4bjHiRo5+KDbKw1xhqjW0GjbfDupVU5LeL9iw==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-9.4.3.tgz", + "integrity": "sha512-Dmiz7ZbpNrNgCxqLAL/Y5s/e7cVkaUKhdDHY500kyyvzUKcMjOHxqDqyWzN+upiUO2X6db90gOu4rqBhrRqxdA==", "dev": true, "requires": { "@types/node": "^20.11.28", - "@wdio/config": "9.2.8", - "@wdio/globals": "9.4.1", + "@wdio/config": "9.4.3", + "@wdio/globals": "9.4.3", "@wdio/logger": "9.1.3", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", "deepmerge-ts": "^7.0.3", "expect-webdriverio": "^5.0.1", - "webdriver": "9.4.1", - "webdriverio": "9.4.1" + "webdriver": "9.4.3", + "webdriverio": "9.4.3" } }, "@wdio/types": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.2.2.tgz", - "integrity": "sha512-nHZ9Ne9iRQFJ1TOYKUn4Fza69IshTTzk6RYmSZ51ImGs9uMZu0+S0Jm9REdly+VLN3FzxG6g2QSe0/F3uNVPdw==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.4.3.tgz", + "integrity": "sha512-ShXtWdtjmFUX1qT3c0Ldj7v9VB+2WnWpU3JxD0d+WL0W4TSQV8yFxVmwahRPvBsFO+ust4F38o6gOZEANCVhgA==", "dev": true, "requires": { "@types/node": "^20.1.0" } }, "@wdio/utils": { - "version": "9.2.8", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.2.8.tgz", - "integrity": "sha512-rKm5FXkpsCyeqh8tdirtRUHvgNytWNMiaVKdctsvKOJvqnDVPAAQcz9Wmgo7bSwoLwtSHcDaRoxY7olV7J4QnA==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.4.3.tgz", + "integrity": "sha512-HIA9bzqADRsTmXZDbVAX3jI0vzFXI9RJ6a92emrkANVG27etEL0KEGXDgoTbdwn7lFLkvY6xp7vY3VR1+Dux0w==", "dev": true, "requires": { "@puppeteer/browsers": "^2.2.0", "@wdio/logger": "9.1.3", - "@wdio/types": "9.2.2", + "@wdio/types": "9.4.3", "decamelize": "^6.0.0", "deepmerge-ts": "^7.0.3", - "edgedriver": "^5.6.1", - "geckodriver": "^4.3.3", + "edgedriver": "^6.1.1", + "geckodriver": "^5.0.0", "get-port": "^7.0.0", "import-meta-resolve": "^4.0.0", "locate-app": "^2.2.24", - "safaridriver": "^0.1.2", + "safaridriver": "^1.0.0", "split2": "^4.2.0", "wait-port": "^1.1.0" }, @@ -30597,9 +30916,9 @@ "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" }, "@zip.js/zip.js": { - "version": "2.7.53", - "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.53.tgz", - "integrity": "sha512-G6Bl5wN9EXXVaTUIox71vIX5Z454zEBe+akKpV4m1tUboIctT5h7ID3QXCJd/Lfy2rSvmkTmZIucf1jGRR4f5A==", + "version": "2.7.54", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.54.tgz", + "integrity": "sha512-qMrJVg2hoEsZJjMJez9yI2+nZlBUxgYzGV3mqcb2B/6T1ihXp0fWBDYlVHlHquuorgNUQP5a8qSmX6HF5rFJNg==", "dev": true }, "abab": { @@ -30654,13 +30973,10 @@ "dev": true }, "agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "requires": { - "debug": "^4.3.4" - } + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true }, "ajv": { "version": "6.12.6", @@ -30785,6 +31101,12 @@ "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==" }, + "ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -31356,13 +31678,13 @@ } }, "bare-stream": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.2.tgz", - "integrity": "sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.1.tgz", + "integrity": "sha512-eVZbtKM+4uehzrsj49KtCy3Pbg7kO1pJ3SKZ1SFrIH/0pnj9scuGGgUlNDf/7qS8WKtGdiJY5Kyhs/ivYPTB/g==", "dev": true, "optional": true, "requires": { - "streamx": "^2.20.0" + "streamx": "^2.21.0" } }, "base64-js": { @@ -31502,6 +31824,12 @@ "fill-range": "^7.1.1" } }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "browserslist": { "version": "4.24.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", @@ -32675,44 +33003,22 @@ } }, "edgedriver": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-5.6.1.tgz", - "integrity": "sha512-3Ve9cd5ziLByUdigw6zovVeWJjVs8QHVmqOB0sJ0WNeVPcwf4p18GnxMmVvlFmYRloUwf5suNuorea4QzwBIOA==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-6.1.1.tgz", + "integrity": "sha512-/dM/PoBf22Xg3yypMWkmRQrBKEnSyNaZ7wHGCT9+qqT14izwtFT+QvdR89rjNkMfXwW+bSFoqOfbcvM+2Cyc7w==", "dev": true, "requires": { - "@wdio/logger": "^8.38.0", - "@zip.js/zip.js": "^2.7.48", + "@wdio/logger": "^9.1.3", + "@zip.js/zip.js": "^2.7.53", "decamelize": "^6.0.0", "edge-paths": "^3.0.5", - "fast-xml-parser": "^4.4.1", + "fast-xml-parser": "^4.5.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "node-fetch": "^3.3.2", - "which": "^4.0.0" + "which": "^5.0.0" }, "dependencies": { - "@wdio/logger": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.38.0.tgz", - "integrity": "sha512-kcHL86RmNbcQP+Gq/vQUGlArfU6IIcbbnNp32rRIraitomZow+iEoc519rdQmSVusDozMS5DZthkgDdxK+vz6Q==", - "dev": true, - "requires": { - "chalk": "^5.1.2", - "loglevel": "^1.6.0", - "loglevel-plugin-prefix": "^0.8.4", - "strip-ansi": "^7.1.0" - } - }, - "ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true - }, - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true - }, "data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -32742,19 +33048,10 @@ "formdata-polyfill": "^4.0.10" } }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, "requires": { "isexe": "^3.1.1" @@ -34088,6 +34385,12 @@ "micromatch": "^4.0.2" } }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -34223,19 +34526,19 @@ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" }, "geckodriver": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.5.1.tgz", - "integrity": "sha512-lGCRqPMuzbRNDWJOQcUqhNqPvNsIFu6yzXF8J/6K3WCYFd2r5ckbeF7h1cxsnjA7YLSEiWzERCt6/gjZ3tW0ug==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-5.0.0.tgz", + "integrity": "sha512-vn7TtQ3b9VMJtVXsyWtQQl1fyBVFhQy7UvJF96kPuuJ0or5THH496AD3eUyaDD11+EqCxH9t6V+EP9soZQk4YQ==", "dev": true, "requires": { - "@wdio/logger": "^9.0.0", - "@zip.js/zip.js": "^2.7.48", + "@wdio/logger": "^9.1.3", + "@zip.js/zip.js": "^2.7.53", "decamelize": "^6.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.5", "node-fetch": "^3.3.2", "tar-fs": "^3.0.6", - "which": "^4.0.0" + "which": "^5.0.0" }, "dependencies": { "data-uri-to-buffer": { @@ -34268,9 +34571,9 @@ } }, "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, "requires": { "isexe": "^3.1.1" @@ -34335,44 +34638,14 @@ } }, "get-uri": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", - "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", + "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", "dev": true, "requires": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4", - "fs-extra": "^11.2.0" - }, - "dependencies": { - "fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "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==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } + "debug": "^4.3.4" } }, "glob": { @@ -34524,6 +34797,12 @@ "function-bind": "^1.1.2" } }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, "hermes-estree": { "version": "0.20.1", "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz", @@ -34757,12 +35036,12 @@ } }, "https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, "requires": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" } }, @@ -35385,56 +35664,6 @@ } } }, - "jasmine": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-5.4.0.tgz", - "integrity": "sha512-E2u4ylX5tgGYvbynImU6EUBKKrSVB1L72FEPjGh4M55ov1VsxR26RA2JU91L9YSPFgcjo4mCLyKn/QXvEYGBkA==", - "dev": true, - "requires": { - "glob": "^10.2.2", - "jasmine-core": "~5.4.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - } - }, - "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "jasmine-core": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.4.0.tgz", - "integrity": "sha512-T4fio3W++llLd7LGSGsioriDHgWyhoL6YTu4k37uwJLF7DzOzspz7mNxRoM3cQdLWtL/ebazQpIf/yZGJx/gzg==", - "dev": true - }, "jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", @@ -37397,6 +37626,193 @@ "minimist": "^1.2.6" } }, + "mocha": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "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==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, "moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -37856,19 +38272,19 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "pac-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", - "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz", + "integrity": "sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==", "dev": true, "requires": { "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", + "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.5", + "https-proxy-agent": "^7.0.6", "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.4" + "socks-proxy-agent": "^8.0.5" } }, "pac-resolver": { @@ -38361,19 +38777,19 @@ } }, "proxy-agent": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", - "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", "dev": true, "requires": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.3", + "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", + "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" + "socks-proxy-agent": "^8.0.5" }, "dependencies": { "lru-cache": { @@ -39753,9 +40169,9 @@ } }, "safaridriver": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/safaridriver/-/safaridriver-0.1.2.tgz", - "integrity": "sha512-4R309+gWflJktzPXBQCobbWEHlzC4aK3a+Ov3tz2Ib2aBxiwd11phkdIBH1l0EO22x24CJMUQkpKFumRriCSRg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safaridriver/-/safaridriver-1.0.0.tgz", + "integrity": "sha512-J92IFbskyo7OYB3Dt4aTdyhag1GlInrfbPCmMteb7aBK7PwlnGz1HI0+oyNN97j7pV9DqUAVoVgkNRMrfY47mQ==", "dev": true }, "safe-buffer": { @@ -40202,12 +40618,12 @@ } }, "socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "dev": true, "requires": { - "agent-base": "^7.1.1", + "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } @@ -40403,9 +40819,9 @@ "dev": true }, "streamx": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", - "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", + "version": "2.21.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.1.tgz", + "integrity": "sha512-PhP9wUnFLa+91CPy3N6tiQsK+gnYyUNuk15S3YG/zjYE7RuPeCjJngqnzpC31ow0lzBHQ+QGO4cNJnd0djYUsw==", "dev": true, "requires": { "bare-events": "^2.2.0", @@ -40740,10 +41156,13 @@ } }, "text-decoder": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", - "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", - "dev": true + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "requires": { + "b4a": "^1.6.4" + } }, "text-encoding": { "version": "0.7.0", @@ -41395,18 +41814,18 @@ "dev": true }, "webdriver": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.4.1.tgz", - "integrity": "sha512-vFDdxMj/9W1+6jhpHSiRYfO8dix23HjAUtLx7aOv9ejEsntC0EzCIAftJ59YsF3Ppu184+FkdDVhnivpkZPTFw==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.4.3.tgz", + "integrity": "sha512-aZrJq+FwJFrrSX18PHqFK3iEw+Pdu/cvJwgIiuur4/ffP47jrirwCqabCVaIV3eut+mJBc1nY7IV3Jd3i4MekQ==", "dev": true, "requires": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", - "@wdio/config": "9.2.8", + "@wdio/config": "9.4.3", "@wdio/logger": "9.1.3", "@wdio/protocols": "9.2.2", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", "deepmerge-ts": "^7.0.3", "undici": "^6.20.1", "ws": "^8.8.0" @@ -41421,19 +41840,19 @@ } }, "webdriverio": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.4.1.tgz", - "integrity": "sha512-XIPtRnxSES4CoxH2BfUY/6QzNgEgJEUjMYu7t7SJR8bVfbLRVXAA1ie9kM0MtdLs4oZ2Pr8rR8fqytsA1CjEWw==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.4.3.tgz", + "integrity": "sha512-MdnMKVZCiC3oqC38pNAkvP5FPomMHK+Hk4bD0JMAKRt7WamQBmaxdObwZAcJMzpn7izYWoo0avZoGYbE/fHRXA==", "dev": true, "requires": { "@types/node": "^20.11.30", "@types/sinonjs__fake-timers": "^8.1.5", - "@wdio/config": "9.2.8", + "@wdio/config": "9.4.3", "@wdio/logger": "9.1.3", "@wdio/protocols": "9.2.2", "@wdio/repl": "9.0.8", - "@wdio/types": "9.2.2", - "@wdio/utils": "9.2.8", + "@wdio/types": "9.4.3", + "@wdio/utils": "9.4.3", "archiver": "^7.0.1", "aria-query": "^5.3.0", "cheerio": "^1.0.0-rc.12", @@ -41452,7 +41871,7 @@ "rgb2hex": "0.2.5", "serialize-error": "^11.0.3", "urlpattern-polyfill": "^10.0.0", - "webdriver": "9.4.1" + "webdriver": "9.4.3" }, "dependencies": { "brace-expansion": { @@ -41937,6 +42356,12 @@ "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true }, + "workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -42075,6 +42500,26 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, "yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", diff --git a/package.json b/package.json index e213131e28..bcfd89de40 100644 --- a/package.json +++ b/package.json @@ -139,10 +139,10 @@ "@types/amplitude-js": "8.16.5", "@types/audioworklet": "0.0.29", "@types/dom-screen-wake-lock": "1.0.1", - "@types/jasmine": "5.1.4", "@types/js-md5": "0.4.3", "@types/jsonwebtoken": "9.0.7", "@types/lodash-es": "4.17.12", + "@types/mocha": "10.0.10", "@types/moment-duration-format": "2.2.6", "@types/offscreencanvas": "2019.7.2", "@types/pixelmatch": "5.2.5", @@ -162,12 +162,12 @@ "@types/zxcvbn": "4.4.1", "@typescript-eslint/eslint-plugin": "5.59.5", "@typescript-eslint/parser": "5.59.5", - "@wdio/allure-reporter": "9.2.14", - "@wdio/cli": "9.4.1", - "@wdio/globals": "9.4.1", - "@wdio/jasmine-framework": "9.4.1", - "@wdio/junit-reporter": "9.2.14", - "@wdio/local-runner": "9.4.1", + "@wdio/allure-reporter": "9.4.3", + "@wdio/cli": "9.4.3", + "@wdio/globals": "9.4.3", + "@wdio/junit-reporter": "9.4.3", + "@wdio/local-runner": "9.4.3", + "@wdio/mocha-framework": "9.4.3", "babel-loader": "9.1.0", "babel-plugin-optional-require": "0.3.1", "circular-dependency-plugin": "5.2.0", @@ -191,7 +191,7 @@ "ts-loader": "9.4.2", "typescript": "5.0.4", "unorm": "1.6.0", - "webdriverio": "9.4.1", + "webdriverio": "9.4.3", "webpack": "5.95.0", "webpack-bundle-analyzer": "4.4.2", "webpack-cli": "5.1.4", diff --git a/tests/env.example b/tests/env.example index d148838be4..01eedff4d1 100644 --- a/tests/env.example +++ b/tests/env.example @@ -1,4 +1,5 @@ # The base url that will be used for the test (default will be using "https://alpha.jitsi.net") +# If there is a tenant in the URL it must end with a slash (e.g. "https://alpha.jitsi.net/sometenant/") #BASE_URL= # To be able to match a domain to a specific address diff --git a/tests/globals.d.ts b/tests/globals.d.ts index 41648b9ebd..f02dccea93 100644 --- a/tests/globals.d.ts +++ b/tests/globals.d.ts @@ -1,5 +1,5 @@ import { IContext } from './helpers/types'; declare global { - const context: IContext; + const ctx: IContext; } diff --git a/tests/helpers/Participant.ts b/tests/helpers/Participant.ts index 263f08848f..1881445151 100644 --- a/tests/helpers/Participant.ts +++ b/tests/helpers/Participant.ts @@ -6,6 +6,7 @@ import { IConfig } from '../../react/features/base/config/configType'; import { urlObjectToString } from '../../react/features/base/util/uri'; import Filmstrip from '../pageobjects/Filmstrip'; import IframeAPI from '../pageobjects/IframeAPI'; +import Notifications from '../pageobjects/Notifications'; import ParticipantsPane from '../pageobjects/ParticipantsPane'; import SettingsDialog from '../pageobjects/SettingsDialog'; import Toolbar from '../pageobjects/Toolbar'; @@ -112,13 +113,13 @@ export class Participant { /** * Joins conference. * - * @param {IContext} context - The context. + * @param {IContext} ctx - The context. * @param {IJoinOptions} options - Options for joining. * @returns {Promise} */ - async joinConference(context: IContext, options: IJoinOptions = {}): Promise { + async joinConference(ctx: IContext, options: IJoinOptions = {}): Promise { const config = { - room: context.roomName, + room: ctx.roomName, configOverwrite: this.config, interfaceConfigOverwrite: { SHOW_CHROME_EXTENSION_BANNER: false @@ -132,17 +133,17 @@ export class Participant { }; } - if (context.iframeAPI) { + if (ctx.iframeAPI) { config.room = 'iframeAPITest.html'; } let url = urlObjectToString(config) || ''; - if (context.iframeAPI) { + if (ctx.iframeAPI) { const baseUrl = new URL(this.driver.options.baseUrl || ''); // @ts-ignore - url = `${this.driver.iframePageBase}${url}&domain="${baseUrl.host}"&room="${context.roomName}"`; + url = `${this.driver.iframePageBase}${url}&domain="${baseUrl.host}"&room="${ctx.roomName}"`; if (baseUrl.pathname.length > 1) { // remove leading slash @@ -155,17 +156,12 @@ export class Participant { await this.driver.setTimeout({ 'pageLoad': 30000 }); - // workaround for https://github.com/webdriverio/webdriverio/issues/13956 - if (url.startsWith('file://')) { - // eslint-disable-next-line @typescript-eslint/no-empty-function - await this.driver.url(url).catch(() => {}); - } else { - await this.driver.url(url.substring(1)); // drop the leading '/' so we can use the tenant if any - } + // drop the leading '/' so we can use the tenant if any + await this.driver.url(url.startsWith('/') ? url.substring(1) : url); await this.waitForPageToLoad(); - if (context.iframeAPI) { + if (ctx.iframeAPI) { const mainFrame = this.driver.$('iframe'); await this.driver.switchFrame(mainFrame); @@ -247,6 +243,14 @@ export class Participant { return await this.driver.execute(() => typeof APP !== 'undefined' && APP.conference?.isJoined()); } + /** + * Checks if the participant is a moderator in the meeting. + */ + async isModerator() { + return await this.driver.execute(() => typeof APP !== 'undefined' + && APP.store?.getState()['features/base/participants']?.local?.role === 'moderator'); + } + /** * Waits to join the muc. * @@ -335,6 +339,13 @@ export class Participant { return new Filmstrip(this); } + /** + * Returns the notifications. + */ + getNotifications(): Notifications { + return new Notifications(this); + } + /** * Returns the participants pane. * @@ -489,7 +500,7 @@ export class Participant { async assertDisplayNameVisibleOnStage(value: string) { const displayNameEl = this.driver.$('div[data-testid="stage-display-name"]'); - expect(await displayNameEl.isDisplayed()).toBeTrue(); + expect(await displayNameEl.isDisplayed()).toBe(true); expect(await displayNameEl.getText()).toBe(value); } } diff --git a/tests/helpers/participants.ts b/tests/helpers/participants.ts index d411d6c4f3..2ed58664a0 100644 --- a/tests/helpers/participants.ts +++ b/tests/helpers/participants.ts @@ -4,44 +4,19 @@ import process from 'node:process'; import { v4 as uuidv4 } from 'uuid'; import { Participant } from './Participant'; -import WebhookProxy from './WebhookProxy'; import { IContext, IJoinOptions } from './types'; -/** - * Generate a random room name. - * Everytime we generate a name and iframeAPI is enabled and there is a configured - * webhooks proxy we connect to it with the new room name. - * - * @returns {string} - The random room name. - */ -function generateRandomRoomName(): string { - const roomName = `jitsimeettorture-${crypto.randomUUID()}`; - - if (context.iframeAPI && !context.webhooksProxy - && process.env.WEBHOOKS_PROXY_URL && process.env.WEBHOOKS_PROXY_SHARED_SECRET) { - context.webhooksProxy = new WebhookProxy(`${process.env.WEBHOOKS_PROXY_URL}&room=${roomName}`, - process.env.WEBHOOKS_PROXY_SHARED_SECRET); - context.webhooksProxy.connect(); - } - - return roomName; -} - /** * Ensure that there is on participant. * - * @param {IContext} context - The context. + * @param {IContext} ctx - The context. * @param {IJoinOptions} options - The options to use when joining the participant. * @returns {Promise} */ -export async function ensureOneParticipant(context: IContext, options?: IJoinOptions): Promise { - if (!context.roomName) { - context.roomName = generateRandomRoomName(); - } +export async function ensureOneParticipant(ctx: IContext, options?: IJoinOptions): Promise { + ctx.p1 = new Participant('participant1'); - context.p1 = new Participant('participant1'); - - await context.p1.joinConference(context, { + await ctx.p1.joinConference(ctx, { ...options, skipInMeetingChecks: true }); @@ -50,70 +25,72 @@ export async function ensureOneParticipant(context: IContext, options?: IJoinOpt /** * Ensure that there are three participants. * - * @param {Object} context - The context. + * @param {Object} ctx - The context. * @returns {Promise} */ -export async function ensureThreeParticipants(context: IContext): Promise { - if (!context.roomName) { - context.roomName = generateRandomRoomName(); - } +export async function ensureThreeParticipants(ctx: IContext): Promise { + await joinTheModeratorAsP1(ctx); - const p1 = new Participant('participant1'); const p2 = new Participant('participant2'); const p3 = new Participant('participant3'); - context.p1 = p1; - context.p2 = p2; - context.p3 = p3; + ctx.p2 = p2; + ctx.p3 = p3; // these need to be all, so we get the error when one fails await Promise.all([ - p1.joinConference(context), - p2.joinConference(context), - p3.joinConference(context) + p2.joinConference(ctx), + p3.joinConference(ctx) ]); await Promise.all([ - p1.waitForRemoteStreams(2), p2.waitForRemoteStreams(2), p3.waitForRemoteStreams(2) ]); } /** - * Ensure that there are two participants. + * Ensure that the first participant is moderator. * - * @param {Object} context - The context. + * @param {Object} ctx - The context. * @param {IJoinOptions} options - The options to join. * @returns {Promise} */ -export async function ensureTwoParticipants(context: IContext, options?: IJoinOptions): Promise { - if (!context.roomName) { - context.roomName = generateRandomRoomName(); - } - +async function joinTheModeratorAsP1(ctx: IContext, options?: IJoinOptions) { const p1DisplayName = 'participant1'; let token; // if it is jaas create the first one to be moderator and second not moderator - if (context.jwtPrivateKeyPath) { + if (ctx.jwtPrivateKeyPath && !options?.skipFirstModerator) { token = getModeratorToken(p1DisplayName); } // make sure the first participant is moderator, if supported by deployment - await _joinParticipant(p1DisplayName, context.p1, p => { - context.p1 = p; + await _joinParticipant(p1DisplayName, ctx.p1, p => { + ctx.p1 = p; }, { ...options, skipInMeetingChecks: true }, token); +} + +/** + * Ensure that there are two participants. + * + * @param {Object} ctx - The context. + * @param {IJoinOptions} options - The options to join. + */ +export async function ensureTwoParticipants(ctx: IContext, options: IJoinOptions = {}): Promise { + await joinTheModeratorAsP1(ctx, options); + + const { skipInMeetingChecks } = options; await Promise.all([ - _joinParticipant('participant2', context.p2, p => { - context.p2 = p; + _joinParticipant('participant2', ctx.p2, p => { + ctx.p2 = p; }, options), - context.p1.waitForRemoteStreams(1), - context.p2.waitForRemoteStreams(1) + skipInMeetingChecks ? Promise.resolve() : ctx.p1.waitForRemoteStreams(1), + skipInMeetingChecks ? Promise.resolve() : ctx.p2.waitForRemoteStreams(1) ]); } @@ -132,7 +109,7 @@ async function _joinParticipant( // eslint-disable-line max-params options: IJoinOptions = {}, jwtToken?: string) { if (p) { - if (context.iframeAPI) { + if (ctx.iframeAPI) { await p.switchInPage(); } @@ -140,7 +117,7 @@ async function _joinParticipant( // eslint-disable-line max-params return; } - if (context.iframeAPI) { + if (ctx.iframeAPI) { // when loading url make sure we are on the top page context or strange errors may occur await p.switchToAPI(); } @@ -156,7 +133,7 @@ async function _joinParticipant( // eslint-disable-line max-params // set the new participant instance, pass it to setter setter(newParticipant); - await newParticipant.joinConference(context, options); + await newParticipant.joinConference(ctx, options); } /** @@ -176,16 +153,28 @@ export async function muteAudioAndCheck(testee: Participant, observer: Participa await testee.getFilmstrip().assertAudioMuteIconIsDisplayed(testee); } +/** + * Unmute audio, checks if the local UI has been updated accordingly and then does the verification from + * the other observer participant perspective. + * @param testee + * @param observer + */ +export async function unmuteAudioAndCheck(testee: Participant, observer: Participant) { + await testee.getToolbar().clickAudioUnmuteButton(); + await testee.getFilmstrip().assertAudioMuteIconIsDisplayed(testee, true); + await observer.getFilmstrip().assertAudioMuteIconIsDisplayed(testee, true); +} + /** * Starts the video on testee and check on observer. * @param testee * @param observer */ -export async function unMuteVideoAndCheck(testee: Participant, observer: Participant): Promise { +export async function unmuteVideoAndCheck(testee: Participant, observer: Participant): Promise { await testee.getToolbar().clickVideoUnmuteButton(); - await observer.getParticipantsPane().assertVideoMuteIconIsDisplayed(testee, true); await testee.getParticipantsPane().assertVideoMuteIconIsDisplayed(testee, true); + await observer.getParticipantsPane().assertVideoMuteIconIsDisplayed(testee, true); } /** @@ -206,7 +195,7 @@ function getModeratorToken(displayName: string) { return; } - const key = fs.readFileSync(context.jwtPrivateKeyPath); + const key = fs.readFileSync(ctx.jwtPrivateKeyPath); const payload = { 'aud': 'jitsi', diff --git a/tests/helpers/types.ts b/tests/helpers/types.ts index 4f292f72d2..e03e82ea1a 100644 --- a/tests/helpers/types.ts +++ b/tests/helpers/types.ts @@ -11,6 +11,7 @@ export type IContext = { p3: Participant; p4: Participant; roomName: string; + skipSuiteTests: boolean; webhooksProxy: WebhookProxy; }; @@ -21,6 +22,11 @@ export type IJoinOptions = { */ skipDisplayName?: boolean; + /** + * Whether to skip setting the moderator role for the first participant (whether to use jwt for it). + */ + skipFirstModerator?: boolean; + /** * Whether to skip in meeting checks like ice connected and send receive data. For single in meeting participant. */ diff --git a/tests/pageobjects/AVModerationMenu.ts b/tests/pageobjects/AVModerationMenu.ts new file mode 100644 index 0000000000..62e91eaa7f --- /dev/null +++ b/tests/pageobjects/AVModerationMenu.ts @@ -0,0 +1,66 @@ +import { Participant } from '../helpers/Participant'; + +const START_AUDIO_MODERATION = 'participants-pane-context-menu-start-audio-moderation'; +const STOP_AUDIO_MODERATION = 'participants-pane-context-menu-stop-audio-moderation'; +const START_VIDEO_MODERATION = 'participants-pane-context-menu-start-video-moderation'; +const STOP_VIDEO_MODERATION = 'participants-pane-context-menu-stop-video-moderation'; + +/** + * Represents the Audio Video Moderation menu in the participants pane. + */ +export default class AVModerationMenu { + private participant: Participant; + + /** + * Represents the Audio Video Moderation menu in the participants pane. + * @param participant + */ + constructor(participant: Participant) { + this.participant = participant; + } + + /** + * Clicks the start audio moderation menu item. + */ + async clickStartAudioModeration() { + await this.clickButton(START_AUDIO_MODERATION); + } + + /** + * Clicks the stop audio moderation menu item. + */ + async clickStopAudioModeration() { + await this.clickButton(STOP_AUDIO_MODERATION); + } + + /** + * Clicks the start video moderation menu item. + */ + async clickStartVideoModeration() { + await this.clickButton(START_VIDEO_MODERATION); + } + + /** + * Clicks the stop audio moderation menu item. + */ + async clickStopVideoModeration() { + await this.clickButton(STOP_VIDEO_MODERATION); + } + + /** + * Clicks a context menu button. + * @param id + * @private + */ + private async clickButton(id: string) { + const button = this.participant.driver.$(`#${id}`); + + await button.waitForDisplayed(); + await button.click(); + + await button.moveTo({ + xOffset: -40, + yOffset: -40 + }); + } +} diff --git a/tests/pageobjects/Filmstrip.ts b/tests/pageobjects/Filmstrip.ts index 04f5ab5151..1bd003e591 100644 --- a/tests/pageobjects/Filmstrip.ts +++ b/tests/pageobjects/Filmstrip.ts @@ -1,5 +1,7 @@ import { Participant } from '../helpers/Participant'; +import BaseDialog from './BaseDialog'; + /** * Filmstrip elements. */ @@ -40,7 +42,7 @@ export default class Filmstrip { await this.participant.driver.$(mutedIconXPath).waitForDisplayed({ reverse, timeout: 2000, - timeoutMsg: `Audio mute icon is ${reverse ? '' : 'not'} displayed for ${testee.name}` + timeoutMsg: `Audio mute icon is${reverse ? '' : ' not'} displayed for ${testee.name}` }); } @@ -77,4 +79,56 @@ export default class Filmstrip { return await elem.isExisting() ? elem.getAttribute('src') : null; } + + /** + * Grants moderator rights to a participant. + * @param participant + */ + async grantModerator(participant: Participant) { + await this.clickOnRemoteMenuLink(await participant.getEndpointId(), 'grantmoderatorlink', true); + } + + /** + * Clicks on the link in the remote participant actions menu. + * @param participantId + * @param linkClassname + * @param dialogConfirm + * @private + */ + private async clickOnRemoteMenuLink(participantId: string, linkClassname: string, dialogConfirm: boolean) { + const thumbnail = this.participant.driver.$( + `//span[@id='participant_${participantId}']//span[@id='remotevideomenu']`); + + await thumbnail.moveTo(); + + const popoverElement = this.participant.driver.$( + `//div[contains(@class, 'popover')]//div[contains(@class, '${linkClassname}')]`); + + await popoverElement.waitForDisplayed(); + await popoverElement.click(); + + if (dialogConfirm) { + await new BaseDialog(this.participant).clickOkButton(); + } + } + + /** + * Mutes the audio of a participant. + * @param participant + */ + async muteAudio(participant: Participant) { + const participantId = await participant.getEndpointId(); + + await this.participant.driver.$(`#participant-item-${participantId}`).moveTo(); + + await this.participant.driver.$(`button[data-testid="mute-audio-${participantId}"]`).click(); + } + + /** + * Mutes the video of a participant. + * @param participant + */ + async muteVideo(participant: Participant) { + await this.clickOnRemoteMenuLink(await participant.getEndpointId(), 'mutevideolink', true); + } } diff --git a/tests/pageobjects/Notifications.ts b/tests/pageobjects/Notifications.ts new file mode 100644 index 0000000000..e1ffc9ac9c --- /dev/null +++ b/tests/pageobjects/Notifications.ts @@ -0,0 +1,54 @@ +import { Participant } from '../helpers/Participant'; + +const ASK_TO_UNMUTE_NOTIFICATION_ID = 'notify.hostAskedUnmute'; +const JOIN_ONE_TEST_ID = 'notify.connectedOneMember'; +const JOIN_TWO_TEST_ID = 'notify.connectedTwoMembers'; +const JOIN_MULTIPLE_TEST_ID = 'notify.connectedThreePlusMembers'; +const RAISE_HAND_NOTIFICATION_ID = 'notify.raisedHand'; + +/** + * Gathers all notifications logic in the UI and obtaining those. + */ +export default class Notifications { + private participant: Participant; + + /** + * Represents the Audio Video Moderation menu in the participants pane. + * @param participant + */ + constructor(participant: Participant) { + this.participant = participant; + } + + /** + * Waits for the raised hand notification to be displayed. + * The notification on moderators page when the participant tries to unmute. + */ + async waitForRaisedHandNotification() { + const displayNameEl + = this.participant.driver.$(`div[data-testid="${RAISE_HAND_NOTIFICATION_ID}"]`); + + await displayNameEl.waitForExist({ timeout: 2000 }); + await displayNameEl.waitForDisplayed(); + } + + /** + * The notification on participants page when the moderator asks to unmute. + */ + async waitForAskToUnmuteNotification() { + const displayNameEl + = this.participant.driver.$(`div[data-testid="${ASK_TO_UNMUTE_NOTIFICATION_ID}"]`); + + await displayNameEl.waitForExist({ timeout: 2000 }); + await displayNameEl.waitForDisplayed(); + } + + /** + * Dismisses any join notifications. + */ + async dismissAnyJoinNotification() { + await Promise.allSettled( + [ `${JOIN_ONE_TEST_ID}-dismiss`, `${JOIN_TWO_TEST_ID}-dismiss`, `${JOIN_MULTIPLE_TEST_ID}-dismiss` ] + .map(async id => this.participant.driver.$(`#${id}"]`).click())); + } +} diff --git a/tests/pageobjects/ParticipantsPane.ts b/tests/pageobjects/ParticipantsPane.ts index 64bd73fe8e..2e636ed72e 100644 --- a/tests/pageobjects/ParticipantsPane.ts +++ b/tests/pageobjects/ParticipantsPane.ts @@ -1,5 +1,7 @@ import { Participant } from '../helpers/Participant'; +import AVModerationMenu from './AVModerationMenu'; + /** * Classname of the closed/hidden participants pane */ @@ -20,6 +22,13 @@ export default class ParticipantsPane { this.participant = participant; } + /** + * Gets the audio video moderation menu. + */ + getAVModerationMenu() { + return new AVModerationMenu(this.participant); + } + /** * Checks if the pane is open. */ @@ -33,7 +42,11 @@ export default class ParticipantsPane { async open() { await this.participant.getToolbar().clickParticipantsPaneButton(); - await this.participant.driver.$(`.${PARTICIPANTS_PANE}`).waitForDisplayed(); + const pane = this.participant.driver.$(`.${PARTICIPANTS_PANE}`); + + await pane.waitForExist(); + await pane.waitForStable(); + await pane.waitForDisplayed(); } /** @@ -68,11 +81,85 @@ export default class ParticipantsPane { await this.participant.driver.$(mutedIconXPath).waitForDisplayed({ reverse, timeout: 2000, - timeoutMsg: `Video mute icon is ${reverse ? '' : 'not'} displayed for ${testee.name}` + timeoutMsg: `Video mute icon is${reverse ? '' : ' not'} displayed for ${testee.name}` }); if (!isOpen) { await this.close(); } } + + /** + * Clicks the context menu button in the participants pane. + */ + async clickContextMenuButton() { + if (!await this.isOpen()) { + await this.open(); + } + + const menu = this.participant.driver.$('#participants-pane-context-menu'); + + await menu.waitForDisplayed(); + await menu.click(); + } + + /** + * Trys to click allow video button. + * @param participantToUnmute + */ + async allowVideo(participantToUnmute: Participant) { + if (!await this.isOpen()) { + await this.open(); + } + + const participantId = await participantToUnmute.getEndpointId(); + const participantItem = this.participant.driver.$(`#participant-item-${participantId}`); + + await participantItem.waitForExist(); + await participantItem.moveTo(); + + const unmuteButton = this.participant.driver + .$(`button[data-testid="unmute-video-${participantId}"]`); + + await unmuteButton.waitForExist(); + await unmuteButton.click(); + } + + /** + * Trys to click ask to unmute button. + * @param participantToUnmute + * @param fromContextMenu + */ + async askToUnmute(participantToUnmute: Participant, fromContextMenu: boolean) { + if (!await this.isOpen()) { + await this.open(); + } + + await this.participant.getNotifications().dismissAnyJoinNotification(); + + const participantId = await participantToUnmute.getEndpointId(); + const participantItem = this.participant.driver.$(`#participant-item-${participantId}`); + + await participantItem.waitForExist(); + await participantItem.waitForStable(); + await participantItem.waitForDisplayed(); + await participantItem.moveTo(); + + if (fromContextMenu) { + const meetingParticipantMoreOptions = this.participant.driver + .$(`[data-testid="participant-more-options-${participantId}"]`); + + await meetingParticipantMoreOptions.waitForExist(); + await meetingParticipantMoreOptions.waitForDisplayed(); + await meetingParticipantMoreOptions.waitForStable(); + await meetingParticipantMoreOptions.moveTo(); + await meetingParticipantMoreOptions.click(); + } + + const unmuteButton = this.participant.driver + .$(`[data-testid="unmute-audio-${participantId}"]`); + + await unmuteButton.waitForExist(); + await unmuteButton.click(); + } } diff --git a/tests/pageobjects/Toolbar.ts b/tests/pageobjects/Toolbar.ts index 11d85051fd..2a4b7a05f7 100644 --- a/tests/pageobjects/Toolbar.ts +++ b/tests/pageobjects/Toolbar.ts @@ -8,6 +8,7 @@ const OVERFLOW_MENU = 'More actions menu'; const OVERFLOW = 'More actions'; const PARTICIPANTS = 'Open participants pane'; const PROFILE = 'Edit your profile'; +const RAISE_HAND = 'Raise your hand'; const VIDEO_QUALITY = 'Manage video quality'; const VIDEO_MUTE = 'Stop camera'; const VIDEO_UNMUTE = 'Start camera'; @@ -142,6 +143,14 @@ export default class Toolbar { return this.clickButtonInOverflowMenu(PROFILE); } + /** + * Clicks on the raise hand button that enables participants will to speak. + */ + async clickRaiseHandButton(): Promise { + this.participant.log('Clicking on: Raise hand Button'); + await this.getButton(RAISE_HAND).click(); + } + /** * Ensure the overflow menu is open and clicks on a specified button. * @param accessibilityLabel The accessibility label of the button to be clicked. @@ -150,6 +159,7 @@ export default class Toolbar { private async clickButtonInOverflowMenu(accessibilityLabel: string) { await this.openOverflowMenu(); + this.participant.log(`Clicking on: ${accessibilityLabel}`); await this.getButton(accessibilityLabel).click(); await this.closeOverflowMenu(); diff --git a/tests/specs/2way/audioOnly.spec.ts b/tests/specs/2way/audioOnly.spec.ts index 17344cd020..951c6831f9 100644 --- a/tests/specs/2way/audioOnly.spec.ts +++ b/tests/specs/2way/audioOnly.spec.ts @@ -2,7 +2,9 @@ import { ensureTwoParticipants } from '../../helpers/participants'; describe('Audio only - ', () => { it('joining the meeting', async () => { - await ensureTwoParticipants(context); + await ensureTwoParticipants(ctx, { + skipFirstModerator: true + }); }); /** @@ -16,10 +18,12 @@ describe('Audio only - ', () => { * Verifies that participant1 sees avatars for itself and other participants. */ it('avatars check', async () => { - await context.p1.driver.$('//div[@id="dominantSpeaker"]').waitForDisplayed(); + const { p1 } = ctx; + + await p1.driver.$('//div[@id="dominantSpeaker"]').waitForDisplayed(); // Makes sure that the avatar is displayed in the local thumbnail and that the video is not displayed. - await context.p1.assertThumbnailShowsAvatar(context.p1); + await p1.assertThumbnailShowsAvatar(p1); }); /** @@ -35,11 +39,13 @@ describe('Audio only - ', () => { * @param enable */ async function setAudioOnlyAndCheck(enable: boolean) { - await context.p1.getVideoQualityDialog().setVideoQuality(enable); + const { p1 } = ctx; + + await p1.getVideoQualityDialog().setVideoQuality(enable); await verifyVideoMute(enable); - await context.p1.driver.$('//div[@id="videoResolutionLabel"][contains(@class, "audio-only")]') + await p1.driver.$('//div[@id="videoResolutionLabel"][contains(@class, "audio-only")]') .waitForDisplayed({ reverse: !enable }); } @@ -48,11 +54,13 @@ describe('Audio only - ', () => { * @param muted */ async function verifyVideoMute(muted: boolean) { + const { p1, p2 } = ctx; + // Verify the observer sees the testee in the desired muted state. - await context.p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(context.p1, !muted); + await p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1, !muted); // Verify the testee sees itself in the desired muted state. - await context.p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(context.p1, !muted); + await p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1, !muted); } /** @@ -60,8 +68,10 @@ describe('Audio only - ', () => { * as video muted. */ it('mute video, set twice and check muted', async () => { + const { p1 } = ctx; + // Mute video on participant1. - await context.p1.getToolbar().clickVideoMuteButton(); + await p1.getToolbar().clickVideoMuteButton(); await verifyVideoMute(true); @@ -69,7 +79,7 @@ describe('Audio only - ', () => { await setAudioOnlyAndCheck(true); // Disable audio-only mode. - await context.p1.getVideoQualityDialog().setVideoQuality(false); + await p1.getVideoQualityDialog().setVideoQuality(false); // p1 should stay muted since it was muted before audio-only was enabled. await verifyVideoMute(true); @@ -77,7 +87,7 @@ describe('Audio only - ', () => { it('unmute video and check not muted', async () => { // Unmute video on participant1. - await context.p1.getToolbar().clickVideoUnmuteButton(); + await ctx.p1.getToolbar().clickVideoUnmuteButton(); await verifyVideoMute(false); }); diff --git a/tests/specs/2way/iFrameParticipantsPresence.spec.ts b/tests/specs/2way/iFrameApiParticipantsPresence.spec.ts similarity index 86% rename from tests/specs/2way/iFrameParticipantsPresence.spec.ts rename to tests/specs/2way/iFrameApiParticipantsPresence.spec.ts index 0f647e737d..c9c6e6989c 100644 --- a/tests/specs/2way/iFrameParticipantsPresence.spec.ts +++ b/tests/specs/2way/iFrameApiParticipantsPresence.spec.ts @@ -7,7 +7,7 @@ import { ensureTwoParticipants, parseJid } from '../../helpers/participants'; * Tests PARTICIPANT_LEFT webhook. */ async function checkParticipantLeftHook(p: Participant, reason: string) { - const { webhooksProxy } = context; + const { webhooksProxy } = ctx; if (webhooksProxy) { // PARTICIPANT_LEFT webhook @@ -20,10 +20,10 @@ async function checkParticipantLeftHook(p: Participant, reason: string) { participantId: string; }; eventType: string; - } = await context.webhooksProxy.waitForEvent('PARTICIPANT_LEFT'); + } = await webhooksProxy.waitForEvent('PARTICIPANT_LEFT'); expect('PARTICIPANT_LEFT').toBe(event.eventType); - expect(event.data.conference).toBe(context.conferenceJid); + expect(event.data.conference).toBe(ctx.conferenceJid); expect(event.data.disconnectReason).toBe(reason); expect(event.data.isBreakout).toBe(false); expect(event.data.participantId).toBe(await p.getEndpointId()); @@ -32,12 +32,10 @@ async function checkParticipantLeftHook(p: Participant, reason: string) { describe('Participants presence - ', () => { it('joining the meeting', async () => { - context.iframeAPI = true; - // ensure 2 participants one moderator and one guest, we will load both with iframeAPI - await ensureTwoParticipants(context); + await ensureTwoParticipants(ctx); - const { p1, p2, webhooksProxy } = context; + const { p1, p2, webhooksProxy } = ctx; // let's populate endpoint ids await Promise.all([ @@ -48,12 +46,8 @@ describe('Participants presence - ', () => { await p1.switchToAPI(); await p2.switchToAPI(); - expect(await p1.getIframeAPI().getEventResult('isModerator')) - .withContext('Is p1 moderator') - .toBeTrue(); - expect(await p2.getIframeAPI().getEventResult('isModerator')) - .withContext('Is p2 non-moderator') - .toBeFalse(); + expect(await p1.getIframeAPI().getEventResult('isModerator')).toBe(true); + expect(await p2.getIframeAPI().getEventResult('isModerator')).toBe(false); expect(await p1.getIframeAPI().getEventResult('videoConferenceJoined')).toBeDefined(); expect(await p2.getIframeAPI().getEventResult('videoConferenceJoined')).toBeDefined(); @@ -66,7 +60,7 @@ describe('Participants presence - ', () => { { participantId: string; } ]; eventType: string; - } = await context.webhooksProxy.waitForEvent('USAGE'); + } = await webhooksProxy.waitForEvent('USAGE'); expect('USAGE').toBe(event.eventType); @@ -85,11 +79,11 @@ describe('Participants presence - ', () => { it('participants info', async () => { - const { p1, roomName, webhooksProxy } = context; + const { p1, roomName, webhooksProxy } = ctx; const roomsInfo = (await p1.getIframeAPI().getRoomsInfo()).rooms[0]; expect(roomsInfo).toBeDefined(); - expect(roomsInfo.isMainRoom).toBeTrue(); + expect(roomsInfo.isMainRoom).toBe(true); expect(roomsInfo.id).toBeDefined(); const { node: roomNode } = parseJid(roomsInfo.id); @@ -98,7 +92,7 @@ describe('Participants presence - ', () => { const { node, resource } = parseJid(roomsInfo.jid); - context.conferenceJid = roomsInfo.jid.substring(0, roomsInfo.jid.indexOf('/')); + ctx.conferenceJid = roomsInfo.jid.substring(0, roomsInfo.jid.indexOf('/')); const p1EpId = await p1.getEndpointId(); @@ -117,17 +111,17 @@ describe('Participants presence - ', () => { isBreakout: boolean; }; eventType: string; - } = await context.webhooksProxy.waitForEvent('ROOM_CREATED'); + } = await webhooksProxy.waitForEvent('ROOM_CREATED'); expect('ROOM_CREATED').toBe(event.eventType); - expect(event.data.conference).toBe(context.conferenceJid); + expect(event.data.conference).toBe(ctx.conferenceJid); expect(event.data.isBreakout).toBe(false); } } ); it('participants pane', async () => { - const { p1 } = context; + const { p1 } = ctx; await p1.switchToAPI(); @@ -145,7 +139,7 @@ describe('Participants presence - ', () => { }); it('grant moderator', async () => { - const { p1, p2, webhooksProxy } = context; + const { p1, p2, webhooksProxy } = ctx; const p2EpId = await p2.getEndpointId(); await p1.getIframeAPI().executeCommand('grantModerator', p2EpId); @@ -179,7 +173,7 @@ describe('Participants presence - ', () => { role: string; }; eventType: string; - } = await context.webhooksProxy.waitForEvent('ROLE_CHANGED'); + } = await webhooksProxy.waitForEvent('ROLE_CHANGED'); expect('ROLE_CHANGED').toBe(event.eventType); expect(event.data.role).toBe('moderator'); @@ -189,7 +183,7 @@ describe('Participants presence - ', () => { }); it('kick participant', async () => { - const { p1, p2 } = context; + const { p1, p2, roomName } = ctx; const p1EpId = await p1.getEndpointId(); const p2EpId = await p2.getEndpointId(); @@ -235,7 +229,7 @@ describe('Participants presence - ', () => { local: true, name: p1DisplayName } - })).toBeTrue(); + })).toBe(true); expect(isEqual(eventP2, { kicked: { @@ -247,7 +241,7 @@ describe('Participants presence - ', () => { id: p1EpId, name: p1DisplayName } - })).toBeTrue(); + })).toBe(true); const eventConferenceLeftP2 = await p2.driver.waitUntil(async () => await p2.getIframeAPI().getEventResult('videoConferenceLeft'), { @@ -256,11 +250,11 @@ describe('Participants presence - ', () => { }); expect(eventConferenceLeftP2).toBeDefined(); - expect(eventConferenceLeftP2.roomName).toBe(context.roomName); + expect(eventConferenceLeftP2.roomName).toBe(roomName); }); it('join after kick', async () => { - const { p1, webhooksProxy } = context; + const { p1, webhooksProxy } = ctx; await p1.getIframeAPI().addEventListener('participantJoined'); await p1.getIframeAPI().addEventListener('participantMenuButtonClick'); @@ -268,7 +262,8 @@ describe('Participants presence - ', () => { webhooksProxy?.clearCache(); // join again - await ensureTwoParticipants(context); + await ensureTwoParticipants(ctx); + const { p2 } = ctx; if (webhooksProxy) { // PARTICIPANT_JOINED webhook @@ -282,14 +277,14 @@ describe('Participants presence - ', () => { participantId: string; }; eventType: string; - } = await context.webhooksProxy.waitForEvent('PARTICIPANT_JOINED'); + } = await webhooksProxy.waitForEvent('PARTICIPANT_JOINED'); expect('PARTICIPANT_JOINED').toBe(event.eventType); - expect(event.data.conference).toBe(context.conferenceJid); + expect(event.data.conference).toBe(ctx.conferenceJid); expect(event.data.isBreakout).toBe(false); expect(event.data.moderator).toBe(false); - expect(event.data.name).toBe(await context.p2.getLocalDisplayName()); - expect(event.data.participantId).toBe(await context.p2.getEndpointId()); + expect(event.data.name).toBe(await p2.getLocalDisplayName()); + expect(event.data.participantId).toBe(await p2.getEndpointId()); } await p1.switchToAPI(); @@ -300,7 +295,6 @@ describe('Participants presence - ', () => { timeoutMsg: 'participantJoined not received' }); - const { p2 } = context; const p2DisplayName = await p2.getLocalDisplayName(); expect(event).toBeDefined(); @@ -311,7 +305,7 @@ describe('Participants presence - ', () => { }); it('overwrite names', async () => { - const { p1, p2 } = context; + const { p1, p2 } = ctx; const p1EpId = await p1.getEndpointId(); const p2EpId = await p2.getEndpointId(); @@ -337,7 +331,7 @@ describe('Participants presence - ', () => { }); it('hangup', async () => { - const { p1, p2 } = context; + const { p1, p2, roomName } = ctx; await p1.switchToAPI(); await p2.switchToAPI(); @@ -354,7 +348,7 @@ describe('Participants presence - ', () => { }); expect(eventConferenceLeftP2).toBeDefined(); - expect(eventConferenceLeftP2.roomName).toBe(context.roomName); + expect(eventConferenceLeftP2.roomName).toBe(roomName); await checkParticipantLeftHook(p2, 'left'); @@ -368,7 +362,7 @@ describe('Participants presence - ', () => { }); it('dispose conference', async () => { - const { p1, webhooksProxy } = context; + const { conferenceJid, p1, roomName, webhooksProxy } = ctx; await p1.switchToAPI(); @@ -384,7 +378,7 @@ describe('Participants presence - ', () => { }); expect(eventConferenceLeft).toBeDefined(); - expect(eventConferenceLeft.roomName).toBe(context.roomName); + expect(eventConferenceLeft.roomName).toBe(roomName); await checkParticipantLeftHook(p1, 'left'); if (webhooksProxy) { @@ -396,10 +390,10 @@ describe('Participants presence - ', () => { isBreakout: boolean; }; eventType: string; - } = await context.webhooksProxy.waitForEvent('ROOM_DESTROYED'); + } = await webhooksProxy.waitForEvent('ROOM_DESTROYED'); expect('ROOM_DESTROYED').toBe(event.eventType); - expect(event.data.conference).toBe(context.conferenceJid); + expect(event.data.conference).toBe(conferenceJid); expect(event.data.isBreakout).toBe(false); } diff --git a/tests/specs/3way/activeSpeaker.spec.ts b/tests/specs/3way/activeSpeaker.spec.ts index 180531b276..a4637d9129 100644 --- a/tests/specs/3way/activeSpeaker.spec.ts +++ b/tests/specs/3way/activeSpeaker.spec.ts @@ -4,30 +4,32 @@ import { ensureThreeParticipants, muteAudioAndCheck } from '../../helpers/partic describe('ActiveSpeaker ', () => { it('testActiveSpeaker', async () => { - await ensureThreeParticipants(context); + await ensureThreeParticipants(ctx); - await muteAudioAndCheck(context.p1, context.p2); - await muteAudioAndCheck(context.p2, context.p1); - await muteAudioAndCheck(context.p3, context.p1); + const { p1, p2, p3 } = ctx; + + await muteAudioAndCheck(p1, p2); + await muteAudioAndCheck(p2, p1); + await muteAudioAndCheck(p3, p1); // participant1 becomes active speaker - check from participant2's perspective - await testActiveSpeaker(context.p1, context.p2, context.p3); + await testActiveSpeaker(p1, p2, p3); // participant3 becomes active speaker - check from participant2's perspective - await testActiveSpeaker(context.p3, context.p2, context.p1); + await testActiveSpeaker(p3, p2, p1); // participant2 becomes active speaker - check from participant1's perspective - await testActiveSpeaker(context.p2, context.p1, context.p3); + await testActiveSpeaker(p2, p1, p3); // check the displayed speakers, there should be only one speaker - await assertOneDominantSpeaker(context.p1); - await assertOneDominantSpeaker(context.p2); - await assertOneDominantSpeaker(context.p3); + await assertOneDominantSpeaker(p1); + await assertOneDominantSpeaker(p2); + await assertOneDominantSpeaker(p3); }); }); /** - * Tries to make given participant an active speaker by un-muting it. + * Tries to make given participant an active speaker by unmuting it. * Verifies from {@code participant2}'s perspective that the active speaker * has been displayed on the large video area. Mutes him back. * @@ -36,7 +38,6 @@ describe('ActiveSpeaker ', () => { * @param {Participant} otherParticipant1 - Participant of the participant who will be observing and verifying * active speaker change. * @param {Participant} otherParticipant2 - Used only to print some debugging info. - * @returns {Promise} */ async function testActiveSpeaker( activeSpeaker: Participant, otherParticipant1: Participant, otherParticipant2: Participant) { @@ -85,7 +86,6 @@ async function testActiveSpeaker( * indicator displayed equals 1. * * @param {Participant} participant - The participant to check. - * @returns {Promise} */ async function assertOneDominantSpeaker(participant: Participant) { expect(await participant.driver.$$( diff --git a/tests/specs/3way/audioVideoModeration.spec.ts b/tests/specs/3way/audioVideoModeration.spec.ts new file mode 100644 index 0000000000..b5faaca273 --- /dev/null +++ b/tests/specs/3way/audioVideoModeration.spec.ts @@ -0,0 +1,284 @@ +import { Participant } from '../../helpers/Participant'; +import { + ensureOneParticipant, + ensureThreeParticipants, ensureTwoParticipants, + unmuteAudioAndCheck, + unmuteVideoAndCheck +} from '../../helpers/participants'; + +describe('AVModeration -', () => { + + it('check for moderators', async () => { + // if all 3 participants are moderators, skip this test + await ensureThreeParticipants(ctx); + + const { p1, p2, p3 } = ctx; + + if (!await p1.isModerator() + || (await p1.isModerator() && await p2.isModerator() && await p3.isModerator())) { + ctx.skipSuiteTests = true; + } + }); + + it('check audio enable/disable', async () => { + const { p1, p3 } = ctx; + const p1ParticipantsPane = p1.getParticipantsPane(); + + await p1ParticipantsPane.clickContextMenuButton(); + await p1ParticipantsPane.getAVModerationMenu().clickStartAudioModeration(); + + await p1ParticipantsPane.close(); + + // Here we want to try unmuting and check that we are still muted. + await tryToAudioUnmuteAndCheck(p3, p1); + + await p1ParticipantsPane.clickContextMenuButton(); + await p1ParticipantsPane.getAVModerationMenu().clickStopAudioModeration(); + + await p1ParticipantsPane.close(); + + await unmuteAudioAndCheck(p3, p1); + }); + + it('check video enable/disable', async () => { + const { p1, p3 } = ctx; + const p1ParticipantsPane = p1.getParticipantsPane(); + + await p1ParticipantsPane.clickContextMenuButton(); + await p1ParticipantsPane.getAVModerationMenu().clickStartVideoModeration(); + + await p1ParticipantsPane.close(); + + // Here we want to try unmuting and check that we are still muted. + await tryToVideoUnmuteAndCheck(p3, p1); + + await p1ParticipantsPane.clickContextMenuButton(); + await p1ParticipantsPane.getAVModerationMenu().clickStopVideoModeration(); + + await p1ParticipantsPane.close(); + + await unmuteVideoAndCheck(p3, p1); + }); + + it('unmute by moderator', async () => { + const { p1, p2, p3 } = ctx; + + await unmuteByModerator(p1, p3, true, true); + + // moderation is stopped at this point, make sure participants 1 & 2 are also unmuted, + // participant3 was unmuted by unmuteByModerator + await unmuteAudioAndCheck(p2, p1); + await unmuteVideoAndCheck(p2, p1); + await unmuteAudioAndCheck(p1, p2); + await unmuteVideoAndCheck(p1, p2); + }); + + it('hangup and change moderator', async () => { + await Promise.all([ ctx.p2.hangup(), ctx.p3.hangup() ]); + + await ensureThreeParticipants(ctx); + const { p1, p2, p3 } = ctx; + + await p2.getToolbar().clickAudioMuteButton(); + await p3.getToolbar().clickAudioMuteButton(); + + const p1ParticipantsPane = p1.getParticipantsPane(); + + await p1ParticipantsPane.clickContextMenuButton(); + await p1ParticipantsPane.getAVModerationMenu().clickStartAudioModeration(); + await p1ParticipantsPane.getAVModerationMenu().clickStartVideoModeration(); + + await p2.getToolbar().clickRaiseHandButton(); + await p3.getToolbar().clickRaiseHandButton(); + + await p1.hangup(); + + // we don't use ensureThreeParticipants to avoid all meeting join checks + // all participants are muted and checks for media will fail + await ensureOneParticipant(ctx); + + // After p1 re-joins either p2 or p3 is promoted to moderator. They should still be muted. + const isP2Moderator = await p2.isModerator(); + const moderator = isP2Moderator ? p2 : p3; + const nonModerator = isP2Moderator ? p3 : p2; + const moderatorParticipantsPane = moderator.getParticipantsPane(); + const nonModeratorParticipantsPane = nonModerator.getParticipantsPane(); + + await moderatorParticipantsPane.assertVideoMuteIconIsDisplayed(moderator); + await nonModeratorParticipantsPane.assertVideoMuteIconIsDisplayed(nonModerator); + + await moderatorParticipantsPane.allowVideo(nonModerator); + await moderatorParticipantsPane.askToUnmute(nonModerator, false); + + await nonModerator.getNotifications().waitForAskToUnmuteNotification(); + + await unmuteAudioAndCheck(nonModerator, p1); + await unmuteVideoAndCheck(nonModerator, p1); + + await moderatorParticipantsPane.clickContextMenuButton(); + await moderatorParticipantsPane.getAVModerationMenu().clickStopAudioModeration(); + await moderatorParticipantsPane.getAVModerationMenu().clickStopVideoModeration(); + }); + it('grant moderator', async () => { + await Promise.all([ ctx.p1.hangup(), ctx.p2.hangup(), ctx.p3.hangup() ]); + + await ensureThreeParticipants(ctx); + + const { p1, p2, p3 } = ctx; + + const p1ParticipantsPane = p1.getParticipantsPane(); + + await p1ParticipantsPane.clickContextMenuButton(); + await p1ParticipantsPane.getAVModerationMenu().clickStartAudioModeration(); + await p1ParticipantsPane.getAVModerationMenu().clickStartVideoModeration(); + + await p1.getFilmstrip().grantModerator(p3); + + await p3.driver.waitUntil( + async () => await p3.isModerator(), { + timeout: 5000, + timeoutMsg: `${p3.name} is not moderator` + }); + + await unmuteByModerator(p3, p2, false, true); + }); + it('ask to unmute', async () => { + await Promise.all([ ctx.p1.hangup(), ctx.p2.hangup(), ctx.p3.hangup() ]); + + await ensureTwoParticipants(ctx); + + const { p1, p2 } = ctx; + + // mute p2 + await p2.getToolbar().clickAudioMuteButton(); + + // ask p2 to unmute + await p1.getParticipantsPane().askToUnmute(p2, true); + + await p2.getNotifications().waitForAskToUnmuteNotification(); + + await p1.getParticipantsPane().close(); + }); + it('remove from whitelist', async () => { + const { p1, p2 } = ctx; + + await unmuteByModerator(p1, p2, true, false); + + // p1 mute audio on p2 and check + await p1.getFilmstrip().muteAudio(p2); + await p1.getFilmstrip().assertAudioMuteIconIsDisplayed(p1); + await p2.getFilmstrip().assertAudioMuteIconIsDisplayed(p1); + + // we try to unmute and test it that it was still muted + await tryToAudioUnmuteAndCheck(p2, p1); + + // stop video and check + await p1.getFilmstrip().muteVideo(p2); + + await p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(p2); + await p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(p2); + + await tryToVideoUnmuteAndCheck(p2, p1); + }); + it('join moderated', async () => { + await Promise.all([ ctx.p1.hangup(), ctx.p2.hangup(), ctx.p3.hangup() ]); + + await ensureOneParticipant(ctx); + + const p1ParticipantsPane = ctx.p1.getParticipantsPane(); + + await p1ParticipantsPane.clickContextMenuButton(); + await p1ParticipantsPane.getAVModerationMenu().clickStartAudioModeration(); + await p1ParticipantsPane.getAVModerationMenu().clickStartVideoModeration(); + + // join with second participant and check + await ensureTwoParticipants(ctx, { + skipInMeetingChecks: true + }); + const { p1, p2 } = ctx; + + await tryToAudioUnmuteAndCheck(p2, p1); + await tryToVideoUnmuteAndCheck(p2, p1); + + // asked to unmute and check + await unmuteByModerator(p1, p2, false, false); + + // mute and check + await p1.getFilmstrip().muteAudio(p2); + + await tryToAudioUnmuteAndCheck(p2, p1); + }); +}); + +/** + * Checks a user can unmute after being asked by moderator. + * @param moderator - The participant that is moderator. + * @param participant - The participant being asked to unmute. + * @param turnOnModeration - if we want to turn on moderation before testing (when it is currently off). + * @param stopModeration - true if moderation to be stopped when done. + */ +async function unmuteByModerator( + moderator: Participant, + participant: Participant, + turnOnModeration: boolean, + stopModeration: boolean) { + const moderatorParticipantsPane = moderator.getParticipantsPane(); + + if (turnOnModeration) { + await moderatorParticipantsPane.clickContextMenuButton(); + await moderatorParticipantsPane.getAVModerationMenu().clickStartAudioModeration(); + await moderatorParticipantsPane.getAVModerationMenu().clickStartVideoModeration(); + + await moderatorParticipantsPane.close(); + } + + // raise hand to speak + await participant.getToolbar().clickRaiseHandButton(); + await moderator.getNotifications().waitForRaisedHandNotification(); + + // ask participant to unmute + await moderatorParticipantsPane.allowVideo(participant); + await moderatorParticipantsPane.askToUnmute(participant, false); + await participant.getNotifications().waitForAskToUnmuteNotification(); + + await unmuteAudioAndCheck(participant, moderator); + await unmuteVideoAndCheck(participant, moderator); + + if (stopModeration) { + await moderatorParticipantsPane.clickContextMenuButton(); + await moderatorParticipantsPane.getAVModerationMenu().clickStopAudioModeration(); + await moderatorParticipantsPane.getAVModerationMenu().clickStopVideoModeration(); + + await moderatorParticipantsPane.close(); + } +} + +/** + * In case of moderation, tries to audio unmute but stays muted. + * Checks locally and remotely that this is still the case. + * @param participant + * @param observer + */ +async function tryToAudioUnmuteAndCheck(participant: Participant, observer: Participant) { + // try to audio unmute and check + await participant.getToolbar().clickAudioUnmuteButton(); + + // Check local audio muted icon state + await participant.getFilmstrip().assertAudioMuteIconIsDisplayed(participant); + await observer.getFilmstrip().assertAudioMuteIconIsDisplayed(participant); +} + +/** + * In case of moderation, tries to video unmute but stays muted. + * Checks locally and remotely that this is still the case. + * @param participant + * @param observer + */ +async function tryToVideoUnmuteAndCheck(participant: Participant, observer: Participant) { + // try to video unmute and check + await participant.getToolbar().clickVideoUnmuteButton(); + + // Check local audio muted icon state + await participant.getParticipantsPane().assertVideoMuteIconIsDisplayed(participant); + await observer.getParticipantsPane().assertVideoMuteIconIsDisplayed(participant); +} diff --git a/tests/specs/3way/avatarTest.spec.ts b/tests/specs/3way/avatarTest.spec.ts deleted file mode 100644 index 47607449fa..0000000000 --- a/tests/specs/3way/avatarTest.spec.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { - ensureThreeParticipants, - ensureTwoParticipants, - unMuteVideoAndCheck -} from '../../helpers/participants'; - -const EMAIL = 'support@jitsi.org'; -const HASH = '38f014e4b7dde0f64f8157d26a8c812e'; - -describe('Avatar - ', () => { - it('setup the meeting', async () => { - // Start p1 - await ensureTwoParticipants(context, { - skipDisplayName: true - }); - }); - - it('change and check', async () => { - // check default avatar for p1 on p2 - await context.p2.assertDefaultAvatarExist(context.p1); - - await context.p1.getToolbar().clickProfileButton(); - - const settings = context.p1.getSettingsDialog(); - - await settings.waitForDisplay(); - await settings.setEmail(EMAIL); - await settings.submit(); - - // check if the local avatar in the toolbar menu has changed - await context.p1.driver.waitUntil( - async () => (await context.p1.getToolbar().getProfileImage())?.includes(HASH), { - timeout: 3000, // give more time for the initial download of the image - timeoutMsg: 'Avatar has not changed for p1' - }); - - // check if the avatar in the local thumbnail has changed - expect(await context.p1.getLocalVideoAvatar()).toContain(HASH); - - const p1EndpointId = await context.p1.getEndpointId(); - - await context.p2.driver.waitUntil( - async () => (await context.p2.getFilmstrip().getAvatar(p1EndpointId))?.includes(HASH), { - timeout: 5000, - timeoutMsg: 'Avatar has not changed for p1 on p2' - }); - - // check if the avatar in the large video has changed - expect(await context.p2.getLargeVideoAvatar()).toContain(HASH); - - // we check whether the default avatar of participant2 is displayed on both sides - await context.p1.assertDefaultAvatarExist(context.p2); - await context.p2.assertDefaultAvatarExist(context.p2); - - // the problem on FF where we can send keys to the input field, - // and the m from the text can mute the call, check whether we are muted - await context.p2.getFilmstrip().assertAudioMuteIconIsDisplayed(context.p1, true); - }); - - it('when video muted', async () => { - await context.p2.hangup(); - - // Mute p1's video - await context.p1.getToolbar().clickVideoMuteButton(); - - await context.p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(context.p1); - - await context.p1.driver.waitUntil( - async () => (await context.p1.getLargeVideoAvatar())?.includes(HASH), { - timeout: 2000, - timeoutMsg: 'Avatar on large video did not change' - }); - - const p1LargeSrc = await context.p1.getLargeVideoAvatar(); - const p1ThumbSrc = await context.p1.getLocalVideoAvatar(); - - // Check if avatar on large video is the same as on local thumbnail - expect(p1ThumbSrc).toBe(p1LargeSrc); - - // Join p2 - await ensureTwoParticipants(context, { - skipDisplayName: true - }); - - // Verify that p1 is muted from the perspective of p2 - await context.p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(context.p1); - - await context.p2.getFilmstrip().pinParticipant(context.p1); - - // Check if p1's avatar is on large video now - await context.p2.driver.waitUntil( - async () => await context.p2.getLargeVideoAvatar() === p1LargeSrc, { - timeout: 2000, - timeoutMsg: 'Avatar on large video did not change' - }); - - // p1 pins p2's video - await context.p1.getFilmstrip().pinParticipant(context.p2); - - // Check if avatar is displayed on p1's local video thumbnail - await context.p1.assertThumbnailShowsAvatar(context.p1, false, false, true); - - // Unmute - now local avatar should be hidden and local video displayed - await unMuteVideoAndCheck(context.p1, context.p2); - - await context.p1.asserLocalThumbnailShowsVideo(); - - // Now both p1 and p2 have video muted - await context.p1.getToolbar().clickVideoMuteButton(); - await context.p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(context.p1); - await context.p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(context.p1); - - await context.p2.getToolbar().clickVideoMuteButton(); - await context.p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(context.p2); - await context.p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(context.p2); - - // Start the third participant - await ensureThreeParticipants(context); - - // Pin local video and verify avatars are displayed - await context.p3.getFilmstrip().pinParticipant(context.p3); - - await context.p3.assertThumbnailShowsAvatar(context.p1, false, false, true); - await context.p3.assertThumbnailShowsAvatar(context.p2, false, true); - - const p1EndpointId = await context.p1.getEndpointId(); - const p2EndpointId = await context.p2.getEndpointId(); - - expect(await context.p3.getFilmstrip().getAvatar(p1EndpointId)).toBe(p1ThumbSrc); - - // Click on p1's video - await context.p3.getFilmstrip().pinParticipant(context.p1); - - // The avatar should be on large video and display name instead of an avatar, local video displayed - await context.p3.driver.waitUntil( - async () => await context.p3.getLargeVideoResource() === p1EndpointId, { - timeout: 2000, - timeoutMsg: `Large video did not switch to ${context.p1.name}` - }); - - await context.p3.assertDisplayNameVisibleOnStage( - await context.p3.getFilmstrip().getRemoteDisplayName(p1EndpointId)); - - // p2 has the default avatar - await context.p3.assertThumbnailShowsAvatar(context.p2, false, true); - await context.p3.assertThumbnailShowsAvatar(context.p3, true); - - // Click on p2's video - await context.p3.getFilmstrip().pinParticipant(context.p2); - - // The avatar should be on large video and display name instead of an avatar, local video displayed - await context.p3.driver.waitUntil( - async () => await context.p3.getLargeVideoResource() === p2EndpointId, { - timeout: 2000, - timeoutMsg: `Large video did not switch to ${context.p2.name}` - }); - - await context.p3.assertDisplayNameVisibleOnStage( - await context.p3.getFilmstrip().getRemoteDisplayName(p2EndpointId) - ); - - await context.p3.assertThumbnailShowsAvatar(context.p1, false, false, true); - await context.p3.assertThumbnailShowsAvatar(context.p3, true); - - await context.p3.hangup(); - - // Unmute p1's and p2's videos - await context.p1.getToolbar().clickVideoUnmuteButton(); - - await context.p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(context.p1, true); - await context.p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(context.p1, true); - }); - - it('email persistence', async () => { - await context.p1.getToolbar().clickProfileButton(); - - expect(await context.p1.getSettingsDialog().getEmail()).toBe(EMAIL); - - await context.p1.hangup(); - - await ensureTwoParticipants(context, { - skipDisplayName: true - }); - - await context.p1.getToolbar().clickProfileButton(); - - expect(await context.p1.getSettingsDialog().getEmail()).toBe(EMAIL); - }); -}); diff --git a/tests/specs/3way/avatars.spec.ts b/tests/specs/3way/avatars.spec.ts new file mode 100644 index 0000000000..9366f0a1f9 --- /dev/null +++ b/tests/specs/3way/avatars.spec.ts @@ -0,0 +1,202 @@ +import { + ensureThreeParticipants, + ensureTwoParticipants, + unmuteVideoAndCheck +} from '../../helpers/participants'; + +const EMAIL = 'support@jitsi.org'; +const HASH = '38f014e4b7dde0f64f8157d26a8c812e'; + +describe('Avatar - ', () => { + it('setup the meeting', async () => { + // Start p1 + await ensureTwoParticipants(ctx, { + skipDisplayName: true, + + // no default avatar if we have used to join a token with an avatar and no option to set it + skipFirstModerator: true + }); + }); + + it('change and check', async () => { + const { p1, p2 } = ctx; + + // check default avatar for p1 on p2 + await p2.assertDefaultAvatarExist(p1); + + await p1.getToolbar().clickProfileButton(); + + const settings = p1.getSettingsDialog(); + + await settings.waitForDisplay(); + await settings.setEmail(EMAIL); + await settings.submit(); + + // check if the local avatar in the toolbar menu has changed + await p1.driver.waitUntil( + async () => (await p1.getToolbar().getProfileImage())?.includes(HASH), { + timeout: 3000, // give more time for the initial download of the image + timeoutMsg: 'Avatar has not changed for p1' + }); + + // check if the avatar in the local thumbnail has changed + expect(await p1.getLocalVideoAvatar()).toContain(HASH); + + const p1EndpointId = await p1.getEndpointId(); + + await p2.driver.waitUntil( + async () => (await p2.getFilmstrip().getAvatar(p1EndpointId))?.includes(HASH), { + timeout: 5000, + timeoutMsg: 'Avatar has not changed for p1 on p2' + }); + + // check if the avatar in the large video has changed + expect(await p2.getLargeVideoAvatar()).toContain(HASH); + + // we check whether the default avatar of participant2 is displayed on both sides + await p1.assertDefaultAvatarExist(p2); + await p2.assertDefaultAvatarExist(p2); + + // the problem on FF where we can send keys to the input field, + // and the m from the text can mute the call, check whether we are muted + await p2.getFilmstrip().assertAudioMuteIconIsDisplayed(p1, true); + }); + + it('when video muted', async () => { + const { p1 } = ctx; + + await ctx.p2.hangup(); + + // Mute p1's video + await p1.getToolbar().clickVideoMuteButton(); + + await p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1); + + await p1.driver.waitUntil( + async () => (await p1.getLargeVideoAvatar())?.includes(HASH), { + timeout: 2000, + timeoutMsg: 'Avatar on large video did not change' + }); + + const p1LargeSrc = await p1.getLargeVideoAvatar(); + const p1ThumbSrc = await p1.getLocalVideoAvatar(); + + // Check if avatar on large video is the same as on local thumbnail + expect(p1ThumbSrc).toBe(p1LargeSrc); + + // Join p2 + await ensureTwoParticipants(ctx, { + skipDisplayName: true + }); + const { p2 } = ctx; + + // Verify that p1 is muted from the perspective of p2 + await p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1); + + await p2.getFilmstrip().pinParticipant(p1); + + // Check if p1's avatar is on large video now + await p2.driver.waitUntil( + async () => await p2.getLargeVideoAvatar() === p1LargeSrc, { + timeout: 2000, + timeoutMsg: 'Avatar on large video did not change' + }); + + // p1 pins p2's video + await p1.getFilmstrip().pinParticipant(p2); + + // Check if avatar is displayed on p1's local video thumbnail + await p1.assertThumbnailShowsAvatar(p1, false, false, true); + + // Unmute - now local avatar should be hidden and local video displayed + await unmuteVideoAndCheck(p1, p2); + + await p1.asserLocalThumbnailShowsVideo(); + + // Now both p1 and p2 have video muted + await p1.getToolbar().clickVideoMuteButton(); + await p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1); + await p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1); + + await p2.getToolbar().clickVideoMuteButton(); + await p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(p2); + await p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(p2); + + // Start the third participant + await ensureThreeParticipants(ctx); + const { p3 } = ctx; + + // Pin local video and verify avatars are displayed + await p3.getFilmstrip().pinParticipant(p3); + + await p3.assertThumbnailShowsAvatar(p1, false, false, true); + await p3.assertThumbnailShowsAvatar(p2, false, true); + + const p1EndpointId = await p1.getEndpointId(); + const p2EndpointId = await p2.getEndpointId(); + + expect(await p3.getFilmstrip().getAvatar(p1EndpointId)).toBe(p1ThumbSrc); + + // Click on p1's video + await p3.getFilmstrip().pinParticipant(p1); + + // The avatar should be on large video and display name instead of an avatar, local video displayed + await p3.driver.waitUntil( + async () => await p3.getLargeVideoResource() === p1EndpointId, { + timeout: 2000, + timeoutMsg: `Large video did not switch to ${p1.name}` + }); + + await p3.assertDisplayNameVisibleOnStage( + await p3.getFilmstrip().getRemoteDisplayName(p1EndpointId)); + + // p2 has the default avatar + await p3.assertThumbnailShowsAvatar(p2, false, true); + await p3.assertThumbnailShowsAvatar(p3, true); + + // Click on p2's video + await p3.getFilmstrip().pinParticipant(p2); + + // The avatar should be on large video and display name instead of an avatar, local video displayed + await p3.driver.waitUntil( + async () => await p3.getLargeVideoResource() === p2EndpointId, { + timeout: 2000, + timeoutMsg: `Large video did not switch to ${p2.name}` + }); + + await p3.assertDisplayNameVisibleOnStage( + await p3.getFilmstrip().getRemoteDisplayName(p2EndpointId) + ); + + await p3.assertThumbnailShowsAvatar(p1, false, false, true); + await p3.assertThumbnailShowsAvatar(p3, true); + + await p3.hangup(); + + // Unmute p1's and p2's videos + await p1.getToolbar().clickVideoUnmuteButton(); + + await p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1, true); + await p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1, true); + }); + + it('email persistence', async () => { + let { p1 } = ctx; + + await p1.getToolbar().clickProfileButton(); + + expect(await p1.getSettingsDialog().getEmail()).toBe(EMAIL); + + await p1.hangup(); + + await ensureTwoParticipants(ctx, { + skipDisplayName: true, + skipFirstModerator: true + }); + p1 = ctx.p1; + + await p1.getToolbar().clickProfileButton(); + + expect(await p1.getSettingsDialog().getEmail()).toBe(EMAIL); + }); +}); diff --git a/tests/tsconfig.json b/tests/tsconfig.json index 2749ca81da..e071e08620 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -9,8 +9,8 @@ "types": [ "node", "@wdio/globals/types", - "@types/jasmine", - "@wdio/jasmine-framework" + "@types/mocha", + "@wdio/mocha-framework" ] } } diff --git a/tests/wdio.conf.ts b/tests/wdio.conf.ts index 8a02fb71c0..84f6772d46 100644 --- a/tests/wdio.conf.ts +++ b/tests/wdio.conf.ts @@ -5,6 +5,7 @@ import path from 'node:path'; import process from 'node:process'; import pretty from 'pretty'; +import WebhookProxy from './helpers/WebhookProxy'; import { getLogs, initLogger, logInfo } from './helpers/browserLogger'; import { IContext } from './helpers/types'; @@ -27,6 +28,10 @@ const chromeArgs = [ '--no-sandbox', '--disable-dev-shm-usage', '--disable-setuid-sandbox', + + // Avoids - "You are checking for animations on an inactive tab, animations do not run for inactive tabs" + // when executing waitForStable() + '--disable-renderer-backgrounding', `--use-file-for-fake-audio-capture=${process.env.REMOTE_RESOURCE_PATH || 'tests/resources'}/fakeAudioStream.wav` ]; @@ -72,10 +77,10 @@ export const config: WebdriverIO.MultiremoteConfig = { // Default request retries count connectionRetryCount: 3, - framework: 'jasmine', + framework: 'mocha', - jasmineOpts: { - defaultTimeoutInterval: 60_000 + mochaOpts: { + timeout: 60_000 }, capabilities: { @@ -183,16 +188,19 @@ export const config: WebdriverIO.MultiremoteConfig = { })); const globalAny: any = global; + const roomName = `jitsimeettorture-${crypto.randomUUID()}`; - globalAny.context = {} as IContext; - - globalAny.context.jwtPrivateKeyPath = process.env.JWT_PRIVATE_KEY_PATH; - globalAny.context.jwtKid = process.env.JWT_KID; + globalAny.ctx = {} as IContext; + globalAny.ctx.roomName = roomName; + globalAny.ctx.jwtPrivateKeyPath = process.env.JWT_PRIVATE_KEY_PATH; + globalAny.ctx.jwtKid = process.env.JWT_KID; }, after() { - if (context.webhooksProxy) { - context.webhooksProxy.disconnect(); + const { ctx }: any = global; + + if (ctx.webhooksProxy) { + ctx.webhooksProxy.disconnect(); } }, @@ -200,9 +208,24 @@ export const config: WebdriverIO.MultiremoteConfig = { * Gets executed before the suite starts (in Mocha/Jasmine only). * * @param {Object} suite - Suite details. - * @returns {Promise} */ beforeSuite(suite) { + const { ctx }: any = global; + + // If we are running the iFrameApi tests, we need to mark it as such and if needed to create the proxy + // and connect to it. + if (path.basename(suite.file).startsWith('iFrameApi')) { + ctx.iframeAPI = true; + + if (!ctx.webhooksProxy + && process.env.WEBHOOKS_PROXY_URL && process.env.WEBHOOKS_PROXY_SHARED_SECRET) { + ctx.webhooksProxy = new WebhookProxy( + `${process.env.WEBHOOKS_PROXY_URL}&room=${ctx.roomName}`, + process.env.WEBHOOKS_PROXY_SHARED_SECRET); + ctx.webhooksProxy.connect(); + } + } + multiremotebrowser.instances.forEach((instance: string) => { logInfo(multiremotebrowser.getInstance(instance), `---=== Begin ${suite.file.substring(suite.file.lastIndexOf('/') + 1)} ===---`); @@ -213,11 +236,13 @@ export const config: WebdriverIO.MultiremoteConfig = { * Function to be executed before a test (in Mocha/Jasmine only). * * @param {Object} test - Test object. - * @returns {Promise} + * @param {Object} context - The context object. */ - beforeTest(test) { + beforeTest(test, context) { + ctx.skipSuiteTests && context.skip(); + multiremotebrowser.instances.forEach((instance: string) => { - logInfo(multiremotebrowser.getInstance(instance), `---=== Start test ${test.fullName} ===---`); + logInfo(multiremotebrowser.getInstance(instance), `---=== Start test ${test.title} ===---`); }); }, @@ -231,7 +256,7 @@ export const config: WebdriverIO.MultiremoteConfig = { */ async afterTest(test, context, { error }) { multiremotebrowser.instances.forEach((instance: string) => - logInfo(multiremotebrowser.getInstance(instance), `---=== End test ${test.fullName} ===---`)); + logInfo(multiremotebrowser.getInstance(instance), `---=== End test ${test.title} ===---`)); if (error) { const allProcessing: Promise[] = [];