Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not work with vitest 1.x.x #567

Open
kibertoad opened this issue Jan 6, 2024 · 10 comments
Open

Does not work with vitest 1.x.x #567

kibertoad opened this issue Jan 6, 2024 · 10 comments

Comments

@kibertoad
Copy link

kibertoad commented Jan 6, 2024

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

@andykenward
Copy link

@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']

@kibertoad
Copy link
Author

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

@andykenward
Copy link

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.

@MatthieuJnon
Copy link

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.

@Horsty80
Copy link

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

@raulfdm
Copy link

raulfdm commented Jan 17, 2024

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
    > {}
}

@carlosvq
Copy link

carlosvq commented Feb 8, 2024

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

@bracki
Copy link

bracki commented Feb 16, 2024

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"]

@opswiz
Copy link

opswiz commented Mar 27, 2024

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.

@jtiala
Copy link

jtiala commented Apr 11, 2024

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.

I found out that if you install @vitest/expect manually it fixes the TS error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants