testing-library / jest-dom

:owl: Custom jest matchers to test the state of the DOM

Home Page:https://testing-library.com/docs/ecosystem-jest-dom

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Does not work with vitest 1.x.x

kibertoad opened this issue · comments

jest-dom TypeScript build breaks if jest-dom assertions (such as toBeInTheDocument) are used in vitest files, when using newer version of vitest (1.x)

versions

  • @testing-library/jest-dom version: 6.2.0
  • node version: 20.10.0
  • vitest version: 1.1.3
  • typescript: 5.3.3
  • @testing-library/react: 14.1.2

Relevant code or config:

Test:

expect(screen.getByText('anytext')).toBeInTheDocument()

tsconfig.json:

"types": ["vite/client", "@testing-library/jest-dom/vitest"]

What you did:

Try to build tests via tsc

What happened:

- error TS2339: Property 'toBeInTheDocument' does not exist on type 'Assertion<HTMLElement>'.

25   expect(screen.getByText('anytext')).toBeInTheDocument()

Reproduction:

See Relevant code or config

Problem description:

This prevents testing-library from working with newer vitest.

Suggested solution:

Support newer vitest versions within jest-dom.

This may be related to vitest-dev/vitest#4688

@kibertoad Have you followed the with vitest setup guide https://github.com/testing-library/jest-dom#with-vitest ?

// In your own vitest-setup.js (or any other name)
import '@testing-library/jest-dom/vitest'

// In vitest.config.js add (if you haven't already)
setupFiles: ['./vitest-setup.js']

yup.
vite.config.ts:

		setupFiles: './test/setup.ts',

test/setup.ts:

/// <reference types="@lokalise/styled/dist/testing-setup" /> This includes global types (not handled by import below unfortunately)
import '@lokalise/styled/testing-setup'
import '@testing-library/jest-dom/vitest'

It works with 0.x vitest, but doesn't with 1.x

In your tsconfig.json try adding to your include the setup.ts file.

{
  //..tsconfig.json
  "include": ["./test/setup.ts"]
}

I would remove the usage of "types": ["vite/client", "@testing-library/jest-dom/vitest"].

Be great if you could put up an example repo or codesandbox so we can recreate the issue and debug it.

I had the same issue you had. This is how I fixed it, maybe it helps you.

Even though versions of vitest and related libraries were all updated in package.json, I did npm ls vitest and realized I still had a rogue 0.34 vitest.
I think the issue is because I didn't upgrade with npm update, I reverted the package lock, and did npm update (with all the updated versions in package.json) and it was all good afterwards. No more rogue <1 version of vitest.

I've update to

"vitest": "^1.2.0",
"@testing-library/jest-dom": "^6.2.0",

with the @andykenward docs and everything is working fine for toBeInTheDocument assert
I don't have TS error

Weird that it seems I have everything correctly but I still get the error:

The setup file inside ./tests/setupFiles/testingLibrary.ts

import '@testing-library/jest-dom/vitest'

My tsconfig.json:

{
  "include": [
    "remix.env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "./tests/setupFiles/testingLibrary.ts"
  ],
  // ...rest
  // baseUrl is "." in compiler options
}

My vitest.config.ts file:

import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      include: ['app/**'],
    },
    clearMocks: true,
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./tests/setupFiles/testingLibrary.ts'],
    css: true,
    silent: process.env.CI === 'true',
    retry: 2,
  },
})

... and my package versions:

pnpm -F my-project ls @testing-library/jest-dom vitest typescript
Legend: production dependency, optional only, dev only

my-project /path/to/monorepo/apps/my-project

devDependencies:
@testing-library/jest-dom 6.2.0
typescript 5.3.3
vitest 1.2.0

With all that in place, I still get the error:

error TS2339: Property 'toBeInTheDocument' does not exist on type 'Assertion<HTMLElement | null>'

I notice one thing though, in the @testing-library/jest-dom/vitest, we're overriding @vitest/expect module:

import {type expect} from 'vitest'
import {type TestingLibraryMatchers} from './matchers'

export {}
declare module '@vitest/expect' {
  interface JestAssertion<T = any>
    extends TestingLibraryMatchers<
      ReturnType<typeof expect.stringContaining>,
      T
    > {}
}

