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

Upgrading to v6.0.0 remove the toBeInTheDocument interface with vitest #515

Open
qchuchu opened this issue Aug 17, 2023 · 34 comments
Open

Comments

@qchuchu
Copy link

qchuchu commented Aug 17, 2023

  • @testing-library/jest-dom version: 6.0.0
  • node version: 18.16
  • npm (or yarn) version: 9.5.1

Relevant code or config:

import '@testing-library/jest-dom/vitest';
import { vitest } from 'vitest';
  await waitFor(() => {
    expect(getByTestId('text-input-error-message')).toBeInTheDocument();
  });

What you did:

Upgraded from v5 to v6

What happened:

image

I don't know why, but upgrading the package to the last version using vitest caused all my "toBeInTheDocument" matchers to be undefined, although I can see them in the type definition of the package.

Reproduction:

TO-DO

Problem description:

  • All my tests are failing because toBeInTheDocument is not defined anymore

Suggested solution:

I guess this is due to an upgrade on the dependency of jest types but I'm not sure. Still digging.

@jgoz
Copy link
Collaborator

jgoz commented Aug 17, 2023

What version of vitest, and where is the import statement located for @testing-library/jest-dom/vitest?

@curtvict
Copy link

fwiw this is happening to me in Jest too.

@qchuchu
Copy link
Author

qchuchu commented Aug 17, 2023

ah sorry I thought that I added the vitest version.

Vitest -> 0.34.2

I added the import statement in the vitest.setup.ts file (that is pointed from my vite.config.ts like this)

/// <reference types="vitest" />

import react from '@vitejs/plugin-react-swc';
import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['test/vitest.setup.ts'],
    include: ['**/?(*.)test.ts?(x)'],
  },
});

@jgoz
Copy link
Collaborator

jgoz commented Aug 17, 2023

@qchuchu Have you added test/vitest.setup.ts to your tsconfig.json file? You might also need to add the global vitest types reference to that file.

test/vitest.setup.ts:

/// <reference types="vitest" />

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

tsconfig.json

{
  "compilerOptions": {},
  "include": ["src", "test/vitest.setup.ts"]
}

@qchuchu
Copy link
Author

qchuchu commented Aug 17, 2023

So it does work by adding the setup file in the tsconfig.json, but only if I stay with the original configuration

test/vitest.setup.ts

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

If I add /vitest at the end, i'm facing the issue again.

@jgoz
Copy link
Collaborator

jgoz commented Aug 17, 2023

Hmm, I think that's because you're using Vitest in "globals" mode. There isn't really a difference between what you have now and using /vitest, which was designed for the default non-globals mode, so if this works for you I say go with it.

@Meemaw
Copy link

Meemaw commented Aug 18, 2023

Getting this error trying to import

// setup.ts
import matchers from '@testing-library/jest-dom/vitest';

Error:

File '/Users/x/y/node_modules/@testing-library/jest-dom/vitest.d.ts' is not a module.ts(2306)

@dominikg
Copy link

dominikg commented Aug 18, 2023

is adding the setup file to the tsconfig the only way to get this to work?
I'm using a monorepo where the vitest config is created in a separate package and the consuming applications/libraries have it like this in their vitest.config.ts

import {defineVitestConfig} from 'shared-workspace-vitest-setup';
export default defineVitestConfig({
  // custom options here that get merged with the default config
  // default config contains a setupFile adding dom matchers
});

i don't really want to add something like ../../packages/vitest-config/setupFile.js to every package tsconfig just for this, if that even works because the file is outside of the tsconfig parent dir....

edit:
Instead of including the setup file in the tsconfig, you can reference it directly in tsconfig compilerOptions.types

"compilerOptions": {
  "types": ["@testing-library/jest-dom/vitest"]
}

or put it in a .d.ts file that's included like src/jest-dom-types.d.ts

/// <reference types="@testing-library/jest-dom/vitest.d.ts" />

@jgoz
Copy link
Collaborator

jgoz commented Aug 18, 2023

Getting this error trying to import

// setup.ts

import matchers from '@testing-library/jest-dom/vitest';

Error:

File '/Users/x/y/node_modules/@testing-library/jest-dom/vitest.d.ts' is not a module.ts(2306)

Matchers are not exported from the vitest export. If you want to import matchers, use this:

import * as matchers from '@testing-library/jest-dom/matchers'

Or if you want to automatically extend Vitest's expect, do this:

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

@jgoz
Copy link
Collaborator

jgoz commented Aug 18, 2023

@dominikg Thanks for pointing out the alternate ways of getting the types recognized by TS. We should probably add that to the readme.

@DeveloperMatheus
Copy link

fwiw this is happening to me in Jest too.

I can also confirm this is also happening with Jest as well. Don't know how to handle those errors yet :(

@jgoz
Copy link
Collaborator

jgoz commented Aug 21, 2023

For those using Jest, make sure you are importing like this:

import '@testing-library/jest-dom'

Many people are using an older deprecated /extend-expect import that was removed in v6.

@curtvict
Copy link

Thanks @jgoz I can confirm this fixes the issue for me.

