60

Just what it says. Some example code:

let wrapper = shallow(<div><button class='btn btn-primary'>OK</button></div>);

const b = wrapper.find('.btn'); 

expect(b.text()).to.be.eql('OK'); // fail

Also the html method returns the contents of the element but also the element itself plus all the attributes, e.g. it gives <button class='btn btn-primary'>OK</button>. So I guess, worst case, I can call html and regex it, but...

Is there a way to just get the contents of the element, so I can assert on it.

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Kevin
  • 24,871
  • 19
  • 102
  • 158

4 Answers4

60

If you found this while looking for "includes text", try:

it('should show correct text', () => {
  const wrapper = shallow(<MyComponent />);
  expect(wrapper.text().includes('my text')).toBe(true);
});
Nelu
  • 16,644
  • 10
  • 80
  • 88
  • 1
    For me, this returns `true` no matter what. If you are using this, you should try to purposefully make it fail for your use case. I needed to do a `mount` instead of `shallow` for it to work. – coler-j Jan 13 '21 at 22:18
46

Don't forget that you are passing a node (ReactElement) to shallow function, and there is no HTML attribute class in React. You have to use className.

From React documentation

All attributes are camel-cased and the attributes class and for are className and htmlFor, respectively, to match the DOM API specification.

This test should works

const wrapper = shallow(<div><button className='btn btn-primary'>OK</button></div>);
const button = wrapper.find('.btn'); 
expect(button.text()).to.be.eql('OK');
Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184
Louis Barranqueiro
  • 10,058
  • 6
  • 42
  • 52
  • 4
    how do you find it if there is no class? also, what if it's not at the top of the tree on the page? – Jason G Dec 19 '18 at 15:50
7

I think @louis-barranqueiro has probably answered your underlying question. That is, you want a CSS selector and so you should have been using className not class.

However, to try and answer the question of how to select an element's text using the actual example you gave:

let wrapper = shallow(<div><button class='btn btn-primary'>OK</button></div>);

you'd need to use something like an object property selector, e.g.:

expect(wrapper.find({ class: "btn btn-primary" }).text()).to.equal('OK');

or prop syntax:

expect(wrapper.find('[class="btn btn-primary"]').text()).to.equal('OK');

(or even more explicitly):

expect(wrapper.find('button[class="btn btn-primary"]').text()).to.equal('OK');

eddies
  • 7,113
  • 3
  • 36
  • 39
  • 1
    If you carefully read the question, the author tries to select the button with `wrapper.find('.btn');`. Based on that, it's obvious, he wants to use `class` HTML attribute and not a custom HTML attribute. So he has to use `className` React DOM attribute because `class` does not exist in the React DOM API. – Louis Barranqueiro Jan 10 '18 at 12:24
  • it it possible to make check/boolean check on its text length? – Anupam Maurya Jan 02 '19 at 07:30
3

I ran into this post when searching for ways to select all/some of the text within a textarea within jest and enzyme. For those who are looking for the same thing, you do can the following to select some text (provided you already know the length):

let wrapper;
let textareaNode;
beforeEach(() => {
    wrapper = mount(<Textarea value="Hello world" />);
    textareaNode = () => wrapper.find("textarea").getDOMNode();
});

it("selects all of the select within the given range", () => {
    textareaNode().setSelectionRange(0, 6);
    wrapper.find("button").simulate("click"); // this would delete the selection via a ref
    expect(wrapper.find("textarea").props().value).toEqual("world");
});
Matt Carlotta
  • 18,972
  • 4
  • 39
  • 51