UNPKG

@octopusdeploy/design-system-components

Version:
152 lines (151 loc) • 7.73 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const testing_library_1 = require("@octopusdeploy/testing-library"); const react_1 = require("@testing-library/react"); const vitest_1 = require("vitest"); const MenuList_1 = require("../../../MenuList/MenuList"); const TestDesignSystemProvider_1 = require("../../../TestDesignSystemProvider"); const SimpleMenuItems_1 = require("../../SimpleMenuItems"); (0, vitest_1.describe)("NestedMenu", () => { (0, vitest_1.test)("entire menu is closed when any nested item is clicked", async () => { const buttonMenuItem = createButton("my button"); const nestedMenuItem = createNestedMenu("nested menu", [buttonMenuItem]); const menu = renderMenu([nestedMenuItem]); const nestedMenu = await menu.clickNestedMenu(nestedMenuItem); await nestedMenu.clickButton(buttonMenuItem); nestedMenu.assertButtonWasClicked(buttonMenuItem); menu.assertMenuWasClosed(); }); (0, vitest_1.test)("first item is focused when menu is expanded", async () => { const firstButtonMenuItem = createButton("first button"); const secondButtonMenuItem = createButton("second button"); const nestedMenuItem = createNestedMenu("nested menu", [firstButtonMenuItem, secondButtonMenuItem]); const menu = renderMenu([nestedMenuItem]); const nestedMenu = await menu.clickNestedMenu(nestedMenuItem); await nestedMenu.assertItemIsFocused(firstButtonMenuItem); }); (0, vitest_1.describe)("keyboard interactions", () => { const firstItem = createButton("first"); const secondItem = createButton("second"); const thirdItem = createButton("third"); const nestedMenuItem = createNestedMenu("nested menu", [firstItem, secondItem, thirdItem]); async function renderAndOpenNestedMenu() { const menu = renderMenu([nestedMenuItem]); const nestedMenu = await menu.clickNestedMenu(nestedMenuItem); return { menu, nestedMenu }; } (0, vitest_1.test)("keydown cycles through focused items", async () => { const { nestedMenu } = await renderAndOpenNestedMenu(); await nestedMenu.pressDownKey(); await nestedMenu.assertItemIsFocused(secondItem); }); (0, vitest_1.test)("when focused at the bottom of the list, keydown causes focus to wrap around to the top", async () => { const { nestedMenu } = await renderAndOpenNestedMenu(); await nestedMenu.pressDownKey(); // second item is focused await nestedMenu.pressDownKey(); // third item is focused await nestedMenu.pressDownKey(); // first item should be focused again await nestedMenu.assertItemIsFocused(firstItem); }); (0, vitest_1.test)("when focused at the top of the list, keyup causes focus to wrap around to the bottom", async () => { const { nestedMenu } = await renderAndOpenNestedMenu(); await nestedMenu.pressUpKey(); await nestedMenu.assertItemIsFocused(thirdItem); }); (0, vitest_1.test)("keyup cycles up through the focused items", async () => { const { nestedMenu } = await renderAndOpenNestedMenu(); await nestedMenu.pressDownKey(); // second item is focused await nestedMenu.pressUpKey(); // first item is focused again await nestedMenu.assertItemIsFocused(firstItem); }); (0, vitest_1.test)("home key focuses the first item", async () => { const { nestedMenu } = await renderAndOpenNestedMenu(); await nestedMenu.pressDownKey(); // focus something else await nestedMenu.pressHomeKey(); await nestedMenu.assertItemIsFocused(firstItem); }); (0, vitest_1.test)("end key focuses the last item", async () => { const { nestedMenu } = await renderAndOpenNestedMenu(); await nestedMenu.pressEndKey(); await nestedMenu.assertItemIsFocused(thirdItem); }); (0, vitest_1.test)("typing an items name will focus that item", async () => { const { nestedMenu } = await renderAndOpenNestedMenu(); await nestedMenu.type(thirdItem.label.substr(0, 2)); await nestedMenu.assertItemIsFocused(thirdItem); }); (0, vitest_1.test)("Escape closes the entire menu", async () => { const { nestedMenu, menu } = await renderAndOpenNestedMenu(); nestedMenu.assertMenuIsVisible(); await nestedMenu.pressEscape(); await nestedMenu.assertMenuIsNotVisible(); menu.assertMenuWasClosed(); }); }); }); function createButton(label) { return { type: "button", label, onClick: vitest_1.vi.fn(), }; } function createNestedMenu(label, children) { return { type: "nested-menu", children, label, }; } function renderMenu(menuItems) { // We need to use a MenuList here to ensure this component works with the keyboard interactions that are provided by MenuList const onClose = vitest_1.vi.fn(); const rootMenuAccessibleName = "root menu"; (0, react_1.render)((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsx)(MenuList_1.MenuList, { accessibleName: rootMenuAccessibleName, children: (0, jsx_runtime_1.jsx)(SimpleMenuItems_1.SimpleMenuItems, { items: menuItems, onClose: onClose }) }) })); return new RootMenuInteractions(onClose, rootMenuAccessibleName); } class MenuInteractions { menuAccessibleName; constructor(menuAccessibleName) { this.menuAccessibleName = menuAccessibleName; } clickNestedMenu = async (nestedMenu) => { await this.getMenu().getMenuItem(nestedMenu.label).click(); return new MenuInteractions(nestedMenu.label); }; clickButton = async (button) => await this.getMenu().getMenuItem(button.label).click(); getMenu = () => testing_library_1.domQueries.getMenu(this.menuAccessibleName); queryMenu = () => testing_library_1.domQueries.queryMenu(this.menuAccessibleName); assertButtonWasClicked = (button) => (0, vitest_1.expect)(button.onClick).toHaveBeenCalled(); assertItemIsFocused = async (button) => { await testing_library_1.domQueries.getActiveElement().click(); this.assertButtonWasClicked(button); }; type = async (textToType) => { await testing_library_1.domQueries.getActiveElement().type(textToType, { skipClick: true }); }; pressUpKey = async () => await pressSpecialKey("ArrowUp"); pressDownKey = async () => await pressSpecialKey("ArrowDown"); pressHomeKey = async () => await pressSpecialKey("Home"); pressEndKey = async () => await pressSpecialKey("End"); pressEscape = async () => await pressSpecialKey("Escape"); assertMenuIsVisible = () => this.getMenu().assertIsInTheDocument(); assertMenuIsNotVisible = async () => { const menu = this.queryMenu(); if (menu.innerElement) { await (0, react_1.waitForElementToBeRemoved)(menu.innerElement); } menu.assertIsNotInTheDocument(); }; } class RootMenuInteractions extends MenuInteractions { onClose; constructor(onClose, menuAccessibleName) { super(menuAccessibleName); this.onClose = onClose; } assertMenuWasClosed = () => (0, vitest_1.expect)(this.onClose).toHaveBeenCalled(); } async function pressSpecialKey(key) { await testing_library_1.domQueries.getActiveElement().type(`{${key}}`, { skipClick: true }); }