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

2

53

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();
Roxanneroxburgh answered 8/2, 2019 at 13:23 Comment(1)
I believe you dont have to do separetely: const { getByAltText } = render(<Image {...testProps} />); const { getByText } = render(<Image {...testProps} />); you can do const { getByAltText, getByText } = render(<Image {...testProps} />);Undershoot
C
44

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()
Conformal answered 8/2, 2019 at 13:48 Comment(1)
I removed the await method within expect method and it fixed it.Dalury
T
0

For my case I fix this with async/await method.

it("renders the image with a src, alt and a className ", async () => {
      const testProps = {
        imageAlt: "some random string",
        imageSrc: "",
        className: "imageDescripton"
      };

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

      const imageAltNode = getByAltText(testProps.imageAlt);
      const imageClassNameNode = getByText(`${testProps.className}`);

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

With async ahead your test function and await ahead your component render, it should work !

Trove answered 17/11, 2022 at 8:39 Comment(1)
but render is synchronous so how come? testing-library.com/docs/react-testing-library/api/…Broiler

© 2022 - 2024 — McMap. All rights reserved.