Skip to content

Commit 50619a2

Browse files
committed
chore: Integ test for checking ensure the layout is not shifting after widget loading
1 parent 5b4491c commit 50619a2

File tree

6 files changed

+124
-66
lines changed

6 files changed

+124
-66
lines changed

pages/app-layout/runtime-drawers.page.tsx

Lines changed: 61 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -82,71 +82,73 @@ export default function WithDrawers() {
8282
breadcrumbs={<Breadcrumbs />}
8383
ref={appLayoutRef}
8484
content={
85-
<ContentLayout
86-
disableOverlap={true}
87-
header={
88-
<SpaceBetween size="m">
89-
<Header
90-
variant="h1"
91-
description="Sometimes you need custom drawers to get the job done."
92-
info={
93-
<Link
94-
data-testid="info-link-header"
95-
variant="info"
96-
onFollow={() => {
97-
setHelpPathSlug('header');
98-
setIsToolsOpen(true);
99-
appLayoutRef.current?.focusToolsClose();
100-
}}
101-
>
102-
Info
103-
</Link>
104-
}
105-
>
106-
Testing Custom Drawers!
107-
</Header>
85+
<div data-testid="app-layout-content-area">
86+
<ContentLayout
87+
disableOverlap={true}
88+
header={
89+
<SpaceBetween size="m">
90+
<Header
91+
variant="h1"
92+
description="Sometimes you need custom drawers to get the job done."
93+
info={
94+
<Link
95+
data-testid="info-link-header"
96+
variant="info"
97+
onFollow={() => {
98+
setHelpPathSlug('header');
99+
setIsToolsOpen(true);
100+
appLayoutRef.current?.focusToolsClose();
101+
}}
102+
>
103+
Info
104+
</Link>
105+
}
106+
>
107+
Testing Custom Drawers!
108+
</Header>
108109

109-
<SpaceBetween size="xs">
110-
<Toggle checked={hasTools} onChange={({ detail }) => setUrlParams({ hasTools: detail.checked })}>
111-
Use Tools
112-
</Toggle>
110+
<SpaceBetween size="xs">
111+
<Toggle checked={hasTools} onChange={({ detail }) => setUrlParams({ hasTools: detail.checked })}>
112+
Use Tools
113+
</Toggle>
113114

114-
<Toggle checked={hasDrawers} onChange={({ detail }) => setUrlParams({ hasDrawers: detail.checked })}>
115-
Use Drawers
116-
</Toggle>
115+
<Toggle checked={hasDrawers} onChange={({ detail }) => setUrlParams({ hasDrawers: detail.checked })}>
116+
Use Drawers
117+
</Toggle>
117118

118-
<Button
119-
onClick={() => awsuiPlugins.appLayout.openDrawer('circle4-global')}
120-
data-testid="open-drawer-button"
121-
>
122-
Open a drawer without a trigger
123-
</Button>
124-
<Button onClick={() => awsuiPlugins.appLayout.closeDrawer('circle4-global')}>
125-
Close a drawer without a trigger
126-
</Button>
119+
<Button
120+
onClick={() => awsuiPlugins.appLayout.openDrawer('circle4-global')}
121+
data-testid="open-drawer-button"
122+
>
123+
Open a drawer without a trigger
124+
</Button>
125+
<Button onClick={() => awsuiPlugins.appLayout.closeDrawer('circle4-global')}>
126+
Close a drawer without a trigger
127+
</Button>
128+
</SpaceBetween>
127129
</SpaceBetween>
128-
</SpaceBetween>
129-
}
130-
>
131-
<Header
132-
info={
133-
<Link
134-
data-testid="info-link-content"
135-
variant="info"
136-
onFollow={() => {
137-
setHelpPathSlug('content');
138-
setIsToolsOpen(true);
139-
}}
140-
>
141-
Info
142-
</Link>
143130
}
144131
>
145-
Content
146-
<CustomContent />
147-
</Header>
148-
<Containers />
149-
</ContentLayout>
132+
<Header
133+
info={
134+
<Link
135+
data-testid="info-link-content"
136+
variant="info"
137+
onFollow={() => {
138+
setHelpPathSlug('content');
139+
setIsToolsOpen(true);
140+
}}
141+
>
142+
Info
143+
</Link>
144+
}
145+
>
146+
Content
147+
<CustomContent />
148+
</Header>
149+
<Containers />
150+
</ContentLayout>
151+
</div>
150152
}
151153
splitPanel={
152154
<SplitPanel header="Split panel header" i18nStrings={splitPaneli18nStrings}>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import { BasePageObject } from '@cloudscape-design/browser-test-tools/page-objects';
4+
import useBrowser from '@cloudscape-design/browser-test-tools/use-browser';
5+
6+
import { viewports } from './constants';
7+
8+
interface SetupTestOptions {
9+
splitPanelPosition?: string;
10+
screenSize?: (typeof viewports)['desktop' | 'mobile'];
11+
disableContentPaddings?: string;
12+
theme: string;
13+
}
14+
15+
const setupTest = (
16+
{ screenSize = viewports.desktop }: SetupTestOptions,
17+
testFn: (page: BasePageObject) => Promise<void>
18+
) =>
19+
useBrowser(screenSize, async browser => {
20+
const page = new BasePageObject(browser);
21+
const params = new URLSearchParams({
22+
appLayoutWidget: 'true',
23+
appLayoutDelayedWidget: 'true',
24+
visualRefresh: 'true',
25+
appLayoutToolbar: 'true',
26+
}).toString();
27+
await browser.url(`#/light/app-layout/runtime-drawers?${params}`);
28+
await testFn(page);
29+
});
30+
31+
describe.each(['refresh-toolbar'] as const)('%s', theme => {
32+
describe.each(['desktop', 'mobile'] as const)('%s', size => {
33+
test(
34+
'main content area layout should not shift after loading the widget part of the page',
35+
setupTest(
36+
{
37+
theme,
38+
screenSize: size === 'desktop' ? viewports.desktop : viewports.mobile,
39+
},
40+
async page => {
41+
// make sure the widget part has not loaded yet
42+
const { top: contentTopBefore, left: contentLeftBefore } = await page.getBoundingBox(
43+
`[data-awsui-app-layout-widget-loaded="false"] [data-testid="app-layout-content-area"]`
44+
);
45+
46+
const { top: contentTopAfter, left: contentLeftAfter } = await page.getBoundingBox(
47+
`[data-awsui-app-layout-widget-loaded="true"] [data-testid="app-layout-content-area"]`
48+
);
49+
50+
expect(contentTopBefore).toBe(contentTopAfter);
51+
expect(contentLeftBefore).toBe(contentLeftAfter);
52+
}
53+
)
54+
);
55+
});
56+
});

src/app-layout/utils/feature-flags.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,10 @@ import { getGlobalFlag } from '@cloudscape-design/component-toolkit/internal';
77
import { useVisualRefresh } from '../../internal/hooks/use-visual-mode';
88
import { AppLayoutToolbarPublicContext } from '../visual-refresh-toolbar/contexts';
99

10-
const getCutomFlag = (flagName: string) => {
11-
const isBrowser = typeof window !== 'undefined';
12-
if (!isBrowser) {
13-
return {};
14-
}
10+
const getCustomFlag = (flagName: string) => {
11+
const flagHolder: any = typeof window !== 'undefined' ? window : globalThis;
1512
const awsuiCustomFlagsSymbol = Symbol.for('awsui-custom-flags');
16-
return window?.[awsuiCustomFlagsSymbol as any]?.[flagName as any];
13+
return flagHolder?.[awsuiCustomFlagsSymbol as any]?.[flagName as any];
1714
};
1815

1916
// useAppLayoutFlagEnabled is set to true only in consoles. It controls if AppLayout theme is toolbar
@@ -34,5 +31,5 @@ export const useAppLayoutToolbarDesignEnabled = () => {
3431
};
3532

3633
export const isAppLayoutDelayedWidget = () => {
37-
return !!getCutomFlag('appLayoutDelayedWidget');
34+
return !!getCustomFlag('appLayoutDelayedWidget');
3835
};

src/app-layout/visual-refresh-toolbar/skeleton/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ export const SkeletonLayout = (props: RootSkeletonLayoutProps) => {
158158
{!hasToolbar && breadcrumbs ? <ScreenreaderOnly>{breadcrumbs}</ScreenreaderOnly> : null}
159159
<VisualContext contextName="app-layout-toolbar">
160160
<div
161+
data-awsui-app-layout-widget-loaded={false}
161162
{...wrapperElAttributes}
162163
className={wrapperElAttributes?.className ?? clsx(styles.root, testutilStyles.root)}
163164
style={

src/app-layout/visual-refresh-toolbar/skeleton/styles.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@
171171
grid-area: toolbar;
172172
block-size: 42px;
173173
border-block-end: awsui.$border-divider-section-width solid awsui.$color-border-layout;
174+
box-sizing: border-box;
174175
}
175176

176177
.notifications-container {

src/app-layout/visual-refresh-toolbar/skeleton/widget-slots/use-skeleton-slots-attributes.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export const useSkeletonSlotsAttributes = ({ appLayoutProps, appLayoutState }: S
3939
[customCssProps.navigationWidth]: `${navigationWidth}px`,
4040
[customCssProps.toolsWidth]: `${activeDrawerSize}px`,
4141
},
42+
'data-awsui-app-layout-widget-loaded': true,
4243
};
4344

4445
const mainElAttributes = {

0 commit comments

Comments
 (0)