Skip to content

Commit

Permalink
test: page in various screens (#3736)
Browse files Browse the repository at this point in the history
  • Loading branch information
sashuk authored Jul 26, 2023
1 parent f40f08e commit 2f9735a
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 58 deletions.
7 changes: 7 additions & 0 deletions .changeset/three-spiders-doubt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@toptal/picasso': minor
---

### PageHamburgerPortal

- disable portal for page menu dropdown
97 changes: 94 additions & 3 deletions cypress/component/Page.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,43 @@
import React from 'react'
import type { PageSidebarProps } from '@toptal/picasso'
import { Container, Menu, Page, Typography } from '@toptal/picasso'
import { getCheckpoints } from '@toptal/picasso/test-utils'

const component = 'Page'
const containerHeight = '30rem'

const checkpoints = getCheckpoints()

// Sidebar menu has custom breakpoint at 1280px that changes its behavior, so 1280px
// acts as a divider for "small" and "wide" page checkpoints
const smallScreenCheckpoints = [
...checkpoints.filter(width => width < 1280),
1279,
]
const wideScreenCheckpoints = [
1280,
...checkpoints.filter(width => width >= 1280),
]

const responsiveHappoTargets = [
...smallScreenCheckpoints,
...wideScreenCheckpoints,
].reduce<Record<string, any>>((acc, width) => {
const name = `chrome-desktop-width-${width}`

acc[name] = {
name,
browser: 'chrome',
viewport: `${width}x1024`,
}

return acc
}, {})

enum TestIds {
WRAPPER = 'wrapper',
SIDEBAR_SCROLLABLE_CONTAINER = 'sidebar-scrollable-container',
MENU_CONTAINER = 'menu-container',
}

const Paragraph = () => (
Expand Down Expand Up @@ -35,7 +65,7 @@ const Sidebar = (props: PageSidebarProps) => (
}}
{...props}
>
<Page.Sidebar.Menu>
<Page.Sidebar.Menu data-testid={TestIds.MENU_CONTAINER}>
<Page.Sidebar.Item selected>Overview</Page.Sidebar.Item>
<Page.Sidebar.Item>Jobs</Page.Sidebar.Item>
<Page.Sidebar.Item>Candidates</Page.Sidebar.Item>
Expand Down Expand Up @@ -100,8 +130,12 @@ const Example = ({ sidebarProps }: ExampleProps) => (
data-testid={TestIds.WRAPPER}
style={{ height: containerHeight, overflowY: 'scroll' }}
>
<Page hamburgerId='banner-and-sidebar-example'>
<Page.TopBar rightContent={<RightContent />} title='Default example' />
<Page>
<Page.TopBar
rightContent={<RightContent />}
title='Default example'
testIds={{ hamburger: 'hamburger-button' }}
/>
<Page.Banner>
We are now in the process of reviewing your profile. After your profile
has been checked, we will reach to you via email about next steps.
Expand Down Expand Up @@ -168,4 +202,61 @@ describe('Page', () => {
})
})
})

describe('for screen sizes smaller than 1280px', () => {
Cypress._.each(smallScreenCheckpoints, width => {
describe(`when page is rendered on a ${width} screen width`, () => {
it('renders hamburger menu and hides sidebar', () => {
cy.viewport(width, 1000)
cy.mount(<Example />)

cy.get('body').happoScreenshot({
component,
variant: `page-menu-screen-smaller-than-1280/${width}-initial`,
targets: [responsiveHappoTargets[`chrome-desktop-width-${width}`]],
})

cy.getByTestId('hamburger-button').should('be.visible')
cy.getByTestId('hamburger-button').realClick()

cy.getByTestId(TestIds.MENU_CONTAINER).should('be.visible')

cy.get('body').happoScreenshot({
component,
variant: `page-menu-screen-smaller-than-1280/${width}-opened-menu`,
targets: [responsiveHappoTargets[`chrome-desktop-width-${width}`]],
})

cy.getByTestId('hamburger-button').realClick()

cy.getByTestId(TestIds.MENU_CONTAINER).should('not.visible')

cy.get('body').happoScreenshot({
component,
variant: `page-menu-screen-smaller-than-1280/${width}-closed-menu`,
targets: [responsiveHappoTargets[`chrome-desktop-width-${width}`]],
})
})
})
})
})

