Skip to content

Commit f628f82

Browse files
committed
fix: common.test.tsx
1 parent acc4ac9 commit f628f82

File tree

1 file changed

+88
-25
lines changed

1 file changed

+88
-25
lines changed

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

Lines changed: 88 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +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 { waitFor } from '@testing-library/react';
45

56
import AppLayout from '../../../lib/components/app-layout';
67
import { AppLayoutWrapper } from '../../../lib/components/test-utils/dom';
@@ -12,13 +13,15 @@ jest.mock('@cloudscape-design/component-toolkit', () => ({
1213
}));
1314

1415
describeEachAppLayout(({ theme, size }) => {
15-
test('Default state', () => {
16+
test('Default state', async () => {
1617
const { wrapper } = renderComponent(<AppLayout />);
1718

1819
expect(wrapper.findNavigationToggle()).toBeTruthy();
1920
expect(wrapper.findNavigation()).toBeTruthy();
2021
expect(wrapper.findNavigationClose()).toBeTruthy();
21-
expect(wrapper.findToolsToggle()).toBeTruthy();
22+
await waitFor(() => {
23+
expect(wrapper.findToolsToggle()).toBeTruthy();
24+
});
2225
expect(wrapper.findTools()).toBeTruthy();
2326
expect(wrapper.findToolsClose()).toBeTruthy();
2427
expect(wrapper.findContentRegion()).toBeTruthy();
@@ -38,9 +41,11 @@ describeEachAppLayout(({ theme, size }) => {
3841
expect(wrapper.findBreadcrumbs()).toBeTruthy();
3942
});
4043

41-
test('should not find tools slot as findActiveDrawer utility', () => {
44+
test('should not find tools slot as findActiveDrawer utility', async () => {
4245
const { wrapper } = renderComponent(<AppLayout toolsOpen={true} tools="test content" />);
43-
expect(wrapper.findTools()!.getElement()).toHaveTextContent('test content');
46+
await waitFor(() => {
47+
expect(wrapper.findTools()!.getElement()).toHaveTextContent('test content');
48+
});
4449
expect(wrapper.findActiveDrawer()).toBeFalsy();
4550
});
4651

@@ -80,52 +85,70 @@ describeEachAppLayout(({ theme, size }) => {
8085
findClose,
8186
}) => {
8287
describe(`${openProp} prop`, () => {
83-
test(`Should call handler once on open when toggle is clicked`, () => {
88+
const waitForAppLayoutLoaded = (wrapper: AppLayoutWrapper) => {
89+
return waitFor(() => {
90+
if (openProp === 'navigationOpen') {
91+
expect(wrapper.findNavigationToggle()).toBeTruthy();
92+
} else {
93+
expect(wrapper.findToolsToggle()).toBeTruthy();
94+
}
95+
});
96+
};
97+
test(`Should call handler once on open when toggle is clicked`, async () => {
8498
const onToggle = jest.fn();
8599
const props = {
86100
[openProp]: false,
87101
[handler]: onToggle,
88102
};
89103
const { wrapper } = renderComponent(<AppLayout {...props} />);
90104

105+
await waitForAppLayoutLoaded(wrapper);
106+
91107
findToggle(wrapper).click();
92108
expect(onToggle).toHaveBeenCalledTimes(size === 'mobile' ? expectedCallsOnMobileToggle : 1);
93109
expect(onToggle).toHaveBeenLastCalledWith(expect.objectContaining({ detail: { open: true } }));
94110
});
95111

96-
test(`Should call handler once on open when span inside toggle is clicked`, () => {
112+
test(`Should call handler once on open when span inside toggle is clicked`, async () => {
97113
const onToggle = jest.fn();
98114
const props = {
99115
[openProp]: false,
100116
[handler]: onToggle,
101117
};
102118
const { wrapper } = renderComponent(<AppLayout {...props} />);
103119

120+
await waitForAppLayoutLoaded(wrapper);
121+
104122
// Chrome bubbles up events from specific elements inside <button>s.
105123
findToggle(wrapper).find('span')!.click();
106124
expect(onToggle).toHaveBeenCalledTimes(size === 'mobile' ? expectedCallsOnMobileToggle : 1);
107125
expect(onToggle).toHaveBeenLastCalledWith(expect.objectContaining({ detail: { open: true } }));
108126
});
109127

110-
test(`Should call handler once on close`, () => {
128+
test(`Should call handler once on close`, async () => {
111129
const onToggle = jest.fn();
112130
const props = {
113131
[openProp]: true,
114132
[handler]: onToggle,
115133
};
116134
const { wrapper } = renderComponent(<AppLayout {...props} />);
117135

136+
await waitForAppLayoutLoaded(wrapper);
137+
118138
findClose(wrapper).click();
119139
expect(onToggle).toHaveBeenCalledTimes(size === 'mobile' ? expectedCallsOnMobileToggle : 1);
120140
expect(onToggle).toHaveBeenLastCalledWith(expect.objectContaining({ detail: { open: false } }));
121141
});
122142

123-
test('Renders two landmarks in closed state', () => {
143+
test('Renders two landmarks in closed state', async () => {
124144
const props = {
125145
[openProp]: false,
126146
[handler]: () => {},
127147
};
128148
const { wrapper } = renderComponent(<AppLayout {...props} />);
149+
150+
await waitForAppLayoutLoaded(wrapper);
151+
129152
const landmarks = findLandmarks(wrapper);
130153
expect(landmarks).toHaveLength(2);
131154

@@ -147,12 +170,15 @@ describeEachAppLayout(({ theme, size }) => {
147170
}
148171
});
149172

150-
test('Renders two landmarks in open state', () => {
173+
test('Renders two landmarks in open state', async () => {
151174
const props = {
152175
[openProp]: true,
153176
[handler]: () => {},
154177
};
155178
const { wrapper } = renderComponent(<AppLayout {...props} />);
179+
180+
await waitForAppLayoutLoaded(wrapper);
181+
156182
const landmarks = findLandmarks(wrapper);
157183
expect(landmarks).toHaveLength(2);
158184
const toggleElement = findToggle(wrapper).getElement();
@@ -173,26 +199,30 @@ describeEachAppLayout(({ theme, size }) => {
173199
}
174200
});
175201

176-
test('Renders aria-expanded only on toggle', () => {
202+
test('Renders aria-expanded only on toggle', async () => {
177203
const props = {
178204
[openProp]: false,
179205
[handler]: () => {},
180206
};
181207

182208
const { wrapper } = renderComponent(<AppLayout {...props} />);
209+
210+
await waitForAppLayoutLoaded(wrapper);
211+
183212
expect(findToggle(wrapper).getElement()).toHaveAttribute('aria-expanded', 'false');
184213
expect(findToggle(wrapper).getElement()).toHaveAttribute('aria-haspopup', 'true');
185214
expect(findClose(wrapper).getElement()).not.toHaveAttribute('aria-expanded');
186215
expect(findClose(wrapper).getElement()).not.toHaveAttribute('aria-haspopup');
187216
});
188217

189-
test('Does not add a label to the toggle and landmark when they are not defined', () => {
218+
test('Does not add a label to the toggle and landmark when they are not defined', async () => {
190219
const { wrapper } = renderComponent(<AppLayout />);
220+
await waitForAppLayoutLoaded(wrapper);
191221
expect(findToggle(wrapper).getElement()).not.toHaveAttribute('aria-label');
192222
expect(findLandmarks(wrapper)[0].getElement()).not.toHaveAttribute('aria-label');
193223
});
194224

195-
test('Adds labels to toggle button and landmark when defined', () => {
225+
test('Adds labels to toggle button and landmark when defined', async () => {
196226
const labels = {
197227
navigationToggle: 'toggle',
198228
toolsToggle: 'toggle',
@@ -201,34 +231,42 @@ describeEachAppLayout(({ theme, size }) => {
201231
};
202232

203233
const { wrapper } = renderComponent(<AppLayout ariaLabels={labels} />);
234+
await waitForAppLayoutLoaded(wrapper);
204235
expect(findToggle(wrapper).getElement()).toHaveAttribute('aria-label', 'toggle');
205236
expect(findLandmarks(wrapper)[theme === 'refresh-toolbar' ? 1 : 0].getElement()).toHaveAttribute(
206237
'aria-label',
207238
'landmark'
208239
);
209240
});
210241

211-
test('Close button does have a label if it is defined', () => {
242+
test('Close button does have a label if it is defined', async () => {
212243
const props = { [openProp]: true, [handler]: () => {} };
213244
const labels = {
214245
navigationClose: 'close label',
215246
toolsClose: 'close label',
216247
};
217248
const { wrapper } = renderComponent(<AppLayout {...props} ariaLabels={labels} />);
218249

250+
await waitForAppLayoutLoaded(wrapper);
251+
219252
expect(findClose(wrapper).getElement()).toHaveAttribute('aria-label', 'close label');
220253
});
221254

222-
test('Close button does not render a label if is not defined', () => {
255+
test('Close button does not render a label if is not defined', async () => {
223256
const props = { [openProp]: true, [handler]: () => {} };
224257
const { wrapper } = renderComponent(<AppLayout {...props} />);
225258

259+
await waitForAppLayoutLoaded(wrapper);
260+
226261
expect(findClose(wrapper).getElement()).not.toHaveAttribute('aria-label');
227262
});
228263

229-
test('Opens and closes drawer in uncontrolled mode', () => {
264+
test('Opens and closes drawer in uncontrolled mode', async () => {
230265
// use content type with initial closed state for all drawers
231266
const { wrapper } = renderComponent(<AppLayout contentType="form" />);
267+
268+
await waitForAppLayoutLoaded(wrapper);
269+
232270
expect(findOpenElement(wrapper)).toBeFalsy();
233271

234272
findToggle(wrapper).click();
@@ -238,10 +276,12 @@ describeEachAppLayout(({ theme, size }) => {
238276
expect(findOpenElement(wrapper)).toBeFalsy();
239277
});
240278

241-
test('Moves focus between open and close buttons', () => {
279+
test('Moves focus between open and close buttons', async () => {
242280
// use content type with initial closed state for all drawers
243281
const { wrapper } = renderComponent(<AppLayout contentType="form" />);
244282

283+
await waitForAppLayoutLoaded(wrapper);
284+
245285
findToggle(wrapper).click();
246286
expect(findClose(wrapper).getElement()).toBe(document.activeElement);
247287

@@ -263,28 +303,33 @@ describeEachAppLayout(({ theme, size }) => {
263303
// Drawers tests
264304

265305
describe(`Drawers`, () => {
266-
test(`Should call handler once on open when toggle is clicked`, () => {
306+
test(`Should call handler once on open when toggle is clicked`, async () => {
267307
const onChange = jest.fn();
268308
const { wrapper } = renderComponent(
269309
<AppLayout drawers={[testDrawer]} onDrawerChange={event => onChange(event.detail)} />
270310
);
311+
await waitFor(() => {
312+
expect(wrapper.findDrawerTriggerById('security')).toBeTruthy();
313+
});
271314
wrapper.findDrawerTriggerById('security')!.click();
272315
expect(onChange).toHaveBeenCalledWith({ activeDrawerId: 'security' });
273316
});
274317

275-
test(`Should call handler once on open when span inside toggle is clicked`, () => {
318+
test(`Should call handler once on open when span inside toggle is clicked`, async () => {
276319
const onChange = jest.fn();
277320
const { wrapper } = renderComponent(
278321
<AppLayout drawers={[testDrawer]} onDrawerChange={event => onChange(event.detail)} />
279322
);
280-
323+
await waitFor(() => {
324+
expect(wrapper.findDrawerTriggerById('security')).toBeTruthy();
325+
});
281326
// Chrome bubbles up events from specific elements inside <button>s.
282327
wrapper.findDrawerTriggerById('security')!.find('span')!.click();
283328
expect(onChange).toHaveBeenCalledTimes(1);
284329
expect(onChange).toHaveBeenCalledWith({ activeDrawerId: 'security' });
285330
});
286331

287-
test(`Should call handler once on close`, () => {
332+
test(`Should call handler once on close`, async () => {
288333
const onChange = jest.fn();
289334
const { wrapper } = renderComponent(
290335
<AppLayout
@@ -293,15 +338,21 @@ describeEachAppLayout(({ theme, size }) => {
293338
onDrawerChange={event => onChange(event.detail)}
294339
/>
295340
);
296-
341+
await waitFor(() => {
342+
expect(wrapper.findActiveDrawerCloseButton()).toBeTruthy();
343+
});
297344
wrapper.findActiveDrawerCloseButton()!.click();
298345
expect(onChange).toHaveBeenCalledTimes(1);
299346
expect(onChange).toHaveBeenCalledWith({ activeDrawerId: null });
300347
});
301348

302-
test('Renders aria-expanded only on toggle', () => {
349+
test('Renders aria-expanded only on toggle', async () => {
303350
const { wrapper } = renderComponent(<AppLayout drawers={[testDrawer]} />);
304351

352+
await waitFor(() => {
353+
expect(wrapper.findDrawerTriggerById('security')).toBeTruthy();
354+
});
355+
305356
const drawerTrigger = wrapper.findDrawerTriggerById('security')!;
306357
expect(drawerTrigger.getElement()).toHaveAttribute('aria-expanded', 'false');
307358
expect(drawerTrigger.getElement()).toHaveAttribute('aria-haspopup', 'true');
@@ -312,30 +363,42 @@ describeEachAppLayout(({ theme, size }) => {
312363
expect(wrapper.findActiveDrawerCloseButton()!.getElement()).not.toHaveAttribute('aria-haspopup');
313364
});
314365

315-
test('Close button does have a label if it is defined', () => {
366+
test('Close button does have a label if it is defined', async () => {
316367
const { wrapper } = renderComponent(
317368
<AppLayout activeDrawerId={testDrawer.id} drawers={[testDrawer]} onDrawerChange={() => {}} />
318369
);
319370

371+
await waitFor(() => {
372+
expect(wrapper.findActiveDrawerCloseButton()).toBeTruthy();
373+
});
374+
320375
expect(wrapper.findActiveDrawerCloseButton()!.getElement()).toHaveAttribute(
321376
'aria-label',
322377
'Security close button'
323378
);
324379
});
325380

326-
test('Close button does not render a label if is not defined', () => {
381+
test('Close button does not render a label if is not defined', async () => {
327382
const { wrapper } = renderComponent(
328383
<AppLayout activeDrawerId={testDrawerWithoutLabels.id} drawers={[testDrawerWithoutLabels]} />
329384
);
330385

386+
await waitFor(() => {
387+
expect(wrapper.findActiveDrawerCloseButton()).toBeTruthy();
388+
});
389+
331390
expect(wrapper.findActiveDrawerCloseButton()!.getElement()).not.toHaveAttribute('aria-label');
332391
});
333392

334-
test('Opens and closes drawer in uncontrolled mode', () => {
393+
test('Opens and closes drawer in uncontrolled mode', async () => {
335394
// use content type with initial closed state for all drawers
336395
const { wrapper } = renderComponent(<AppLayout drawers={[testDrawer]} />);
337396
expect(wrapper.findActiveDrawer()).toBeNull();
338397

398+
await waitFor(() => {
399+
expect(wrapper.findDrawerTriggerById('security')).toBeTruthy();
400+
});
401+
339402
wrapper.findDrawerTriggerById('security')!.find('span')!.click();
340403
expect(wrapper.findActiveDrawer()).not.toBeNull();
341404

0 commit comments

Comments
 (0)