diff --git a/.eslintrc.json b/.eslintrc.json index f1ecd8723b..32f4cb131b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -22,6 +22,7 @@ "import", "@vitest", "eslint-plugin-react-compiler", + "jest-dom", "testing-library" ], "parser": "@typescript-eslint/parser", @@ -107,6 +108,7 @@ "overrides": [ { "extends": [ + "plugin:jest-dom/recommended", "plugin:testing-library/react", "plugin:@vitest/legacy-recommended" ], diff --git a/.github/workflows/test-old-typescript.yml b/.github/workflows/test-old-typescript.yml index 6c97c2d803..bf194b6faa 100644 --- a/.github/workflows/test-old-typescript.yml +++ b/.github/workflows/test-old-typescript.yml @@ -85,6 +85,9 @@ jobs: if: ${{ matrix.typescript == '4.4.4' || matrix.typescript == '4.3.5' || matrix.typescript == '4.2.3' || matrix.typescript == '4.1.5' || matrix.typescript == '4.0.5' || startsWith(matrix.typescript, '3.') }} run: | pnpm add -D vitest@0.33.0 @vitest/coverage-v8@0.33.0 @vitest/ui@0.33.0 + pnpm add -D @testing-library/jest-dom@5 @types/testing-library__jest-dom@5 + pnpm add -D @types/jest@27.4.1 + sed -i~ 's/"@testing-library\/jest-dom"/"@types\/testing-library__jest-dom"/' tsconfig.json - name: Patch testing setup for older TS if: ${{ matrix.typescript == '4.0.5' || startsWith(matrix.typescript, '3.') }} run: | diff --git a/package.json b/package.json index 895a7073c2..744ee0b612 100644 --- a/package.json +++ b/package.json @@ -128,6 +128,7 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^12.1.1", "@testing-library/dom": "^10.4.0", + "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.0.1", "@testing-library/user-event": "^14.5.2", "@types/babel__core": "^7.20.5", @@ -147,6 +148,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-alias": "^1.1.2", "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jest-dom": "^5.4.0", "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-react": "^7.37.2", "eslint-plugin-react-compiler": "19.0.0-beta-a7bf2bd-20241110", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2b8c24f661..d2bc14c56f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,9 @@ devDependencies: '@testing-library/dom': specifier: ^10.4.0 version: 10.4.0 + '@testing-library/jest-dom': + specifier: ^6.6.3 + version: 6.6.3 '@testing-library/react': specifier: ^16.0.1 version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.0)(react@19.0.0-rc.0) @@ -98,6 +101,9 @@ devDependencies: eslint-plugin-import: specifier: ^2.31.0 version: 2.31.0(@typescript-eslint/parser@8.13.0)(eslint@8.57.0) + eslint-plugin-jest-dom: + specifier: ^5.4.0 + version: 5.4.0(@testing-library/dom@10.4.0)(eslint@8.57.0) eslint-plugin-prettier: specifier: ^5.2.1 version: 5.2.1(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.3.3) @@ -164,6 +170,10 @@ devDependencies: packages: + /@adobe/css-tools@4.4.0: + resolution: {integrity: sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==} + dev: true + /@ampproject/remapping@2.3.0: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -2206,6 +2216,19 @@ packages: pretty-format: 27.5.1 dev: true + /@testing-library/jest-dom@6.6.3: + resolution: {integrity: sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + dependencies: + '@adobe/css-tools': 4.4.0 + aria-query: 5.3.0 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + lodash: 4.17.21 + redent: 3.0.0 + dev: true + /@testing-library/react@16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@19.0.0-rc.0)(react@19.0.0-rc.0): resolution: {integrity: sha512-dSmwJVtJXmku+iocRhWOUFbrERC76TX2Mnf0ATODz8brzAZrMBbzLwQixlBSanZxR6LddK3eiwpSFZgDET1URg==} engines: {node: '>=18'} @@ -2957,6 +2980,14 @@ packages: pathval: 2.0.0 dev: true + /chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -3041,6 +3072,10 @@ packages: which: 2.0.2 dev: true + /css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + dev: true + /cssstyle@4.1.0: resolution: {integrity: sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==} engines: {node: '>=18'} @@ -3193,6 +3228,10 @@ packages: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} dev: true + /dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dev: true + /downlevel-dts@0.11.0: resolution: {integrity: sha512-vo835pntK7kzYStk7xUHDifiYJvXxVhUapt85uk2AI94gUUAQX9HNRtrcMHNSc3YHJUEHGbYIGsM99uIbgAtxw==} hasBin: true @@ -3510,6 +3549,22 @@ packages: - supports-color dev: true + /eslint-plugin-jest-dom@5.4.0(@testing-library/dom@10.4.0)(eslint@8.57.0): + resolution: {integrity: sha512-yBqvFsnpS5Sybjoq61cJiUsenRkC9K32hYQBFS9doBR7nbQZZ5FyO+X7MlmfM1C48Ejx/qTuOCgukDUNyzKZ7A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6', yarn: '>=1'} + peerDependencies: + '@testing-library/dom': ^8.0.0 || ^9.0.0 || ^10.0.0 + eslint: ^6.8.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + peerDependenciesMeta: + '@testing-library/dom': + optional: true + dependencies: + '@babel/runtime': 7.26.0 + '@testing-library/dom': 10.4.0 + eslint: 8.57.0 + requireindex: 1.2.0 + dev: true + /eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.3.3): resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -4088,6 +4143,11 @@ packages: engines: {node: '>=0.8.19'} dev: true + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. @@ -4620,6 +4680,11 @@ packages: engines: {node: '>=6'} dev: true + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -4956,6 +5021,14 @@ packages: resolve: 1.22.8 dev: true + /redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + dev: true + /reflect.getprototypeof@1.0.6: resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} engines: {node: '>= 0.4'} @@ -5023,6 +5096,11 @@ packages: jsesc: 3.0.2 dev: true + /requireindex@1.2.0: + resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} + engines: {node: '>=0.10.5'} + dev: true + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -5416,6 +5494,13 @@ packages: engines: {node: '>=4'} dev: true + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} diff --git a/tests/react/async.test.tsx b/tests/react/async.test.tsx index d70a7bef6e..147a095464 100644 --- a/tests/react/async.test.tsx +++ b/tests/react/async.test.tsx @@ -1,12 +1,5 @@ import { StrictMode, Suspense, useEffect, useRef } from 'react' -import { - act, - fireEvent, - render, - screen, - waitFor, - waitForElementToBeRemoved, -} from '@testing-library/react' +import { act, fireEvent, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { expect, it } from 'vitest' import { useAtom } from 'jotai/react' diff --git a/tests/react/optimization.test.tsx b/tests/react/optimization.test.tsx index 7fb823f5d9..dbb3a49935 100644 --- a/tests/react/optimization.test.tsx +++ b/tests/react/optimization.test.tsx @@ -41,24 +41,24 @@ it('only relevant render function called (#156)', async () => { , ) - expect(screen.getByText('count1: 0')).toBeDefined() - expect(screen.getByText('count2: 0')).toBeDefined() + expect(screen.getByText('count1: 0')).toBeInTheDocument() + expect(screen.getByText('count2: 0')).toBeInTheDocument() const viewCount1AfterMount = viewCount1 const viewCount2AfterMount = viewCount2 await userEvent.click(screen.getByText('button1')) - expect(screen.getByText('count1: 1')).toBeDefined() - expect(screen.getByText('count2: 0')).toBeDefined() + expect(screen.getByText('count1: 1')).toBeInTheDocument() + expect(screen.getByText('count2: 0')).toBeInTheDocument() expect(viewCount1).toBe(viewCount1AfterMount + 1) expect(viewCount2).toBe(viewCount2AfterMount + 0) await userEvent.click(screen.getByText('button2')) - expect(screen.getByText('count1: 1')).toBeDefined() - expect(screen.getByText('count2: 1')).toBeDefined() + expect(screen.getByText('count1: 1')).toBeInTheDocument() + expect(screen.getByText('count2: 1')).toBeInTheDocument() expect(viewCount1).toBe(viewCount1AfterMount + 1) expect(viewCount2).toBe(viewCount2AfterMount + 1) @@ -252,21 +252,21 @@ it('no extra rerenders after commit with derived atoms (#1213)', async () => { await userEvent.click(screen.getByText('inc1')) - expect(screen.getByText('count1: 1')).toBeDefined() - expect(screen.getByText('count2: 0')).toBeDefined() + expect(screen.getByText('count1: 1')).toBeInTheDocument() + expect(screen.getByText('count2: 0')).toBeInTheDocument() expect(viewCount1).toBe(viewCount1AfterCommit) await userEvent.click(screen.getByText('inc2')) - expect(screen.getByText('count1: 1')).toBeDefined() - expect(screen.getByText('count2: 1')).toBeDefined() + expect(screen.getByText('count1: 1')).toBeInTheDocument() + expect(screen.getByText('count2: 1')).toBeInTheDocument() expect(viewCount2).toBe(viewCount2AfterCommit) await userEvent.click(screen.getByText('inc1')) - expect(screen.getByText('count1: 2')).toBeDefined() - expect(screen.getByText('count2: 1')).toBeDefined() + expect(screen.getByText('count1: 2')).toBeInTheDocument() + expect(screen.getByText('count2: 1')).toBeInTheDocument() expect(viewCount1).toBe(viewCount1AfterCommit) }) diff --git a/tests/react/vanilla-utils/atomWithDefault.test.tsx b/tests/react/vanilla-utils/atomWithDefault.test.tsx index 9c5c1dd0f2..8c11d1cfc8 100644 --- a/tests/react/vanilla-utils/atomWithDefault.test.tsx +++ b/tests/react/vanilla-utils/atomWithDefault.test.tsx @@ -222,9 +222,9 @@ it('can be set synchronously by passing value', async () => { render() - expect(screen.getByText('count: 1')).toBeDefined() + expect(screen.getByText('count: 1')).toBeInTheDocument() await userEvent.click(screen.getByRole('button', { name: 'Set to 10' })) - expect(screen.getByText('count: 10')).toBeDefined() + expect(screen.getByText('count: 10')).toBeInTheDocument() }) diff --git a/tests/react/vanilla-utils/atomWithStorage.test.tsx b/tests/react/vanilla-utils/atomWithStorage.test.tsx index 35bf410c25..fc26a4de5a 100644 --- a/tests/react/vanilla-utils/atomWithStorage.test.tsx +++ b/tests/react/vanilla-utils/atomWithStorage.test.tsx @@ -545,9 +545,9 @@ describe('atomWithStorage (with browser storage)', () => { expect(store.get(isLoggedAtom)).toBeTruthy() expect(store.get(isDevModeStorageAtom)).toBeTruthy() - expect(checkbox.checked).toBeTruthy() + expect(checkbox).toBeChecked() await userEvent.click(checkbox) - expect(checkbox.checked).toBeFalsy() + expect(checkbox).not.toBeChecked() }) }) diff --git a/tests/react/vanilla-utils/splitAtom.test.tsx b/tests/react/vanilla-utils/splitAtom.test.tsx index 2bc592785b..b911e92c14 100644 --- a/tests/react/vanilla-utils/splitAtom.test.tsx +++ b/tests/react/vanilla-utils/splitAtom.test.tsx @@ -1,5 +1,5 @@ import { StrictMode, useEffect, useRef } from 'react' -import { render, screen, waitFor } from '@testing-library/react' +import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { expect, it } from 'vitest' import { useAtom, useAtomValue, useSetAtom } from 'jotai/react' @@ -68,35 +68,35 @@ it('no unnecessary updates when updating atoms', async () => { , ) - expect(screen.getByText('TaskListUpdates: 1')).toBeDefined() - expect(screen.getByText('get cat food commits: 1')).toBeDefined() - expect(screen.getByText('get dragon food commits: 1')).toBeDefined() + expect(screen.getByText('TaskListUpdates: 1')).toBeInTheDocument() + expect(screen.getByText('get cat food commits: 1')).toBeInTheDocument() + expect(screen.getByText('get dragon food commits: 1')).toBeInTheDocument() const catBox = screen.getByTestId('get cat food-checkbox') as HTMLInputElement const dragonBox = screen.getByTestId( 'get dragon food-checkbox', ) as HTMLInputElement - expect(catBox.checked).toBeFalsy() - expect(dragonBox.checked).toBeFalsy() + expect(catBox).not.toBeChecked() + expect(dragonBox).not.toBeChecked() await userEvent.click(catBox) - expect(screen.getByText('TaskListUpdates: 1')).toBeDefined() - expect(screen.getByText('get cat food commits: 2')).toBeDefined() - expect(screen.getByText('get dragon food commits: 1')).toBeDefined() + expect(screen.getByText('TaskListUpdates: 1')).toBeInTheDocument() + expect(screen.getByText('get cat food commits: 2')).toBeInTheDocument() + expect(screen.getByText('get dragon food commits: 1')).toBeInTheDocument() - expect(catBox.checked).toBeTruthy() - expect(dragonBox.checked).toBeFalsy() + expect(catBox).toBeChecked() + expect(dragonBox).not.toBeChecked() await userEvent.click(dragonBox) - expect(screen.getByText('TaskListUpdates: 1')).toBeDefined() - expect(screen.getByText('get cat food commits: 2')).toBeDefined() - expect(screen.getByText('get dragon food commits: 2')).toBeDefined() + expect(screen.getByText('TaskListUpdates: 1')).toBeInTheDocument() + expect(screen.getByText('get cat food commits: 2')).toBeInTheDocument() + expect(screen.getByText('get dragon food commits: 2')).toBeInTheDocument() - expect(catBox.checked).toBeTruthy() - expect(dragonBox.checked).toBeTruthy() + expect(catBox).toBeChecked() + expect(dragonBox).toBeChecked() }) it('removing atoms', async () => { @@ -145,27 +145,27 @@ it('removing atoms', async () => { , ) - expect(screen.getByText('get cat food')).toBeTruthy() - expect(screen.getByText('get dragon food')).toBeTruthy() - expect(screen.getByText('help nana')).toBeTruthy() + expect(screen.getByText('get cat food')).toBeInTheDocument() + expect(screen.getByText('get dragon food')).toBeInTheDocument() + expect(screen.getByText('help nana')).toBeInTheDocument() await userEvent.click(screen.getByTestId('get cat food-removebutton')) - expect(screen.queryByText('get cat food')).toBeFalsy() - expect(screen.getByText('get dragon food')).toBeTruthy() - expect(screen.getByText('help nana')).toBeTruthy() + expect(screen.queryByText('get cat food')).not.toBeInTheDocument() + expect(screen.getByText('get dragon food')).toBeInTheDocument() + expect(screen.getByText('help nana')).toBeInTheDocument() await userEvent.click(screen.getByTestId('get dragon food-removebutton')) - expect(screen.queryByText('get cat food')).toBeFalsy() - expect(screen.queryByText('get dragon food')).toBeFalsy() - expect(screen.getByText('help nana')).toBeTruthy() + expect(screen.queryByText('get cat food')).not.toBeInTheDocument() + expect(screen.queryByText('get dragon food')).not.toBeInTheDocument() + expect(screen.getByText('help nana')).toBeInTheDocument() await userEvent.click(screen.getByTestId('help nana-removebutton')) - expect(screen.queryByText('get cat food')).toBeFalsy() - expect(screen.queryByText('get dragon food')).toBeFalsy() - expect(screen.queryByText('help nana')).toBeFalsy() + expect(screen.queryByText('get cat food')).not.toBeInTheDocument() + expect(screen.queryByText('get dragon food')).not.toBeInTheDocument() + expect(screen.queryByText('help nana')).not.toBeInTheDocument() }) it('inserting atoms', async () => { @@ -237,22 +237,22 @@ it('inserting atoms', async () => { , ) - expect(screen.getByTestId('list').textContent).toBe( + expect(screen.getByTestId('list')).toHaveTextContent( 'get cat food+get dragon food+help nana+', ) await userEvent.click(screen.getByTestId('help nana-insertbutton')) - expect(screen.getByTestId('list').textContent).toBe( + expect(screen.getByTestId('list')).toHaveTextContent( 'get cat food+get dragon food+new task1+help nana+', ) await userEvent.click(screen.getByTestId('get cat food-insertbutton')) - expect(screen.getByTestId('list').textContent).toBe( + expect(screen.getByTestId('list')).toHaveTextContent( 'new task2+get cat food+get dragon food+new task1+help nana+', ) await userEvent.click(screen.getByTestId('addtaskbutton')) - expect(screen.getByTestId('list').textContent).toBe( + expect(screen.getByTestId('list')).toHaveTextContent( 'new task2+get cat food+get dragon food+new task1+help nana+end+', ) }) @@ -335,27 +335,27 @@ it('moving atoms', async () => { , ) - expect(screen.getByTestId('list').textContent).toBe( + expect(screen.getByTestId('list')).toHaveTextContent( 'get cat food<>get dragon food<>help nana<>', ) await userEvent.click(screen.getByTestId('help nana-leftbutton')) - expect(screen.getByTestId('list').textContent).toBe( + expect(screen.getByTestId('list')).toHaveTextContent( 'get cat food<>help nana<>get dragon food<>', ) await userEvent.click(screen.getByTestId('get cat food-rightbutton')) - expect(screen.getByTestId('list').textContent).toBe( + expect(screen.getByTestId('list')).toHaveTextContent( 'help nana<>get cat food<>get dragon food<>', ) await userEvent.click(screen.getByTestId('get cat food-rightbutton')) - expect(screen.getByTestId('list').textContent).toBe( + expect(screen.getByTestId('list')).toHaveTextContent( 'help nana<>get dragon food<>get cat food<>', ) await userEvent.click(screen.getByTestId('help nana-leftbutton')) - expect(screen.getByTestId('list').textContent).toBe( + expect(screen.getByTestId('list')).toHaveTextContent( 'get dragon food<>get cat food<>help nana<>', ) }) @@ -402,8 +402,8 @@ it('read-only array atom', async () => { 'get dragon food-checkbox', ) as HTMLInputElement - expect(catBox.checked).toBeFalsy() - expect(dragonBox.checked).toBeFalsy() + expect(catBox).not.toBeChecked() + expect(dragonBox).not.toBeChecked() }) it('no error with cached atoms (fix 510)', async () => { diff --git a/tests/setup.ts b/tests/setup.ts new file mode 100644 index 0000000000..a9d0dd31aa --- /dev/null +++ b/tests/setup.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom/vitest' diff --git a/tests/vanilla/store.test.tsx b/tests/vanilla/store.test.tsx index c0be322c45..4fa0e668af 100644 --- a/tests/vanilla/store.test.tsx +++ b/tests/vanilla/store.test.tsx @@ -358,7 +358,7 @@ it('resolves dependencies reliably after a delay (#2192)', async () => { resolve[3]!() resolve[4]!() - await new Promise(setImmediate) + await Promise.resolve() await waitFor(() => assert(store.get(countAtom) === 4)) expect(result).toBe(4) // 3 diff --git a/tsconfig.json b/tsconfig.json index e91385a96a..d03b9a6c92 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,7 @@ "verbatimModuleSyntax": true, "declaration": true, "isolatedDeclarations": true, + "types": ["@testing-library/jest-dom"], "noEmit": true, "baseUrl": ".", "paths": { diff --git a/vitest.config.ts b/vitest.config.ts index 685df2b269..11c28e63f8 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -17,6 +17,7 @@ export default defineConfig({ environment: 'jsdom', dir: 'tests', reporters: 'basic', + setupFiles: ['tests/setup.ts'], coverage: { reporter: ['text', 'json', 'html', 'text-summary'], reportsDirectory: './coverage/',