Я пытаюсь проверить наличие моего модального окна с помощью библиотеки тестирования React с помощью findByRole. Я продолжаю получать сообщение об ошибке: Unable to find role = "dialog"
, хотя я ясно вижу, что это распечатано в консоли теста.
Вот мой тест:
import React from "react";
import {
render,
screen,
within,
fireEvent, cleanup, waitFor
} from '@testing-library/react';
import '@testing-library/jest-dom';
import "@testing-library/react/dont-cleanup-after-each";
import Modal from 'react-modal';
import PackagerModal from './PackagerModal';
const mockedEmptyFn = jest.fn();
const mockBaseProps = {
openPackager: true,
setOpenPackager: mockedEmptyFn,
activeOrder: {
// ... // lots of irrelevant properties here
]
},
setOrders: mockedEmptyFn,
customStyles: {
content: {
backgroundColor: "var(--color-primary)",
border: "1px solid #ccc",
boxShadow: "-2rem 2rem 2rem rgba(0, 0, 0, 0.5)",
color: "rgba(var(--RGB-text), 0.8)",
filter: "blur(0)",
fontSize: "1.1em",
fontWeight: "bold",
margin: "50px auto",
opacity: 1,
outline: 0,
position: "relative",
visibility: "visible",
width: "500px"
},
overlay: {
backgroundColor: "rgba(255, 255, 255, 0.9)"
}
},
readOnly: false,
setReadOnly: mockedEmptyFn,
};
Modal.setAppElement('body');
const Component = (props) => <PackagerModal {...mockBaseProps} {...props} />
describe('Packager Modal tests with editable inputs', () => {
afterAll(() => {
cleanup();
});
test('Should show packager modal', async () => {
render(
<Component/>
);
// screen.debug();
const modalWindow = await screen.findByRole('dialog');
expect(modalWindow).toBeInTheDocument();
});
});
И вот мой модальный:
import ReactModal from 'react-modal';
import React, { useEffect, useRef, useState } from 'react';
import CloseButton from './CloseButton';
import PropTypes from 'prop-types';
const PackagerModal = (props) => {
const {
openPackager,
setOpenPackager,
activeOrder,
setOrders,
customStyles,
readOnly,
setReadOnly,
} = props;
const cleanUpModal = () => {
setReadOnly(false);
setUserInput(initialState);
};
return (
<ReactModal
isOpen = {openPackager}
style = {customStyles}
className = {'order-details-modal'}
closeTimeoutMS = {1000}
onAfterClose = {cleanUpModal}
>
<CloseButton setOpenModal = {setOpenPackager} />
<h2 className = {'title'}>Packager Order Checklist</h2>
</ReactModal>
);
};
PackagerModal.propTypes = {
openPackager: PropTypes.bool.isRequired,
setOpenPackager: PropTypes.func.isRequired,
customStyles: PropTypes.object.isRequired,
activeOrder: PropTypes.object.isRequired,
setOrders: PropTypes.func.isRequired,
readOnly: PropTypes.bool.isRequired,
setReadOnly: PropTypes.func.isRequired,
};
export default PackagerModal;
И, наконец, вот часть вывода, который я вижу в консоли из теста:
● Packager Modal tests with editable inputs › Should show packager modal
Unable to find role = "dialog"
Ignored nodes: comments, script, style
<body
aria-hidden = "true"
class = "ReactModal__Body--open"
>
<div
data-react-modal-body-trap = ""
style = "position: absolute; opacity: 0;"
tabindex = "0"
/>
<div />
<div
data-react-modal-body-trap = ""
style = "position: absolute; opacity: 0;"
tabindex = "0"
/>
<div
class = "ReactModalPortal"
>
<div
class = "ReactModal__Overlay ReactModal__Overlay--after-open"
style = "position: fixed; top: 0px; left: 0px; right: 0px; bottom: 0px; background-color: rgba(255, 255, 255, 0.9);"
>
<div
aria-modal = "true"
class = "ReactModal__Content ReactModal__Content--after-open order-details-modal"
role = "dialog"
style = "border: 1px solid #ccc; box-shadow: -2rem 2rem 2rem rgba(0, 0, 0, 0.5); filter: blur(0); font-size: 1.1em; font-weight: bold; margin: 50px auto; opacity: 1; outline: 0; position: relative; visibility: visible; width: 500px;"
tabindex = "-1"
>
...
Это сработало! Я посмотрю, как я смоделирую модальное окно, и посмотрю, не делаю ли я что-то не так, чтобы вызвать это. Спасибо!
Не стесняйтесь добавлять это в качестве ответа, и я приму это.
Круто, рад, что смог помочь. Я разместил свой комментарий как ответ :)
Похоже, тело вашего теста скрыто — aria-hidden = "true"
(не знаю, почему, поскольку я не знаком с пакетом). Библиотека тестирования React в значительной степени ориентирована на доступность, поэтому по умолчанию она игнорирует любые недоступные элементы.
Попробуйте запросить свой элемент с опцией { hidden: true }
const myModal = getByRole('dialog', { hidden: true });
Это действительно не лучшее решение, в идеале вы не хотите, чтобы модальное окно появлялось внутри элемента с aria-hidden = "true"
. Я сталкиваюсь с той же проблемой, когда вам нужно, чтобы эта метка aria была установлена на что-то еще, кроме тела
Хотя ответ Ави работает, технически он не подходит для тестирования. У меня была та же проблема, и я понял, что у нас такая же проблема с нашим кодом, так что вот что происходит.
Проблема в том, что вы говорите Modal.setAppElement('body');
в своем тестовом файле.
Если вы читаете документы для модального реагирования, они говорят, что вам нужно сообщить модальному модулю, где находится содержимое вашего приложения, чтобы, когда модальное окно было открыто, все в этом элементе имело aria-hidden: true
, чтобы программы чтения с экрана не улавливали ни одного из другой контент, кроме того, что находится внутри модального окна, поскольку он отображается через портал, добавленный в конец вашего тела. Таким образом, вы устанавливаете setAppElement
в body, что делает все, что внутри скрыто для программ чтения с экрана, включая ваше модальное окно.
Итак, чтобы решить эту проблему, вам нужно установить это на что-то другое, лично у меня есть собственная функция рендеринга, в которой есть такие вещи, как провайдеры, поэтому я просто добавил туда новый div. Но в вашем случае вы можете добавить его в свой Component
const Component = (props) => <div id = "root"><PackagerModal {...mockBaseProps} {...props} /></div>
Затем вы можете изменить строку setAppElement на
Modal.setAppElement('root');
Это будет означать, что вам не нужно добавлять опцию { hidden: true }
к вашим запросам.
Вам также не нужно использовать findBy
, поскольку в вашем тесте пока не происходит никаких асинхронных изменений.
test('Should show packager modal', () => {
render(<Component/>);
const modalWindow = screen.getByRole('dialog');
expect(modalWindow).toBeInTheDocument();
});
Похоже, тело вашего теста скрыто
aria-hidden = "true" (not sure why as I'm not familiar with the package)
. Вы пробовали запрашивать свой элемент с опцией{ hidden: true }
?const myModal = getByRole('dialog', { hidden: true })
. Дай мне знать, если это работает!