describe('for screen sizes equal or bigger than 1280px', () => {
Cypress._.each(wideScreenCheckpoints, width => {
describe(`when page is rendered on a ${width} screen width`, () => {
it('does not show hamburger menu button and renders sidebar', () => {
cy.viewport(width, 1000)
cy.mount(<Example />)

cy.getByTestId('hamburger-button').should('not.be.visible')

cy.get('body').happoScreenshot({
component,
variant: `page-menu-screen-bigger-or-equal-than-1280/${width}-default`,
targets: [responsiveHappoTargets[`chrome-desktop-width-${width}`]],
})
})
})
})
})
})
4 changes: 4 additions & 0 deletions cypress/component/PageSidebar.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ describe('Sidebar', () => {

cy.getByTestId(TestIds.SIDEBAR_CONTAINER).realHover()

cy.getByTestId(TestIds.ITEM_TEXT_CONTENT).should('not.exist')

cy.get('body').happoScreenshot({
component,
variant: 'collapsed sidebar default',
Expand All @@ -203,6 +205,8 @@ describe('Sidebar', () => {
cy.getByTestId(TestIds.SIDEBAR_CONTAINER).realHover()
cy.getByTestId(TestIds.SIDEBAR_COLLAPSE_BUTTON).realClick()

cy.getByTestId(TestIds.ITEM_TEXT_CONTENT).should('exist')

cy.get('body').happoScreenshot({ component, variant: 'expand sidebar' })
})
})
Expand Down
4 changes: 4 additions & 0 deletions packages/picasso/src/PageHamburger/PageHamburger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ const PageHamburger = ({ id, 'data-testid': dataTestId }: Props) => {
content: classes.responsiveWrapperContent,
popper: classes.popper,
}}
// The "disablePortal" is needed for testing the dropdown hamburger menu in Cypress.
// Without it, React fails to create portal inside of portal (via `createPortal()`), so
// the problem needs to be further debugged on React code level.
disablePortal
popperOptions={{
modifiers: {
flip: { enabled: false },
Expand Down
1 change: 0 additions & 1 deletion packages/picasso/src/PageHamburger/PageHamburgerPortal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const PageHamburgerPortal = ({ children }: Props) => {

useEffect(() => {
setIsMounted(true)

if (hamburgerRef?.current) {
setContainer(hamburgerRef.current)
}
Expand Down
108 changes: 54 additions & 54 deletions packages/picasso/src/PageTopBar/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,24 @@ exports[`Page.TopBar render with custom logo 1`] = `
</span>
</button>
</div>
<div
class="PicassoPopper-root PicassoDropdown-popper PageHamburger-popper"
role="navigation"
style="position: fixed; top: 0px; left: 0px; display: none;"
>
<div>
<div
class="MuiPaper-root PicassoDropdown-content PageHamburger-responsiveWrapperContent MuiPaper-elevation2"
style="opacity: 0; transform: scale(0.75, 0.5625); visibility: hidden;"
>
<div>
<div
id="hamburger"
/>
</div>
</div>
</div>
</div>
</div>
<div>
Custom logo content
Expand Down Expand Up @@ -75,24 +93,6 @@ exports[`Page.TopBar render with custom logo 1`] = `
</div>
</header>
</div>
<div
class="PicassoPopper-root PicassoDropdown-popper PageHamburger-popper"
role="navigation"
style="position: fixed; top: 0px; left: 0px; display: none;"
>
<div>
<div
class="MuiPaper-root PicassoDropdown-content PageHamburger-responsiveWrapperContent MuiPaper-elevation2"
style="opacity: 0; transform: scale(0.75, 0.5625); visibility: hidden;"
>
<div>
<div
id="hamburger"
/>
</div>
</div>
</div>
</div>
</div>
</div>
`;
Expand Down Expand Up @@ -144,6 +144,24 @@ exports[`Page.TopBar render with link 1`] = `
</span>
</button>
</div>
<div
class="PicassoPopper-root PicassoDropdown-popper PageHamburger-popper"
role="navigation"
style="position: fixed; top: 0px; left: 0px; display: none;"
>
<div>
<div
class="MuiPaper-root PicassoDropdown-content PageHamburger-responsiveWrapperContent MuiPaper-elevation2"
style="opacity: 0; transform: scale(0.75, 0.5625); visibility: hidden;"
>
<div>
<div
id="hamburger"
/>
</div>
</div>
</div>
</div>
</div>
<a
class="MuiTypography-root MuiLink-root MuiLink-underlineHover PicassoLink-root PicassoLink-blue MuiTypography-colorPrimary"
Expand Down Expand Up @@ -198,24 +216,6 @@ exports[`Page.TopBar render with link 1`] = `
</div>
</header>
</div>
<div
class="PicassoPopper-root PicassoDropdown-popper PageHamburger-popper"
role="navigation"
style="position: fixed; top: 0px; left: 0px; display: none;"
>
<div>
<div
class="MuiPaper-root PicassoDropdown-content PageHamburger-responsiveWrapperContent MuiPaper-elevation2"
style="opacity: 0; transform: scale(0.75, 0.5625); visibility: hidden;"
>
<div>
<div
id="hamburger"
/>
</div>
</div>
</div>
</div>
</div>
</div>
`;
Expand Down Expand Up @@ -267,6 +267,24 @@ exports[`Page.TopBar renders 1`] = `
</span>
</button>
</div>
<div
class="PicassoPopper-root PicassoDropdown-popper PageHamburger-popper"
role="navigation"
style="position: fixed; top: 0px; left: 0px; display: none;"
>
<div>
<div
class="MuiPaper-root PicassoDropdown-content PageHamburger-responsiveWrapperContent MuiPaper-elevation2"
style="opacity: 0; transform: scale(0.75, 0.5625); visibility: hidden;"
>
<div>
<div
id="hamburger"
/>
</div>
</div>
</div>
</div>
</div>
<svg
class="PicassoSvgLogoEmblem-root PicassoLogo-root PicassoLogo-white PicassoTopBar-logoEmblem"
Expand Down Expand Up @@ -316,24 +334,6 @@ exports[`Page.TopBar renders 1`] = `
</div>
</header>
</div>
<div
class="PicassoPopper-root PicassoDropdown-popper PageHamburger-popper"
role="navigation"
style="position: fixed; top: 0px; left: 0px; display: none;"
>
<div>
<div
class="MuiPaper-root PicassoDropdown-content PageHamburger-responsiveWrapperContent MuiPaper-elevation2"
style="opacity: 0; transform: scale(0.75, 0.5625); visibility: hidden;"
>
<div>
<div
id="hamburger"
/>
</div>
</div>
</div>
</div>
</div>
</div>
`;
25 changes: 25 additions & 0 deletions packages/picasso/src/test-utils/get-checkpoints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { PicassoBreakpoints } from '@toptal/picasso-provider'

/**
* Produces an array of checkpoints – screen size values, needed for covering
* all existing breakpoints in tests (checkpoints are different from breakpoints
* by certain offset).
*
* @returns {number[]} Array of checkpoints
*/
export const getCheckpoints = () => {
const offset = 1
const breakpointValues = Object.values(
PicassoBreakpoints.breakpoints.values
).sort((valueA, valueB) => valueA - valueB)

return [
...breakpointValues
// Skip the first breakpoint as it equals to 0
.slice(1)
// Genereate checkpoints by subtsracting offset from each breakpoint
.map(breakpointValue => breakpointValue - offset),
// Add the last checkpoint that covers screens wider that the last breakpoint
breakpointValues[breakpointValues.length - 1] + offset,
]
}
1 change: 1 addition & 0 deletions packages/picasso/src/test-utils/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ const customRender = (

export * from '@testing-library/react'
export { customRender as render, TestingPicasso }
export { getCheckpoints } from './get-checkpoints'
1 change: 1 addition & 0 deletions tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"*": ["@types/*"],
"~/*": ["./*"],
"@toptal/picasso/*": ["node_modules/@toptal/picasso/src/*"],
"@toptal/picasso-provider/*": ["node_modules/@toptal/picasso-provider/src/*"],
"@toptal/*": ["node_modules/@toptal/*/src"]
}
},
Expand Down

0 comments on commit 2f9735a

Please sign in to comment.