Unable to find an element with the text: "myText" error when using react-testing-library

intercoder picture intercoder · Feb 8, 2019 · Viewed 30.2k times · Source

I'm trying to use react-testing-library with React and Jest but one of my tests are failing and I think it has something to do with the regex on the className prop on the test file.

Below I have attached the respectives test & component files.

Also, is there a way to snapshot testing with this library? I feel that my test is not complete for some reason.

// Image.js Component


// @flow
import * as React from "react";
import styled from "styled-components";

const StyledImage = styled.img`
  max-width: ${props => props.imageWidth || 100}%;
`;

type Props = {
  imageAlt: string,
  imageSrc: string | boolean | Function,
  className?: string,
  StyledImage: React.Element<typeof StyledImage>
};

const Image = (props: Props) => {
  const { imageAlt, imageSrc, className } = props;
  return (
    <StyledImage
      {...props}
      className={className}
      src={imageSrc}
      alt={imageAlt}
    />
  );
};

export default Image;



// Image.test.js 


import React from "react";
import { render, cleanup } from "react-testing-library";
import Image from "../Image";

describe("<Image /> component", () => {
  afterEach(cleanup);

  describe("Component as a whole", () => {
    it("renders the image with a src, alt and a className ", () => {
      const testProps = {
        imageAlt: "some random string",
        imageSrc: "" /* [ASK]: How to test this */,
        className: "imageDescripton" /* [ASK]: How to test this */
      };

      const { getByAltText } = render(<Image {...testProps} />);
      const { getByText } = render(<Image {...testProps} />);

      const imageAltNode = getByAltText(testProps.imageAlt);
      const imageClassNameNode = getByText(`${testProps.className}`); // [FAIL]: Fails with error.  Unable to find an element with the text: imageDescripton. Regex problem?

      expect(imageAltNode).toBeDefined();
      expect(imageClassNameNode).toBeDefined();
    });
  });
});

Complete error log:

Unable to find an element with the text: imageDescripton. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

<body>
  <div>
    <img
      alt="some random string"
      class="imageDescripton Image__StyledImage-sc-1icad3x-0 judnkv"
      src=""
    />
  </div>
  <div>
    <img
      alt="some random string"
      class="imageDescripton Image__StyledImage-sc-1icad3x-0 judnkv"
      src=""
    />
  </div>
</body>

  18 |
  19 |       const imageAltNode = getByAltText(testProps.imageAlt);
> 20 |       const imageClassNameNode = getByText(`${testProps.className}`); // [FAIL]: Fails with error.  Unable to find an element with the text: imageDescripton. Regex problem?
     |                                  ^
  21 |
  22 |       expect(imageAltNode).toBeDefined();
  23 |       expect(imageClassNameNode).toBeDefined();

Answer

Giorgio Polvara - Gpx picture Giorgio Polvara - Gpx · Feb 8, 2019

getByText looks for the text inside a node. So in this example:

<div class="foo">bar</div>

the text is bar.

getByAltText is the best way to find an image. Another way is to use getByTestId.

What if you must find an element by class? In these cases, you can use container which is returned by render. container is just a DOM node so you can do

const { container } = render(<MyComponent />)
container.querySelector('.my-class')

Note that you don't have to use toBeDefined(), you can use toBeInTheDocument() which is more idiomatic. Make sure you install jest-dom first.


How to make a snapshot? Again, you can use container. In this case you want the first child.

expect(container.firstChild).toMatchSnapshot()