@DeveloperMatheus
Copy link

DeveloperMatheus commented Aug 23, 2023

@jgoz Sorry for asking help in this issue, i was checking my setup files and i see that i'm importing almost the same way as the library's documentation:

I have a .setup folder that groups some mocks globally, and also the import '@testing-library/jest-dom.
This is my setupFilesAfterEnv property in jest.config.js:
setupFilesAfterEnv: ['<rootDir>/.jest/setup.ts']

You have any suggestion of what might be causing my errors? When i'm importing on each test, the errors goes away (of course this is a solution, but would be better for me importing this globally in the setup hehe)

EDIT:

I found one possible solution, in my case, i tried to create e second setup file outside this folder (just in the root dir normally), and mentioned in the jest config file, and it worked! But, following my old setup file, can't it be inside any folder anymore?

@jgoz
Copy link
Collaborator

jgoz commented Aug 23, 2023

@DeveloperMatheus Is your setup file included in tsconfig.json? Like, in the includes or files properties?

@DeveloperMatheus
Copy link

DeveloperMatheus commented Aug 24, 2023

@jgoz It's like this:

{
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
      "~/*": ["*"]
    },
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": false
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

It doesn't have the files property

EDIT: My setup file is linked in my jest.config.js

@jgoz
Copy link
Collaborator

jgoz commented Aug 24, 2023

@DeveloperMatheus it might be because your setup file is in a .jest folder. Typescript might not automatically include files in dot-folders even if they match an include pattern. Try creating a files property next to include and explicitly list the setup file:

"include": [...],
"files": [".jest/setup.ts"]

@DeveloperMatheus
Copy link

@jgoz Many many many thanks for your help! It worked!

@kalvenschraut
Copy link

I think depending on how you import expect may cause this issue to occur. For instance my import looks like

import { expect } from 'vitest';

and below is a SS of what the type def points to
image

instead of the above if I do
image
then typescript finds the functions defined by jest-dom. Not sure if both need to be defined depending on how expect is being imported by the user?

@ajnozari
Copy link

ajnozari commented Sep 4, 2023

So while adding import '@testing-library/jest-dom'; to my setup for vitest (0.34.3) does prevent TS from giving an error, removing it gives me a slightly different error:

Property  toBeInTheDocument  does not exist on type  Assertion<HTMLElement>

@jgoz
Copy link
Collaborator

jgoz commented Sep 4, 2023

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

@ajnozari
Copy link

ajnozari commented Sep 4, 2023

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

This is my current setupTests.ts

import '@testing-library/jest-dom';
import '@testing-library/jest-dom/vitest';
import createFetchMock from 'vitest-fetch-mock';
import { afterEach, vi } from 'vitest';
import { cleanup } from '@testing-library/react';

export const fetchMocker = createFetchMock(vi);
fetchMocker.enableMocks();

afterEach(() => {
    cleanup();
});

I've tried with both import '@testing-library/jest-dom/vitest'; and import '@testing-library/jest-dom'; and JUST import '@testing-library/jest-dom/vitest'; alone.

I'm starting to think it might be something to do with yarn PnP and WebStorm. I have updated TS, ensured I only import /vitest and my IDE still shows errors.

Interestingly the tests still pass despite the error.

@jgoz
Copy link
Collaborator

jgoz commented Sep 5, 2023

And setupTests.ts is included in your tsconfig.json file, either via include or files?

@justinwaite
Copy link

justinwaite commented Sep 6, 2023

Also using pnpm, I'm getting the type error Property  toBeInTheDocument  does not exist on type  Assertion<HTMLElement> .

The tests pass, but still get the typescript error when typechecking.

test/setup-test-env.ts:

import { installGlobals } from '@remix-run/node';
import '@testing-library/jest-dom/vitest';

installGlobals();

tsconfig includes test/setup-test-env.ts explicitly

tsconfig:

{
  "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx", "test/setup-test-env.ts"],
  "compilerOptions": {
    "lib": ["DOM", "DOM.Iterable", "ES2019"],
    "isolatedModules": true,
    "esModuleInterop": true,
    "jsx": "react-jsx",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "target": "ES2019",
    "strict": true,
    "allowJs": true,
    "forceConsistentCasingInFileNames": true,
    "baseUrl": ".",
    "paths": {
      "~/*": ["./app/*"]
    },
    "types": ["vitest/globals"],

    // Remix takes care of building everything in `remix build`.
    "noEmit": true
  }
}

image

@dteoh
Copy link

dteoh commented Oct 6, 2023

Hey guys, I also ran into the same issue but finally got a working setup with v6.1.3, vitest 0.34.6 and pnpm. I have a React project created by Vite.

My setup:

// src/__tests__/extend-expect.ts
import "@testing-library/jest-dom/vitest";

Remember to add the above to vite.config.ts setupFiles.

// src/vitest.d.ts
import { type TestingLibraryMatchers } from "@testing-library/jest-dom/matchers";
import {
  type Assertion,
  type AsymmetricMatchersContaining,
  type expect,
} from "vitest";

type CustomMatchers<R = unknown> = TestingLibraryMatchers<
  ReturnType<typeof expect.stringContaining>,
  R
