Skip to content

Commit acc4ac9

Browse files
committed
fix: drawers.test.tsx
1 parent b588832 commit acc4ac9

File tree

1 file changed

+102
-66
lines changed

1 file changed

+102
-66
lines changed

src/app-layout/__tests__/drawers.test.tsx

Lines changed: 102 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33
import React from 'react';
4-
import { act, fireEvent, render } from '@testing-library/react';
4+
import { act, fireEvent, render, waitFor } from '@testing-library/react';
55

66
import { KeyCode } from '@cloudscape-design/test-utils-core/utils.js';
77

@@ -32,9 +32,11 @@ jest.mock('@cloudscape-design/component-toolkit', () => ({
3232
}));
3333

3434
describeEachAppLayout(({ size, theme }) => {
35-
test(`should not render drawer when it is not defined`, () => {
35+
test(`should not render drawer when it is not defined`, async () => {
3636
const { wrapper, rerender } = renderComponent(<AppLayout toolsHide={true} drawers={[testDrawer]} />);
37-
expect(wrapper.findDrawersTriggers()).toHaveLength(1);
37+
await waitFor(() => {
38+
expect(wrapper.findDrawersTriggers()).toHaveLength(1);
39+
});
3840
rerender(<AppLayout />);
3941

4042
expect(wrapper.findDrawersTriggers()).toHaveLength(0);
@@ -48,67 +50,77 @@ describeEachAppLayout(({ size, theme }) => {
4850
expect(wrapper.findToolsToggle()).toBeFalsy();
4951
});
5052

51-
test('ignores tools when drawers API is used', () => {
53+
test('ignores tools when drawers API is used', async () => {
5254
const { wrapper } = renderComponent(<AppLayout tools="Test" drawers={[testDrawer]} />);
5355

54-
expect(wrapper.findToolsToggle()).toBeFalsy();
56+
await waitFor(() => {
57+
expect(wrapper.findToolsToggle()).toBeFalsy();
58+
});
5559
expect(wrapper.findDrawersTriggers()).toHaveLength(1);
5660
});
5761

58-
test('should open active drawer on click of overflow item', () => {
62+
test('should open active drawer on click of overflow item', async () => {
5963
const { wrapper } = renderComponent(<AppLayout drawers={manyDrawers} />);
60-
const buttonDropdown = wrapper.findDrawersOverflowTrigger();
6164

62-
expect(wrapper.findActiveDrawer()).toBeFalsy();
63-
buttonDropdown!.openDropdown();
64-
buttonDropdown!.findItemById('5')!.click();
65-
expect(wrapper.findActiveDrawer()).toBeTruthy();
65+
await waitFor(() => {
66+
const buttonDropdown = wrapper.findDrawersOverflowTrigger();
67+
expect(wrapper.findActiveDrawer()).toBeFalsy();
68+
buttonDropdown!.openDropdown();
69+
buttonDropdown!.findItemById('5')!.click();
70+
expect(wrapper.findActiveDrawer()).toBeTruthy();
71+
});
6672
});
6773

68-
test('renders correct aria-label on overflow menu', () => {
74+
test('renders correct aria-label on overflow menu', async () => {
6975
const ariaLabels: AppLayoutProps.Labels = {
7076
drawersOverflow: 'Overflow drawers',
7177
drawersOverflowWithBadge: 'Overflow drawers (Unread notifications)',
7278
};
7379
const { wrapper, rerender } = renderComponent(<AppLayout drawers={manyDrawers} ariaLabels={ariaLabels} />);
74-
const buttonDropdown = wrapper.findDrawersOverflowTrigger();
7580

76-
expect(buttonDropdown!.findNativeButton().getElement()).toHaveAttribute('aria-label', 'Overflow drawers');
81+
await waitFor(() => {
82+
const buttonDropdown = wrapper.findDrawersOverflowTrigger();
83+
expect(buttonDropdown!.findNativeButton().getElement()).toHaveAttribute('aria-label', 'Overflow drawers');
84+
});
7785

86+
const buttonDropdown = wrapper.findDrawersOverflowTrigger();
7887
rerender(<AppLayout drawers={manyDrawersWithBadges} ariaLabels={ariaLabels} />);
7988
expect(buttonDropdown!.findNativeButton().getElement()).toHaveAttribute(
8089
'aria-label',
8190
'Overflow drawers (Unread notifications)'
8291
);
8392
});
8493

85-
test('overflow menu item have aria-role set to `menuitem`', () => {
94+
test('overflow menu item have aria-role set to `menuitem`', async () => {
8695
const { wrapper } = renderComponent(<AppLayout drawers={manyDrawers} />);
87-
const buttonDropdown = wrapper.findDrawersOverflowTrigger();
88-
89-
buttonDropdown!.openDropdown();
9096

91-
const countItems = buttonDropdown!.findItems();
92-
const countRoleMenuItemRole = buttonDropdown!
93-
.findOpenDropdown()!
94-
.find('[role="menu"]')!
95-
.findAll('[role="menuitem"]');
97+
await waitFor(() => {
98+
const buttonDropdown = wrapper.findDrawersOverflowTrigger();
99+
buttonDropdown!.openDropdown();
100+
const countItems = buttonDropdown!.findItems();
101+
const countRoleMenuItemRole = buttonDropdown!
102+
.findOpenDropdown()!
103+
.find('[role="menu"]')!
104+
.findAll('[role="menuitem"]');
96105

97-
expect(countItems.length).toBe(countRoleMenuItemRole.length);
106+
expect(countItems.length).toBe(countRoleMenuItemRole.length);
107+
});
98108
});
99109

100-
test('renders aria-labels', () => {
110+
test('renders aria-labels', async () => {
101111
const { wrapper } = renderComponent(<AppLayout drawers={[testDrawer]} />);
102-
expect(wrapper.findDrawerTriggerById('security')!.getElement()).toHaveAttribute(
103-
'aria-label',
104-
'Security trigger button'
105-
);
112+
await waitFor(() => {
113+
expect(wrapper.findDrawerTriggerById('security')!.getElement()).toHaveAttribute(
114+
'aria-label',
115+
'Security trigger button'
116+
);
117+
});
106118
wrapper.findDrawerTriggerById('security')!.click();
107119
expect(findActiveDrawerLandmark(wrapper)!.getElement()).toHaveAttribute('aria-label', 'Security drawer content');
108120
expect(wrapper.findActiveDrawerCloseButton()!.getElement()).toHaveAttribute('aria-label', 'Security close button');
109121
});
110122

111-
test('renders resize only on resizable drawer', () => {
123+
test('renders resize only on resizable drawer', async () => {
112124
const { wrapper } = renderComponent(
113125
<AppLayout
114126
drawers={[
@@ -122,7 +134,9 @@ describeEachAppLayout(({ size, theme }) => {
122134
/>
123135
);
124136

125-
wrapper.findDrawerTriggerById('security')!.click();
137+
await waitFor(() => {
138+
wrapper.findDrawerTriggerById('security')!.click();
139+
});
126140
expect(wrapper.findActiveDrawerResizeHandle()).toBeFalsy();
127141

128142
wrapper.findDrawerTriggerById('security-resizable')!.click();
@@ -137,7 +151,7 @@ describeEachAppLayout(({ size, theme }) => {
137151
}
138152
});
139153

140-
test('focuses drawer close button', () => {
154+
test('focuses drawer close button', async () => {
141155
let ref: AppLayoutProps.Ref | null = null;
142156
const { wrapper } = renderComponent(
143157
<AppLayout
@@ -147,7 +161,9 @@ describeEachAppLayout(({ size, theme }) => {
147161
onDrawerChange={() => {}}
148162
/>
149163
);
150-
expect(wrapper.findActiveDrawer()).toBeTruthy();
164+
await waitFor(() => {
165+
expect(wrapper.findActiveDrawer()).toBeTruthy();
166+
});
151167
act(() => ref!.focusActiveDrawer());
152168
expect(wrapper.findActiveDrawerCloseButton()!.getElement()).toHaveFocus();
153169
});
@@ -178,23 +194,31 @@ describeEachAppLayout(({ size, theme }) => {
178194
expect(wrapper.findActiveDrawerCloseButton()!.getElement()).toHaveFocus();
179195
});
180196

181-
test('registers public drawers api', () => {
197+
test('registers public drawers api', async () => {
182198
const { wrapper } = renderComponent(<AppLayout drawers={[testDrawer]} />);
183-
expect(wrapper.findDrawersTriggers()).toHaveLength(1);
199+
await waitFor(() => {
200+
expect(wrapper.findDrawersTriggers()).toHaveLength(1);
201+
});
184202
});
185203

186-
testIf(size !== 'mobile')('aria-controls points to an existing drawer id', () => {
204+
testIf(size !== 'mobile')('aria-controls points to an existing drawer id', async () => {
187205
const { wrapper } = renderComponent(<AppLayout drawers={[testDrawer]} />);
188-
const drawerTrigger = wrapper.findDrawerTriggerById('security')!;
189-
expect(drawerTrigger!.getElement()).not.toHaveAttribute('aria-controls');
206+
await waitFor(() => {
207+
const drawerTrigger = wrapper.findDrawerTriggerById('security')!;
208+
expect(drawerTrigger!.getElement()).not.toHaveAttribute('aria-controls');
209+
});
190210

211+
const drawerTrigger = wrapper.findDrawerTriggerById('security')!;
191212
drawerTrigger.click();
192213
expect(drawerTrigger!.getElement()).toHaveAttribute('aria-controls', 'security');
193214
expect(wrapper.findActiveDrawer()!.getElement()).toHaveAttribute('id', 'security');
194215
});
195216

196-
testIf(size !== 'mobile' && theme !== 'classic')('shows trigger button as selected when drawer opened', () => {
217+
testIf(size !== 'mobile' && theme !== 'classic')('shows trigger button as selected when drawer opened', async () => {
197218
const { wrapper } = renderComponent(<AppLayout drawers={[testDrawer]} />);
219+
await waitFor(() => {
220+
expect(wrapper.findDrawerTriggerById('security')!).toBeTruthy();
221+
});
198222
const drawerTrigger = wrapper.findDrawerTriggerById('security')!;
199223
const selectedClass = theme === 'refresh' ? visualRefreshStyles.selected : toolbarTriggerButtonStyles.selected;
200224
expect(drawerTrigger!.getElement()).not.toHaveClass(selectedClass);
@@ -207,46 +231,55 @@ describeEachAppLayout(({ size, theme }) => {
207231
expect(drawerTrigger!.getElement()).not.toHaveClass(selectedClass);
208232
});
209233

210-
testIf(theme === 'refresh-toolbar')('tooltip renders correctly on focus, blur, and escape key press events', () => {
211-
const mockDrawers = [testDrawer];
212-
const result = render(<AppLayout drawers={mockDrawers} />);
213-
const wrapper = createWrapper(result.container).findAppLayout();
214-
expect(wrapper!.findDrawerTriggerTooltip()).toBeNull();
215-
expect(() => result.getByTestId(testDrawer.ariaLabels.drawerName)).toThrow();
234+
testIf(theme === 'refresh-toolbar')(
235+
'tooltip renders correctly on focus, blur, and escape key press events',
236+
async () => {
237+
const mockDrawers = [testDrawer];
238+
const result = render(<AppLayout drawers={mockDrawers} />);
239+
const wrapper = createWrapper(result.container).findAppLayout();
240+
expect(wrapper!.findDrawerTriggerTooltip()).toBeNull();
241+
expect(() => result.getByTestId(testDrawer.ariaLabels.drawerName)).toThrow();
216242

217-
const items = wrapper!.findDrawersTriggers();
218-
expect(items.length).toEqual(mockDrawers.length);
243+
await waitFor(() => {
244+
expect(wrapper!.findDrawersTriggers()).toBeTruthy();
245+
});
246+
const items = wrapper!.findDrawersTriggers();
247+
expect(items.length).toEqual(mockDrawers.length);
219248

220-
fireEvent.focus(items![0].getElement());
221-
expect(wrapper!.findDrawerTriggerTooltip()).toBeTruthy();
222-
expect(result.getByText(testDrawer.ariaLabels.drawerName)).toBeTruthy();
249+
fireEvent.focus(items![0].getElement());
250+
expect(wrapper!.findDrawerTriggerTooltip()).toBeTruthy();
251+
expect(result.getByText(testDrawer.ariaLabels.drawerName)).toBeTruthy();
223252

224-
fireEvent.blur(items![0].getElement());
225-
expect(wrapper!.findDrawerTriggerTooltip()).toBeNull();
226-
expect(() => result.getByTestId(testDrawer.ariaLabels.drawerName)).toThrow();
253+
fireEvent.blur(items![0].getElement());
254+
expect(wrapper!.findDrawerTriggerTooltip()).toBeNull();
255+
expect(() => result.getByTestId(testDrawer.ariaLabels.drawerName)).toThrow();
227256

228-
fireEvent.focus(items![0].getElement());
229-
expect(wrapper!.findDrawerTriggerTooltip()).toBeTruthy();
230-
expect(result.getByText(testDrawer.ariaLabels.drawerName)).toBeTruthy();
257+
fireEvent.focus(items![0].getElement());
258+
expect(wrapper!.findDrawerTriggerTooltip()).toBeTruthy();
259+
expect(result.getByText(testDrawer.ariaLabels.drawerName)).toBeTruthy();
231260

232-
fireEvent.keyDown(items![0].getElement(), {
233-
...mockEventBubble,
234-
key: 'Escape',
235-
code: KeyCode.escape,
236-
});
237-
expect(wrapper!.findDrawerTriggerTooltip()).toBeNull();
238-
expect(() => result.getByTestId(testDrawer.ariaLabels.drawerName)).toThrow();
239-
});
261+
fireEvent.keyDown(items![0].getElement(), {
262+
...mockEventBubble,
263+
key: 'Escape',
264+
code: KeyCode.escape,
265+
});
266+
expect(wrapper!.findDrawerTriggerTooltip()).toBeNull();
267+
expect(() => result.getByTestId(testDrawer.ariaLabels.drawerName)).toThrow();
268+
}
269+
);
240270

241271
testIf(theme === 'refresh-toolbar')(
242272
'tooltip renders correctly on pointer events and is removed on escape key press',
243-
() => {
273+
async () => {
244274
const mockDrawers = [testDrawer];
245275
const result = render(<AppLayout drawers={mockDrawers} />);
246276
const wrapper = createWrapper(result.container).findAppLayout();
247277
expect(wrapper!.findDrawerTriggerTooltip()).toBeNull();
248278
expect(() => result.getByTestId(testDrawer.ariaLabels.drawerName)).toThrow();
249279

280+
await waitFor(() => {
281+
expect(wrapper!.findDrawersTriggers()).toBeTruthy();
282+
});
250283
const items = wrapper!.findDrawersTriggers();
251284
expect(items?.length).toEqual(mockDrawers.length);
252285

@@ -272,12 +305,15 @@ describeEachAppLayout(({ size, theme }) => {
272305
}
273306
);
274307

275-
testIf(theme === 'refresh-toolbar')('tooltip does not render on trigger focus via close button', () => {
308+
testIf(theme === 'refresh-toolbar')('tooltip does not render on trigger focus via close button', async () => {
276309
const mockDrawers = [testDrawer];
277310
const result = render(<AppLayout drawers={mockDrawers} />);
278311
const wrapper = createWrapper(result.container).findAppLayout();
279312
expect(wrapper!.findDrawerTriggerTooltip()).toBeNull();
280313
expect(() => result.getByTestId(testDrawer.ariaLabels.drawerName)).toThrow();
314+
await waitFor(() => {
315+
expect(wrapper?.findDrawerTriggerById(testDrawer.id)!.getElement()).toBeTruthy();
316+
});
281317
wrapper?.findDrawerTriggerById(testDrawer.id)!.click();
282318
expect(wrapper?.findActiveDrawer()).toBeTruthy();
283319
wrapper?.findActiveDrawerCloseButton()!.click();

0 commit comments

Comments
 (0)