testing-library / dom-testing-library

🐙 Simple and complete DOM testing utilities that encourage good testing practices.
https://testing-library.com/dom
MIT License
3.26k stars 466 forks source link

*ByRole with opetion { hidden: true } reads a opened dialog when using with recoil. #1176

Closed mymactive closed 1 year ago

mymactive commented 1 year ago

Relevant code or config:

import { act, renderHook, screen } from '@testing-library/react';
import { JSXElementConstructor, ReactElement } from 'react';
import { atom, RecoilRoot, useRecoilState } from 'recoil';

// Implementation
const dialogAtom = atom({
  key: 'dialog',
  default: false,
});

const useDialog = () => {
  const [isOpen, setIsOpen] = useRecoilState(dialogAtom);
  return { isOpen, setIsOpen };
};

const Dialog = () => {
  const { isOpen } = useDialog();

  return (
    <dialog aria-label="test" open={isOpen}>
      Hello World
    </dialog>
  );
};

// Test codes
const DialogWrapper: JSXElementConstructor<{ children: ReactElement }> = ({
  children,
}) => {
  return (
    <>
      <RecoilRoot>
        {children}
        <Dialog />
      </RecoilRoot>
    </>
  );
};

test('should be not hidden when setState(true)', () => {
  const { result } = renderHook(() => useDialog(), { wrapper: DialogWrapper });

  act(() => {
    result.current.setIsOpen(true);
  });

  expect(screen.getByRole('dialog', { hidden: true })).toBeInTheDocument(); // Pass
  expect(screen.getByRole('dialog')).not.toHaveAttribute('open'); // Don't pass.
});

What you did:

I am trying to synchronize the "open" attribute of the dialog element by recoil state.

What happened:

The following test passes.

expect(screen.getByRole('dialog', { hidden: true })).toBeInTheDocument();

However, the other test does not pass.

expect(screen.getByRole('dialog')).not.toHaveAttribute('open');

error message:

    expect(element).not.toHaveAttribute("open") // element.hasAttribute("open")

    Expected the element not to have attribute:
      open
    Received:
      open=""

The dialog is open in test codes, but getByRole with option { hidden: true} reads it This is false negative. queryByRole, and findByRole are as well.

Reproduction:

Problem description:

Suggested solution:

mymactive commented 1 year ago

~~Sorry, it was sent in the middle of editing. I will fill in the content and resubmit. When I do, I reopen this issue.~~

Sorry, this is my misunderstanding.