TypeError: Expected container to be an Element, a Document or a DocumentFragment but got string

Viewed 11182

I'm trying to run the below testcase using RTL , and the test is failing with the error "TypeError: Expected container to be an Element, a Document or a DocumentFragment but got string.". I tried searching for solution but couldn't find one .

describe("Feedback Commponent",()=>{
  it('should throw error when feedback textbox is empty', () => {
    const { getByLabelText} = render(<Contact />);

    fireEvent.change(getByLabelText('Feedback'), {
      target: { value: '' },
    });

    fireEvent.blur(getByLabelText('Feedback'));
    debug();

    expect(getByTestId('feedback-error')).toBe(
      'Please Enter Your Feedback'
    );
  });
});

The above snippet is suppose to test the feedback form , to be specific only the feedback text box , when it is empty and when user goes out of focus from the textbox ,there should be an error stating "Please Enter Your Feedback".

2 Answers

It seems that you imported getByTestId method straight from testing library instead of destructuring it from render like you did with getByLabelText. getByTestId, according to the docs is:

getByTestId(
  // If you're using `screen`, then skip the container argument:
  container: HTMLElement,
  text: TextMatch,
  options?: {
    exact?: boolean = true,
    normalizer?: NormalizerFn,
  }): HTMLElement

So it expects the first argument to be the HTML container, hence the error. One solution would be to destructure getByTestId as well:

const { getByLabelText, getByTestId } = render(<Contact />);

Another one is to use screen, as suggested by the docs:

import { screen } from '@testing-library/react';
...

expect(screen.getByTestId('feedback-error')).toBe(
  'Please Enter Your Feedback'
);

In which case the first 'container' argument is skipped and the string 'feedback-error' is treated like test id 'text' argument. Docs: https://testing-library.com/docs/queries/bytestid

I resolved the issue by changing the assertion to

expect(getByText('Please Enter Your Feedback')).toBeInTheDocument();

from

 expect(getByTestId('feedback-error')).toBe('Please Enter Your Feedback');

Also I noticed that I had setupTest.js file with

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

missing , which adds custom jest matchers for asserting on DOM nodes, so after adding the above changes my test case passed

Related