addons/shared/__tests__/ContextMenu.test.tsxblame
View source
b69ab311/**
b69ab312 * Copyright (c) Meta Platforms, Inc. and affiliates.
b69ab313 *
b69ab314 * This source code is licensed under the MIT license found in the
b69ab315 * LICENSE file in the root directory of this source tree.
b69ab316 *
b69ab317 * @jest-environment jsdom
b69ab318 */
b69ab319
b69ab3110import '@testing-library/jest-dom';
b69ab3111import {act, fireEvent, render, screen} from '@testing-library/react';
b69ab3112import {Provider} from 'jotai';
b69ab3113import {ContextMenus, useContextMenu} from '../ContextMenu';
b69ab3114
b69ab3115const onClick1 = jest.fn();
b69ab3116const onClick2 = jest.fn();
b69ab3117
b69ab3118function TestComponent() {
b69ab3119 const menu = useContextMenu(() => [
b69ab3120 {label: 'Context item 1', onClick: onClick1},
b69ab3121 {label: 'Context item 2', onClick: onClick2},
b69ab3122 ]);
b69ab3123 return (
b69ab3124 <div data-testid="test-component" onContextMenu={menu}>
b69ab3125 Hello click me
b69ab3126 </div>
b69ab3127 );
b69ab3128}
b69ab3129
b69ab3130function TestApp() {
b69ab3131 return (
b69ab3132 <Provider>
b69ab3133 <div>
b69ab3134 <TestComponent />
b69ab3135 <ContextMenus />
b69ab3136 </div>
b69ab3137 </Provider>
b69ab3138 );
b69ab3139}
b69ab3140
b69ab3141function rightClick(el: HTMLElement) {
b69ab3142 fireEvent.contextMenu(el);
b69ab3143}
b69ab3144
b69ab3145describe('Context Menu', () => {
b69ab3146 it('shows context menu items on right click', () => {
b69ab3147 render(<TestApp />);
b69ab3148
b69ab3149 act(() => {
b69ab3150 const component = screen.getByTestId('test-component');
b69ab3151 rightClick(component);
b69ab3152 });
b69ab3153
b69ab3154 expect(screen.getByText('Context item 1')).toBeInTheDocument();
b69ab3155 expect(screen.getByText('Context item 2')).toBeInTheDocument();
b69ab3156 });
b69ab3157
b69ab3158 it('runs callbacks on clicking an item', () => {
b69ab3159 render(<TestApp />);
b69ab3160
b69ab3161 act(() => {
b69ab3162 const component = screen.getByTestId('test-component');
b69ab3163 rightClick(component);
b69ab3164 });
b69ab3165
b69ab3166 act(() => {
b69ab3167 fireEvent.click(screen.getByText('Context item 1'));
b69ab3168 });
b69ab3169 expect(onClick1).toHaveBeenCalled();
b69ab3170 expect(onClick2).not.toHaveBeenCalled();
b69ab3171 });
b69ab3172
b69ab3173 it('dismisses on escape key', () => {
b69ab3174 render(<TestApp />);
b69ab3175
b69ab3176 act(() => {
b69ab3177 const component = screen.getByTestId('test-component');
b69ab3178 rightClick(component);
b69ab3179 });
b69ab3180
b69ab3181 act(() => {
b69ab3182 fireEvent.keyUp(window, {key: 'Escape'});
b69ab3183 });
b69ab3184
b69ab3185 expect(screen.queryByText('Context item 1')).not.toBeInTheDocument();
b69ab3186 expect(screen.queryByText('Context item 2')).not.toBeInTheDocument();
b69ab3187 });
b69ab3188
b69ab3189 it('dismisses on click outside', () => {
b69ab3190 render(<TestApp />);
b69ab3191
b69ab3192 act(() => {
b69ab3193 const component = screen.getByTestId('test-component');
b69ab3194 rightClick(component);
b69ab3195 });
b69ab3196
b69ab3197 act(() => {
b69ab3198 fireEvent.click(screen.getByTestId('test-component'));
b69ab3199 });
b69ab31100
b69ab31101 expect(screen.queryByText('Context item 1')).not.toBeInTheDocument();
b69ab31102 expect(screen.queryByText('Context item 2')).not.toBeInTheDocument();
b69ab31103 });
b69ab31104});