From da7fa8d14e5c741acb6177ef259cb71a1e3da51b Mon Sep 17 00:00:00 2001 From: Chance Strickland Date: Wed, 29 Oct 2025 10:33:24 -0700 Subject: [PATCH] Setup alias in vitest --- package.json | 10 +++ pnpm-lock.yaml | 199 ++++++++++++++++++++++++++++++++++++++++++ scripts/test-alias.ts | 13 +++ scripts/test-env.ts | 26 ++++++ vitest.config.mts | 2 + 5 files changed, 250 insertions(+) create mode 100644 scripts/test-alias.ts create mode 100644 scripts/test-env.ts diff --git a/package.json b/package.json index ac2193f71b..854b10719b 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,8 @@ "lint": "pnpm -r run lint", "types:check": "pnpm -r --parallel run typecheck", "test": "vitest", + "test:react-17": "REACT_VERSION=17 pnpm test", + "test:react-18": "REACT_VERSION=18 pnpm test", "test:ci": "vitest run && pnpm cypress:ci", "storybook": "BROWSER=none pnpm --filter=@repo/storybook run dev -p 9009", "storybook:build": "BROWSER=none pnpm --filter=@repo/storybook run build", @@ -38,6 +40,8 @@ "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.0", + "@testing-library/react-17": "npm:@testing-library/react@^12.1.5", + "@testing-library/react-18": "npm:@testing-library/react@^16.3.0", "@testing-library/user-event": "^14.6.1", "@types/fs-extra": "^11", "@types/node": "^22", @@ -61,6 +65,12 @@ "react-test-renderer": "^19.2.0", "react-is": "^19.2.0", "react-remove-scroll": "^2.6.3", + "react-17": "npm:react@^17.0.2", + "react-18": "npm:react@^18.3.1", + "react-dom-17": "npm:react-dom@^17.0.2", + "react-dom-18": "npm:react-dom@^18.3.1", + "react-is-17": "npm:react-is@^17.0.2", + "react-is-18": "npm:react-is@^18.3.1", "replace-in-files": "^3.0.0", "start-server-and-test": "^2.1.2", "typescript": "^5.9.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5ef3d64c04..cae707b24c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,6 +34,12 @@ importers: '@testing-library/react': specifier: ^16.3.0 version: 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@testing-library/react-17': + specifier: npm:@testing-library/react@^12.1.5 + version: '@testing-library/react@12.1.5(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' + '@testing-library/react-18': + specifier: npm:@testing-library/react@^16.3.0 + version: '@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' '@testing-library/user-event': specifier: ^14.6.1 version: 14.6.1(@testing-library/dom@10.4.1) @@ -91,12 +97,30 @@ importers: react: specifier: ^19.2.0 version: 19.2.0 + react-17: + specifier: npm:react@^17.0.2 + version: react@17.0.2 + react-18: + specifier: npm:react@^18.3.1 + version: react@18.3.1 react-dom: specifier: ^19.2.0 version: 19.2.0(react@19.2.0) + react-dom-17: + specifier: npm:react-dom@^17.0.2 + version: react-dom@17.0.2(react@19.2.0) + react-dom-18: + specifier: npm:react-dom@^18.3.1 + version: react-dom@18.3.1(react@19.2.0) react-is: specifier: ^19.2.0 version: 19.2.0 + react-is-17: + specifier: npm:react-is@^17.0.2 + version: react-is@17.0.2 + react-is-18: + specifier: npm:react-is@^18.3.1 + version: react-is@18.3.1 react-remove-scroll: specifier: ^2.6.3 version: 2.6.3(@types/react@19.2.2)(react@19.2.0) @@ -4298,10 +4322,21 @@ packages: resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} + '@testing-library/dom@8.20.1': + resolution: {integrity: sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==} + engines: {node: '>=12'} + '@testing-library/jest-dom@6.9.1': resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + '@testing-library/react@12.1.5': + resolution: {integrity: sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==} + engines: {node: '>=12'} + peerDependencies: + react: <18.0.0 + react-dom: <18.0.0 + '@testing-library/react@16.3.0': resolution: {integrity: sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==} engines: {node: '>=18'} @@ -4386,6 +4421,11 @@ packages: '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/react-dom@17.0.26': + resolution: {integrity: sha512-Z+2VcYXJwOqQ79HreLU/1fyQ88eXSSFh6I3JdrEHQIfYSI0kCQpTGvOrbE6jFGGYXKsHuwY9tBa/w5Uo6KzrEg==} + peerDependencies: + '@types/react': ^17.0.0 + '@types/react-dom@19.2.2': resolution: {integrity: sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==} peerDependencies: @@ -4699,6 +4739,9 @@ packages: resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} engines: {node: '>=10'} + aria-query@5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} @@ -5245,6 +5288,10 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} + deep-equal@2.2.3: + resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} + engines: {node: '>= 0.4'} + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -5385,6 +5432,9 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + es-iterator-helpers@1.2.1: resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} engines: {node: '>= 0.4'} @@ -5977,6 +6027,10 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -6520,6 +6574,10 @@ packages: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} @@ -6881,6 +6939,16 @@ packages: resolution: {integrity: sha512-hlSJDQ2synMPKFZOsKo9Hi8WWZTC7POR8EmWvTSjow+VDgKzkmjQvFm2fk0tmRw+f0vTOIYKlarR0iL4996pdg==} engines: {node: '>=16.14.0'} + react-dom@17.0.2: + resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} + peerDependencies: + react: 17.0.2 + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + react-dom@19.2.0: resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} peerDependencies: @@ -6892,6 +6960,9 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-is@19.2.0: resolution: {integrity: sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==} @@ -6930,6 +7001,14 @@ packages: peerDependencies: react: ^19.2.0 + react@17.0.2: + resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==} + engines: {node: '>=0.10.0'} + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + react@19.2.0: resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} engines: {node: '>=0.10.0'} @@ -7059,6 +7138,12 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} + scheduler@0.20.2: + resolution: {integrity: sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} @@ -7196,6 +7281,10 @@ packages: std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + storybook@9.1.15: resolution: {integrity: sha512-es7uDdEwRVVUAt7XLAZZ1hicOq9r4ov5NFeFPpa2YEyAsyHYOCr0CTlHBfslWG6D5EVNWK3kVIIuW8GHB6hEig==} hasBin: true @@ -8923,6 +9012,17 @@ snapshots: picocolors: 1.1.1 pretty-format: 27.5.1 + '@testing-library/dom@8.20.1': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/runtime': 7.27.0 + '@types/aria-query': 5.0.4 + aria-query: 5.1.3 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + '@testing-library/jest-dom@6.9.1': dependencies: '@adobe/css-tools': 4.4.2 @@ -8932,6 +9032,16 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 + '@testing-library/react@12.1.5(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@babel/runtime': 7.27.0 + '@testing-library/dom': 8.20.1 + '@types/react-dom': 17.0.26(@types/react@19.2.2) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + transitivePeerDependencies: + - '@types/react' + '@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@babel/runtime': 7.27.0 @@ -9017,6 +9127,10 @@ snapshots: '@types/parse-json@4.0.2': {} + '@types/react-dom@17.0.26(@types/react@19.2.2)': + dependencies: + '@types/react': 19.2.2 + '@types/react-dom@19.2.2(@types/react@19.2.2)': dependencies: '@types/react': 19.2.2 @@ -9389,6 +9503,10 @@ snapshots: dependencies: tslib: 2.8.1 + aria-query@5.1.3: + dependencies: + deep-equal: 2.2.3 + aria-query@5.3.0: dependencies: dequal: 2.0.3 @@ -9960,6 +10078,27 @@ snapshots: deep-eql@5.0.2: {} + deep-equal@2.2.3: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + es-get-iterator: 1.1.3 + get-intrinsic: 1.3.0 + is-arguments: 1.2.0 + is-array-buffer: 3.0.5 + is-date-object: 1.1.0 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + isarray: 2.0.5 + object-is: 1.1.6 + object-keys: 1.1.1 + object.assign: 4.1.7 + regexp.prototype.flags: 1.5.4 + side-channel: 1.1.0 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + deep-extend@0.6.0: {} deep-is@0.1.4: {} @@ -10143,6 +10282,18 @@ snapshots: es-errors@1.3.0: {} + es-get-iterator@1.1.3: + dependencies: + call-bind: 1.0.8 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + is-arguments: 1.2.0 + is-map: 2.0.3 + is-set: 2.0.3 + is-string: 1.1.1 + isarray: 2.0.5 + stop-iteration-iterator: 1.1.0 + es-iterator-helpers@1.2.1: dependencies: call-bind: 1.0.8 @@ -10880,6 +11031,11 @@ snapshots: hasown: 2.0.2 side-channel: 1.1.0 + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -11424,6 +11580,11 @@ snapshots: object-inspect@1.13.4: {} + object-is@1.1.6: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + object-keys@1.1.1: {} object.assign@4.1.7: @@ -11771,6 +11932,19 @@ snapshots: transitivePeerDependencies: - supports-color + react-dom@17.0.2(react@19.2.0): + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react: 19.2.0 + scheduler: 0.20.2 + + react-dom@18.3.1(react@19.2.0): + dependencies: + loose-envify: 1.4.0 + react: 19.2.0 + scheduler: 0.23.2 + react-dom@19.2.0(react@19.2.0): dependencies: react: 19.2.0 @@ -11780,6 +11954,8 @@ snapshots: react-is@17.0.2: {} + react-is@18.3.1: {} + react-is@19.2.0: {} react-remove-scroll-bar@2.3.8(@types/react@19.2.2)(react@19.2.0): @@ -11815,6 +11991,15 @@ snapshots: react-is: 19.2.0 scheduler: 0.27.0 + react@17.0.2: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + react@19.2.0: {} read-yaml-file@1.1.0: @@ -11992,6 +12177,15 @@ snapshots: dependencies: xmlchars: 2.2.0 + scheduler@0.20.2: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + scheduler@0.27.0: {} schema-utils@3.3.0: @@ -12203,6 +12397,11 @@ snapshots: std-env@3.9.0: {} + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + storybook@9.1.15(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@7.1.12(@types/node@22.14.0)(terser@5.39.0)): dependencies: '@storybook/global': 5.0.0 diff --git a/scripts/test-alias.ts b/scripts/test-alias.ts new file mode 100644 index 0000000000..47adc367c3 --- /dev/null +++ b/scripts/test-alias.ts @@ -0,0 +1,13 @@ +import { reactVersion, DEFAULT_REACT_VERSION } from './test-env'; + +let alias: Record = {}; +if (reactVersion !== DEFAULT_REACT_VERSION) { + alias = { + react: `react-${reactVersion}`, + 'react-dom': `react-dom-${reactVersion}`, + 'react-is': `react-is-${reactVersion}`, + '@testing-library/react': `@testing-library/react-${reactVersion}`, + }; +} + +export { alias }; diff --git a/scripts/test-env.ts b/scripts/test-env.ts new file mode 100644 index 0000000000..514215abf4 --- /dev/null +++ b/scripts/test-env.ts @@ -0,0 +1,26 @@ +const SUPPORTED_REACT_VERSIONS = new Set([17, 18, 19] as const); +const DEFAULT_REACT_VERSION = 19; +type SupportedReactVersion = SetValue; +const reactVersion = sanitizeReactVersion(process.env.REACT_VERSION) ?? DEFAULT_REACT_VERSION; + +export { reactVersion, DEFAULT_REACT_VERSION }; + +function sanitizeReactVersion(version: string | undefined) { + version = version?.trim(); + if (!version) { + return undefined; + } + + const parsed = Number.parseInt(version, 10); + if (!isSupportedReactVersion(parsed)) { + throw new Error(`Invalid React version: ${version}`); + } + + return parsed; +} + +function isSupportedReactVersion(version: number): version is SupportedReactVersion { + return SUPPORTED_REACT_VERSIONS.has(version as SupportedReactVersion); +} + +type SetValue> = T extends Set ? U : never; diff --git a/vitest.config.mts b/vitest.config.mts index 5f80a49c22..a54e32a0d4 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -1,4 +1,5 @@ import { defineConfig } from 'vitest/config'; +import { alias } from './scripts/test-alias'; export default defineConfig({ test: { @@ -6,5 +7,6 @@ export default defineConfig({ environment: 'jsdom', include: ['**/*.test.?(c|m)[jt]s?(x)'], retry: 1, + alias, }, });