Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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