Skip to content

Commit

Permalink
chore: Add regression tests for runtime preferences handling in multi…
Browse files Browse the repository at this point in the history
…-app-layout setup
  • Loading branch information
just-boris committed Nov 21, 2024
1 parent 66976ad commit 2df6dbd
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Link from '~components/link';
import SideNavigation, { SideNavigationProps } from '~components/side-navigation';
import SpaceBetween from '~components/space-between';

import './utils/external-widget';
import { IframeWrapper } from '../utils/iframe-wrapper';
import ScreenshotArea from '../utils/screenshot-area';
import { Breadcrumbs, Tools } from './utils/content-blocks';
Expand All @@ -18,7 +19,6 @@ function createView(name: string) {
return function View() {
return (
<AppLayout
{...{ __disableRuntimeDrawers: true }}
data-testid="secondary-layout"
ariaLabels={labels}
breadcrumbs={<Breadcrumbs />}
Expand Down Expand Up @@ -55,6 +55,7 @@ export default function () {
return (
<ScreenshotArea gutters={false}>
<AppLayout
{...{ __disableRuntimeDrawers: true }}
data-testid="main-layout"
ariaLabels={labels}
navigation={
Expand Down
12 changes: 9 additions & 3 deletions pages/app-layout/utils/external-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ awsuiPlugins.appLayout.registerDrawer({
defaultActive: !!searchParams.get('force-default-active'),
onToggle: event => {
console.log('security drawer on toggle', event.detail);
awsuiPlugins.appLayout.updateDrawer({ id: 'security', defaultActive: event.detail.isOpen });
},

resizable: true,
Expand All @@ -56,6 +57,7 @@ awsuiPlugins.appLayout.registerDrawer({
onResize: event => {
setSizeRef.current?.(true);
console.log('resize', event.detail);
awsuiPlugins.appLayout.updateDrawer({ id: 'security', defaultSize: event.detail.size });
},

mountContent: container => {
Expand Down Expand Up @@ -165,15 +167,15 @@ awsuiPlugins.appLayout.registerDrawer({
});

awsuiPlugins.appLayout.registerDrawer({
id: 'circle2-global',
id: 'global-with-stored-state',
type: 'global',
defaultActive: false,
resizable: true,
defaultSize: 320,

ariaLabels: {
closeButton: 'Close button',
content: 'Content',
content: 'Drawer with counter',
triggerButton: 'Trigger button',
resizeHandle: 'Resize handle',
},
Expand All @@ -185,10 +187,14 @@ awsuiPlugins.appLayout.registerDrawer({
</svg>`,
},

onToggle(event) {
awsuiPlugins.appLayout.updateDrawer({ id: 'global-with-stored-state', defaultActive: event.detail.isOpen });
},

mountContent: container => {
ReactDOM.render(
<>
<Counter id="circle2-global" />
<Counter id="global-with-stored-state" />
global widget content circle 2
</>,
container
Expand Down
2 changes: 1 addition & 1 deletion pages/app-layout/with-drawers-scrollable.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ awsuiPlugins.appLayout.registerDrawer({
unmountContent: container => unmountComponentAtNode(container),
});
awsuiPlugins.appLayout.registerDrawer({
id: 'circle2-global',
id: 'global-with-stored-state',
type: 'global',
defaultActive: false,
resizable: true,
Expand Down
86 changes: 64 additions & 22 deletions src/app-layout/__integ__/runtime-drawers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,30 @@ const findDrawerContentById = (wrapper: AppLayoutWrapper, id: string) => {
};

describe.each(['classic', 'refresh', 'refresh-toolbar'] as Theme[])('%s', theme => {
function setupTest({ hasDrawers = 'false' }, testFn: (page: BasePageObject) => Promise<void>) {
return useBrowser(async browser => {
function setupTest(
{ hasDrawers = 'false', url = 'runtime-drawers', size = viewports.desktop },
testFn: (page: BasePageObject) => Promise<void>
) {
return useBrowser({ width: size.width, height: size.height }, async browser => {
const page = new BasePageObject(browser);

await browser.url(
`#/light/app-layout/runtime-drawers?${getUrlParams(theme, {
`#/light/app-layout/${url}?${getUrlParams(theme, {
hasDrawers: hasDrawers,
hasTools: 'true',
splitPanelPosition: 'side',
})}`
);
await page.waitForVisible(wrapper.findDrawerTriggerById('security').toSelector(), true);
await page.waitForVisible(wrapper.findContentRegion().toSelector());
await testFn(page);
});
}

//drawer width assertions not neccessary for mobile
//drawer width assertions not necessary for mobile
describe('desktop', () => {
test(
'should resize equally with tools or drawers',
setupTest({}, async page => {
await page.setWindowSize({ ...viewports.desktop, width: 1800 });
setupTest({ size: { ...viewports.desktop, width: 1800 } }, async page => {
await page.click(wrapper.findToolsToggle().toSelector());
await page.click(wrapper.findSplitPanel().findOpenButton().toSelector());

Expand All @@ -53,7 +55,6 @@ describe.each(['classic', 'refresh', 'refresh-toolbar'] as Theme[])('%s', theme
test(
'renders according to defaultSize property',
setupTest({}, async page => {
await page.setWindowSize(viewports.desktop);
await page.click(wrapper.findDrawerTriggerById('security').toSelector());
// using `clientWidth` to neglect possible border width set on this element
const width = await page.getElementProperty(wrapper.findActiveDrawer().toSelector(), 'clientWidth');
Expand All @@ -64,7 +65,6 @@ describe.each(['classic', 'refresh', 'refresh-toolbar'] as Theme[])('%s', theme
test(
'should call resize handler',
setupTest({}, async page => {
await page.setWindowSize(viewports.desktop);
// close navigation panel to give drawer more room to resize
await page.click(wrapper.findNavigationClose().toSelector());
await page.click(wrapper.findDrawerTriggerById('security').toSelector());
Expand All @@ -76,10 +76,38 @@ describe.each(['classic', 'refresh', 'refresh-toolbar'] as Theme[])('%s', theme
})
);

test(
'should persist runtime drawer preferences when switching between multiple app layouts',
setupTest(
{
url: 'multi-layout-with-hidden-instances-iframe',
},
async page => {
await page.runInsideIframe('#page1', theme !== 'refresh-toolbar', async () => {
await page.click(wrapper.findDrawerTriggerById('security').toSelector());

Check warning on line 87 in src/app-layout/__integ__/runtime-drawers.test.ts

View workflow job for this annotation

GitHub Actions / dry-run / Components integration tests shards (2)

RETRY 1: refresh-toolbar › desktop › should persist runtime drawer preferences when switching between multiple app layouts

Can't call click on element with selector "body [class*="awsui_root_1fj9k"] [class*="awsui_drawers-trigger_1fj9k"][data-testid="awsui-app-layout-trigger-security"]" because element wasn't found at implicitWait (node_modules/webdriverio/build/utils/implicitWait.js:34:19) at Element.elementErrorHandlerCallbackFn (node_modules/webdriverio/build/middlewares.js:20:29) at Element.wrapCommandFn (node_modules/@wdio/utils/build/shim.js:136:29) at BasePageObject.click (node_modules/@cloudscape-design/browser-test-tools/page-objects/base.js:57:9) at src/app-layout/__integ__/runtime-drawers.test.ts:87:13 at src/app-layout/__integ__/runtime-drawers.test.ts:86:11 at src/app-layout/__integ__/runtime-drawers.test.ts:34:7 at Object.<anonymous> (node_modules/@cloudscape-design/browser-test-tools/use-browser.js:36:13)
});
let newWidth: number;
await page.runInsideIframe('#page1', true, async () => {
await expect(page.getText(wrapper.findActiveDrawer().toSelector())).resolves.toContain('Security');
const { width: originalWidth } = await page.getBoundingBox(wrapper.findActiveDrawer().toSelector());
await page.dragAndDrop(wrapper.findActiveDrawerResizeHandle().toSelector(), -200);
({ width: newWidth } = await page.getBoundingBox(wrapper.findActiveDrawer().toSelector()));
expect(newWidth).toBeGreaterThan(originalWidth);
});

await page.click(wrapper.findNavigation().findSideNavigation().findLinkByHref('page2').toSelector());
await page.runInsideIframe('#page2', true, async () => {
await page.waitForVisible(wrapper.findActiveDrawer().toSelector());
expect((await page.getBoundingBox(wrapper.findActiveDrawer().toSelector())).width).toEqual(newWidth!);
await expect(page.getText(wrapper.findActiveDrawer().toSelector())).resolves.toContain('Security');
});
}
)
);

test(
'should show sticky elements on scroll in drawer',
setupTest({ hasDrawers: 'true' }, async page => {
await page.setWindowSize(viewports.desktop);
await page.waitForVisible(wrapper.findDrawerTriggerById('pro-help').toSelector(), true);

await expect(page.isDisplayed('[data-testid="drawer-sticky-footer"]')).resolves.toBe(false);
Expand Down Expand Up @@ -151,11 +179,13 @@ describe('Visual refresh toolbar only', () => {
await page.setWindowSize({ ...viewports.desktop, width: 1700 });
await page.click(wrapper.findDrawerTriggerById('security').toSelector());
await page.click(wrapper.findDrawerTriggerById('circle-global').toSelector());
await page.click(wrapper.findDrawerTriggerById('circle2-global').toSelector());
await page.click(wrapper.findDrawerTriggerById('global-with-stored-state').toSelector());

await expect(page.isClickable(findDrawerById(wrapper, 'security')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'circle-global')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'circle2-global')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'global-with-stored-state')!.toSelector())).resolves.toBe(
true
);
})
);

Expand All @@ -165,7 +195,7 @@ describe('Visual refresh toolbar only', () => {
setupTest(async page => {
await page.setWindowSize({ ...viewports.desktop, width: 1600 });
await page.click(wrapper.findDrawerTriggerById('circle-global').toSelector());
await page.click(wrapper.findDrawerTriggerById('circle2-global').toSelector());
await page.click(wrapper.findDrawerTriggerById('global-with-stored-state').toSelector());

// resize an active drawer to take up all available space
await page.dragAndDrop(wrapper.findActiveDrawerResizeHandle().toSelector(), -600);
Expand All @@ -174,7 +204,9 @@ describe('Visual refresh toolbar only', () => {

await expect(page.isClickable(findDrawerById(wrapper, 'security')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'circle-global')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'circle2-global')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'global-with-stored-state')!.toSelector())).resolves.toBe(
true
);
})
);

Expand All @@ -183,12 +215,14 @@ describe('Visual refresh toolbar only', () => {
setupTest(async page => {
await page.setWindowSize({ ...viewports.desktop, width: 1400 });
await page.click(wrapper.findDrawerTriggerById('circle-global').toSelector());
await page.click(wrapper.findDrawerTriggerById('circle2-global').toSelector());
await page.click(wrapper.findDrawerTriggerById('global-with-stored-state').toSelector());
await page.click(wrapper.findDrawerTriggerById('security').toSelector());

await expect(page.isClickable(findDrawerById(wrapper, 'circle-global')!.toSelector())).resolves.toBe(false);
await expect(page.isClickable(findDrawerById(wrapper, 'security')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'circle2-global')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'global-with-stored-state')!.toSelector())).resolves.toBe(
true
);
})
);

Expand All @@ -199,12 +233,14 @@ describe('Visual refresh toolbar only', () => {
await page.click(wrapper.findDrawerTriggerById('circle').toSelector());
await page.click(wrapper.findDrawerTriggerById('security').toSelector());
await page.click(wrapper.findDrawerTriggerById('circle-global').toSelector());
await page.click(wrapper.findDrawerTriggerById('circle2-global').toSelector());
await page.click(wrapper.findDrawerTriggerById('global-with-stored-state').toSelector());

await expect(page.isClickable(findDrawerById(wrapper, 'circle')!.toSelector())).resolves.toBe(false);
await expect(page.isClickable(findDrawerById(wrapper, 'security')!.toSelector())).resolves.toBe(false);
await expect(page.isClickable(findDrawerById(wrapper, 'circle-global')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'circle2-global')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'global-with-stored-state')!.toSelector())).resolves.toBe(
true
);
})
);
});
Expand All @@ -214,28 +250,34 @@ describe('Visual refresh toolbar only', () => {
setupTest(async page => {
await page.setWindowSize({ ...viewports.desktop, width: 1600 });
await page.click(wrapper.findDrawerTriggerById('circle').toSelector());
await page.click(wrapper.findDrawerTriggerById('circle2-global').toSelector());
await page.click(wrapper.findDrawerTriggerById('global-with-stored-state').toSelector());
await page.click(wrapper.findDrawerTriggerById('circle3-global').toSelector());

await expect(page.isClickable(wrapper.findNavigation().toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'circle')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'circle2-global')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'global-with-stored-state')!.toSelector())).resolves.toBe(
true
);
await expect(page.isClickable(findDrawerById(wrapper, 'circle3-global')!.toSelector())).resolves.toBe(true);
await expect(page.hasHorizontalScroll()).resolves.toBe(false);

await page.setWindowSize({ ...viewports.desktop, width: 1185 });
// navigation panel closes first
await expect(page.isClickable(wrapper.findNavigation().toSelector())).resolves.toBe(false);
await expect(page.isClickable(findDrawerById(wrapper, 'circle')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'circle2-global')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'global-with-stored-state')!.toSelector())).resolves.toBe(
true
);
await expect(page.isClickable(findDrawerById(wrapper, 'circle3-global')!.toSelector())).resolves.toBe(true);
await expect(page.hasHorizontalScroll()).resolves.toBe(false);

await page.setWindowSize({ ...viewports.desktop, width: 900 });
// then the first opened drawer closes
await expect(page.isClickable(wrapper.findNavigation().toSelector())).resolves.toBe(false);
await expect(page.isClickable(findDrawerById(wrapper, 'circle')!.toSelector())).resolves.toBe(false);
await expect(page.isClickable(findDrawerById(wrapper, 'circle2-global')!.toSelector())).resolves.toBe(true);
await expect(page.isClickable(findDrawerById(wrapper, 'global-with-stored-state')!.toSelector())).resolves.toBe(
true
);
await expect(page.isClickable(findDrawerById(wrapper, 'circle3-global')!.toSelector())).resolves.toBe(true);
await expect(page.hasHorizontalScroll()).resolves.toBe(false);
})
Expand Down
13 changes: 11 additions & 2 deletions src/app-layout/utils/use-pointer-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ export const usePointerEvents = ({ position, panelRef, handleRef, onResize }: Si
);

const onDocumentPointerUp = useCallback(() => {
if (!panelRef || !panelRef.current) {
const panelElement = panelRef?.current;
/* istanbul ignore if */
if (!panelElement) {
return;
}
const document = panelElement.ownerDocument;

document.body.classList.remove(styles['resize-active']);
document.body.classList.remove(styles[`resize-${position}`]);
Expand All @@ -52,11 +55,17 @@ export const usePointerEvents = ({ position, panelRef, handleRef, onResize }: Si
}, [panelRef, onDocumentPointerMove, position]);

const onSliderPointerDown = useCallback(() => {
const panelElement = panelRef?.current;
/* istanbul ignore if */
if (!panelElement) {
return;
}
const document = panelElement.ownerDocument;
document.body.classList.add(styles['resize-active']);
document.body.classList.add(styles[`resize-${position}`]);
document.addEventListener('pointerup', onDocumentPointerUp);
document.addEventListener('pointermove', onDocumentPointerMove);
}, [onDocumentPointerMove, onDocumentPointerUp, position]);
}, [panelRef, onDocumentPointerMove, onDocumentPointerUp, position]);

return onSliderPointerDown;
};

0 comments on commit 2df6dbd

Please sign in to comment.