/* * Copyright 2015 Palantir Technologies, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { mount, type ReactWrapper, shallow, type ShallowWrapper } from "enzyme"; import { assert, describe, expect, it, vi } from "@blueprintjs/test-commons/vitest"; import { Classes } from "../../common"; import { Button } from "../button/buttons"; import { Icon } from "../icon/icon"; import { PopoverInteractionKind } from "../popover/popoverProps"; import { PopoverNext } from "../popover-next/popoverNext"; import { Text } from "../text/text"; import { type MenuProps } from "./menu"; import { MenuItem, type MenuItemProps } from "./menuItem"; describe("MenuItem", () => { it("basic rendering", () => { const wrapper = shallow(); assert.isTrue(wrapper.find(Icon).exists()); assert.strictEqual(findText(wrapper).text(), "Graph"); }); it("supports HTML props", () => { const mouseHandler = (_event: React.MouseEvent) => false; const keyHandler = (_event: React.KeyboardEvent) => false; const item = shallow( , ).find("a"); assert.strictEqual(item.prop("onClick"), mouseHandler); assert.strictEqual(item.prop("onKeyDown"), keyHandler); assert.strictEqual(item.prop("onMouseMove"), mouseHandler); }); it("children appear in submenu", () => { const wrapper = shallow( , ); const submenu = findSubmenu(wrapper); assert.lengthOf(submenu.props.children, 3); }); it("default role prop structure is correct for a menuitem that is a an item of a ul with role=menu", () => { const wrapper = mount(); assert.equal(wrapper.find("li").prop("role"), "none"); assert.equal(wrapper.find("a").prop("role"), "menuitem"); }); it("can set roleStructure to change role prop structure to that of a listbox or select item", () => { const wrapper = mount(); assert.equal(wrapper.find("li").prop("role"), "option"); assert.isUndefined(wrapper.find("a").prop("role")); }); it("can set roleStructure to change role prop structure to that of a list item", () => { const wrapper = mount(); assert.isUndefined(wrapper.find("li").prop("role")); assert.isUndefined(wrapper.find("a").prop("role")); }); it('can set roleStructure to change role prop structure to void li role (set role="none")', () => { const wrapper = mount(); assert.equal(wrapper.find("li").prop("role"), "none"); assert.isUndefined(wrapper.find("a").prop("role")); }); it("disabled MenuItem will not show its submenu", () => { const wrapper = shallow( , ); assert.isTrue(wrapper.find(PopoverNext).prop("disabled")); }); it("disabled MenuItem blocks mouse listeners", () => { const mouseSpy = vi.fn(); mount() .simulate("click") .simulate("mouseenter") .simulate("click"); expect(mouseSpy).not.toHaveBeenCalled(); }); it("clicking MenuItem triggers onClick prop", () => { const onClick = vi.fn(); shallow() .find("a") .simulate("click"); expect(onClick).toHaveBeenCalledOnce(); }); it("pressing enter on MenuItem triggers onClick prop", async () => { const user = userEvent.setup(); const onClick = vi.fn(); render(); const menuItem = screen.getByRole("menuitem"); menuItem.focus(); await user.keyboard("{Enter}"); expect(onClick).toHaveBeenCalledOnce(); }); it("clicking disabled MenuItem does not trigger onClick prop", () => { const onClick = vi.fn(); shallow() .find("a") .simulate("click"); expect(onClick).not.toHaveBeenCalled(); }); it("shouldDismissPopover=false prevents a clicked MenuItem from closing the Popover automatically", () => { const handleClose = vi.fn(); const menu = ; const wrapper = mount(