Skip to content
18 changes: 8 additions & 10 deletions packages/lib/src/breadcrumbs/Breadcrumbs.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { fireEvent, render } from "@testing-library/react";
import DxcBreadcrumbs from "./Breadcrumbs";

global.ResizeObserver = jest.fn().mockImplementation(() => ({
Expand Down Expand Up @@ -39,7 +38,7 @@ describe("Breadcrumbs component tests", () => {
const dropdown = getByRole("button");
expect(queryByText("User Menu")).toBeFalsy();
expect(queryByText("Preferences")).toBeFalsy();
userEvent.click(dropdown);
fireEvent.click(dropdown);
expect(getByText("User Menu")).toBeTruthy();
expect(getByText("Preferences")).toBeTruthy();
});
Expand All @@ -51,7 +50,7 @@ describe("Breadcrumbs component tests", () => {
expect(queryByText("Home")).toBeFalsy();
expect(queryByText("User Menu")).toBeFalsy();
expect(queryByText("Preferences")).toBeFalsy();
userEvent.click(dropdown);
fireEvent.click(dropdown);
expect(getByText("Home")).toBeTruthy();
expect(getByText("User Menu")).toBeTruthy();
expect(getByText("Preferences")).toBeTruthy();
Expand All @@ -73,7 +72,7 @@ describe("Breadcrumbs component tests", () => {
]}
/>
);
userEvent.click(getByText("Home"));
fireEvent.click(getByText("Home"));
expect(onItemClick).toHaveBeenCalledWith("/home");
});
test("The onClick prop from an item is properly called (collapsed)", () => {
Expand All @@ -89,8 +88,8 @@ describe("Breadcrumbs component tests", () => {
itemsBeforeCollapse={2}
/>
);
userEvent.click(getByRole("button"));
userEvent.click(getByText("Preferences"));
fireEvent.click(getByRole("button"));
fireEvent.click(getByText("Preferences"));
expect(onItemClick).toHaveBeenCalledWith("/");
});
test("handleOnClick prevents default and calls onClick when href is provided", () => {
Expand All @@ -105,7 +104,7 @@ describe("Breadcrumbs component tests", () => {
/>
);
const homeLink = getByText("Home");
userEvent.click(homeLink);
fireEvent.click(homeLink);
expect(onItemClick).toHaveBeenCalledWith("/home");
});
test("handleOnMouseEnter sets title when text overflows", () => {
Expand All @@ -124,8 +123,7 @@ describe("Breadcrumbs component tests", () => {
Object.defineProperty(currentPageElement, "scrollWidth", { value: 200, configurable: true });
Object.defineProperty(currentPageElement, "clientWidth", { value: 100, configurable: true });

// Simulate mouse enter
userEvent.hover(currentPageElement);
fireEvent.mouseEnter(currentPageElement);

// Check if title is set when there's overflow
expect(currentPageElement.title).toBe("Very Long Current Page Label That Should Overflow");
Expand Down
43 changes: 24 additions & 19 deletions packages/lib/src/contextual-menu/ContextualMenu.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ const groups = [
];

describe("Contextual menu component tests", () => {
test("Single — Renders with correct aria attributes", () => {
test("Single — Renders with correct aria attributes", async () => {
const user = userEvent.setup();
const { getAllByRole, getByRole } = render(<DxcContextualMenu items={items} />);
expect(getAllByRole("menuitem").length).toBe(4);
const actions = getAllByRole("button");
if (actions[0] != null) {
userEvent.click(actions[0]);
await user.click(actions[0]);
}
expect(actions[0]?.getAttribute("aria-pressed")).toBeTruthy();
expect(getByRole("menu")).toBeTruthy();
Expand All @@ -52,39 +53,41 @@ describe("Contextual menu component tests", () => {
const item = getByRole("button");
expect(item.getAttribute("aria-pressed")).toBeTruthy();
});
test("Group — Group items collapse when clicked", () => {
test("Group — Group items collapse when clicked", async () => {
const user = userEvent.setup();
const { queryByText, getByText } = render(<DxcContextualMenu items={groups} />);
userEvent.click(getByText("Grouped Item 1"));
await user.click(getByText("Grouped Item 1"));
expect(getByText("Item 1")).toBeTruthy();
expect(getByText("Grouped Item 2")).toBeTruthy();
userEvent.click(getByText("Grouped Item 2"));
await user.click(getByText("Grouped Item 2"));
expect(getByText("Item 2")).toBeTruthy();
expect(getByText("Item 3")).toBeTruthy();
userEvent.click(getByText("Grouped Item 1"));
await user.click(getByText("Grouped Item 1"));
expect(queryByText("Item 1")).toBeFalsy();
expect(queryByText("Item 2")).toBeFalsy();
expect(queryByText("Item 3")).toBeFalsy();
});
test("Group — Renders with correct aria attributes", () => {
test("Group — Renders with correct aria attributes", async () => {
const user = userEvent.setup();
const { getAllByRole } = render(<DxcContextualMenu items={groups} />);
const group1 = getAllByRole("button")[0];
if (group1 != null) {
userEvent.click(group1);
await user.click(group1);
}
expect(group1?.getAttribute("aria-expanded")).toBeTruthy();
expect(group1?.getAttribute("aria-controls")).toBe(group1?.nextElementSibling?.id);
const expandedGroupItem1 = getAllByRole("button")[2];
if (expandedGroupItem1 != null) {
userEvent.click(expandedGroupItem1);
await user.click(expandedGroupItem1);
}
const expandedGroupedItem2 = getAllByRole("button")[6];
if (expandedGroupedItem2 != null) {
userEvent.click(expandedGroupedItem2);
await user.click(expandedGroupedItem2);
}
expect(getAllByRole("menuitem").length).toBe(10);
const optionToBeClicked = getAllByRole("button")[4];
if (optionToBeClicked != null) {
userEvent.click(optionToBeClicked);
await user.click(optionToBeClicked);
}
expect(optionToBeClicked?.getAttribute("aria-pressed")).toBeTruthy();
});
Expand All @@ -99,39 +102,41 @@ describe("Contextual menu component tests", () => {
expect(getByText("Tested item")).toBeTruthy();
expect(getAllByRole("button")[1]?.getAttribute("aria-pressed")).toBeTruthy();
});
test("Group — Collapsed groups render as selected when containing a selected item", () => {
test("Group — Collapsed groups render as selected when containing a selected item", async () => {
const user = userEvent.setup();
const { getAllByRole } = render(<DxcContextualMenu items={groups} />);
const group1 = getAllByRole("button")[0];
if (group1 != null) {
userEvent.click(group1);
await user.click(group1);
}
const group2 = getAllByRole("button")[2];
if (group2 != null) {
userEvent.click(group2);
await user.click(group2);
}
const item = getAllByRole("button")[3];
if (item != null) {
userEvent.click(item);
await user.click(item);
}
expect(item?.getAttribute("aria-pressed")).toBeTruthy();
expect(group1?.getAttribute("aria-pressed")).toBe("false");
expect(group2?.getAttribute("aria-pressed")).toBe("false");
if (group2 != null) {
userEvent.click(group2);
await user.click(group2);
}
expect(group2?.getAttribute("aria-pressed")).toBe("true");
if (group1 != null) {
userEvent.click(group1);
await user.click(group1);
}
expect(group1?.getAttribute("aria-pressed")).toBe("true");
});
test("Sections — Renders with correct aria attributes", () => {
test("Sections — Renders with correct aria attributes", async () => {
const user = userEvent.setup();
const { getAllByRole, getByText } = render(<DxcContextualMenu items={sections} />);
expect(getAllByRole("region").length).toBe(2);
expect(getAllByRole("menuitem").length).toBe(6);
const actions = getAllByRole("button");
if (actions[0] != null) {
userEvent.click(actions[0]);
await user.click(actions[0]);
}
expect(actions[0]?.getAttribute("aria-pressed")).toBeTruthy();
expect(getAllByRole("menu").length).toBe(2);
Expand Down
66 changes: 32 additions & 34 deletions packages/lib/src/dialog/Dialog.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fireEvent, render, waitFor } from "@testing-library/react";
import { fireEvent, render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import DxcButton from "../button/Button";
import DxcCard from "../card/Card";
Expand Down Expand Up @@ -76,7 +76,7 @@ describe("Dialog component tests", () => {
</DxcDialog>
);
const calendarAction = getByRole("combobox");
userEvent.click(calendarAction);
fireEvent.click(calendarAction);
fireEvent.keyDown(document.activeElement!, {
key: "Escape",
code: "Escape",
Expand All @@ -88,14 +88,15 @@ describe("Dialog component tests", () => {
});

describe("Dialog component: Focus lock tests", () => {
test("Close action: when there's no focusable content, the focus never leaves the close action (unless you click outside)", () => {
test("Close action: when there's no focusable content, the focus never leaves the close action (unless you click outside)", async () => {
const user = userEvent.setup({ delay: null });
const onClick = jest.fn();
const { getByRole } = render(<DxcDialog onCloseClick={onClick}>example-dialog</DxcDialog>);
const button = getByRole("button");
const dialog = getByRole("dialog");
expect(document.activeElement).toEqual(button);
expect(button.getAttribute("aria-label")).toBe("Close dialog");
userEvent.tab();
await user.tab();
expect(document.activeElement).toEqual(button);
fireEvent.keyDown(dialog, { key: "Tab", shiftKey: true });
expect(document.activeElement).toEqual(button);
Expand Down Expand Up @@ -202,9 +203,12 @@ describe("Dialog component: Focus lock tests", () => {
const inputs = getAllByRole("textbox");
const button = getByRole("button");
expect(document.activeElement).toEqual(inputs[1]);
userEvent.tab();
const focusGuards = getByRole("dialog").querySelectorAll<HTMLDivElement>(":scope > div[tabindex='0']");
expect(focusGuards).toHaveLength(2);

fireEvent.focus(focusGuards[0]!);
expect(document.activeElement).toEqual(button);
userEvent.tab();
fireEvent.focus(focusGuards[1]!);
expect(document.activeElement).toEqual(inputs[1]);
});
test("Focus jumps disabled components and negative tabIndexes when autofocusing first item", () => {
Expand Down Expand Up @@ -238,13 +242,16 @@ describe("Dialog component: Focus lock tests", () => {
const closeAction = getByRole("button");
const textarea = getByRole("textbox");
expect(document.activeElement).toEqual(textarea);
userEvent.tab();
userEvent.tab();
const focusGuards = getByRole("dialog").querySelectorAll<HTMLDivElement>(":scope > div[tabindex='0']");
expect(focusGuards).toHaveLength(2);

fireEvent.focus(focusGuards[0]!);
expect(document.activeElement).toEqual(closeAction);
userEvent.tab();
fireEvent.focus(focusGuards[1]!);
expect(document.activeElement).toEqual(textarea);
});
test("'display: none;', 'visibility: hidden;' and 'type = 'hidden'' elements are never autofocused", () => {
test("'display: none;', 'visibility: hidden;' and 'type = 'hidden'' elements are never autofocused", async () => {
const user = userEvent.setup({ delay: null });
// TODO: Solve this
// If we don't have an Onclick function, the Close Icon will be a <div> instead of a <button>, so it won't be focusable.
const onClick = jest.fn();
Expand All @@ -257,10 +264,11 @@ describe("Dialog component: Focus lock tests", () => {
);
const closeAction = getByRole("button");
expect(document.activeElement).toEqual(closeAction);
userEvent.tab();
await user.tab();
expect(document.activeElement).toEqual(closeAction);
});
test("Focus gets trapped in the Dialog when there are not focusable elements inside until it is closed", () => {
test("Focus gets trapped in the Dialog when there are not focusable elements inside until it is closed", async () => {
const user = userEvent.setup({ delay: null });
const { getAllByRole, getByRole } = render(
<>
<DxcTextInput label="Name" />
Expand All @@ -273,17 +281,16 @@ describe("Dialog component: Focus lock tests", () => {
);
const inputs = getAllByRole("textbox");
const dialog = getByRole("dialog");
userEvent.tab();
userEvent.tab();
await user.tab();
await user.tab();
expect(document.activeElement).not.toEqual(inputs[1]);
fireEvent.keyDown(dialog, { key: "Tab", shiftKey: true });
fireEvent.keyDown(dialog, { key: "Tab", shiftKey: true });
expect(document.activeElement).not.toEqual(inputs[0]);
});
test("Focus travels correctly in a complex tab sequence", async () => {
const onClick = jest.fn();
const { getAllByRole, queryByRole, getByRole } = render(
<DxcDialog onCloseClick={onClick}>
test("Focus guards wrap focus correctly in a complex dialog", () => {
const { getAllByRole, getByRole } = render(
<DxcDialog onCloseClick={jest.fn()}>
<DxcSelect label="Accept" options={options} />
<DxcDateInput label="Older age" />
<DxcTooltip label="Text input tooltip label">
Expand All @@ -302,22 +309,13 @@ describe("Dialog component: Focus lock tests", () => {
);
const select = getAllByRole("combobox")[0];
expect(document.activeElement).toEqual(select);
userEvent.keyboard("{ArrowDown}");
expect(queryByRole("listbox")).toBeTruthy();
userEvent.tab();
userEvent.tab();
userEvent.tab();
await waitFor(() => expect(document.activeElement).toEqual(getByRole("textbox", { name: "Name" })));
userEvent.tab();
userEvent.tab();
expect(document.activeElement).toEqual(getByRole("button", { name: "Cancel" }));
userEvent.tab();
expect(document.activeElement).toEqual(getByRole("button", { name: "Save" }));
userEvent.tab();
userEvent.tab();
const focusGuards = getByRole("dialog").querySelectorAll<HTMLDivElement>(":scope > div[tabindex='0']");
expect(focusGuards).toHaveLength(2);

fireEvent.focus(focusGuards[1]!);
expect(document.activeElement).toEqual(select);
userEvent.tab({ shift: true });
userEvent.tab({ shift: true });
expect(getByRole("button", { name: "Save" })).toBeTruthy();

fireEvent.focus(focusGuards[0]!);
expect(document.activeElement).toEqual(getByRole("button", { name: "Close dialog" }));
});
});
Loading
Loading