https://github.com/testing-library/jest-dom/blob/1fb156c2b544e0069c56a72a2f1909fe04850f6c/types/vitest.d.ts

I don't have @vitest/expect listed in my package.json file and even though I know it's a dependency of vitest and it's being used under-the-hood, I guess that's the issue. That's because if I change the module declaration from @vitest/expect to vitest:

import {type expect} from 'vitest'
import {type TestingLibraryMatchers} from './matchers'

export {}
-declare module '@vitest/expect' {
+declare module 'vitest' {
  interface JestAssertion<T = any>
    extends TestingLibraryMatchers<
      ReturnType<typeof expect.stringContaining>,
      T
    > {}
}

... it worked as intended.

I don't know if it's something related to pnpm, or monorepos.

My workaround was doing by hand what the testing-library/vitest abstraction is doing:

import * as matchers from '@testing-library/jest-dom/matchers'
import { expect } from 'vitest'

expect.extend(matchers)

declare module 'vitest' { // vitest instead `@vitest/expect`
  interface JestAssertion<T = any>
    extends matchers.TestingLibraryMatchers<
      ReturnType<typeof expect.stringContaining>,
      T
    > {}
}

I'm having the same issue after upgrading from 0.34 to 1.2.2

I couldn't get it to work. My problem was having the tests in a tests folder.
So the when I change the include in tsconfig.json to read it works:

"include": ["src", "tests"]

Weird that it seems I have everything correctly but I still get the error:

The setup file inside ./tests/setupFiles/testingLibrary.ts

import '@testing-library/jest-dom/vitest'

My tsconfig.json:

{
  "include": [
    "remix.env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "./tests/setupFiles/testingLibrary.ts"
  ],
  // ...rest
  // baseUrl is "." in compiler options
}

My vitest.config.ts file:

import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      include: ['app/**'],
    },
    clearMocks: true,
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./tests/setupFiles/testingLibrary.ts'],
    css: true,
    silent: process.env.CI === 'true',
    retry: 2,
  },
})

... and my package versions:

pnpm -F my-project ls @testing-library/jest-dom vitest typescript
Legend: production dependency, optional only, dev only

my-project /path/to/monorepo/apps/my-project

devDependencies:
@testing-library/jest-dom 6.2.0
typescript 5.3.3
vitest 1.2.0

With all that in place, I still get the error:

error TS2339: Property 'toBeInTheDocument' does not exist on type 'Assertion<HTMLElement | null>'

I notice one thing though, in the @testing-library/jest-dom/vitest, we're overriding @vitest/expect module:

import {type expect} from 'vitest'
import {type TestingLibraryMatchers} from './matchers'

export {}
declare module '@vitest/expect' {
  interface JestAssertion<T = any>
    extends TestingLibraryMatchers<
      ReturnType<typeof expect.stringContaining>,
      T
    > {}
}

https://github.com/testing-library/jest-dom/blob/1fb156c2b544e0069c56a72a2f1909fe04850f6c/types/vitest.d.ts

I don't have @vitest/expect listed in my package.json file and even though I know it's a dependency of vitest and it's being used under-the-hood, I guess that's the issue. That's because if I change the module declaration from @vitest/expect to vitest:

import {type expect} from 'vitest'
import {type TestingLibraryMatchers} from './matchers'

export {}
-declare module '@vitest/expect' {
+declare module 'vitest' {
  interface JestAssertion<T = any>
    extends TestingLibraryMatchers<
      ReturnType<typeof expect.stringContaining>,
      T
    > {}
}

... it worked as intended.

I don't know if it's something related to pnpm, or monorepos.

My workaround was doing by hand what the testing-library/vitest abstraction is doing:

import * as matchers from '@testing-library/jest-dom/matchers'
import { expect } from 'vitest'

expect.extend(matchers)

declare module 'vitest' { // vitest instead `@vitest/expect`
  interface JestAssertion<T = any>
    extends matchers.TestingLibraryMatchers<
      ReturnType<typeof expect.stringContaining>,
      T
    > {}
}

Facing this same issue with pnpm with monorepos.