[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.

feat!: move browser providers to @vitest/browser package (#4364)

authored by

Vladimir and committed by
GitHub
(Oct 27, 2023, 9:02 AM +0200) 5cdeb558 2af2ba7a

+594 -760
+188 -470
pnpm-lock.yaml
··· 359 359 examples/playwright: 360 360 devDependencies: 361 361 '@playwright/test': 362 - specifier: ^1.28.0 363 - version: 1.28.0 362 + specifier: ^1.39.0 363 + version: 1.39.0 364 364 '@vitest/ui': 365 365 specifier: latest 366 366 version: link:../../packages/ui 367 367 playwright: 368 - specifier: ^1.28.0 369 - version: 1.28.0 368 + specifier: ^1.39.0 369 + version: 1.39.0 370 370 vite: 371 371 specifier: ^4.5.0 372 372 version: 4.5.0(@types/node@18.16.19)(less@4.1.3) ··· 976 976 '@vitest/ws-client': 977 977 specifier: workspace:* 978 978 version: link:../ws-client 979 + '@wdio/protocols': 980 + specifier: ^8.18.0 981 + version: 8.18.0 979 982 periscopic: 980 983 specifier: ^3.1.0 981 984 version: 3.1.0 985 + playwright: 986 + specifier: ^1.39.0 987 + version: 1.39.0 988 + playwright-core: 989 + specifier: ^1.39.0 990 + version: 1.39.0 991 + safaridriver: 992 + specifier: ^0.1.0 993 + version: 0.1.0 982 994 vitest: 983 995 specifier: workspace:* 984 996 version: link:../vitest 997 + webdriverio: 998 + specifier: ^8.20.0 999 + version: 8.20.0(typescript@5.1.6) 985 1000 986 1001 packages/coverage-istanbul: 987 1002 dependencies: ··· 1470 1485 pkg-types: 1471 1486 specifier: ^1.0.3 1472 1487 version: 1.0.3 1473 - playwright: 1474 - specifier: ^1.35.1 1475 - version: 1.35.1 1476 1488 pretty-format: 1477 1489 specifier: ^29.5.0 1478 1490 version: 29.5.0 1479 1491 prompts: 1480 1492 specifier: ^2.4.2 1481 1493 version: 2.4.2 1482 - safaridriver: 1483 - specifier: ^0.0.5 1484 - version: 0.0.5 1485 1494 strip-ansi: 1486 1495 specifier: ^7.1.0 1487 1496 version: 7.1.0 1488 - webdriverio: 1489 - specifier: ^8.11.2 1490 - version: 8.12.1(typescript@5.1.6) 1491 1497 ws: 1492 1498 specifier: ^8.13.0 1493 1499 version: 8.13.0 ··· 1972 1978 specifier: ^10.1.0 1973 1979 version: 10.1.0 1974 1980 playwright-chromium: 1975 - specifier: ^1.27.0 1976 - version: 1.30.0 1981 + specifier: ^1.39.0 1982 + version: 1.39.0 1977 1983 vitest: 1978 1984 specifier: workspace:* 1979 1985 version: link:../../packages/vitest ··· 7393 7399 dependencies: 7394 7400 '@types/istanbul-lib-coverage': 2.0.4 7395 7401 '@types/istanbul-reports': 3.0.1 7396 - '@types/node': 18.18.6 7402 + '@types/node': 20.8.8 7397 7403 '@types/yargs': 15.0.14 7398 7404 chalk: 4.1.2 7399 7405 dev: true ··· 7416 7422 '@jest/schemas': 29.4.3 7417 7423 '@types/istanbul-lib-coverage': 2.0.4 7418 7424 '@types/istanbul-reports': 3.0.1 7419 - '@types/node': 18.18.6 7425 + '@types/node': 20.8.8 7420 7426 '@types/yargs': 17.0.12 7421 7427 chalk: 4.1.2 7422 7428 dev: true ··· 8129 8135 dev: true 8130 8136 optional: true 8131 8137 8132 - /@playwright/test@1.28.0: 8133 - resolution: {integrity: sha512-vrHs5DFTPwYox5SGKq/7TDn/S4q6RA1zArd7uhO6EyP9hj3XgZBBM12ktMbnDQNxh/fL1IUKsTNLxihmsU38lQ==} 8134 - engines: {node: '>=14'} 8138 + /@playwright/test@1.39.0: 8139 + resolution: {integrity: sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==} 8140 + engines: {node: '>=16'} 8135 8141 hasBin: true 8136 8142 dependencies: 8137 - '@types/node': 20.8.2 8138 - playwright-core: 1.28.0 8143 + playwright: 1.39.0 8139 8144 dev: true 8140 8145 8141 8146 /@pmmmwh/react-refresh-webpack-plugin@0.5.7(react-refresh@0.11.0)(webpack@5.74.0): ··· 8242 8247 '@rollup/pluginutils': 4.2.1 8243 8248 preact: 10.15.1 8244 8249 vite: 4.5.0(@types/node@18.16.19)(less@4.1.3) 8245 - transitivePeerDependencies: 8246 - - supports-color 8247 - dev: true 8248 - 8249 - /@puppeteer/browsers@1.3.0(typescript@5.1.6): 8250 - resolution: {integrity: sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==} 8251 - engines: {node: '>=16.0.0'} 8252 - hasBin: true 8253 - peerDependencies: 8254 - typescript: '>= 4.7.4' 8255 - peerDependenciesMeta: 8256 - typescript: 8257 - optional: true 8258 - dependencies: 8259 - debug: 4.3.4(supports-color@8.1.1) 8260 - extract-zip: 2.0.1(supports-color@8.1.1) 8261 - http-proxy-agent: 5.0.0 8262 - https-proxy-agent: 5.0.1 8263 - progress: 2.0.3 8264 - proxy-from-env: 1.1.0 8265 - tar-fs: 2.1.1 8266 - typescript: 5.1.6 8267 - unbzip2-stream: 1.4.3 8268 - yargs: 17.7.1 8269 8250 transitivePeerDependencies: 8270 8251 - supports-color 8271 8252 dev: true ··· 9391 9372 globby: 11.1.0 9392 9373 ip: 2.0.0 9393 9374 lodash: 4.17.21 9394 - node-fetch: 2.6.11 9375 + node-fetch: 2.7.0 9395 9376 open: 8.4.0 9396 9377 pretty-hrtime: 1.0.3 9397 9378 prompts: 2.4.2 ··· 9565 9546 find-up: 5.0.0 9566 9547 fs-extra: 9.1.0 9567 9548 html-webpack-plugin: 4.5.2(webpack@4.46.0) 9568 - node-fetch: 2.6.11 9549 + node-fetch: 2.7.0 9569 9550 pnp-webpack-plugin: 1.6.4(typescript@4.8.4) 9570 9551 react: 17.0.2 9571 9552 react-dom: 17.0.2(react@17.0.2) ··· 10414 10395 /@types/cheerio@0.22.31: 10415 10396 resolution: {integrity: sha512-Kt7Cdjjdi2XWSfrZ53v4Of0wG3ZcmaegFXjMmz9tfNrZSkzzo36G0AL1YqSdcIA78Etjt6E609pt5h1xnQkPUw==} 10416 10397 dependencies: 10417 - '@types/node': 20.8.2 10398 + '@types/node': 20.8.8 10418 10399 dev: true 10419 10400 10420 10401 /@types/codemirror@5.60.8: ··· 10537 10518 /@types/fs-extra@8.1.3: 10538 10519 resolution: {integrity: sha512-7IdV01N0u/CaVO0fuY1YmEg14HQN3+EW8mpNgg6NEfxEl/lzCa5OxlBu3iFsCAdamnYOcTQ7oEi43Xc/67Rgzw==} 10539 10520 dependencies: 10540 - '@types/node': 20.8.2 10521 + '@types/node': 20.8.8 10541 10522 dev: true 10542 10523 10543 10524 /@types/fs-extra@9.0.13: ··· 10550 10531 resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} 10551 10532 dependencies: 10552 10533 '@types/minimatch': 5.1.1 10553 - '@types/node': 18.18.6 10534 + '@types/node': 20.8.8 10554 10535 dev: true 10555 10536 10556 10537 /@types/glob@8.0.0: 10557 10538 resolution: {integrity: sha512-l6NQsDDyQUVeoTynNpC9uRvCUint/gSUXQA2euwmTuWGvPY5LSDUu6tkCtJB2SvGQlJQzLaKqcGZP4//7EDveA==} 10558 10539 dependencies: 10559 10540 '@types/minimatch': 5.1.1 10560 - '@types/node': 18.18.6 10541 + '@types/node': 20.8.8 10561 10542 dev: true 10562 10543 10563 10544 /@types/graceful-fs@4.1.5: 10564 10545 resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} 10565 10546 dependencies: 10566 - '@types/node': 18.18.6 10547 + '@types/node': 20.8.8 10567 10548 dev: true 10568 10549 10569 10550 /@types/graceful-fs@4.1.8: ··· 10677 10658 /@types/jsonfile@6.1.1: 10678 10659 resolution: {integrity: sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==} 10679 10660 dependencies: 10680 - '@types/node': 20.8.2 10661 + '@types/node': 20.8.8 10681 10662 dev: true 10682 10663 10683 10664 /@types/lodash@4.14.195: ··· 10719 10700 /@types/node-fetch@2.6.2: 10720 10701 resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} 10721 10702 dependencies: 10722 - '@types/node': 18.18.6 10703 + '@types/node': 20.8.8 10723 10704 form-data: 3.0.1 10724 10705 dev: true 10725 10706 ··· 10747 10728 10748 10729 /@types/node@20.8.2: 10749 10730 resolution: {integrity: sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==} 10731 + dev: true 10732 + 10733 + /@types/node@20.8.8: 10734 + resolution: {integrity: sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==} 10735 + dependencies: 10736 + undici-types: 5.25.3 10750 10737 dev: true 10751 10738 10752 10739 /@types/normalize-package-data@2.4.1: ··· 10904 10891 /@types/set-cookie-parser@2.4.2: 10905 10892 resolution: {integrity: sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==} 10906 10893 dependencies: 10907 - '@types/node': 18.18.6 10894 + '@types/node': 20.8.8 10908 10895 dev: true 10909 10896 10910 10897 /@types/sinonjs__fake-timers@8.1.1: ··· 10950 10937 /@types/through@0.0.30: 10951 10938 resolution: {integrity: sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==} 10952 10939 dependencies: 10953 - '@types/node': 18.18.6 10940 + '@types/node': 20.8.8 10954 10941 dev: true 10955 10942 10956 10943 /@types/tough-cookie@4.0.2: ··· 10988 10975 /@types/webpack-sources@3.2.0: 10989 10976 resolution: {integrity: sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==} 10990 10977 dependencies: 10991 - '@types/node': 18.18.6 10978 + '@types/node': 20.8.8 10992 10979 '@types/source-list-map': 0.1.2 10993 10980 source-map: 0.7.4 10994 10981 dev: true ··· 10996 10983 /@types/webpack@4.41.32: 10997 10984 resolution: {integrity: sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg==} 10998 10985 dependencies: 10999 - '@types/node': 18.18.6 10986 + '@types/node': 20.8.8 11000 10987 '@types/tapable': 1.0.8 11001 10988 '@types/uglify-js': 3.17.0 11002 10989 '@types/webpack-sources': 3.2.0 ··· 11044 11031 resolution: {integrity: sha512-Km7XAtUIduROw7QPgvcft0lIupeG8a8rdKL8RiSyKvlE7dYY31fEn41HVuQsRFDuROA8tA4K2UVL+WdfFmErBA==} 11045 11032 requiresBuild: true 11046 11033 dependencies: 11047 - '@types/node': 18.18.6 11034 + '@types/node': 20.8.8 11048 11035 dev: true 11049 11036 optional: true 11050 11037 ··· 12000 11987 vue-demi: 0.14.0(vue@3.2.39) 12001 11988 dev: false 12002 11989 12003 - /@wdio/config@8.12.1: 12004 - resolution: {integrity: sha512-6DfTU+5Ugg6HKMSqVNCLEgdFd7l+QnaMoDe2/tZ8zoYNdJlFu0NfClXLL4qnTCCjebmz3eu0/O+aRPJyxo6GGQ==} 12005 - engines: {node: ^16.13 || >=18} 12006 - dependencies: 12007 - '@wdio/logger': 8.11.0 12008 - '@wdio/types': 8.10.4 12009 - '@wdio/utils': 8.12.1 12010 - decamelize: 6.0.0 12011 - deepmerge-ts: 5.0.0 12012 - glob: 10.3.10 12013 - import-meta-resolve: 3.0.0 12014 - read-pkg-up: 9.1.0 12015 - dev: true 12016 - 12017 11990 /@wdio/config@8.16.20: 12018 11991 resolution: {integrity: sha512-JFD7aYs3nGF2kNhc0eV03mWFQMJku42NCBl+aedb1jzP3z6tBWV3n1a0ETS4MTLps8lFXBDZWvWEnl+ZvVrHZw==} 12019 11992 engines: {node: ^16.13 || >=18} ··· 12030 12003 - supports-color 12031 12004 dev: true 12032 12005 12033 - /@wdio/logger@8.11.0: 12034 - resolution: {integrity: sha512-IsuKSaYi7NKEdgA57h8muzlN/MVp1dQG+V4C//7g4m03YJUnNQLvDhJzLjdeNTfvZy61U7foQSyt+3ktNzZkXA==} 12006 + /@wdio/config@8.20.0: 12007 + resolution: {integrity: sha512-ODsafHlxEawyYa6IyIdXJMV2plPFyrDbGrXLNKNFBQVfB/FmoHUiiOTh+4Gu+sUXzpn2YNH5O199qHxHw61uUw==} 12035 12008 engines: {node: ^16.13 || >=18} 12036 12009 dependencies: 12037 - chalk: 5.2.0 12038 - loglevel: 1.8.1 12039 - loglevel-plugin-prefix: 0.8.4 12040 - strip-ansi: 7.1.0 12010 + '@wdio/logger': 8.16.17 12011 + '@wdio/types': 8.20.0 12012 + '@wdio/utils': 8.20.0 12013 + decamelize: 6.0.0 12014 + deepmerge-ts: 5.1.0 12015 + glob: 10.3.10 12016 + import-meta-resolve: 3.0.0 12017 + read-pkg-up: 10.1.0 12018 + transitivePeerDependencies: 12019 + - supports-color 12041 12020 dev: true 12042 12021 12043 12022 /@wdio/logger@8.16.17: ··· 12050 12029 strip-ansi: 7.1.0 12051 12030 dev: true 12052 12031 12053 - /@wdio/protocols@8.11.0: 12054 - resolution: {integrity: sha512-eXTMYt/XoaX53H/Q2qmsn1uWthIC5aSTGtX9YyXD/AkagG2hXeX3lLmzNWBaSIvKR+vWXRYbg3Y/7IvL2s25Wg==} 12055 - dev: true 12056 - 12057 12032 /@wdio/protocols@8.16.5: 12058 12033 resolution: {integrity: sha512-u9I57hIqmcOgrDH327ZCc2GTXv2YFN5bg6UaA3OUoJU7eJgGYHFB6RrjiNjLXer68iIx07wwVM70V/1xzijd3Q==} 12034 + dev: true 12035 + 12036 + /@wdio/protocols@8.18.0: 12037 + resolution: {integrity: sha512-TABA0mksHvu5tE8qNYYDR0fDyo90NCANeghbGAtsI8TUsJzgH0dwpos3WSSiB97J9HRSZuWIMa7YuABEkBIjWQ==} 12059 12038 dev: true 12060 12039 12061 12040 /@wdio/repl@8.10.1: 12062 12041 resolution: {integrity: sha512-VZ1WFHTNKjR8Ga97TtV2SZM6fvRjWbYI2i/f4pJB4PtusorKvONAMJf2LQcUBIyzbVobqr7KSrcjmSwRolI+yw==} 12063 12042 engines: {node: ^16.13 || >=18} 12064 12043 dependencies: 12065 - '@types/node': 20.8.2 12066 - dev: true 12067 - 12068 - /@wdio/types@8.10.4: 12069 - resolution: {integrity: sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==} 12070 - engines: {node: ^16.13 || >=18} 12071 - dependencies: 12072 - '@types/node': 20.8.2 12044 + '@types/node': 20.8.8 12073 12045 dev: true 12074 12046 12075 12047 /@wdio/types@8.16.12: 12076 12048 resolution: {integrity: sha512-TjCZJ3P9ual21G0dRv0lC9QgHGd3Igv+guEINevBKf/oD4/N84PvQ2eZG1nSbZ3xh8X/dvi+O64A6VEv43gx2w==} 12077 12049 engines: {node: ^16.13 || >=18} 12078 12050 dependencies: 12079 - '@types/node': 20.8.2 12051 + '@types/node': 20.8.8 12080 12052 dev: true 12081 12053 12082 - /@wdio/utils@8.12.1: 12083 - resolution: {integrity: sha512-VmF6O++84FTH3AKaVFyqn0MJA65/1G6dbm6p61KBqkD25LxaWo4398lCCbt264hzBIobtXRZoQ87bSxdfnlUKQ==} 12054 + /@wdio/types@8.20.0: 12055 + resolution: {integrity: sha512-y0En5V5PPF48IHJMetaNYQobhCr3ddsgp2aX/crLL51UccWqnFpCL8pCh6cP01gRgCchCasa2JCBMB+PucbYmA==} 12084 12056 engines: {node: ^16.13 || >=18} 12085 12057 dependencies: 12086 - '@wdio/logger': 8.11.0 12087 - '@wdio/types': 8.10.4 12088 - import-meta-resolve: 3.0.0 12089 - p-iteration: 1.1.8 12058 + '@types/node': 20.8.8 12090 12059 dev: true 12091 12060 12092 12061 /@wdio/utils@8.16.17: ··· 12096 12065 '@puppeteer/browsers': 1.7.0 12097 12066 '@wdio/logger': 8.16.17 12098 12067 '@wdio/types': 8.16.12 12068 + decamelize: 6.0.0 12069 + deepmerge-ts: 5.1.0 12070 + edgedriver: 5.3.6 12071 + geckodriver: 4.2.0 12072 + get-port: 7.0.0 12073 + got: 13.0.0 12074 + import-meta-resolve: 3.0.0 12075 + locate-app: 2.1.0 12076 + safaridriver: 0.1.0 12077 + split2: 4.2.0 12078 + wait-port: 1.0.4 12079 + transitivePeerDependencies: 12080 + - supports-color 12081 + dev: true 12082 + 12083 + /@wdio/utils@8.20.0: 12084 + resolution: {integrity: sha512-nZ5QF5lPyZNJG9YaSrRuVfkVeg80yRrUQT42D0mUDDjmUIh2pAXDMu4HxgxocuQSOyLacg4Vpg3Sju9NFipxIA==} 12085 + engines: {node: ^16.13 || >=18} 12086 + dependencies: 12087 + '@puppeteer/browsers': 1.7.0 12088 + '@wdio/logger': 8.16.17 12089 + '@wdio/types': 8.20.0 12099 12090 decamelize: 6.0.0 12100 12091 deepmerge-ts: 5.1.0 12101 12092 edgedriver: 5.3.6 ··· 12900 12891 resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} 12901 12892 dev: true 12902 12893 12903 - /archiver-utils@2.1.0: 12904 - resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} 12905 - engines: {node: '>= 6'} 12906 - dependencies: 12907 - glob: 7.2.3 12908 - graceful-fs: 4.2.11 12909 - lazystream: 1.0.1 12910 - lodash.defaults: 4.2.0 12911 - lodash.difference: 4.5.0 12912 - lodash.flatten: 4.4.0 12913 - lodash.isplainobject: 4.0.6 12914 - lodash.union: 4.6.0 12915 - normalize-path: 3.0.0 12916 - readable-stream: 2.3.7 12917 - dev: true 12918 - 12919 12894 /archiver-utils@4.0.1: 12920 12895 resolution: {integrity: sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==} 12921 12896 engines: {node: '>= 12.0.0'} ··· 12926 12901 lodash: 4.17.21 12927 12902 normalize-path: 3.0.0 12928 12903 readable-stream: 3.6.0 12929 - dev: true 12930 - 12931 - /archiver@5.3.1: 12932 - resolution: {integrity: sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==} 12933 - engines: {node: '>= 10'} 12934 - dependencies: 12935 - archiver-utils: 2.1.0 12936 - async: 3.2.4 12937 - buffer-crc32: 0.2.13 12938 - readable-stream: 3.6.0 12939 - readdir-glob: 1.1.2 12940 - tar-stream: 2.2.0 12941 - zip-stream: 4.1.0 12942 12904 dev: true 12943 12905 12944 12906 /archiver@6.0.1: ··· 14360 14322 engines: {node: '>=10'} 14361 14323 dev: true 14362 14324 14363 - /chrome-launcher@0.15.1: 14364 - resolution: {integrity: sha512-UugC8u59/w2AyX5sHLZUHoxBAiSiunUhZa3zZwMH6zPVis0C3dDKiRWyUGIo14tTbZHGVviWxv3PQWZ7taZ4fg==} 14365 - engines: {node: '>=12.13.0'} 14366 - hasBin: true 14367 - dependencies: 14368 - '@types/node': 18.18.6 14369 - escape-string-regexp: 4.0.0 14370 - is-wsl: 2.2.0 14371 - lighthouse-logger: 1.3.0 14372 - transitivePeerDependencies: 14373 - - supports-color 14374 - dev: true 14375 - 14376 14325 /chrome-trace-event@1.0.3: 14377 14326 resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} 14378 14327 engines: {node: '>=6.0'} ··· 14384 14333 devtools-protocol: '*' 14385 14334 dependencies: 14386 14335 devtools-protocol: 0.0.1147663 14387 - mitt: 3.0.0 14388 - dev: true 14389 - 14390 - /chromium-bidi@0.4.9(devtools-protocol@0.0.1120988): 14391 - resolution: {integrity: sha512-u3DC6XwgLCA9QJ5ak1voPslCmacQdulZNCPsI3qNXxSnEcZS7DFIbww+5RM2bznMEje7cc0oydavRLRvOIZtHw==} 14392 - peerDependencies: 14393 - devtools-protocol: '*' 14394 - dependencies: 14395 - devtools-protocol: 0.0.1120988 14396 14336 mitt: 3.0.0 14397 14337 dev: true 14398 14338 ··· 14702 14642 resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} 14703 14643 dev: true 14704 14644 14705 - /compress-commons@4.1.1: 14706 - resolution: {integrity: sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==} 14707 - engines: {node: '>= 10'} 14708 - dependencies: 14709 - buffer-crc32: 0.2.13 14710 - crc32-stream: 4.0.2 14711 - normalize-path: 3.0.0 14712 - readable-stream: 3.6.0 14713 - dev: true 14714 - 14715 14645 /compress-commons@5.0.1: 14716 14646 resolution: {integrity: sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==} 14717 14647 engines: {node: '>= 12.0.0'} ··· 14949 14879 hasBin: true 14950 14880 dev: true 14951 14881 14952 - /crc32-stream@4.0.2: 14953 - resolution: {integrity: sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==} 14954 - engines: {node: '>= 10'} 14955 - dependencies: 14956 - crc-32: 1.2.2 14957 - readable-stream: 3.6.0 14958 - dev: true 14959 - 14960 14882 /crc32-stream@5.0.0: 14961 14883 resolution: {integrity: sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==} 14962 14884 engines: {node: '>= 12.0.0'} ··· 14999 14921 node-fetch: 2.6.7 15000 14922 transitivePeerDependencies: 15001 14923 - encoding 15002 - 15003 - /cross-fetch@3.1.6: 15004 - resolution: {integrity: sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==} 15005 - dependencies: 15006 - node-fetch: 2.6.11 15007 - transitivePeerDependencies: 15008 - - encoding 15009 - dev: true 15010 14924 15011 14925 /cross-fetch@4.0.0: 15012 14926 resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} ··· 15564 15478 resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 15565 15479 dev: true 15566 15480 15567 - /deepmerge-ts@5.0.0: 15568 - resolution: {integrity: sha512-esq9xUO8+CQCG63IlpkoOBNlpm1m4WBm0NRLFrGL/dcgzqWi1tmTLfG7QTvffqYt6T+dS+xaxrHxdexqGWkV1g==} 15569 - engines: {node: '>=16.0.0'} 15570 - dev: true 15571 - 15572 15481 /deepmerge-ts@5.1.0: 15573 15482 resolution: {integrity: sha512-eS8dRJOckyo9maw9Tu5O5RUi/4inFLrnoLkBe3cPfDMx3WZioXtmOew4TXQaxq7Rhl4xjDtR7c6x8nNTxOvbFw==} 15574 15483 engines: {node: '>=16.0.0'} ··· 15753 15662 resolution: {integrity: sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==} 15754 15663 dev: true 15755 15664 15756 - /devtools-protocol@0.0.1120988: 15757 - resolution: {integrity: sha512-39fCpE3Z78IaIPChJsP6Lhmkbf4dWXOmzLk/KFTdRkNk/0JymRIfUynDVRndV9HoDz8PyalK1UH21ST/ivwW5Q==} 15758 - dev: true 15759 - 15760 15665 /devtools-protocol@0.0.1147663: 15761 15666 resolution: {integrity: sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==} 15762 - dev: true 15763 - 15764 - /devtools-protocol@0.0.1161598: 15765 - resolution: {integrity: sha512-MQNeVRDiJ9yAfHUlumx7OCweu15GgMIqEIvz/DTZwpZKjT7oGo9FcwUqS7PyH0mDJsWnuJIn41BZ4SPoQbZfew==} 15766 15667 dev: true 15767 15668 15768 15669 /devtools-protocol@0.0.1203626: 15769 15670 resolution: {integrity: sha512-nEzHZteIUZfGCZtTiS1fRpC8UZmsfD1SiyPvaUNvS13dvKf666OAm8YTi0+Ca3n1nLEyu49Cy4+dPWpaHFJk9g==} 15770 15671 dev: true 15771 15672 15772 - /devtools-protocol@0.0.981744: 15773 - resolution: {integrity: sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==} 15673 + /devtools-protocol@0.0.1209236: 15674 + resolution: {integrity: sha512-z4eehc+fhmptqhxwreLcg9iydszZGU4Q5FzaaElXVGp3KyfXbjtXeUCmo4l8FxBJbyXtCz4VRIJsGW2ekApyUQ==} 15774 15675 dev: true 15775 15676 15776 - /devtools@8.12.1(typescript@5.1.6): 15777 - resolution: {integrity: sha512-R72raQLN1lDSqbr2DVj9SRh07JRyojzmrcLa33VBa2nw3cf5ZyHOHe0DgxlJ/5c2Dfs1+wGNJy16gWKGBq+xgg==} 15778 - engines: {node: ^16.13 || >=18} 15779 - dependencies: 15780 - '@types/node': 20.8.2 15781 - '@wdio/config': 8.12.1 15782 - '@wdio/logger': 8.11.0 15783 - '@wdio/protocols': 8.11.0 15784 - '@wdio/types': 8.10.4 15785 - '@wdio/utils': 8.12.1 15786 - chrome-launcher: 0.15.1 15787 - edge-paths: 3.0.5 15788 - import-meta-resolve: 3.0.0 15789 - puppeteer-core: 20.3.0(typescript@5.1.6) 15790 - query-selector-shadow-dom: 1.0.1 15791 - ua-parser-js: 1.0.34 15792 - uuid: 9.0.0 15793 - which: 3.0.0 15794 - transitivePeerDependencies: 15795 - - bufferutil 15796 - - encoding 15797 - - supports-color 15798 - - typescript 15799 - - utf-8-validate 15677 + /devtools-protocol@0.0.981744: 15678 + resolution: {integrity: sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==} 15800 15679 dev: true 15801 15680 15802 15681 /dezalgo@1.0.3: ··· 18070 17949 dev: true 18071 17950 optional: true 18072 17951 17952 + /fsevents@2.3.2: 17953 + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 17954 + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 17955 + os: [darwin] 17956 + requiresBuild: true 17957 + dev: true 17958 + optional: true 17959 + 18073 17960 /fsevents@2.3.3: 18074 17961 resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 18075 17962 engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} ··· 18388 18275 fs.realpath: 1.0.0 18389 18276 inflight: 1.0.6 18390 18277 inherits: 2.0.4 18391 - minimatch: 5.1.1 18278 + minimatch: 5.1.6 18392 18279 once: 1.4.0 18393 18280 dev: true 18394 18281 ··· 18829 18716 18830 18717 /hosted-git-info@2.8.9: 18831 18718 resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} 18832 - dev: true 18833 - 18834 - /hosted-git-info@4.1.0: 18835 - resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} 18836 - engines: {node: '>=10'} 18837 - dependencies: 18838 - lru-cache: 6.0.0 18839 18719 dev: true 18840 18720 18841 18721 /hosted-git-info@7.0.0: ··· 20141 20021 dependencies: 20142 20022 '@jest/types': 26.6.2 20143 20023 '@types/graceful-fs': 4.1.5 20144 - '@types/node': 18.18.6 20024 + '@types/node': 20.8.8 20145 20025 anymatch: 3.1.3 20146 20026 fb-watchman: 2.0.1 20147 20027 graceful-fs: 4.2.11 ··· 20402 20282 resolution: {integrity: sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==} 20403 20283 engines: {node: '>= 10.14.2'} 20404 20284 dependencies: 20405 - '@types/node': 18.18.6 20285 + '@types/node': 20.8.8 20406 20286 graceful-fs: 4.2.11 20407 20287 dev: true 20408 20288 ··· 20449 20329 engines: {node: '>= 10.14.2'} 20450 20330 dependencies: 20451 20331 '@jest/types': 26.6.2 20452 - '@types/node': 18.18.6 20332 + '@types/node': 20.8.8 20453 20333 chalk: 4.1.2 20454 20334 graceful-fs: 4.2.11 20455 20335 is-ci: 2.0.0 ··· 20473 20353 engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 20474 20354 dependencies: 20475 20355 '@jest/types': 29.0.1 20476 - '@types/node': 18.18.6 20356 + '@types/node': 20.8.8 20477 20357 chalk: 4.1.2 20478 20358 ci-info: 3.8.0 20479 20359 graceful-fs: 4.2.11 ··· 20509 20389 resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} 20510 20390 engines: {node: '>= 10.13.0'} 20511 20391 dependencies: 20512 - '@types/node': 18.18.6 20392 + '@types/node': 20.8.8 20513 20393 merge-stream: 2.0.0 20514 20394 supports-color: 7.2.0 20515 20395 dev: true ··· 20518 20398 resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} 20519 20399 engines: {node: '>= 10.13.0'} 20520 20400 dependencies: 20521 - '@types/node': 18.18.6 20401 + '@types/node': 20.8.8 20522 20402 merge-stream: 2.0.0 20523 20403 supports-color: 8.1.1 20524 20404 dev: true ··· 21062 20942 set-cookie-parser: 2.5.1 21063 20943 dev: true 21064 20944 21065 - /lighthouse-logger@1.3.0: 21066 - resolution: {integrity: sha512-BbqAKApLb9ywUli+0a+PcV04SyJ/N1q/8qgCNe6U97KbPCS1BTksEuHFLYdvc8DltuhfxIUBqDZsC0bBGtl3lA==} 21067 - dependencies: 21068 - debug: 2.6.9 21069 - marky: 1.2.5 21070 - transitivePeerDependencies: 21071 - - supports-color 21072 - dev: true 21073 - 21074 20945 /lilconfig@2.1.0: 21075 20946 resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} 21076 20947 engines: {node: '>=10'} ··· 21279 21150 resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} 21280 21151 dev: true 21281 21152 21282 - /lodash.defaults@4.2.0: 21283 - resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} 21284 - dev: true 21285 - 21286 - /lodash.difference@4.5.0: 21287 - resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} 21288 - dev: true 21289 - 21290 21153 /lodash.escape@4.0.1: 21291 21154 resolution: {integrity: sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==} 21292 - dev: true 21293 - 21294 - /lodash.flatten@4.4.0: 21295 - resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} 21296 21155 dev: true 21297 21156 21298 21157 /lodash.flattendeep@4.4.0: ··· 21301 21160 21302 21161 /lodash.isequal@4.5.0: 21303 21162 resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} 21304 - dev: true 21305 - 21306 - /lodash.isplainobject@4.0.6: 21307 - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} 21308 21163 dev: true 21309 21164 21310 21165 /lodash.merge@4.6.2: ··· 21317 21172 21318 21173 /lodash.sortby@4.7.0: 21319 21174 resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} 21320 - dev: true 21321 - 21322 - /lodash.union@4.6.0: 21323 - resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} 21324 21175 dev: true 21325 21176 21326 21177 /lodash.uniq@4.5.0: ··· 21549 21400 warp10: 2.1.0 21550 21401 transitivePeerDependencies: 21551 21402 - supports-color 21552 - dev: true 21553 - 21554 - /marky@1.2.5: 21555 - resolution: {integrity: sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==} 21556 21403 dev: true 21557 21404 21558 21405 /match-sorter@6.3.1: ··· 21828 21675 resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 21829 21676 dependencies: 21830 21677 brace-expansion: 1.1.11 21831 - 21832 - /minimatch@5.1.1: 21833 - resolution: {integrity: sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==} 21834 - engines: {node: '>=10'} 21835 - dependencies: 21836 - brace-expansion: 2.0.1 21837 - dev: true 21838 21678 21839 21679 /minimatch@5.1.6: 21840 21680 resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} ··· 22292 22132 resolution: {integrity: sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==} 22293 22133 dev: true 22294 22134 22295 - /node-fetch@2.6.11: 22296 - resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} 22297 - engines: {node: 4.x || >=6.0.0} 22298 - peerDependencies: 22299 - encoding: ^0.1.0 22300 - peerDependenciesMeta: 22301 - encoding: 22302 - optional: true 22303 - dependencies: 22304 - whatwg-url: 5.0.0 22305 - dev: true 22306 - 22307 22135 /node-fetch@2.6.7: 22308 22136 resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} 22309 22137 engines: {node: 4.x || >=6.0.0} ··· 22385 22213 hosted-git-info: 2.8.9 22386 22214 resolve: 1.22.8 22387 22215 semver: 5.7.2 22388 - validate-npm-package-license: 3.0.4 22389 - dev: true 22390 - 22391 - /normalize-package-data@3.0.3: 22392 - resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} 22393 - engines: {node: '>=10'} 22394 - dependencies: 22395 - hosted-git-info: 4.1.0 22396 - is-core-module: 2.13.0 22397 - semver: 7.5.4 22398 22216 validate-npm-package-license: 3.0.4 22399 22217 dev: true 22400 22218 ··· 22825 22643 /p-finally@1.0.0: 22826 22644 resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} 22827 22645 engines: {node: '>=4'} 22828 - dev: true 22829 - 22830 - /p-iteration@1.1.8: 22831 - resolution: {integrity: sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ==} 22832 - engines: {node: '>=8.0.0'} 22833 22646 dev: true 22834 22647 22835 22648 /p-limit@2.3.0: ··· 23287 23100 resolution: {integrity: sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==} 23288 23101 dependencies: 23289 23102 readable-stream: 4.1.0 23290 - split2: 4.1.0 23103 + split2: 4.2.0 23291 23104 dev: true 23292 23105 23293 23106 /pino-std-serializers@6.0.0: ··· 23351 23164 mlly: 1.4.0 23352 23165 pathe: 1.1.1 23353 23166 23354 - /playwright-chromium@1.30.0: 23355 - resolution: {integrity: sha512-ZfqjYdFuxnZxK02mDZtHFK/Mi0+cjCVn51RmwLwLLHA8PkCExk0odmZH2REx+LjqX8tDLGnmf6vDnPAirdSY0g==} 23356 - engines: {node: '>=14'} 23357 - hasBin: true 23358 - requiresBuild: true 23359 - dependencies: 23360 - playwright-core: 1.30.0 23361 - dev: true 23362 - 23363 - /playwright-core@1.28.0: 23364 - resolution: {integrity: sha512-nJLknd28kPBiCNTbqpu6Wmkrh63OEqJSFw9xOfL9qxfNwody7h6/L3O2dZoWQ6Oxcm0VOHjWmGiCUGkc0X3VZA==} 23365 - engines: {node: '>=14'} 23366 - hasBin: true 23367 - dev: true 23368 - 23369 - /playwright-core@1.30.0: 23370 - resolution: {integrity: sha512-7AnRmTCf+GVYhHbLJsGUtskWTE33SwMZkybJ0v6rqR1boxq2x36U7p1vDRV7HO2IwTZgmycracLxPEJI49wu4g==} 23371 - engines: {node: '>=14'} 23372 - hasBin: true 23373 - dev: true 23374 - 23375 - /playwright-core@1.35.1: 23376 - resolution: {integrity: sha512-pNXb6CQ7OqmGDRspEjlxE49w+4YtR6a3X6mT1hZXeJHWmsEz7SunmvZeiG/+y1yyMZdHnnn73WKYdtV1er0Xyg==} 23377 - engines: {node: '>=16'} 23378 - hasBin: true 23379 - dev: true 23380 - 23381 - /playwright@1.28.0: 23382 - resolution: {integrity: sha512-kyOXGc5y1mgi+hgEcCIyE1P1+JumLrxS09nFHo5sdJNzrucxPRAGwM4A2X3u3SDOfdgJqx61yIoR6Av+5plJPg==} 23383 - engines: {node: '>=14'} 23384 - hasBin: true 23385 - requiresBuild: true 23386 - dependencies: 23387 - playwright-core: 1.28.0 23388 - dev: true 23389 - 23390 - /playwright@1.35.1: 23391 - resolution: {integrity: sha512-NbwBeGJLu5m7VGM0+xtlmLAH9VUfWwYOhUi/lSEDyGg46r1CA9RWlvoc5yywxR9AzQb0mOCm7bWtOXV7/w43ZA==} 23167 + /playwright-chromium@1.39.0: 23168 + resolution: {integrity: sha512-0WVmvn9ppPbcyb2PQherIpzsvJlyjqziCZiAiexTEYSz8k6/+/3wljmFaMRMP1lcv2xKyHDn9yWd/lHb7IzYyA==} 23392 23169 engines: {node: '>=16'} 23393 23170 hasBin: true 23394 23171 requiresBuild: true 23395 23172 dependencies: 23396 - playwright-core: 1.35.1 23173 + playwright-core: 1.39.0 23174 + dev: true 23175 + 23176 + /playwright-core@1.39.0: 23177 + resolution: {integrity: sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==} 23178 + engines: {node: '>=16'} 23179 + hasBin: true 23180 + dev: true 23181 + 23182 + /playwright@1.39.0: 23183 + resolution: {integrity: sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==} 23184 + engines: {node: '>=16'} 23185 + hasBin: true 23186 + dependencies: 23187 + playwright-core: 1.39.0 23188 + optionalDependencies: 23189 + fsevents: 2.3.2 23397 23190 dev: true 23398 23191 23399 23192 /pluralize@8.0.0: ··· 23802 23595 /punycode@2.3.0: 23803 23596 resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} 23804 23597 engines: {node: '>=6'} 23805 - dev: true 23806 - 23807 - /puppeteer-core@20.3.0(typescript@5.1.6): 23808 - resolution: {integrity: sha512-264pBrIui5bO6NJeOcbJrLa0OCwmA4+WK00JMrLIKTfRiqe2gx8KWTzLsjyw/bizErp3TKS7vt/I0i5fTC+mAw==} 23809 - engines: {node: '>=16.0.0'} 23810 - peerDependencies: 23811 - typescript: '>= 4.7.4' 23812 - peerDependenciesMeta: 23813 - typescript: 23814 - optional: true 23815 - dependencies: 23816 - '@puppeteer/browsers': 1.3.0(typescript@5.1.6) 23817 - chromium-bidi: 0.4.9(devtools-protocol@0.0.1120988) 23818 - cross-fetch: 3.1.6 23819 - debug: 4.3.4(supports-color@8.1.1) 23820 - devtools-protocol: 0.0.1120988 23821 - typescript: 5.1.6 23822 - ws: 8.13.0 23823 - transitivePeerDependencies: 23824 - - bufferutil 23825 - - encoding 23826 - - supports-color 23827 - - utf-8-validate 23828 23598 dev: true 23829 23599 23830 23600 /puppeteer-core@20.9.0(typescript@5.1.6): ··· 24345 24115 type-fest: 0.8.1 24346 24116 dev: true 24347 24117 24348 - /read-pkg-up@9.1.0: 24349 - resolution: {integrity: sha512-vaMRR1AC1nrd5CQM0PhlRsO5oc2AAigqr7cCrZ/MW/Rsaflz4RlgzkpL4qoU/z1F6wrbd85iFv1OQj/y5RdGvg==} 24350 - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 24351 - dependencies: 24352 - find-up: 6.3.0 24353 - read-pkg: 7.1.0 24354 - type-fest: 2.19.0 24355 - dev: true 24356 - 24357 24118 /read-pkg@1.1.0: 24358 24119 resolution: {integrity: sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==} 24359 24120 engines: {node: '>=0.10.0'} ··· 24382 24143 normalize-package-data: 2.5.0 24383 24144 parse-json: 5.2.0 24384 24145 type-fest: 0.6.0 24385 - dev: true 24386 - 24387 - /read-pkg@7.1.0: 24388 - resolution: {integrity: sha512-5iOehe+WF75IccPc30bWTbpdDQLOCc3Uu8bi3Dte3Eueij81yx1Mrufk8qBx/YAbR4uL1FdUr+7BKXDwEtisXg==} 24389 - engines: {node: '>=12.20'} 24390 - dependencies: 24391 - '@types/normalize-package-data': 2.4.1 24392 - normalize-package-data: 3.0.3 24393 - parse-json: 5.2.0 24394 - type-fest: 2.19.0 24395 24146 dev: true 24396 24147 24397 24148 /read-pkg@8.1.0: ··· 25062 24813 resolution: {integrity: sha512-EgK9Vc2Bk4WaECq1E7ti9GyeQ6JKKQNs40vNOE/b5Ul5dDEt429G0Kj5Nzs4FRS5ZIVa7nBck1TyHuinOYdz2Q==} 25063 24814 dev: true 25064 24815 25065 - /safaridriver@0.0.5: 25066 - resolution: {integrity: sha512-997HUPVHdOk0019Yz2qbX/B47bC0LcUxMrHU2PDY8IOO7hiT1uhBQEeEAF1BeCrZKFgx5cmsbWYmFgFN0TfqNA==} 25067 - dev: true 25068 - 25069 24816 /safaridriver@0.1.0: 25070 24817 resolution: {integrity: sha512-azzzIP3gR1TB9bVPv7QO4Zjw0rR1BWEU/s2aFdUMN48gxDjxEB13grAEuXDmkKPgE74cObymDxmAmZnL3clj4w==} 25071 24818 dev: true ··· 25322 25069 engines: {node: '>=14.16'} 25323 25070 dependencies: 25324 25071 type-fest: 2.19.0 25325 - dev: true 25326 - 25327 - /serialize-error@8.1.0: 25328 - resolution: {integrity: sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==} 25329 - engines: {node: '>=10'} 25330 - dependencies: 25331 - type-fest: 0.20.2 25332 25072 dev: true 25333 25073 25334 25074 /serialize-javascript@4.0.0: ··· 25827 25567 engines: {node: '>=0.10.0'} 25828 25568 dependencies: 25829 25569 extend-shallow: 3.0.2 25830 - dev: true 25831 - 25832 - /split2@4.1.0: 25833 - resolution: {integrity: sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==} 25834 - engines: {node: '>= 10.x'} 25835 25570 dev: true 25836 25571 25837 25572 /split2@4.2.0: ··· 27192 26927 hasBin: true 27193 26928 dev: true 27194 26929 27195 - /ua-parser-js@1.0.34: 27196 - resolution: {integrity: sha512-K9mwJm/DaB6mRLZfw6q8IMXipcrmuT6yfhYmwhAkuh+81sChuYstYA+znlgaflUPaYUa3odxKPKGw6Vw/lANew==} 27197 - dev: true 27198 - 27199 26930 /ufo@1.1.2: 27200 26931 resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==} 27201 26932 ··· 27239 26970 '@antfu/utils': 0.7.5 27240 26971 defu: 6.1.2 27241 26972 jiti: 1.18.2 26973 + dev: true 26974 + 26975 + /undici-types@5.25.3: 26976 + resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==} 27242 26977 dev: true 27243 26978 27244 26979 /undici@5.22.1: ··· 27853 27588 hasBin: true 27854 27589 dev: true 27855 27590 27856 - /uuid@9.0.0: 27857 - resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} 27858 - hasBin: true 27859 - dev: true 27860 - 27861 27591 /v8-compile-cache@2.3.0: 27862 27592 resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} 27863 27593 dev: true ··· 28392 28122 engines: {node: '>= 8'} 28393 28123 dev: true 28394 28124 28395 - /webdriver@8.12.1: 28396 - resolution: {integrity: sha512-Ca+MUYUXfl5gsnX40xAIUgfoa76qQsfX7REGFzMl09Cb7vHKtM17bEOGDaTbXIX4kbkXylyUSAuBpe3gCtDDKg==} 28397 - engines: {node: ^16.13 || >=18} 28398 - dependencies: 28399 - '@types/node': 20.8.2 28400 - '@types/ws': 8.5.5 28401 - '@wdio/config': 8.12.1 28402 - '@wdio/logger': 8.11.0 28403 - '@wdio/protocols': 8.11.0 28404 - '@wdio/types': 8.10.4 28405 - '@wdio/utils': 8.12.1 28406 - deepmerge-ts: 5.0.0 28407 - got: 12.6.1 28408 - ky: 0.33.3 28409 - ws: 8.13.0 28410 - transitivePeerDependencies: 28411 - - bufferutil 28412 - - utf-8-validate 28413 - dev: true 28414 - 28415 28125 /webdriver@8.16.20: 28416 28126 resolution: {integrity: sha512-3Dynj9pfTqmbDadqmMmD/sQgGFwho92zQPGgpAqLUMebE/qEkraoIfRWdbi2tw1ityiThOJVPTXfwsY/bpvknw==} 28417 28127 engines: {node: ^16.13 || >=18} 28418 28128 dependencies: 28419 - '@types/node': 20.8.2 28129 + '@types/node': 20.8.8 28420 28130 '@types/ws': 8.5.5 28421 28131 '@wdio/config': 8.16.20 28422 28132 '@wdio/logger': 8.16.17 ··· 28433 28143 - utf-8-validate 28434 28144 dev: true 28435 28145 28436 - /webdriverio@8.12.1(typescript@5.1.6): 28437 - resolution: {integrity: sha512-lW0Qo3fy64cVbYWWAZbXxLIOK0pbTARgpY89J+0Sr6zh2K2NKtd/0D11k3WfMeYxd0b0he7E7XC1b6M6w4h75A==} 28146 + /webdriver@8.20.0: 28147 + resolution: {integrity: sha512-U/sej7yljVf/enEWR9L2AtOntrd3lqtkEtHeuSWU2FPp5cWvoMEe7vQiG0WJA74VE2e7uwd8S1LfCgQD1wY3Bg==} 28438 28148 engines: {node: ^16.13 || >=18} 28439 28149 dependencies: 28440 - '@types/node': 20.8.2 28441 - '@wdio/config': 8.12.1 28442 - '@wdio/logger': 8.11.0 28443 - '@wdio/protocols': 8.11.0 28444 - '@wdio/repl': 8.10.1 28445 - '@wdio/types': 8.10.4 28446 - '@wdio/utils': 8.12.1 28447 - archiver: 5.3.1 28448 - aria-query: 5.3.0 28449 - css-shorthand-properties: 1.1.1 28450 - css-value: 0.0.1 28451 - devtools: 8.12.1(typescript@5.1.6) 28452 - devtools-protocol: 0.0.1161598 28453 - grapheme-splitter: 1.0.4 28454 - import-meta-resolve: 3.0.0 28455 - is-plain-obj: 4.1.0 28456 - lodash.clonedeep: 4.5.0 28457 - lodash.zip: 4.2.0 28458 - minimatch: 9.0.3 28459 - puppeteer-core: 20.3.0(typescript@5.1.6) 28460 - query-selector-shadow-dom: 1.0.1 28461 - resq: 1.11.0 28462 - rgb2hex: 0.2.5 28463 - serialize-error: 8.1.0 28464 - webdriver: 8.12.1 28150 + '@types/node': 20.8.8 28151 + '@types/ws': 8.5.5 28152 + '@wdio/config': 8.20.0 28153 + '@wdio/logger': 8.16.17 28154 + '@wdio/protocols': 8.18.0 28155 + '@wdio/types': 8.20.0 28156 + '@wdio/utils': 8.20.0 28157 + deepmerge-ts: 5.1.0 28158 + got: 12.6.1 28159 + ky: 0.33.3 28160 + ws: 8.13.0 28465 28161 transitivePeerDependencies: 28466 28162 - bufferutil 28467 - - encoding 28468 28163 - supports-color 28469 - - typescript 28470 28164 - utf-8-validate 28471 28165 dev: true 28472 28166 ··· 28503 28197 rgb2hex: 0.2.5 28504 28198 serialize-error: 11.0.2 28505 28199 webdriver: 8.16.20 28200 + transitivePeerDependencies: 28201 + - bufferutil 28202 + - encoding 28203 + - supports-color 28204 + - typescript 28205 + - utf-8-validate 28206 + dev: true 28207 + 28208 + /webdriverio@8.20.0(typescript@5.1.6): 28209 + resolution: {integrity: sha512-nVd3n4v1CYzjEezK6OgmGIcVx+T/7PNYwLK3fTNH2hGRNX05TyGGcR9HAcVZCbIu8WWFKRE0SrLvCjEutPO8gg==} 28210 + engines: {node: ^16.13 || >=18} 28211 + peerDependencies: 28212 + devtools: ^8.14.0 28213 + peerDependenciesMeta: 28214 + devtools: 28215 + optional: true 28216 + dependencies: 28217 + '@types/node': 20.8.8 28218 + '@wdio/config': 8.20.0 28219 + '@wdio/logger': 8.16.17 28220 + '@wdio/protocols': 8.18.0 28221 + '@wdio/repl': 8.10.1 28222 + '@wdio/types': 8.20.0 28223 + '@wdio/utils': 8.20.0 28224 + archiver: 6.0.1 28225 + aria-query: 5.3.0 28226 + css-shorthand-properties: 1.1.1 28227 + css-value: 0.0.1 28228 + devtools-protocol: 0.0.1209236 28229 + grapheme-splitter: 1.0.4 28230 + import-meta-resolve: 3.0.0 28231 + is-plain-obj: 4.1.0 28232 + lodash.clonedeep: 4.5.0 28233 + lodash.zip: 4.2.0 28234 + minimatch: 9.0.3 28235 + puppeteer-core: 20.9.0(typescript@5.1.6) 28236 + query-selector-shadow-dom: 1.0.1 28237 + resq: 1.11.0 28238 + rgb2hex: 0.2.5 28239 + serialize-error: 11.0.2 28240 + webdriver: 8.20.0 28506 28241 transitivePeerDependencies: 28507 28242 - bufferutil 28508 28243 - encoding ··· 28829 28564 /which@2.0.2: 28830 28565 resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 28831 28566 engines: {node: '>= 8'} 28832 - hasBin: true 28833 - dependencies: 28834 - isexe: 2.0.0 28835 - dev: true 28836 - 28837 - /which@3.0.0: 28838 - resolution: {integrity: sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ==} 28839 - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} 28840 28567 hasBin: true 28841 28568 dependencies: 28842 28569 isexe: 2.0.0 ··· 29278 29005 /zen-observable@0.8.15: 29279 29006 resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} 29280 29007 dev: false 29281 - 29282 - /zip-stream@4.1.0: 29283 - resolution: {integrity: sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==} 29284 - engines: {node: '>= 10'} 29285 - dependencies: 29286 - archiver-utils: 2.1.0 29287 - compress-commons: 4.1.1 29288 - readable-stream: 3.6.0 29289 - dev: true 29290 29008 29291 29009 /zip-stream@5.0.1: 29292 29010 resolution: {integrity: sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==}
+6 -29
.github/workflows/ci.yml
··· 125 125 - uses: browser-actions/setup-chrome@v1 126 126 - uses: browser-actions/setup-firefox@v1 127 127 - uses: browser-actions/setup-edge@v1 128 + id: setup-edge 128 129 with: 129 - edge-version: beta 130 + edge-version: stable 130 131 131 132 - name: Install 132 133 run: pnpm i 133 134 134 135 - name: Install Playwright Dependencies 135 - run: pnpx playwright install-deps 136 + run: pnpx playwright install --with-deps 136 137 137 138 - name: Build 138 139 run: pnpm run build 139 140 140 141 - name: Test Browser (webdriverio) 141 142 run: pnpm run test:browser:webdriverio 143 + env: 144 + EDGEDRIVER_VERSION: ${{ steps.setup-edge.outputs.edge-version }} 142 145 143 146 - name: Test Browser (playwright) 144 147 run: pnpm run test:browser:playwright ··· 169 172 run: pnpm i 170 173 171 174 - name: Install Playwright Dependencies 172 - run: pnpx playwright install-deps 175 + run: pnpx playwright install --with-deps 173 176 174 177 - name: Build 175 178 run: pnpm run build ··· 181 184 run: pnpm run test:browser:playwright 182 185 env: 183 186 BROWSER: ${{ matrix.browser[1] }} 184 - 185 - test-browser-safari: 186 - runs-on: macos-latest 187 - timeout-minutes: 30 188 - 189 - steps: 190 - - uses: actions/checkout@v4 191 - 192 - - uses: ./.github/actions/setup-and-cache 193 - with: 194 - node-version: 20 195 - 196 - - name: Install 197 - run: sudo pnpm i --frozen-lockfile 198 - 199 - - name: Build 200 - run: sudo pnpm run build 201 - 202 - - name: Enable 203 - run: sudo safaridriver --enable 204 - 205 - - name: Test Browser (webdriverio) 206 - run: sudo BROWSER=safari pnpm run test:browser:webdriverio 207 - 208 - - name: Test Browser (playwright) 209 - run: sudo BROWSER=webkit pnpm run test:browser:playwright
+37 -1
docs/config/index.md
··· 1332 1332 export interface BrowserProvider { 1333 1333 name: string 1334 1334 getSupportedBrowsers(): readonly string[] 1335 - initialize(ctx: Vitest, options: { browser: string }): Awaitable<void> 1335 + initialize(ctx: Vitest, options: { browser: string; options?: BrowserProviderOptions }): Awaitable<void> 1336 1336 openPage(url: string): Awaitable<void> 1337 1337 close(): Awaitable<void> 1338 1338 } ··· 1340 1340 1341 1341 ::: warning 1342 1342 This is an advanced API for library authors. If you just need to run tests in a browser, use the [browser](/config/#browser) option. 1343 + ::: 1344 + 1345 + #### browser.providerOptions 1346 + 1347 + - **Type:** `BrowserProviderOptions` 1348 + - **Version:** Since Vitest 1.0.0-beta.3 1349 + 1350 + Options that will be passed down to provider when calling `provider.initialize`. 1351 + 1352 + ```ts 1353 + export default defineConfig({ 1354 + test: { 1355 + browser: { 1356 + providerOptions: { 1357 + launch: { 1358 + devtools: true, 1359 + } 1360 + } 1361 + } 1362 + } 1363 + }) 1364 + ``` 1365 + 1366 + ::: tip 1367 + To have a better type safety when using built-in providers, you can add one of these types (for provider that you are using) to your tsconfig's `compilerOptions.types` field: 1368 + 1369 + ```json 1370 + { 1371 + "compilerOptions": { 1372 + "types": [ 1373 + "@vitest/browser/providers/webdriverio", 1374 + "@vitest/browser/providers/playwright" 1375 + ] 1376 + } 1377 + } 1378 + ``` 1343 1379 ::: 1344 1380 1345 1381 #### browser.slowHijackESM
+2 -2
examples/playwright/package.json
··· 7 7 "test:ui": "vite build && vitest --ui" 8 8 }, 9 9 "devDependencies": { 10 - "@playwright/test": "^1.28.0", 10 + "@playwright/test": "^1.39.0", 11 11 "@vitest/ui": "latest", 12 - "playwright": "^1.28.0", 12 + "playwright": "^1.39.0", 13 13 "vite": "latest", 14 14 "vitest": "latest" 15 15 }
+32 -3
packages/browser/package.json
··· 20 20 "types": "./dist/index.d.ts", 21 21 "import": "./dist/index.js" 22 22 }, 23 + "./providers": { 24 + "types": "./providers.d.ts", 25 + "import": "./dist/providers.js" 26 + }, 27 + "./providers/webdriverio": { 28 + "types": "./dist/providers/webdriverio.d.ts" 29 + }, 30 + "./providers/playwright": { 31 + "types": "./dist/providers/playwright.d.ts" 32 + }, 23 33 "./*": "./*" 24 34 }, 25 35 "main": "./dist/index.js", ··· 27 37 "types": "./dist/index.d.ts", 28 38 "files": [ 29 39 "dist", 30 - "stubs" 40 + "providers" 31 41 ], 32 42 "scripts": { 33 43 "build": "rimraf dist && pnpm build:node && pnpm build:client", ··· 39 49 "prepublishOnly": "pnpm build" 40 50 }, 41 51 "peerDependencies": { 42 - "vitest": "^1.0.0-0" 52 + "playwright": "*", 53 + "safaridriver": "*", 54 + "vitest": "^1.0.0-0", 55 + "webdriverio": "*" 56 + }, 57 + "peerDependenciesMeta": { 58 + "webdriverio": { 59 + "optional": true 60 + }, 61 + "safaridriver": { 62 + "optional": true 63 + }, 64 + "playwright": { 65 + "optional": true 66 + } 43 67 }, 44 68 "dependencies": { 45 69 "estree-walker": "^3.0.3", ··· 52 76 "@vitest/runner": "workspace:*", 53 77 "@vitest/ui": "workspace:*", 54 78 "@vitest/ws-client": "workspace:*", 79 + "@wdio/protocols": "^8.18.0", 55 80 "periscopic": "^3.1.0", 56 - "vitest": "workspace:*" 81 + "playwright": "^1.39.0", 82 + "playwright-core": "^1.39.0", 83 + "safaridriver": "^0.1.0", 84 + "vitest": "workspace:*", 85 + "webdriverio": "^8.20.0" 57 86 } 58 87 }
+6
packages/browser/providers.d.ts
··· 1 + import type { BrowserProvider } from 'vitest/nide' 2 + 3 + declare var webdriverio: BrowserProvider 4 + declare var playwright: BrowserProvider 5 + 6 + export { webdriverio, playwright }
+9 -4
packages/browser/rollup.config.js
··· 8 8 const external = [ 9 9 ...Object.keys(pkg.dependencies), 10 10 ...Object.keys(pkg.peerDependencies || {}), 11 + 'vitest/node', 12 + 'vitest', 11 13 'worker_threads', 12 14 'node:worker_threads', 13 15 ] ··· 23 25 }), 24 26 ] 25 27 28 + const input = { 29 + index: './src/node/index.ts', 30 + providers: './src/node/providers/index.ts', 31 + } 32 + 26 33 export default () => [ 27 34 { 28 - input: [ 29 - './src/node/index.ts', 30 - ], 35 + input, 31 36 output: { 32 37 dir: 'dist', 33 38 format: 'esm', ··· 36 41 plugins, 37 42 }, 38 43 { 39 - input: './src/node/index.ts', 44 + input: input.index, 40 45 output: { 41 46 file: 'dist/index.d.ts', 42 47 format: 'esm',
+1 -16
packages/vitest/package.json
··· 111 111 "@vitest/browser": "*", 112 112 "@vitest/ui": "*", 113 113 "happy-dom": "*", 114 - "jsdom": "*", 115 - "playwright": "*", 116 - "safaridriver": "*", 117 - "webdriverio": "*" 114 + "jsdom": "*" 118 115 }, 119 116 "peerDependenciesMeta": { 120 117 "@types/node": { ··· 130 127 "optional": true 131 128 }, 132 129 "jsdom": { 133 - "optional": true 134 - }, 135 - "webdriverio": { 136 - "optional": true 137 - }, 138 - "safaridriver": { 139 - "optional": true 140 - }, 141 - "playwright": { 142 130 "optional": true 143 131 }, 144 132 "@edge-runtime/vm": { ··· 198 186 "mlly": "^1.4.0", 199 187 "p-limit": "^4.0.0", 200 188 "pkg-types": "^1.0.3", 201 - "playwright": "^1.35.1", 202 189 "pretty-format": "^29.5.0", 203 190 "prompts": "^2.4.2", 204 - "safaridriver": "^0.0.5", 205 191 "strip-ansi": "^7.1.0", 206 - "webdriverio": "^8.11.2", 207 192 "ws": "^8.13.0" 208 193 } 209 194 }
+1 -3
packages/vitest/rollup.config.js
··· 59 59 'rollup', 60 60 'node:vm', 61 61 'inspector', 62 - 'webdriverio', 63 - 'safaridriver', 64 - 'playwright', 65 62 'vite-node/source-map', 66 63 'vite-node/client', 67 64 'vite-node/server', ··· 92 89 export default ({ watch }) => defineConfig([ 93 90 { 94 91 input: entries, 92 + treeshake: true, 95 93 output: { 96 94 dir: 'dist', 97 95 format: 'esm',
+1 -1
test/ui/package.json
··· 7 7 "devDependencies": { 8 8 "execa": "^6.1.0", 9 9 "fs-extra": "^10.1.0", 10 - "playwright-chromium": "^1.27.0", 10 + "playwright-chromium": "^1.39.0", 11 11 "vitest": "workspace:*" 12 12 } 13 13 }
+8
packages/browser/providers/playwright.d.ts
··· 1 + import type { Browser, LaunchOptions } from 'playwright' 2 + 3 + declare module 'vitest/node' { 4 + interface BrowserProviderOptions { 5 + launch?: LaunchOptions 6 + page?: Parameters<Browser['newPage']>[0] 7 + } 8 + }
+5
packages/browser/providers/webdriverio.d.ts
··· 1 + import type { RemoteOptions } from 'webdriverio' 2 + 3 + declare module 'vitest/node' { 4 + interface BrowserProviderOptions extends RemoteOptions {} 5 + }
+1 -1
test/bail/test/bail.test.ts
··· 6 6 const pools: UserConfig[] = [{ pool: 'threads' }, { pool: 'forks' }, { pool: 'threads', poolOptions: { threads: { singleThread: true } } }] 7 7 8 8 if (process.platform !== 'win32') 9 - pools.push({ browser: { enabled: true, name: 'chrome' } }) 9 + pools.push({ browser: { enabled: true, name: 'chromium', provider: 'playwright' } }) 10 10 11 11 for (const isolate of [true, false]) { 12 12 for (const pool of pools) {
+2 -2
test/core/test/sequencers.test.ts
··· 1 1 import type { Vitest } from 'vitest' 2 2 import { describe, expect, test, vi } from 'vitest' 3 - import type { VitestWorkspace } from 'vitest/node' 3 + import type { WorkspaceProject } from 'vitest/node' 4 4 import { RandomSequencer } from '../../../packages/vitest/src/node/sequencers/RandomSequencer' 5 5 import { BaseSequencer } from '../../../packages/vitest/src/node/sequencers/BaseSequencer' 6 6 import type { WorkspaceSpec } from '../../../packages/vitest/src/node/pool' ··· 20 20 function buildWorkspace() { 21 21 return { 22 22 getName: () => 'test', 23 - } as any as VitestWorkspace 23 + } as any as WorkspaceProject 24 24 } 25 25 26 26 const workspace = buildWorkspace()
+6 -1
packages/browser/src/client/main.ts
··· 70 70 message: unhandledError.message, 71 71 stack: unhandledError.stack, 72 72 } 73 + if (testId !== 'no-isolate') 74 + error.VITEST_TEST_PATH = testId 73 75 await client.rpc.onUnhandledError(error, type) 74 76 await client.rpc.onDone(testId) 75 77 } ··· 81 83 82 84 async function reportUnexpectedError(rpc: typeof client.rpc, type: string, error: any) { 83 85 const { processError } = await importId('vitest/browser') as typeof import('vitest/browser') 84 - await rpc.onUnhandledError(processError(error), type) 86 + const processedError = processError(error) 87 + if (testId !== 'no-isolate') 88 + error.VITEST_TEST_PATH = testId 89 + await rpc.onUnhandledError(processedError, type) 85 90 if (!runningTests) 86 91 await rpc.onDone(testId) 87 92 }
+12 -14
packages/vitest/src/integrations/browser.ts
··· 1 - import { PlaywrightBrowserProvider } from '../node/browser/playwright' 2 - import { WebdriverBrowserProvider } from '../node/browser/webdriver' 1 + import { ensurePackageInstalled } from '../node/pkg' 3 2 import type { BrowserProviderModule, ResolvedBrowserOptions } from '../types/browser' 4 3 5 4 interface Loader { 6 - executeId: (id: string) => Promise<{ default: BrowserProviderModule }> 5 + root: string 6 + executeId: (id: string) => any 7 7 } 8 8 9 9 export async function getBrowserProvider(options: ResolvedBrowserOptions, loader: Loader): Promise<BrowserProviderModule> { 10 - switch (options.provider) { 11 - case undefined: 12 - case 'webdriverio': 13 - return WebdriverBrowserProvider 14 - 15 - case 'playwright': 16 - return PlaywrightBrowserProvider 17 - 18 - default: 19 - break 10 + if (options.provider == null || options.provider === 'webdriverio' || options.provider === 'playwright') { 11 + await ensurePackageInstalled('@vitest/browser', loader.root) 12 + const providers = await loader.executeId('@vitest/browser/providers') as { 13 + webdriverio: BrowserProviderModule 14 + playwright: BrowserProviderModule 15 + } 16 + const provider = (options.provider || 'webdriverio') as 'webdriverio' | 'playwright' 17 + return providers[provider] 20 18 } 21 19 22 20 let customProviderModule 23 21 24 22 try { 25 - customProviderModule = await loader.executeId(options.provider) 23 + customProviderModule = await loader.executeId(options.provider) as { default: BrowserProviderModule } 26 24 } 27 25 catch (error) { 28 26 throw new Error(`Failed to load custom BrowserProvider from ${options.provider}`, { cause: error })
+4 -1
packages/vitest/src/node/index.ts
··· 1 1 export type { Vitest } from './core' 2 - export type { WorkspaceProject as VitestWorkspace } from './workspace' 2 + export type { WorkspaceProject } from './workspace' 3 3 export { createVitest } from './create' 4 4 export { VitestPlugin } from './plugins' 5 5 export { startVitest } from './cli-api' ··· 8 8 9 9 export type { TestSequencer, TestSequencerConstructor } from './sequencers/types' 10 10 export { BaseSequencer } from './sequencers/BaseSequencer' 11 + 12 + export { ensurePackageInstalled } from './pkg' 13 + export type { BrowserProviderInitializationOptions, BrowserProvider, BrowserProviderOptions } from '../types/browser'
+2 -1
packages/vitest/src/node/workspace.ts
··· 356 356 throw new Error(`[${this.getName()}] Browser name is required. Please, set \`test.browser.name\` option manually.`) 357 357 if (!supportedBrowsers.includes(browser)) 358 358 throw new Error(`[${this.getName()}] Browser "${browser}" is not supported by the browser provider "${this.browserProvider.name}". Supported browsers: ${supportedBrowsers.join(', ')}.`) 359 - await this.browserProvider.initialize(this, { browser }) 359 + const providerOptions = this.config.browser.providerOptions 360 + await this.browserProvider.initialize(this, { browser, options: providerOptions }) 360 361 } 361 362 }
+1 -1
packages/vitest/src/runtime/child.ts
··· 8 8 import type { ResolvedConfig, WorkerGlobalState } from '../types' 9 9 import type { RunnerRPC, RuntimeRPC } from '../types/rpc' 10 10 import type { ChildContext } from '../types/child' 11 - import { loadEnvironment } from '../integrations/env' 11 + import { loadEnvironment } from '../integrations/env/loader' 12 12 import { mockMap, moduleCache, startViteNode } from './execute' 13 13 import { createSafeRpc, rpcDone } from './rpc' 14 14 import { setupInspect } from './inspector'
+1 -1
packages/vitest/src/runtime/vm.ts
··· 9 9 import type { CancelReason } from '@vitest/runner' 10 10 import type { RunnerRPC, RuntimeRPC, WorkerContext, WorkerGlobalState } from '../types' 11 11 import { distDir } from '../paths' 12 - import { loadEnvironment } from '../integrations/env' 12 + import { loadEnvironment } from '../integrations/env/loader' 13 13 import { startVitestExecutor } from './execute' 14 14 import { createCustomConsole } from './console' 15 15 import { createSafeRpc } from './rpc'
+1 -1
packages/vitest/src/runtime/worker.ts
··· 4 4 import type { CancelReason } from '@vitest/runner' 5 5 import type { RunnerRPC, RuntimeRPC, WorkerContext, WorkerGlobalState } from '../types' 6 6 import { getWorkerState } from '../utils/global' 7 - import { loadEnvironment } from '../integrations/env' 7 + import { loadEnvironment } from '../integrations/env/loader' 8 8 import { mockMap, moduleCache, startViteNode } from './execute' 9 9 import { setupInspect } from './inspector' 10 10 import { createSafeRpc, rpcDone } from './rpc'
+18 -3
packages/vitest/src/types/browser.ts
··· 2 2 import type { WorkspaceProject } from '../node/workspace' 3 3 import type { ApiConfig } from './config' 4 4 5 - export interface BrowserProviderOptions { 5 + export interface BrowserProviderInitializationOptions { 6 6 browser: string 7 + options?: BrowserProviderOptions 7 8 } 8 9 9 10 export interface BrowserProvider { 10 11 name: string 11 12 getSupportedBrowsers(): readonly string[] 12 - initialize(ctx: WorkspaceProject, options: BrowserProviderOptions): Awaitable<void> 13 + initialize(ctx: WorkspaceProject, options: BrowserProviderInitializationOptions): Awaitable<void> 13 14 openPage(url: string): Awaitable<void> 14 15 catchError(cb: (error: Error) => Awaitable<void>): () => Awaitable<void> 15 16 close(): Awaitable<void> ··· 18 19 export interface BrowserProviderModule { 19 20 new (): BrowserProvider 20 21 } 22 + 23 + export interface BrowserProviderOptions {} 21 24 22 25 export interface BrowserConfigOptions { 23 26 /** ··· 33 36 name: string 34 37 35 38 /** 36 - * browser provider 39 + * Browser provider 37 40 * 38 41 * @default 'webdriverio' 39 42 */ 40 43 provider?: 'webdriverio' | 'playwright' | (string & {}) 44 + 45 + /** 46 + * Options that are passed down to a browser provider. 47 + * To support type hinting, add one of the types to your tsconfig.json "compilerOptions.types" field: 48 + * 49 + * - for webdriverio: `@vitest/browser/providers/webdriverio` 50 + * - for playwright: `@vitest/browser/providers/playwright` 51 + * 52 + * @example 53 + * { playwright: { launch: { devtools: true } } 54 + */ 55 + providerOptions?: BrowserProviderOptions 41 56 42 57 /** 43 58 * enable headless mode
+5
packages/browser/src/node/providers/index.ts
··· 1 + import { PlaywrightBrowserProvider } from './playwright' 2 + import { WebdriverBrowserProvider } from './webdriver' 3 + 4 + export const webdriverio = WebdriverBrowserProvider 5 + export const playwright = PlaywrightBrowserProvider
+80
packages/browser/src/node/providers/playwright.ts
··· 1 + import type { Browser, LaunchOptions, Page } from 'playwright' 2 + import type { BrowserProvider, BrowserProviderInitializationOptions, WorkspaceProject } from 'vitest/node' 3 + import { ensurePackageInstalled } from 'vitest/node' 4 + 5 + type Awaitable<T> = T | PromiseLike<T> 6 + 7 + export const playwrightBrowsers = ['firefox', 'webkit', 'chromium'] as const 8 + export type PlaywrightBrowser = typeof playwrightBrowsers[number] 9 + 10 + export interface PlaywrightProviderOptions extends BrowserProviderInitializationOptions { 11 + browser: PlaywrightBrowser 12 + } 13 + 14 + export class PlaywrightBrowserProvider implements BrowserProvider { 15 + public name = 'playwright' 16 + 17 + private cachedBrowser: Browser | null = null 18 + private cachedPage: Page | null = null 19 + private browser!: PlaywrightBrowser 20 + private ctx!: WorkspaceProject 21 + 22 + private options?: { 23 + launch?: LaunchOptions 24 + page?: Parameters<Browser['newPage']>[0] 25 + } 26 + 27 + getSupportedBrowsers() { 28 + return playwrightBrowsers 29 + } 30 + 31 + async initialize(ctx: WorkspaceProject, { browser, options }: PlaywrightProviderOptions) { 32 + this.ctx = ctx 33 + this.browser = browser 34 + this.options = options as any 35 + 36 + const root = this.ctx.config.root 37 + 38 + if (!await ensurePackageInstalled('playwright', root)) 39 + throw new Error('Cannot find "playwright" package. Please install it manually.') 40 + } 41 + 42 + private async openBrowserPage() { 43 + if (this.cachedPage) 44 + return this.cachedPage 45 + 46 + const options = this.ctx.config.browser 47 + 48 + const playwright = await import('playwright') 49 + 50 + const browser = await playwright[this.browser].launch({ 51 + ...this.options?.launch, 52 + headless: options.headless, 53 + }) 54 + this.cachedBrowser = browser 55 + this.cachedPage = await browser.newPage(this.options?.page) 56 + 57 + this.cachedPage.on('close', () => { 58 + browser.close() 59 + }) 60 + 61 + return this.cachedPage 62 + } 63 + 64 + catchError(cb: (error: Error) => Awaitable<void>) { 65 + this.cachedPage?.on('pageerror', cb) 66 + return () => { 67 + this.cachedPage?.off('pageerror', cb) 68 + } 69 + } 70 + 71 + async openPage(url: string) { 72 + const browserPage = await this.openBrowserPage() 73 + await browserPage.goto(url) 74 + } 75 + 76 + async close() { 77 + await this.cachedPage?.close() 78 + await this.cachedBrowser?.close() 79 + } 80 + }
+116
packages/browser/src/node/providers/webdriver.ts
··· 1 + import type { BrowserProvider, BrowserProviderInitializationOptions, WorkspaceProject } from 'vitest/node' 2 + import { ensurePackageInstalled } from 'vitest/node' 3 + import type { Browser, RemoteOptions } from 'webdriverio' 4 + 5 + type Awaitable<T> = T | PromiseLike<T> 6 + 7 + const webdriverBrowsers = ['firefox', 'chrome', 'edge', 'safari'] as const 8 + type WebdriverBrowser = typeof webdriverBrowsers[number] 9 + 10 + interface WebdriverProviderOptions extends BrowserProviderInitializationOptions { 11 + browser: WebdriverBrowser 12 + } 13 + 14 + export class WebdriverBrowserProvider implements BrowserProvider { 15 + public name = 'webdriverio' 16 + 17 + private cachedBrowser: Browser | null = null 18 + private stopSafari: () => void = () => {} 19 + private browser!: WebdriverBrowser 20 + private ctx!: WorkspaceProject 21 + 22 + private options?: RemoteOptions 23 + 24 + getSupportedBrowsers() { 25 + return webdriverBrowsers 26 + } 27 + 28 + async initialize(ctx: WorkspaceProject, { browser, options }: WebdriverProviderOptions) { 29 + this.ctx = ctx 30 + this.browser = browser 31 + this.options = options as RemoteOptions 32 + 33 + const root = this.ctx.config.root 34 + 35 + if (!await ensurePackageInstalled('webdriverio', root)) 36 + throw new Error('Cannot find "webdriverio" package. Please install it manually.') 37 + 38 + if (browser === 'safari' && !await ensurePackageInstalled('safaridriver', root)) 39 + throw new Error('Cannot find "safaridriver" package. Please install it manually.') 40 + } 41 + 42 + async openBrowser() { 43 + if (this.cachedBrowser) 44 + return this.cachedBrowser 45 + 46 + const options = this.ctx.config.browser 47 + 48 + if (this.browser === 'safari') { 49 + if (options.headless) 50 + throw new Error('You\'ve enabled headless mode for Safari but it doesn\'t currently support it.') 51 + 52 + const safaridriver = await import('safaridriver') 53 + safaridriver.start({ diagnose: true }) 54 + this.stopSafari = () => safaridriver.stop() 55 + 56 + process.on('beforeExit', () => { 57 + safaridriver.stop() 58 + }) 59 + } 60 + 61 + const { remote } = await import('webdriverio') 62 + 63 + // TODO: close everything, if browser is closed from the outside 64 + this.cachedBrowser = await remote({ 65 + ...this.options, 66 + logLevel: 'error', 67 + capabilities: this.buildCapabilities(), 68 + }) 69 + 70 + return this.cachedBrowser 71 + } 72 + 73 + private buildCapabilities() { 74 + const capabilities: RemoteOptions['capabilities'] = { 75 + ...this.options?.capabilities, 76 + browserName: this.browser, 77 + } 78 + 79 + const headlessMap = { 80 + chrome: ['goog:chromeOptions', ['headless', 'disable-gpu']], 81 + firefox: ['moz:firefoxOptions', ['-headless']], 82 + edge: ['ms:edgeOptions', ['--headless']], 83 + } as const 84 + 85 + const options = this.ctx.config.browser 86 + const browser = this.browser 87 + if (browser !== 'safari' && options.headless) { 88 + const [key, args] = headlessMap[browser] 89 + const currentValues = (this.options?.capabilities as any)?.[key] || {} 90 + const newArgs = [...currentValues.args || [], ...args] 91 + capabilities[key] = { ...currentValues, args: newArgs as any } 92 + } 93 + 94 + return capabilities 95 + } 96 + 97 + async openPage(url: string) { 98 + const browserInstance = await this.openBrowser() 99 + await browserInstance.url(url) 100 + } 101 + 102 + // TODO 103 + catchError(_cb: (error: Error) => Awaitable<void>) { 104 + return () => {} 105 + } 106 + 107 + async close() { 108 + await Promise.all([ 109 + this.stopSafari(), 110 + this.cachedBrowser?.sessionId ? this.cachedBrowser?.deleteSession?.() : null, 111 + ]) 112 + // TODO: right now process can only exit with timeout, if we use browser 113 + // needs investigating 114 + process.exit() 115 + } 116 + }
+1 -46
packages/vitest/src/integrations/env/index.ts
··· 1 - import { normalize, resolve } from 'pathe' 2 - import { resolvePath } from 'mlly' 3 - import { ViteNodeRunner } from 'vite-node/client' 4 - import type { ViteNodeRunnerOptions } from 'vite-node' 5 - import type { BuiltinEnvironment, VitestEnvironment } from '../../types/config' 6 - import type { Environment } from '../../types' 1 + import type { VitestEnvironment } from '../../types/config' 7 2 import node from './node' 8 3 import jsdom from './jsdom' 9 4 import happy from './happy-dom' ··· 24 19 'edge-runtime': '@edge-runtime/vm', 25 20 } 26 21 27 - function isBuiltinEnvironment(env: VitestEnvironment): env is BuiltinEnvironment { 28 - return env in environments 29 - } 30 - 31 22 export function getEnvPackageName(env: VitestEnvironment) { 32 23 if (env === 'node') 33 24 return null ··· 36 27 if (env[0] === '.' || env[0] === '/') 37 28 return null 38 29 return `vitest-environment-${env}` 39 - } 40 - 41 - const _loaders = new Map<string, ViteNodeRunner>() 42 - 43 - export async function createEnvironmentLoader(options: ViteNodeRunnerOptions) { 44 - if (!_loaders.has(options.root)) { 45 - const loader = new ViteNodeRunner(options) 46 - await loader.executeId('/@vite/env') 47 - _loaders.set(options.root, loader) 48 - } 49 - return _loaders.get(options.root)! 50 - } 51 - 52 - export async function loadEnvironment(name: VitestEnvironment, options: ViteNodeRunnerOptions): Promise<Environment> { 53 - if (isBuiltinEnvironment(name)) 54 - return environments[name] 55 - const loader = await createEnvironmentLoader(options) 56 - const root = loader.root 57 - const packageId = name[0] === '.' || name[0] === '/' 58 - ? resolve(root, name) 59 - : await resolvePath(`vitest-environment-${name}`, { url: [root] }) ?? resolve(root, name) 60 - const pkg = await loader.executeId(normalize(packageId)) 61 - if (!pkg || !pkg.default || typeof pkg.default !== 'object') { 62 - throw new TypeError( 63 - `Environment "${name}" is not a valid environment. ` 64 - + `Path "${packageId}" should export default object with a "setup" or/and "setupVM" method.`, 65 - ) 66 - } 67 - const environment = pkg.default 68 - if (environment.transformMode !== 'web' && environment.transformMode !== 'ssr') { 69 - throw new TypeError( 70 - `Environment "${name}" is not a valid environment. ` 71 - + `Path "${packageId}" should export default object with a "transformMode" method equal to "ssr" or "web".`, 72 - ) 73 - } 74 - return environment 75 30 }
+47
packages/vitest/src/integrations/env/loader.ts
··· 1 + import { normalize, resolve } from 'pathe' 2 + import { resolvePath } from 'mlly' 3 + import { ViteNodeRunner } from 'vite-node/client' 4 + import type { ViteNodeRunnerOptions } from 'vite-node' 5 + import type { BuiltinEnvironment, VitestEnvironment } from '../../types/config' 6 + import type { Environment } from '../../types' 7 + import { environments } from './index' 8 + 9 + function isBuiltinEnvironment(env: VitestEnvironment): env is BuiltinEnvironment { 10 + return env in environments 11 + } 12 + 13 + const _loaders = new Map<string, ViteNodeRunner>() 14 + 15 + export async function createEnvironmentLoader(options: ViteNodeRunnerOptions) { 16 + if (!_loaders.has(options.root)) { 17 + const loader = new ViteNodeRunner(options) 18 + await loader.executeId('/@vite/env') 19 + _loaders.set(options.root, loader) 20 + } 21 + return _loaders.get(options.root)! 22 + } 23 + 24 + export async function loadEnvironment(name: VitestEnvironment, options: ViteNodeRunnerOptions): Promise<Environment> { 25 + if (isBuiltinEnvironment(name)) 26 + return environments[name] 27 + const loader = await createEnvironmentLoader(options) 28 + const root = loader.root 29 + const packageId = name[0] === '.' || name[0] === '/' 30 + ? resolve(root, name) 31 + : await resolvePath(`vitest-environment-${name}`, { url: [root] }) ?? resolve(root, name) 32 + const pkg = await loader.executeId(normalize(packageId)) 33 + if (!pkg || !pkg.default || typeof pkg.default !== 'object') { 34 + throw new TypeError( 35 + `Environment "${name}" is not a valid environment. ` 36 + + `Path "${packageId}" should export default object with a "setup" or/and "setupVM" method.`, 37 + ) 38 + } 39 + const environment = pkg.default 40 + if (environment.transformMode !== 'web' && environment.transformMode !== 'ssr') { 41 + throw new TypeError( 42 + `Environment "${name}" is not a valid environment. ` 43 + + `Path "${packageId}" should export default object with a "transformMode" method equal to "ssr" or "web".`, 44 + ) 45 + } 46 + return environment 47 + }
-71
packages/vitest/src/node/browser/playwright.ts
··· 1 - import type { Page } from 'playwright' 2 - import type { BrowserProvider, BrowserProviderOptions } from '../../types/browser' 3 - import { ensurePackageInstalled } from '../pkg' 4 - import type { WorkspaceProject } from '../workspace' 5 - import type { Awaitable } from '../../types' 6 - 7 - export const playwrightBrowsers = ['firefox', 'webkit', 'chromium'] as const 8 - export type PlaywrightBrowser = typeof playwrightBrowsers[number] 9 - 10 - export interface PlaywrightProviderOptions extends BrowserProviderOptions { 11 - browser: PlaywrightBrowser 12 - } 13 - 14 - export class PlaywrightBrowserProvider implements BrowserProvider { 15 - public name = 'playwright' 16 - 17 - private cachedBrowser: Page | null = null 18 - private browser!: PlaywrightBrowser 19 - private ctx!: WorkspaceProject 20 - 21 - getSupportedBrowsers() { 22 - return playwrightBrowsers 23 - } 24 - 25 - async initialize(ctx: WorkspaceProject, { browser }: PlaywrightProviderOptions) { 26 - this.ctx = ctx 27 - this.browser = browser 28 - 29 - const root = this.ctx.config.root 30 - 31 - if (!await ensurePackageInstalled('playwright', root)) 32 - throw new Error('Cannot find "playwright" package. Please install it manually.') 33 - } 34 - 35 - async openBrowser() { 36 - if (this.cachedBrowser) 37 - return this.cachedBrowser 38 - 39 - const options = this.ctx.config.browser 40 - 41 - const playwright = await import('playwright') 42 - 43 - const playwrightInstance = await playwright[this.browser].launch({ headless: options.headless }) 44 - this.cachedBrowser = await playwrightInstance.newPage() 45 - 46 - this.cachedBrowser.on('close', () => { 47 - playwrightInstance.close() 48 - }) 49 - 50 - return this.cachedBrowser 51 - } 52 - 53 - catchError(cb: (error: Error) => Awaitable<void>) { 54 - this.cachedBrowser?.on('pageerror', cb) 55 - return () => { 56 - this.cachedBrowser?.off('pageerror', cb) 57 - } 58 - } 59 - 60 - async openPage(url: string) { 61 - const browserInstance = await this.openBrowser() 62 - await browserInstance.goto(url) 63 - } 64 - 65 - async close() { 66 - await this.cachedBrowser?.close() 67 - // TODO: right now process can only exit with timeout, if we use browser 68 - // needs investigating 69 - process.exit() 70 - } 71 - }
-87
packages/vitest/src/node/browser/webdriver.ts
··· 1 - import type { Awaitable } from '@vitest/utils' 2 - import type { BrowserProvider, BrowserProviderOptions } from '../../types/browser' 3 - import { ensurePackageInstalled } from '../pkg' 4 - import type { WorkspaceProject } from '../workspace' 5 - 6 - export const webdriverBrowsers = ['firefox', 'chrome', 'edge', 'safari'] as const 7 - export type WebdriverBrowser = typeof webdriverBrowsers[number] 8 - 9 - export interface WebdriverProviderOptions extends BrowserProviderOptions { 10 - browser: WebdriverBrowser 11 - } 12 - 13 - export class WebdriverBrowserProvider implements BrowserProvider { 14 - public name = 'webdriverio' 15 - 16 - private cachedBrowser: WebdriverIO.Browser | null = null 17 - private stopSafari: () => void = () => {} 18 - private browser!: WebdriverBrowser 19 - private ctx!: WorkspaceProject 20 - 21 - getSupportedBrowsers() { 22 - return webdriverBrowsers 23 - } 24 - 25 - async initialize(ctx: WorkspaceProject, { browser }: WebdriverProviderOptions) { 26 - this.ctx = ctx 27 - this.browser = browser 28 - 29 - const root = this.ctx.config.root 30 - 31 - if (!await ensurePackageInstalled('webdriverio', root)) 32 - throw new Error('Cannot find "webdriverio" package. Please install it manually.') 33 - 34 - if (browser === 'safari' && !await ensurePackageInstalled('safaridriver', root)) 35 - throw new Error('Cannot find "safaridriver" package. Please install it manually.') 36 - } 37 - 38 - async openBrowser() { 39 - if (this.cachedBrowser) 40 - return this.cachedBrowser 41 - 42 - const options = this.ctx.config.browser 43 - 44 - if (this.browser === 'safari') { 45 - const safaridriver = await import('safaridriver') 46 - safaridriver.start({ diagnose: true }) 47 - this.stopSafari = () => safaridriver.stop() 48 - 49 - process.on('beforeExit', () => { 50 - safaridriver.stop() 51 - }) 52 - } 53 - 54 - const { remote } = await import('webdriverio') 55 - 56 - // TODO: close everything, if browser is closed from the outside 57 - this.cachedBrowser = await remote({ 58 - logLevel: 'error', 59 - capabilities: { 60 - 'browserName': this.browser, 61 - 'wdio:devtoolsOptions': { headless: options.headless }, 62 - }, 63 - }) 64 - 65 - return this.cachedBrowser 66 - } 67 - 68 - async openPage(url: string) { 69 - const browserInstance = await this.openBrowser() 70 - await browserInstance.url(url) 71 - } 72 - 73 - // TODO 74 - catchError(_cb: (error: Error) => Awaitable<void>) { 75 - return () => {} 76 - } 77 - 78 - async close() { 79 - await Promise.all([ 80 - this.stopSafari(), 81 - this.cachedBrowser?.sessionId ? this.cachedBrowser?.deleteSession?.() : null, 82 - ]) 83 - // TODO: right now process can only exit with timeout, if we use browser 84 - // needs investigating 85 - process.exit() 86 - } 87 - }
+1 -1
packages/vitest/src/node/pools/rpc.ts
··· 6 6 const ctx = project.ctx 7 7 return { 8 8 async onWorkerExit(error, code) { 9 - await ctx.logger.printError(error, { type: 'Unexpected Exit' }) 9 + await ctx.logger.printError(error, { type: 'Unexpected Exit', fullStack: true }) 10 10 process.exit(code || 1) 11 11 }, 12 12 snapshotSaved(snapshot) {