Skip to content

Commit aa44d1d

Browse files
refactor(react): update menu tests to use RTL (#11872)
* refactor(react): update menu tests to rtl * chore(react): update snapshots Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
1 parent b80c37e commit aa44d1d

File tree

3 files changed

+90
-114
lines changed

3 files changed

+90
-114
lines changed

packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8470,7 +8470,7 @@ Map {
84708470
"type": "oneOf",
84718471
},
84728472
"target": Object {
8473-
"type": "element",
8473+
"type": "object",
84748474
},
84758475
"x": Object {
84768476
"args": Array [

packages/react/src/components/Menu/Menu-test.js

Lines changed: 88 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -6,134 +6,110 @@
66
*/
77

88
import React from 'react';
9-
import Menu, {
10-
MenuItem,
11-
MenuRadioGroup,
12-
MenuSelectableItem,
13-
MenuDivider,
14-
} from '../Menu';
15-
import { mount } from 'enzyme';
16-
17-
const prefix = 'cds';
9+
import Menu, { MenuItem } from '../Menu';
10+
import { render, screen } from '@testing-library/react';
11+
import userEvent from '@testing-library/user-event';
1812

1913
describe('Menu', () => {
2014
describe('renders as expected', () => {
21-
describe('menu', () => {
22-
it("isn't rendered when closed", () => {
23-
const wrapper = mount(<Menu />);
24-
expect(wrapper.getDOMNode()).toBe(null);
25-
});
26-
27-
it('receives the expected classes when opened', () => {
28-
const wrapper = mount(<Menu open />);
29-
const container = wrapper.getDOMNode();
30-
31-
expect(container.classList.contains(`${prefix}--menu`)).toBe(true);
32-
expect(container.classList.contains(`${prefix}--menu--open`)).toBe(
33-
true
34-
);
35-
});
15+
it('should place a className on the outermost element', () => {
16+
render(<Menu className="custom-class" open />);
17+
18+
expect(document.querySelector('.custom-class')).toBeDefined();
3619
});
3720

38-
describe('option', () => {
39-
it('receives the expected classes', () => {
40-
const wrapper = mount(<MenuItem label="Copy" />);
41-
const container = wrapper.childAt(0).childAt(0);
42-
43-
expect(container.hasClass(`${prefix}--menu-option`)).toBe(true);
44-
});
45-
46-
it('renders props.label', () => {
47-
const wrapper = mount(<MenuItem label="Copy" />);
48-
49-
expect(wrapper.find(`span.${prefix}--menu-option__label`).text()).toBe(
50-
'Copy'
51-
);
52-
expect(
53-
wrapper.find(`span.${prefix}--menu-option__label`).prop('title')
54-
).toBe('Copy');
55-
});
56-
57-
it('renders props.shortcut when provided', () => {
58-
const wrapper = mount(<MenuItem label="Copy" shortcut="⌘C" />);
59-
60-
expect(
61-
wrapper.find(`div.${prefix}--menu-option__info`).length
62-
).toBeGreaterThan(0);
63-
expect(wrapper.find(`div.${prefix}--menu-option__info`).text()).toBe(
64-
'⌘C'
65-
);
66-
});
67-
68-
it('respects props.disabled', () => {
69-
const wrapper = mount(<MenuItem label="Copy" disabled />);
70-
const content = wrapper.find(`div.${prefix}--menu-option__content`);
71-
72-
expect(
73-
content.hasClass(`${prefix}--menu-option__content--disabled`)
74-
).toBe(true);
75-
expect(
76-
wrapper.find(`li.${prefix}--menu-option`).prop('aria-disabled')
77-
).toBe(true);
78-
});
79-
80-
it('supports danger kind', () => {
81-
const wrapper = mount(<MenuItem label="Delete" kind="danger" />);
82-
const option = wrapper.find(`.${prefix}--menu-option`);
83-
84-
expect(option.hasClass(`${prefix}--menu-option--danger`)).toBe(true);
85-
});
86-
87-
it('renders props.children as submenu', () => {
88-
const wrapper = mount(
89-
<Menu open>
90-
<MenuItem label="Format">
91-
<MenuItem label="Bold" />
92-
<MenuItem label="Italic" />
93-
</MenuItem>
94-
</Menu>
95-
);
96-
97-
const level1 = wrapper.find(`li.${prefix}--menu-option`).at(0);
98-
99-
expect(level1.find(`ul.${prefix}--menu`).length).toBeGreaterThan(0);
100-
});
21+
it('should spread props onto ul', () => {
22+
render(<Menu data-testid="test-id" open />);
23+
24+
expect(screen.getByRole('menu')).toHaveAttribute(
25+
'data-testid',
26+
'test-id'
27+
);
10128
});
10229

103-
describe('radiogroup', () => {
104-
it('children have role "menuitemradio"', () => {
105-
const wrapper = mount(
106-
<MenuRadioGroup label="Share with" items={['None', 'All']} />
107-
);
108-
const options = wrapper.find(`li.${prefix}--menu-option`);
30+
it('have an id when one is provided', () => {
31+
render(<Menu id="test-id" open />);
10932

110-
expect(options.every('li[role="menuitemradio"]')).toBe(true);
111-
});
33+
expect(screen.getByRole('menu')).toHaveAttribute('id', 'test-id');
11234
});
11335

114-
describe('selectable', () => {
115-
it('has role "menuitemcheckbox"', () => {
116-
const wrapper = mount(<MenuSelectableItem label="Publish" />);
117-
const container = wrapper.childAt(0);
36+
it('should call onClose on key down', () => {
37+
const onClose = jest.fn();
38+
render(
39+
<Menu open onClose={onClose}>
40+
<MenuItem label="item" />
41+
</Menu>
42+
);
43+
44+
userEvent.type(screen.getByRole('menuitem'), '{enter}');
11845

119-
expect(container.prop('role')).toBe('menuitemcheckbox');
120-
});
46+
expect(onClose).toHaveBeenCalled();
12147
});
12248

123-
describe('divider', () => {
124-
it('receives the expected classes', () => {
125-
const wrapper = mount(<MenuDivider />);
126-
const container = wrapper.childAt(0);
49+
it('should call onClose on click', () => {
50+
const onClose = jest.fn();
51+
render(
52+
<Menu open onClose={onClose}>
53+
<MenuItem label="item" />
54+
</Menu>
55+
);
56+
57+
userEvent.click(screen.getByRole('menuitem'));
58+
59+
expect(onClose).toHaveBeenCalled();
60+
});
61+
62+
it('should be open if open is supplied', () => {
63+
render(<Menu open />);
64+
65+
expect(screen.getByRole('menu')).toBeInTheDocument();
66+
});
67+
68+
it('should change size based on size prop', () => {
69+
render(<Menu open size="lg" />);
70+
71+
expect(screen.getByRole('menu')).toHaveClass('cds--menu--lg');
72+
});
12773

128-
expect(container.hasClass(`${prefix}--menu-divider`)).toBe(true);
129-
});
74+
it('should append to target element', () => {
75+
const el = document.createElement('div');
76+
document.body.appendChild(el);
77+
el.classList.add('custom-class');
78+
render(<Menu open target={el} />);
79+
80+
expect(document.querySelector('.custom-class')).toBeInTheDocument();
81+
document.body.removeChild(el);
82+
});
83+
});
84+
});
85+
86+
describe('MenuItem', () => {
87+
describe('renders as expected', () => {
88+
it('should be disabled', () => {
89+
render(<MenuItem label="item" disabled />);
90+
91+
expect(screen.getByRole('menuitem')).toHaveAttribute(
92+
'aria-disabled',
93+
'true'
94+
);
95+
96+
expect(screen.getByRole('menuitem')).toHaveClass(
97+
'cds--menu-option--disabled'
98+
);
99+
});
100+
101+
it('should change kind based on prop', () => {
102+
render(<MenuItem label="item" kind="danger" />);
103+
104+
expect(screen.getByRole('menuitem')).toHaveClass(
105+
'cds--menu-option--danger'
106+
);
107+
});
130108

131-
it('has role "separator"', () => {
132-
const wrapper = mount(<MenuDivider />);
133-
const container = wrapper.childAt(0);
109+
it('should render label', () => {
110+
render(<MenuItem label="item" />);
134111

135-
expect(container.prop('role')).toBe('separator');
136-
});
112+
expect(screen.getByText('item')).toBeInTheDocument();
137113
});
138114
});
139115
});

packages/react/src/components/Menu/Menu.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ Menu.propTypes = {
351351
/**
352352
* Optionally pass an element the Menu should be appended to as a child. Defaults to document.body.
353353
*/
354-
target: PropTypes.element,
354+
target: PropTypes.object,
355355

356356
/**
357357
* Specify the x position where this menu is rendered

0 commit comments

Comments
 (0)