This page will provide common testing recipes for components through ReactMD.
All examples assume that fake timers are not enabled. Enable at your own debugging risk!
The following examples will use the Autocomplete Simple Example code.
The Autocomplete
is broken up into a few accessible roles that can be found:
"combobox"
- The main TextField
"listbox"
- The popup menu of suggestions"option"
- The available suggestions in the popup menuFor simple tests, it is recommended just to update the Autocomplete
like
a normal TextField
using user.type()
or fireEvent.change()
If the test needs to verify specific suggestions are visible, filtering behavior, or anything else, open the listbox and select an option to change the value.
The Checkbox
can be found like any other checkbox element:
The FileInput
can be found like any other <input type="file">
and updated
using the upload utility
The Radio
can be found like any other radio element:
The following examples will use the Simple Select code.
This example showcases how to:
Select
componentThe Select
display value cannot be found using a normal query and instead
can be found as the container.getByRole("combobox", { name: "LABEL" }).firstElementChild
.
ReactMD provides React Testing Library queries named
getSelectTestElements
and
findSelectTestElements
to find the important Select
element parts with the correct type definitions.
Tests including the Slider
are generally setup to include verifying the
current value and optionally changing it. The slider element can be found
using screen.getByRole("slider", { name: "THE_SLIDER_LABEL" })
which can
be used to verify the current numeric value and update through touch, drag,
or keyboard events.
Since updating through touch, drag, or keyboard events aren't convenient for
tests, it's recommended to find the hidden <input type="range" />
and trigger
a change event on that instead and could be found by
screen.getByRole("slider", { name: "", hidden: true })
.
ReactMD provides React Testing Library queries named
getSliderTestElements
and
findSliderTestElements
that can be used to get the slider
element and the sliderInput
.
ReactMD provides additional React Testing Library queries named
getRangeSliderTestElements
and
findRangeSliderTestElements
that can be used for a range slider. It will return the minSlider
,
minSliderInput
, maxSlider
, and maxSliderInput
allowing the values to be
verified like the normal slider.
The Switch
is an extension of an <input type="checkbox">
with
role="switch"
, so the element can be changed just like a Checkbox
.
A tooltip can be found using using .getByRole("tooltip")
or
.findByRole("tooltip")
along with the hover
event:
This example will also work with custom useTooltip
usage and by
changing the button to the tooltipped element.
MenuItem
The MenuitemCheckbox
can be found using the "menuitemcheckbox"
role:
The MenuItemFileInput
does not render an <input type="file">
in the DOM, and instead
dynamically creates the input when the menu item is clicked. To help test this flow,
use the uploadMenuItemFileInput
from @react-md/core/test-utils/jest-globals
or @react-md/core/test-utils/vitest
:
The MenuItemRadio
can be found using the menuitemradio
role:
The MenuItemSwitch
can be found using the "menuitemcheckbox"
role:
Each tab can be found by using the "tab"
role while the tab panel can be
found using the "tabpanel"
role. The inactive tab panels are hidden using
display: none
by default so the visibility can be tested using the
isElementVisible util.
This test uses the Tabs Simple Example.
The following examples use the Single Select Tree Example.
The top-level tree can be found using the "tree"
role and each item with "treeitem"
:
Unless the temporaryChildItems
props are enabled, all tree items will be
rendered but hidden using display: none
. The expansion state can be verified
using the aria-expanded
attribute on the tree item or using the
isElementVisible
util with each subtree group.
Both the Dialog
and Sheet
can be found using the "dialog"
role or "alertdialog"
when
the modal
prop is enabled. Here's a simple test flow for the
Simple Dialog Example.
The following examples use the Expansion Panel Group Example.
Each expansion panel can be found using the "button"
role while the panel
contents can be found using the "region"
role. The collapsed panel contents
are hidden using display: none
by default so the visibility can be tested
using the isElementVisible util.
The isElementVisible
util really only verifies that the element or
any parent elements do not contain the "rmd-display-none"
class. A custom
util will be required for components not apart of react-md
or custom
styling to hide elements.
import { describe, expect, it } from "@jest/globals";
import {
fireEvent,
rmdRender,
screen,
userEvent,
} from "@react-md/core/test-utils";
import SimpleExample from "@/components/autocomplete/SimpleExample.jsx";
describe("SimpleExample", () => {
it("should be able to change the value", async () => {
const user = userEvent.setup();
rmdRender(<SimpleExample />);
const autocomplete = screen.getByRole("combobox", { name: "Fruit" });
expect(autocomplete).toHaveValue("");
await user.type(autocomplete, "Apple");
expect(autocomplete).toHaveValue("Apple");
// or fireEvent
fireEvent.change(autocomplete, { target: { value: "Orange" } });
expect(autocomplete).toHaveValue("Orange");
});
});
import { describe, expect, it } from "@jest/globals";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
import SimpleExample from "@/components/autocomplete/SimpleExample.jsx";
describe("SimpleExample", () => {
it("should be able to quickly change the value by clicking a suggestion", async () => {
const user = userEvent.setup();
rmdRender(<SimpleExample />);
const autocomplete = screen.getByRole("combobox", { name: "Fruit" });
expect(autocomplete).toHaveValue("");
await user.click(autocomplete);
await user.click(screen.getByRole("option", { name: "Apple" }));
expect(autocomplete).toHaveValue("Apple");
});
// this is a more verbose test
it("should be able to change the value by clicking a suggestion", async () => {
const user = userEvent.setup();
rmdRender(<SimpleExample />);
const autocomplete = screen.getByRole("combobox", { name: "Fruit" });
expect(autocomplete).toHaveValue("");
// these aren't required, but just helps show some of the state
// - the autocomplete listbox is currently not visible
// - there are no keyboard focused items
expect(autocomplete).toHaveAttribute("aria-expanded", "false");
expect(autocomplete).toHaveAttribute("aria-activedescendant", "");
expect(() => screen.getByRole("listbox")).toThrow();
await user.type(autocomplete, "a");
// the listbox should now be visible and displaying the filtered suggestions
const listbox = screen.getByRole("listbox", { name: "Fruits" });
// this could also be `within(listbox).getAllByRole("option")` if needed
const options = screen.getAllByRole("option");
expect(options).toHaveLength(2);
const [apple, apricot] = options;
expect(apple).toHaveTextContent("Apple");
expect(apricot).toHaveTextContent("Apricot");
await user.click(apricot);
expect(autocomplete).toHaveValue("Apricot");
// these aren't required, but showing that the listbox as been removed
// along with the suggestions
expect(listbox).not.toBeInTheDocument();
expect(apple).not.toBeInTheDocument();
expect(apricot).not.toBeInTheDocument();
});
});
import { describe, expect, it } from "@jest/globals";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
describe("Checkbox", () => {
it("should be able to change value", async () => {
const user = userEvent.setup();
rmdRender(<Checkbox label="Label" />);
const checkbox = screen.getByRole("checkbox", { name: "Label" });
expect(checkbox).not.toBeChecked();
await user.click(checkbox);
expect(checkbox).toBeChecked();
await user.click(checkbox);
expect(checkbox).not.toBeChecked();
});
});
import { describe, expect, it } from "@jest/globals";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
function Test() {
return (
<Form>
<FileInput
onChange={(event) => {
// do something
}}
/>
</Form>
);
}
describe("Test", () => {
it("should be able to change value", async () => {
const user = userEvent.setup();
rmdRender(<Test />);
const input = screen.getByLabelTest("Upload");
const file = new File(["some-example-content"], "README.md");
await user.upload(input, file);
expect(input.files[0]).toBe(file);
});
});
import { describe, expect, it } from "@jest/globals";
import { Form } from "@react-md/core/form/Form";
import { Radio } from "@react-md/core/form/Radio";
import { useRadioGroup } from "@react-md/core/form/useRadioGroup";
function Test() {
const { getRadioProps } = useRadioGroup({ name: "example" });
return (
<Form>
<Radio {...getRadioProps("a")} label="First" />
<Radio {...getRadioProps("b")} label="Second" />
<Radio {...getRadioProps("c")} label="Third" />
<Radio {...getRadioProps("d")} label="Forth" />
</Form>
);
}
describe("Test", () => {
it("should be able to change value", async () => {
const user = userEvent.setup();
render(<Test />);
const radio1 = screen.getByRole("radio", { name: "First" });
const radio2 = screen.getByRole("radio", { name: "Second" });
const radio3 = screen.getByRole("radio", { name: "Third" });
const radio4 = screen.getByRole("radio", { name: "Forth" });
expect(radio1).toHaveAttribute("value", "a");
expect(radio2).toHaveAttribute("value", "b");
expect(radio3).toHaveAttribute("value", "c");
expect(radio4).toHaveAttribute("value", "d");
expect(radio1).not.toBeChecked();
expect(radio2).not.toBeChecked();
expect(radio3).not.toBeChecked();
expect(radio4).not.toBeChecked();
await user.click(radio1);
expect(radio1).toBeChecked();
expect(radio2).not.toBeChecked();
expect(radio3).not.toBeChecked();
expect(radio4).not.toBeChecked();
await user.click(radio3);
expect(radio1).not.toBeChecked();
expect(radio2).not.toBeChecked();
expect(radio3).toBeChecked();
expect(radio4).not.toBeChecked();
});
});
import { describe, expect, it } from "@jest/globals";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
import SimpleSelect from "@/components/select/SimpleSelect.jsx";
describe("SimpleSelect", () => {
it("should be able to change value", async () => {
const user = userEvent.setup();
rmdRender(<SimpleSelect />);
// this is the clickable element that allows the listbox of options to appear
const select = screen.getByRole("combobox", { name: "Label" });
// this stores the current value
const selectInput = screen.getByRole("textbox", { hidden: true });
expect(selectInput).toHaveValue("");
await user.click(select);
// the `name` should be the accessible text in any of the available options
await user.click(screen.getByRole("option", { name: "Option 1" }));
expect(selectInput).toHaveValue("a");
await user.click(select);
// the `Option 1` should now be selected
expect(() =>
screen.getByRole("option", { name: "Option 1", selected: true })
).not.toThrow();
});
});
import { describe, expect, it } from "@jest/globals";
import {
getSelectTestElements,
rmdRender,
screen,
userEvent,
} from "@react-md/core/test-utils";
import SimpleSelect from "@/components/select/SimpleSelect.jsx";
describe("SimpleSelect", () => {
it("should be able to verify the display value", async () => {
const user = userEvent.setup();
rmdRender(<SimpleSelect />);
const { select, selectInput, selectedOption } = getSelectTestElements({
name: "Label",
});
// this isn't required, but added to show what element this is
expect(selectedOption).toHaveClass("rmd-selected-option");
// there is currently no selected value
expect(selectedOption).toHaveTextContent("");
await user.click(select);
await user.click(screen.getByRole("option", { name: "Option 1" }));
expect(selectInput).toHaveValue("a");
expect(selectedOption).toHaveTextContent("Option 1");
});
});
import { describe, expect, it } from "@jest/globals";
import {
fireEvent,
getSliderTestElements,
rmdRender,
} from "@react-md/core/test-utils";
import HorizontalSlider from "@/components/slider/HorizontalSlider.jsx";
describe("HorizontalSlider", () => {
it("should be able to change the value", async () => {
rmdRender(<HorizontalSlider />);
// `name` is the accessible label for the `Slider`
const { slider, sliderInput } = getSliderTestElements({ name: "Slider" });
expect(slider).toHaveValue(50);
expect(sliderInput).toHaveValue("50");
fireEvent.change(sliderInput, { target: { value: "80" } });
expect(slider).toHaveValue(80);
expect(sliderInput).toHaveValue("80");
});
});
import { describe, expect, it } from "@jest/globals";
import {
fireEvent,
getRangeSliderTestElements,
rmdRender,
} from "@react-md/core/test-utils";
import RangeSlider from "@/components/slider/RangeSlider.jsx";
describe("RangeSlider", () => {
it("should be able to change the value", async () => {
rmdRender(<RangeSlider defaultValue={[30, 60]} />);
const { minSlider, minSliderInput, maxSlider, maxSliderInput } =
getRangeSliderTestElements();
expedct(minSlider).toHaveValue(30);
expedct(minSliderInput).toHaveValue("30");
expedct(maxSlider).toHaveValue(60);
expedct(maxSliderInput).toHaveValue("60");
fireEvent.change(minSliderInput, { target: { value: "50" } });
expect(slider).toHaveValue(50);
expect(sliderInput).toHaveValue("50");
expedct(maxSlider).toHaveValue(60);
expedct(maxSliderInput).toHaveValue("60");
});
});
import { describe, expect, it } from "@jest/globals";
import { Switch } from "@react-md/core/form/Switch";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
describe("Switch", () => {
it("should be able to change the checked state", async () => {
const user = userEvent.setup();
rmdRender(<Switch label="Label" />);
const switchElement = screen.getByRole("switch", { name: "Label" });
expect(switchElement).not.toBeChecked();
await user.click(switchElement);
expect(switchElement).toBeChecked();
});
});
import { describe, expect, it } from "@jest/globals";
import { TooltippedButton } from "@react-md/core/button/TooltippedButton";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
function Test() {
return (
<TooltippedButton tooltip={<span>Some Tooltip</span>}>
Button
</TooltippedButton>
);
}
describe("Test", () => {
it("should be able to trigger a tooltip", async () => {
const user = userEvent.setup();
rmdRender(<Test />);
const button = screen.getByRole("button", { name: "Button" });
expect(() => screen.getByRole("tooltip")).toThrow();
await user.hover(button);
// change `name` to the tooltip text or another query
const tooltip = screen.getByRole("tooltip", { name: "Some Tooltip" });
expect(tooltip).toBeInTheDocument();
await user.unhover(button);
expect(tooltip).not.toBeInTheDocument();
});
});
import { expect, it, jest } from "@jest/globals";
import { DropdownMenu } from "@react-md/core/menu/DropdownMenu";
import { MenuItem } from "@react-md/core/menu/MenuItem";
import { rmdRender } from "@react-md/core/test-utils";
const handleClick1 = jest.fn();
const handleClick2 = jest.fn();
function Test() {
return (
<DropdownMenu buttonChildren="Menu Toggle">
<MenuItem onClick={handleClick1}>First Item</MenuItem>
<MenuItem onClick={handleClick2}>Second Item</MenuItem>
</DropdownMenu>
);
}
describe("Test", () => {
it("should be able to open the menu and trigger actions", async () => {
const user = userEvent.setup();
rmdRender(<Test />);
const menuToggle = screen.getByRole("button", { name: "Menu Toggle" });
expect(() => screen.getByRole("menu")).toThrow();
await user.click(menuToggle);
// this isn't really required, but shows how you can find the menu
// the name defaults to the button label, but will reflect the `aria-label`
// or `aria-labelledby` prop if it was provided
expect(() =>
screen.getByRole("menu", { name: "Menu Toggle" })
).not.toThrow();
await user.click(screen.getByRole("menuitem", { name: "First Item" }));
expect(handleClick1).toHaveBeenCalledTimes(1);
// menu no longer is visible
expect(() => screen.getByRole("menu")).toThrow();
const menuToggle = screen.getByRole("button", { name: "Menu Toggle" });
await user.click(screen.getByRole("menuitem", { name: "Second Item" }));
expect(handleClick2).toHaveBeenCalledTimes(1);
});
});
import { describe, expect, it } from "@jest/globals";
import { useCheckboxGroup } from "@react-md/core/form/useCheckboxGroup";
import { DropdownMenu } from "@react-md/core/menu/DropdownMenu";
import { MenuItemCheckbox } from "@react-md/core/menu/MenuItemCheckbox";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
const values = ["a", "b", "c", "d"];
const labels = {
a: "Label 1",
b: "Label 2",
c: "Label 3",
d: "Label 4",
};
function Test() {
const { getCheckboxProps, getIndeterminateProps } = useCheckboxGroup({
menu: true,
values,
});
return (
<DropdownMenu buttonChildren="Checkboxes">
<MenuItemCheckbox {...getIndeterminateProps()}>
Toggle All
</MenuItemCheckbox>
{values.map((value) => (
<MenuItemCheckbox key={value} {...getCheckboxProps(value)}>
{labels[value]}
</MenuItemCheckbox>
))}
</DropdownMenu>
);
}
describe("Test", () => {
it("should be able to change the checked state", async () => {
const user = userEvent.setup();
rmdRender(<Test />);
const toggle = screen.getByRole("button", { name: "Checkboxes" });
await user.click(toggle);
let toggleAll = screen.getByRole("menuitemcheckbox", {
name: "Toggle All",
});
let label1 = screen.getByRole("menuitemcheckbox", {
name: "Label 1",
});
let label2 = screen.getByRole("menuitemcheckbox", {
name: "Label 2",
});
let label3 = screen.getByRole("menuitemcheckbox", {
name: "Label 3",
});
let label4 = screen.getByRole("menuitemcheckbox", {
name: "Label 4",
});
expect(toggleAll).not.toBeChecked();
expect(label1).not.toBeChecked();
expect(label2).not.toBeChecked();
expect(label3).not.toBeChecked();
expect(label4).not.toBeChecked();
await user.click(label1);
// the menu closed
expect(toggleAll).not.toBeInTheDocument();
expect(label1).not.toBeInTheDocument();
expect(label2).not.toBeInTheDocument();
expect(label3).not.toBeInTheDocument();
expect(label4).not.toBeInTheDocument();
await user.click(toggle);
// can also use `getAllByRole` since the order is known
[toggleAll, label1, label2, label3, label4] =
screen.getAllByRole("menuitemcheckbox");
expect(toggleAll).not.toBeChecked();
expect(toggleAll).toHaveAttribute("aria-checked", "mixed");
expect(label1).toBeChecked();
expect(label2).not.toBeChecked();
expect(label3).not.toBeChecked();
expect(label4).not.toBeChecked();
});
});
import { describe, expect, it, jest } from "@jest/globals";
import { DropdownMenu } from "@react-md/core/menu/DropdownMenu";
import { MenuItemFileInput } from "@react-md/core/menu/MenuItemFileInput";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
import { uploadMenuItemFileInput } from "@react-md/core/test-utils/jest-globals";
const handleChange = jest.fn();
function Test() {
return (
<DropdownMenu buttonChildren="Dropdown Menu">
<MenuItemFileInput
onChange={(event) => {
// do something
handleUpload(event.currentTarget.files[0]);
}}
>
Upload
</MenuItemFileInput>
</DropdownMenu>
);
}
describe("Test", () => {
it("should be able to trigger the change event", async () => {
const user = userEvent.setup();
rmdRender(<Test />);
await user.click(screen.getByRole("button", { name: "Dropdown Menu" }));
const menuItem = screen.getByRole("menuitem", { name: "Upload" });
const file = new File(["example-content"], "README.md");
await uploadMenuItemFileInput({
user,
menuItem,
// this could also be a list of files if multiple files should be uploaded
files: file,
});
// expect the files to be uploaded
expect(handleChange).toHaveBeenCalledWith(file);
});
});
import { describe, expect, it } from "@jest/globals";
import { DropdownMenu } from "@react-md/core/menu/DropdownMenu";
import { MenuItemRadio } from "@react-md/core/menu/MenuItemRadio";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
const decorations = ["none", "underline", "overline", "strike-through"];
function Test() {
const { getRadioProps } = useRadioGroup({
menu: true,
defaultValue: "none",
});
return (
<DropdownMenu buttonChildren="Radio">
{decorations.map((decoration) => (
<MenuItemRadio key={decoration} {...getRadioProps(decoration)}>
{decoration}
</MenuItemRadio>
))}
</DropdownMenu>
);
}
describe("Test", () => {
it("should be able to trigger the change event", async () => {
const user = userEvent.setup();
rmdRender(<Test />);
const toggle = screen.getByRole("button", { name: "Dropdown Menu" });
await user.click(toggle);
let none = screen.getByRole("menuitemradio", { name: "none" });
let underline = screen.getByRole("menuitemradio", { name: "underline" });
let overline = screen.getByRole("menuitemradio", { name: "overline" });
let strikeThrough = screen.getByRole("menuitemradio", {
name: "strike-through",
});
expect(none).toBeChecked();
expect(underline).not.toBeChecked();
expect(overline).not.toBeChecked();
expect(strikeThrough).not.toBeChecked();
await user.click(overline);
// the menu has closed
expect(none).not.toBeInTheDocument();
expect(underline).not.toBeInTheDocument();
expect(overline).not.toBeInTheDocument();
expect(strikeThrough).not.toBeInTheDocument();
await user.click(toggle);
// can also just find them using the `getAllByRole`
[none, underline, overline, strikeThrough] =
screen.getAllByRole("menuitemradio");
expect(none).not.toBeChecked();
expect(underline).not.toBeChecked();
expect(overline).toBeChecked();
expect(strikeThrough).not.toBeChecked();
});
});
import { describe, expect, it } from "@jest/globals";
import { DropdownMenu } from "@react-md/core/menu/DropdownMenu";
import { MenuItemSwitch } from "@react-md/core/menu/MenuItemSwitch";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
import { useState } from "react";
function Test() {
const [checked, setChecked] = useState(false);
return (
<DropdownMenu buttonChildren="Toggle">
<MenuItemSwitch
checked={checked}
onCheckedChange={(checked) => setChecked(checked)}
>
Mute
</MenuItemSwitch>
</DropdownMenu>
);
}
describe("Test", () => {
it("should be able to change the checked state", async () => {
const user = userEvent.setup();
rmdRender(<Test />);
const toggle = screen.getByRole("button", { name: "Toggle" });
await user.click(toggle);
const mute = screen.getByRole("menuitemcheckbox", { name: "Mute" });
expect(mute).not.toBeChecked();
await user.click(mute);
// the menu has closed
expect(mute).not.toBeInTheDocument();
await user.click(toggle);
expect(
screen.getByRole("menuitemcheckbox", { name: "Mute" })
).toBeChecked();
});
});
import { describe, expect, it } from "@jest/globals";
import { isElementVisible } from "@react-md/core/utils/isElementVisible";
import SimpleExample from "@/components/tabs/SimpleExample.jsx"
describe("SimpleExample", () => {
it("should be able to change the active tab panel when clicking on a tab", async () => {
const user = userEvent.setup();
rmdRender(<SimpleExample />);
const tab1 = screen.getByRole("tab", { name: "Tab 1" });
const tab2 = screen.getByRole("tab", { name: "Tab 2" });
const tab3 = screen.getByRole("tab", { name: "Tab 3" });
const panel1 = screen.getByRole("tabpanel", { name: "Tab 1" });
const panel2 = screen.getByRole("tabpanel", { name: "Tab 2" });
const panel3 = screen.getByRole("tabpanel", { name: "Tab 3" });
expect(tab1).toHaveAttribute("aria-selected", "true");
expect(tab2).toHaveAttribute("aria-selected", "false");
expect(tab3).toHaveAttribute("aria-selected", "false");
expect(isElementVisible(panel1)).toBe(true);
expect(isElementVisible(panel2)).toBe(false);
expect(isElementVisible(panel3)).toBe(false);
await user.click(tab2);
expect(tab1).toHaveAttribute("aria-selected", "false");
expect(tab2).toHaveAttribute("aria-selected", "true");
expect(tab3).toHaveAttribute("aria-selected", "false");
expect(isElementVisible(panel1)).toBe(false);
expect(isElementVisible(panel2)).toBe(true);
expect(isElementVisible(panel3)).toBe(false);
});
});
import { describe, expect, it } from "@jest/globals";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
import SingleSelectTree from "@/components/tree/SingleSelectTree.jsx";
describe("SingleSelectTree", () => {
it("should be able to verify the selected tree items", async () => {
const user = userEvent.setup();
rmdRender(<SingleSelectTree />);
// name is the `aria-label`
const tree = screen.getByRole("tree", { name: "Tree" });
const folder1 = screen.getByRole("treeitem", { name: "Folder 1" });
const folder2 = screen.getByRole("treeitem", { name: "Folder 2" });
expect(folder1).toHaveAttribute("aria-selected", "true");
expect(folder2).toHaveAttribute("aria-selected", "false");
await user.click(folder2);
expect(folder1).toHaveAttribute("aria-selected", "false");
expect(folder2).toHaveAttribute("aria-selected", "true");
});
});
import { describe, expect, it } from "@jest/globals";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
import SingleSelectTree from "@/components/tree/SingleSelectTree.jsx";
describe("SingleSelectTree", () => {
it("should be able to verify the expanded states", async () => {
const user = userEvent.setup();
rmdRender(<SingleSelectTree />);
const tree = screen.getByRole("tree", { name: "Tree" });
const folder1 = screen.getByRole("treeitem", { name: "Folder 1" });
const folder2 = screen.getByRole("treeitem", { name: "Folder 2" });
const subtrees = within(tree).getAllByRole("group");
// only `Folder 2` and `Folder 2 Child 2` have child items
expect(subtrees).toHaveLength(2);
const [folder2Subtree, folder2Child2Subtree] = subtrees;
// NOTE: This would error while not expanded if the `temporaryChildItems` prop was enabled.
// Also, this could be found by
// `within(folder2Subtree).getByRole("treeitem", { name: "Folder 2 Child 1" })`
// if there are items with the same name
const folder11 = screen.getByRole("treeitem", { name: "Folder 2 Child 1" });
expect(folder1).toHaveAttribute("aria-selected", "true");
expect(folder1).toHaveAttribute("aria-expanded", "false");
expect(folder2).toHaveAttribute("aria-selected", "false");
expect(folder2).toHaveAttribute("aria-expanded", "false");
expect(isElementVisible(folder11)).toBe(false);
expect(isElementVisible(folder2Subtree)).toBe(false);
expect(isElementVisible(folder2Child2Subtree)).toBe(false);
await user.click(folder2);
expect(folder1).toHaveAttribute("aria-selected", "false");
expect(folder1).toHaveAttribute("aria-expanded", "false");
expect(folder2).toHaveAttribute("aria-selected", "true");
expect(folder2).toHaveAttribute("aria-expanded", "true");
// due to timers, might to use `waitFor`
await waitFor(() => {
expect(isElementVisible(folder2Subtree)).toBe(true);
});
expect(isElementVisible(folder11)).toBe(true);
});
});
import { describe, expect, it } from "@jest/globals";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
import SimpleExample from "@/components/dialog/SimpleExample.jsx";
describe("SimpleExample", () => {
it("should be able to change the visibility", async () => {
const user = userEvent.setup();
rmdRender(<SimpleExample />);
// not required -- just show that the dialog isn't visible
expect(() => screen.getByRole("dialog")).toThrow();
const show = screen.getByRole("button", { name: "Show" });
await user.click(show);
const dialog = screen.getByRole("dialog", { name: "Simple Dialog" });
// do whatever you want to verify
// close the dialog by clicking the close button
await user.click(screen.getByRole("button", { name: "Close" }));
expect(dialog).not.toBeInTheDocument();
});
});
import { describe, expect, it } from "@jest/globals";
import { rmdRender, screen, userEvent } from "@react-md/core/test-utils";
import ExpansionPanelGroupExample from "@/components/expansion-panel/ExpansionPanelGroupExample.jsx";
describe("ExpansionPanelGroupExample", () => {
it("should be able to expand and collapse panels", async () => {
const user = userEvent.setup();
rmdRender(<ExpansionPanelGroupExample />);
const panel1 = screen.getByRole("button", { name: "Panel 1" });
const panel2 = screen.getByRole("button", { name: "Panel 2" });
const panel3 = screen.getByRole("button", { name: "Panel 3" });
const [panel1Contents, panel2Contents, panel3Contents] =
screen.getAllByRole("region");
expect(panel1).toHaveAttribute("aria-expanded", "false");
expect(panel2).toHaveAttribute("aria-expanded", "false");
expect(panel3).toHaveAttribute("aria-expanded", "false");
expect(panel1Contents).toBeInTheDocument();
expect(panel2Contents).toBeInTheDocument();
expect(panel3Contents).toBeInTheDocument();
expect(isElementVisible(panel1Contents)).toBe(false);
expect(isElementVisible(panel2Contents)).toBe(false);
expect(isElementVisible(panel3Contents)).toBe(false);
await user.click(panel3);
expect(panel1).toHaveAttribute("aria-expanded", "false");
expect(panel2).toHaveAttribute("aria-expanded", "false");
expect(panel3).toHaveAttribute("aria-expanded", "true");
expect(panel1Contents).toBeInTheDocument();
expect(panel2Contents).toBeInTheDocument();
expect(panel3Contents).toBeInTheDocument();
expect(isElementVisible(panel1Contents)).toBe(false);
expect(isElementVisible(panel2Contents)).toBe(false);
expect(isElementVisible(panel3Contents)).toBe(true);
});
});