From 8101a16a6abafcb7be16659af6e37021b251679c Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Thu, 20 Nov 2025 20:51:37 +0000 Subject: [PATCH 01/32] fix: Fix failing NPM build. --- package-lock.json | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index dcdb8356..2708e624 100644 --- a/package-lock.json +++ b/package-lock.json @@ -947,6 +947,7 @@ "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -1265,6 +1266,7 @@ "url": "https://opencollective.com/csstools" } ], + "peer": true, "engines": { "node": ">=18" }, @@ -1287,6 +1289,7 @@ "url": "https://opencollective.com/csstools" } ], + "peer": true, "engines": { "node": ">=18" } @@ -2084,6 +2087,7 @@ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -2766,6 +2770,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2799,6 +2804,7 @@ "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -3284,6 +3290,7 @@ "integrity": "sha512-BbWUcpqroY241XgSxTuAiEMHeIZ6u3+oD2zOATf3Fi+0NMWJ/MdMtuSkOcDCSk6Nc7WR3z5n9GHKqz2L+3kQOQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "jsdom": "26.1.0" }, @@ -3414,6 +3421,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001669", "electron-to-chromium": "^1.5.41", @@ -4852,6 +4860,7 @@ "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -5665,6 +5674,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5773,6 +5783,21 @@ "dev": true, "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -6870,6 +6895,7 @@ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", "dev": true, + "peer": true, "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", @@ -9386,6 +9412,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -9799,6 +9826,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -10098,6 +10126,7 @@ "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10439,6 +10468,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", "dev": true, + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", @@ -10486,6 +10516,7 @@ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", @@ -10678,7 +10709,8 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD" + "license": "0BSD", + "peer": true }, "node_modules/webpack-dev-server": { "version": "5.2.1", @@ -10769,6 +10801,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", From b85a4b1d720835bfe2a62a5e64f08ba24425e9b5 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Thu, 20 Nov 2025 21:37:53 +0000 Subject: [PATCH 02/32] chore: Disable workflows for investigation. --- .github/workflows/build.yml | 6 ++++-- .github/workflows/test.yml | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 41f96b40..950d857a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,6 +15,7 @@ jobs: build_tip_of_tree_v12: name: Build test (against tip-of-tree core develop) runs-on: ubuntu-latest + if: false steps: - name: Checkout experimentation plugin uses: actions/checkout@v4 @@ -59,8 +60,7 @@ jobs: build: name: Build test (against pinned v12) - # Don't run pinned version checks for PRs. - if: ${{ !github.base_ref }} + if: false runs-on: ubuntu-latest steps: - name: Checkout experimentation plugin @@ -81,6 +81,7 @@ jobs: name: Eslint check timeout-minutes: 5 runs-on: ubuntu-latest + if: false steps: - uses: actions/checkout@v4 @@ -99,6 +100,7 @@ jobs: name: Prettier check timeout-minutes: 5 runs-on: ubuntu-latest + if: false steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 711d2f61..92a47d9c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [macos-latest] steps: - name: Checkout experimentation plugin @@ -67,8 +67,7 @@ jobs: webdriverio_tests: name: WebdriverIO tests (against pinned v12) - # Don't run pinned version checks for PRs. - if: ${{ !github.base_ref }} + if: false timeout-minutes: 10 runs-on: ${{ matrix.os }} From 8859f98f544bb49bda5f7347c0786fa5429d483c Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Thu, 20 Nov 2025 22:12:07 +0000 Subject: [PATCH 03/32] chore: Debug & disable test for investigation. --- test/webdriverio/test/scroll_test.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index c340714b..d7997056 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -44,7 +44,7 @@ suite('Scrolling into view', function () { await testSetup(testFileLocations.BASE, this.timeout()); }); - test('Insert scrolls new block into view', async function () { + test.only('Insert scrolls new block into view', async function () { // Increase timeout to 10s for this longer test. this.timeout(PAUSE_TIME ? 0 : 10000); @@ -72,6 +72,27 @@ suite('Scrolling into view', function () { // Assert new block has been scrolled into the viewport. await this.browser.pause(PAUSE_TIME); + const blockBounds = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + const block = workspace.getBlocksByType( + 'controls_if', + )[0] as Blockly.BlockSvg; + const blockBounds = block.getBoundingRectangleWithoutChildren(); + return blockBounds; + }); + console.log("block bounds:", blockBounds); + const viewport = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + const rawViewport = workspace.getMetricsManager().getViewMetrics(true); + const viewport = new Blockly.utils.Rect( + rawViewport.top, + rawViewport.top + rawViewport.height, + rawViewport.left, + rawViewport.left + rawViewport.width, + ); + return viewport; + }); + console.log("viewport:", viewport); const inViewport = await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; const block = workspace.getBlocksByType( From ae9ee306b260cb2e5f54a49831aa97d7099f2d9b Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Thu, 20 Nov 2025 23:26:17 +0000 Subject: [PATCH 04/32] chore: More investigation work. Attempt to use BiDi and upgrade WIO so that viewport manipulation can be used instead of window management for better compatibility. --- package-lock.json | 551 +++++++++++------- package.json | 2 +- test/webdriverio/test/scroll_test.ts | 12 +- test/webdriverio/test/test_setup.ts | 6 +- .../test/workspace_comment_test.ts | 4 +- 5 files changed, 352 insertions(+), 223 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2708e624..4c229f47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "prettier": "^3.3.1", "ts-loader": "^9.5.1", "typescript": "^5.4.5", - "webdriverio": "^9.12.1" + "webdriverio": "^9.13.0" }, "peerDependencies": { "blockly": "^12.3.0" @@ -1685,22 +1685,24 @@ "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.8.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.8.0.tgz", - "integrity": "sha512-yTwt2KWRmCQAfhvbCRjebaSX8pV1//I0Y3g+A7f/eS7gf0l4eRJoUCvcYdVtboeU4CTOZQuqYbZNS8aBYb8ROQ==", + "version": "2.10.13", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.13.tgz", + "integrity": "sha512-a9Ruw3j3qlnB5a/zHRTkruppynxqaeE4H9WNj5eYGRWqw0ZauZ23f4W2ARf3hghF5doozyD+CRtt7XSYuYRI/Q==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "debug": "^4.4.0", + "debug": "^4.4.3", "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.5.0", - "semver": "^7.7.1", - "tar-fs": "^3.0.8", + "semver": "^7.7.3", + "tar-fs": "^3.1.1", "yargs": "^17.7.2" }, "bin": { @@ -1753,7 +1755,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/@types/body-parser": { "version": "1.19.5", @@ -2023,7 +2026,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/ws": { "version": "8.5.10", @@ -2040,6 +2044,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": "*" @@ -2278,14 +2283,15 @@ "license": "ISC" }, "node_modules/@wdio/config": { - "version": "9.12.1", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.12.1.tgz", - "integrity": "sha512-eYyF9HBQg2PyX6ScieZ5akDG4BaJmNBdYFJmwhUAGcJlxLgoI02vSqIuoWaQd5shbvtCdDzsFI0Jt8+S/xqINQ==", + "version": "9.20.1", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.20.1.tgz", + "integrity": "sha512-npl2J+rjCDJPjVySgWpciOyhWddn6s7n5sepKXLR7x1ADQHl5zUFv1dHD3jx4OQ9l6lrGQSPaofuz+7e9mu+vg==", "dev": true, + "license": "MIT", "dependencies": { - "@wdio/logger": "9.4.4", - "@wdio/types": "9.10.1", - "@wdio/utils": "9.12.1", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.20.0", + "@wdio/utils": "9.20.1", "deepmerge-ts": "^7.0.3", "glob": "^10.2.2", "import-meta-resolve": "^4.0.0" @@ -2295,19 +2301,21 @@ } }, "node_modules/@wdio/config/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==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "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==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -2328,6 +2336,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" }, @@ -2339,14 +2348,16 @@ } }, "node_modules/@wdio/logger": { - "version": "9.4.4", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-9.4.4.tgz", - "integrity": "sha512-BXx8RXFUW2M4dcO6t5Le95Hi2ZkTQBRsvBQqLekT2rZ6Xmw8ZKZBPf0FptnoftFGg6dYmwnDidYv/0+4PiHjpQ==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-9.18.0.tgz", + "integrity": "sha512-HdzDrRs+ywAqbXGKqe1i/bLtCv47plz4TvsHFH3j729OooT5VH38ctFn5aLXgECmiAKDkmH/A6kOq2Zh5DIxww==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^5.1.2", "loglevel": "^1.6.0", "loglevel-plugin-prefix": "^0.8.4", + "safe-regex2": "^5.0.0", "strip-ansi": "^7.1.0" }, "engines": { @@ -2354,10 +2365,11 @@ } }, "node_modules/@wdio/logger/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2366,10 +2378,11 @@ } }, "node_modules/@wdio/logger/node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -2378,10 +2391,11 @@ } }, "node_modules/@wdio/logger/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==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -2393,16 +2407,18 @@ } }, "node_modules/@wdio/protocols": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-9.7.0.tgz", - "integrity": "sha512-5DI8cqJqT9K6oQn8UpaSTmcGAl4ufkUWC5FoPT3oXdLjILfxvweZDf/2XNBCbGMk4+VOMKqB2ofOqKhDIB2nAg==", - "dev": true + "version": "9.16.2", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-9.16.2.tgz", + "integrity": "sha512-h3k97/lzmyw5MowqceAuY3HX/wGJojXHkiPXA3WlhGPCaa2h4+GovV2nJtRvknCKsE7UHA1xB5SWeI8MzloBew==", + "dev": true, + "license": "MIT" }, "node_modules/@wdio/repl": { - "version": "9.4.4", - "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-9.4.4.tgz", - "integrity": "sha512-kchPRhoG/pCn4KhHGiL/ocNhdpR8OkD2e6sANlSUZ4TGBVi86YSIEjc2yXUwLacHknC/EnQk/SFnqd4MsNjGGg==", + "version": "9.16.2", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-9.16.2.tgz", + "integrity": "sha512-FLTF0VL6+o5BSTCO7yLSXocm3kUnu31zYwzdsz4n9s5YWt83sCtzGZlZpt7TaTzb3jVUfxuHNQDTb8UMkCu0lQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0" }, @@ -2411,25 +2427,28 @@ } }, "node_modules/@wdio/repl/node_modules/@types/node": { - "version": "20.17.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.28.tgz", - "integrity": "sha512-DHlH/fNL6Mho38jTy7/JT7sn2wnXI+wULR6PV4gy4VHLVvnrV/d3pHAMQHhc4gjdLmK2ZiPoMxzp6B3yRajLSQ==", + "version": "20.19.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", + "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.21.0" } }, "node_modules/@wdio/repl/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" }, "node_modules/@wdio/types": { - "version": "9.10.1", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.10.1.tgz", - "integrity": "sha512-/t1VXPU5Ad1FQjRUP0WlK7IR0dCTX5hSkul8SpCuUpWbeyI4Iol/Wx2b1YU6nS+Ydh78rJCyHxtV0eE5TM1rbw==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.20.0.tgz", + "integrity": "sha512-zMmAtse2UMCSOW76mvK3OejauAdcFGuKopNRH7crI0gwKTZtvV89yXWRziz9cVXpFgfmJCjf9edxKFWdhuF5yw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0" }, @@ -2438,36 +2457,40 @@ } }, "node_modules/@wdio/types/node_modules/@types/node": { - "version": "20.17.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.28.tgz", - "integrity": "sha512-DHlH/fNL6Mho38jTy7/JT7sn2wnXI+wULR6PV4gy4VHLVvnrV/d3pHAMQHhc4gjdLmK2ZiPoMxzp6B3yRajLSQ==", + "version": "20.19.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", + "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.21.0" } }, "node_modules/@wdio/types/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" }, "node_modules/@wdio/utils": { - "version": "9.12.1", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.12.1.tgz", - "integrity": "sha512-WrkBdglOwKMpwvCZbOatlLUCghxNWyVfKRDyl92RBX3DuRqqq+uZK8fSHHAJMvXfax5TxcTRzHZUKrQO3ASSXw==", + "version": "9.20.1", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.20.1.tgz", + "integrity": "sha512-C/Gsy5NAatsGUF1eT9Ks/ErR52/X4YI7MSm7BtwNOw8v2Ko+SiCA5qXts61J0A7QYwOn4gfXfBZZnzSAng6G/w==", "dev": true, + "license": "MIT", "dependencies": { "@puppeteer/browsers": "^2.2.0", - "@wdio/logger": "9.4.4", - "@wdio/types": "9.10.1", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.20.0", "decamelize": "^6.0.0", "deepmerge-ts": "^7.0.3", - "edgedriver": "^6.1.1", + "edgedriver": "^6.1.2", "geckodriver": "^5.0.0", "get-port": "^7.0.0", "import-meta-resolve": "^4.0.0", "locate-app": "^2.2.24", + "mitt": "^3.0.1", "safaridriver": "^1.0.0", "split2": "^4.2.0", "wait-port": "^1.1.0" @@ -2477,10 +2500,11 @@ } }, "node_modules/@wdio/utils/node_modules/decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.1.tgz", + "integrity": "sha512-G7Cqgaelq68XHJNGlZ7lrNQyhZGsFqpwtGFexqUv4IQdjKoSYF7ipZ9UuTJZUSQXFj/XaoBLuEVIVqr8EJngEQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -2711,14 +2735,15 @@ "license": "Apache-2.0" }, "node_modules/@zip.js/zip.js": { - "version": "2.7.57", - "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.57.tgz", - "integrity": "sha512-BtonQ1/jDnGiMed6OkV6rZYW78gLmLswkHOzyMrMb+CAR7CZO8phOHO6c2qw6qb1g1betN7kwEHhhZk30dv+NA==", + "version": "2.8.11", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.11.tgz", + "integrity": "sha512-0fztsk/0ryJ+2PPr9EyXS5/Co7OK8q3zY/xOoozEWaUsL5x+C0cyZ4YyMuUffOO2Dx/rAdq4JMPqW0VUtm+vzA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "bun": ">=0.7.0", "deno": ">=1.0.0", - "node": ">=16.5.0" + "node": ">=18.0.0" } }, "node_modules/abab": { @@ -3079,6 +3104,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" }, @@ -3090,7 +3116,8 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/astral-regex": { "version": "2.0.0", @@ -3161,15 +3188,18 @@ "optional": true }, "node_modules/bare-fs": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.0.2.tgz", - "integrity": "sha512-S5mmkMesiduMqnz51Bfh0Et9EX0aTCJxhsI4bvzFFLs8Z1AV8RDHadfY5CyLwdoLHgXbNBEN1gQcbEtGwuvixw==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.1.tgz", + "integrity": "sha512-zGUCsm3yv/ePt2PHNbVxjjn0nNB1MkIaR4wOCxJ2ig5pCf5cCVAYJXVhQg/3OhhJV6DB1ts7Hv0oUaElc2TPQg==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", - "bare-stream": "^2.6.4" + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" }, "engines": { "bare": ">=1.16.0" @@ -3184,10 +3214,11 @@ } }, "node_modules/bare-os": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", - "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", "dev": true, + "license": "Apache-2.0", "optional": true, "engines": { "bare": ">=1.14.0" @@ -3198,16 +3229,18 @@ "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "bare-os": "^3.0.1" } }, "node_modules/bare-stream": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz", - "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", + "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "streamx": "^2.21.0" @@ -3225,6 +3258,17 @@ } } }, + "node_modules/bare-url": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", + "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-path": "^3.0.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -3250,6 +3294,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" } @@ -4216,6 +4261,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" } @@ -4234,10 +4280,11 @@ } }, "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==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -4300,6 +4347,7 @@ "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=16.0.0" } @@ -4352,6 +4400,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", @@ -4560,6 +4609,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" @@ -4572,17 +4622,18 @@ } }, "node_modules/edgedriver": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-6.1.1.tgz", - "integrity": "sha512-/dM/PoBf22Xg3yypMWkmRQrBKEnSyNaZ7wHGCT9+qqT14izwtFT+QvdR89rjNkMfXwW+bSFoqOfbcvM+2Cyc7w==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-6.1.2.tgz", + "integrity": "sha512-UvFqd/IR81iPyWMcxXbUNi+xKWR7JjfoHjfuwjqsj9UHQKn80RpQmS0jf+U25IPi+gKVPcpOSKm0XkqgGMq4zQ==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "@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.5.0", + "fast-xml-parser": "^5.0.8", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.5", "node-fetch": "^3.3.2", @@ -4596,10 +4647,11 @@ } }, "node_modules/edgedriver/node_modules/decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.1.tgz", + "integrity": "sha512-G7Cqgaelq68XHJNGlZ7lrNQyhZGsFqpwtGFexqUv4IQdjKoSYF7ipZ9UuTJZUSQXFj/XaoBLuEVIVqr8EJngEQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -4612,6 +4664,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" } @@ -4621,6 +4674,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -4685,10 +4739,11 @@ } }, "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "dev": true, + "license": "MIT", "dependencies": { "once": "^1.4.0" } @@ -4829,6 +4884,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", @@ -4850,6 +4906,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -5322,6 +5379,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", @@ -5337,21 +5395,6 @@ "@types/yauzl": "^2.9.1" } }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5397,9 +5440,9 @@ "license": "MIT" }, "node_modules/fast-xml-parser": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", - "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.2.tgz", + "integrity": "sha512-n8v8b6p4Z1sMgqRmqLJm3awW4NX7NkaKPfb3uJIBTSH7Pdvufi3PQ3/lJLQrvxcMYl7JI2jnDO90siPEpD8JBA==", "dev": true, "funding": [ { @@ -5407,8 +5450,9 @@ "url": "https://github.com/sponsors/NaturalIntelligence" } ], + "license": "MIT", "dependencies": { - "strnum": "^1.1.1" + "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" @@ -5452,6 +5496,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" } @@ -5471,6 +5516,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" @@ -5727,6 +5773,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" }, @@ -5821,6 +5868,7 @@ "integrity": "sha512-vn7TtQ3b9VMJtVXsyWtQQl1fyBVFhQy7UvJF96kPuuJ0or5THH496AD3eUyaDD11+EqCxH9t6V+EP9soZQk4YQ==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "@wdio/logger": "^9.1.3", "@zip.js/zip.js": "^2.7.53", @@ -5839,10 +5887,11 @@ } }, "node_modules/geckodriver/node_modules/decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.1.tgz", + "integrity": "sha512-G7Cqgaelq68XHJNGlZ7lrNQyhZGsFqpwtGFexqUv4IQdjKoSYF7ipZ9UuTJZUSQXFj/XaoBLuEVIVqr8EJngEQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -5855,6 +5904,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" } @@ -5864,6 +5914,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -5923,6 +5974,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" }, @@ -5944,11 +5996,28 @@ "node": ">= 0.4" } }, + "node_modules/get-stream": { + "version": "5.2.0", + "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" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-uri": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", - "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", "dev": true, + "license": "MIT", "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", @@ -5963,6 +6032,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" } @@ -6253,10 +6323,11 @@ } }, "node_modules/htmlfy": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/htmlfy/-/htmlfy-0.6.2.tgz", - "integrity": "sha512-dWRE+TW3QSB5mXsnYCUPLoPmaCu2O7kp6/3xh5fayiGuaNtRL/64SdjhoTBwJ2XvuSkLoMgQDLunrAqwxJj40Q==", - "dev": true + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/htmlfy/-/htmlfy-0.8.1.tgz", + "integrity": "sha512-xWROBw9+MEGwxpotll0h672KCaLrKKiCYzsyN8ZgL9cQbVumFnyvsk2JqiB9ELAV1GLj1GG/jxZUjV9OZZi/yQ==", + "dev": true, + "license": "MIT" }, "node_modules/htmlparser2": { "version": "6.1.0", @@ -6484,10 +6555,11 @@ } }, "node_modules/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -6533,24 +6605,15 @@ } }, "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", "dev": true, - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, + "license": "MIT", "engines": { "node": ">= 12" } }, - "node_modules/ip-address/node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true - }, "node_modules/ipaddr.js": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", @@ -6874,12 +6937,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true - }, "node_modules/jsdoc-type-pratt-parser": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", @@ -7198,6 +7255,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", @@ -7209,6 +7267,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" }, @@ -7302,6 +7361,7 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6.0" }, @@ -7314,7 +7374,8 @@ "version": "0.8.4", "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loupe": { "version": "3.1.3", @@ -7495,6 +7556,13 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" + }, "node_modules/mocha": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz", @@ -7666,6 +7734,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" } @@ -7730,6 +7799,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", "dev": true, "funding": [ { @@ -7741,6 +7811,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "engines": { "node": ">=10.5.0" } @@ -7750,6 +7821,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", @@ -7970,6 +8042,7 @@ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", "dev": true, + "license": "MIT", "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.1.2", @@ -7989,6 +8062,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" @@ -8223,7 +8297,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", @@ -8405,6 +8480,7 @@ "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.1.2", "debug": "^4.3.4", @@ -8424,6 +8500,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" } @@ -8432,13 +8509,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==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -8746,6 +8825,16 @@ "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", "dev": true }, + "node_modules/ret": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.5.0.tgz", + "integrity": "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -8838,6 +8927,7 @@ "resolved": "https://registry.npmjs.org/safaridriver/-/safaridriver-1.0.0.tgz", "integrity": "sha512-J92IFbskyo7OYB3Dt4aTdyhag1GlInrfbPCmMteb7aBK7PwlnGz1HI0+oyNN97j7pV9DqUAVoVgkNRMrfY47mQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18.0.0" } @@ -8863,6 +8953,26 @@ ], "license": "MIT" }, + "node_modules/safe-regex2": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-5.0.0.tgz", + "integrity": "sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ret": "~0.5.0" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -8924,10 +9034,11 @@ } }, "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -8988,27 +9099,29 @@ } }, "node_modules/serialize-error": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", - "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-12.0.0.tgz", + "integrity": "sha512-ZYkZLAvKTKQXWuh5XpBw7CdbSzagarX39WyZ2H07CDLC5/KfsRGlIXV8d4+tfqX1M7916mRqR1QfNHSij+c9Pw==", "dev": true, + "license": "MIT", "dependencies": { - "type-fest": "^2.12.2" + "type-fest": "^4.31.0" }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/serialize-error/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=12.20" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9326,6 +9439,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" @@ -9344,12 +9458,13 @@ } }, "node_modules/socks": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz", - "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==", + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", "dev": true, + "license": "MIT", "dependencies": { - "ip-address": "^9.0.5", + "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -9362,6 +9477,7 @@ "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.2", "debug": "^4.3.4", @@ -9492,7 +9608,8 @@ "type": "github", "url": "https://github.com/hejny/spacetrim/blob/main/README.md#%EF%B8%8F-contributing" } - ] + ], + "license": "Apache-2.0" }, "node_modules/spdx-exceptions": { "version": "2.5.0", @@ -9556,6 +9673,7 @@ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, + "license": "ISC", "engines": { "node": ">= 10.x" } @@ -9670,16 +9788,17 @@ } }, "node_modules/strnum": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", - "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", + "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" } - ] + ], + "license": "MIT" }, "node_modules/supports-color": { "version": "7.2.0", @@ -9741,9 +9860,9 @@ } }, "node_modules/tar-fs": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.9.tgz", - "integrity": "sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dev": true, "license": "MIT", "dependencies": { @@ -10136,10 +10255,11 @@ } }, "node_modules/undici": { - "version": "6.21.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.2.tgz", - "integrity": "sha512-uROZWze0R0itiAKVPsYhFov9LxrPMHLMEQFszeI2gCN6bnIIZ8twzBCJcN2LJrBBLfrP0t1FW0g+JmKVl8Vk1g==", + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.22.0.tgz", + "integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=18.17" } @@ -10221,6 +10341,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" } @@ -10293,6 +10414,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", @@ -10310,6 +10432,7 @@ "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" } @@ -10343,25 +10466,28 @@ "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.12.1", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.12.1.tgz", - "integrity": "sha512-gtdsfoYAVgPVlN1x3kXhPmOOzQXx6vtw9KB0LCeFQH2zUfNMB7RB1OJN475cFgSgJ7PpyvXk3CKdT1lGCHRTxQ==", + "version": "9.20.1", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.20.1.tgz", + "integrity": "sha512-QtvYqPai2NOnq7qePPH6kNSwk7+tnmSvnlOnY8dIT/Y24TPdQp44NjF/BUYAWIlqoBlZqHClQFTSVwT2qvO2Tw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", - "@wdio/config": "9.12.1", - "@wdio/logger": "9.4.4", - "@wdio/protocols": "9.7.0", - "@wdio/types": "9.10.1", - "@wdio/utils": "9.12.1", + "@wdio/config": "9.20.1", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.16.2", + "@wdio/types": "9.20.0", + "@wdio/utils": "9.20.1", "deepmerge-ts": "^7.0.3", - "undici": "^6.20.1", + "https-proxy-agent": "^7.0.6", + "undici": "^6.21.3", "ws": "^8.8.0" }, "engines": { @@ -10369,41 +10495,44 @@ } }, "node_modules/webdriver/node_modules/@types/node": { - "version": "20.17.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.28.tgz", - "integrity": "sha512-DHlH/fNL6Mho38jTy7/JT7sn2wnXI+wULR6PV4gy4VHLVvnrV/d3pHAMQHhc4gjdLmK2ZiPoMxzp6B3yRajLSQ==", + "version": "20.19.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", + "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.21.0" } }, "node_modules/webdriver/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" }, "node_modules/webdriverio": { - "version": "9.12.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.12.1.tgz", - "integrity": "sha512-xKasUD3DRey9lEcTAbrI29XCxLX45cxVHOIN5EJK44/thch4zhzfskdCKY3BQ9589TCkSGY1CGf8q9LFx2Ve5Q==", + "version": "9.20.1", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.20.1.tgz", + "integrity": "sha512-QVM/asb5sDESz37ow/BAOA0z2HtUJsuAjPKHdw+Vx92PaQP3EfHwTgxK2T5rgwa0WRNh+c+n/0nEqIvqBl01sA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.11.30", "@types/sinonjs__fake-timers": "^8.1.5", - "@wdio/config": "9.12.1", - "@wdio/logger": "9.4.4", - "@wdio/protocols": "9.7.0", - "@wdio/repl": "9.4.4", - "@wdio/types": "9.10.1", - "@wdio/utils": "9.12.1", + "@wdio/config": "9.20.1", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.16.2", + "@wdio/repl": "9.16.2", + "@wdio/types": "9.20.0", + "@wdio/utils": "9.20.1", "archiver": "^7.0.1", "aria-query": "^5.3.0", "cheerio": "^1.0.0-rc.12", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", "grapheme-splitter": "^1.0.4", - "htmlfy": "^0.6.0", + "htmlfy": "^0.8.1", "is-plain-obj": "^4.1.0", "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", @@ -10411,15 +10540,15 @@ "query-selector-shadow-dom": "^1.0.1", "resq": "^1.11.0", "rgb2hex": "0.2.5", - "serialize-error": "^11.0.3", + "serialize-error": "^12.0.0", "urlpattern-polyfill": "^10.0.0", - "webdriver": "9.12.1" + "webdriver": "9.20.1" }, "engines": { "node": ">=18.20.0" }, "peerDependencies": { - "puppeteer-core": "^22.3.0" + "puppeteer-core": ">=22.x || <=24.x" }, "peerDependenciesMeta": { "puppeteer-core": { @@ -11105,6 +11234,7 @@ "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" @@ -11115,6 +11245,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": "*" } diff --git a/package.json b/package.json index 663b312d..5629a333 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "prettier": "^3.3.1", "ts-loader": "^9.5.1", "typescript": "^5.4.5", - "webdriverio": "^9.12.1" + "webdriverio": "^9.13.0" }, "peerDependencies": { "blockly": "^12.3.0" diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index d7997056..46103808 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -26,17 +26,17 @@ suite('Scrolling into view', function () { // N.B. that this is called only one per suite, not once per test. suiteSetup(async function () { this.browser = await testSetup(testFileLocations.BASE, this.timeout()); - this.windowSize = await this.browser.getWindowSize(); - await this.browser.setWindowSize(800, 600); + // this.windowSize = await this.browser.getWindowSize(); + await this.browser.setViewport({width: 800, height: 600, devicePixelRatio: 1}); await this.browser.pause(PAUSE_TIME); }); // Restore original browser window size. suiteTeardown(async function () { - await this.browser.setWindowSize( - this.windowSize.width, - this.windowSize.height, - ); + // await this.browser.setWindowSize( + // this.windowSize.width, + // this.windowSize.height, + // ); }); // Clear the workspace and load start blocks. diff --git a/test/webdriverio/test/test_setup.ts b/test/webdriverio/test/test_setup.ts index 1ddbac97..8c91f34d 100644 --- a/test/webdriverio/test/test_setup.ts +++ b/test/webdriverio/test/test_setup.ts @@ -65,10 +65,8 @@ export async function driverSetup( 'goog:chromeOptions': { args: ['--allow-file-access-from-files'], }, - // We aren't (yet) using any BiDi features, and BiDi is sensitive to - // mismatches between Chrome version and Chromedriver version. - // eslint-disable-next-line @typescript-eslint/naming-convention - 'wdio:enforceWebDriverClassic': true, + // Allows certain BiDi features to work correctly. + 'webSocketUrl': true }, waitforTimeout: wdioWaitTimeoutMs, logLevel: 'warn' as const, diff --git a/test/webdriverio/test/workspace_comment_test.ts b/test/webdriverio/test/workspace_comment_test.ts index 7f9e4a75..7f1c3d8a 100644 --- a/test/webdriverio/test/workspace_comment_test.ts +++ b/test/webdriverio/test/workspace_comment_test.ts @@ -151,7 +151,7 @@ suite('Workspace comment navigation', function () { return Blockly.getMainWorkspace() .getCommentById(commentId) ?.isCollapsed(); - }, this.commentId1); + }, this.commentId1 as string); chai.assert.isTrue(collapsed); }); @@ -172,7 +172,7 @@ suite('Workspace comment navigation', function () { const commentText = await this.browser.execute((commentId) => { return Blockly.getMainWorkspace().getCommentById(commentId)?.getText(); - }, this.commentId1); + }, this.commentId1 as string); chai.assert.equal(commentText, 'Comment oneHello world'); }); From 27785c68119097b5c9d32826ad426f60b46ebfd9 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Thu, 20 Nov 2025 23:33:25 +0000 Subject: [PATCH 05/32] chore: Clean up test & re-enable all. This test suite seems to now pass consistently between Linux & Mac. --- test/webdriverio/test/scroll_test.ts | 40 +++++----------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index 46103808..721db981 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -21,30 +21,25 @@ suite('Scrolling into view', function () { // Disable timeouts when non-zero PAUSE_TIME is used to watch tests run. if (PAUSE_TIME) this.timeout(0); - // Resize browser to provide predictable small window size for scrolling. + // Resize browser to provide predictable small viewport size for scrolling. // // N.B. that this is called only one per suite, not once per test. suiteSetup(async function () { this.browser = await testSetup(testFileLocations.BASE, this.timeout()); - // this.windowSize = await this.browser.getWindowSize(); - await this.browser.setViewport({width: 800, height: 600, devicePixelRatio: 1}); + // Note that a viewport is used here over adjusting window size to ensure + // consistency across platforms and environments. + await this.browser.setViewport({ + width: 800, height: 600, devicePixelRatio: 1 + }); await this.browser.pause(PAUSE_TIME); }); - // Restore original browser window size. - suiteTeardown(async function () { - // await this.browser.setWindowSize( - // this.windowSize.width, - // this.windowSize.height, - // ); - }); - // Clear the workspace and load start blocks. setup(async function () { await testSetup(testFileLocations.BASE, this.timeout()); }); - test.only('Insert scrolls new block into view', async function () { + test('Insert scrolls new block into view', async function () { // Increase timeout to 10s for this longer test. this.timeout(PAUSE_TIME ? 0 : 10000); @@ -72,27 +67,6 @@ suite('Scrolling into view', function () { // Assert new block has been scrolled into the viewport. await this.browser.pause(PAUSE_TIME); - const blockBounds = await this.browser.execute(() => { - const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; - const block = workspace.getBlocksByType( - 'controls_if', - )[0] as Blockly.BlockSvg; - const blockBounds = block.getBoundingRectangleWithoutChildren(); - return blockBounds; - }); - console.log("block bounds:", blockBounds); - const viewport = await this.browser.execute(() => { - const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; - const rawViewport = workspace.getMetricsManager().getViewMetrics(true); - const viewport = new Blockly.utils.Rect( - rawViewport.top, - rawViewport.top + rawViewport.height, - rawViewport.left, - rawViewport.left + rawViewport.width, - ); - return viewport; - }); - console.log("viewport:", viewport); const inViewport = await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; const block = workspace.getBlocksByType( From d5497fe450b14b0994c27f5a014647ec5bc93b22 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Thu, 20 Nov 2025 23:47:47 +0000 Subject: [PATCH 06/32] chore: Try upgrading WebdriverIO. --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4c229f47..d931aa2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "prettier": "^3.3.1", "ts-loader": "^9.5.1", "typescript": "^5.4.5", - "webdriverio": "^9.13.0" + "webdriverio": "^9.20.1" }, "peerDependencies": { "blockly": "^12.3.0" diff --git a/package.json b/package.json index 5629a333..048710b0 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "prettier": "^3.3.1", "ts-loader": "^9.5.1", "typescript": "^5.4.5", - "webdriverio": "^9.13.0" + "webdriverio": "^9.20.1" }, "peerDependencies": { "blockly": "^12.3.0" From 8d56eba369cd9ccb33ff745dfbc47069d8f5e387 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 00:02:34 +0000 Subject: [PATCH 07/32] chore: Re-isolate scroll test. It's failing either again (after WIO update) or when run with the rest of the test suite. --- test/webdriverio/test/scroll_test.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index 721db981..11a0df75 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -39,7 +39,7 @@ suite('Scrolling into view', function () { await testSetup(testFileLocations.BASE, this.timeout()); }); - test('Insert scrolls new block into view', async function () { + test.only('Insert scrolls new block into view', async function () { // Increase timeout to 10s for this longer test. this.timeout(PAUSE_TIME ? 0 : 10000); @@ -67,6 +67,27 @@ suite('Scrolling into view', function () { // Assert new block has been scrolled into the viewport. await this.browser.pause(PAUSE_TIME); + const blockBounds = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + const block = workspace.getBlocksByType( + 'controls_if', + )[0] as Blockly.BlockSvg; + const blockBounds = block.getBoundingRectangleWithoutChildren(); + return blockBounds; + }); + console.log("block bounds:", blockBounds); + const viewport = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + const rawViewport = workspace.getMetricsManager().getViewMetrics(true); + const viewport = new Blockly.utils.Rect( + rawViewport.top, + rawViewport.top + rawViewport.height, + rawViewport.left, + rawViewport.left + rawViewport.width, + ); + return viewport; + }); + console.log("viewport:", viewport); const inViewport = await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; const block = workspace.getBlocksByType( From af1dbaa8645bbfd2a352ad11bfe020e558349598 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 00:11:56 +0000 Subject: [PATCH 08/32] chore: Add more debug logs. --- test/webdriverio/test/scroll_test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index 11a0df75..835b2b1a 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -51,6 +51,11 @@ suite('Scrolling into view', function () { await sendKeyAndWait(this.browser, [Key.Alt, Key.ArrowDown], 25); await sendKeyAndWait(this.browser, Key.Enter); // Scroll back up, leaving cursor on the draw block out of the viewport. + const scrollPosition1 = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + return [workspace.scrollX, workspace.scrollY]; + }); + console.log("workspace scroll position before scroll:", scrollPosition1); await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; workspace.scrollBoundsIntoView( @@ -59,6 +64,11 @@ suite('Scrolling into view', function () { ).getBoundingRectangleWithoutChildren(), ); }); + const scrollPosition2 = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + return [workspace.scrollX, workspace.scrollY]; + }); + console.log("workspace scroll position after scroll:", scrollPosition2); // Insert and confirm the test block which should be scrolled into view. await sendKeyAndWait(this.browser, 't'); From 2e210fe962593661f70cc2399d239018d1a40cb2 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 00:21:56 +0000 Subject: [PATCH 09/32] chore: Run tests up to 50 times. --- .github/workflows/test.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 92a47d9c..c5f0987c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -63,7 +63,11 @@ jobs: - name: Run tests run: | cd main - npm run test:ci + for i in $(seq 1 50); + do + echo "Attempt $i" + npm run test:ci + done webdriverio_tests: name: WebdriverIO tests (against pinned v12) From 2187b2c64865ab9dc3f2491c56c041a2241b9bc5 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 00:52:32 +0000 Subject: [PATCH 10/32] chore: Speed & reduce tests for CI investigating. --- .github/workflows/test.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c5f0987c..5ea4b163 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ permissions: jobs: webdriverio_tests_tip_of_tree_v12: name: WebdriverIO tests (against tip-of-tree core develop) - timeout-minutes: 10 + # timeout-minutes: 10 runs-on: ${{ matrix.os }} strategy: @@ -60,13 +60,19 @@ jobs: npm link blockly cd .. - - name: Run tests + - name: Build tests run: | cd main + npm run wdio:clean + npm run wdio:build + + - name: Run tests (up to 50 times) + run: | + cd test/webdriverio/test for i in $(seq 1 50); do echo "Attempt $i" - npm run test:ci + npx mocha --timeout 30000 dist done webdriverio_tests: From dabaad5249bdad4f2520427e6817937a1dc95f50 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 01:01:16 +0000 Subject: [PATCH 11/32] chore: Fix path changing. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5ea4b163..6bb40288 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -68,7 +68,7 @@ jobs: - name: Run tests (up to 50 times) run: | - cd test/webdriverio/test + cd main/test/webdriverio/test for i in $(seq 1 50); do echo "Attempt $i" From 4b97659f88da84a2e23f6ce6fbcdbea497f7a9c3 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 01:12:27 +0000 Subject: [PATCH 12/32] chore: Remove debug logs to test theory. --- test/webdriverio/test/scroll_test.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index 835b2b1a..169ca7f9 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -51,11 +51,11 @@ suite('Scrolling into view', function () { await sendKeyAndWait(this.browser, [Key.Alt, Key.ArrowDown], 25); await sendKeyAndWait(this.browser, Key.Enter); // Scroll back up, leaving cursor on the draw block out of the viewport. - const scrollPosition1 = await this.browser.execute(() => { - const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; - return [workspace.scrollX, workspace.scrollY]; - }); - console.log("workspace scroll position before scroll:", scrollPosition1); + // const scrollPosition1 = await this.browser.execute(() => { + // const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + // return [workspace.scrollX, workspace.scrollY]; + // }); + // console.log("workspace scroll position before scroll:", scrollPosition1); await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; workspace.scrollBoundsIntoView( @@ -64,11 +64,11 @@ suite('Scrolling into view', function () { ).getBoundingRectangleWithoutChildren(), ); }); - const scrollPosition2 = await this.browser.execute(() => { - const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; - return [workspace.scrollX, workspace.scrollY]; - }); - console.log("workspace scroll position after scroll:", scrollPosition2); + // const scrollPosition2 = await this.browser.execute(() => { + // const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + // return [workspace.scrollX, workspace.scrollY]; + // }); + // console.log("workspace scroll position after scroll:", scrollPosition2); // Insert and confirm the test block which should be scrolled into view. await sendKeyAndWait(this.browser, 't'); From cefb2867cf7b4d1e8aeb052aeaceeb32acf8eba2 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 01:17:46 +0000 Subject: [PATCH 13/32] chore: Try to remove more logs. --- test/webdriverio/test/scroll_test.ts | 42 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index 169ca7f9..fdbba2fd 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -77,27 +77,27 @@ suite('Scrolling into view', function () { // Assert new block has been scrolled into the viewport. await this.browser.pause(PAUSE_TIME); - const blockBounds = await this.browser.execute(() => { - const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; - const block = workspace.getBlocksByType( - 'controls_if', - )[0] as Blockly.BlockSvg; - const blockBounds = block.getBoundingRectangleWithoutChildren(); - return blockBounds; - }); - console.log("block bounds:", blockBounds); - const viewport = await this.browser.execute(() => { - const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; - const rawViewport = workspace.getMetricsManager().getViewMetrics(true); - const viewport = new Blockly.utils.Rect( - rawViewport.top, - rawViewport.top + rawViewport.height, - rawViewport.left, - rawViewport.left + rawViewport.width, - ); - return viewport; - }); - console.log("viewport:", viewport); + // const blockBounds = await this.browser.execute(() => { + // const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + // const block = workspace.getBlocksByType( + // 'controls_if', + // )[0] as Blockly.BlockSvg; + // const blockBounds = block.getBoundingRectangleWithoutChildren(); + // return blockBounds; + // }); + // console.log("block bounds:", blockBounds); + // const viewport = await this.browser.execute(() => { + // const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + // const rawViewport = workspace.getMetricsManager().getViewMetrics(true); + // const viewport = new Blockly.utils.Rect( + // rawViewport.top, + // rawViewport.top + rawViewport.height, + // rawViewport.left, + // rawViewport.left + rawViewport.width, + // ); + // return viewport; + // }); + // console.log("viewport:", viewport); const inViewport = await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; const block = workspace.getBlocksByType( From 28a32f432ffddded87377f5f0e24032de3bf2564 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 01:22:00 +0000 Subject: [PATCH 14/32] chore: Try adding a pause. --- test/webdriverio/test/move_test.ts | 2 +- test/webdriverio/test/scroll_test.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/webdriverio/test/move_test.ts b/test/webdriverio/test/move_test.ts index 72212051..132a26ec 100644 --- a/test/webdriverio/test/move_test.ts +++ b/test/webdriverio/test/move_test.ts @@ -18,7 +18,7 @@ import { contextMenuItems, } from './test_setup.js'; -suite('Move start tests', function () { +suite.skip('Move start tests', function () { // Increase timeout to 10s for this longer test (but disable // timeouts if when non-zero PAUSE_TIME is used to watch tests) run. this.timeout(PAUSE_TIME ? 0 : 10000); diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index fdbba2fd..c2dadd02 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -64,6 +64,7 @@ suite('Scrolling into view', function () { ).getBoundingRectangleWithoutChildren(), ); }); + await this.browser.pause(PAUSE_TIME); // const scrollPosition2 = await this.browser.execute(() => { // const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; // return [workspace.scrollX, workspace.scrollY]; From 059092f58f95eb8793f96a5b423af3336d7d6a85 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 01:26:58 +0000 Subject: [PATCH 15/32] chore: Add comment & enable most tests. --- test/webdriverio/test/scroll_test.ts | 35 ++-------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index c2dadd02..fa072c29 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -39,7 +39,7 @@ suite('Scrolling into view', function () { await testSetup(testFileLocations.BASE, this.timeout()); }); - test.only('Insert scrolls new block into view', async function () { + test('Insert scrolls new block into view', async function () { // Increase timeout to 10s for this longer test. this.timeout(PAUSE_TIME ? 0 : 10000); @@ -50,12 +50,6 @@ suite('Scrolling into view', function () { await sendKeyAndWait(this.browser, 'm'); await sendKeyAndWait(this.browser, [Key.Alt, Key.ArrowDown], 25); await sendKeyAndWait(this.browser, Key.Enter); - // Scroll back up, leaving cursor on the draw block out of the viewport. - // const scrollPosition1 = await this.browser.execute(() => { - // const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; - // return [workspace.scrollX, workspace.scrollY]; - // }); - // console.log("workspace scroll position before scroll:", scrollPosition1); await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; workspace.scrollBoundsIntoView( @@ -64,12 +58,8 @@ suite('Scrolling into view', function () { ).getBoundingRectangleWithoutChildren(), ); }); + // Pause to allow scrolling to stabilize before proceeding. await this.browser.pause(PAUSE_TIME); - // const scrollPosition2 = await this.browser.execute(() => { - // const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; - // return [workspace.scrollX, workspace.scrollY]; - // }); - // console.log("workspace scroll position after scroll:", scrollPosition2); // Insert and confirm the test block which should be scrolled into view. await sendKeyAndWait(this.browser, 't'); @@ -78,27 +68,6 @@ suite('Scrolling into view', function () { // Assert new block has been scrolled into the viewport. await this.browser.pause(PAUSE_TIME); - // const blockBounds = await this.browser.execute(() => { - // const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; - // const block = workspace.getBlocksByType( - // 'controls_if', - // )[0] as Blockly.BlockSvg; - // const blockBounds = block.getBoundingRectangleWithoutChildren(); - // return blockBounds; - // }); - // console.log("block bounds:", blockBounds); - // const viewport = await this.browser.execute(() => { - // const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; - // const rawViewport = workspace.getMetricsManager().getViewMetrics(true); - // const viewport = new Blockly.utils.Rect( - // rawViewport.top, - // rawViewport.top + rawViewport.height, - // rawViewport.left, - // rawViewport.left + rawViewport.width, - // ); - // return viewport; - // }); - // console.log("viewport:", viewport); const inViewport = await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; const block = workspace.getBlocksByType( From 531979e0c86212684c811c917f7d30e071c1e310 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 01:30:40 +0000 Subject: [PATCH 16/32] chore: Re-add removed comment. --- test/webdriverio/test/scroll_test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index fa072c29..a7c1e9ba 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -50,6 +50,7 @@ suite('Scrolling into view', function () { await sendKeyAndWait(this.browser, 'm'); await sendKeyAndWait(this.browser, [Key.Alt, Key.ArrowDown], 25); await sendKeyAndWait(this.browser, Key.Enter); + // Scroll back up, leaving cursor on the draw block out of the viewport. await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; workspace.scrollBoundsIntoView( From efecfd9fa718a77987044652917ed47aeb895356 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 01:35:32 +0000 Subject: [PATCH 17/32] chore: Re-add logs for investigation. --- test/webdriverio/test/scroll_test.ts | 33 +++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index a7c1e9ba..e2d68144 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -39,7 +39,7 @@ suite('Scrolling into view', function () { await testSetup(testFileLocations.BASE, this.timeout()); }); - test('Insert scrolls new block into view', async function () { + test.only('Insert scrolls new block into view', async function () { // Increase timeout to 10s for this longer test. this.timeout(PAUSE_TIME ? 0 : 10000); @@ -51,6 +51,11 @@ suite('Scrolling into view', function () { await sendKeyAndWait(this.browser, [Key.Alt, Key.ArrowDown], 25); await sendKeyAndWait(this.browser, Key.Enter); // Scroll back up, leaving cursor on the draw block out of the viewport. + const scrollPosition1 = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + return [workspace.scrollX, workspace.scrollY]; + }); + console.log("workspace scroll position before scroll:", scrollPosition1); await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; workspace.scrollBoundsIntoView( @@ -61,6 +66,11 @@ suite('Scrolling into view', function () { }); // Pause to allow scrolling to stabilize before proceeding. await this.browser.pause(PAUSE_TIME); + const scrollPosition2 = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + return [workspace.scrollX, workspace.scrollY]; + }); + console.log("workspace scroll position after scroll:", scrollPosition2); // Insert and confirm the test block which should be scrolled into view. await sendKeyAndWait(this.browser, 't'); @@ -69,6 +79,27 @@ suite('Scrolling into view', function () { // Assert new block has been scrolled into the viewport. await this.browser.pause(PAUSE_TIME); + const blockBounds = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + const block = workspace.getBlocksByType( + 'controls_if', + )[0] as Blockly.BlockSvg; + const blockBounds = block.getBoundingRectangleWithoutChildren(); + return blockBounds; + }); + console.log("block bounds:", blockBounds); + const viewport = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + const rawViewport = workspace.getMetricsManager().getViewMetrics(true); + const viewport = new Blockly.utils.Rect( + rawViewport.top, + rawViewport.top + rawViewport.height, + rawViewport.left, + rawViewport.left + rawViewport.width, + ); + return viewport; + }); + console.log("viewport:", viewport); const inViewport = await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; const block = workspace.getBlocksByType( From 1e96c0a25d4783e6f9f86dacd658569d7d3ee6d9 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 01:40:22 +0000 Subject: [PATCH 18/32] chore: Undo accidental test isolation. --- test/webdriverio/test/scroll_test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index e2d68144..51cd57e6 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -39,7 +39,7 @@ suite('Scrolling into view', function () { await testSetup(testFileLocations.BASE, this.timeout()); }); - test.only('Insert scrolls new block into view', async function () { + test('Insert scrolls new block into view', async function () { // Increase timeout to 10s for this longer test. this.timeout(PAUSE_TIME ? 0 : 10000); From 7c607d1a316ccbaa0d76fbba0a9cde6872599225 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 01:51:57 +0000 Subject: [PATCH 19/32] chore: More logs. --- test/webdriverio/test/scroll_test.ts | 8 ++++++++ test/webdriverio/test/test_setup.ts | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index 51cd57e6..7ddfea86 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -71,11 +71,19 @@ suite('Scrolling into view', function () { return [workspace.scrollX, workspace.scrollY]; }); console.log("workspace scroll position after scroll:", scrollPosition2); + const focusedNodeId1 = await this.browser.execute(() => { + return Blockly.getFocusManager().getFocusedNode()?.getFocusableElement()?.id; + }); + console.log("current focused node before insert:", focusedNodeId1); // Insert and confirm the test block which should be scrolled into view. await sendKeyAndWait(this.browser, 't'); await keyRight(this.browser); await sendKeyAndWait(this.browser, Key.Enter, 2); + const focusedNodeId2 = await this.browser.execute(() => { + return Blockly.getFocusManager().getFocusedNode()?.getFocusableElement()?.id; + }); + console.log("current focused node after insert:", focusedNodeId2); // Assert new block has been scrolled into the viewport. await this.browser.pause(PAUSE_TIME); diff --git a/test/webdriverio/test/test_setup.ts b/test/webdriverio/test/test_setup.ts index 8c91f34d..51de0922 100644 --- a/test/webdriverio/test/test_setup.ts +++ b/test/webdriverio/test/test_setup.ts @@ -42,7 +42,7 @@ let driver: webdriverio.Browser | null = null; * the browser.wait* functions if you need your test to wait for * something to happen after sending input. */ -export const PAUSE_TIME = 0; +export const PAUSE_TIME = 200; /** * Start up WebdriverIO and load the test page. This should only be From 385b562b22ce76de6a3831390aca7c9ca02b1604 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 01:58:56 +0000 Subject: [PATCH 20/32] chore: Undo pause. --- test/webdriverio/test/scroll_test.ts | 2 +- test/webdriverio/test/test_setup.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index 7ddfea86..f46b62ba 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -39,7 +39,7 @@ suite('Scrolling into view', function () { await testSetup(testFileLocations.BASE, this.timeout()); }); - test('Insert scrolls new block into view', async function () { + test.only('Insert scrolls new block into view', async function () { // Increase timeout to 10s for this longer test. this.timeout(PAUSE_TIME ? 0 : 10000); diff --git a/test/webdriverio/test/test_setup.ts b/test/webdriverio/test/test_setup.ts index 51de0922..8c91f34d 100644 --- a/test/webdriverio/test/test_setup.ts +++ b/test/webdriverio/test/test_setup.ts @@ -42,7 +42,7 @@ let driver: webdriverio.Browser | null = null; * the browser.wait* functions if you need your test to wait for * something to happen after sending input. */ -export const PAUSE_TIME = 200; +export const PAUSE_TIME = 0; /** * Start up WebdriverIO and load the test page. This should only be From bfe5ea6c230ecf3abcc32894a73519503a68431d Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 01:59:34 +0000 Subject: [PATCH 21/32] chore: Re-enable most tests. --- test/webdriverio/test/scroll_test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index f46b62ba..7ddfea86 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -39,7 +39,7 @@ suite('Scrolling into view', function () { await testSetup(testFileLocations.BASE, this.timeout()); }); - test.only('Insert scrolls new block into view', async function () { + test('Insert scrolls new block into view', async function () { // Increase timeout to 10s for this longer test. this.timeout(PAUSE_TIME ? 0 : 10000); From 7e2035ed8d6d53a6fbd3309919f8e4fae6ea7889 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 02:10:25 +0000 Subject: [PATCH 22/32] chore: More logs. --- test/webdriverio/test/scroll_test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index 7ddfea86..2fd30803 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -84,6 +84,11 @@ suite('Scrolling into view', function () { return Blockly.getFocusManager().getFocusedNode()?.getFocusableElement()?.id; }); console.log("current focused node after insert:", focusedNodeId2); + const scrollPosition3 = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + return [workspace.scrollX, workspace.scrollY]; + }); + console.log("workspace scroll position after insert:", scrollPosition3); // Assert new block has been scrolled into the viewport. await this.browser.pause(PAUSE_TIME); From c82a4866d326fba98a068413a7072989034413d6 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 02:16:46 +0000 Subject: [PATCH 23/32] chore: More logs. --- test/webdriverio/test/scroll_test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index 2fd30803..e558210f 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -50,6 +50,12 @@ suite('Scrolling into view', function () { await sendKeyAndWait(this.browser, 'm'); await sendKeyAndWait(this.browser, [Key.Alt, Key.ArrowDown], 25); await sendKeyAndWait(this.browser, Key.Enter); + const movedBlockBounds = await this.browser.execute(() => { + const block = Blockly.getFocusManager().getFocusedNode() as Blockly.BlockSvg; + const blockBounds = block.getBoundingRectangleWithoutChildren(); + return blockBounds; + }); + console.log("just moved block bounds:", movedBlockBounds); // Scroll back up, leaving cursor on the draw block out of the viewport. const scrollPosition1 = await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; From 4fb876cd737bde53099c552a916a42946f7d67b3 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 02:23:41 +0000 Subject: [PATCH 24/32] chore: More logs. --- test/webdriverio/test/scroll_test.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index e558210f..7685e408 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -107,6 +107,15 @@ suite('Scrolling into view', function () { return blockBounds; }); console.log("block bounds:", blockBounds); + const [blockParentBounds, blockParentId] = await this.browser.execute(() => { + const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; + const block = workspace.getBlocksByType( + 'controls_if', + )[0] as Blockly.BlockSvg; + const blockBounds = block.getParent()?.getBoundingRectangleWithoutChildren(); + return [blockBounds, block.getParent()?.getFocusableElement()?.id]; + }); + console.log("block's parent bounds:", blockParentBounds, "id:", blockParentId); const viewport = await this.browser.execute(() => { const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg; const rawViewport = workspace.getMetricsManager().getViewMetrics(true); From 75a8bc820a3964b832e07e4f199c8d422b758b42 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 02:26:55 +0000 Subject: [PATCH 25/32] chore: Use correct parent. --- test/webdriverio/test/scroll_test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index 7685e408..2ab13f34 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -112,8 +112,8 @@ suite('Scrolling into view', function () { const block = workspace.getBlocksByType( 'controls_if', )[0] as Blockly.BlockSvg; - const blockBounds = block.getParent()?.getBoundingRectangleWithoutChildren(); - return [blockBounds, block.getParent()?.getFocusableElement()?.id]; + const blockBounds = block.getSurroundParent()?.getBoundingRectangleWithoutChildren(); + return [blockBounds, block.getSurroundParent()?.getFocusableElement()?.id]; }); console.log("block's parent bounds:", blockParentBounds, "id:", blockParentId); const viewport = await this.browser.execute(() => { From 4b4c84227a06ec33c1b2a9665f9d4e85659efaf0 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 02:32:13 +0000 Subject: [PATCH 26/32] chore: Try to 'jiggle' block. --- test/webdriverio/test/scroll_test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index 2ab13f34..fa5084e1 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -9,6 +9,7 @@ import * as chai from 'chai'; import {Key} from 'webdriverio'; import { sendKeyAndWait, + keyUp, keyDown, keyRight, PAUSE_TIME, @@ -85,7 +86,10 @@ suite('Scrolling into view', function () { // Insert and confirm the test block which should be scrolled into view. await sendKeyAndWait(this.browser, 't'); await keyRight(this.browser); - await sendKeyAndWait(this.browser, Key.Enter, 2); + await sendKeyAndWait(this.browser, Key.Enter); + await keyDown(this.browser); + await keyUp(this.browser); + await sendKeyAndWait(this.browser, Key.Enter); const focusedNodeId2 = await this.browser.execute(() => { return Blockly.getFocusManager().getFocusedNode()?.getFocusableElement()?.id; }); From 2cc74788415faef21640e150953ec4df10d40a3b Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 02:41:32 +0000 Subject: [PATCH 27/32] chore: Try using pause time. --- test/webdriverio/test/test_setup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/webdriverio/test/test_setup.ts b/test/webdriverio/test/test_setup.ts index 8c91f34d..735141ec 100644 --- a/test/webdriverio/test/test_setup.ts +++ b/test/webdriverio/test/test_setup.ts @@ -42,7 +42,7 @@ let driver: webdriverio.Browser | null = null; * the browser.wait* functions if you need your test to wait for * something to happen after sending input. */ -export const PAUSE_TIME = 0; +export const PAUSE_TIME = 10; /** * Start up WebdriverIO and load the test page. This should only be From 27b375fca063c65e5961f7d78aa7b37877467edf Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 03:18:15 +0000 Subject: [PATCH 28/32] feat: Record & upload test failures in CI. --- .github/workflows/test.yml | 13 ++++++++++--- package.json | 4 ++-- test/webdriverio/test/actions_test.ts | 5 +++++ test/webdriverio/test/basic_test.ts | 9 +++++++++ test/webdriverio/test/block_comment_test.ts | 5 +++++ test/webdriverio/test/clipboard_test.ts | 5 +++++ test/webdriverio/test/delete_test.ts | 5 +++++ test/webdriverio/test/duplicate_test.ts | 5 +++++ test/webdriverio/test/flyout_test.ts | 5 +++++ test/webdriverio/test/insert_test.ts | 9 +++++++++ test/webdriverio/test/keyboard_mode_test.ts | 5 +++++ test/webdriverio/test/move_test.ts | 13 +++++++++++++ test/webdriverio/test/mutator_test.ts | 5 +++++ test/webdriverio/test/scroll_test.ts | 5 +++++ test/webdriverio/test/stack_navigation.ts | 5 +++++ test/webdriverio/test/styling_test.ts | 5 +++++ test/webdriverio/test/test_setup.ts | 10 ++++++++++ test/webdriverio/test/toast_test.ts | 6 +++++- test/webdriverio/test/workspace_comment_test.ts | 5 +++++ 19 files changed, 118 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6bb40288..4867b2e1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -69,11 +69,18 @@ jobs: - name: Run tests (up to 50 times) run: | cd main/test/webdriverio/test - for i in $(seq 1 50); - do + #for i in $(seq 1 50); + #do echo "Attempt $i" npx mocha --timeout 30000 dist - done + #done + + - name: Upload test failure screenshots + if: always() + uses: actions/upload-artifact@v5 + with: + name: test-failure-screenshots + path: test/webdriverio/test/failures webdriverio_tests: name: WebdriverIO tests (against pinned v12) diff --git a/package.json b/package.json index 048710b0..af24bb5f 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "wdio:build": "npm run wdio:build:app && npm run wdio:build:tests", "wdio:build:app": "cd test/webdriverio && webpack", "wdio:build:tests": "tsc -p ./test/webdriverio/test/tsconfig.json", - "wdio:clean": "cd test/webdriverio/test && rm -rf dist", - "wdio:run": "npm run wdio:build && cd test/webdriverio/test && npx mocha dist", + "wdio:clean": "cd test/webdriverio/test && rm -rf dist && rm -rf failures", + "wdio:run": "npm run wdio:build && cd test/webdriverio/test && mkdir failures && npx mocha dist", "wdio:run:ci": "npm run wdio:build && cd test/webdriverio/test && npx mocha --timeout 30000 dist" }, "main": "./dist/index.js", diff --git a/test/webdriverio/test/actions_test.ts b/test/webdriverio/test/actions_test.ts index 56c5b85b..595401b5 100644 --- a/test/webdriverio/test/actions_test.ts +++ b/test/webdriverio/test/actions_test.ts @@ -20,6 +20,7 @@ import { sendKeyAndWait, keyRight, contextMenuItems, + checkForFailures, } from './test_setup.js'; const isDarwin = process.platform === 'darwin'; @@ -99,6 +100,10 @@ suite('Menus test', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Menu action via keyboard on block opens menu', async function () { // Navigate to draw_circle_1. await focusOnBlock(this.browser, 'draw_circle_1'); diff --git a/test/webdriverio/test/basic_test.ts b/test/webdriverio/test/basic_test.ts index 276f6835..3f77c3ab 100644 --- a/test/webdriverio/test/basic_test.ts +++ b/test/webdriverio/test/basic_test.ts @@ -22,6 +22,7 @@ import { keyRight, keyUp, keyDown, + checkForFailures, } from './test_setup.js'; import {Key} from 'webdriverio'; @@ -37,6 +38,10 @@ suite('Keyboard navigation on Blocks', function () { ); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Default workspace', async function () { const blockCount = await this.browser.execute(() => { return Blockly.getMainWorkspace().getAllBlocks(false).length; @@ -235,6 +240,10 @@ suite('Keyboard navigation on Fields', function () { ); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Up from first field selects block', async function () { await focusOnBlockField(this.browser, 'p5_canvas_1', 'WIDTH'); await this.browser.pause(PAUSE_TIME); diff --git a/test/webdriverio/test/block_comment_test.ts b/test/webdriverio/test/block_comment_test.ts index f4c50169..008d9058 100644 --- a/test/webdriverio/test/block_comment_test.ts +++ b/test/webdriverio/test/block_comment_test.ts @@ -14,6 +14,7 @@ import { testFileLocations, keyRight, PAUSE_TIME, + checkForFailures, } from './test_setup.js'; import {Key} from 'webdriverio'; @@ -34,6 +35,10 @@ suite('Block comment navigation', function () { }); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Activating a block comment icon focuses the comment', async function () { await focusOnBlock(this.browser, 'p5_canvas_1'); await keyRight(this.browser); diff --git a/test/webdriverio/test/clipboard_test.ts b/test/webdriverio/test/clipboard_test.ts index b204a2ee..8eb71de6 100644 --- a/test/webdriverio/test/clipboard_test.ts +++ b/test/webdriverio/test/clipboard_test.ts @@ -18,6 +18,7 @@ import { blockIsPresent, getFocusedBlockType, sendKeyAndWait, + checkForFailures, } from './test_setup.js'; import {Key, KeyAction, PointerAction, WheelAction} from 'webdriverio'; @@ -31,6 +32,10 @@ suite('Clipboard test', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Copy and paste while block selected', async function () { // Navigate to draw_circle_1. await focusOnBlock(this.browser, 'draw_circle_1'); diff --git a/test/webdriverio/test/delete_test.ts b/test/webdriverio/test/delete_test.ts index a379c273..f758805c 100644 --- a/test/webdriverio/test/delete_test.ts +++ b/test/webdriverio/test/delete_test.ts @@ -18,6 +18,7 @@ import { sendKeyAndWait, keyRight, focusOnBlockField, + checkForFailures, } from './test_setup.js'; import {Key} from 'webdriverio'; @@ -34,6 +35,10 @@ suite('Deleting Blocks', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Deleting block selects parent block', async function () { await focusOnBlock(this.browser, 'controls_if_2'); await this.browser.pause(PAUSE_TIME); diff --git a/test/webdriverio/test/duplicate_test.ts b/test/webdriverio/test/duplicate_test.ts index 879ef964..83c6aad4 100644 --- a/test/webdriverio/test/duplicate_test.ts +++ b/test/webdriverio/test/duplicate_test.ts @@ -15,6 +15,7 @@ import { testFileLocations, testSetup, sendKeyAndWait, + checkForFailures, } from './test_setup.js'; suite('Duplicate test', function () { @@ -27,6 +28,10 @@ suite('Duplicate test', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Duplicate block', async function () { // Navigate to draw_circle_1. await focusOnBlock(this.browser, 'draw_circle_1'); diff --git a/test/webdriverio/test/flyout_test.ts b/test/webdriverio/test/flyout_test.ts index 4e438f6d..efe5b9b8 100644 --- a/test/webdriverio/test/flyout_test.ts +++ b/test/webdriverio/test/flyout_test.ts @@ -20,6 +20,7 @@ import { getCurrentFocusNodeId, getCurrentFocusedBlockId, tabNavigateToToolbox, + checkForFailures, } from './test_setup.js'; suite('Toolbox and flyout test', function () { @@ -32,6 +33,10 @@ suite('Toolbox and flyout test', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Tab navigating to toolbox should open flyout', async function () { // Two tabs should navigate to the toolbox (initial element is skipped). await tabNavigateForward(this.browser); diff --git a/test/webdriverio/test/insert_test.ts b/test/webdriverio/test/insert_test.ts index 6517cb46..f22413c8 100644 --- a/test/webdriverio/test/insert_test.ts +++ b/test/webdriverio/test/insert_test.ts @@ -22,6 +22,7 @@ import { blockIsPresent, keyUp, tabNavigateToToolbox, + checkForFailures, } from './test_setup.js'; suite('Insert test', function () { @@ -34,6 +35,10 @@ suite('Insert test', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Insert and cancel with block selection', async function () { // Navigate to draw_circle_1. await focusOnBlock(this.browser, 'draw_circle_1'); @@ -148,6 +153,10 @@ suite('Insert test with more blocks', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Does not bump immovable input blocks on insert', async function () { // Focus the print block with a connected input block. Ordinarily, inserting // an input block would connect it to this block and bump its child, but diff --git a/test/webdriverio/test/keyboard_mode_test.ts b/test/webdriverio/test/keyboard_mode_test.ts index 1c0f4d8e..bf78b4f0 100644 --- a/test/webdriverio/test/keyboard_mode_test.ts +++ b/test/webdriverio/test/keyboard_mode_test.ts @@ -15,6 +15,7 @@ import { tabNavigateToWorkspace, clickBlock, sendKeyAndWait, + checkForFailures, } from './test_setup.js'; import {Key} from 'webdriverio'; @@ -48,6 +49,10 @@ suite( await tabNavigateToWorkspace(this.browser); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('T to open toolbox enables keyboard mode', async function () { await this.browser.pause(PAUSE_TIME); await sendKeyAndWait(this.browser, 't'); diff --git a/test/webdriverio/test/move_test.ts b/test/webdriverio/test/move_test.ts index 132a26ec..03de6334 100644 --- a/test/webdriverio/test/move_test.ts +++ b/test/webdriverio/test/move_test.ts @@ -16,6 +16,7 @@ import { sendKeyAndWait, keyDown, contextMenuItems, + checkForFailures, } from './test_setup.js'; suite.skip('Move start tests', function () { @@ -32,6 +33,10 @@ suite.skip('Move start tests', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + // When a move of a statement block begins, it is expected that only // that block (and all blocks connected to its inputs) will be // moved, with subsequent statement blocks below it in the stack @@ -194,6 +199,10 @@ suite('Statement move tests', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + /** Serialized simple statement block with no statement inputs. */ const STATEMENT_SIMPLE = { type: 'draw_emoji', @@ -477,6 +486,10 @@ suite(`Value expression move tests`, function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + suite('Constrained moves of a simple reporter block', function () { setup(async function () { await appendBlock(this.browser, VALUE_SIMPLE, 'join0', 'ADD0'); diff --git a/test/webdriverio/test/mutator_test.ts b/test/webdriverio/test/mutator_test.ts index b604c752..df087dda 100644 --- a/test/webdriverio/test/mutator_test.ts +++ b/test/webdriverio/test/mutator_test.ts @@ -17,6 +17,7 @@ import { sendKeyAndWait, keyRight, keyDown, + checkForFailures, } from './test_setup.js'; import {Key} from 'webdriverio'; @@ -40,6 +41,10 @@ suite('Mutator navigation', function () { }; }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Enter opens mutator', async function () { await this.openMutator(); diff --git a/test/webdriverio/test/scroll_test.ts b/test/webdriverio/test/scroll_test.ts index fa5084e1..a972cb93 100644 --- a/test/webdriverio/test/scroll_test.ts +++ b/test/webdriverio/test/scroll_test.ts @@ -16,6 +16,7 @@ import { tabNavigateToWorkspace, testFileLocations, testSetup, + checkForFailures, } from './test_setup.js'; suite('Scrolling into view', function () { @@ -40,6 +41,10 @@ suite('Scrolling into view', function () { await testSetup(testFileLocations.BASE, this.timeout()); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Insert scrolls new block into view', async function () { // Increase timeout to 10s for this longer test. this.timeout(PAUSE_TIME ? 0 : 10000); diff --git a/test/webdriverio/test/stack_navigation.ts b/test/webdriverio/test/stack_navigation.ts index b26f273f..4034e7be 100644 --- a/test/webdriverio/test/stack_navigation.ts +++ b/test/webdriverio/test/stack_navigation.ts @@ -13,6 +13,7 @@ import { testFileLocations, testSetup, sendKeyAndWait, + checkForFailures, } from './test_setup.js'; suite('Stack navigation', function () { @@ -22,6 +23,10 @@ suite('Stack navigation', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Next', async function () { await tabNavigateToWorkspace(this.browser); chai.assert.equal( diff --git a/test/webdriverio/test/styling_test.ts b/test/webdriverio/test/styling_test.ts index 78a99018..08b9ab6e 100644 --- a/test/webdriverio/test/styling_test.ts +++ b/test/webdriverio/test/styling_test.ts @@ -14,6 +14,7 @@ import { tabNavigateToWorkspace, testFileLocations, testSetup, + checkForFailures, } from './test_setup.js'; import * as chai from 'chai'; @@ -27,6 +28,10 @@ suite('Styling test', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + async function strokeColorEquals( browser: WebdriverIO.Browser, selector: string, diff --git a/test/webdriverio/test/test_setup.ts b/test/webdriverio/test/test_setup.ts index 735141ec..53f2df2c 100644 --- a/test/webdriverio/test/test_setup.ts +++ b/test/webdriverio/test/test_setup.ts @@ -128,6 +128,16 @@ export async function testSetup( return driver; } +export async function checkForFailures( + browser: WebdriverIO.Browser, + testTitle: string, + testState: string | undefined +) { + if (testState === 'failed') { + await browser.saveScreenshot(`failures/${testTitle}.png`); + } +} + /** * Replaces OS-specific path with POSIX style path. * diff --git a/test/webdriverio/test/toast_test.ts b/test/webdriverio/test/toast_test.ts index d73ca3d6..de0c04e3 100644 --- a/test/webdriverio/test/toast_test.ts +++ b/test/webdriverio/test/toast_test.ts @@ -6,7 +6,7 @@ import * as chai from 'chai'; import * as Blockly from 'blockly/core'; -import {PAUSE_TIME, testFileLocations, testSetup} from './test_setup.js'; +import {PAUSE_TIME, testFileLocations, testSetup, checkForFailures} from './test_setup.js'; suite('HTML toasts', function () { // Disable timeouts when non-zero PAUSE_TIME is used to watch tests run. @@ -18,6 +18,10 @@ suite('HTML toasts', function () { await this.browser.pause(PAUSE_TIME); }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Can be displayed', async function () { const equal = await this.browser.execute(() => { const element = document.createElement('div'); diff --git a/test/webdriverio/test/workspace_comment_test.ts b/test/webdriverio/test/workspace_comment_test.ts index 7f1c3d8a..22ec5569 100644 --- a/test/webdriverio/test/workspace_comment_test.ts +++ b/test/webdriverio/test/workspace_comment_test.ts @@ -20,6 +20,7 @@ import { keyUp, contextMenuItems, PAUSE_TIME, + checkForFailures, } from './test_setup.js'; import {Key} from 'webdriverio'; @@ -69,6 +70,10 @@ suite('Workspace comment navigation', function () { }; }); + teardown(async function() { + await checkForFailures(this.browser, this.currentTest!.title, this.currentTest?.state); + }); + test('Navigate forward from block to workspace comment', async function () { await focusOnBlock(this.browser, 'p5_canvas_1'); await keyDown(this.browser); From ffed2d13d08f0b847527430eff4c24ae6eafb64d Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 03:23:29 +0000 Subject: [PATCH 29/32] chore: Remove pause timeout. --- test/webdriverio/test/test_setup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/webdriverio/test/test_setup.ts b/test/webdriverio/test/test_setup.ts index 53f2df2c..b857b11f 100644 --- a/test/webdriverio/test/test_setup.ts +++ b/test/webdriverio/test/test_setup.ts @@ -42,7 +42,7 @@ let driver: webdriverio.Browser | null = null; * the browser.wait* functions if you need your test to wait for * something to happen after sending input. */ -export const PAUSE_TIME = 10; +export const PAUSE_TIME = 0; /** * Start up WebdriverIO and load the test page. This should only be From b0ef7f9a32740a3f25cca29f55e820a98278edad Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 03:26:15 +0000 Subject: [PATCH 30/32] chore: Hopefully fix screenshots in CI. --- .github/workflows/test.yml | 4 +--- package.json | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4867b2e1..098a58af 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -64,15 +64,13 @@ jobs: run: | cd main npm run wdio:clean - npm run wdio:build - name: Run tests (up to 50 times) run: | - cd main/test/webdriverio/test #for i in $(seq 1 50); #do echo "Attempt $i" - npx mocha --timeout 30000 dist + npm run wdio:run:ci #done - name: Upload test failure screenshots diff --git a/package.json b/package.json index af24bb5f..543336ac 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "wdio:build:tests": "tsc -p ./test/webdriverio/test/tsconfig.json", "wdio:clean": "cd test/webdriverio/test && rm -rf dist && rm -rf failures", "wdio:run": "npm run wdio:build && cd test/webdriverio/test && mkdir failures && npx mocha dist", - "wdio:run:ci": "npm run wdio:build && cd test/webdriverio/test && npx mocha --timeout 30000 dist" + "wdio:run:ci": "npm run wdio:build && cd test/webdriverio/test && mkdir failures && npx mocha --timeout 30000 dist" }, "main": "./dist/index.js", "module": "./src/index.js", From c757c64a8c4cf2232eb2220a2b9e572253d7bdb2 Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 03:28:09 +0000 Subject: [PATCH 31/32] chore: Add missing 'cd'. --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 098a58af..2bfb3c43 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -67,6 +67,7 @@ jobs: - name: Run tests (up to 50 times) run: | + cd main #for i in $(seq 1 50); #do echo "Attempt $i" From cb6f91f20fad5868e6d23659a7e8d2db1071f6bb Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 21 Nov 2025 03:31:10 +0000 Subject: [PATCH 32/32] chore: Fix artifact path. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2bfb3c43..ef71ffd0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -79,7 +79,7 @@ jobs: uses: actions/upload-artifact@v5 with: name: test-failure-screenshots - path: test/webdriverio/test/failures + path: main/test/webdriverio/test/failures webdriverio_tests: name: WebdriverIO tests (against pinned v12)