Skip to content

Commit 9bae389

Browse files
committed
new snapshot tests
1 parent aaff79b commit 9bae389

10 files changed

+4182
-2795
lines changed

src/app-layout/__tests__/__snapshots__/widget-contract-old.test.tsx.snap

Lines changed: 2435 additions & 0 deletions
Large diffs are not rendered by default.

src/app-layout/__tests__/__snapshots__/widget-contract-split-panel-old.test.tsx.snap

Lines changed: 1466 additions & 0 deletions
Large diffs are not rendered by default.

src/app-layout/__tests__/__snapshots__/widget-contract-split-panel.test.tsx.snap

Lines changed: 103 additions & 2700 deletions
Large diffs are not rendered by default.

src/app-layout/__tests__/__snapshots__/widget-contract.test.tsx.snap

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
exports[`Theme=refresh-toolbar, Size=desktop contract for default use-case 1`] = `
44
Map {
5-
[Function] => {
5+
"BeforeMainSlotImplementation" => {
66
"appLayoutProps": {
77
"ariaLabels": {
88
"drawers": undefined,
@@ -53,7 +53,7 @@ Map {
5353
"onNavigationToggle": undefined,
5454
},
5555
},
56-
[Function] => {
56+
"TopContentSlotImplementation" => {
5757
"appLayoutProps": {
5858
"ariaLabels": {
5959
"drawers": undefined,
@@ -104,7 +104,7 @@ Map {
104104
"onNavigationToggle": undefined,
105105
},
106106
},
107-
[Function] => {
107+
"BottomContentSlotImplementation" => {
108108
"appLayoutProps": {
109109
"ariaLabels": {
110110
"drawers": undefined,
@@ -155,7 +155,7 @@ Map {
155155
"onNavigationToggle": undefined,
156156
},
157157
},
158-
[Function] => {
158+
"AfterMainSlotImplementation" => {
159159
"appLayoutProps": {
160160
"ariaLabels": {
161161
"drawers": undefined,
@@ -206,7 +206,7 @@ Map {
206206
"onNavigationToggle": undefined,
207207
},
208208
},
209-
[Function] => {
209+
"AppLayoutStateProvider" => {
210210
"appLayoutProps": {
211211
"ariaLabels": {
212212
"drawers": undefined,
@@ -249,7 +249,7 @@ Map {
249249

250250
exports[`Theme=refresh-toolbar, Size=desktop contract with all slots provided 1`] = `
251251
Map {
252-
[Function] => {
252+
"BeforeMainSlotImplementation" => {
253253
"appLayoutProps": {
254254
"ariaLabels": {
255255
"drawers": undefined,
@@ -319,7 +319,7 @@ Map {
319319
"onNavigationToggle": undefined,
320320
},
321321
},
322-
[Function] => {
322+
"TopContentSlotImplementation" => {
323323
"appLayoutProps": {
324324
"ariaLabels": {
325325
"drawers": undefined,
@@ -389,7 +389,7 @@ Map {
389389
"onNavigationToggle": undefined,
390390
},
391391
},
392-
[Function] => {
392+
"BottomContentSlotImplementation" => {
393393
"appLayoutProps": {
394394
"ariaLabels": {
395395
"drawers": undefined,
@@ -459,7 +459,7 @@ Map {
459459
"onNavigationToggle": undefined,
460460
},
461461
},
462-
[Function] => {
462+
"AfterMainSlotImplementation" => {
463463
"appLayoutProps": {
464464
"ariaLabels": {
465465
"drawers": undefined,
@@ -529,7 +529,7 @@ Map {
529529
"onNavigationToggle": undefined,
530530
},
531531
},
532-
[Function] => {
532+
"AppLayoutStateProvider" => {
533533
"appLayoutProps": {
534534
"ariaLabels": {
535535
"drawers": undefined,
@@ -590,7 +590,7 @@ Map {
590590

591591
exports[`Theme=refresh-toolbar, Size=desktop contract with drawers 1`] = `
592592
Map {
593-
[Function] => {
593+
"BeforeMainSlotImplementation" => {
594594
"appLayoutProps": {
595595
"activeDrawerId": "security",
596596
"ariaLabels": {
@@ -660,7 +660,7 @@ Map {
660660
"onNavigationToggle": undefined,
661661
},
662662
},
663-
[Function] => {
663+
"TopContentSlotImplementation" => {
664664
"appLayoutProps": {
665665
"activeDrawerId": "security",
666666
"ariaLabels": {
@@ -730,7 +730,7 @@ Map {
730730
"onNavigationToggle": undefined,
731731
},
732732
},
733-
[Function] => {
733+
"BottomContentSlotImplementation" => {
734734
"appLayoutProps": {
735735
"activeDrawerId": "security",
736736
"ariaLabels": {
@@ -800,7 +800,7 @@ Map {
800800
"onNavigationToggle": undefined,
801801
},
802802
},
803-
[Function] => {
803+
"AfterMainSlotImplementation" => {
804804
"appLayoutProps": {
805805
"activeDrawerId": "security",
806806
"ariaLabels": {
@@ -870,7 +870,7 @@ Map {
870870
"onNavigationToggle": undefined,
871871
},
872872
},
873-
[Function] => {
873+
"AppLayoutStateProvider" => {
874874
"appLayoutProps": {
875875
"activeDrawerId": "security",
876876
"ariaLabels": {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import React from 'react';
4+
import { render } from '@testing-library/react';
5+
6+
import './widget-old-mocks'; // should be imported before components to activate mocks
7+
import AppLayout from '../../../lib/components/app-layout';
8+
import { describeEachAppLayout, testDrawer } from './utils';
9+
import { renderedProps } from './widget-old-mocks';
10+
11+
jest.mock('@cloudscape-design/component-toolkit/internal', () => {
12+
let counter = 0;
13+
return {
14+
...jest.requireActual('@cloudscape-design/component-toolkit/internal'),
15+
useUniqueId: (prefix: string) => `${prefix}${++counter}`,
16+
};
17+
});
18+
19+
describeEachAppLayout({ themes: ['refresh-toolbar'], sizes: ['desktop'] }, () => {
20+
beforeEach(() => {
21+
renderedProps.clear();
22+
});
23+
24+
test('contract for default use-case', () => {
25+
render(<AppLayout />);
26+
expect(renderedProps).toMatchSnapshot();
27+
});
28+
29+
test('contract with all slots provided', () => {
30+
render(
31+
<AppLayout
32+
breadcrumbs={<div>breadcrumbs</div>}
33+
notifications={<div>notifications</div>}
34+
navigation={<div>navigation</div>}
35+
tools={<div>tools</div>}
36+
content={<div>content</div>}
37+
splitPanel={<div>split panel</div>}
38+
/>
39+
);
40+
expect(renderedProps).toMatchSnapshot();
41+
});
42+
43+
test('contract with drawers', () => {
44+
render(<AppLayout activeDrawerId={testDrawer.id} onDrawerChange={() => {}} drawers={[testDrawer]} />);
45+
expect(renderedProps).toMatchSnapshot();
46+
});
47+
});
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
/* eslint-disable simple-import-sort/imports */
4+
import React from 'react';
5+
import { render, waitFor } from '@testing-library/react';
6+
7+
import './widget-old-mocks'; // should be imported before components to activate mocks
8+
import { describeEachAppLayout } from './utils';
9+
import AppLayout from '../../../lib/components/app-layout';
10+
import SplitPanel from '../../../lib/components/split-panel';
11+
import createWrapper from '../../../lib/components/test-utils/selectors';
12+
import { renderedProps } from './widget-old-mocks';
13+
14+
jest.mock('@cloudscape-design/component-toolkit/internal', () => {
15+
let counter = 0;
16+
return {
17+
...jest.requireActual('@cloudscape-design/component-toolkit/internal'),
18+
useUniqueId: (prefix: string) => `${prefix}${++counter}`,
19+
useRandomId: (prefix: string) => `${prefix}${++counter}`,
20+
};
21+
});
22+
23+
describeEachAppLayout({ themes: ['refresh-toolbar'], sizes: ['desktop'] }, () => {
24+
beforeEach(() => {
25+
renderedProps.clear();
26+
});
27+
28+
test('contract with split panel', async () => {
29+
render(
30+
<AppLayout
31+
splitPanel={
32+
<SplitPanel header="Split panel header">
33+
<div>split panel content</div>
34+
</SplitPanel>
35+
}
36+
/>
37+
);
38+
await waitFor(() => {
39+
expect(createWrapper().findSplitPanel()).toBeTruthy();
40+
});
41+
expect(renderedProps).toMatchSnapshot();
42+
});
43+
44+
test('contract with split panel (trigger is hidden)', async () => {
45+
render(
46+
<AppLayout
47+
splitPanel={
48+
<SplitPanel header="Split panel header" closeBehavior="hide">
49+
<div>split panel content</div>
50+
</SplitPanel>
51+
}
52+
/>
53+
);
54+
await waitFor(() => {
55+
expect(createWrapper().findSplitPanel()).toBeTruthy();
56+
});
57+
expect(renderedProps).toMatchSnapshot();
58+
});
59+
});

src/app-layout/__tests__/widget-contract-split-panel.test.tsx

Lines changed: 2 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4,78 +4,13 @@
44
import React from 'react';
55
import { render, waitFor } from '@testing-library/react';
66

7+
import './widget-new-mocks'; // should be imported before components to activate mocks
78
import { describeEachAppLayout } from './utils';
89
import AppLayout from '../../../lib/components/app-layout';
910
import SplitPanel from '../../../lib/components/split-panel';
1011
import createWrapper from '../../../lib/components/test-utils/selectors';
12+
import { renderedProps } from './widget-new-mocks';
1113

12-
const isObject = (value: any) => Object.prototype.toString.call(value) === '[object Object]';
13-
14-
// this string
15-
// awsui_root_7nfqu_jksfw_153 awsui_root_1fj9k_z5zo8_5 awsui_has-adaptive-widths-default_7nfqu_jksfw_197
16-
// becomes
17-
// awsui_root awsui_root awsui_has-adaptive-widths-default
18-
function skipHashInClassnames(classNames: string): string {
19-
return classNames
20-
.split(' ')
21-
.map(className => className.replace(/_[a-z0-9]+_[a-z0-9]+_\d+$/i, ''))
22-
.join(' ');
23-
}
24-
25-
// --awsui-max-content-width-kcc2gu becomes --awsui-max-content-width
26-
function skipHashInGLobalStyle(style: string): string {
27-
if (!style.startsWith('--awsui')) {
28-
return style;
29-
}
30-
31-
const parts = style.split('-');
32-
parts.pop();
33-
return parts.join('-');
34-
}
35-
36-
function sanitizeProps(props: any): any {
37-
if (!isObject(props)) {
38-
return props;
39-
}
40-
if (React.isValidElement(props) || props?.current instanceof Element) {
41-
return '__JSX__';
42-
}
43-
// Now that classNames and styles are provided by the widget API,
44-
// they need to be included in the check.
45-
// However, they're regenerated on every build, and the hash part makes the snapshot test flaky.
46-
// To avoid this, we strip out the hash portion.
47-
if (props.className) {
48-
return {
49-
...props,
50-
className: skipHashInClassnames(props.className),
51-
...(props.style && {
52-
style: Object.keys(props.style).reduce(
53-
(acc, key) => ({ ...acc, [skipHashInGLobalStyle(key)]: props.style[key] }),
54-
{}
55-
),
56-
}),
57-
};
58-
}
59-
return Object.fromEntries(
60-
Object.entries(props).map(([key, value]) => {
61-
return [key, sanitizeProps(value)];
62-
})
63-
);
64-
}
65-
66-
const renderedProps = new Map();
67-
function createWidgetizedComponentMock(Implementation: React.ComponentType) {
68-
return () => {
69-
return function Widgetized(props: any) {
70-
renderedProps.set(Implementation, sanitizeProps(props));
71-
return <Implementation {...(props as any)} />;
72-
};
73-
};
74-
}
75-
76-
jest.mock('../../../lib/components/internal/widgets', () => ({
77-
createWidgetizedComponent: createWidgetizedComponentMock,
78-
}));
7914
jest.mock('@cloudscape-design/component-toolkit/internal', () => {
8015
let counter = 0;
8116
return {

src/app-layout/__tests__/widget-contract.test.tsx

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,11 @@
33
import React from 'react';
44
import { render } from '@testing-library/react';
55

6+
import './widget-new-mocks'; // should be imported before components to activate mocks
67
import AppLayout from '../../../lib/components/app-layout';
78
import { describeEachAppLayout, testDrawer } from './utils';
9+
import { renderedProps } from './widget-new-mocks';
810

9-
const renderedProps = new Map();
10-
function createWidgetizedComponentMock(Implementation: React.ComponentType) {
11-
return () => {
12-
return function Widgetized(props: any) {
13-
renderedProps.set(Implementation, props);
14-
return null;
15-
};
16-
};
17-
}
18-
19-
jest.mock('../../../lib/components/internal/widgets', () => ({
20-
createWidgetizedComponent: createWidgetizedComponentMock,
21-
}));
2211
jest.mock('@cloudscape-design/component-toolkit/internal', () => {
2312
let counter = 0;
2413
return {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import React from 'react';
4+
5+
export const renderedProps = new Map();
6+
function createWidgetizedComponentMock(Implementation: React.ComponentType) {
7+
return () => {
8+
return function Widgetized(props: any) {
9+
renderedProps.set(Implementation.name, props);
10+
return null;
11+
};
12+
};
13+
}
14+
15+
jest.mock('../../../lib/components/internal/widgets', () => ({
16+
createWidgetizedComponent: createWidgetizedComponentMock,
17+
}));

0 commit comments

Comments
 (0)