>;

declare module "vitest" {
  interface Assertion<T = unknown> extends CustomMatchers<T> {}
  interface AsymmetricMatchersContaining extends CustomMatchers {}
}

For tsconfig.json, there were no additional changes. I did not add the extend-expect file into include (Vite already added src dir).

I think the problem is that the types being shipped for @testing-library/jest-dom/vitest just doesn't match with Vitest's own official docs of how to extend the types.

@Ridd0
Copy link

Ridd0 commented Oct 10, 2023

To make it work if you are using the vitest:

  1. Make sure you have installed @testing-library/jest-dom
  2. Create the setupTests.ts file with content inside import '@testing-library/jest-dom/vitest'
  3. Import the setupTests.ts file inside vitest.config.ts, for example: setupFiles: path.resolve(__dirname, '../../setupTests.ts'),
  4. Add "files": ["../../setupTests.ts"] into the tsconfig.json file

@nwi-di
Copy link

nwi-di commented Oct 12, 2023

So it does work by adding the setup file in the tsconfig.json, but only if I stay with the original configuration

test/vitest.setup.ts

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

If I add /vitest at the end, i'm facing the issue again.

Had the same issue and can confirm this. When having "globals" set to true (in vite.config.ts), I need to import from @testing-library/jest-dom instead of @testing-library/jest-dom/vitest to make TypeScript happy.

But after taking a look into docs from vitest config for globals, I saw that you need to add vitest/globals to compilerOptions\types property. I did not had that and added it now. With that the import from @testing-library/jest-dom/vitest works without troubles

@mdodge-ecgrow
Copy link

So it does work by adding the setup file in the tsconfig.json, but only if I stay with the original configuration
test/vitest.setup.ts

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

If I add /vitest at the end, i'm facing the issue again.

Had the same issue and can confirm this. When having "globals" set to true (in vite.config.ts), I need to import from @testing-library/jest-dom instead of @testing-library/jest-dom/vitest to make TypeScript happy.

But after taking a look into docs from vitest config for globals, I saw that you need to add vitest/globals to compilerOptions\types property. I did not had that and added it now. With that the import from @testing-library/jest-dom/vitest works without troubles

Thank you!! I can confirm this also worked for me!

@matchatype
Copy link

Just bumped in this issue. For me, after following the setup instructions found on the testing-library docs, I also had to add jsdom types: npm i -D @types/testing-library__jest-dom, then it worked.

@vnaykvkrm
Copy link

vnaykvkrm commented Feb 9, 2024

create a setupTest.ts file in src folder and add import '@testing-library/jest-dom'

In vitest.config.ts file

import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./src/setupTests.ts'],
    coverage: {
      provider: 'v8'
    }
  }
})

And finally install types/testing-library. This worked for me

@ecoms-ye
Copy link

ecoms-ye commented Mar 11, 2024

According to the comments above, import '@testing-library/jest-dom' can fix this error.

So this error can be fixed by using the TypeScript's Triple-Slash Directive:

// https://github.com/testing-library/jest-dom/issues/515
/// <reference types="@testing-library/jest-dom" />

// https://github.com/testing-library/jest-dom?tab=readme-ov-file#with-vitest
import '@testing-library/jest-dom/vitest'

Update: PR #589 can also solve this problem.

nyaapass added a commit to nyaapass/jest-dom that referenced this issue Mar 11, 2024
@RinalinDS
Copy link

RinalinDS commented Mar 20, 2024

"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.2",
"vitest": "^1.4.0"

i have one project create with next.js
and it was enough to create a setup.ts and add vitest.config setupFiles
But in second project which started with vite i have identical versions as above and this approach didn't work
i have to manually create global.d.ts with :

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

declare global {
 namespace jest {
   interface Matchers<R> {
     toBeInTheDocument(): R;
   }
 }
}

can't tell why it worked in first , but didn't in second
and also tests were working fine even before adding , i just had vscode to tell me that toBeInTheDocument doesn't exist.
and also i checked other mathers from jest-dom without global.d.ts they were working fine, somehow it only affects toBeInTheDocument

@curtvict
Copy link

curtvict commented Mar 20, 2024

@RinalinDS I just ran into this same issue this morning! Try this:

import * as matchers from '@testing-library/jest-dom/matchers';
import '@testing-library/jest-dom/vitest';
import { cleanup } from '@testing-library/react';
import { afterEach, expect } from 'vitest';

expect.extend(matchers);

afterEach(() => {
  cleanup();
});

The import '@testing-library/jest-dom/vitest'; bit took me a while to find.

To get vscode to "get in the van", so to speak, I had to run yarn dlx @yarnpkg/sdks vscode, edit my vscode workspace json to add this setting: typescript.tsdk": ".yarn/sdks/typescript/lib", and restart.

@SidiEyel
Copy link

SidiEyel commented May 6, 2024

To make it work if you are using the vitest:

  1. Make sure you have installed @testing-library/jest-dom
  2. import '@testing-library/jest-dom/vitest' in test file for example > app.test.tsx import '@testing-library/jest-dom/vitest';

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