[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

refactor!: remove webdriverio package (#10675)

authored by

Vladimir and committed by
GitHub
(Jun 30, 2026, 11:06 AM +0900) 5fed68f7 d20aa66b

+510 -3690
+1 -1
AGENTS.md
··· 33 33 - **Examples**: `CI=true pnpm test:examples` 34 34 - **Specific test suite**: `CI=true cd test/<test-folder> && pnpm test <test-file>` 35 35 - **Unit directory test**: `CI=true pnpm test <test-file>` (for `test/unit`) 36 - - **Browser tests**: `CI=true pnpm test:browser:playwright` or `CI=true pnpm test:browser:webdriverio` 36 + - **Browser tests**: `CI=true pnpm test:browser:playwright` 37 37 38 38 **IMPORTANT: Do NOT use `--` when passing test filters to pnpm.** 39 39 Using `--` causes pnpm to drop the filter, resulting in a full test run instead of a filtered one.
-1
package.json
··· 36 36 "ui:dev": "npm -C packages/ui run dev:client", 37 37 "ui:test": "npm -C packages/ui run test:run", 38 38 "override-vite7": "yq -i '.overrides.vite = \"npm:vite@7\"' pnpm-workspace.yaml", 39 - "test:browser:webdriverio": "pnpm -C test/browser run test:webdriverio", 40 39 "test:browser:playwright": "pnpm -C test/browser run test:playwright" 41 40 }, 42 41 "devDependencies": {
+447 -390
pnpm-lock.yaml
··· 180 180 '@vitest/browser': workspace:* 181 181 '@vitest/browser-playwright': workspace:* 182 182 '@vitest/browser-preview': workspace:* 183 - '@vitest/browser-webdriverio': workspace:* 184 183 '@vitest/ui': workspace:* 185 184 acorn: 8.11.3 186 185 mlly: ^1.8.0 ··· 632 631 specifier: workspace:* 633 632 version: link:../vitest 634 633 635 - packages/browser-webdriverio: 636 - dependencies: 637 - '@vitest/browser': 638 - specifier: workspace:* 639 - version: link:../browser 640 - devDependencies: 641 - '@wdio/types': 642 - specifier: ^9.24.0 643 - version: 9.24.0 644 - vitest: 645 - specifier: workspace:* 646 - version: link:../vitest 647 - webdriverio: 648 - specifier: ^9.20.0 649 - version: 9.20.0 650 - 651 634 packages/coverage-istanbul: 652 635 dependencies: 653 636 '@babel/core': ··· 925 908 '@vitest/browser-preview': 926 909 specifier: workspace:* 927 910 version: link:../browser-preview 928 - '@vitest/browser-webdriverio': 929 - specifier: workspace:* 930 - version: link:../browser-webdriverio 931 911 '@vueuse/core': 932 912 specifier: 'catalog:' 933 913 version: 14.2.1(vue@3.5.29(typescript@5.9.3)) ··· 1026 1006 specifier: workspace:* 1027 1007 version: link:../browser-preview 1028 1008 '@vitest/browser-webdriverio': 1029 - specifier: workspace:* 1030 - version: link:../browser-webdriverio 1009 + specifier: ^5.0.0-beta.5 || >=5.0.0 1010 + version: 5.0.0-beta.5(vitest@packages+vitest)(webdriverio@9.29.1) 1031 1011 '@vitest/coverage-istanbul': 1032 1012 specifier: workspace:* 1033 1013 version: link:../coverage-istanbul ··· 1213 1193 '@vitest/browser-preview': 1214 1194 specifier: workspace:* 1215 1195 version: link:../../packages/browser-preview 1216 - '@vitest/browser-webdriverio': 1217 - specifier: workspace:* 1218 - version: link:../../packages/browser-webdriverio 1219 1196 '@vitest/bundled-lib': 1220 1197 specifier: link:./bundled-lib 1221 1198 version: link:bundled-lib ··· 1360 1337 '@vitest/browser-preview': 1361 1338 specifier: workspace:* 1362 1339 version: link:../../packages/browser-preview 1363 - '@vitest/browser-webdriverio': 1364 - specifier: workspace:* 1365 - version: link:../../packages/browser-webdriverio 1366 1340 '@vitest/mocker': 1367 1341 specifier: workspace:* 1368 1342 version: link:../../packages/mocker ··· 3421 3395 resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} 3422 3396 engines: {node: ^14.21.3 || >=16} 3423 3397 3398 + '@nodable/entities@2.2.0': 3399 + resolution: {integrity: sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==} 3400 + 3424 3401 '@one-ini/wasm@0.1.1': 3425 3402 resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} 3426 3403 ··· 4536 4513 '@polka/url@1.0.0-next.24': 4537 4514 resolution: {integrity: sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==} 4538 4515 4539 - '@promptbook/utils@0.63.4': 4540 - resolution: {integrity: sha512-ME3I9Twxu/d7hpnGTkNYMUyIY8IAwY5Mg86i4xpD1WSZKfYMTNQomvkyk2Fi33vZDu8NDwb6Quyd0zJ0T3xo9w==} 4516 + '@promptbook/utils@0.69.5': 4517 + resolution: {integrity: sha512-xm5Ti/Hp3o4xHrsK9Yy3MS6KbDxYbq485hDsFvxqaNA7equHLPdo8H8faTitTeb14QCDfLW4iwCxdVYu5sn6YQ==} 4541 4518 4542 4519 '@protobufjs/aspromise@1.1.2': 4543 4520 resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} ··· 4569 4546 '@protobufjs/utf8@1.1.0': 4570 4547 resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} 4571 4548 4572 - '@puppeteer/browsers@2.7.1': 4573 - resolution: {integrity: sha512-MK7rtm8JjaxPN7Mf1JdZIZKPD2Z+W7osvrC1vjpvfOX1K0awDIHYbNi89f7eotp7eMUn2shWnt03HwVbriXtKQ==} 4549 + '@puppeteer/browsers@2.13.2': 4550 + resolution: {integrity: sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==} 4574 4551 engines: {node: '>=18'} 4575 4552 hasBin: true 4576 4553 ··· 5775 5752 '@vitejs/test-dep-virtual@file:test/e2e/deps/test-dep-virtual': 5776 5753 resolution: {directory: test/e2e/deps/test-dep-virtual, type: directory} 5777 5754 5755 + '@vitest/browser-webdriverio@5.0.0-beta.5': 5756 + resolution: {integrity: sha512-NOrcI2gALhSyn4BmYChdqFoRALIcGVvocGxviQMzfeT00bkegREemPVY8BsUT+RwlkB7HEVqOHBVS/sKuI7qog==} 5757 + peerDependencies: 5758 + vitest: workspace:* 5759 + webdriverio: '*' 5760 + 5778 5761 '@vitest/cjs-lib@file:test/browser/cjs-lib': 5779 5762 resolution: {directory: test/browser/cjs-lib, type: directory} 5780 5763 ··· 6046 6029 peerDependencies: 6047 6030 vue: ^3.5.0 6048 6031 6049 - '@wdio/config@9.20.0': 6050 - resolution: {integrity: sha512-ggwd3EMsVj/LTcbYw2h+hma+/7fQ1cTXMuy9B5WTkLjDlOtbLjsqs9QLt4BLIo1cdsxvAw/UVpRVUuYy7rTmtQ==} 6032 + '@wdio/config@9.29.1': 6033 + resolution: {integrity: sha512-8IXDiRG9wUUnpU6M/uzsVqIHJD/7o4y9RaOU2Jh/OdRJP/7rxwfGsa24Bv486rnMGdghztkwLCBJWG0jbeEtfw==} 6051 6034 engines: {node: '>=18.20.0'} 6052 6035 6053 - '@wdio/logger@9.18.0': 6054 - resolution: {integrity: sha512-HdzDrRs+ywAqbXGKqe1i/bLtCv47plz4TvsHFH3j729OooT5VH38ctFn5aLXgECmiAKDkmH/A6kOq2Zh5DIxww==} 6036 + '@wdio/logger@9.29.1': 6037 + resolution: {integrity: sha512-0ZAEIo6PNyMIJPlOGkIgyOJUjcd0pC8/QHlVAAe1c91/IcjZ1X+k0yidXHaboJdN7dq1XPUacmhRdtua0U5EZg==} 6055 6038 engines: {node: '>=18.20.0'} 6056 6039 6057 - '@wdio/protocols@9.16.2': 6058 - resolution: {integrity: sha512-h3k97/lzmyw5MowqceAuY3HX/wGJojXHkiPXA3WlhGPCaa2h4+GovV2nJtRvknCKsE7UHA1xB5SWeI8MzloBew==} 6040 + '@wdio/protocols@9.29.1': 6041 + resolution: {integrity: sha512-NFlBQOA4zDb4D/ETpVMqDgbJyEqdhGRsJWybLOXG7PGlPwfcrfmTMHC1+Boq4KODgpwbhCmI9zIk2JQmGYIttQ==} 6059 6042 6060 6043 '@wdio/repl@9.16.2': 6061 6044 resolution: {integrity: sha512-FLTF0VL6+o5BSTCO7yLSXocm3kUnu31zYwzdsz4n9s5YWt83sCtzGZlZpt7TaTzb3jVUfxuHNQDTb8UMkCu0lQ==} 6062 6045 engines: {node: '>=18.20.0'} 6063 6046 6064 - '@wdio/types@9.20.0': 6065 - resolution: {integrity: sha512-zMmAtse2UMCSOW76mvK3OejauAdcFGuKopNRH7crI0gwKTZtvV89yXWRziz9cVXpFgfmJCjf9edxKFWdhuF5yw==} 6047 + '@wdio/types@9.29.1': 6048 + resolution: {integrity: sha512-jp8jgMv6TS35G96YzHZxw3PVN0Dz6xQ6tnMAicndAJ8Jt9AIXb0ywIse4TjaFywakO3dLoEhlyA3ZtR26vmt+w==} 6066 6049 engines: {node: '>=18.20.0'} 6067 6050 6068 - '@wdio/types@9.24.0': 6069 - resolution: {integrity: sha512-PYYunNl8Uq1r8YMJAK6ReRy/V/XIrCSyj5cpCtR5EqCL6heETOORFj7gt4uPnzidfgbtMBcCru0LgjjlMiH1UQ==} 6070 - engines: {node: '>=18.20.0'} 6071 - 6072 - '@wdio/utils@9.20.0': 6073 - resolution: {integrity: sha512-T1ze005kncUTocYImSBQc/FAVcOwP/vOU4MDJFgzz/RTcps600qcKX98sVdWM5/ukXCVkjOufWteDHIbX5/tEA==} 6051 + '@wdio/utils@9.29.1': 6052 + resolution: {integrity: sha512-jyt6b6FfdYwVbMISVhuyGC1xQGZj6xM03KhTHozH7a9/zu9b++94KRdT9HRbwX8zefjW0YeIC5+qWSIf7WWHZg==} 6074 6053 engines: {node: '>=18.20.0'} 6075 6054 6076 6055 '@yeger/debounce@2.0.17': 6077 6056 resolution: {integrity: sha512-wz9ARkGnY25yToyaZaCz887aRxsIg96uI/waBLkV/Qfh9/VHP+C6uAFpOg8FPba0KMS2QYo2dhCOqPvCoDigyA==} 6078 6057 6079 - '@zip.js/zip.js@2.7.57': 6080 - resolution: {integrity: sha512-BtonQ1/jDnGiMed6OkV6rZYW78gLmLswkHOzyMrMb+CAR7CZO8phOHO6c2qw6qb1g1betN7kwEHhhZk30dv+NA==} 6081 - engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=16.5.0'} 6058 + '@zip.js/zip.js@2.8.26': 6059 + resolution: {integrity: sha512-RQ4h9F6DOiHxpdocUDrOl6xBM+yOtz+LkUol47AVWcfebGBDpZ7w7Xvz9PS24JgXvLGiXXzSAfdCdVy1tPlaFA==} 6060 + engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=18.0.0'} 6082 6061 6083 6062 abbrev@2.0.0: 6084 6063 resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} ··· 6170 6149 anymatch@3.1.3: 6171 6150 resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 6172 6151 engines: {node: '>= 8'} 6152 + 6153 + anynum@1.0.1: 6154 + resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==} 6173 6155 6174 6156 appdata-path@1.0.0: 6175 6157 resolution: {integrity: sha512-ZbH3ezXfnT/YE3NdqduIt4lBV+H0ybvA2Qx3K76gIjQvh8gROpDFdDLpx6B1QJtW7zxisCbpTlCLhKqoR8cDBw==} ··· 6263 6245 axios@1.13.4: 6264 6246 resolution: {integrity: sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==} 6265 6247 6266 - b4a@1.6.4: 6267 - resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} 6248 + b4a@1.8.1: 6249 + resolution: {integrity: sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==} 6250 + peerDependencies: 6251 + react-native-b4a: '*' 6252 + peerDependenciesMeta: 6253 + react-native-b4a: 6254 + optional: true 6268 6255 6269 6256 babel-plugin-polyfill-corejs2@0.4.17: 6270 6257 resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==} ··· 6291 6278 resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} 6292 6279 engines: {node: 18 || 20 || >=22} 6293 6280 6294 - bare-events@2.4.2: 6295 - resolution: {integrity: sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==} 6281 + bare-events@2.9.1: 6282 + resolution: {integrity: sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==} 6283 + peerDependencies: 6284 + bare-abort-controller: '*' 6285 + peerDependenciesMeta: 6286 + bare-abort-controller: 6287 + optional: true 6296 6288 6297 - bare-fs@4.0.1: 6298 - resolution: {integrity: sha512-ilQs4fm/l9eMfWY2dY0WCIUplSUp7U0CT1vrqMg1MUdeZl4fypu5UP0XcDBK5WBQPJAKP1b7XEodISmekH/CEg==} 6299 - engines: {bare: '>=1.7.0'} 6289 + bare-fs@4.7.2: 6290 + resolution: {integrity: sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg==} 6291 + engines: {bare: '>=1.16.0'} 6292 + peerDependencies: 6293 + bare-buffer: '*' 6294 + peerDependenciesMeta: 6295 + bare-buffer: 6296 + optional: true 6300 6297 6301 - bare-os@3.4.0: 6302 - resolution: {integrity: sha512-9Ous7UlnKbe3fMi7Y+qh0DwAup6A1JkYgPnjvMDNOlmnxNRQvQ/7Nst+OnUQKzk0iAT0m9BisbDVp9gCv8+ETA==} 6303 - engines: {bare: '>=1.6.0'} 6298 + bare-os@3.9.2: 6299 + resolution: {integrity: sha512-h530JsrkYi8518ZfR57GHaLoI5YzXkGGEV0Y+mf4KYPBn4OnNajiznwkDq7FgE+Vnmyss9Utnzi44y7sowiAXA==} 6300 + engines: {bare: '>=1.14.0'} 6304 6301 6305 - bare-path@3.0.0: 6306 - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} 6302 + bare-path@3.0.1: 6303 + resolution: {integrity: sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==} 6307 6304 6308 - bare-stream@2.1.3: 6309 - resolution: {integrity: sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==} 6305 + bare-stream@2.13.3: 6306 + resolution: {integrity: sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==} 6307 + peerDependencies: 6308 + bare-abort-controller: '*' 6309 + bare-buffer: '*' 6310 + bare-events: '*' 6311 + peerDependenciesMeta: 6312 + bare-abort-controller: 6313 + optional: true 6314 + bare-buffer: 6315 + optional: true 6316 + bare-events: 6317 + optional: true 6318 + 6319 + bare-url@2.4.5: 6320 + resolution: {integrity: sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==} 6321 + 6322 + base64-js@1.5.1: 6323 + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} 6310 6324 6311 6325 baseline-browser-mapping@2.10.38: 6312 6326 resolution: {integrity: sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==} ··· 6317 6331 resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==} 6318 6332 hasBin: true 6319 6333 6320 - basic-ftp@5.0.3: 6321 - resolution: {integrity: sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==} 6334 + basic-ftp@5.3.1: 6335 + resolution: {integrity: sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==} 6322 6336 engines: {node: '>=10.0.0'} 6323 - deprecated: Security vulnerability fixed in 5.2.1, please upgrade 6324 6337 6325 6338 bidi-js@1.0.3: 6326 6339 resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} ··· 6379 6392 buffer-image-size@0.6.4: 6380 6393 resolution: {integrity: sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ==} 6381 6394 engines: {node: '>=4.0'} 6395 + 6396 + buffer@6.0.3: 6397 + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} 6382 6398 6383 6399 builtin-modules@5.0.0: 6384 6400 resolution: {integrity: sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==} ··· 6462 6478 resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 6463 6479 engines: {node: '>=10'} 6464 6480 6465 - chalk@5.3.0: 6466 - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} 6481 + chalk@5.6.2: 6482 + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} 6467 6483 engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} 6468 6484 6469 6485 change-case@5.4.4: ··· 6490 6506 cheerio-select@2.1.0: 6491 6507 resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} 6492 6508 6493 - cheerio@1.0.0: 6494 - resolution: {integrity: sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==} 6495 - engines: {node: '>=18.17'} 6509 + cheerio@1.2.0: 6510 + resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==} 6511 + engines: {node: '>=20.18.1'} 6496 6512 6497 6513 chokidar@3.6.0: 6498 6514 resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} ··· 6684 6700 resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} 6685 6701 engines: {node: '>=8'} 6686 6702 6687 - css-select@5.1.0: 6688 - resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} 6703 + css-select@5.2.2: 6704 + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} 6689 6705 6690 - css-shorthand-properties@1.1.1: 6691 - resolution: {integrity: sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A==} 6706 + css-shorthand-properties@1.1.2: 6707 + resolution: {integrity: sha512-C2AugXIpRGQTxaCW0N7n5jD/p5irUmCrwl03TrnMFBHDbdq44CFWR2zO7rK9xPN4Eo3pUxC4vQzQgbIpzrD1PQ==} 6692 6708 6693 6709 css-tree@3.1.0: 6694 6710 resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} ··· 6701 6717 css-value@0.0.1: 6702 6718 resolution: {integrity: sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==} 6703 6719 6704 - css-what@6.1.0: 6705 - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} 6720 + css-what@6.2.2: 6721 + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} 6706 6722 engines: {node: '>= 6'} 6707 6723 6708 6724 css.escape@1.5.1: ··· 6769 6785 resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} 6770 6786 engines: {node: '>=12'} 6771 6787 6772 - data-uri-to-buffer@4.0.1: 6773 - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} 6774 - engines: {node: '>= 12'} 6775 - 6776 - data-uri-to-buffer@5.0.1: 6777 - resolution: {integrity: sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg==} 6788 + data-uri-to-buffer@6.0.2: 6789 + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} 6778 6790 engines: {node: '>= 14'} 6779 6791 6780 6792 data-urls@6.0.0: ··· 6814 6826 supports-color: 6815 6827 optional: true 6816 6828 6817 - decamelize@6.0.0: 6818 - resolution: {integrity: sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==} 6829 + decamelize@6.0.1: 6830 + resolution: {integrity: sha512-G7Cqgaelq68XHJNGlZ7lrNQyhZGsFqpwtGFexqUv4IQdjKoSYF7ipZ9UuTJZUSQXFj/XaoBLuEVIVqr8EJngEQ==} 6819 6831 engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 6820 6832 6821 6833 decimal.js@10.6.0: ··· 6956 6968 resolution: {integrity: sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==} 6957 6969 engines: {node: '>=14.0.0'} 6958 6970 6959 - edgedriver@6.1.2: 6960 - resolution: {integrity: sha512-UvFqd/IR81iPyWMcxXbUNi+xKWR7JjfoHjfuwjqsj9UHQKn80RpQmS0jf+U25IPi+gKVPcpOSKm0XkqgGMq4zQ==} 6961 - engines: {node: '>=18.0.0'} 6971 + edgedriver@6.3.0: 6972 + resolution: {integrity: sha512-ggEQL+oEyIcM4nP2QC3AtCQ04o4kDNefRM3hja0odvlPSnsaxiruMxEZ93v3gDCKWYW6BXUr51PPradb+3nffw==} 6973 + engines: {node: '>=20.0.0'} 6962 6974 hasBin: true 6963 6975 6964 6976 editorconfig@1.0.4: ··· 6994 7006 resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} 6995 7007 engines: {node: '>= 0.8'} 6996 7008 6997 - encoding-sniffer@0.2.0: 6998 - resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==} 7009 + encoding-sniffer@0.2.1: 7010 + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} 6999 7011 7000 - end-of-stream@1.4.4: 7001 - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} 7012 + end-of-stream@1.4.5: 7013 + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} 7002 7014 7003 7015 enhanced-resolve@5.18.4: 7004 7016 resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} ··· 7310 7322 resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} 7311 7323 engines: {node: '>=6'} 7312 7324 7325 + events-universal@1.0.1: 7326 + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} 7327 + 7328 + events@3.3.0: 7329 + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} 7330 + engines: {node: '>=0.8.x'} 7331 + 7313 7332 execa@8.0.1: 7314 7333 resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} 7315 7334 engines: {node: '>=16.17'} ··· 7383 7402 fast-wrap-ansi@0.2.2: 7384 7403 resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} 7385 7404 7386 - fast-xml-parser@5.2.5: 7387 - resolution: {integrity: sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==} 7405 + fast-xml-builder@1.2.0: 7406 + resolution: {integrity: sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==} 7407 + 7408 + fast-xml-parser@5.9.3: 7409 + resolution: {integrity: sha512-brCNCeScma/kqa54J4PIDriSSSLssRkuYaUCpvHJulGc3HGI/xxKUCTDcYkAdqJsyb//ydpbxecjC3hB9+tb/g==} 7388 7410 hasBin: true 7389 7411 7390 7412 fastify@5.7.2: ··· 7407 7429 peerDependenciesMeta: 7408 7430 picomatch: 7409 7431 optional: true 7410 - 7411 - fetch-blob@3.2.0: 7412 - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} 7413 - engines: {node: ^12.20 || >= 14.13} 7414 7432 7415 7433 fflate@0.8.2: 7416 7434 resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} ··· 7490 7508 resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} 7491 7509 engines: {node: '>=0.4.x'} 7492 7510 7493 - formdata-polyfill@4.0.10: 7494 - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} 7495 - engines: {node: '>=12.20.0'} 7496 - 7497 7511 formidable@3.5.4: 7498 7512 resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==} 7499 7513 engines: {node: '>=14.0.0'} ··· 7505 7519 fresh@0.5.2: 7506 7520 resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} 7507 7521 engines: {node: '>= 0.6'} 7508 - 7509 - fs-extra@8.1.0: 7510 - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} 7511 - engines: {node: '>=6 <7 || >=8'} 7512 7522 7513 7523 fs-extra@9.1.0: 7514 7524 resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} ··· 7544 7554 fzf@0.5.2: 7545 7555 resolution: {integrity: sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==} 7546 7556 7547 - geckodriver@5.0.0: 7548 - resolution: {integrity: sha512-vn7TtQ3b9VMJtVXsyWtQQl1fyBVFhQy7UvJF96kPuuJ0or5THH496AD3eUyaDD11+EqCxH9t6V+EP9soZQk4YQ==} 7549 - engines: {node: '>=18.0.0'} 7557 + geckodriver@6.1.0: 7558 + resolution: {integrity: sha512-ZRXLa4ZaYTTgUO4Eefw+RsQCleugU2QLb1ME7qTYxxuRj51yAhfnXaItXNs5/vUzfIaDHuZ+YnSF005hfp07nQ==} 7559 + engines: {node: '>=20.0.0'} 7550 7560 hasBin: true 7551 7561 7552 7562 generator-function@2.0.1: ··· 7568 7578 get-own-enumerable-property-symbols@3.0.2: 7569 7579 resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} 7570 7580 7571 - get-port@7.0.0: 7572 - resolution: {integrity: sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==} 7581 + get-port@7.2.0: 7582 + resolution: {integrity: sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==} 7573 7583 engines: {node: '>=16'} 7574 7584 7575 7585 get-proto@1.0.1: ··· 7602 7612 get-tsconfig@4.13.0: 7603 7613 resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} 7604 7614 7605 - get-uri@6.0.1: 7606 - resolution: {integrity: sha512-7ZqONUVqaabogsYNWlYj0t3YZaL6dhuEueZXGF+/YVmf6dHmaFg8/6psJKqhx9QykIDKzpGcy2cn4oV4YC7V/Q==} 7615 + get-uri@6.0.5: 7616 + resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} 7607 7617 engines: {node: '>= 14'} 7608 7618 7609 7619 giget@1.2.3: ··· 7758 7768 htmlfy@0.8.1: 7759 7769 resolution: {integrity: sha512-xWROBw9+MEGwxpotll0h672KCaLrKKiCYzsyN8ZgL9cQbVumFnyvsk2JqiB9ELAV1GLj1GG/jxZUjV9OZZi/yQ==} 7760 7770 7761 - htmlparser2@9.1.0: 7762 - resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} 7771 + htmlparser2@10.1.0: 7772 + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} 7763 7773 7764 7774 http-deceiver@1.2.7: 7765 7775 resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} ··· 7806 7816 idb@7.1.1: 7807 7817 resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} 7808 7818 7819 + ieee754@1.2.1: 7820 + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} 7821 + 7809 7822 ignore@5.3.2: 7810 7823 resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} 7811 7824 engines: {node: '>= 4'} ··· 7824 7837 resolution: {integrity: sha512-OnGy+eYT7wVejH2XWgLRgbmzujhhVIATQH0ztIeRilwHBjTeG3pD+XnH3PKX0r9gJ0BuJmJ68q/oh9qgXnNDQg==} 7825 7838 engines: {node: '>=18'} 7826 7839 7827 - import-meta-resolve@4.0.0: 7828 - resolution: {integrity: sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==} 7840 + import-meta-resolve@4.2.0: 7841 + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} 7829 7842 7830 7843 imurmurhash@0.1.4: 7831 7844 resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} ··· 7856 7869 resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} 7857 7870 engines: {node: '>= 0.4'} 7858 7871 7859 - ip-address@9.0.5: 7860 - resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} 7872 + ip-address@10.2.0: 7873 + resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} 7861 7874 engines: {node: '>= 12'} 7862 7875 7863 7876 ipaddr.js@1.9.1: ··· 8033 8046 resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} 8034 8047 engines: {node: '>=18'} 8035 8048 8049 + is-unsafe@1.0.1: 8050 + resolution: {integrity: sha512-CLK2+VdgERgD96EYm5lUQssZYlRg2tkZnbsxZoacmSiRxiFJ4Nk4SzjCl+Ur+v3kXIY9dTIdb3IH22y1mZ56LA==} 8051 + 8036 8052 is-weakmap@2.0.2: 8037 8053 resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} 8038 8054 engines: {node: '>= 0.4'} ··· 8062 8078 isexe@2.0.0: 8063 8079 resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 8064 8080 8065 - isexe@3.1.1: 8066 - resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} 8067 - engines: {node: '>=16'} 8081 + isexe@4.0.0: 8082 + resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} 8083 + engines: {node: '>=20'} 8068 8084 8069 8085 istanbul-lib-coverage@3.2.2: 8070 8086 resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} ··· 8144 8160 resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} 8145 8161 hasBin: true 8146 8162 8147 - jsbn@1.1.0: 8148 - resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} 8149 - 8150 8163 jsdoc-type-pratt-parser@7.1.1: 8151 8164 resolution: {integrity: sha512-/2uqY7x6bsrpi3i9LVU6J89352C0rpMk0as8trXxCtvd4kPk1ke/Eyif6wqfSLvoNJqcDG9Vk4UsXgygzCt2xA==} 8152 8165 engines: {node: '>=20.0.0'} ··· 8200 8213 8201 8214 jsonc-parser@3.3.1: 8202 8215 resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} 8203 - 8204 - jsonfile@4.0.0: 8205 - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} 8206 8216 8207 8217 jsonfile@6.2.1: 8208 8218 resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} ··· 8411 8421 resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} 8412 8422 engines: {node: '>=14'} 8413 8423 8414 - locate-app@2.4.27: 8415 - resolution: {integrity: sha512-QCNcJic0ZEZwMNrOXEi1FkxAjnZ0FSf1vjsgJAdOtnRkmYQJWQoZRiO/xff2rT7PuG2f8BJpY4D5dZJIkP55hA==} 8424 + locate-app@2.5.0: 8425 + resolution: {integrity: sha512-xIqbzPMBYArJRmPGUZD9CzV9wOqmVtQnaAn3wrj3s6WYW0bQvPI7x+sPYUGmDTYMHefVK//zc6HEYZ1qnxIK+Q==} 8416 8426 8417 8427 locate-path@6.0.0: 8418 8428 resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} ··· 8445 8455 loglevel-plugin-prefix@0.8.4: 8446 8456 resolution: {integrity: sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==} 8447 8457 8448 - loglevel@1.8.1: 8449 - resolution: {integrity: sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==} 8458 + loglevel@1.9.2: 8459 + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} 8450 8460 engines: {node: '>= 0.6.0'} 8451 8461 8452 8462 long@5.3.2: ··· 8781 8791 mlly@1.8.0: 8782 8792 resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} 8783 8793 8794 + modern-tar@0.7.6: 8795 + resolution: {integrity: sha512-sweCIVXzx1aIGTCdzcMlSZt1h8k5Tmk08VNAuRk3IU28XamGiOH5ypi11g6De2CH7PhYqSSnGy2A/EFhbWnVKg==} 8796 + engines: {node: '>=18.0.0'} 8797 + 8784 8798 module-details-from-path@1.0.4: 8785 8799 resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} 8786 8800 ··· 8837 8851 resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} 8838 8852 engines: {node: '>= 0.6'} 8839 8853 8840 - netmask@2.0.2: 8841 - resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} 8854 + netmask@2.1.1: 8855 + resolution: {integrity: sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==} 8842 8856 engines: {node: '>= 0.4.0'} 8843 8857 8844 8858 node-addon-api@7.1.1: 8845 8859 resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} 8846 8860 8847 - node-domexception@1.0.0: 8848 - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} 8849 - engines: {node: '>=10.5.0'} 8850 - deprecated: Use your platform's native DOMException instead 8851 - 8852 8861 node-fetch-native@1.6.7: 8853 8862 resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} 8854 - 8855 - node-fetch@3.3.2: 8856 - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} 8857 - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 8858 8863 8859 8864 node-releases@2.0.27: 8860 8865 resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} ··· 9066 9071 resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 9067 9072 engines: {node: '>=8'} 9068 9073 9074 + path-expression-matcher@1.6.1: 9075 + resolution: {integrity: sha512-h7bxdzhHk8Knyc4Tj+jMaa7fEEoUJy7p1qtbVgkYg1Uhpe5Np5VuGXCRZnkZvU+Q42M1vStt0ifa3ueykRJPmQ==} 9076 + engines: {node: '>=14.0.0'} 9077 + 9069 9078 path-is-absolute@1.0.1: 9070 9079 resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 9071 9080 engines: {node: '>=0.10.0'} ··· 9231 9240 process-warning@5.0.0: 9232 9241 resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} 9233 9242 9243 + process@0.11.10: 9244 + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} 9245 + engines: {node: '>= 0.6.0'} 9246 + 9234 9247 progress@2.0.3: 9235 9248 resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} 9236 9249 engines: {node: '>=0.4.0'} ··· 9264 9277 proxy-from-env@1.1.0: 9265 9278 resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} 9266 9279 9267 - pump@3.0.0: 9268 - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} 9280 + pump@3.0.4: 9281 + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} 9269 9282 9270 9283 punycode.js@2.3.1: 9271 9284 resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} ··· 9298 9311 9299 9312 query-selector-shadow-dom@1.0.1: 9300 9313 resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==} 9301 - 9302 - queue-tick@1.0.1: 9303 - resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} 9304 9314 9305 9315 quick-format-unescaped@4.0.4: 9306 9316 resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} ··· 9352 9362 resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} 9353 9363 engines: {node: '>= 6'} 9354 9364 9355 - readable-stream@4.1.0: 9356 - resolution: {integrity: sha512-sVisi3+P2lJ2t0BPbpK629j8wRW06yKGJUcaLAGXPAUhyUxVJm7VsCTit1PFgT4JHUDMrGNR+ZjSKpzGaRF3zw==} 9365 + readable-stream@4.7.0: 9366 + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} 9357 9367 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 9358 9368 9359 - readdir-glob@1.1.2: 9360 - resolution: {integrity: sha512-6RLVvwJtVwEDfPdn6X6Ille4/lxGl0ATOY4FN/B9nxQcgOazvvI0nodiD19ScKq0PvA/29VpaOQML36o5IzZWA==} 9369 + readdir-glob@1.1.3: 9370 + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} 9361 9371 9362 9372 readdirp@3.6.0: 9363 9373 resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} ··· 9533 9543 rxjs@7.8.2: 9534 9544 resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} 9535 9545 9536 - safaridriver@1.0.0: 9537 - resolution: {integrity: sha512-J92IFbskyo7OYB3Dt4aTdyhag1GlInrfbPCmMteb7aBK7PwlnGz1HI0+oyNN97j7pV9DqUAVoVgkNRMrfY47mQ==} 9546 + safaridriver@1.0.1: 9547 + resolution: {integrity: sha512-jkg4434cYgtrIF2AeY/X0Wmd2W73cK5qIEFE3hDrrQenJH/2SDJIXGvPAigfvQTcE9+H31zkiNHbUqcihEiMRA==} 9538 9548 engines: {node: '>=18.0.0'} 9539 9549 9540 9550 safe-array-concat@1.1.4: ··· 9849 9859 resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} 9850 9860 engines: {node: '>= 14'} 9851 9861 9852 - socks@2.8.4: 9853 - resolution: {integrity: sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==} 9862 + socks@2.8.9: 9863 + resolution: {integrity: sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==} 9854 9864 engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} 9855 9865 9856 9866 sonic-boom@4.2.0: ··· 9879 9889 space-separated-tokens@2.0.2: 9880 9890 resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} 9881 9891 9882 - spacetrim@0.11.39: 9883 - resolution: {integrity: sha512-S/baW29azJ7py5ausQRE2S6uEDQnlxgMHOEEq4V770ooBDD1/9kZnxRcco/tjZYuDuqYXblCk/r3N13ZmvHZ2g==} 9892 + spacetrim@0.11.59: 9893 + resolution: {integrity: sha512-lLYsktklSRKprreOm7NXReW8YiX2VBjbgmXYEziOoGf/qsJqAEACaDvoTtUOycwjpaSh+bT8eu0KrJn7UNxiCg==} 9884 9894 9885 9895 spdx-compare@1.0.0: 9886 9896 resolution: {integrity: sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==} ··· 9929 9939 sprintf-js@1.0.3: 9930 9940 resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} 9931 9941 9932 - sprintf-js@1.1.3: 9933 - resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} 9934 - 9935 9942 ssim.js@3.5.0: 9936 9943 resolution: {integrity: sha512-Aj6Jl2z6oDmgYFFbQqK7fght19bXdOxY7Tj03nF+03M9gCBAjeIiO8/PlEGMfKDwYpw4q6iBqVq2YuREorGg/g==} 9937 9944 ··· 9959 9966 resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} 9960 9967 engines: {node: '>= 0.4'} 9961 9968 9962 - streamx@2.20.1: 9963 - resolution: {integrity: sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==} 9969 + streamx@2.28.0: 9970 + resolution: {integrity: sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw==} 9964 9971 9965 9972 strict-event-emitter@0.5.1: 9966 9973 resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} ··· 10037 10044 strip-literal@3.1.0: 10038 10045 resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} 10039 10046 10040 - strnum@2.1.1: 10041 - resolution: {integrity: sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==} 10047 + strnum@2.4.1: 10048 + resolution: {integrity: sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==} 10042 10049 10043 10050 subpackage@file:test/e2e/fixtures/conditions-subpackage: 10044 10051 resolution: {directory: test/e2e/fixtures/conditions-subpackage, type: directory} ··· 10096 10103 resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} 10097 10104 engines: {node: '>=6'} 10098 10105 10099 - tar-fs@3.0.8: 10100 - resolution: {integrity: sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==} 10106 + tar-fs@3.1.3: 10107 + resolution: {integrity: sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ==} 10101 10108 10102 - tar-stream@3.1.6: 10103 - resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} 10109 + tar-stream@3.2.0: 10110 + resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} 10104 10111 10105 10112 tar@6.2.0: 10106 10113 resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} 10107 10114 engines: {node: '>=10'} 10108 10115 deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me 10116 + 10117 + teex@1.0.1: 10118 + resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} 10109 10119 10110 10120 temp-dir@2.0.0: 10111 10121 resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} ··· 10141 10151 test-dep-simple@file:test/e2e/deps/dep-simple: 10142 10152 resolution: {directory: test/e2e/deps/dep-simple, type: directory} 10143 10153 10144 - text-decoder@1.1.1: 10145 - resolution: {integrity: sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==} 10154 + text-decoder@1.2.7: 10155 + resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} 10146 10156 10147 10157 thingies@2.5.0: 10148 10158 resolution: {integrity: sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==} ··· 10307 10317 resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} 10308 10318 engines: {node: '>=10'} 10309 10319 10310 - type-fest@2.13.0: 10311 - resolution: {integrity: sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==} 10312 - engines: {node: '>=12.20'} 10320 + type-fest@4.26.0: 10321 + resolution: {integrity: sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==} 10322 + engines: {node: '>=16'} 10313 10323 10314 10324 type-fest@4.41.0: 10315 10325 resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} ··· 10374 10384 undici-types@7.16.0: 10375 10385 resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} 10376 10386 10377 - undici@6.21.3: 10378 - resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} 10387 + undici@6.27.0: 10388 + resolution: {integrity: sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==} 10379 10389 engines: {node: '>=18.17'} 10380 10390 10381 10391 undici@7.25.0: ··· 10426 10436 10427 10437 unist-util-visit@5.0.0: 10428 10438 resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} 10429 - 10430 - universalify@0.1.2: 10431 - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} 10432 - engines: {node: '>= 4.0.0'} 10433 10439 10434 10440 universalify@2.0.1: 10435 10441 resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} ··· 10512 10518 resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} 10513 10519 engines: {node: '>= 0.4'} 10514 10520 10515 - urlpattern-polyfill@10.0.0: 10516 - resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} 10521 + urlpattern-polyfill@10.1.0: 10522 + resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} 10517 10523 10518 - userhome@1.0.0: 10519 - resolution: {integrity: sha512-ayFKY3H+Pwfy4W98yPdtH1VqH4psDeyW8lYYFzfecR9d6hqLpqhecktvYR3SEEXt7vG0S1JEpciI3g94pMErig==} 10524 + userhome@1.0.1: 10525 + resolution: {integrity: sha512-5cnLm4gseXjAclKowC4IjByaGsjtAoV6PrOQOljplNB54ReUYJP8HdAFq2muHinSDAh09PPX/uXDPfdxRHvuSA==} 10520 10526 engines: {node: '>= 0.8.0'} 10521 10527 10522 10528 util-deprecate@1.0.2: ··· 10740 10746 wbuf@1.7.3: 10741 10747 resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} 10742 10748 10743 - web-streams-polyfill@3.2.1: 10744 - resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} 10745 - engines: {node: '>= 8'} 10746 - 10747 - webdriver@9.20.0: 10748 - resolution: {integrity: sha512-Kk+AGV1xWLNHVpzUynQJDULMzbcO3IjXo3s0BzfC30OpGxhpaNmoazMQodhtv0Lp242Mb1VYXD89dCb4oAHc4w==} 10749 + webdriver@9.29.1: 10750 + resolution: {integrity: sha512-uhxYap3qQXC9H2V8SDr7vcy0blZETeri4goLwbw1TFq4EZHF1Dv503Zc0PAjfkNQJCD4/rzAyr07+EX72kx1pg==} 10749 10751 engines: {node: '>=18.20.0'} 10750 10752 10751 - webdriverio@9.20.0: 10752 - resolution: {integrity: sha512-cqaXfahTzCFaQLlk++feZaze6tAsW8OSdaVRgmOGJRII1z2A4uh4YGHtusTpqOiZAST7OBPqycOwfh01G/Ktbg==} 10753 + webdriverio@9.29.1: 10754 + resolution: {integrity: sha512-UIplAnvbjdE0tucHVR/8Uk0Y7rz72VaEx/s0Tq91fMdXm+m+Za16e+b5tObh4xEEfyCITODPfzgBva9rA+xApQ==} 10753 10755 engines: {node: '>=18.20.0'} 10754 10756 peerDependencies: 10755 10757 puppeteer-core: '>=22.x || <=24.x' ··· 10820 10822 engines: {node: '>= 8'} 10821 10823 hasBin: true 10822 10824 10823 - which@5.0.0: 10824 - resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} 10825 - engines: {node: ^18.17.0 || >=20.5.0} 10825 + which@6.0.1: 10826 + resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} 10827 + engines: {node: ^20.17.0 || >=22.9.0} 10826 10828 hasBin: true 10827 10829 10828 10830 why-is-node-running@2.3.0: ··· 10931 10933 xml-name-validator@5.0.0: 10932 10934 resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} 10933 10935 engines: {node: '>=18'} 10936 + 10937 + xml-naming@0.1.0: 10938 + resolution: {integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==} 10939 + engines: {node: '>=16.0.0'} 10934 10940 10935 10941 xmlchars@2.2.0: 10936 10942 resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} ··· 12758 12764 12759 12765 '@noble/hashes@1.8.0': {} 12760 12766 12767 + '@nodable/entities@2.2.0': {} 12768 + 12761 12769 '@one-ini/wasm@0.1.1': {} 12762 12770 12763 12771 '@open-draft/deferred-promise@2.2.0': {} ··· 13545 13553 13546 13554 '@polka/url@1.0.0-next.24': {} 13547 13555 13548 - '@promptbook/utils@0.63.4': 13556 + '@promptbook/utils@0.69.5': 13549 13557 dependencies: 13550 - spacetrim: 0.11.39 13558 + spacetrim: 0.11.59 13551 13559 13552 13560 '@protobufjs/aspromise@1.1.2': {} 13553 13561 ··· 13572 13580 13573 13581 '@protobufjs/utf8@1.1.0': {} 13574 13582 13575 - '@puppeteer/browsers@2.7.1': 13583 + '@puppeteer/browsers@2.13.2': 13576 13584 dependencies: 13577 13585 debug: 4.4.3 13578 13586 extract-zip: 2.0.1 13579 13587 progress: 2.0.3 13580 13588 proxy-agent: 6.5.0 13581 13589 semver: 7.8.5 13582 - tar-fs: 3.0.8 13590 + tar-fs: 3.1.3 13583 13591 yargs: 17.7.2 13584 13592 transitivePeerDependencies: 13593 + - bare-abort-controller 13594 + - bare-buffer 13595 + - react-native-b4a 13585 13596 - supports-color 13586 13597 13587 13598 '@quansync/fs@0.1.5': ··· 14745 14756 14746 14757 '@vitejs/test-dep-virtual@file:test/e2e/deps/test-dep-virtual': {} 14747 14758 14759 + '@vitest/browser-webdriverio@5.0.0-beta.5(vitest@packages+vitest)(webdriverio@9.29.1)': 14760 + dependencies: 14761 + '@vitest/browser': link:packages/browser 14762 + vitest: link:packages/vitest 14763 + webdriverio: 9.29.1 14764 + 14748 14765 '@vitest/cjs-lib@file:test/browser/cjs-lib': {} 14749 14766 14750 14767 '@vitest/eslint-plugin@1.6.20(@typescript-eslint/eslint-plugin@8.62.0(@typescript-eslint/parser@8.62.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)(vitest@packages+vitest)': ··· 15048 15065 dependencies: 15049 15066 vue: 3.5.29(typescript@5.9.3) 15050 15067 15051 - '@wdio/config@9.20.0': 15068 + '@wdio/config@9.29.1': 15052 15069 dependencies: 15053 - '@wdio/logger': 9.18.0 15054 - '@wdio/types': 9.20.0 15055 - '@wdio/utils': 9.20.0 15070 + '@wdio/logger': 9.29.1 15071 + '@wdio/types': 9.29.1 15072 + '@wdio/utils': 9.29.1 15056 15073 deepmerge-ts: 7.1.5 15057 15074 glob: 10.4.1 15058 - import-meta-resolve: 4.0.0 15075 + import-meta-resolve: 4.2.0 15059 15076 jiti: 2.6.1 15060 15077 transitivePeerDependencies: 15078 + - bare-abort-controller 15079 + - bare-buffer 15080 + - react-native-b4a 15061 15081 - supports-color 15062 15082 15063 - '@wdio/logger@9.18.0': 15083 + '@wdio/logger@9.29.1': 15064 15084 dependencies: 15065 - chalk: 5.3.0 15066 - loglevel: 1.8.1 15085 + chalk: 5.6.2 15086 + loglevel: 1.9.2 15067 15087 loglevel-plugin-prefix: 0.8.4 15068 15088 safe-regex2: 5.0.0 15069 15089 strip-ansi: 7.1.0 15070 15090 15071 - '@wdio/protocols@9.16.2': {} 15091 + '@wdio/protocols@9.29.1': {} 15072 15092 15073 15093 '@wdio/repl@9.16.2': 15074 15094 dependencies: 15075 15095 '@types/node': 24.12.0 15076 15096 15077 - '@wdio/types@9.20.0': 15097 + '@wdio/types@9.29.1': 15078 15098 dependencies: 15079 15099 '@types/node': 24.12.0 15080 15100 15081 - '@wdio/types@9.24.0': 15101 + '@wdio/utils@9.29.1': 15082 15102 dependencies: 15083 - '@types/node': 24.12.0 15084 - 15085 - '@wdio/utils@9.20.0': 15086 - dependencies: 15087 - '@puppeteer/browsers': 2.7.1 15088 - '@wdio/logger': 9.18.0 15089 - '@wdio/types': 9.20.0 15090 - decamelize: 6.0.0 15103 + '@puppeteer/browsers': 2.13.2 15104 + '@wdio/logger': 9.29.1 15105 + '@wdio/types': 9.29.1 15106 + decamelize: 6.0.1 15091 15107 deepmerge-ts: 7.1.5 15092 - edgedriver: 6.1.2 15093 - geckodriver: 5.0.0 15094 - get-port: 7.0.0 15095 - import-meta-resolve: 4.0.0 15096 - locate-app: 2.4.27 15108 + edgedriver: 6.3.0 15109 + geckodriver: 6.1.0 15110 + get-port: 7.2.0 15111 + import-meta-resolve: 4.2.0 15112 + locate-app: 2.5.0 15097 15113 mitt: 3.0.1 15098 - safaridriver: 1.0.0 15114 + safaridriver: 1.0.1 15099 15115 split2: 4.2.0 15100 15116 wait-port: 1.1.0 15101 15117 transitivePeerDependencies: 15118 + - bare-abort-controller 15119 + - bare-buffer 15120 + - react-native-b4a 15102 15121 - supports-color 15103 15122 15104 15123 '@yeger/debounce@2.0.17': {} 15105 15124 15106 - '@zip.js/zip.js@2.7.57': {} 15125 + '@zip.js/zip.js@2.8.26': {} 15107 15126 15108 15127 abbrev@2.0.0: {} 15109 15128 ··· 15181 15200 normalize-path: 3.0.0 15182 15201 picomatch: 2.3.2 15183 15202 15203 + anynum@1.0.1: {} 15204 + 15184 15205 appdata-path@1.0.0: {} 15185 15206 15186 15207 archiver-utils@5.0.2: ··· 15189 15210 graceful-fs: 4.2.11 15190 15211 is-stream: 2.0.1 15191 15212 lazystream: 1.0.1 15192 - lodash: 4.17.21 15213 + lodash: 4.18.1 15193 15214 normalize-path: 3.0.0 15194 - readable-stream: 4.1.0 15215 + readable-stream: 4.7.0 15195 15216 15196 15217 archiver@7.0.1: 15197 15218 dependencies: 15198 15219 archiver-utils: 5.0.2 15199 15220 async: 3.2.6 15200 15221 buffer-crc32: 1.0.0 15201 - readable-stream: 4.1.0 15202 - readdir-glob: 1.1.2 15203 - tar-stream: 3.1.6 15222 + readable-stream: 4.7.0 15223 + readdir-glob: 1.1.3 15224 + tar-stream: 3.2.0 15204 15225 zip-stream: 6.0.1 15226 + transitivePeerDependencies: 15227 + - bare-abort-controller 15228 + - bare-buffer 15229 + - react-native-b4a 15205 15230 15206 15231 are-docs-informative@0.0.2: {} 15207 15232 ··· 15289 15314 transitivePeerDependencies: 15290 15315 - debug 15291 15316 15292 - b4a@1.6.4: {} 15317 + b4a@1.8.1: {} 15293 15318 15294 15319 babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.7): 15295 15320 dependencies: ··· 15321 15346 15322 15347 balanced-match@4.0.4: {} 15323 15348 15324 - bare-events@2.4.2: 15325 - optional: true 15349 + bare-events@2.9.1: {} 15326 15350 15327 - bare-fs@4.0.1: 15351 + bare-fs@4.7.2: 15328 15352 dependencies: 15329 - bare-events: 2.4.2 15330 - bare-path: 3.0.0 15331 - bare-stream: 2.1.3 15332 - optional: true 15353 + bare-events: 2.9.1 15354 + bare-path: 3.0.1 15355 + bare-stream: 2.13.3(bare-events@2.9.1) 15356 + bare-url: 2.4.5 15357 + fast-fifo: 1.3.2 15358 + transitivePeerDependencies: 15359 + - bare-abort-controller 15360 + - react-native-b4a 15333 15361 15334 - bare-os@3.4.0: 15335 - optional: true 15362 + bare-os@3.9.2: {} 15336 15363 15337 - bare-path@3.0.0: 15364 + bare-path@3.0.1: 15338 15365 dependencies: 15339 - bare-os: 3.4.0 15340 - optional: true 15366 + bare-os: 3.9.2 15341 15367 15342 - bare-stream@2.1.3: 15368 + bare-stream@2.13.3(bare-events@2.9.1): 15343 15369 dependencies: 15344 - streamx: 2.20.1 15345 - optional: true 15370 + b4a: 1.8.1 15371 + streamx: 2.28.0 15372 + teex: 1.0.1 15373 + optionalDependencies: 15374 + bare-events: 2.9.1 15375 + transitivePeerDependencies: 15376 + - react-native-b4a 15377 + 15378 + bare-url@2.4.5: 15379 + dependencies: 15380 + bare-path: 3.0.1 15381 + 15382 + base64-js@1.5.1: {} 15346 15383 15347 15384 baseline-browser-mapping@2.10.38: {} 15348 15385 15349 15386 baseline-browser-mapping@2.9.11: {} 15350 15387 15351 - basic-ftp@5.0.3: {} 15388 + basic-ftp@5.3.1: {} 15352 15389 15353 15390 bidi-js@1.0.3: 15354 15391 dependencies: ··· 15421 15458 buffer-image-size@0.6.4: 15422 15459 dependencies: 15423 15460 '@types/node': 24.12.0 15461 + 15462 + buffer@6.0.3: 15463 + dependencies: 15464 + base64-js: 1.5.1 15465 + ieee754: 1.2.1 15424 15466 15425 15467 builtin-modules@5.0.0: {} 15426 15468 ··· 15527 15569 ansi-styles: 4.3.0 15528 15570 supports-color: 7.2.0 15529 15571 15530 - chalk@5.3.0: {} 15572 + chalk@5.6.2: {} 15531 15573 15532 15574 change-case@5.4.4: {} 15533 15575 ··· 15573 15615 cheerio-select@2.1.0: 15574 15616 dependencies: 15575 15617 boolbase: 1.0.0 15576 - css-select: 5.1.0 15577 - css-what: 6.1.0 15618 + css-select: 5.2.2 15619 + css-what: 6.2.2 15578 15620 domelementtype: 2.3.0 15579 15621 domhandler: 5.0.3 15580 15622 domutils: 3.2.2 15581 15623 15582 - cheerio@1.0.0: 15624 + cheerio@1.2.0: 15583 15625 dependencies: 15584 15626 cheerio-select: 2.1.0 15585 15627 dom-serializer: 2.0.0 15586 15628 domhandler: 5.0.3 15587 15629 domutils: 3.2.2 15588 - encoding-sniffer: 0.2.0 15589 - htmlparser2: 9.1.0 15630 + encoding-sniffer: 0.2.1 15631 + htmlparser2: 10.1.0 15590 15632 parse5: 7.3.0 15591 15633 parse5-htmlparser2-tree-adapter: 7.1.0 15592 15634 parse5-parser-stream: 7.1.2 15593 - undici: 6.21.3 15635 + undici: 7.25.0 15594 15636 whatwg-mimetype: 4.0.0 15595 15637 15596 15638 chokidar@3.6.0: ··· 15687 15729 crc32-stream: 6.0.0 15688 15730 is-stream: 2.0.1 15689 15731 normalize-path: 3.0.0 15690 - readable-stream: 4.1.0 15732 + readable-stream: 4.7.0 15691 15733 15692 15734 compressible@2.0.18: 15693 15735 dependencies: ··· 15758 15800 crc32-stream@6.0.0: 15759 15801 dependencies: 15760 15802 crc-32: 1.2.2 15761 - readable-stream: 4.1.0 15803 + readable-stream: 4.7.0 15762 15804 15763 15805 cross-spawn@7.0.6: 15764 15806 dependencies: ··· 15768 15810 15769 15811 crypto-random-string@2.0.0: {} 15770 15812 15771 - css-select@5.1.0: 15813 + css-select@5.2.2: 15772 15814 dependencies: 15773 15815 boolbase: 1.0.0 15774 - css-what: 6.1.0 15816 + css-what: 6.2.2 15775 15817 domhandler: 5.0.3 15776 15818 domutils: 3.2.2 15777 15819 nth-check: 2.1.1 15778 15820 15779 - css-shorthand-properties@1.1.1: {} 15821 + css-shorthand-properties@1.1.2: {} 15780 15822 15781 15823 css-tree@3.1.0: 15782 15824 dependencies: ··· 15790 15832 15791 15833 css-value@0.0.1: {} 15792 15834 15793 - css-what@6.1.0: {} 15835 + css-what@6.2.2: {} 15794 15836 15795 15837 css.escape@1.5.1: {} 15796 15838 ··· 15858 15900 d3-selection: 3.0.0 15859 15901 d3-transition: 3.0.1(d3-selection@3.0.0) 15860 15902 15861 - data-uri-to-buffer@4.0.1: {} 15862 - 15863 - data-uri-to-buffer@5.0.1: {} 15903 + data-uri-to-buffer@6.0.2: {} 15864 15904 15865 15905 data-urls@6.0.0: 15866 15906 dependencies: ··· 15900 15940 dependencies: 15901 15941 ms: 2.1.3 15902 15942 15903 - decamelize@6.0.0: {} 15943 + decamelize@6.0.1: {} 15904 15944 15905 15945 decimal.js@10.6.0: {} 15906 15946 ··· 16025 16065 '@types/which': 2.0.2 16026 16066 which: 2.0.2 16027 16067 16028 - edgedriver@6.1.2: 16068 + edgedriver@6.3.0: 16029 16069 dependencies: 16030 - '@wdio/logger': 9.18.0 16031 - '@zip.js/zip.js': 2.7.57 16032 - decamelize: 6.0.0 16070 + '@wdio/logger': 9.29.1 16071 + '@zip.js/zip.js': 2.8.26 16072 + decamelize: 6.0.1 16033 16073 edge-paths: 3.0.5 16034 - fast-xml-parser: 5.2.5 16074 + fast-xml-parser: 5.9.3 16035 16075 http-proxy-agent: 7.0.2 16036 16076 https-proxy-agent: 7.0.6 16037 - node-fetch: 3.3.2 16038 - which: 5.0.0 16077 + which: 6.0.1 16039 16078 transitivePeerDependencies: 16040 16079 - supports-color 16041 16080 ··· 16064 16103 16065 16104 encodeurl@1.0.2: {} 16066 16105 16067 - encoding-sniffer@0.2.0: 16106 + encoding-sniffer@0.2.1: 16068 16107 dependencies: 16069 16108 iconv-lite: 0.6.3 16070 16109 whatwg-encoding: 3.1.1 16071 16110 16072 - end-of-stream@1.4.4: 16111 + end-of-stream@1.4.5: 16073 16112 dependencies: 16074 16113 once: 1.4.0 16075 16114 ··· 16550 16589 16551 16590 event-target-shim@5.0.1: {} 16552 16591 16592 + events-universal@1.0.1: 16593 + dependencies: 16594 + bare-events: 2.9.1 16595 + transitivePeerDependencies: 16596 + - bare-abort-controller 16597 + 16598 + events@3.3.0: {} 16599 + 16553 16600 execa@8.0.1: 16554 16601 dependencies: 16555 16602 cross-spawn: 7.0.6 ··· 16674 16721 dependencies: 16675 16722 fast-string-width: 3.0.2 16676 16723 16677 - fast-xml-parser@5.2.5: 16724 + fast-xml-builder@1.2.0: 16678 16725 dependencies: 16679 - strnum: 2.1.1 16726 + path-expression-matcher: 1.6.1 16727 + xml-naming: 0.1.0 16728 + 16729 + fast-xml-parser@5.9.3: 16730 + dependencies: 16731 + '@nodable/entities': 2.2.0 16732 + fast-xml-builder: 1.2.0 16733 + is-unsafe: 1.0.1 16734 + path-expression-matcher: 1.6.1 16735 + strnum: 2.4.1 16736 + xml-naming: 0.1.0 16680 16737 16681 16738 fastify@5.7.2: 16682 16739 dependencies: ··· 16715 16772 fdir@6.5.0(picomatch@4.0.4): 16716 16773 optionalDependencies: 16717 16774 picomatch: 4.0.4 16718 - 16719 - fetch-blob@3.2.0: 16720 - dependencies: 16721 - node-domexception: 1.0.0 16722 - web-streams-polyfill: 3.2.1 16723 16775 16724 16776 fflate@0.8.2: {} 16725 16777 ··· 16802 16854 16803 16855 format@0.2.2: {} 16804 16856 16805 - formdata-polyfill@4.0.10: 16806 - dependencies: 16807 - fetch-blob: 3.2.0 16808 - 16809 16857 formidable@3.5.4: 16810 16858 dependencies: 16811 16859 '@paralleldrive/cuid2': 2.3.1 ··· 16815 16863 forwarded@0.2.0: {} 16816 16864 16817 16865 fresh@0.5.2: {} 16818 - 16819 - fs-extra@8.1.0: 16820 - dependencies: 16821 - graceful-fs: 4.2.11 16822 - jsonfile: 4.0.0 16823 - universalify: 0.1.2 16824 16866 16825 16867 fs-extra@9.1.0: 16826 16868 dependencies: ··· 16859 16901 16860 16902 fzf@0.5.2: {} 16861 16903 16862 - geckodriver@5.0.0: 16904 + geckodriver@6.1.0: 16863 16905 dependencies: 16864 - '@wdio/logger': 9.18.0 16865 - '@zip.js/zip.js': 2.7.57 16866 - decamelize: 6.0.0 16906 + '@wdio/logger': 9.29.1 16907 + '@zip.js/zip.js': 2.8.26 16908 + decamelize: 6.0.1 16867 16909 http-proxy-agent: 7.0.2 16868 16910 https-proxy-agent: 7.0.6 16869 - node-fetch: 3.3.2 16870 - tar-fs: 3.0.8 16871 - which: 5.0.0 16911 + modern-tar: 0.7.6 16872 16912 transitivePeerDependencies: 16873 16913 - supports-color 16874 16914 ··· 16893 16933 16894 16934 get-own-enumerable-property-symbols@3.0.2: {} 16895 16935 16896 - get-port@7.0.0: {} 16936 + get-port@7.2.0: {} 16897 16937 16898 16938 get-proto@1.0.1: 16899 16939 dependencies: ··· 16904 16944 16905 16945 get-stream@5.2.0: 16906 16946 dependencies: 16907 - pump: 3.0.0 16947 + pump: 3.0.4 16908 16948 16909 16949 get-stream@8.0.1: {} 16910 16950 ··· 16927 16967 dependencies: 16928 16968 resolve-pkg-maps: 1.0.0 16929 16969 16930 - get-uri@6.0.1: 16970 + get-uri@6.0.5: 16931 16971 dependencies: 16932 - basic-ftp: 5.0.3 16933 - data-uri-to-buffer: 5.0.1 16972 + basic-ftp: 5.3.1 16973 + data-uri-to-buffer: 6.0.2 16934 16974 debug: 4.4.3 16935 - fs-extra: 8.1.0 16936 16975 transitivePeerDependencies: 16937 16976 - supports-color 16938 16977 ··· 17117 17156 17118 17157 htmlfy@0.8.1: {} 17119 17158 17120 - htmlparser2@9.1.0: 17159 + htmlparser2@10.1.0: 17121 17160 dependencies: 17122 17161 domelementtype: 2.3.0 17123 17162 domhandler: 5.0.3 17124 17163 domutils: 3.2.2 17125 - entities: 4.5.0 17164 + entities: 7.0.1 17126 17165 17127 17166 http-deceiver@1.2.7: {} 17128 17167 ··· 17177 17216 17178 17217 idb@7.1.1: {} 17179 17218 17219 + ieee754@1.2.1: {} 17220 + 17180 17221 ignore@5.3.2: {} 17181 17222 17182 17223 ignore@7.0.5: {} ··· 17192 17233 cjs-module-lexer: 2.2.0 17193 17234 module-details-from-path: 1.0.4 17194 17235 17195 - import-meta-resolve@4.0.0: {} 17236 + import-meta-resolve@4.2.0: {} 17196 17237 17197 17238 imurmurhash@0.1.4: {} 17198 17239 ··· 17217 17258 hasown: 2.0.4 17218 17259 side-channel: 1.1.1 17219 17260 17220 - ip-address@9.0.5: 17221 - dependencies: 17222 - jsbn: 1.1.0 17223 - sprintf-js: 1.1.3 17261 + ip-address@10.2.0: {} 17224 17262 17225 17263 ipaddr.js@1.9.1: {} 17226 17264 ··· 17375 17413 17376 17414 is-unicode-supported@2.1.0: {} 17377 17415 17416 + is-unsafe@1.0.1: {} 17417 + 17378 17418 is-weakmap@2.0.2: {} 17379 17419 17380 17420 is-weakref@1.1.1: ··· 17398 17438 17399 17439 isexe@2.0.0: {} 17400 17440 17401 - isexe@3.1.1: {} 17441 + isexe@4.0.0: {} 17402 17442 17403 17443 istanbul-lib-coverage@3.2.2: {} 17404 17444 ··· 17484 17524 argparse: 1.0.10 17485 17525 esprima: 4.0.1 17486 17526 17487 - jsbn@1.1.0: {} 17488 - 17489 17527 jsdoc-type-pratt-parser@7.1.1: {} 17490 17528 17491 17529 jsdom@27.4.0(@noble/hashes@1.8.0): ··· 17566 17604 semver: 7.8.5 17567 17605 17568 17606 jsonc-parser@3.3.1: {} 17569 - 17570 - jsonfile@4.0.0: 17571 - optionalDependencies: 17572 - graceful-fs: 4.2.11 17573 17607 17574 17608 jsonfile@6.2.1: 17575 17609 dependencies: ··· 17741 17775 pkg-types: 2.3.0 17742 17776 quansync: 0.2.11 17743 17777 17744 - locate-app@2.4.27: 17778 + locate-app@2.5.0: 17745 17779 dependencies: 17746 - '@promptbook/utils': 0.63.4 17747 - type-fest: 2.13.0 17748 - userhome: 1.0.0 17780 + '@promptbook/utils': 0.69.5 17781 + type-fest: 4.26.0 17782 + userhome: 1.0.1 17749 17783 17750 17784 locate-path@6.0.0: 17751 17785 dependencies: ··· 17769 17803 17770 17804 loglevel-plugin-prefix@0.8.4: {} 17771 17805 17772 - loglevel@1.8.1: {} 17806 + loglevel@1.9.2: {} 17773 17807 17774 17808 long@5.3.2: {} 17775 17809 ··· 18303 18337 pkg-types: 1.3.1 18304 18338 ufo: 1.6.1 18305 18339 18340 + modern-tar@0.7.6: {} 18341 + 18306 18342 module-details-from-path@1.0.4: {} 18307 18343 18308 18344 module-replacements@2.11.0: {} ··· 18354 18390 18355 18391 negotiator@0.6.3: {} 18356 18392 18357 - netmask@2.0.2: {} 18393 + netmask@2.1.1: {} 18358 18394 18359 18395 node-addon-api@7.1.1: 18360 18396 optional: true 18361 18397 18362 - node-domexception@1.0.0: {} 18363 - 18364 18398 node-fetch-native@1.6.7: {} 18365 - 18366 - node-fetch@3.3.2: 18367 - dependencies: 18368 - data-uri-to-buffer: 4.0.1 18369 - fetch-blob: 3.2.0 18370 - formdata-polyfill: 4.0.10 18371 18399 18372 18400 node-releases@2.0.27: {} 18373 18401 ··· 18649 18677 '@tootallnate/quickjs-emscripten': 0.23.0 18650 18678 agent-base: 7.1.3 18651 18679 debug: 4.4.3 18652 - get-uri: 6.0.1 18680 + get-uri: 6.0.5 18653 18681 http-proxy-agent: 7.0.2 18654 18682 https-proxy-agent: 7.0.6 18655 18683 pac-resolver: 7.0.1 ··· 18660 18688 pac-resolver@7.0.1: 18661 18689 dependencies: 18662 18690 degenerator: 5.0.1 18663 - netmask: 2.0.2 18691 + netmask: 2.1.1 18664 18692 18665 18693 package-manager-detector@1.3.0: {} 18666 18694 ··· 18706 18734 path-browserify@1.0.1: {} 18707 18735 18708 18736 path-exists@4.0.0: {} 18737 + 18738 + path-expression-matcher@1.6.1: {} 18709 18739 18710 18740 path-is-absolute@1.0.1: {} 18711 18741 ··· 18850 18880 18851 18881 process-warning@5.0.0: {} 18852 18882 18883 + process@0.11.10: {} 18884 + 18853 18885 progress@2.0.3: {} 18854 18886 18855 18887 prompts@2.4.2: ··· 18911 18943 18912 18944 proxy-from-env@1.1.0: {} 18913 18945 18914 - pump@3.0.0: 18946 + pump@3.0.4: 18915 18947 dependencies: 18916 - end-of-stream: 1.4.4 18948 + end-of-stream: 1.4.5 18917 18949 once: 1.4.0 18918 18950 18919 18951 punycode.js@2.3.1: {} ··· 18939 18971 quansync@1.0.0: {} 18940 18972 18941 18973 query-selector-shadow-dom@1.0.1: {} 18942 - 18943 - queue-tick@1.0.1: {} 18944 18974 18945 18975 quick-format-unescaped@4.0.4: {} 18946 18976 ··· 18997 19027 string_decoder: 1.3.0 18998 19028 util-deprecate: 1.0.2 18999 19029 19000 - readable-stream@4.1.0: 19030 + readable-stream@4.7.0: 19001 19031 dependencies: 19002 19032 abort-controller: 3.0.0 19033 + buffer: 6.0.3 19034 + events: 3.3.0 19035 + process: 0.11.10 19036 + string_decoder: 1.3.0 19003 19037 19004 - readdir-glob@1.1.2: 19038 + readdir-glob@1.1.3: 19005 19039 dependencies: 19006 19040 minimatch: 5.1.9 19007 19041 ··· 19291 19325 dependencies: 19292 19326 tslib: 2.8.1 19293 19327 19294 - safaridriver@1.0.0: {} 19328 + safaridriver@1.0.1: {} 19295 19329 19296 19330 safe-array-concat@1.1.4: 19297 19331 dependencies: ··· 19651 19685 dependencies: 19652 19686 agent-base: 7.1.3 19653 19687 debug: 4.4.3 19654 - socks: 2.8.4 19688 + socks: 2.8.9 19655 19689 transitivePeerDependencies: 19656 19690 - supports-color 19657 19691 19658 - socks@2.8.4: 19692 + socks@2.8.9: 19659 19693 dependencies: 19660 - ip-address: 9.0.5 19694 + ip-address: 10.2.0 19661 19695 smart-buffer: 4.2.0 19662 19696 19663 19697 sonic-boom@4.2.0: ··· 19681 19715 19682 19716 space-separated-tokens@2.0.2: {} 19683 19717 19684 - spacetrim@0.11.39: {} 19718 + spacetrim@0.11.59: {} 19685 19719 19686 19720 spdx-compare@1.0.0: 19687 19721 dependencies: ··· 19746 19780 19747 19781 sprintf-js@1.0.3: {} 19748 19782 19749 - sprintf-js@1.1.3: {} 19750 - 19751 19783 ssim.js@3.5.0: {} 19752 19784 19753 19785 ssr-no-external-dep@file:test/e2e/deps/vite-ssr-resolve/ssr-no-external-dep: {} ··· 19767 19799 es-errors: 1.3.0 19768 19800 internal-slot: 1.1.0 19769 19801 19770 - streamx@2.20.1: 19802 + streamx@2.28.0: 19771 19803 dependencies: 19804 + events-universal: 1.0.1 19772 19805 fast-fifo: 1.3.2 19773 - queue-tick: 1.0.1 19774 - text-decoder: 1.1.1 19775 - optionalDependencies: 19776 - bare-events: 2.4.2 19806 + text-decoder: 1.2.7 19807 + transitivePeerDependencies: 19808 + - bare-abort-controller 19809 + - react-native-b4a 19777 19810 19778 19811 strict-event-emitter@0.5.1: {} 19779 19812 ··· 19874 19907 dependencies: 19875 19908 js-tokens: 9.0.1 19876 19909 19877 - strnum@2.1.1: {} 19910 + strnum@2.4.1: 19911 + dependencies: 19912 + anynum: 1.0.1 19878 19913 19879 19914 subpackage@file:test/e2e/fixtures/conditions-subpackage: {} 19880 19915 ··· 19934 19969 19935 19970 tapable@2.3.0: {} 19936 19971 19937 - tar-fs@3.0.8: 19972 + tar-fs@3.1.3: 19938 19973 dependencies: 19939 - pump: 3.0.0 19940 - tar-stream: 3.1.6 19974 + pump: 3.0.4 19975 + tar-stream: 3.2.0 19941 19976 optionalDependencies: 19942 - bare-fs: 4.0.1 19943 - bare-path: 3.0.0 19977 + bare-fs: 4.7.2 19978 + bare-path: 3.0.1 19979 + transitivePeerDependencies: 19980 + - bare-abort-controller 19981 + - bare-buffer 19982 + - react-native-b4a 19944 19983 19945 - tar-stream@3.1.6: 19984 + tar-stream@3.2.0: 19946 19985 dependencies: 19947 - b4a: 1.6.4 19986 + b4a: 1.8.1 19987 + bare-fs: 4.7.2 19948 19988 fast-fifo: 1.3.2 19949 - streamx: 2.20.1 19989 + streamx: 2.28.0 19990 + transitivePeerDependencies: 19991 + - bare-abort-controller 19992 + - bare-buffer 19993 + - react-native-b4a 19950 19994 19951 19995 tar@6.2.0: 19952 19996 dependencies: ··· 19956 20000 minizlib: 2.1.2 19957 20001 mkdirp: 1.0.4 19958 20002 yallist: 4.0.0 20003 + 20004 + teex@1.0.1: 20005 + dependencies: 20006 + streamx: 2.28.0 20007 + transitivePeerDependencies: 20008 + - bare-abort-controller 20009 + - react-native-b4a 19959 20010 19960 20011 temp-dir@2.0.0: {} 19961 20012 ··· 19991 20042 19992 20043 test-dep-simple@file:test/e2e/deps/dep-simple: {} 19993 20044 19994 - text-decoder@1.1.1: 20045 + text-decoder@1.2.7: 19995 20046 dependencies: 19996 - b4a: 1.6.4 20047 + b4a: 1.8.1 20048 + transitivePeerDependencies: 20049 + - react-native-b4a 19997 20050 19998 20051 thingies@2.5.0(tslib@2.8.1): 19999 20052 dependencies: ··· 20133 20186 20134 20187 type-fest@0.16.0: {} 20135 20188 20136 - type-fest@2.13.0: {} 20189 + type-fest@4.26.0: {} 20137 20190 20138 20191 type-fest@4.41.0: {} 20139 20192 ··· 20218 20271 20219 20272 undici-types@7.16.0: {} 20220 20273 20221 - undici@6.21.3: {} 20274 + undici@6.27.0: {} 20222 20275 20223 20276 undici@7.25.0: {} 20224 20277 ··· 20277 20330 '@types/unist': 3.0.2 20278 20331 unist-util-is: 6.0.0 20279 20332 unist-util-visit-parents: 6.0.1 20280 - 20281 - universalify@0.1.2: {} 20282 20333 20283 20334 universalify@2.0.1: {} 20284 20335 ··· 20385 20436 punycode: 1.4.1 20386 20437 qs: 6.14.0 20387 20438 20388 - urlpattern-polyfill@10.0.0: {} 20439 + urlpattern-polyfill@10.1.0: {} 20389 20440 20390 - userhome@1.0.0: {} 20441 + userhome@1.0.1: {} 20391 20442 20392 20443 util-deprecate@1.0.2: {} 20393 20444 ··· 20641 20692 dependencies: 20642 20693 minimalistic-assert: 1.0.1 20643 20694 20644 - web-streams-polyfill@3.2.1: {} 20645 - 20646 - webdriver@9.20.0: 20695 + webdriver@9.29.1: 20647 20696 dependencies: 20648 20697 '@types/node': 24.12.0 20649 20698 '@types/ws': 8.18.1 20650 - '@wdio/config': 9.20.0 20651 - '@wdio/logger': 9.18.0 20652 - '@wdio/protocols': 9.16.2 20653 - '@wdio/types': 9.20.0 20654 - '@wdio/utils': 9.20.0 20699 + '@wdio/config': 9.29.1 20700 + '@wdio/logger': 9.29.1 20701 + '@wdio/protocols': 9.29.1 20702 + '@wdio/types': 9.29.1 20703 + '@wdio/utils': 9.29.1 20655 20704 deepmerge-ts: 7.1.5 20656 20705 https-proxy-agent: 7.0.6 20657 - undici: 6.21.3 20706 + undici: 6.27.0 20658 20707 ws: 8.21.0 20659 20708 transitivePeerDependencies: 20709 + - bare-abort-controller 20710 + - bare-buffer 20660 20711 - bufferutil 20712 + - react-native-b4a 20661 20713 - supports-color 20662 20714 - utf-8-validate 20663 20715 20664 - webdriverio@9.20.0: 20716 + webdriverio@9.29.1: 20665 20717 dependencies: 20666 20718 '@types/node': 24.12.0 20667 20719 '@types/sinonjs__fake-timers': 8.1.5 20668 - '@wdio/config': 9.20.0 20669 - '@wdio/logger': 9.18.0 20670 - '@wdio/protocols': 9.16.2 20720 + '@wdio/config': 9.29.1 20721 + '@wdio/logger': 9.29.1 20722 + '@wdio/protocols': 9.29.1 20671 20723 '@wdio/repl': 9.16.2 20672 - '@wdio/types': 9.20.0 20673 - '@wdio/utils': 9.20.0 20724 + '@wdio/types': 9.29.1 20725 + '@wdio/utils': 9.29.1 20674 20726 archiver: 7.0.1 20675 20727 aria-query: 5.3.0 20676 - cheerio: 1.0.0 20677 - css-shorthand-properties: 1.1.1 20728 + cheerio: 1.2.0 20729 + css-shorthand-properties: 1.1.2 20678 20730 css-value: 0.0.1 20679 20731 grapheme-splitter: 1.0.4 20680 20732 htmlfy: 0.8.1 ··· 20686 20738 resq: 1.11.0 20687 20739 rgb2hex: 0.2.5 20688 20740 serialize-error: 12.0.0 20689 - urlpattern-polyfill: 10.0.0 20690 - webdriver: 9.20.0 20741 + urlpattern-polyfill: 10.1.0 20742 + webdriver: 9.29.1 20691 20743 transitivePeerDependencies: 20744 + - bare-abort-controller 20745 + - bare-buffer 20692 20746 - bufferutil 20747 + - react-native-b4a 20693 20748 - supports-color 20694 20749 - utf-8-validate 20695 20750 ··· 20775 20830 dependencies: 20776 20831 isexe: 2.0.0 20777 20832 20778 - which@5.0.0: 20833 + which@6.0.1: 20779 20834 dependencies: 20780 - isexe: 3.1.1 20835 + isexe: 4.0.0 20781 20836 20782 20837 why-is-node-running@2.3.0: 20783 20838 dependencies: ··· 20932 20987 20933 20988 xml-name-validator@5.0.0: {} 20934 20989 20990 + xml-naming@0.1.0: {} 20991 + 20935 20992 xmlchars@2.2.0: {} 20936 20993 20937 20994 y18n@5.0.8: {} ··· 20979 21036 dependencies: 20980 21037 archiver-utils: 5.0.2 20981 21038 compress-commons: 6.0.2 20982 - readable-stream: 4.1.0 21039 + readable-stream: 4.7.0 20983 21040 20984 21041 zone.js@0.15.1: {} 20985 21042
+7 -8
pnpm-workspace.yaml
··· 8 8 trustPolicyExclude: 9 9 - semver@6.3.1 10 10 - chokidar@4.0.3 11 - - webdriverio@9.20.0 12 - - webdriver@9.20.0 13 - - '@wdio/types@9.20.0' 11 + - webdriverio@9.29.1 12 + - webdriver@9.29.1 13 + - '@wdio/types@9.29.1' 14 14 - '@wdio/repl@9.16.2' 15 - - '@wdio/utils@9.20.0' 16 - - '@wdio/config@9.20.0' 17 - - '@wdio/logger@9.18.0' 18 - - '@wdio/protocols@9.16.2' 15 + - '@wdio/utils@9.29.1' 16 + - '@wdio/config@9.29.1' 17 + - '@wdio/logger@9.29.1' 18 + - '@wdio/protocols@9.29.1' 19 19 - undici-types@6.21.0 20 20 - undici@6.21.3 21 21 - rxjs@7.8.2 ··· 31 31 '@vitest/browser': workspace:* 32 32 '@vitest/browser-playwright': workspace:* 33 33 '@vitest/browser-preview': workspace:* 34 - '@vitest/browser-webdriverio': workspace:* 35 34 '@vitest/ui': workspace:* 36 35 acorn: 8.11.3 37 36 mlly: ^1.8.0
-21
.github/workflows/ci.yml
··· 109 109 with: 110 110 node-version: ${{ matrix.node_version }} 111 111 112 - - uses: ./.github/actions/setup-webdriverio 113 - id: setup-webdriverio 114 - with: 115 - firefox-version: false 116 - 117 112 - name: Install 118 113 run: pnpm i 119 114 ··· 179 174 with: 180 175 node-version: ${{ matrix.node_version }} 181 176 182 - - uses: ./.github/actions/setup-webdriverio 183 - id: setup-webdriverio 184 - with: 185 - firefox-version: false 186 - 187 177 - name: Install 188 178 run: pnpm i 189 179 ··· 220 210 with: 221 211 node-version: ${{ matrix.node_version }} 222 212 223 - - uses: ./.github/actions/setup-webdriverio 224 - id: setup-webdriverio 225 - 226 213 - name: Install 227 214 run: pnpm i 228 215 ··· 233 220 234 221 - name: Test Browser (playwright) 235 222 run: pnpm run test:browser:playwright 236 - 237 - - name: Test Browser (webdriverio) 238 - run: pnpm run test:browser:webdriverio 239 223 240 224 test-vite7: 241 225 needs: changed ··· 254 238 - uses: ./.github/actions/setup-and-cache 255 239 with: 256 240 node-version: 24 257 - 258 - - uses: ./.github/actions/setup-webdriverio 259 - id: setup-webdriverio 260 - with: 261 - firefox-version: false 262 241 263 242 - name: Install 264 243 run: |
-48
packages/browser-webdriverio/README.md
··· 1 - # @vitest/browser-webdriverio 2 - 3 - [![NPM version](https://img.shields.io/npm/v/@vitest/browser-webdriverio?color=a1b858&label=)](https://npmx.dev/package/@vitest/browser-webdriverio) 4 - 5 - Run your Vitest [browser tests](https://vitest.dev/guide/browser/) using [webdriverio](https://webdriver.io/docs/api/browser) API. Note that Vitest does not use webdriverio as a test runner, but only as a browser provider. 6 - 7 - We recommend using this package if you are already using webdriverio in your project. 8 - 9 - ## Installation 10 - 11 - Install the package with your favorite package manager: 12 - 13 - ```sh 14 - npm install -D @vitest/browser-webdriverio 15 - # or 16 - yarn add -D @vitest/browser-webdriverio 17 - # or 18 - pnpm add -D @vitest/browser-webdriverio 19 - ``` 20 - 21 - Then specify it in the `browser.provider` field of your Vitest configuration: 22 - 23 - ```ts 24 - // vitest.config.ts 25 - import { defineConfig } from 'vitest/config' 26 - import { webdriverio } from '@vitest/browser-webdriverio' 27 - 28 - export default defineConfig({ 29 - test: { 30 - browser: { 31 - provider: webdriverio({ 32 - // ...custom webdriverio options 33 - }), 34 - instances: [ 35 - { browser: 'chrome' }, 36 - ], 37 - }, 38 - }, 39 - }) 40 - ``` 41 - 42 - Then run Vitest in the browser mode: 43 - 44 - ```sh 45 - npx vitest --browser 46 - ``` 47 - 48 - [GitHub](https://github.com/vitest-dev/vitest/tree/main/packages/browser-webdriverio) | [Documentation](https://vitest.dev/config/browser/webdriverio)
-1
packages/browser-webdriverio/context.d.ts
··· 1 - export * from '@vitest/browser/context'
-65
packages/browser-webdriverio/package.json
··· 1 - { 2 - "name": "@vitest/browser-webdriverio", 3 - "type": "module", 4 - "version": "5.0.0-beta.5", 5 - "description": "Browser running for Vitest using webdriverio", 6 - "license": "MIT", 7 - "funding": "https://opencollective.com/vitest", 8 - "homepage": "https://vitest.dev/config/browser/webdriverio", 9 - "repository": { 10 - "type": "git", 11 - "url": "git+https://github.com/vitest-dev/vitest.git", 12 - "directory": "packages/browser-webdriverio" 13 - }, 14 - "bugs": { 15 - "url": "https://github.com/vitest-dev/vitest/issues" 16 - }, 17 - "keywords": [ 18 - "browser", 19 - "webdriverio", 20 - "wdio", 21 - "component", 22 - "mocks", 23 - "test", 24 - "testing" 25 - ], 26 - "sideEffects": false, 27 - "exports": { 28 - ".": { 29 - "types": "./dist/index.d.ts", 30 - "default": "./dist/index.js" 31 - }, 32 - "./context": { 33 - "types": "./context.d.ts" 34 - }, 35 - "./package.json": "./package.json" 36 - }, 37 - "main": "./dist/index.js", 38 - "module": "./dist/index.js", 39 - "types": "./dist/index.d.ts", 40 - "files": [ 41 - "context.d.ts", 42 - "dist" 43 - ], 44 - "scripts": { 45 - "build": "premove dist && pnpm rollup -c", 46 - "dev": "rollup -c --watch --watch.include 'src/**'" 47 - }, 48 - "peerDependencies": { 49 - "vitest": "workspace:*", 50 - "webdriverio": "*" 51 - }, 52 - "peerDependenciesMeta": { 53 - "webdriverio": { 54 - "optional": false 55 - } 56 - }, 57 - "dependencies": { 58 - "@vitest/browser": "workspace:*" 59 - }, 60 - "devDependencies": { 61 - "@wdio/types": "^9.24.0", 62 - "vitest": "workspace:*", 63 - "webdriverio": "^9.20.0" 64 - } 65 - }
-60
packages/browser-webdriverio/rollup.config.js
··· 1 - import { createRequire } from 'node:module' 2 - import commonjs from '@rollup/plugin-commonjs' 3 - import json from '@rollup/plugin-json' 4 - import resolve from '@rollup/plugin-node-resolve' 5 - import { defineConfig } from 'rollup' 6 - import oxc from 'unplugin-oxc/rollup' 7 - import { createDtsUtils } from '../../scripts/build-utils.js' 8 - 9 - const require = createRequire(import.meta.url) 10 - const pkg = require('./package.json') 11 - 12 - const external = [ 13 - ...Object.keys(pkg.dependencies), 14 - ...Object.keys(pkg.peerDependencies || {}), 15 - /^@?vitest(\/|$)/, 16 - ] 17 - 18 - const dtsUtils = createDtsUtils() 19 - 20 - const plugins = [ 21 - resolve({ 22 - preferBuiltins: true, 23 - }), 24 - json(), 25 - commonjs(), 26 - oxc({ 27 - transform: { target: 'node20' }, 28 - }), 29 - ] 30 - 31 - export default () => 32 - defineConfig([ 33 - { 34 - input: { 35 - index: './src/index.ts', 36 - locators: './src/locators.ts', 37 - }, 38 - output: { 39 - dir: 'dist', 40 - format: 'esm', 41 - }, 42 - external, 43 - context: 'null', 44 - plugins: [ 45 - ...dtsUtils.isolatedDecl(), 46 - ...plugins, 47 - ], 48 - }, 49 - { 50 - input: dtsUtils.dtsInput('src/index.ts'), 51 - output: { 52 - dir: 'dist', 53 - entryFileNames: '[name].d.ts', 54 - format: 'esm', 55 - }, 56 - watch: false, 57 - external, 58 - plugins: dtsUtils.dts(), 59 - }, 60 - ])
-13
packages/browser-webdriverio/tsconfig.json
··· 1 - { 2 - "extends": "../../tsconfig.base.json", 3 - "compilerOptions": { 4 - "types": ["node", "vite/client"], 5 - "isolatedDeclarations": true 6 - }, 7 - "exclude": [ 8 - "dist", 9 - "node_modules", 10 - "**/vite.config.ts", 11 - "src/client/**/*.ts" 12 - ] 13 - }
-1
packages/ui/package.json
··· 73 73 "@vitejs/plugin-vue": "catalog:", 74 74 "@vitest/browser-playwright": "workspace:*", 75 75 "@vitest/browser-preview": "workspace:*", 76 - "@vitest/browser-webdriverio": "workspace:*", 77 76 "@vueuse/core": "catalog:", 78 77 "ansi-to-html": "^0.7.2", 79 78 "birpc": "catalog:",
+4 -22
packages/ui/vitest.config.ts
··· 1 1 import { playwright } from '@vitest/browser-playwright' 2 2 import { preview } from '@vitest/browser-preview' 3 - import { webdriverio } from '@vitest/browser-webdriverio' 4 3 import { mergeConfig } from 'vite' 5 4 import { configDefaults, defineConfig } from 'vitest/config' 6 5 import viteConfig from './vite.config' 7 6 8 7 // known working set of tests for providers 9 8 // pnpm -C packages/ui test:ui 10 - // PROVIDER=webdriverio pnpm -C packages/ui test:ui SmallTab 11 9 // PROVIDER=preview pnpm -C packages/ui test:ui SmallTab -t access 12 10 13 11 const providerName = (process.env.PROVIDER || 'playwright') as 14 12 | 'playwright' 15 - | 'webdriverio' 16 13 | 'preview' 17 14 18 15 const testConfig = defineConfig({ ··· 42 39 provider: 43 40 providerName === 'preview' 44 41 ? preview() 45 - : providerName === 'webdriverio' 46 - ? webdriverio({ 47 - ...(process.env.CHROMEDRIVER_PATH && process.env.CHROME_BIN 48 - ? { 49 - 'wdio:chromedriverOptions': { 50 - binary: process.env.CHROMEDRIVER_PATH, 51 - }, 52 - 'capabilities': { 53 - 'goog:chromeOptions': { 54 - binary: process.env.CHROME_BIN, 55 - }, 56 - }, 57 - } 58 - : {}), 59 - }) 60 - : playwright({ 61 - actionTimeout: 5000, 62 - }), 63 - instances: [providerName === 'webdriverio' ? { browser: 'chrome' } : { browser: 'chromium' }], 42 + : playwright({ 43 + actionTimeout: 5000, 44 + }), 45 + instances: [{ browser: 'chromium' }], 64 46 }, 65 47 }, 66 48 })
+1 -1
packages/vitest/package.json
··· 120 120 "@types/node": "^22.0.0 || >=24.0.0", 121 121 "@vitest/browser-playwright": "workspace:*", 122 122 "@vitest/browser-preview": "workspace:*", 123 - "@vitest/browser-webdriverio": "workspace:*", 123 + "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0", 124 124 "@vitest/coverage-istanbul": "workspace:*", 125 125 "@vitest/coverage-v8": "workspace:*", 126 126 "@vitest/ui": "workspace:*",
+1 -1
test/browser/README.md
··· 14 14 pnpm run test-fixtures --root ./fixtures/locators 15 15 16 16 # run specific fixture with selected provider and browser 17 - PROVIDER=webdriverio TEST_BROWSER=firefox pnpm run test-fixtures --root ./fixtures/locators 17 + PROVIDER=playwright TEST_BROWSER=firefox pnpm run test-fixtures --root ./fixtures/locators 18 18 ``` 19 19 20 20 ## Using docker playwright
+1 -5
test/browser/package.json
··· 3 3 "type": "module", 4 4 "private": true, 5 5 "scripts": { 6 - "test": "pnpm run test:webdriverio && pnpm run test:playwright", 6 + "test": "pnpm run test:playwright", 7 7 "test:unit": "vitest --no-watch --config=vitest.config.unit.mts", 8 - "test:webdriverio": "PROVIDER=webdriverio pnpm run test:unit", 9 8 "test:playwright": "PROVIDER=playwright pnpm run test:unit", 10 - "test:safaridriver": "PROVIDER=webdriverio BROWSER=safari pnpm run test:unit", 11 9 "test-fixtures": "vitest", 12 10 "bench-fixtures": "vitest bench", 13 11 "test-expect-dom": "vitest --root ./fixtures/expect-dom", ··· 27 25 "coverage": "vitest --coverage.enabled --coverage.provider=istanbul --browser.headless=yes", 28 26 "test:browser:preview": "PROVIDER=preview vitest", 29 27 "test:browser:playwright": "PROVIDER=playwright vitest", 30 - "test:browser:webdriverio": "PROVIDER=webdriverio vitest", 31 28 "test:browser:playwright:html": "PROVIDER=playwright vitest --reporter=html", 32 29 "docker": "docker compose" 33 30 }, ··· 38 35 "@vitest/browser": "workspace:*", 39 36 "@vitest/browser-playwright": "workspace:*", 40 37 "@vitest/browser-preview": "workspace:*", 41 - "@vitest/browser-webdriverio": "workspace:*", 42 38 "@vitest/bundled-lib": "link:./bundled-lib", 43 39 "@vitest/cjs-lib": "link:./cjs-lib", 44 40 "playwright": "catalog:",
+3 -39
test/browser/settings.ts
··· 1 1 import type { BrowserInstanceOption } from 'vitest/node' 2 2 import { playwright } from '@vitest/browser-playwright' 3 3 import { preview } from '@vitest/browser-preview' 4 - import { webdriverio } from '@vitest/browser-webdriverio' 5 4 6 - const providerName = (process.env.PROVIDER || 'playwright') as 'playwright' | 'webdriverio' | 'preview' 5 + const providerName = (process.env.PROVIDER || 'playwright') as 'playwright' | 'preview' 7 6 8 7 const wsEndpoint = process.env.BROWSER_WS_ENDPOINT === 'true' ? 'ws://127.0.0.1:6677/' : process.env.BROWSER_WS_ENDPOINT 9 8 ··· 18 17 } 19 18 : options), 20 19 preview, 21 - webdriverio: (options?: Parameters<typeof webdriverio>[0]) => { 22 - const capabilities = options?.capabilities || {} 23 - 24 - return webdriverio({ 25 - ...options, 26 - capabilities: { 27 - ...capabilities, 28 - // Explicit browser/driver binaries keep WebDriverIO from auto-downloading mismatched versions. 29 - // https://webdriver.io/docs/driverbinaries 30 - // https://webdriver.io/docs/capabilities#webdriverio-capabilities-to-manage-browser-driver-options 31 - ...(process.env.CHROMEDRIVER_PATH && process.env.CHROME_BIN 32 - ? { 33 - 'wdio:chromedriverOptions': { 34 - ...(capabilities as any)['wdio:chromedriverOptions'], 35 - binary: process.env.CHROMEDRIVER_PATH, 36 - }, 37 - // https://developer.chrome.com/docs/chromedriver/capabilities#chromeoptions-object 38 - 'goog:chromeOptions': { 39 - ...(capabilities as any)['goog:chromeOptions'], 40 - binary: process.env.CHROME_BIN, 41 - }, 42 - } 43 - : {}), 44 - ...(process.env.FIREFOX_BIN 45 - ? { 46 - // https://developer.mozilla.org/en-US/docs/Web/WebDriver/Reference/Capabilities/firefoxOptions 47 - 'moz:firefoxOptions': { 48 - ...(capabilities as any)['moz:firefoxOptions'], 49 - binary: process.env.FIREFOX_BIN, 50 - }, 51 - } 52 - : {}), 53 - }, 54 - }) 55 - }, 56 20 } 57 21 58 22 export const provider = providers[providerName]() ··· 65 29 ...(process.env.BROWSER_NO_WEBKIT ? [] : [{ browser: 'webkit' as const }]), 66 30 ] 67 31 68 - const webdriverioInstances: BrowserInstanceOption[] = [ 32 + const previewInstances: BrowserInstanceOption[] = [ 69 33 { browser: 'chrome' }, 70 34 { browser: 'firefox' }, 71 35 ] ··· 85 49 ] 86 50 : provider.name === 'playwright' 87 51 ? playwrightInstances 88 - : webdriverioInstances 52 + : previewInstances
-1
test/e2e/package.json
··· 24 24 "@vitejs/test-dep-virtual": "file:./deps/test-dep-virtual", 25 25 "@vitest/browser-playwright": "workspace:*", 26 26 "@vitest/browser-preview": "workspace:*", 27 - "@vitest/browser-webdriverio": "workspace:*", 28 27 "@vitest/mocker": "workspace:*", 29 28 "@vitest/test-dep-optimizer-external": "file:./deps/optimizer/external", 30 29 "@vitest/test-dep-optimizer-optimized": "file:./deps/optimizer/optimized",
-65
.github/actions/setup-webdriverio/action.yml
··· 1 - name: Setup WebDriverIO Browsers 2 - description: Setup Chrome, ChromeDriver, and optional Firefox for WebDriverIO tests 3 - 4 - inputs: 5 - chrome-version: 6 - description: Chrome for Testing version to install, or false to skip 7 - # Pin to Chrome 148 while Chrome for Testing 149 Linux downloads/install are broken. 8 - default: '148' 9 - firefox-version: 10 - description: Firefox version to install, or false to skip 11 - default: latest 12 - 13 - runs: 14 - using: composite 15 - steps: 16 - - uses: browser-actions/setup-chrome@4f8e94349a351df0f048634f25fec36c3c91eded # v2.1.1 17 - if: inputs.chrome-version != 'false' 18 - id: setup-chrome 19 - with: 20 - chrome-version: ${{ inputs.chrome-version }} 21 - install-chromedriver: true 22 - 23 - - name: Export Chrome binaries 24 - if: inputs.chrome-version != 'false' 25 - shell: bash 26 - env: 27 - CHROME_PATH: ${{ steps.setup-chrome.outputs.chrome-path }} 28 - CHROMEDRIVER_PATH_VALUE: ${{ steps.setup-chrome.outputs.chromedriver-path }} 29 - run: | # zizmor: ignore[github-env] values come from pinned browser-actions/setup-chrome outputs. 30 - echo "CHROME_BIN=$CHROME_PATH" >> "$GITHUB_ENV" 31 - echo "CHROMEDRIVER_PATH=$CHROMEDRIVER_PATH_VALUE" >> "$GITHUB_ENV" 32 - 33 - - name: Allow setup-chrome sandbox 34 - if: inputs.chrome-version != 'false' && runner.os == 'Linux' 35 - shell: bash 36 - env: 37 - CHROME_PATH: ${{ steps.setup-chrome.outputs.chrome-path }} 38 - run: | 39 - # Chrome for Testing is not covered by Ubuntu's AppArmor sandbox policy on CI. 40 - # https://pptr.dev/troubleshooting#issues-with-apparmor-on-ubuntu 41 - # https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md 42 - # https://github.com/browser-actions/setup-chrome/issues/639 43 - cat <<EOF | sudo tee /etc/apparmor.d/chrome-for-testing 44 - abi <abi/4.0>, 45 - include <tunables/global> 46 - 47 - profile chrome-for-testing "$CHROME_PATH" flags=(unconfined) { 48 - userns, 49 - include if exists <local/chrome> 50 - } 51 - EOF 52 - sudo apparmor_parser -r /etc/apparmor.d/chrome-for-testing 53 - 54 - - uses: browser-actions/setup-firefox@fcf821c621167805dd63a29662bd7cb5676c81a8 # v1.7.1 55 - if: inputs.firefox-version != 'false' 56 - id: setup-firefox 57 - with: 58 - firefox-version: ${{ inputs.firefox-version }} 59 - 60 - - name: Export Firefox binary 61 - if: inputs.firefox-version != 'false' 62 - shell: bash 63 - env: 64 - FIREFOX_PATH: ${{ steps.setup-firefox.outputs.firefox-path }} 65 - run: echo "FIREFOX_BIN=$FIREFOX_PATH" >> "$GITHUB_ENV" # zizmor: ignore[github-env] value comes from pinned browser-actions/setup-firefox output.
+2 -2
docs/config/browser/webdriverio.md
··· 1 1 # Configuring WebdriverIO 2 2 3 - ::: info Playwright vs WebdriverIO 4 - If you do not already use WebdriverIO in your project, we recommend starting with [Playwright](/config/browser/playwright) as it is easier to configure and has more flexible API. 3 + ::: info Community maintained 4 + The WebdriverIO provider ([`@vitest/browser-webdriverio`](https://github.com/vitest-community/vitest-webdriverio)) is maintained by the Vitest community in the [`vitest-community`](https://github.com/vitest-community) organization, separately from the core Vitest packages. Please report provider-specific issues to its repository. 5 5 ::: 6 6 7 7 To run tests using WebdriverIO, you need to install the [`@vitest/browser-webdriverio`](https://npmx.dev/package/@vitest/browser-webdriverio) npm package and specify its `webdriverio` export in the `test.browser.provider` property of your config:
-5
packages/browser-webdriverio/src/constants.ts
··· 1 - import { fileURLToPath } from 'node:url' 2 - import { resolve } from 'pathe' 3 - 4 - const pkgRoot = resolve(fileURLToPath(import.meta.url), '../..') 5 - export const distRoot: string = resolve(pkgRoot, 'dist')
-6
packages/browser-webdriverio/src/index.ts
··· 1 - export { 2 - WebdriverBrowserProvider, 3 - webdriverio, 4 - type WebdriverProviderOptions, 5 - } from './webdriverio' 6 - export { defineBrowserCommand } from '@vitest/browser'
-308
packages/browser-webdriverio/src/locators.ts
··· 1 - import type { 2 - LocatorScreenshotOptions, 3 - UserEventClearOptions, 4 - UserEventClickOptions, 5 - UserEventDragAndDropOptions, 6 - UserEventFillOptions, 7 - UserEventHoverOptions, 8 - UserEventSelectOptions, 9 - UserEventWheelOptions, 10 - } from 'vitest/browser' 11 - import { 12 - convertElementToCssSelector, 13 - ensureAwaited, 14 - getByAltTextSelector, 15 - getByLabelSelector, 16 - getByPlaceholderSelector, 17 - getByRoleSelector, 18 - getByTestIdSelector, 19 - getByTextSelector, 20 - getByTitleSelector, 21 - getIframeScale, 22 - Locator, 23 - selectorEngine, 24 - triggerCommandWithTrace, 25 - } from '@vitest/browser/locators' 26 - import { page, server, utils } from 'vitest/browser' 27 - import { __INTERNAL } from 'vitest/internal/browser' 28 - 29 - class WebdriverIOLocator extends Locator { 30 - constructor(protected _pwSelector: string, protected _container?: Element) { 31 - super() 32 - } 33 - 34 - // This exists to avoid calling `this.elements` in `this.selector`'s getter in interactive actions 35 - private withElement( 36 - element: Element, 37 - error: Error | undefined, 38 - pwSelector: string, 39 - ) { 40 - const cssSelector = convertElementToCssSelector(element) 41 - return new ElementWebdriverIOLocator(cssSelector, error, pwSelector, element) 42 - } 43 - 44 - override get selector(): string { 45 - const selectors = this.elements().map(element => convertElementToCssSelector(element)) 46 - if (!selectors.length) { 47 - throw utils.getElementError(this._pwSelector, this._container || document.body) 48 - } 49 - let hasShadowRoot = false 50 - const newSelectors = selectors.map((selector) => { 51 - if (selector.startsWith('>>>')) { 52 - hasShadowRoot = true 53 - return selector.slice(3) 54 - } 55 - return selector 56 - }) 57 - return (hasShadowRoot ? '>>>' : '') + newSelectors.join(', ') 58 - } 59 - 60 - public override click(options?: UserEventClickOptions): Promise<void> { 61 - return ensureAwaited(async (error) => { 62 - const element = await this.findElement(options) 63 - return this.withElement(element, error, this._pwSelector).click(processClickOptions(options)) 64 - }) 65 - } 66 - 67 - public override dblClick(options?: UserEventClickOptions): Promise<void> { 68 - return ensureAwaited(async (error) => { 69 - const element = await this.findElement(options) 70 - return this.withElement(element, error, this._pwSelector).dblClick(processClickOptions(options)) 71 - }) 72 - } 73 - 74 - public override tripleClick(options?: UserEventClickOptions): Promise<void> { 75 - return ensureAwaited(async (error) => { 76 - const element = await this.findElement(options) 77 - return this.withElement(element, error, this._pwSelector).tripleClick(processClickOptions(options)) 78 - }) 79 - } 80 - 81 - public selectOptions( 82 - value: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[], 83 - options?: UserEventSelectOptions, 84 - ): Promise<void> { 85 - return ensureAwaited(async (error) => { 86 - const element = await this.findElement(options) 87 - const values = getWebdriverioSelectOptions(element, value) 88 - const selector = convertElementToCssSelector(element) 89 - const locator = this.asLocator() 90 - return triggerCommandWithTrace<void>({ 91 - name: '__vitest_selectOptions', 92 - arguments: [{ selector, locator }, values, options], 93 - errorSource: error, 94 - }) 95 - }) 96 - } 97 - 98 - public override hover(options?: UserEventHoverOptions): Promise<void> { 99 - return ensureAwaited(async (error) => { 100 - const element = await this.findElement(options) 101 - return this.withElement(element, error, this._pwSelector).hover(processHoverOptions(options)) 102 - }) 103 - } 104 - 105 - public override dropTo(target: Locator, options?: UserEventDragAndDropOptions): Promise<void> { 106 - // playwright doesn't enforce a single element, it selects the first one, 107 - // so we just follow the behavior 108 - return super.dropTo(target, processDragAndDropOptions(options)) 109 - } 110 - 111 - public override wheel(options: UserEventWheelOptions): Promise<void> { 112 - return ensureAwaited(async (error) => { 113 - const element = await this.findElement(options) 114 - return this.withElement(element, error, this._pwSelector).wheel(options) 115 - }) 116 - } 117 - 118 - public override clear(options?: UserEventClearOptions): Promise<void> { 119 - return ensureAwaited(async (error) => { 120 - const element = await this.findElement(options) 121 - return this.withElement(element, error, this._pwSelector).clear(options) 122 - }) 123 - } 124 - 125 - public override fill(text: string, options?: UserEventFillOptions): Promise<void> { 126 - return ensureAwaited(async (error) => { 127 - const element = await this.findElement(options) 128 - return this.withElement(element, error, this._pwSelector).fill(text, options) 129 - }) 130 - } 131 - 132 - public override screenshot(options?: LocatorScreenshotOptions): Promise<any> { 133 - return ensureAwaited(async (error) => { 134 - const element = await this.findElement(options) 135 - return this.withElement(element, error, this._pwSelector).screenshot(options) 136 - }) 137 - } 138 - 139 - // playwright doesn't enforce a single element in upload 140 - // public override async upload(): Promise<void> 141 - 142 - protected locator(selector: string) { 143 - return new WebdriverIOLocator(`${this._pwSelector} >> ${selector}`, this._container) 144 - } 145 - 146 - protected elementLocator(element: Element) { 147 - return new WebdriverIOLocator(selectorEngine.generateSelectorSimple(element), element) 148 - } 149 - } 150 - 151 - const kElementLocator = Symbol.for('$$vitest:locator-resolved') 152 - 153 - class ElementWebdriverIOLocator extends Locator { 154 - public [kElementLocator] = true 155 - 156 - constructor( 157 - private _cssSelector: string, 158 - protected _errorSource: Error | undefined, 159 - protected _pwSelector: string, 160 - protected _container: Element, 161 - ) { 162 - super() 163 - } 164 - 165 - override get selector() { 166 - return this._cssSelector 167 - } 168 - 169 - protected locator(_selector: string): Locator { 170 - throw new Error(`should not be called`) 171 - } 172 - 173 - protected elementLocator(_element: Element): Locator { 174 - throw new Error(`should not be called`) 175 - } 176 - } 177 - 178 - page.extend({ 179 - getByLabelText(text, options) { 180 - return new WebdriverIOLocator(getByLabelSelector(text, options)) 181 - }, 182 - getByRole(role, options) { 183 - return new WebdriverIOLocator(getByRoleSelector(role, options)) 184 - }, 185 - getByTestId(testId) { 186 - return new WebdriverIOLocator(getByTestIdSelector(server.config.browser.locators.testIdAttribute, testId)) 187 - }, 188 - getByAltText(text, options) { 189 - return new WebdriverIOLocator(getByAltTextSelector(text, options)) 190 - }, 191 - getByPlaceholder(text, options) { 192 - return new WebdriverIOLocator(getByPlaceholderSelector(text, options)) 193 - }, 194 - getByText(text, options) { 195 - return new WebdriverIOLocator(getByTextSelector(text, options)) 196 - }, 197 - getByTitle(title, options) { 198 - return new WebdriverIOLocator(getByTitleSelector(title, options)) 199 - }, 200 - 201 - elementLocator(element: Element) { 202 - return new WebdriverIOLocator(selectorEngine.generateSelectorSimple(element)) 203 - }, 204 - }) 205 - 206 - __INTERNAL._createLocator = selector => new WebdriverIOLocator(selector) 207 - 208 - function getWebdriverioSelectOptions(element: Element, value: string | string[] | HTMLElement[] | HTMLElement | Locator | Locator[]) { 209 - const options = [...element.querySelectorAll('option')] as HTMLOptionElement[] 210 - 211 - const arrayValues = Array.isArray(value) ? value : [value] 212 - 213 - if (!arrayValues.length) { 214 - return [] 215 - } 216 - 217 - if (arrayValues.length > 1) { 218 - throw new Error('Provider "webdriverio" doesn\'t support selecting multiple values at once') 219 - } 220 - 221 - const optionValue = arrayValues[0] 222 - 223 - if (typeof optionValue !== 'string') { 224 - const element = ('element' in optionValue ? optionValue.element() : optionValue) as HTMLOptionElement 225 - const index = options.indexOf(element) 226 - if (index === -1) { 227 - throw new Error(`The element ${selectorEngine.previewNode(element)} was not found in the "select" options.`) 228 - } 229 - 230 - return [{ index }] 231 - } 232 - 233 - const valueIndex = options.findIndex(option => option.value === optionValue) 234 - if (valueIndex !== -1) { 235 - return [{ index: valueIndex }] 236 - } 237 - 238 - const labelIndex = options.findIndex(option => 239 - option.textContent?.trim() === optionValue || option.ariaLabel === optionValue, 240 - ) 241 - 242 - if (labelIndex === -1) { 243 - throw new Error(`The option "${optionValue}" was not found in the "select" options.`) 244 - } 245 - 246 - return [{ index: labelIndex }] 247 - } 248 - 249 - function processClickOptions(options?: UserEventClickOptions) { 250 - // only ui scales the iframe, so we need to adjust the position 251 - if (!options || !server.config.browser.ui) { 252 - return options 253 - } 254 - if (options.x != null || options.y != null) { 255 - const cache = {} 256 - if (options.x != null) { 257 - options.x = scaleCoordinate(options.x, cache) 258 - } 259 - if (options.y != null) { 260 - options.y = scaleCoordinate(options.y, cache) 261 - } 262 - } 263 - return options 264 - } 265 - 266 - function processHoverOptions(options?: UserEventHoverOptions) { 267 - // only ui scales the iframe, so we need to adjust the position 268 - if (!options || !server.config.browser.ui) { 269 - return options 270 - } 271 - const cache = {} 272 - if (options.xOffset != null) { 273 - options.xOffset = scaleCoordinate(options.xOffset, cache) 274 - } 275 - if (options.yOffset != null) { 276 - options.yOffset = scaleCoordinate(options.yOffset, cache) 277 - } 278 - return options 279 - } 280 - 281 - function processDragAndDropOptions(options?: UserEventDragAndDropOptions) { 282 - // only ui scales the iframe, so we need to adjust the position 283 - if (!options || !server.config.browser.ui) { 284 - return options 285 - } 286 - const cache = {} 287 - if (options.sourceX != null) { 288 - options.sourceX = scaleCoordinate(options.sourceX, cache) 289 - } 290 - if (options.sourceY != null) { 291 - options.sourceY = scaleCoordinate(options.sourceY, cache) 292 - } 293 - if (options.targetX != null) { 294 - options.targetX = scaleCoordinate(options.targetX, cache) 295 - } 296 - if (options.targetY != null) { 297 - options.targetY = scaleCoordinate(options.targetY, cache) 298 - } 299 - return options 300 - } 301 - 302 - function scaleCoordinate(coordinate: number, cache: any) { 303 - return Math.round(coordinate * getCachedScale(cache)) 304 - } 305 - 306 - function getCachedScale(cache: { scale: number | undefined }) { 307 - return cache.scale ??= getIframeScale() 308 - }
-346
packages/browser-webdriverio/src/webdriverio.ts
··· 1 - import type { CustomComparatorsRegistry } from '@vitest/browser' 2 - import type { Capabilities } from '@wdio/types' 3 - import type { 4 - ScreenshotComparatorRegistry, 5 - ScreenshotMatcherOptions, 6 - SelectorOptions, 7 - } from 'vitest/browser' 8 - import type { 9 - BrowserCommand, 10 - BrowserProvider, 11 - BrowserProviderOption, 12 - CDPSession, 13 - TestProject, 14 - } from 'vitest/node' 15 - import type { ClickOptions, DragAndDropOptions, MoveToOptions, remote } from 'webdriverio' 16 - import { defineBrowserProvider } from '@vitest/browser' 17 - 18 - import { resolve } from 'pathe' 19 - import { createDebugger } from 'vitest/node' 20 - import commands from './commands' 21 - import { distRoot } from './constants' 22 - 23 - const debug = createDebugger('vitest:browser:wdio') 24 - 25 - const webdriverBrowsers = ['firefox', 'chrome', 'edge', 'safari'] as const 26 - type WebdriverBrowser = (typeof webdriverBrowsers)[number] 27 - 28 - export interface WebdriverProviderOptions extends Partial< 29 - Parameters<typeof remote>[0] 30 - > {} 31 - 32 - export function webdriverio(options: WebdriverProviderOptions = {}): BrowserProviderOption<WebdriverProviderOptions> { 33 - return defineBrowserProvider({ 34 - name: 'webdriverio', 35 - supportedBrowser: webdriverBrowsers, 36 - options, 37 - providerFactory(project) { 38 - return new WebdriverBrowserProvider(project, options) 39 - }, 40 - }) 41 - } 42 - 43 - export class WebdriverBrowserProvider implements BrowserProvider { 44 - public name = 'webdriverio' as const 45 - public supportsParallelism: boolean = false 46 - 47 - public browser: WebdriverIO.Browser | null = null 48 - 49 - private browserName!: WebdriverBrowser 50 - private project!: TestProject 51 - 52 - private options?: WebdriverProviderOptions 53 - 54 - private closing = false 55 - private iframeSwitched = false 56 - private topLevelContext: string | undefined 57 - 58 - public initScripts: string[] = [ 59 - resolve(distRoot, 'locators.js'), 60 - ] 61 - 62 - getSupportedBrowsers(): readonly string[] { 63 - return webdriverBrowsers 64 - } 65 - 66 - constructor( 67 - project: TestProject, 68 - options: WebdriverProviderOptions, 69 - ) { 70 - // increase shutdown timeout because WDIO takes some extra time to kill the driver 71 - if (!project.vitest.state._data.timeoutIncreased) { 72 - project.vitest.state._data.timeoutIncreased = true 73 - project.vitest.config.teardownTimeout += 10_000 74 - } 75 - 76 - this.closing = false 77 - this.project = project 78 - this.browserName = project.config.browser.name as WebdriverBrowser 79 - this.options = options 80 - 81 - for (const [name, command] of Object.entries(commands)) { 82 - project.browser!.registerCommand(name as any, command as BrowserCommand) 83 - } 84 - } 85 - 86 - isIframeSwitched(): boolean { 87 - return this.iframeSwitched 88 - } 89 - 90 - async switchToTestFrame(): Promise<void> { 91 - const browser = this.browser! 92 - // support wdio@9 93 - if (browser.switchFrame) { 94 - await browser.switchFrame(browser.$('iframe[data-vitest]')) 95 - } 96 - else { 97 - const iframe = await browser.findElement( 98 - 'css selector', 99 - 'iframe[data-vitest]', 100 - ) 101 - await browser.switchToFrame(iframe) 102 - } 103 - this.iframeSwitched = true 104 - } 105 - 106 - async switchToMainFrame(): Promise<void> { 107 - const page = this.browser! 108 - if (page.switchFrame) { 109 - await page.switchFrame(null) 110 - } 111 - else { 112 - await page.switchToParentFrame() 113 - } 114 - this.iframeSwitched = false 115 - } 116 - 117 - async setViewport(options: { width: number; height: number }): Promise<void> { 118 - if (this.topLevelContext == null || !this.browser) { 119 - throw new Error(`The browser has no open pages.`) 120 - } 121 - if (this.browser.isBidi) { 122 - await this.browser.send({ 123 - method: 'browsingContext.setViewport', 124 - params: { 125 - context: this.topLevelContext, 126 - devicePixelRatio: 1, 127 - viewport: options, 128 - }, 129 - }) 130 - } 131 - else { 132 - await this.browser.setWindowSize(options.width, options.height) 133 - } 134 - } 135 - 136 - getCommandsContext(): { 137 - browser: WebdriverIO.Browser | null 138 - } { 139 - return { 140 - browser: this.browser, 141 - } 142 - } 143 - 144 - async openBrowser(): Promise<WebdriverIO.Browser> { 145 - await this._throwIfClosing('opening the browser') 146 - 147 - if (this.browser) { 148 - debug?.('[%s] the browser is already opened, reusing it', this.browserName) 149 - return this.browser 150 - } 151 - 152 - const options = this.project.config.browser 153 - 154 - if (this.browserName === 'safari') { 155 - if (options.headless) { 156 - throw new Error( 157 - 'You\'ve enabled headless mode for Safari but it doesn\'t currently support it.', 158 - ) 159 - } 160 - } 161 - 162 - const { remote } = await import('webdriverio') 163 - 164 - const remoteOptions: Capabilities.WebdriverIOConfig = { 165 - logLevel: 'silent', 166 - ...this.options, 167 - capabilities: this.buildCapabilities(), 168 - } 169 - 170 - debug?.('[%s] opening the browser with options: %O', this.browserName, remoteOptions) 171 - // TODO: close everything, if browser is closed from the outside 172 - this.browser = await remote(remoteOptions) 173 - await this._throwIfClosing() 174 - 175 - return this.browser 176 - } 177 - 178 - private buildCapabilities() { 179 - const capabilities: Capabilities.WebdriverIOConfig['capabilities'] = { 180 - ...this.options?.capabilities, 181 - browserName: this.browserName, 182 - } 183 - 184 - const headlessMap = { 185 - chrome: ['goog:chromeOptions', ['headless', 'disable-gpu']], 186 - firefox: ['moz:firefoxOptions', ['-headless']], 187 - edge: ['ms:edgeOptions', ['--headless']], 188 - } as const 189 - 190 - const options = this.project.config.browser 191 - const browser = this.browserName 192 - if (browser !== 'safari' && options.headless) { 193 - const [key, defaultArgs] = headlessMap[browser] 194 - const currentValues = (this.options?.capabilities as any)?.[key] || {} 195 - const currentArgs: string[] = currentValues.args || [] 196 - 197 - const hasEnableGpu = browser === 'chrome' && (currentArgs.includes('--enable-gpu') || currentArgs.includes('enable-gpu')) 198 - 199 - const argsToAdd = hasEnableGpu 200 - ? defaultArgs.filter(arg => arg !== 'disable-gpu') 201 - : defaultArgs 202 - 203 - const newArgs = [...currentArgs, ...argsToAdd] 204 - 205 - capabilities[key] = { ...currentValues, args: newArgs as any } 206 - } 207 - 208 - // start Vitest UI maximized only on supported browsers 209 - if (options.ui && (browser === 'chrome' || browser === 'edge')) { 210 - const key = browser === 'chrome' 211 - ? 'goog:chromeOptions' 212 - : 'ms:edgeOptions' 213 - const args = capabilities[key]?.args || [] 214 - if (!args.includes('--start-maximized') && !args.includes('--start-fullscreen')) { 215 - args.push('--start-maximized') 216 - } 217 - capabilities[key] ??= {} 218 - capabilities[key]!.args = args 219 - } 220 - 221 - const inspector = this.project.vitest.config.inspector 222 - if (inspector.enabled && (browser === 'chrome' || browser === 'edge')) { 223 - const key = browser === 'chrome' 224 - ? 'goog:chromeOptions' 225 - : 'ms:edgeOptions' 226 - const args = capabilities[key]?.args || [] 227 - 228 - // NodeJS equivalent defaults: https://nodejs.org/en/learn/getting-started/debugging#enable-inspector 229 - const port = inspector.port || 9229 230 - const host = inspector.host || '127.0.0.1' 231 - 232 - args.push(`--remote-debugging-port=${port}`) 233 - 234 - if (host !== 'localhost' && host !== '127.0.0.1' && host !== '::1') { 235 - this.project.vitest.logger.warn(`Custom inspector host "${host}" will be ignored. Chrome only allows remote debugging on localhost.`) 236 - } 237 - this.project.vitest.logger.log(`Debugger listening on ws://127.0.0.1:${port}`) 238 - 239 - capabilities[key] ??= {} 240 - capabilities[key]!.args = args 241 - } 242 - 243 - return capabilities 244 - } 245 - 246 - async openPage(sessionId: string, url: string): Promise<void> { 247 - await this._throwIfClosing('creating the browser') 248 - debug?.('[%s][%s] creating the browser page for %s', sessionId, this.browserName, url) 249 - const browserInstance = await this.openBrowser() 250 - debug?.('[%s][%s] browser page is created, opening %s', sessionId, this.browserName, url) 251 - await browserInstance.url(url) 252 - this.topLevelContext = await browserInstance.getWindowHandle() 253 - await this._throwIfClosing('opening the url') 254 - } 255 - 256 - private async _throwIfClosing(action?: string) { 257 - if (this.closing) { 258 - debug?.(`[%s] provider was closed, cannot perform the action${action ? ` ${action}` : ''}`, this.browserName) 259 - await (this.browser?.sessionId ? this.browser?.deleteSession?.() : null) 260 - throw new Error(`[vitest] The provider was closed.`) 261 - } 262 - } 263 - 264 - async close(): Promise<void> { 265 - debug?.('[%s] closing provider', this.browserName) 266 - this.closing = true 267 - const browser = this.browser 268 - const sessionId = browser?.sessionId 269 - if (!browser || !sessionId) { 270 - return 271 - } 272 - 273 - // https://github.com/webdriverio/webdriverio/blob/ab1a2e82b13a9c7d0e275ae87e7357e1b047d8d3/packages/wdio-runner/src/index.ts#L486 274 - await browser.deleteSession() 275 - browser.sessionId = undefined as unknown as string 276 - this.browser = null 277 - } 278 - 279 - async getCDPSession(_sessionId: string): Promise<CDPSession> { 280 - return { 281 - send: (method, params) => { 282 - if (!this.browser) { 283 - throw new Error(`The environment was torn down.`) 284 - } 285 - return this.browser.sendCommandAndGetResult(method, params ?? {}).catch((error) => { 286 - return Promise.reject(new Error(`Failed to execute "${method}" command.`, { cause: error })) 287 - }) 288 - }, 289 - on: () => { 290 - throw new Error(`webdriverio provider doesn't support cdp.on()`) 291 - }, 292 - once: () => { 293 - throw new Error(`webdriverio provider doesn't support cdp.once()`) 294 - }, 295 - off: () => { 296 - throw new Error(`webdriverio provider doesn't support cdp.off()`) 297 - }, 298 - } 299 - } 300 - } 301 - 302 - declare module 'vitest/browser' { 303 - export interface UserEventClickOptions extends Partial<ClickOptions>, SelectorOptions {} 304 - export interface UserEventHoverOptions extends MoveToOptions, SelectorOptions {} 305 - export interface UserEventDragAndDropOptions extends DragAndDropOptions { 306 - sourceX?: number 307 - sourceY?: number 308 - targetX?: number 309 - targetY?: number 310 - } 311 - export interface UserEventFillOptions extends SelectorOptions {} 312 - export interface UserEventSelectOptions extends SelectorOptions {} 313 - export interface UserEventClearOptions extends SelectorOptions {} 314 - export interface UserEventDoubleClickOptions extends SelectorOptions {} 315 - export interface UserEventTripleClickOptions extends SelectorOptions {} 316 - export interface UserEventWheelBaseOptions extends SelectorOptions {} 317 - export interface LocatorScreenshotOptions extends SelectorOptions {} 318 - } 319 - 320 - interface WebdriverCDPSession { 321 - send: (method: string, params?: Record<string, unknown>) => Promise<unknown> 322 - on: (event: string, listener: (...args: unknown[]) => void) => void 323 - once: (event: string, listener: (...args: unknown[]) => void) => void 324 - off: (event: string, listener: (...args: unknown[]) => void) => void 325 - } 326 - 327 - declare module 'vitest/node' { 328 - export interface BrowserCommandContext { 329 - browser: WebdriverIO.Browser 330 - } 331 - 332 - export interface _BrowserNames { 333 - webdriverio: WebdriverBrowser 334 - } 335 - 336 - export interface ToMatchScreenshotOptions 337 - extends Omit< 338 - ScreenshotMatcherOptions, 339 - 'comparatorName' | 'comparatorOptions' 340 - >, CustomComparatorsRegistry {} 341 - 342 - export interface ToMatchScreenshotComparators 343 - extends ScreenshotComparatorRegistry {} 344 - 345 - export interface CDPSession extends WebdriverCDPSession {} 346 - }
-11
test/browser/specs/multiple-different-configs.test.ts
··· 12 12 expect(stdout).toContain('[chromium] HTML_INJECTED_VAR is true') 13 13 expect(stdout).toContain('[firefox] HTML_INJECTED_VAR is undefined') 14 14 }) 15 - 16 - test.runIf(provider.name === 'webdriverio')('[webdriverio] runs multiple different configurations correctly', async () => { 17 - const { stdout, exitCode, stderr } = await runBrowserTests({ 18 - root: './fixtures/multiple-different-configs', 19 - }) 20 - 21 - expect(stderr).toBe('') 22 - expect(exitCode).toBe(0) 23 - expect(stdout).toContain('[chromium] HTML_INJECTED_VAR is true') 24 - expect(stdout).toContain('[firefox] HTML_INJECTED_VAR is undefined') 25 - })
+1 -6
test/browser/specs/runner.test.ts
··· 346 346 const { stdout, stderr } = await runBrowserTests({ 347 347 root: './fixtures/user-event', 348 348 }) 349 - if (provider.name !== 'webdriverio') { 350 - expect(stderr).toBe('') 351 - } 349 + expect(stderr).toBe('') 352 350 onTestFailed(() => console.error(stderr)) 353 351 instances.forEach(({ browser }) => { 354 352 expect(stdout).toReportPassedTest('cleanup-retry.test.ts', browser) ··· 367 365 if (provider.name === 'playwright') { 368 366 expect(stderr).toContain('locator.click: Timeout 500ms exceeded.') 369 367 expect(stderr).toContain('locator.click: Timeout 345ms exceeded.') 370 - } 371 - if (provider.name === 'webdriverio') { 372 - expect(stderr).toContain('Cannot find element with locator') 373 368 } 374 369 }) 375 370
+8 -1557
test/browser/specs/trace.test.ts
··· 7 7 8 8 // update snapshots by 9 9 // TEST_BROWSER=chromium pnpm -C test/browser/ test:playwright specs/trace.test.ts -u --run 10 - // TEST_BROWSER=chrome pnpm -C test/browser/ test:webdriverio specs/trace.test.ts -u --run 11 10 // run fixture directly by 12 11 // TEST_BROWSER=chromium pnpm -C test/browser/ test-fixtures --root fixtures/trace 13 12 ··· 143 142 }, 144 143 } 145 144 `) 146 - // selector format is different between providers 147 - if (provider.name === 'webdriverio') { 148 - expect.soft(projectArtifactTree[browser], browser).toMatchInlineSnapshot(` 149 - { 150 - "exotic.test.ts": { 151 - "adopted stylesheets are not captured by snapshot alone": [ 152 - { 153 - "entries": [ 154 - { 155 - "element": { 156 - "_pwSelector": "internal:role=button", 157 - "locator": "getByRole('button')", 158 - "selector": "html > body > button", 159 - }, 160 - "kind": "mark", 161 - "location": "exotic.test.ts:58", 162 - "name": "button rendered with adopted stylesheet", 163 - "snapshot": { 164 - "selectorResolution": "matched", 165 - }, 166 - }, 167 - ], 168 - }, 169 - { 170 - "entries": [ 171 - { 172 - "kind": "lifecycle", 173 - "location": "exotic.test.ts:51", 174 - "name": "vitest:onAfterRetryTask", 175 - "snapshot": {}, 176 - "status": "pass", 177 - }, 178 - ], 179 - }, 180 - ], 181 - "canvas pixels are captured for replay": [ 182 - { 183 - "entries": [ 184 - { 185 - "element": { 186 - "_pwSelector": "internal:testid=[data-testid="trace-canvas"s]", 187 - "locator": "getByTestId('trace-canvas')", 188 - "selector": "html > body > canvas", 189 - }, 190 - "kind": "mark", 191 - "location": "exotic.test.ts:17", 192 - "name": "canvas drawn before mark", 193 - "snapshot": { 194 - "selectorResolution": "matched", 195 - }, 196 - }, 197 - ], 198 - }, 199 - { 200 - "entries": [ 201 - { 202 - "kind": "lifecycle", 203 - "location": "exotic.test.ts:11", 204 - "name": "vitest:onAfterRetryTask", 205 - "snapshot": {}, 206 - "status": "pass", 207 - }, 208 - ], 209 - }, 210 - ], 211 - "custom element dom shape is rebuilt without runtime behavior": [ 212 - { 213 - "entries": [ 214 - { 215 - "element": { 216 - "_pwSelector": "internal:role=button[name="Custom element button"s]", 217 - "locator": "getByRole('button', { name: 'Custom element button' })", 218 - "selector": ">>>html > body > trace-widget > button", 219 - }, 220 - "kind": "mark", 221 - "location": "exotic.test.ts:47", 222 - "name": "custom element rendered", 223 - "snapshot": { 224 - "selectorResolution": "matched", 225 - }, 226 - }, 227 - ], 228 - }, 229 - { 230 - "entries": [ 231 - { 232 - "kind": "lifecycle", 233 - "location": "exotic.test.ts:32", 234 - "name": "vitest:onAfterRetryTask", 235 - "snapshot": {}, 236 - "status": "pass", 237 - }, 238 - ], 239 - }, 240 - ], 241 - "shadow dom is rebuilt and highlightable by mirror id": [ 242 - { 243 - "entries": [ 244 - { 245 - "element": { 246 - "_pwSelector": "internal:role=button[name="Shadow button"s]", 247 - "locator": "getByRole('button', { name: 'Shadow button' })", 248 - "selector": ">>>html > body > section > button", 249 - }, 250 - "kind": "mark", 251 - "location": "exotic.test.ts:28", 252 - "name": "shadow button rendered", 253 - "snapshot": { 254 - "selectorResolution": "matched", 255 - }, 256 - }, 257 - ], 258 - }, 259 - { 260 - "entries": [ 261 - { 262 - "kind": "lifecycle", 263 - "location": "exotic.test.ts:20", 264 - "name": "vitest:onAfterRetryTask", 265 - "snapshot": {}, 266 - "status": "pass", 267 - }, 268 - ], 269 - }, 270 - ], 271 - }, 272 - "expect.test.ts": { 273 - "click": [ 274 - { 275 - "entries": [ 276 - { 277 - "element": { 278 - "_pwSelector": "internal:role=button", 279 - "locator": "getByRole('button')", 280 - "selector": "html > body > button", 281 - }, 282 - "kind": "action", 283 - "location": "expect.test.ts:25", 284 - "name": "vitest:click", 285 - "range": { 286 - "phase": "start", 287 - }, 288 - "snapshot": { 289 - "selectorResolution": "matched", 290 - }, 291 - }, 292 - ], 293 - }, 294 - { 295 - "entries": [ 296 - { 297 - "element": { 298 - "_pwSelector": "internal:role=button", 299 - "locator": "getByRole('button')", 300 - "selector": "html > body > button", 301 - }, 302 - "kind": "action", 303 - "location": "expect.test.ts:25", 304 - "name": "vitest:click", 305 - "range": { 306 - "phase": "end", 307 - }, 308 - "snapshot": { 309 - "selectorResolution": "matched", 310 - }, 311 - "status": "pass", 312 - }, 313 - ], 314 - }, 315 - { 316 - "entries": [ 317 - { 318 - "kind": "lifecycle", 319 - "location": "expect.test.ts:23", 320 - "name": "vitest:onAfterRetryTask", 321 - "snapshot": {}, 322 - "status": "pass", 323 - }, 324 - ], 325 - }, 326 - ], 327 - "click fail": [ 328 - { 329 - "entries": [ 330 - { 331 - "kind": "lifecycle", 332 - "location": "expect.test.ts:33", 333 - "name": "vitest:onAfterRetryTask", 334 - "snapshot": {}, 335 - "status": "fail", 336 - }, 337 - ], 338 - }, 339 - ], 340 - "expect.element fail": [ 341 - { 342 - "entries": [ 343 - { 344 - "element": { 345 - "_pwSelector": "internal:role=button", 346 - "locator": "getByRole('button')", 347 - "selector": "html > body > button", 348 - }, 349 - "kind": "expect", 350 - "location": "expect.test.ts:15", 351 - "name": "toHaveTextContent", 352 - "range": { 353 - "phase": "start", 354 - }, 355 - "snapshot": { 356 - "selectorResolution": "matched", 357 - }, 358 - }, 359 - ], 360 - }, 361 - { 362 - "entries": [ 363 - { 364 - "element": { 365 - "_pwSelector": "internal:role=button", 366 - "locator": "getByRole('button')", 367 - "selector": "html > body > button", 368 - }, 369 - "kind": "expect", 370 - "location": "expect.test.ts:15", 371 - "name": "toHaveTextContent [ERROR]", 372 - "range": { 373 - "phase": "end", 374 - }, 375 - "snapshot": { 376 - "selectorResolution": "matched", 377 - }, 378 - "status": "fail", 379 - }, 380 - ], 381 - }, 382 - { 383 - "entries": [ 384 - { 385 - "kind": "lifecycle", 386 - "location": "expect.test.ts:15", 387 - "name": "vitest:onAfterRetryTask", 388 - "snapshot": {}, 389 - "status": "fail", 390 - }, 391 - ], 392 - }, 393 - ], 394 - "expect.element pass": [ 395 - { 396 - "entries": [ 397 - { 398 - "element": { 399 - "_pwSelector": "internal:role=button", 400 - "locator": "getByRole('button')", 401 - "selector": "html > body > button", 402 - }, 403 - "kind": "expect", 404 - "location": "expect.test.ts:10", 405 - "name": "toHaveTextContent", 406 - "range": { 407 - "phase": "start", 408 - }, 409 - "snapshot": { 410 - "selectorResolution": "matched", 411 - }, 412 - }, 413 - ], 414 - }, 415 - { 416 - "entries": [ 417 - { 418 - "element": { 419 - "_pwSelector": "internal:role=button", 420 - "locator": "getByRole('button')", 421 - "selector": "html > body > button", 422 - }, 423 - "kind": "expect", 424 - "location": "expect.test.ts:10", 425 - "name": "toHaveTextContent", 426 - "range": { 427 - "phase": "end", 428 - }, 429 - "snapshot": { 430 - "selectorResolution": "matched", 431 - }, 432 - "status": "pass", 433 - }, 434 - ], 435 - }, 436 - { 437 - "entries": [ 438 - { 439 - "kind": "lifecycle", 440 - "location": "expect.test.ts:8", 441 - "name": "vitest:onAfterRetryTask", 442 - "snapshot": {}, 443 - "status": "pass", 444 - }, 445 - ], 446 - }, 447 - ], 448 - "failure": [ 449 - { 450 - "entries": [ 451 - { 452 - "kind": "lifecycle", 453 - "location": "expect.test.ts:20", 454 - "name": "vitest:onAfterRetryTask", 455 - "snapshot": {}, 456 - "status": "fail", 457 - }, 458 - ], 459 - }, 460 - ], 461 - }, 462 - "mark.test.ts": { 463 - "custom command": [ 464 - { 465 - "entries": [ 466 - { 467 - "kind": "action", 468 - "name": "from server command", 469 - "snapshot": {}, 470 - }, 471 - ], 472 - }, 473 - { 474 - "entries": [ 475 - { 476 - "kind": "lifecycle", 477 - "location": "mark.test.ts:48", 478 - "name": "vitest:onAfterRetryTask", 479 - "snapshot": {}, 480 - "status": "pass", 481 - }, 482 - ], 483 - }, 484 - ], 485 - "helper": [ 486 - { 487 - "entries": [ 488 - { 489 - "element": { 490 - "_pwSelector": "internal:role=button[name="Hello"i]", 491 - "locator": "getByRole('button', { name: 'Hello', exact: false })", 492 - "selector": "html > body > button", 493 - }, 494 - "kind": "mark", 495 - "location": "mark.test.ts:24", 496 - "name": "render helper", 497 - "snapshot": { 498 - "selectorResolution": "matched", 499 - }, 500 - }, 501 - ], 502 - }, 503 - { 504 - "entries": [ 505 - { 506 - "kind": "lifecycle", 507 - "location": "mark.test.ts:23", 508 - "name": "vitest:onAfterRetryTask", 509 - "snapshot": {}, 510 - "status": "pass", 511 - }, 512 - ], 513 - }, 514 - ], 515 - "kind": [ 516 - { 517 - "entries": [ 518 - { 519 - "kind": "action", 520 - "location": "mark.test.ts:42", 521 - "name": "action marker", 522 - "snapshot": {}, 523 - }, 524 - ], 525 - }, 526 - { 527 - "entries": [ 528 - { 529 - "kind": "expect", 530 - "location": "mark.test.ts:43", 531 - "name": "expect marker", 532 - "snapshot": {}, 533 - }, 534 - ], 535 - }, 536 - { 537 - "entries": [ 538 - { 539 - "kind": "lifecycle", 540 - "location": "mark.test.ts:44", 541 - "name": "lifecycle group", 542 - "snapshot": {}, 543 - }, 544 - ], 545 - }, 546 - { 547 - "entries": [ 548 - { 549 - "kind": "mark", 550 - "location": "mark.test.ts:45", 551 - "name": "lifecycle group", 552 - "snapshot": {}, 553 - }, 554 - ], 555 - }, 556 - { 557 - "entries": [ 558 - { 559 - "kind": "lifecycle", 560 - "location": "mark.test.ts:39", 561 - "name": "vitest:onAfterRetryTask", 562 - "snapshot": {}, 563 - "status": "pass", 564 - }, 565 - ], 566 - }, 567 - ], 568 - "locator.mark": [ 569 - { 570 - "entries": [ 571 - { 572 - "element": { 573 - "_pwSelector": "internal:role=button", 574 - "locator": "getByRole('button')", 575 - "selector": "html > body > button", 576 - }, 577 - "kind": "mark", 578 - "location": "mark.test.ts:10", 579 - "name": "button rendered - locator", 580 - "snapshot": { 581 - "selectorResolution": "matched", 582 - }, 583 - }, 584 - ], 585 - }, 586 - { 587 - "entries": [ 588 - { 589 - "kind": "lifecycle", 590 - "location": "mark.test.ts:8", 591 - "name": "vitest:onAfterRetryTask", 592 - "snapshot": {}, 593 - "status": "pass", 594 - }, 595 - ], 596 - }, 597 - ], 598 - "mark function": [ 599 - { 600 - "entries": [ 601 - { 602 - "kind": "mark", 603 - "location": "mark.test.ts:34", 604 - "name": "render group", 605 - "range": { 606 - "phase": "start", 607 - }, 608 - "snapshot": {}, 609 - }, 610 - ], 611 - }, 612 - { 613 - "entries": [ 614 - { 615 - "kind": "mark", 616 - "location": "mark.test.ts:34", 617 - "name": "render group", 618 - "range": { 619 - "phase": "end", 620 - }, 621 - "snapshot": {}, 622 - "status": "pass", 623 - }, 624 - ], 625 - }, 626 - { 627 - "entries": [ 628 - { 629 - "kind": "lifecycle", 630 - "location": "mark.test.ts:33", 631 - "name": "vitest:onAfterRetryTask", 632 - "snapshot": {}, 633 - "status": "pass", 634 - }, 635 - ], 636 - }, 637 - ], 638 - "mark function fail": [ 639 - { 640 - "entries": [ 641 - { 642 - "kind": "mark", 643 - "location": "mark.test.ts:57", 644 - "name": "failed render group", 645 - "range": { 646 - "phase": "start", 647 - }, 648 - "snapshot": {}, 649 - }, 650 - ], 651 - }, 652 - { 653 - "entries": [ 654 - { 655 - "kind": "mark", 656 - "location": "mark.test.ts:57", 657 - "name": "failed render group", 658 - "range": { 659 - "phase": "end", 660 - }, 661 - "snapshot": {}, 662 - "status": "fail", 663 - }, 664 - ], 665 - }, 666 - { 667 - "entries": [ 668 - { 669 - "kind": "lifecycle", 670 - "location": "mark.test.ts:59", 671 - "name": "vitest:onAfterRetryTask", 672 - "snapshot": {}, 673 - "status": "fail", 674 - }, 675 - ], 676 - }, 677 - ], 678 - "page.mark": [ 679 - { 680 - "entries": [ 681 - { 682 - "kind": "mark", 683 - "location": "mark.test.ts:15", 684 - "name": "button rendered - page", 685 - "snapshot": {}, 686 - }, 687 - ], 688 - }, 689 - { 690 - "entries": [ 691 - { 692 - "kind": "lifecycle", 693 - "location": "mark.test.ts:13", 694 - "name": "vitest:onAfterRetryTask", 695 - "snapshot": {}, 696 - "status": "pass", 697 - }, 698 - ], 699 - }, 700 - ], 701 - "stack": [ 702 - { 703 - "entries": [ 704 - { 705 - "element": { 706 - "_pwSelector": "internal:role=button", 707 - "locator": "getByRole('button')", 708 - "selector": "html > body > button", 709 - }, 710 - "kind": "mark", 711 - "location": "mark.test.ts:29", 712 - "name": "button rendered - stack", 713 - "snapshot": { 714 - "selectorResolution": "matched", 715 - }, 716 - }, 717 - ], 718 - }, 719 - { 720 - "entries": [ 721 - { 722 - "kind": "lifecycle", 723 - "location": "mark.test.ts:27", 724 - "name": "vitest:onAfterRetryTask", 725 - "snapshot": {}, 726 - "status": "pass", 727 - }, 728 - ], 729 - }, 730 - ], 731 - }, 732 - "resources.test.ts": { 733 - "external image remains url dependent": [ 734 - { 735 - "entries": [ 736 - { 737 - "element": { 738 - "_pwSelector": "internal:attr=[alt="external trace asset"s]", 739 - "locator": "getByAltText('external trace asset')", 740 - "selector": "html > body > img", 741 - }, 742 - "kind": "mark", 743 - "location": "resources.test.ts:20", 744 - "name": "image rendered from external url", 745 - "snapshot": { 746 - "selectorResolution": "matched", 747 - }, 748 - }, 749 - ], 750 - }, 751 - { 752 - "entries": [ 753 - { 754 - "kind": "lifecycle", 755 - "location": "resources.test.ts:17", 756 - "name": "vitest:onAfterRetryTask", 757 - "snapshot": {}, 758 - "status": "pass", 759 - }, 760 - ], 761 - }, 762 - ], 763 - "same-origin image is inlined for offline replay": [ 764 - { 765 - "entries": [ 766 - { 767 - "element": { 768 - "_pwSelector": "internal:attr=[alt="local trace asset"s]", 769 - "locator": "getByAltText('local trace asset')", 770 - "selector": "html > body > img", 771 - }, 772 - "kind": "mark", 773 - "location": "resources.test.ts:12", 774 - "name": "image rendered from same-origin url", 775 - "snapshot": { 776 - "selectorResolution": "matched", 777 - }, 778 - }, 779 - ], 780 - }, 781 - { 782 - "entries": [ 783 - { 784 - "kind": "lifecycle", 785 - "location": "resources.test.ts:9", 786 - "name": "vitest:onAfterRetryTask", 787 - "snapshot": {}, 788 - "status": "pass", 789 - }, 790 - ], 791 - }, 792 - ], 793 - }, 794 - "retry.test.ts": { 795 - "repeated retried tests": [ 796 - { 797 - "entries": [ 798 - { 799 - "element": { 800 - "_pwSelector": "internal:role=list", 801 - "locator": "getByRole('list')", 802 - "selector": "html > body > ul", 803 - }, 804 - "kind": "mark", 805 - "location": "retry.test.ts:29", 806 - "name": "renderHelper", 807 - "snapshot": { 808 - "selectorResolution": "matched", 809 - }, 810 - }, 811 - ], 812 - }, 813 - { 814 - "entries": [ 815 - { 816 - "kind": "lifecycle", 817 - "location": "retry.test.ts:31", 818 - "name": "vitest:onAfterRetryTask", 819 - "snapshot": {}, 820 - "status": "fail", 821 - }, 822 - ], 823 - }, 824 - { 825 - "entries": [ 826 - { 827 - "element": { 828 - "_pwSelector": "internal:role=list", 829 - "locator": "getByRole('list')", 830 - "selector": "html > body > ul", 831 - }, 832 - "kind": "mark", 833 - "location": "retry.test.ts:29", 834 - "name": "renderHelper", 835 - "snapshot": { 836 - "selectorResolution": "matched", 837 - }, 838 - }, 839 - ], 840 - "retry": 1, 841 - }, 842 - { 843 - "entries": [ 844 - { 845 - "kind": "lifecycle", 846 - "location": "retry.test.ts:31", 847 - "name": "vitest:onAfterRetryTask", 848 - "snapshot": {}, 849 - "status": "fail", 850 - }, 851 - ], 852 - "retry": 1, 853 - }, 854 - { 855 - "entries": [ 856 - { 857 - "element": { 858 - "_pwSelector": "internal:role=list", 859 - "locator": "getByRole('list')", 860 - "selector": "html > body > ul", 861 - }, 862 - "kind": "mark", 863 - "location": "retry.test.ts:29", 864 - "name": "renderHelper", 865 - "snapshot": { 866 - "selectorResolution": "matched", 867 - }, 868 - }, 869 - ], 870 - "retry": 2, 871 - }, 872 - { 873 - "entries": [ 874 - { 875 - "kind": "lifecycle", 876 - "location": "retry.test.ts:28", 877 - "name": "vitest:onAfterRetryTask", 878 - "snapshot": {}, 879 - "status": "pass", 880 - }, 881 - ], 882 - "retry": 2, 883 - }, 884 - { 885 - "entries": [ 886 - { 887 - "element": { 888 - "_pwSelector": "internal:role=list", 889 - "locator": "getByRole('list')", 890 - "selector": "html > body > ul", 891 - }, 892 - "kind": "mark", 893 - "location": "retry.test.ts:29", 894 - "name": "renderHelper", 895 - "snapshot": { 896 - "selectorResolution": "matched", 897 - }, 898 - }, 899 - ], 900 - "repeats": 1, 901 - }, 902 - { 903 - "entries": [ 904 - { 905 - "kind": "lifecycle", 906 - "location": "retry.test.ts:28", 907 - "name": "vitest:onAfterRetryTask", 908 - "snapshot": {}, 909 - "status": "pass", 910 - }, 911 - ], 912 - "repeats": 1, 913 - }, 914 - { 915 - "entries": [ 916 - { 917 - "element": { 918 - "_pwSelector": "internal:role=list", 919 - "locator": "getByRole('list')", 920 - "selector": "html > body > ul", 921 - }, 922 - "kind": "mark", 923 - "location": "retry.test.ts:29", 924 - "name": "renderHelper", 925 - "snapshot": { 926 - "selectorResolution": "matched", 927 - }, 928 - }, 929 - ], 930 - "repeats": 2, 931 - }, 932 - { 933 - "entries": [ 934 - { 935 - "kind": "lifecycle", 936 - "location": "retry.test.ts:28", 937 - "name": "vitest:onAfterRetryTask", 938 - "snapshot": {}, 939 - "status": "pass", 940 - }, 941 - ], 942 - "repeats": 2, 943 - }, 944 - ], 945 - "repeated test": [ 946 - { 947 - "entries": [ 948 - { 949 - "element": { 950 - "_pwSelector": "internal:role=list", 951 - "locator": "getByRole('list')", 952 - "selector": "html > body > ul", 953 - }, 954 - "kind": "mark", 955 - "location": "retry.test.ts:18", 956 - "name": "renderHelper", 957 - "snapshot": { 958 - "selectorResolution": "matched", 959 - }, 960 - }, 961 - ], 962 - }, 963 - { 964 - "entries": [ 965 - { 966 - "kind": "lifecycle", 967 - "location": "retry.test.ts:17", 968 - "name": "vitest:onAfterRetryTask", 969 - "snapshot": {}, 970 - "status": "pass", 971 - }, 972 - ], 973 - }, 974 - { 975 - "entries": [ 976 - { 977 - "element": { 978 - "_pwSelector": "internal:role=list", 979 - "locator": "getByRole('list')", 980 - "selector": "html > body > ul", 981 - }, 982 - "kind": "mark", 983 - "location": "retry.test.ts:18", 984 - "name": "renderHelper", 985 - "snapshot": { 986 - "selectorResolution": "matched", 987 - }, 988 - }, 989 - ], 990 - "repeats": 1, 991 - }, 992 - { 993 - "entries": [ 994 - { 995 - "kind": "lifecycle", 996 - "location": "retry.test.ts:17", 997 - "name": "vitest:onAfterRetryTask", 998 - "snapshot": {}, 999 - "status": "pass", 1000 - }, 1001 - ], 1002 - "repeats": 1, 1003 - }, 1004 - { 1005 - "entries": [ 1006 - { 1007 - "element": { 1008 - "_pwSelector": "internal:role=list", 1009 - "locator": "getByRole('list')", 1010 - "selector": "html > body > ul", 1011 - }, 1012 - "kind": "mark", 1013 - "location": "retry.test.ts:18", 1014 - "name": "renderHelper", 1015 - "snapshot": { 1016 - "selectorResolution": "matched", 1017 - }, 1018 - }, 1019 - ], 1020 - "repeats": 2, 1021 - }, 1022 - { 1023 - "entries": [ 1024 - { 1025 - "kind": "lifecycle", 1026 - "location": "retry.test.ts:17", 1027 - "name": "vitest:onAfterRetryTask", 1028 - "snapshot": {}, 1029 - "status": "pass", 1030 - }, 1031 - ], 1032 - "repeats": 2, 1033 - }, 1034 - ], 1035 - "repeated test retried on later repeat": [ 1036 - { 1037 - "entries": [ 1038 - { 1039 - "element": { 1040 - "_pwSelector": "internal:role=list", 1041 - "locator": "getByRole('list')", 1042 - "selector": "html > body > ul", 1043 - }, 1044 - "kind": "mark", 1045 - "location": "retry.test.ts:36", 1046 - "name": "renderHelper", 1047 - "snapshot": { 1048 - "selectorResolution": "matched", 1049 - }, 1050 - }, 1051 - ], 1052 - }, 1053 - { 1054 - "entries": [ 1055 - { 1056 - "kind": "lifecycle", 1057 - "location": "retry.test.ts:35", 1058 - "name": "vitest:onAfterRetryTask", 1059 - "snapshot": {}, 1060 - "status": "pass", 1061 - }, 1062 - ], 1063 - }, 1064 - { 1065 - "entries": [ 1066 - { 1067 - "element": { 1068 - "_pwSelector": "internal:role=list", 1069 - "locator": "getByRole('list')", 1070 - "selector": "html > body > ul", 1071 - }, 1072 - "kind": "mark", 1073 - "location": "retry.test.ts:36", 1074 - "name": "renderHelper", 1075 - "snapshot": { 1076 - "selectorResolution": "matched", 1077 - }, 1078 - }, 1079 - ], 1080 - "repeats": 1, 1081 - }, 1082 - { 1083 - "entries": [ 1084 - { 1085 - "kind": "lifecycle", 1086 - "location": "retry.test.ts:38", 1087 - "name": "vitest:onAfterRetryTask", 1088 - "snapshot": {}, 1089 - "status": "fail", 1090 - }, 1091 - ], 1092 - "repeats": 1, 1093 - }, 1094 - { 1095 - "entries": [ 1096 - { 1097 - "element": { 1098 - "_pwSelector": "internal:role=list", 1099 - "locator": "getByRole('list')", 1100 - "selector": "html > body > ul", 1101 - }, 1102 - "kind": "mark", 1103 - "location": "retry.test.ts:36", 1104 - "name": "renderHelper", 1105 - "snapshot": { 1106 - "selectorResolution": "matched", 1107 - }, 1108 - }, 1109 - ], 1110 - "repeats": 1, 1111 - "retry": 1, 1112 - }, 1113 - { 1114 - "entries": [ 1115 - { 1116 - "kind": "lifecycle", 1117 - "location": "retry.test.ts:35", 1118 - "name": "vitest:onAfterRetryTask", 1119 - "snapshot": {}, 1120 - "status": "pass", 1121 - }, 1122 - ], 1123 - "repeats": 1, 1124 - "retry": 1, 1125 - }, 1126 - { 1127 - "entries": [ 1128 - { 1129 - "element": { 1130 - "_pwSelector": "internal:role=list", 1131 - "locator": "getByRole('list')", 1132 - "selector": "html > body > ul", 1133 - }, 1134 - "kind": "mark", 1135 - "location": "retry.test.ts:36", 1136 - "name": "renderHelper", 1137 - "snapshot": { 1138 - "selectorResolution": "matched", 1139 - }, 1140 - }, 1141 - ], 1142 - "repeats": 2, 1143 - }, 1144 - { 1145 - "entries": [ 1146 - { 1147 - "kind": "lifecycle", 1148 - "location": "retry.test.ts:35", 1149 - "name": "vitest:onAfterRetryTask", 1150 - "snapshot": {}, 1151 - "status": "pass", 1152 - }, 1153 - ], 1154 - "repeats": 2, 1155 - }, 1156 - ], 1157 - "retried test": [ 1158 - { 1159 - "entries": [ 1160 - { 1161 - "element": { 1162 - "_pwSelector": "internal:role=list", 1163 - "locator": "getByRole('list')", 1164 - "selector": "html > body > ul", 1165 - }, 1166 - "kind": "mark", 1167 - "location": "retry.test.ts:22", 1168 - "name": "renderHelper", 1169 - "snapshot": { 1170 - "selectorResolution": "matched", 1171 - }, 1172 - }, 1173 - ], 1174 - }, 1175 - { 1176 - "entries": [ 1177 - { 1178 - "kind": "lifecycle", 1179 - "location": "retry.test.ts:24", 1180 - "name": "vitest:onAfterRetryTask", 1181 - "snapshot": {}, 1182 - "status": "fail", 1183 - }, 1184 - ], 1185 - }, 1186 - { 1187 - "entries": [ 1188 - { 1189 - "element": { 1190 - "_pwSelector": "internal:role=list", 1191 - "locator": "getByRole('list')", 1192 - "selector": "html > body > ul", 1193 - }, 1194 - "kind": "mark", 1195 - "location": "retry.test.ts:22", 1196 - "name": "renderHelper", 1197 - "snapshot": { 1198 - "selectorResolution": "matched", 1199 - }, 1200 - }, 1201 - ], 1202 - "retry": 1, 1203 - }, 1204 - { 1205 - "entries": [ 1206 - { 1207 - "kind": "lifecycle", 1208 - "location": "retry.test.ts:24", 1209 - "name": "vitest:onAfterRetryTask", 1210 - "snapshot": {}, 1211 - "status": "fail", 1212 - }, 1213 - ], 1214 - "retry": 1, 1215 - }, 1216 - { 1217 - "entries": [ 1218 - { 1219 - "element": { 1220 - "_pwSelector": "internal:role=list", 1221 - "locator": "getByRole('list')", 1222 - "selector": "html > body > ul", 1223 - }, 1224 - "kind": "mark", 1225 - "location": "retry.test.ts:22", 1226 - "name": "renderHelper", 1227 - "snapshot": { 1228 - "selectorResolution": "matched", 1229 - }, 1230 - }, 1231 - ], 1232 - "retry": 2, 1233 - }, 1234 - { 1235 - "entries": [ 1236 - { 1237 - "kind": "lifecycle", 1238 - "location": "retry.test.ts:21", 1239 - "name": "vitest:onAfterRetryTask", 1240 - "snapshot": {}, 1241 - "status": "pass", 1242 - }, 1243 - ], 1244 - "retry": 2, 1245 - }, 1246 - ], 1247 - }, 1248 - "styles.test.ts": { 1249 - "css url resources stay as urls": [ 1250 - { 1251 - "entries": [ 1252 - { 1253 - "kind": "mark", 1254 - "location": "styles.test.ts:51", 1255 - "name": "element rendered with css url resource", 1256 - "snapshot": {}, 1257 - }, 1258 - ], 1259 - }, 1260 - { 1261 - "entries": [ 1262 - { 1263 - "kind": "lifecycle", 1264 - "location": "styles.test.ts:45", 1265 - "name": "vitest:onAfterRetryTask", 1266 - "snapshot": {}, 1267 - "status": "pass", 1268 - }, 1269 - ], 1270 - }, 1271 - ], 1272 - "external stylesheet remains url dependent": [ 1273 - { 1274 - "entries": [ 1275 - { 1276 - "kind": "mark", 1277 - "location": "styles.test.ts:62", 1278 - "name": "button rendered with external stylesheet", 1279 - "snapshot": {}, 1280 - }, 1281 - ], 1282 - }, 1283 - { 1284 - "entries": [ 1285 - { 1286 - "kind": "lifecycle", 1287 - "location": "styles.test.ts:55", 1288 - "name": "vitest:onAfterRetryTask", 1289 - "snapshot": {}, 1290 - "status": "pass", 1291 - }, 1292 - ], 1293 - }, 1294 - ], 1295 - "font files remain url dependent": [ 1296 - { 1297 - "entries": [ 1298 - { 1299 - "kind": "mark", 1300 - "location": "styles.test.ts:80", 1301 - "name": "button rendered with font-face url", 1302 - "snapshot": {}, 1303 - }, 1304 - ], 1305 - }, 1306 - { 1307 - "entries": [ 1308 - { 1309 - "kind": "lifecycle", 1310 - "location": "styles.test.ts:66", 1311 - "name": "vitest:onAfterRetryTask", 1312 - "snapshot": {}, 1313 - "status": "pass", 1314 - }, 1315 - ], 1316 - }, 1317 - ], 1318 - "inline styles": [ 1319 - { 1320 - "entries": [ 1321 - { 1322 - "kind": "mark", 1323 - "location": "styles.test.ts:11", 1324 - "name": "button rendered with css", 1325 - "snapshot": {}, 1326 - }, 1327 - ], 1328 - }, 1329 - { 1330 - "entries": [ 1331 - { 1332 - "kind": "lifecycle", 1333 - "location": "styles.test.ts:9", 1334 - "name": "vitest:onAfterRetryTask", 1335 - "snapshot": {}, 1336 - "status": "pass", 1337 - }, 1338 - ], 1339 - }, 1340 - ], 1341 - "same-origin link css is inlined": [ 1342 - { 1343 - "entries": [ 1344 - { 1345 - "kind": "mark", 1346 - "location": "styles.test.ts:41", 1347 - "name": "button rendered with same-origin linked css", 1348 - "snapshot": {}, 1349 - }, 1350 - ], 1351 - }, 1352 - { 1353 - "entries": [ 1354 - { 1355 - "kind": "lifecycle", 1356 - "location": "styles.test.ts:32", 1357 - "name": "vitest:onAfterRetryTask", 1358 - "snapshot": {}, 1359 - "status": "pass", 1360 - }, 1361 - ], 1362 - }, 1363 - ], 1364 - "snapshot-time pseudo-state styles": [ 1365 - { 1366 - "entries": [ 1367 - { 1368 - "element": { 1369 - "_pwSelector": "internal:role=button[name="First pseudo state"s]", 1370 - "locator": "getByRole('button', { name: 'First pseudo state' })", 1371 - "selector": "html > body > button:nth-child(1)", 1372 - }, 1373 - "kind": "expect", 1374 - "location": "styles.test.ts:101", 1375 - "name": "toHaveStyle", 1376 - "range": { 1377 - "phase": "start", 1378 - }, 1379 - "snapshot": { 1380 - "selectorResolution": "matched", 1381 - }, 1382 - }, 1383 - ], 1384 - }, 1385 - { 1386 - "entries": [ 1387 - { 1388 - "element": { 1389 - "_pwSelector": "internal:role=button[name="First pseudo state"s]", 1390 - "locator": "getByRole('button', { name: 'First pseudo state' })", 1391 - "selector": "html > body > button:nth-child(1)", 1392 - }, 1393 - "kind": "expect", 1394 - "location": "styles.test.ts:101", 1395 - "name": "toHaveStyle", 1396 - "range": { 1397 - "phase": "end", 1398 - }, 1399 - "snapshot": { 1400 - "selectorResolution": "matched", 1401 - }, 1402 - "status": "pass", 1403 - }, 1404 - ], 1405 - }, 1406 - { 1407 - "entries": [ 1408 - { 1409 - "element": { 1410 - "_pwSelector": "internal:role=button[name="First pseudo state"s]", 1411 - "locator": "getByRole('button', { name: 'First pseudo state' })", 1412 - "selector": "html > body > button:nth-child(1)", 1413 - }, 1414 - "kind": "action", 1415 - "location": "styles.test.ts:104", 1416 - "name": "vitest:hover", 1417 - "range": { 1418 - "phase": "start", 1419 - }, 1420 - "snapshot": { 1421 - "selectorResolution": "matched", 1422 - }, 1423 - }, 1424 - ], 1425 - }, 1426 - { 1427 - "entries": [ 1428 - { 1429 - "element": { 1430 - "_pwSelector": "internal:role=button[name="First pseudo state"s]", 1431 - "locator": "getByRole('button', { name: 'First pseudo state' })", 1432 - "selector": "html > body > button:nth-child(1)", 1433 - }, 1434 - "kind": "action", 1435 - "location": "styles.test.ts:104", 1436 - "name": "vitest:hover", 1437 - "range": { 1438 - "phase": "end", 1439 - }, 1440 - "snapshot": { 1441 - "selectorResolution": "matched", 1442 - }, 1443 - "status": "pass", 1444 - }, 1445 - ], 1446 - }, 1447 - { 1448 - "entries": [ 1449 - { 1450 - "element": { 1451 - "_pwSelector": "internal:role=button[name="Second pseudo state"s]", 1452 - "locator": "getByRole('button', { name: 'Second pseudo state' })", 1453 - "selector": "html > body > button:nth-child(2)", 1454 - }, 1455 - "kind": "action", 1456 - "location": "styles.test.ts:105", 1457 - "name": "vitest:click", 1458 - "range": { 1459 - "phase": "start", 1460 - }, 1461 - "snapshot": { 1462 - "selectorResolution": "matched", 1463 - }, 1464 - }, 1465 - ], 1466 - }, 1467 - { 1468 - "entries": [ 1469 - { 1470 - "element": { 1471 - "_pwSelector": "internal:role=button[name="Second pseudo state"s]", 1472 - "locator": "getByRole('button', { name: 'Second pseudo state' })", 1473 - "selector": "html > body > button:nth-child(2)", 1474 - }, 1475 - "kind": "action", 1476 - "location": "styles.test.ts:105", 1477 - "name": "vitest:click", 1478 - "range": { 1479 - "phase": "end", 1480 - }, 1481 - "snapshot": { 1482 - "selectorResolution": "matched", 1483 - }, 1484 - "status": "pass", 1485 - }, 1486 - ], 1487 - }, 1488 - { 1489 - "entries": [ 1490 - { 1491 - "element": { 1492 - "_pwSelector": "internal:role=textbox[name="Focused pseudo state"s]", 1493 - "locator": "getByRole('textbox', { name: 'Focused pseudo state' })", 1494 - "selector": "html > body > input", 1495 - }, 1496 - "kind": "action", 1497 - "location": "styles.test.ts:106", 1498 - "name": "vitest:fill", 1499 - "range": { 1500 - "phase": "start", 1501 - }, 1502 - "snapshot": { 1503 - "selectorResolution": "matched", 1504 - }, 1505 - }, 1506 - ], 1507 - }, 1508 - { 1509 - "entries": [ 1510 - { 1511 - "element": { 1512 - "_pwSelector": "internal:role=textbox[name="Focused pseudo state"s]", 1513 - "locator": "getByRole('textbox', { name: 'Focused pseudo state' })", 1514 - "selector": "html > body > input", 1515 - }, 1516 - "kind": "action", 1517 - "location": "styles.test.ts:106", 1518 - "name": "vitest:fill", 1519 - "range": { 1520 - "phase": "end", 1521 - }, 1522 - "snapshot": { 1523 - "selectorResolution": "matched", 1524 - }, 1525 - "status": "pass", 1526 - }, 1527 - ], 1528 - }, 1529 - { 1530 - "entries": [ 1531 - { 1532 - "element": { 1533 - "_pwSelector": "internal:role=textbox[name="Focus within pseudo state"s]", 1534 - "locator": "getByRole('textbox', { name: 'Focus within pseudo state' })", 1535 - "selector": "html > body > label > input", 1536 - }, 1537 - "kind": "action", 1538 - "location": "styles.test.ts:107", 1539 - "name": "vitest:fill", 1540 - "range": { 1541 - "phase": "start", 1542 - }, 1543 - "snapshot": { 1544 - "selectorResolution": "matched", 1545 - }, 1546 - }, 1547 - ], 1548 - }, 1549 - { 1550 - "entries": [ 1551 - { 1552 - "element": { 1553 - "_pwSelector": "internal:role=textbox[name="Focus within pseudo state"s]", 1554 - "locator": "getByRole('textbox', { name: 'Focus within pseudo state' })", 1555 - "selector": "html > body > label > input", 1556 - }, 1557 - "kind": "action", 1558 - "location": "styles.test.ts:107", 1559 - "name": "vitest:fill", 1560 - "range": { 1561 - "phase": "end", 1562 - }, 1563 - "snapshot": { 1564 - "selectorResolution": "matched", 1565 - }, 1566 - "status": "pass", 1567 - }, 1568 - ], 1569 - }, 1570 - { 1571 - "entries": [ 1572 - { 1573 - "kind": "lifecycle", 1574 - "location": "styles.test.ts:83", 1575 - "name": "vitest:onAfterRetryTask", 1576 - "snapshot": {}, 1577 - "status": "pass", 1578 - }, 1579 - ], 1580 - }, 1581 - ], 1582 - "style tag css is inlined": [ 1583 - { 1584 - "entries": [ 1585 - { 1586 - "kind": "mark", 1587 - "location": "styles.test.ts:29", 1588 - "name": "button rendered with style tag css", 1589 - "snapshot": {}, 1590 - }, 1591 - ], 1592 - }, 1593 - { 1594 - "entries": [ 1595 - { 1596 - "kind": "lifecycle", 1597 - "location": "styles.test.ts:14", 1598 - "name": "vitest:onAfterRetryTask", 1599 - "snapshot": {}, 1600 - "status": "pass", 1601 - }, 1602 - ], 1603 - }, 1604 - ], 1605 - }, 1606 - "viewport.test.ts": { 1607 - "document scroll is restored from trace metadata": [ 1608 - { 1609 - "entries": [ 1610 - { 1611 - "element": { 1612 - "_pwSelector": "internal:role=button", 1613 - "locator": "getByRole('button')", 1614 - "selector": "html > body > main > button", 1615 - }, 1616 - "kind": "mark", 1617 - "location": "viewport.test.ts:31", 1618 - "name": "document scrolled before mark", 1619 - "snapshot": { 1620 - "selectorResolution": "matched", 1621 - }, 1622 - }, 1623 - ], 1624 - }, 1625 - { 1626 - "entries": [ 1627 - { 1628 - "kind": "lifecycle", 1629 - "location": "viewport.test.ts:24", 1630 - "name": "vitest:onAfterRetryTask", 1631 - "snapshot": {}, 1632 - "status": "pass", 1633 - }, 1634 - ], 1635 - }, 1636 - ], 1637 - "overflow element scroll is stored in snapshot payload": [ 1638 - { 1639 - "entries": [ 1640 - { 1641 - "element": { 1642 - "_pwSelector": "internal:testid=[data-testid="scroll-box"s]", 1643 - "locator": "getByTestId('scroll-box')", 1644 - "selector": "html > body > section", 1645 - }, 1646 - "kind": "mark", 1647 - "location": "viewport.test.ts:47", 1648 - "name": "overflow container scrolled before mark", 1649 - "snapshot": { 1650 - "selectorResolution": "matched", 1651 - }, 1652 - }, 1653 - ], 1654 - }, 1655 - { 1656 - "entries": [ 1657 - { 1658 - "kind": "lifecycle", 1659 - "location": "viewport.test.ts:34", 1660 - "name": "vitest:onAfterRetryTask", 1661 - "snapshot": {}, 1662 - "status": "pass", 1663 - }, 1664 - ], 1665 - }, 1666 - ], 1667 - "viewport media query depends on replay viewport": [ 1668 - { 1669 - "entries": [ 1670 - { 1671 - "kind": "mark", 1672 - "location": "viewport.test.ts:21", 1673 - "name": "viewport sensitive layout rendered", 1674 - "snapshot": {}, 1675 - }, 1676 - ], 1677 - }, 1678 - { 1679 - "entries": [ 1680 - { 1681 - "kind": "lifecycle", 1682 - "location": "viewport.test.ts:10", 1683 - "name": "vitest:onAfterRetryTask", 1684 - "snapshot": {}, 1685 - "status": "pass", 1686 - }, 1687 - ], 1688 - }, 1689 - ], 1690 - }, 1691 - } 1692 - `) 1693 - } 1694 145 if (provider.name === 'playwright') { 1695 146 expect.soft(projectArtifactTree[browser], browser).toMatchInlineSnapshot(` 1696 147 { ··· 1704 155 "selector": "internal:role=button", 1705 156 }, 1706 157 "kind": "mark", 1707 - "location": "exotic.test.ts:58", 158 + "location": "exotic.test.ts:54", 1708 159 "name": "button rendered with adopted stylesheet", 1709 160 "snapshot": { 1710 161 "selectorResolution": "matched", ··· 1716 167 "entries": [ 1717 168 { 1718 169 "kind": "lifecycle", 1719 - "location": "exotic.test.ts:51", 170 + "location": "exotic.test.ts:47", 1720 171 "name": "vitest:onAfterRetryTask", 1721 172 "snapshot": {}, 1722 173 "status": "pass", ··· 1762 213 "selector": "internal:role=button[name="Custom element button"s]", 1763 214 }, 1764 215 "kind": "mark", 1765 - "location": "exotic.test.ts:47", 216 + "location": "exotic.test.ts:43", 1766 217 "name": "custom element rendered", 1767 218 "snapshot": { 1768 219 "selectorResolution": "matched", ··· 1774 225 "entries": [ 1775 226 { 1776 227 "kind": "lifecycle", 1777 - "location": "exotic.test.ts:32", 228 + "location": "exotic.test.ts:30", 1778 229 "name": "vitest:onAfterRetryTask", 1779 230 "snapshot": {}, 1780 231 "status": "pass", ··· 1791 242 "selector": "internal:role=button[name="Shadow button"s]", 1792 243 }, 1793 244 "kind": "mark", 1794 - "location": "exotic.test.ts:28", 245 + "location": "exotic.test.ts:26", 1795 246 "name": "shadow button rendered", 1796 247 "snapshot": { 1797 248 "selectorResolution": "matched", ··· 1874 325 "selector": "internal:role=button[name="Missing"s]", 1875 326 }, 1876 327 "kind": "action", 1877 - "location": "expect.test.ts:33", 328 + "location": "expect.test.ts:31", 1878 329 "name": "vitest:click", 1879 330 "range": { 1880 331 "phase": "start", ··· 1893 344 "selector": "internal:role=button[name="Missing"s]", 1894 345 }, 1895 346 "kind": "action", 1896 - "location": "expect.test.ts:33", 347 + "location": "expect.test.ts:31", 1897 348 "name": "vitest:click", 1898 349 "range": { 1899 350 "phase": "end", ··· 1909 360 "entries": [ 1910 361 { 1911 362 "kind": "lifecycle", 1912 - "location": "expect.test.ts:33", 363 + "location": "expect.test.ts:31", 1913 364 "name": "vitest:onAfterRetryTask", 1914 365 "snapshot": {}, 1915 366 "status": "fail",
+1 -20
test/browser/test/dom.test.ts
··· 1 1 import { createNode } from '#src/createNode' 2 2 import { afterAll, beforeEach, describe, expect, test } from 'vitest' 3 - import { page, server } from 'vitest/browser' 3 + import { page } from 'vitest/browser' 4 4 import '../src/button.css' 5 5 6 6 afterAll(() => { ··· 114 114 expect(screenshotPath).toMatch( 115 115 /__screenshots__\/dom.test.ts\/dom-related-activity-svg-screenshot-1.png/, 116 116 ) 117 - }) 118 - 119 - test.runIf(server.provider === 'webdriverio')('shadow dom works with multiple elements', async () => { 120 - const wrapper = createWrapper() 121 - const div = createNode() 122 - wrapper.appendChild(div) 123 - 124 - const shadow = div.attachShadow({ mode: 'open' }) 125 - const shadowDiv1 = createNode() 126 - shadowDiv1.role = 'tab' 127 - const shadowDiv2 = createNode() 128 - shadowDiv2.role = 'tab' 129 - shadow.appendChild(shadowDiv1) 130 - shadow.appendChild(shadowDiv2) 131 - 132 - expect( 133 - page.getByRole('tab').selector, 134 - 'there is only a single >>> in the selector', 135 - ).toBe('>>>html > body > div > div > div, html > body > div > div > div') 136 117 }) 137 118 }) 138 119
+5 -11
test/browser/test/userEvent.test.ts
··· 767 767 ]) 768 768 }) 769 769 770 - // looks like wdio doesn't support releasing Enter on its own 771 770 test('should not auto release', async () => { 772 771 const spyKeydown = vi.fn() 773 772 const spyKeyup = vi.fn() ··· 928 927 expect(select.value).toBe('2') 929 928 }) 930 929 931 - // webdriverio doesn't support selecting multiple values 932 - describe.skipIf(server.provider === 'webdriverio')('multiple values', () => { 930 + describe('multiple values', () => { 933 931 test('can select multiple values', async () => { 934 932 const { select, options } = createSelect() 935 933 select.multiple = true ··· 972 970 }) 973 971 974 972 describe('uploading files', async () => { 975 - test.skipIf(server.provider === 'webdriverio')('can upload an instance of File', async () => { 973 + test('can upload an instance of File', async () => { 976 974 const file = new File(['hello'], 'hello.png', { type: 'image/png' }) 977 975 const input = document.createElement('input') 978 976 input.id = 'file' ··· 987 985 expect(await uploadedFile.text()).toBe('hello') 988 986 }) 989 987 990 - test.skipIf(server.provider === 'webdriverio')('can upload several instances of File', async () => { 988 + test('can upload several instances of File', async () => { 991 989 const file1 = new File(['hello1'], 'hello1.png', { type: 'image/png' }) 992 990 const file2 = new File(['hello2'], 'hello2.png', { type: 'image/png' }) 993 991 const input = document.createElement('input') ··· 1007 1005 expect(uploadedFile2.type).toBe('image/png') 1008 1006 }) 1009 1007 1010 - test.skipIf( 1011 - server.provider === 'webdriverio' && server.browser === 'firefox', 1012 - )('can upload a file by filepath relative to test file', async () => { 1008 + test('can upload a file by filepath relative to test file', async () => { 1013 1009 const input = document.createElement('input') 1014 1010 input.id = 'file' 1015 1011 input.type = 'file' ··· 1022 1018 expect(uploadedFile.type).toBe('text/css') 1023 1019 }) 1024 1020 1025 - test.skipIf( 1026 - server.provider === 'webdriverio' && server.browser === 'firefox', 1027 - )('can upload several files by filepath relative to test file', async () => { 1021 + test('can upload several files by filepath relative to test file', async () => { 1028 1022 const input = document.createElement('input') 1029 1023 input.id = 'file' 1030 1024 input.type = 'file'
+7 -15
test/e2e/test/failures.test.ts
··· 1 1 import type { RunVitestConfig, VitestRunnerCLIOptions } from '../../test-utils' 2 2 import { playwright } from '@vitest/browser-playwright' 3 3 import { preview } from '@vitest/browser-preview' 4 - import { webdriverio } from '@vitest/browser-webdriverio' 5 4 import { normalize, resolve } from 'pathe' 6 5 import { beforeEach, expect, test } from 'vitest' 7 6 import { version } from 'vitest/package.json' ··· 9 8 10 9 const providers = [ 11 10 playwright(), 12 - webdriverio(), 13 11 preview(), 14 12 ] as const 15 - const names = ['edge', 'chromium', 'webkit', 'chrome', 'firefox', 'safari'] as const 13 + const names = ['chromium', 'webkit', 'firefox'] as const 16 14 const browsers = providers.map(provider => names.map(name => ({ name, provider }))).flat() 17 15 18 16 function runVitest(config: RunVitestConfig, runnerOptions?: VitestRunnerCLIOptions) { ··· 109 107 if (provider.name === 'playwright' && name === 'chromium') { 110 108 continue 111 109 } 112 - if (provider.name === 'webdriverio' && (name === 'chrome' || name === 'edge')) { 113 - continue 114 - } 115 110 116 111 const { stderr } = await runVitest({ 117 112 [option]: true, ··· 137 132 Use either: 138 133 { 139 134 browser: { 140 - provider: ${provider.name === 'preview' ? 'playwright' : provider.name}(), 135 + provider: playwright(), 141 136 instances: [ 142 - { browser: '${(provider.name === 'preview' || provider.name === 'playwright') ? 'chromium' : 'chrome'}' } 137 + { browser: 'chromium' } 143 138 ], 144 139 }, 145 140 } ··· 155 150 browsers.filter(({ provider, name }) => { 156 151 if (provider.name === 'playwright') { 157 152 return name !== 'chromium' 158 - } 159 - if (provider.name === 'webdriverio') { 160 - return name !== 'chrome' && name !== 'edge' 161 153 } 162 154 return true 163 155 }), ··· 187 179 Use either: 188 180 { 189 181 browser: { 190 - provider: ${provider.name === 'preview' ? 'playwright' : provider.name}(), 182 + provider: playwright(), 191 183 instances: [ 192 - { browser: '${(provider.name === 'preview' || provider.name === 'playwright') ? 'chromium' : 'chrome'}' } 184 + { browser: 'chromium' } 193 185 ], 194 186 }, 195 187 } ··· 262 254 name: 'Browser project', 263 255 browser: { 264 256 enabled: true, 265 - provider: webdriverio(), 257 + provider: playwright(), 266 258 instances: [{ browser: 'webkit' }], 267 259 }, 268 260 }, ··· 273 265 `Error: @vitest/coverage-v8 does not work with 274 266 { 275 267 browser: { 276 - provider: webdriverio(), 268 + provider: playwright(), 277 269 instances: [ 278 270 { browser: 'webkit' } 279 271 ],
+17 -101
test/e2e/test/mocking.test.ts
··· 1 1 import type { RunVitestConfig } from '../../test-utils' 2 - import { setDefaultResultOrder } from 'node:dns' 3 2 import path from 'node:path' 4 3 import { playwright } from '@vitest/browser-playwright' 5 - import { webdriverio } from '@vitest/browser-webdriverio' 6 - import { afterAll, expect, test } from 'vitest' 4 + import { expect, test } from 'vitest' 7 5 import { rolldownVersion } from 'vitest/node' 8 6 import { runInlineTests, runVitest } from '../../test-utils' 9 - 10 - // webdriver@9 sets dns.setDefaultResultOrder("ipv4first") on import, 11 - // which makes Vite resolve localhost to 127.0.0.1 and breaks other tests asserting "localhost" 12 - afterAll(() => setDefaultResultOrder('verbatim')) 13 7 14 8 test('setting resetMocks works if restoreMocks is also set', async () => { 15 9 const { stderr, testTree } = await runInlineTests({ ··· 146 140 `) 147 141 }) 148 142 149 - function replaceRoot(tree: any, root: string): any { 150 - for (const child of Object.values(tree) as any[]) { 151 - if (child?.__module_errors__) { 152 - child.__module_errors__ = child.__module_errors__.map((e: string) => e.replace(root, '<root>')) 153 - } 154 - } 155 - return tree 156 - } 157 - 158 143 function modeToConfig(mode: string): RunVitestConfig { 159 144 if (mode === 'playwright') { 160 145 return { ··· 166 151 }, 167 152 } 168 153 } 169 - if (mode === 'webdriverio') { 170 - return { 171 - browser: { 172 - enabled: true, 173 - provider: webdriverio({ 174 - ...(process.env.CHROMEDRIVER_PATH && process.env.CHROME_BIN 175 - ? { 176 - 'wdio:chromedriverOptions': { 177 - binary: process.env.CHROMEDRIVER_PATH, 178 - }, 179 - 'capabilities': { 180 - 'goog:chromeOptions': { 181 - binary: process.env.CHROME_BIN, 182 - }, 183 - }, 184 - } 185 - : {}), 186 - }), 187 - instances: [{ browser: 'chrome' }], 188 - headless: true, 189 - }, 190 - } 191 - } 192 154 return {} 193 155 } 194 156 195 - test.for(['node', 'playwright', 'webdriverio'])('importOriginal for virtual modules (%s)', async (mode) => { 196 - const { stderr, errorTree, root } = await runInlineTests({ 157 + test.for(['node', 'playwright'])('importOriginal for virtual modules (%s)', async (mode) => { 158 + const { stderr, errorTree } = await runInlineTests({ 197 159 'vitest.config.js': ` 198 160 import { defineConfig } from 'vitest/config' 199 161 export default defineConfig({ ··· 227 189 `, 228 190 }, modeToConfig(mode)) 229 191 230 - // webdriverio uses a server-side interceptor plugin whose load hook 231 - // intercepts the clean id, so importActual returns the mock instead 232 - // of the original module. This is a known limitation. 233 - if (mode === 'webdriverio') { 234 - expect(replaceRoot(errorTree(), root)).toMatchInlineSnapshot(` 235 - { 236 - "__unhandled_errors__": [ 237 - "[vitest] There was an error when mocking a module. If you are using "vi.mock" factory, make sure there are no top level variables inside, since this call is hoisted to top of the file. Read more: https://vitest.dev/api/vi.html#vi-mock", 238 - ], 239 - "basic.test.js": { 240 - "__module_errors__": [ 241 - "Failed to import test file <root>/basic.test.js", 242 - ], 243 - }, 244 - } 245 - `) 246 - } 247 - else { 248 - expect(stderr).toBe('') 249 - expect(errorTree()).toMatchInlineSnapshot(` 250 - { 251 - "basic.test.js": { 252 - "importOriginal returns original virtual module exports": "passed", 253 - }, 254 - } 255 - `) 256 - } 192 + expect(stderr).toBe('') 193 + expect(errorTree()).toMatchInlineSnapshot(` 194 + { 195 + "basic.test.js": { 196 + "importOriginal returns original virtual module exports": "passed", 197 + }, 198 + } 199 + `) 257 200 }) 258 201 259 - test.for(['node', 'playwright', 'webdriverio'])('mocking virtual module without importOriginal skips loading original (%s)', async (mode) => { 202 + test.for(['node', 'playwright'])('mocking virtual module without importOriginal skips loading original (%s)', async (mode) => { 260 203 const { stderr, testTree } = await runInlineTests({ 261 204 'vitest.config.js': ` 262 205 import { defineConfig } from 'vitest/config' ··· 300 243 `) 301 244 }) 302 245 303 - test.for(['node', 'playwright', 'webdriverio'])('mocking actual module with factory skips loading original (%s)', async (mode) => { 304 - const { stderr, errorTree, root } = await runInlineTests({ 246 + test.for(['node', 'playwright'])('mocking actual module with factory skips loading original (%s)', async (mode) => { 247 + const { stderr, errorTree } = await runInlineTests({ 305 248 'vitest.config.js': ` 306 249 import { defineConfig } from 'vitest/config' 307 250 export default defineConfig({ ··· 330 273 `, 331 274 }, modeToConfig(mode)) 332 275 333 - if (mode === 'webdriverio') { 334 - expect(replaceRoot(errorTree(), root)).toMatchInlineSnapshot(` 335 - { 336 - "basic.test.js": { 337 - "__module_errors__": [ 338 - "Failed to import test file <root>/basic.test.js", 339 - ], 340 - }, 341 - } 342 - `) 343 - return 344 - } 345 - 346 276 expect(stderr).toBe('') 347 277 expect(errorTree()).toMatchInlineSnapshot(` 348 278 { ··· 353 283 `) 354 284 }) 355 285 356 - test.for(['node', 'playwright', 'webdriverio'])('mocking actual module via __mocks__ skips loading original (%s)', async (mode) => { 357 - const { stderr, errorTree, root } = await runInlineTests({ 286 + test.for(['node', 'playwright'])('mocking actual module via __mocks__ skips loading original (%s)', async (mode) => { 287 + const { stderr, errorTree } = await runInlineTests({ 358 288 'vitest.config.js': ` 359 289 import { defineConfig } from 'vitest/config' 360 290 export default defineConfig({ ··· 381 311 }) 382 312 `, 383 313 }, modeToConfig(mode)) 384 - 385 - if (mode === 'webdriverio') { 386 - expect(replaceRoot(errorTree(), root)).toMatchInlineSnapshot(` 387 - { 388 - "basic.test.js": { 389 - "__module_errors__": [ 390 - "Failed to import test file <root>/basic.test.js", 391 - ], 392 - }, 393 - } 394 - `) 395 - return 396 - } 397 314 398 315 expect(stderr).toBe('') 399 316 expect(errorTree()).toMatchInlineSnapshot(` ··· 449 366 test.for([ 450 367 'node', 451 368 'playwright', 452 - 'webdriverio', 453 369 ])('repeating mock, importActual, and resetModules (%s)', async (mode) => { 454 370 const { stderr, errorTree } = await runInlineTests({ 455 371 // external ··· 551 467 './local.js': `export const local = 'local'`, 552 468 }, modeToConfig(mode)) 553 469 554 - if (mode === 'webdriverio' || mode === 'playwright') { 470 + if (mode === 'playwright') { 555 471 // browser mode doesn't support resetModules nor node builtin 556 472 expect(errorTree()).toMatchInlineSnapshot(` 557 473 {
-10
packages/browser-webdriverio/src/commands/clear.ts
··· 1 - import type { UserEvent } from 'vitest/browser' 2 - import type { UserEventCommand } from './utils' 3 - 4 - export const clear: UserEventCommand<UserEvent['clear']> = async ( 5 - context, 6 - { selector }, 7 - ) => { 8 - const browser = context.browser 9 - await browser.$(selector).clearValue() 10 - }
-44
packages/browser-webdriverio/src/commands/click.ts
··· 1 - import type { UserEvent } from 'vitest/browser' 2 - import type { UserEventCommand } from './utils' 3 - 4 - export const click: UserEventCommand<UserEvent['click']> = async ( 5 - context, 6 - { selector }, 7 - options, 8 - ) => { 9 - const browser = context.browser 10 - await browser.$(selector).click(options) 11 - } 12 - 13 - export const dblClick: UserEventCommand<UserEvent['dblClick']> = async ( 14 - context, 15 - { selector }, 16 - _options, 17 - ) => { 18 - const browser = context.browser 19 - await browser.$(selector).doubleClick() 20 - } 21 - 22 - export const tripleClick: UserEventCommand<UserEvent['tripleClick']> = async ( 23 - context, 24 - { selector }, 25 - _options, 26 - ) => { 27 - const browser = context.browser 28 - await browser 29 - .action('pointer', { parameters: { pointerType: 'mouse' } }) 30 - // move the pointer over the button 31 - .move({ origin: browser.$(selector) }) 32 - // simulate 3 clicks 33 - .down() 34 - .up() 35 - .pause(50) 36 - .down() 37 - .up() 38 - .pause(50) 39 - .down() 40 - .up() 41 - .pause(50) 42 - // run the sequence 43 - .perform() 44 - }
-27
packages/browser-webdriverio/src/commands/dragAndDrop.ts
··· 1 - import type { UserEvent } from 'vitest/browser' 2 - import type { UserEventCommand } from './utils' 3 - 4 - export const dragAndDrop: UserEventCommand<UserEvent['dragAndDrop']> = async ( 5 - context, 6 - { selector: source }, 7 - { selector: target }, 8 - options_, 9 - ) => { 10 - const $source = context.browser.$(source) 11 - const $target = context.browser.$(target) 12 - const options = (options_ || {}) as any 13 - const duration = options.duration ?? 10 14 - 15 - // https://github.com/webdriverio/webdriverio/issues/8022#issuecomment-1700919670 16 - await context.browser 17 - .action('pointer') 18 - .move({ duration: 0, origin: $source, x: options.sourceX ?? 0, y: options.sourceY ?? 0 }) 19 - .down({ button: 0 }) 20 - .move({ duration: 0, origin: 'pointer', x: 0, y: 0 }) 21 - .pause(duration) 22 - .move({ duration: 0, origin: $target, x: options.targetX ?? 0, y: options.targetY ?? 0 }) 23 - .move({ duration: 0, origin: 'pointer', x: 1, y: 0 }) 24 - .move({ duration: 0, origin: 'pointer', x: -1, y: 0 }) 25 - .up({ button: 0 }) 26 - .perform() 27 - }
-12
packages/browser-webdriverio/src/commands/fill.ts
··· 1 - import type { UserEvent } from 'vitest/browser' 2 - import type { UserEventCommand } from './utils' 3 - 4 - export const fill: UserEventCommand<UserEvent['fill']> = async ( 5 - context, 6 - { selector }, 7 - text, 8 - _options = {}, 9 - ) => { 10 - const browser = context.browser 11 - await browser.$(selector).setValue(text) 12 - }
-11
packages/browser-webdriverio/src/commands/hover.ts
··· 1 - import type { UserEvent } from 'vitest/browser' 2 - import type { UserEventCommand } from './utils' 3 - 4 - export const hover: UserEventCommand<UserEvent['hover']> = async ( 5 - context, 6 - { selector }, 7 - options = {}, 8 - ) => { 9 - const browser = context.browser 10 - await browser.$(selector).moveTo(options as any) 11 - }
-32
packages/browser-webdriverio/src/commands/index.ts
··· 1 - import { clear } from './clear' 2 - import { click, dblClick, tripleClick } from './click' 3 - import { dragAndDrop } from './dragAndDrop' 4 - import { fill } from './fill' 5 - import { hover } from './hover' 6 - import { keyboard, keyboardCleanup } from './keyboard' 7 - import { takeScreenshot } from './screenshot' 8 - import { selectOptions } from './select' 9 - import { tab } from './tab' 10 - import { type } from './type' 11 - import { upload } from './upload' 12 - import { viewport } from './viewport' 13 - import { wheel } from './wheel' 14 - 15 - export default { 16 - __vitest_upload: upload as typeof upload, 17 - __vitest_click: click as typeof click, 18 - __vitest_dblClick: dblClick as typeof dblClick, 19 - __vitest_tripleClick: tripleClick as typeof tripleClick, 20 - __vitest_wheel: wheel as typeof wheel, 21 - __vitest_takeScreenshot: takeScreenshot as typeof takeScreenshot, 22 - __vitest_type: type as typeof type, 23 - __vitest_clear: clear as typeof clear, 24 - __vitest_fill: fill as typeof fill, 25 - __vitest_tab: tab as typeof tab, 26 - __vitest_keyboard: keyboard as typeof keyboard, 27 - __vitest_selectOptions: selectOptions as typeof selectOptions, 28 - __vitest_dragAndDrop: dragAndDrop as typeof dragAndDrop, 29 - __vitest_hover: hover as typeof hover, 30 - __vitest_cleanup: keyboardCleanup as typeof keyboardCleanup, 31 - __vitest_viewport: viewport as typeof viewport, 32 - }
-125
packages/browser-webdriverio/src/commands/keyboard.ts
··· 1 - import type { BrowserProvider } from 'vitest/node' 2 - import type { WebdriverBrowserProvider } from '../webdriverio' 3 - import type { UserEventCommand } from './utils' 4 - import { parseKeyDef } from '@vitest/browser' 5 - import { Key } from 'webdriverio' 6 - 7 - export interface KeyboardState { 8 - unreleased: string[] 9 - } 10 - 11 - export const keyboard: UserEventCommand<( 12 - text: string, 13 - state: KeyboardState, 14 - ) => Promise<{ unreleased: string[] }>> = async ( 15 - context, 16 - text, 17 - state, 18 - ) => { 19 - await context.browser.execute(focusIframe) 20 - 21 - const pressed = new Set<string>(state.unreleased) 22 - 23 - await keyboardImplementation( 24 - pressed, 25 - context.provider, 26 - context.sessionId, 27 - text, 28 - async () => { 29 - await context.browser.execute(selectAll) 30 - }, 31 - true, 32 - ) 33 - 34 - return { 35 - unreleased: Array.from(pressed), 36 - } 37 - } 38 - 39 - export const keyboardCleanup: UserEventCommand<(state: KeyboardState) => Promise<void>> = async ( 40 - context, 41 - state, 42 - ) => { 43 - if (!state.unreleased) { 44 - return 45 - } 46 - const keyboard = context.browser.action('key') 47 - for (const key of state.unreleased) { 48 - keyboard.up(key) 49 - } 50 - await keyboard.perform() 51 - } 52 - 53 - export async function keyboardImplementation( 54 - pressed: Set<string>, 55 - provider: BrowserProvider, 56 - _sessionId: string, 57 - text: string, 58 - selectAll: () => Promise<void>, 59 - skipRelease: boolean, 60 - ): Promise<{ pressed: Set<string> }> { 61 - const browser = (provider as WebdriverBrowserProvider).browser! 62 - const actions = parseKeyDef(text) 63 - 64 - let keyboard = browser.action('key') 65 - 66 - for (const { releasePrevious, releaseSelf, repeat, keyDef } of actions) { 67 - let key = keyDef.key! 68 - const special = Key[key as 'Shift'] 69 - 70 - if (special) { 71 - key = special 72 - } 73 - 74 - if (pressed.has(key)) { 75 - keyboard.up(key) 76 - pressed.delete(key) 77 - } 78 - 79 - if (!releasePrevious) { 80 - if (key === 'selectall') { 81 - await keyboard.perform() 82 - keyboard = browser.action('key') 83 - await selectAll() 84 - continue 85 - } 86 - 87 - for (let i = 1; i <= repeat; i++) { 88 - keyboard.down(key) 89 - } 90 - 91 - if (releaseSelf) { 92 - keyboard.up(key) 93 - } 94 - else { 95 - pressed.add(key) 96 - } 97 - } 98 - } 99 - 100 - // seems like webdriverio doesn't release keys automatically if skipRelease is true and all events are keyUp 101 - const allRelease = keyboard.toJSON().actions.every(action => action.type === 'keyUp') 102 - 103 - await keyboard.perform(allRelease ? false : skipRelease) 104 - 105 - return { 106 - pressed, 107 - } 108 - } 109 - 110 - function focusIframe() { 111 - if ( 112 - !document.activeElement 113 - || document.activeElement.ownerDocument !== document 114 - || document.activeElement === document.body 115 - ) { 116 - window.focus() 117 - } 118 - } 119 - 120 - function selectAll() { 121 - const element = document.activeElement as HTMLInputElement 122 - if (element && typeof element.select === 'function') { 123 - element.select() 124 - } 125 - }
-74
packages/browser-webdriverio/src/commands/screenshot.ts
··· 1 - import type { SerializedLocator } from '@vitest/browser' 2 - import type { ScreenshotOptions } from 'vitest/browser' 3 - import type { BrowserCommandContext } from 'vitest/node' 4 - import crypto from 'node:crypto' 5 - import { mkdir, rm } from 'node:fs/promises' 6 - import { normalize as platformNormalize } from 'node:path' 7 - import { resolveScreenshotPath } from '@vitest/browser' 8 - import { dirname, normalize, resolve } from 'pathe' 9 - 10 - interface ScreenshotCommandOptions extends Omit<ScreenshotOptions, 'element' | 'mask'> { 11 - element?: SerializedLocator 12 - mask?: readonly SerializedLocator[] 13 - target?: 'element' | 'page' 14 - } 15 - 16 - /** 17 - * Takes a screenshot using the provided browser context and returns a buffer and the expected screenshot path. 18 - * 19 - * **Note**: the returned `path` indicates where the screenshot *might* be found. 20 - * It is not guaranteed to exist, especially if `options.save` is `false`. 21 - * 22 - * @throws {Error} If the function is not called within a test or if the browser provider does not support screenshots. 23 - */ 24 - export async function takeScreenshot( 25 - context: BrowserCommandContext, 26 - name: string, 27 - options: Omit<ScreenshotCommandOptions, 'base64'>, 28 - ): Promise<{ buffer: Buffer<ArrayBufferLike>; path: string }> { 29 - if (!context.testPath) { 30 - throw new Error(`Cannot take a screenshot without a test path`) 31 - } 32 - 33 - const path = resolveScreenshotPath( 34 - context.testPath, 35 - name, 36 - context.project.config, 37 - options.path, 38 - ) 39 - 40 - // playwright does not need a screenshot path if we don't intend to save it 41 - let savePath: string | undefined 42 - 43 - if (options.save) { 44 - savePath = normalize(path) 45 - 46 - await mkdir(dirname(savePath), { recursive: true }) 47 - } 48 - 49 - // webdriverio needs a path, so if one is not already set we create a temporary one 50 - if (savePath === undefined) { 51 - savePath = resolve(context.project.tmpDir, crypto.randomUUID()) 52 - 53 - await mkdir(context.project.tmpDir, { recursive: true }) 54 - } 55 - 56 - // webdriverio expects the path to contain the extension and only works with PNG files 57 - const savePathWithExtension = savePath.endsWith('.png') ? savePath : `${savePath}.png` 58 - 59 - // there seems to be a bug in webdriverio, `X:/` gets appended to cwd, so we convert to `X:\` 60 - const normalizedSavePath = platformNormalize(savePathWithExtension) 61 - // `browser.saveScreenshot` captures the top-level page for `expect(page)`; 62 - // element and plain `page.screenshot()` calls keep the existing body fallback. 63 - const buffer = options.target === 'page' 64 - ? await context.browser.saveScreenshot(normalizedSavePath) 65 - : await context.browser.$(options.element?.selector ?? 'body').saveScreenshot( 66 - normalizedSavePath, 67 - ) 68 - 69 - if (!options.save) { 70 - await rm(savePathWithExtension, { force: true }) 71 - } 72 - 73 - return { buffer, path } 74 - }
-25
packages/browser-webdriverio/src/commands/select.ts
··· 1 - import type { UserEvent } from 'vitest/browser' 2 - import type { UserEventCommand } from './utils' 3 - 4 - export const selectOptions: UserEventCommand<UserEvent['selectOptions']> = async ( 5 - context, 6 - { selector }, 7 - userValues, 8 - _options = {}, 9 - ) => { 10 - const values = userValues as any as [({ index: number })] 11 - 12 - if (!values.length) { 13 - return 14 - } 15 - 16 - const browser = context.browser 17 - 18 - if (values.length === 1 && 'index' in values[0]) { 19 - const selectElement = browser.$(selector) 20 - await selectElement.selectByIndex(values[0].index) 21 - } 22 - else { 23 - throw new Error('Provider "webdriverio" doesn\'t support selecting multiple values at once') 24 - } 25 - }
-11
packages/browser-webdriverio/src/commands/tab.ts
··· 1 - import type { UserEvent } from 'vitest/browser' 2 - import type { UserEventCommand } from './utils' 3 - import { Key } from 'webdriverio' 4 - 5 - export const tab: UserEventCommand<UserEvent['tab']> = async ( 6 - context, 7 - options = {}, 8 - ) => { 9 - const browser = context.browser 10 - await browser.keys(options.shift === true ? [Key.Shift, Key.Tab] : [Key.Tab]) 11 - }
-38
packages/browser-webdriverio/src/commands/type.ts
··· 1 - import type { UserEvent } from 'vitest/browser' 2 - import type { UserEventCommand } from './utils' 3 - import { keyboardImplementation } from './keyboard' 4 - 5 - export const type: UserEventCommand<UserEvent['type']> = async ( 6 - context, 7 - { selector }, 8 - text, 9 - options = {}, 10 - ) => { 11 - const { skipClick = false, skipAutoClose = false } = options 12 - const unreleased = new Set(Reflect.get(options, 'unreleased') as string[] ?? []) 13 - 14 - const browser = context.browser 15 - const element = browser.$(selector) 16 - 17 - if (!skipClick && !await element.isFocused()) { 18 - await element.click() 19 - } 20 - 21 - await keyboardImplementation( 22 - unreleased, 23 - context.provider, 24 - context.sessionId, 25 - text, 26 - () => browser.execute(() => { 27 - const element = document.activeElement as HTMLInputElement 28 - if (element && typeof element.select === 'function') { 29 - element.select() 30 - } 31 - }), 32 - skipAutoClose, 33 - ) 34 - 35 - return { 36 - unreleased: Array.from(unreleased), 37 - } 38 - }
-35
packages/browser-webdriverio/src/commands/upload.ts
··· 1 - import type { SerializedLocator } from '@vitest/browser' 2 - import type { UserEventUploadOptions } from 'vitest/browser' 3 - import type { UserEventCommand } from './utils' 4 - import { resolve } from 'pathe' 5 - 6 - export const upload: UserEventCommand<(element: SerializedLocator, files: Array<string | { 7 - name: string 8 - mimeType: string 9 - base64: string 10 - }>, options: UserEventUploadOptions) => void> = async ( 11 - context, 12 - { selector }, 13 - files, 14 - _options, 15 - ) => { 16 - const testPath = context.testPath 17 - if (!testPath) { 18 - throw new Error(`Cannot upload files outside of a test`) 19 - } 20 - const root = context.project.config.root 21 - 22 - for (const file of files) { 23 - if (typeof file !== 'string') { 24 - throw new TypeError(`The "${context.provider.name}" provider doesn't support uploading files objects. Provide a file path instead.`) 25 - } 26 - } 27 - 28 - const element = context.browser.$(selector) 29 - 30 - for (const file of files) { 31 - const filepath = resolve(root, file as string) 32 - const remoteFilePath = await context.browser.uploadFile(filepath) 33 - await element.addValue(remoteFilePath) 34 - } 35 - }
-12
packages/browser-webdriverio/src/commands/utils.ts
··· 1 - import type { SerializedLocator } from '@vitest/browser' 2 - import type { Locator } from 'vitest/browser' 3 - import type { BrowserCommand } from 'vitest/node' 4 - 5 - export type UserEventCommand<T extends (...args: any) => any> = BrowserCommand< 6 - ConvertUserEventParameters<Parameters<T>> 7 - > 8 - 9 - type ConvertElementToLocator<T> = T extends Element | Locator ? SerializedLocator : T 10 - type ConvertUserEventParameters<T extends unknown[]> = { 11 - [K in keyof T]: ConvertElementToLocator<T[K]>; 12 - }
-9
packages/browser-webdriverio/src/commands/viewport.ts
··· 1 - import type { WebdriverBrowserProvider } from '../webdriverio' 2 - import type { UserEventCommand } from './utils' 3 - 4 - export const viewport: UserEventCommand<(options: { 5 - width: number 6 - height: number 7 - }) => void> = async (context, options) => { 8 - await (context.provider as WebdriverBrowserProvider).setViewport(options) 9 - }
-28
packages/browser-webdriverio/src/commands/wheel.ts
··· 1 - import type { Locator, UserEventWheelDeltaOptions } from 'vitest/browser' 2 - import type { UserEventCommand } from './utils' 3 - 4 - type WheelCommand = (element: Locator | Element, options: UserEventWheelDeltaOptions) => Promise<void> 5 - 6 - export const wheel: UserEventCommand<WheelCommand> = async ( 7 - context, 8 - { selector }, 9 - options, 10 - ) => { 11 - const browser = context.browser 12 - const times = options.times ?? 1 13 - const deltaX = options.delta.x ?? 0 14 - const deltaY = options.delta.y ?? 0 15 - 16 - let action = browser.action('wheel') 17 - const wheelOptions: Parameters<typeof action['scroll']>[0] = { 18 - deltaX, 19 - deltaY, 20 - origin: browser.$(selector), 21 - } 22 - 23 - for (let count = 0; count < times; count += 1) { 24 - action = action.scroll(wheelOptions) 25 - } 26 - 27 - await action.perform() 28 - }
-11
test/browser/fixtures/browser-crash/vitest.config.ts
··· 16 16 17 17 throw new Error(`Browser crash not supported for ${browser}`) 18 18 } 19 - if (context.provider.name === 'webdriverio') { 20 - const browser = context.browser 21 - const name = context.project.config.browser.name 22 - if (name === 'chrome') { 23 - await browser.url('chrome://crash') 24 - } 25 - if (name === 'firefox') { 26 - await browser.url('about:crashcontent') 27 - } 28 - throw new Error(`Browser crash not supported for ${name}`) 29 - } 30 19 } 31 20 32 21 export default defineConfig({
+1 -1
test/browser/fixtures/inspect/vitest.config.ts
··· 9 9 enabled: true, 10 10 provider, 11 11 instances: [ 12 - { browser: provider.name === 'webdriverio' ? "chrome" : "chromium" }, 12 + { browser: "chromium" }, 13 13 ], 14 14 headless: true, 15 15 },
+1 -1
test/browser/fixtures/inspect/vitest.config.with-workspace.ts
··· 15 15 enabled: true, 16 16 headless: true, 17 17 instances: [ 18 - { browser: provider.name === 'webdriverio' ? "chrome" : "chromium" }, 18 + { browser: "chromium" }, 19 19 ], 20 20 }, 21 21 },
-2
test/browser/fixtures/server-url/vitest.config.ts
··· 9 9 10 10 // ignore https errors due to self-signed certificate from plugin-basic-ssl 11 11 // https://playwright.dev/docs/api/class-browser#browser-new-context-option-ignore-https-errors 12 - // https://webdriver.io/docs/configuration/#strictssl and acceptInsecureCerts in https://webdriver.io/docs/api/browser/#properties 13 12 const configuredProvider = (function () { 14 13 switch (provider.name) { 15 14 case 'playwright': return providers.playwright() 16 - case 'webdriverio': return providers.webdriverio({ strictSSL: false, capabilities: { acceptInsecureCerts: true } }) 17 15 default: { 18 16 throw new Error(`Invalid provider: ${provider.name}`) 19 17 }
-4
test/browser/fixtures/trace/exotic.test.ts
··· 23 23 const shadow = host.attachShadow({ mode: 'open' }) 24 24 shadow.innerHTML = '<button>Shadow button</button>' 25 25 document.body.append(host) 26 - // TODO: webdriverio currently records this trace-view selector after it is 27 - // lowered to a provider-specific shadow DOM selector. 28 26 await page.getByRole('button', { name: 'Shadow button' }).mark('shadow button rendered') 29 27 }) 30 28 ··· 42 40 } 43 41 44 42 document.body.innerHTML = '<trace-widget></trace-widget>' 45 - // TODO: webdriverio currently records this trace-view selector after it is 46 - // lowered to a provider-specific shadow DOM selector. 47 43 await page.getByRole('button', { name: 'Custom element button' }).mark('custom element rendered') 48 44 }) 49 45
-2
test/browser/fixtures/trace/expect.test.ts
··· 28 28 test('click fail', async () => { 29 29 document.body.innerHTML = '<button>Hello</button>' 30 30 try { 31 - // TODO: webdriverio currently records only the lifecycle failure for this case, 32 - // not the failed action trace entry with selectorResolution: "missing". 33 31 await page.getByRole('button', { name: 'Missing' }).click({ timeout: 100 }) 34 32 } 35 33 catch (e) {
-1
test/browser/fixtures/user-event/clipboard.test.ts
··· 2 2 import { page, userEvent } from 'vitest/browser'; 3 3 4 4 test('clipboard', async () => { 5 - // make it smaller since webdriverio fails when scaled 6 5 page.viewport(300, 300) 7 6 8 7 document.body.innerHTML = `
+2 -29
test/browser/fixtures/user-event/keyboard.test.ts
··· 15 15 await expect.element(page.getByPlaceholder("fill-#7396")).toHaveValue('éèù') 16 16 17 17 // playwright: garbled characters 18 - // webdriverio: error: invalid argument: missing command parameters 19 18 // preview: ok 20 19 if (server.provider === 'playwright') { 21 20 await userEvent.type(page.getByPlaceholder("type-emoji"), '😊😍') ··· 24 23 } else { 25 24 await expect.element(page.getByPlaceholder("type-emoji")).toHaveValue('😊😍') 26 25 } 27 - } else if (server.provider === 'webdriverio') { 28 - await expect(() => 29 - userEvent.type(page.getByPlaceholder("type-emoji"), '😊😍') 30 - ).rejects.toThrow() 31 26 } else { 32 27 await userEvent.type(page.getByPlaceholder("type-emoji"), '😊😍') 33 28 await expect.element(page.getByPlaceholder("type-emoji")).toHaveValue('😊😍') 34 29 } 35 30 36 31 // playwright: ok 37 - // webdriverio: error: ChromeDriver only supports characters in the BMP 38 32 // preview: ok 39 - if (server.provider === 'webdriverio') { 40 - if (server.browser === 'firefox') { 41 - await userEvent.fill(page.getByPlaceholder("fill-emoji"), '😊😍') 42 - await expect.element(page.getByPlaceholder("fill-emoji")).toHaveValue('😊😍') 43 - } else { 44 - await expect(() => 45 - userEvent.fill(page.getByPlaceholder("fill-emoji"), '😊😍') 46 - ).rejects.toThrow() 47 - } 48 - } else { 49 - await userEvent.fill(page.getByPlaceholder("fill-emoji"), '😊😍') 50 - await expect.element(page.getByPlaceholder("fill-emoji")).toHaveValue('😊😍') 51 - } 33 + await userEvent.fill(page.getByPlaceholder("fill-emoji"), '😊😍') 34 + await expect.element(page.getByPlaceholder("fill-emoji")).toHaveValue('😊😍') 52 35 }) 53 36 54 37 test('click with modifier', async () => { ··· 63 46 }); 64 47 65 48 await userEvent.keyboard('{Shift>}') 66 - // By using an empty object as the option, this opts in to using a chain of actions instead of an elementClick in webdriver. 67 49 await userEvent.click(el, {}) 68 50 await userEvent.keyboard('{/Shift}') 69 51 await expect.poll(() => el.textContent).toContain("[ok]") ··· 73 55 // https://testing-library.com/docs/user-event/keyboard 74 56 // https://github.com/testing-library/user-event/blob/main/src/keyboard/keyMap.ts 75 57 // https://playwright.dev/docs/api/class-keyboard 76 - // https://webdriver.io/docs/api/browser/keys/ 77 58 test('special keys', async () => { 78 59 async function testKeyboard(text: string) { 79 60 let data: any; ··· 96 77 expect(await testKeyboard('{ShiftLeft}')).toMatchInlineSnapshot(`"Shift|ShiftLeft|1"`); 97 78 expect(await testKeyboard('{ShiftRight}')).toMatchInlineSnapshot(`"Shift|ShiftRight|2"`); 98 79 expect(await testKeyboard('[Shift]')).toMatchInlineSnapshot(`undefined`); 99 - expect(await testKeyboard('[ShiftLeft]')).toMatchInlineSnapshot(`"Shift|ShiftLeft|1"`); 100 - expect(await testKeyboard('[ShiftRight]')).toMatchInlineSnapshot(`"Shift|ShiftLeft|1"`); 101 - } 102 - if (server.provider === 'webdriverio') { 103 - expect(await testKeyboard('{Shift}')).toMatchInlineSnapshot(`"Shift|ShiftLeft|1"`); 104 - expect(await testKeyboard('{ShiftLeft}')).toMatchInlineSnapshot(`"ERROR"`); 105 - expect(await testKeyboard('{ShiftRight}')).toMatchInlineSnapshot(`"ERROR"`); 106 - expect(await testKeyboard('[Shift]')).toMatchInlineSnapshot(`"ERROR"`); 107 80 expect(await testKeyboard('[ShiftLeft]')).toMatchInlineSnapshot(`"Shift|ShiftLeft|1"`); 108 81 expect(await testKeyboard('[ShiftRight]')).toMatchInlineSnapshot(`"Shift|ShiftLeft|1"`); 109 82 }
-15
test/e2e/test/config/browser-configs.test.ts
··· 467 467 }) 468 468 }) 469 469 470 - test('core provider has options if `provider` is wdio', async () => { 471 - const v = await vitest({}, { 472 - browser: { 473 - enabled: true, 474 - provider: playwright({ contextOptions: { hasTouch: true } }), 475 - instances: [ 476 - { browser: 'chrome' }, 477 - ], 478 - }, 479 - }) 480 - expect(v.config.browser.provider?.options).toEqual({ 481 - contextOptions: { hasTouch: true }, 482 - }) 483 - }) 484 - 485 470 test('core provider has options if `provider` is preview', async () => { 486 471 const v = await vitest({}, { 487 472 browser: {