Skip to content

expect(...).toHaveTextContent is not a function #379

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

Closed
atav32 opened this issue Jun 1, 2019 · 18 comments
Closed

expect(...).toHaveTextContent is not a function #379

atav32 opened this issue Jun 1, 2019 · 18 comments

Comments

@atav32
Copy link

atav32 commented Jun 1, 2019

  • react-testing-library version: 8.0.1
  • react version: 16.8.6
  • node version: 10.15.2
  • npm (or yarn) version: 6.4.1

Relevant code or config:

Component

import React, { useState, useEffect } from 'react';

const ClickCounter = (props) => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button data-testid="click-counter-button" onClick={() => setCount(count => count + 1)}>
        Click Me
      </button>
    </div>
  )
}

export default ClickCounter;

Test

test('component updates count when clicked', () => {
  const { getByText, getByTestId, asFragment } = render(
    <ClickCounter />
  );
  fireEvent.click(getByText('Click Me'));
  // const countTextNode = getByText(/You click.*\d.*times/i);
  const countTextNode = getByTestId('click-counter-button');
  expect(countTextNode).toHaveTextContent('You clicked 1 times');
});

What you did:

Just following the react-testing-library example to write a test for the React Hooks example.

What happened:

TypeError: expect(...).toHaveTextContent is not a function

Screen Shot 2019-05-31 at 11 50 22 PM

Reproduction:

https://github.com/atav32/react-testing-toHaveTextContent-bug

Just run npm test

Problem description:

I expected the test to pass, since it's in the Readme example.

Did something change in jest-dom and the example needs to be updated? I took a peek at that library and the toHaveTextContent() is still part of the API.

This is probably just me not understanding the jest-dom API or a dependencies issue.

Suggested solution:

Not really a solution, but a workaround seems to work

expect(countTextNode.textContent).toBe('You clicked 1 times');
@atav32
Copy link
Author

atav32 commented Jun 1, 2019

Just realized that it's preferred to ask these types of questions on Spectrum.

Feel free to close and reply here, https://spectrum.chat/testing-library/help-react/expect-tohavetextcontent-is-not-a-function~1b79c850-369b-4b67-88e8-ab27fa5d3bfe

@atav32
Copy link
Author

atav32 commented Jun 1, 2019

Ok nvm, I missed this line

// this adds custom jest matchers from jest-dom
import 'jest-dom/extend-expect'

My preference would be to keep the example as barebones as possible in order to highlight how to use react-testing-library. Throwing in a function from jest-dom was a red herring.

I never expect examples to have additional dependencies that I have to manually install, unless they're explicitly stated in big bold instructions. I thought jest-dom was automatically included in react-testing-library, just like jsdom is included in jest.

My suggestion would be to remove the jest-dom dependency from the example and change the line

expect(getByTestId('greeting-text')).toHaveTextContent('hello there')

to

expect(getByTestId('greeting-text').textContent).toBe('hello there')

If the authors/maintainers agree, then I can make a PR.

@alexkrolick
Copy link
Collaborator

Thanks for pointing this out. Yes, a PR would be welcome to remove usage of extra dependencies from the example.

@gnapse
Copy link
Member

gnapse commented Jun 1, 2019

I'm not sure I agree with your suggestion. That is an example of the usage of react testing library with jest, hence the addition of the jest-dom helpers. react testing library also does not depend on jest, it can be used with other test runners and assertion libraries. That's why jest-dom is not included by default. But if the example already uses jest, why not use also jest-dom? As you said the instruction to import the dependency was right there.

If you remove it, you'd also have to avoid using the toHaveAttribute('disabled') in the line next to the one that failed with toHaveTextContent.

@kentcdodds
Copy link
Member

Agreed, I think we should just add a comment explaining where the assertion is coming from

@atav32
Copy link
Author

atav32 commented Jun 2, 2019

@kentcdodds I'm on board with that

@gnapse good point that react-testing-library doesn't depend on Jest. Would it be easy to add examples with other test runners then? I could give it a shot, but I'm not familiar with the other ones.

@kentcdodds
Copy link
Member

I've updated the README to be more descriptive.

@cooervo
Copy link

cooervo commented Jan 31, 2020

For me this fixed:

import "@testing-library/jest-dom/extend-expect";

@lucksp
Copy link

lucksp commented Apr 22, 2020

what is the trick with a create-react-app & react-testing to have setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'], implemented correctly?

If I try to put setupFilesAfterEnv inside the jest object of package.json, it tells me to create a setupTests.js file...so I do that. Then when I try to use an expected assertion such as toBeChecked or toHaveAttribute it says they are not functions.

Without create-react-app if I have a jest.config file the setup is easier IMO. Please advise. thanks!

@kentcdodds
Copy link
Member

Create that setupTest.js file and put this in it:

// src/setupTest.js
import '@testing-library/jest-dom/extend-expect'

That'll do it :)

You might also appreciate https://github.com/kentcdodds/bookshelf as an example of a create-react-app based app that does this.

@lucksp
Copy link

lucksp commented Apr 22, 2020

```js
import '@testing-library/jest-dom/extend-expect'

Oh! I had understood to do this:

module.exports = {
  setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
};

so close, but no cigar. THanks Kent!

@kentcdodds
Copy link
Member

That's what you'd normally do, but CRA doesn't allow you to customize Jest, so you have to put the import in the src/setupTests.js file.

@ghost
Copy link

ghost commented Apr 28, 2020

Workable solution:
setupTests.js
import "@testing-library/jest-dom/extend-expect";

@toluadetula
Copy link

@stephyswe That worked for me

@chety
Copy link

chety commented Aug 29, 2020

Create that setupTest.js file and put this in it:

// src/setupTest.js
import '@testing-library/jest-dom/extend-expect'

That'll do it :)

You might also appreciate https://github.com/kentcdodds/bookshelf as an example of a create-react-app based app that does this.

I think there is a typo here. File name should be setupTests.js. (s at the end).

@targumon
Copy link

targumon commented Feb 3, 2021

I think there is a typo here. File name should be setupTests.js. (s at the end).

@chety in jest.config.js you add something like this: setupFilesAfterEnv: ['./src/setupTests.js']. The convention is indeed setupTests.js, but as far as I understand you can name that file however you see fit, just point setupFilesAfterEnv at it.

bobbyquennell added a commit to bobbyquennell/peggy that referenced this issue Aug 9, 2021
- enhance jest.config.js
 1. add moduleDirectories: ['node_modules', 'src'], so jest can find modules in src folder
 instead of writing test like this: import greeter from './greeter'
 we can: import greeter from 'greeter';
 2. add setupFilesAfterEnv: ['<rootDir>/src/setupTests.ts']
 to support extended handy expect
 check: testing-library/react-testing-library#379 (comment)
- add "esModuleInterop": true in tsconfig.json
  to fix: Cannot read property 'createElement' of undefined using TypeScript
   testing-library/react-testing-library#374 (comment)
   esModuleInterop vs allowSyntheticDefaultImports
   note: Enabling esModuleInterop will also enable allowSyntheticDefaultImports.
- add a new text example for react component: App.test.tsx
@pesterhazy
Copy link

In my project I wasn't using any transformers so import didn't work in my jest-setup.js, but this did:

require('@testing-library/jest-dom');

@lucasrmagalhaes
Copy link

For me this fixed:

import "@testing-library/jest-dom/extend-expect";

Thanks!

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