From a571916d265151d2d6b89fd8c702ee9745a9dec8 Mon Sep 17 00:00:00 2001 From: Pavithra Kodmad Date: Thu, 11 Aug 2022 13:17:42 +1000 Subject: [PATCH 1/5] Add interaction tests for pagelayout sticky Maybe add a wait Remove wait times --- src/PageLayout/PageLayout.stories.tsx | 45 +-- src/PageLayout/interaction.stories.tsx | 399 +++++++++++++++++++++++++ 2 files changed, 427 insertions(+), 17 deletions(-) create mode 100644 src/PageLayout/interaction.stories.tsx diff --git a/src/PageLayout/PageLayout.stories.tsx b/src/PageLayout/PageLayout.stories.tsx index 83ddf55db28..190d72c9baa 100644 --- a/src/PageLayout/PageLayout.stories.tsx +++ b/src/PageLayout/PageLayout.stories.tsx @@ -489,27 +489,38 @@ export const StickyPane: Story = args => ( - {Array.from({length: args.numParagraphsInContent}).map((_, i) => ( - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at enim id lorem tempus egestas a non ipsum. - Maecenas imperdiet ante quam, at varius lorem molestie vel. Sed at eros consequat, varius tellus et, auctor - felis. Donec pulvinar lacinia urna nec commodo. Phasellus at imperdiet risus. Donec sit amet massa purus. - Nunc sem lectus, bibendum a sapien nec, tristique tempus felis. Ut porttitor auctor tellus in imperdiet. Ut - blandit tincidunt augue, quis fringilla nunc tincidunt sed. Vestibulum auctor euismod nisi. Nullam tincidunt - est in mi tincidunt dictum. Sed consectetur aliquet velit ut ornare. - - ))} + {Array.from({length: args.numParagraphsInContent}).map((_, i) => { + const testId = `content${i}` + return ( + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at enim id lorem tempus egestas a non + ipsum. Maecenas imperdiet ante quam, at varius lorem molestie vel. Sed at eros consequat, varius tellus + et, auctor felis. Donec pulvinar lacinia urna nec commodo. Phasellus at imperdiet risus. Donec sit amet + massa purus. Nunc sem lectus, bibendum a sapien nec, tristique tempus felis. Ut porttitor auctor tellus + in imperdiet. Ut blandit tincidunt augue, quis fringilla nunc tincidunt sed. Vestibulum auctor euismod + nisi. Nullam tincidunt est in mi tincidunt dictum. Sed consectetur aliquet velit ut ornare. + + + ) + })} - {Array.from({length: args.numParagraphsInPane}).map((_, i) => ( - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at enim id lorem tempus egestas a non ipsum. - Maecenas imperdiet ante quam, at varius lorem molestie vel. Sed at eros consequat, varius tellus et, auctor - felis. Donec pulvinar lacinia urna nec commodo. Phasellus at imperdiet risus. Donec sit amet massa purus. - - ))} + {Array.from({length: args.numParagraphsInPane}).map((_, i) => { + const testId = `paragraph${i}` + return ( + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at enim id lorem tempus egestas a non + ipsum. Maecenas imperdiet ante quam, at varius lorem molestie vel. Sed at eros consequat, varius tellus + et, auctor felis. Donec pulvinar lacinia urna nec commodo. Phasellus at imperdiet risus. Donec sit amet + massa purus. + + + ) + })} diff --git a/src/PageLayout/interaction.stories.tsx b/src/PageLayout/interaction.stories.tsx new file mode 100644 index 00000000000..30e89e3a2bf --- /dev/null +++ b/src/PageLayout/interaction.stories.tsx @@ -0,0 +1,399 @@ +import {Meta} from '@storybook/react' +import {StickyPane} from './PageLayout.stories' +import {within} from '@storybook/testing-library' +import {expect} from '@storybook/jest' + +const meta: Meta = { + title: 'Layout/PageLayout/interactions', + // component: PageLayout, + parameters: { + layout: 'fullscreen', + controls: {expanded: true} + }, + argTypes: { + // Debug controls + 'Render header?': { + type: 'boolean', + defaultValue: true, + table: {category: 'Debug'} + }, + 'Render pane?': { + type: 'boolean', + defaultValue: true, + table: {category: 'Debug'} + }, + 'Render footer?': { + type: 'boolean', + defaultValue: true, + table: {category: 'Debug'} + }, + 'Header placeholder height': { + type: 'number', + defaultValue: 64, + table: {category: 'Debug'} + }, + 'Pane placeholder height': { + type: 'number', + defaultValue: 200, + table: {category: 'Debug'} + }, + 'Content placeholder height': { + type: 'number', + defaultValue: 400, + table: {category: 'Debug'} + }, + 'Footer placeholder height': { + type: 'number', + defaultValue: 64, + table: {category: 'Debug'} + }, + + // PageLayout prop controls + containerWidth: { + type: { + name: 'enum', + value: ['full', 'medium', 'large', 'xlarge'] + }, + defaultValue: 'xlarge', + control: {type: 'radio'}, + table: {category: 'PageLayout props'} + }, + padding: { + type: { + name: 'enum', + value: ['none', 'condensed', 'normal'] + }, + defaultValue: 'normal', + control: {type: 'radio'}, + table: {category: 'PageLayout props'} + }, + rowGap: { + type: { + name: 'enum', + value: ['none', 'condensed', 'normal'] + }, + defaultValue: 'normal', + control: {type: 'radio'}, + table: {category: 'PageLayout props'} + }, + columnGap: { + type: { + name: 'enum', + value: ['none', 'condensed', 'normal'] + }, + defaultValue: 'normal', + control: {type: 'radio'}, + table: {category: 'PageLayout props'} + }, + + // Header prop controls + 'Header.divider.regular': { + type: { + name: 'enum', + value: ['none', 'line'] + }, + defaultValue: 'none', + control: { + type: 'radio' + }, + table: { + category: 'Header props' + } + }, + 'Header.divider.narrow': { + type: { + name: 'enum', + value: ['none', 'line', 'filled'] + }, + defaultValue: 'none', + control: { + type: 'radio' + }, + table: { + category: 'Header props' + } + }, + 'Header.divider.wide': { + type: { + name: 'enum', + value: ['none', 'line'] + }, + defaultValue: 'none', + control: { + type: 'radio' + }, + table: { + category: 'Header props' + } + }, + 'Header.padding': { + type: { + name: 'enum', + value: ['none', 'condensed', 'normal'] + }, + defaultValue: 'none', + control: {type: 'radio'}, + table: {category: 'Header props'} + }, + 'Header.hidden.regular': { + type: 'boolean', + defaultValue: false, + table: {category: 'Header props'} + }, + 'Header.hidden.narrow': { + type: 'boolean', + defaultValue: false, + table: {category: 'Header props'} + }, + 'Header.hidden.wide': { + type: 'boolean', + defaultValue: false, + table: {category: 'Header props'} + }, + + // Content prop controls + 'Content.width': { + type: { + name: 'enum', + value: ['full', 'medium', 'large', 'xlarge'] + }, + defaultValue: 'full', + control: {type: 'radio'}, + table: {category: 'Content props'} + }, + 'Content.padding': { + type: { + name: 'enum', + value: ['none', 'condensed', 'normal'] + }, + defaultValue: 'none', + control: {type: 'radio'}, + table: {category: 'Content props'} + }, + 'Content.hidden.regular': { + type: 'boolean', + defaultValue: false, + table: {category: 'Content props'} + }, + 'Content.hidden.narrow': { + type: 'boolean', + defaultValue: false, + table: {category: 'Content props'} + }, + 'Content.hidden.wide': { + type: 'boolean', + defaultValue: false, + table: {category: 'Content props'} + }, + + // Pane prop controls + 'Pane.position.regular': { + type: { + name: 'enum', + value: ['start', 'end'] + }, + defaultValue: 'end', + control: {type: 'radio'}, + table: {category: 'Pane props'} + }, + 'Pane.position.narrow': { + type: { + name: 'enum', + value: ['start', 'end'] + }, + defaultValue: 'end', + control: {type: 'radio'}, + table: {category: 'Pane props'} + }, + 'Pane.position.wide': { + type: { + name: 'enum', + value: ['start', 'end'] + }, + defaultValue: 'end', + control: {type: 'radio'}, + table: {category: 'Pane props'} + }, + 'Pane.width': { + type: { + name: 'enum', + value: ['small', 'medium', 'large'] + }, + defaultValue: 'medium', + control: {type: 'radio'}, + table: {category: 'Pane props'} + }, + 'Pane.sticky': { + type: 'boolean', + defaultValue: false, + table: {category: 'Pane props'} + }, + 'Pane.padding': { + type: { + name: 'enum', + value: ['none', 'condensed', 'normal'] + }, + defaultValue: 'none', + control: {type: 'radio'}, + table: {category: 'Pane props'} + }, + 'Pane.divider.regular': { + type: { + name: 'enum', + value: ['none', 'line'] + }, + defaultValue: 'none', + control: {type: 'radio'}, + table: {category: 'Pane props'} + }, + 'Pane.divider.narrow': { + type: { + name: 'enum', + value: ['none', 'line', 'filled'] + }, + defaultValue: 'none', + control: {type: 'radio'}, + table: {category: 'Pane props'} + }, + 'Pane.divider.wide': { + type: { + name: 'enum', + value: ['none', 'line'] + }, + defaultValue: 'none', + control: {type: 'radio'}, + table: {category: 'Pane props'} + }, + + // Footer prop controls + 'Footer.divider.regular': { + type: { + name: 'enum', + value: ['none', 'line'] + }, + defaultValue: 'none', + control: { + type: 'radio' + }, + table: { + category: 'Footer props' + } + }, + 'Footer.divider.narrow': { + type: { + name: 'enum', + value: ['none', 'line', 'filled'] + }, + defaultValue: 'none', + control: { + type: 'radio' + }, + table: { + category: 'Footer props' + } + }, + 'Footer.divider.wide': { + type: { + name: 'enum', + value: ['none', 'line'] + }, + defaultValue: 'none', + control: { + type: 'radio' + }, + table: { + category: 'Footer props' + } + }, + 'Footer.padding': { + type: { + name: 'enum', + value: ['none', 'condensed', 'normal'] + }, + defaultValue: 'none', + control: {type: 'radio'}, + table: {category: 'Footer props'} + }, + 'Footer.hidden.regular': { + type: 'boolean', + defaultValue: false, + table: {category: 'Footer props'} + }, + 'Footer.hidden.narrow': { + type: 'boolean', + defaultValue: false, + table: {category: 'Footer props'} + }, + 'Footer.hidden.wide': { + type: 'boolean', + defaultValue: false, + table: {category: 'Footer props'} + } + } +} + +StickyPane.argTypes = { + sticky: { + type: 'boolean', + defaultValue: true + }, + numParagraphsInPane: { + type: 'number', + defaultValue: 3 + }, + numParagraphsInContent: { + type: 'number', + defaultValue: 30 + } +} + +const isInViewPort = (boundingRect: {top: number; left: number; right: number; bottom: number}) => { + return ( + boundingRect.top >= 0 && + boundingRect.left >= 0 && + boundingRect.right <= document.documentElement.clientWidth && + boundingRect.bottom <= document.documentElement.clientHeight + ) +} + +StickyPane.play = async ({canvasElement}: {canvasElement: HTMLElement}) => { + const canvas = within(canvasElement) + const content3 = await canvas.getByTestId('content3') + content3.scrollIntoView() + const paragraph0 = await canvas.getByTestId('paragraph0') + const paragraphRect = paragraph0.getBoundingClientRect() + expect(isInViewPort(paragraphRect)).toBe(true) + const paragraph2 = await canvas.getByTestId('paragraph2') + const paragraphRect2 = paragraph2.getBoundingClientRect() + expect(isInViewPort(paragraphRect2)).toBe(false) +} + +const NonStickyPane = StickyPane.bind({}) +NonStickyPane.argTypes = { + sticky: { + type: 'boolean', + defaultValue: false + }, + numParagraphsInPane: { + type: 'number', + defaultValue: 6 + }, + numParagraphsInContent: { + type: 'number', + defaultValue: 30 + } +} + +NonStickyPane.play = async ({canvasElement}: {canvasElement: HTMLElement}) => { + const canvas = within(canvasElement) + const content3 = await canvas.getByTestId('content3') + content3.scrollIntoView() + const paragraph0 = await canvas.getByTestId('paragraph0') + const paragraphRect = paragraph0.getBoundingClientRect() + expect(isInViewPort(paragraphRect)).toBe(false) + const paragraph2 = await canvas.getByTestId('paragraph2') + const paragraphRect2 = paragraph2.getBoundingClientRect() + expect(isInViewPort(paragraphRect2)).toBe(true) +} +export default meta +export {StickyPane, NonStickyPane} From e9ba58531b02f75f15dbb334a6ccc96d299f3e48 Mon Sep 17 00:00:00 2001 From: Pavithra Kodmad Date: Thu, 18 Aug 2022 16:29:46 +1000 Subject: [PATCH 2/5] The second check makes things flaky --- src/PageLayout/interaction.stories.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/PageLayout/interaction.stories.tsx b/src/PageLayout/interaction.stories.tsx index 30e89e3a2bf..adc9a7981e8 100644 --- a/src/PageLayout/interaction.stories.tsx +++ b/src/PageLayout/interaction.stories.tsx @@ -363,9 +363,6 @@ StickyPane.play = async ({canvasElement}: {canvasElement: HTMLElement}) => { const paragraph0 = await canvas.getByTestId('paragraph0') const paragraphRect = paragraph0.getBoundingClientRect() expect(isInViewPort(paragraphRect)).toBe(true) - const paragraph2 = await canvas.getByTestId('paragraph2') - const paragraphRect2 = paragraph2.getBoundingClientRect() - expect(isInViewPort(paragraphRect2)).toBe(false) } const NonStickyPane = StickyPane.bind({}) @@ -391,9 +388,6 @@ NonStickyPane.play = async ({canvasElement}: {canvasElement: HTMLElement}) => { const paragraph0 = await canvas.getByTestId('paragraph0') const paragraphRect = paragraph0.getBoundingClientRect() expect(isInViewPort(paragraphRect)).toBe(false) - const paragraph2 = await canvas.getByTestId('paragraph2') - const paragraphRect2 = paragraph2.getBoundingClientRect() - expect(isInViewPort(paragraphRect2)).toBe(true) } export default meta export {StickyPane, NonStickyPane} From 2de9c8e5b4c160326c13e41a499d13b2171e8bc6 Mon Sep 17 00:00:00 2001 From: Armagan Ersoz Date: Mon, 22 Aug 2022 15:14:11 +1000 Subject: [PATCH 3/5] add interaction tests for custom sticky header --- src/PageLayout/PageLayout.stories.tsx | 52 ++++++++++++++++---------- src/PageLayout/interaction.stories.tsx | 43 +++++++++++++++++++-- 2 files changed, 72 insertions(+), 23 deletions(-) diff --git a/src/PageLayout/PageLayout.stories.tsx b/src/PageLayout/PageLayout.stories.tsx index 190d72c9baa..ce34d512d3e 100644 --- a/src/PageLayout/PageLayout.stories.tsx +++ b/src/PageLayout/PageLayout.stories.tsx @@ -600,8 +600,9 @@ NestedScrollContainer.argTypes = { export const CustomStickyHeader: Story = args => ( // a box to create a sticky top element that will be on the consumer side and outside of the PageLayout component - + ( - - {Array.from({length: args.numParagraphsInContent}).map((_, i) => ( - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at enim id lorem tempus egestas a non ipsum. - Maecenas imperdiet ante quam, at varius lorem molestie vel. Sed at eros consequat, varius tellus et, - auctor felis. Donec pulvinar lacinia urna nec commodo. Phasellus at imperdiet risus. Donec sit amet massa - purus. Nunc sem lectus, bibendum a sapien nec, tristique tempus felis. Ut porttitor auctor tellus in - imperdiet. Ut blandit tincidunt augue, quis fringilla nunc tincidunt sed. Vestibulum auctor euismod nisi. - Nullam tincidunt est in mi tincidunt dictum. Sed consectetur aliquet velit ut ornare. - - ))} + + {Array.from({length: args.numParagraphsInContent}).map((_, i) => { + const testId = `content${i}` + return ( + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at enim id lorem tempus egestas a non + ipsum. Maecenas imperdiet ante quam, at varius lorem molestie vel. Sed at eros consequat, varius + tellus et, auctor felis. Donec pulvinar lacinia urna nec commodo. Phasellus at imperdiet risus. Donec + sit amet massa purus. Nunc sem lectus, bibendum a sapien nec, tristique tempus felis. Ut porttitor + auctor tellus in imperdiet. Ut blandit tincidunt augue, quis fringilla nunc tincidunt sed. Vestibulum + auctor euismod nisi. Nullam tincidunt est in mi tincidunt dictum. Sed consectetur aliquet velit ut + ornare. + + + ) + })} - {Array.from({length: args.numParagraphsInPane}).map((_, i) => ( - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at enim id lorem tempus egestas a non ipsum. - Maecenas imperdiet ante quam, at varius lorem molestie vel. Sed at eros consequat, varius tellus et, - auctor felis. Donec pulvinar lacinia urna nec commodo. Phasellus at imperdiet risus. Donec sit amet massa - purus. - - ))} + {Array.from({length: args.numParagraphsInPane}).map((_, i) => { + const testId = `paragraph${i}` + return ( + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at enim id lorem tempus egestas a non + ipsum. Maecenas imperdiet ante quam, at varius lorem molestie vel. Sed at eros consequat, varius + tellus et, auctor felis. Donec pulvinar lacinia urna nec commodo. Phasellus at imperdiet risus. Donec + sit amet massa purus. + + + ) + })} diff --git a/src/PageLayout/interaction.stories.tsx b/src/PageLayout/interaction.stories.tsx index adc9a7981e8..28cf8cb1edc 100644 --- a/src/PageLayout/interaction.stories.tsx +++ b/src/PageLayout/interaction.stories.tsx @@ -1,7 +1,8 @@ import {Meta} from '@storybook/react' -import {StickyPane} from './PageLayout.stories' -import {within} from '@storybook/testing-library' +import {StickyPane, CustomStickyHeader} from './PageLayout.stories' +import {within, fireEvent} from '@storybook/testing-library' import {expect} from '@storybook/jest' +import {setTimeout} from 'timers/promises' const meta: Meta = { title: 'Layout/PageLayout/interactions', @@ -389,5 +390,41 @@ NonStickyPane.play = async ({canvasElement}: {canvasElement: HTMLElement}) => { const paragraphRect = paragraph0.getBoundingClientRect() expect(isInViewPort(paragraphRect)).toBe(false) } + +CustomStickyHeader.argTypes = { + sticky: { + type: 'boolean', + defaultValue: true + }, + stickyTop: { + type: 'string', + defaultValue: '8rem' + }, + numParagraphsInPane: { + type: 'number', + defaultValue: 10 + }, + numParagraphsInContent: { + type: 'number', + defaultValue: 30 + } +} + +CustomStickyHeader.play = async ({canvasElement}: {canvasElement: HTMLElement}) => { + const canvas = within(canvasElement) + const contentToScroll = await canvas.getByTestId('content3') + contentToScroll.scrollIntoView() + + // fireEvent alternative? + const storyWindow = await canvas.getByTestId('story-window') + await fireEvent.scroll(storyWindow, {top: 600}) + + const stickyPaneFirstParagraph = await canvas.getByTestId('paragraph0') + const paragraphBoundaries = stickyPaneFirstParagraph.getBoundingClientRect() + const stickyHeader = await canvas.getByTestId('sticky-header') + const stickyHeaderBoundaries = stickyHeader.getBoundingClientRect() + expect(isInViewPort(paragraphBoundaries)).toBe(true) + expect(isInViewPort(stickyHeaderBoundaries)).toBe(true) +} export default meta -export {StickyPane, NonStickyPane} +export {StickyPane, NonStickyPane, CustomStickyHeader} From f67bd6199ca60336dc612e10d37aaba4a9f7c7f8 Mon Sep 17 00:00:00 2001 From: Armagan Ersoz Date: Mon, 22 Aug 2022 15:15:41 +1000 Subject: [PATCH 4/5] remove unnecessary import --- src/PageLayout/interaction.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/PageLayout/interaction.stories.tsx b/src/PageLayout/interaction.stories.tsx index 28cf8cb1edc..9f6a3159c84 100644 --- a/src/PageLayout/interaction.stories.tsx +++ b/src/PageLayout/interaction.stories.tsx @@ -2,7 +2,6 @@ import {Meta} from '@storybook/react' import {StickyPane, CustomStickyHeader} from './PageLayout.stories' import {within, fireEvent} from '@storybook/testing-library' import {expect} from '@storybook/jest' -import {setTimeout} from 'timers/promises' const meta: Meta = { title: 'Layout/PageLayout/interactions', From ef49be1a06c10943f597ea0a92452a9855e23488 Mon Sep 17 00:00:00 2001 From: Armagan Ersoz Date: Tue, 30 Aug 2022 09:53:36 +1000 Subject: [PATCH 5/5] remove fireEvent scroll --- src/PageLayout/interaction.stories.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/PageLayout/interaction.stories.tsx b/src/PageLayout/interaction.stories.tsx index 9f6a3159c84..6c225176b0d 100644 --- a/src/PageLayout/interaction.stories.tsx +++ b/src/PageLayout/interaction.stories.tsx @@ -1,6 +1,6 @@ import {Meta} from '@storybook/react' import {StickyPane, CustomStickyHeader} from './PageLayout.stories' -import {within, fireEvent} from '@storybook/testing-library' +import {within} from '@storybook/testing-library' import {expect} from '@storybook/jest' const meta: Meta = { @@ -414,10 +414,6 @@ CustomStickyHeader.play = async ({canvasElement}: {canvasElement: HTMLElement}) const contentToScroll = await canvas.getByTestId('content3') contentToScroll.scrollIntoView() - // fireEvent alternative? - const storyWindow = await canvas.getByTestId('story-window') - await fireEvent.scroll(storyWindow, {top: 600}) - const stickyPaneFirstParagraph = await canvas.getByTestId('paragraph0') const paragraphBoundaries = stickyPaneFirstParagraph.getBoundingClientRect() const stickyHeader = await canvas.getByTestId('sticky-header')