MouseEnter/MouseOver 不适用于 react-testing-library。如何使用 react-testing-library 测试悬停事件
MouseEnter/MouseOver doesn't work with react-testing-library. How to test hover events with react-testing-library
我有一个 ant-design 下拉列表,它显示了悬停元素的列表。我想测试下拉菜单中的列表。我正在使用 fireEvent.mouseOver() 但它不起作用。 screen.debug() 没有显示菜单。如何测试悬停元素?
提前致谢
这是我的测试代码。
使用 await 等待菜单出现很重要。
MyDropdown.tsx
import React from 'react'
import { Menu, Dropdown, Button } from 'antd';
const menu = (
<Menu data-testid="dropdown-menu">
<Menu.Item>
<a target="_blank" rel="noopener noreferrer" href="http://www.alipay.com/">
1st menu item
</a>
</Menu.Item>
<Menu.Item>
<a target="_blank" rel="noopener noreferrer" href="http://www.taobao.com/">
2nd menu item
</a>
</Menu.Item>
<Menu.Item>
<a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/">
3rd menu item
</a>
</Menu.Item>
</Menu>
);
export const MyDropdown: React.FC = () => {
return(
<Dropdown overlay={menu} placement="bottomLeft" arrow>
<Button>bottomLeft</Button>
</Dropdown>
)
}
MyDropdown.test.tsx
import React from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { MyDropdown } from "./MyDropdown";
describe("<MyDropdown />", () => {
it("check dropdown menu item", async () => {
render(<MyDropdown />);
fireEvent.mouseOver(screen.getByText('bottomLeft'));
await waitFor(() => screen.getByTestId('dropdown-menu'))
expect(screen.getByText('1st menu item')).toBeInTheDocument()
expect(screen.getByText('2nd menu item')).toBeInTheDocument()
expect(screen.getByText('3rd menu item')).toBeInTheDocument()
});
});
这里是参考代码。将鼠标悬停在条款和条件上,弹出窗口将 show/hide
import React, { useState } from 'react';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import Popover from "react-bootstrap/Popover";
import OverlayTrigger from "react-bootstrap/OverlayTrigger";
export default function SummaryForm() {
const [tcChecked, setTcChecked] = useState(false);
const popover = (
<Popover id="popover-basic">
No ice cream will be delivered
</Popover>
);
const checkboxLabel = (
<span>
<OverlayTrigger overlay={popover} placement="right">
<span style={{ color: 'blue' }}> Terms and Conditions</span>
</OverlayTrigger>
</span>
) ;
return (
<Form>
<Form.Group controlId="terms-and-conditions">
<Form.Check
type="checkbox"
checked={tcChecked}
onChange={(e) => setTcChecked(e.target.checked)}
label={checkboxLabel}
/>
</Form.Group>
<Button variant="primary" type="submit" disabled={!tcChecked}>
Confirm order
</Button>
</Form>
);
}
import {
render,
screen,
waitForElementToBeRemoved,
} from '@testing-library/react';
import SummaryForm from '../Form';
import userEvent from '@testing-library/user-event';
test('Initial conditions', () => {
render(<SummaryForm />);
const checkbox = screen.getByRole('checkbox', {
name: /terms and conditions/i,
});
expect(checkbox).not.toBeChecked();
const confirmButton = screen.getByRole('button', { name: /confirm order/i });
expect(confirmButton).toBeDisabled();
});
test('Checkbox enables button on first click and disables on second click', () => {
render(<SummaryForm />);
const checkbox = screen.getByRole('checkbox', {
name: /terms and conditions/i,
});
const confirmButton = screen.getByRole('button', { name: /confirm order/i });
userEvent.click(checkbox);
expect(confirmButton).toBeEnabled();
userEvent.click(checkbox);
expect(confirmButton).toBeDisabled();
});
test('popover responds to hover', async () => {
render(<SummaryForm />);
// popover starts out hidden
const nullPopover = screen.queryByText(
/No ice cream will be delivered/i
);
expect(nullPopover).not.toBeInTheDocument();
// popover appears upon mouseover of checkbox label
const termsAndConditions = screen.getByText(/terms and conditions/i);
userEvent.hover(termsAndConditions);
const popover = screen.queryByText(/No ice cream will be delivered/i);
expect(popover).toBeInTheDocument();
// popover disappears when we mouse out
userEvent.unhover(termsAndConditions);
await waitForElementToBeRemoved(() =>
screen.queryByText(/No ice cream will be delivered/i)
);
});
我有一个 ant-design 下拉列表,它显示了悬停元素的列表。我想测试下拉菜单中的列表。我正在使用 fireEvent.mouseOver() 但它不起作用。 screen.debug() 没有显示菜单。如何测试悬停元素?
提前致谢
这是我的测试代码。 使用 await 等待菜单出现很重要。
MyDropdown.tsx
import React from 'react'
import { Menu, Dropdown, Button } from 'antd';
const menu = (
<Menu data-testid="dropdown-menu">
<Menu.Item>
<a target="_blank" rel="noopener noreferrer" href="http://www.alipay.com/">
1st menu item
</a>
</Menu.Item>
<Menu.Item>
<a target="_blank" rel="noopener noreferrer" href="http://www.taobao.com/">
2nd menu item
</a>
</Menu.Item>
<Menu.Item>
<a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/">
3rd menu item
</a>
</Menu.Item>
</Menu>
);
export const MyDropdown: React.FC = () => {
return(
<Dropdown overlay={menu} placement="bottomLeft" arrow>
<Button>bottomLeft</Button>
</Dropdown>
)
}
MyDropdown.test.tsx
import React from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { MyDropdown } from "./MyDropdown";
describe("<MyDropdown />", () => {
it("check dropdown menu item", async () => {
render(<MyDropdown />);
fireEvent.mouseOver(screen.getByText('bottomLeft'));
await waitFor(() => screen.getByTestId('dropdown-menu'))
expect(screen.getByText('1st menu item')).toBeInTheDocument()
expect(screen.getByText('2nd menu item')).toBeInTheDocument()
expect(screen.getByText('3rd menu item')).toBeInTheDocument()
});
});
这里是参考代码。将鼠标悬停在条款和条件上,弹出窗口将 show/hide
import React, { useState } from 'react';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import Popover from "react-bootstrap/Popover";
import OverlayTrigger from "react-bootstrap/OverlayTrigger";
export default function SummaryForm() {
const [tcChecked, setTcChecked] = useState(false);
const popover = (
<Popover id="popover-basic">
No ice cream will be delivered
</Popover>
);
const checkboxLabel = (
<span>
<OverlayTrigger overlay={popover} placement="right">
<span style={{ color: 'blue' }}> Terms and Conditions</span>
</OverlayTrigger>
</span>
) ;
return (
<Form>
<Form.Group controlId="terms-and-conditions">
<Form.Check
type="checkbox"
checked={tcChecked}
onChange={(e) => setTcChecked(e.target.checked)}
label={checkboxLabel}
/>
</Form.Group>
<Button variant="primary" type="submit" disabled={!tcChecked}>
Confirm order
</Button>
</Form>
);
}
import {
render,
screen,
waitForElementToBeRemoved,
} from '@testing-library/react';
import SummaryForm from '../Form';
import userEvent from '@testing-library/user-event';
test('Initial conditions', () => {
render(<SummaryForm />);
const checkbox = screen.getByRole('checkbox', {
name: /terms and conditions/i,
});
expect(checkbox).not.toBeChecked();
const confirmButton = screen.getByRole('button', { name: /confirm order/i });
expect(confirmButton).toBeDisabled();
});
test('Checkbox enables button on first click and disables on second click', () => {
render(<SummaryForm />);
const checkbox = screen.getByRole('checkbox', {
name: /terms and conditions/i,
});
const confirmButton = screen.getByRole('button', { name: /confirm order/i });
userEvent.click(checkbox);
expect(confirmButton).toBeEnabled();
userEvent.click(checkbox);
expect(confirmButton).toBeDisabled();
});
test('popover responds to hover', async () => {
render(<SummaryForm />);
// popover starts out hidden
const nullPopover = screen.queryByText(
/No ice cream will be delivered/i
);
expect(nullPopover).not.toBeInTheDocument();
// popover appears upon mouseover of checkbox label
const termsAndConditions = screen.getByText(/terms and conditions/i);
userEvent.hover(termsAndConditions);
const popover = screen.queryByText(/No ice cream will be delivered/i);
expect(popover).toBeInTheDocument();
// popover disappears when we mouse out
userEvent.unhover(termsAndConditions);
await waitForElementToBeRemoved(() =>
screen.queryByText(/No ice cream will be delivered/i)
);
});