Skip to content

Commit

Permalink
Update exercise 2: cypress components
Browse files Browse the repository at this point in the history
  • Loading branch information
marcysutton committed May 12, 2022
1 parent 6147c66 commit fcd0411
Show file tree
Hide file tree
Showing 12 changed files with 435 additions and 342 deletions.
1 change: 0 additions & 1 deletion components/meganav/meganav-section.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const MegaNavSection = React.forwardRef((props, ref) => {
`}
>
<SubNavButton
aria-expanded={props.activeMenu === ref}
buttonName={props.buttonName}
className="megamenu-navitem header-main-item"
idRef={props.id}
Expand Down
5 changes: 2 additions & 3 deletions components/meganav/subnav-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ import PropTypes from 'prop-types'

const SubNavButton = React.forwardRef((props, ref) => (
<h2>
<button
aria-expanded={props['aria-expanded']}
<div
className="megamenu-navitem header-main-item"
id={props.idRef}
data-testid={props.idRef}
onClick={(event) => { props.onClick(event) }}
ref={ref}
>
{props.buttonName}
</button>
</div>
</h2>
))

Expand Down
4 changes: 2 additions & 2 deletions cypress.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"component": {
"componentFolder": "exercise2-cypress-components",
"testFiles": "**/*spec.{js,jsx,ts,tsx}"
"testFiles": "**/*test.{js,jsx,ts,tsx}"
},
"integrationFolder": "exercise3-cypress-integration",
"testFiles": "**/*.spec.{js,jsx,ts,tsx}",
"testFiles": "**/*.test.{js,jsx,ts,tsx}",
"video": false
}
3 changes: 3 additions & 0 deletions exercise2-cypress-components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ Using a mounted component in Cypress, write tests that assert the following beha
- Activating the menu via click
- Asserting focus doesn’t go to items in the closed menu
- Asserting focus does go to items in the open menu

Your tests should go into `exercise2-cypress-components/meganav.test.js`. You
can also peek at the tests written in the answers directory!
19 changes: 16 additions & 3 deletions exercise2-cypress-components/answer/meganav.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import * as React from 'react'
import { mount } from '@cypress/react'
import MegaNav from 'components/meganav/index'

describe('MegaNav', () => {
import MegaNav from './meganav/index'

xdescribe('MegaNav', () => {
beforeEach(() => {
mount(<MegaNav />)
cy.injectAxe()
})

it('should operate with the keyboard via toggle buttons', () => {
Expand All @@ -24,7 +26,7 @@ describe('MegaNav', () => {
})
})

it('should operate submenus with the keyboard', () => {
it('should reach open submenu items with the keyboard', () => {
cy.get('button[data-testid="megamenu-section2"]').focus().click()

cy.focused().realPress('Tab')
Expand All @@ -33,4 +35,15 @@ describe('MegaNav', () => {
expect($el).to.have.attr('data-testid', 'link-0')
})
})

it('should have no accessibility issues when open', () => {
cy.get('button[data-testid="megamenu-section1"]').click()

cy.checkA11y(null, {
runOnly: {
type: 'rule',
values: ['color-contrast']
}
})
})
})
72 changes: 72 additions & 0 deletions exercise2-cypress-components/answer/meganav/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { useEffect, useRef, useState } from "react"

import "/components/meganav/meganav.scss"
import MegaNavSection from "./meganav-section"


const MegaNav = () => {
const [activeMenu, setActiveMenu] = useState()
const navRef = useRef()
const menu1 = useRef()
const menu2 = useRef()
const menu3 = useRef()

useEffect(() => {
if (activeMenu) {
document.addEventListener('mouseup', clickOutside)
} else {
document.removeEventListener('mouseup', clickOutside)
}
return () => {
document.removeEventListener('mouseup', clickOutside)
}
}, [activeMenu])

const clickOutside = (event) => {
if (!navRef.current.contains(event.target)) {
setActiveMenu()
}
}
const handleEscape = (event) => {
if (event.key === 'Escape' && activeMenu) {
setActiveMenu()
}
}
const navItemClick = (menuRef) => {
if (activeMenu === menuRef) {
setActiveMenu()
} else {
setActiveMenu(menuRef)
}
}
return (
<nav
id="header-megamenu"
onKeyUp={(event) => { handleEscape(event) }}
ref={navRef}
>
<MegaNavSection
activeMenu={activeMenu}
id="megamenu-section1"
buttonName="Plan Your Trip"
ref={menu1}
onClick={() => { navItemClick(menu1) }}
/>
<MegaNavSection
activeMenu={activeMenu}
id="megamenu-section2"
buttonName="Ways to Stay"
ref={menu2}
onClick={() => { navItemClick(menu2) }}
/>
<MegaNavSection
activeMenu={activeMenu}
id="megamenu-section3"
buttonName="Resources"
ref={menu3}
onClick={() => { navItemClick(menu3) }}
/>
</nav>
)
}
export default MegaNav
48 changes: 48 additions & 0 deletions exercise2-cypress-components/answer/meganav/meganav-section.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from "react"
import LoadedImageUrl from "/components/utils/loaded-image-url"

import navMap from "/data/nav-map.json"
import * as imageMap from "../../../images/meganav/*.{jpg,svg}"

import SubNavButton from './subnav-button'
import SubNavLinkGroup from '/components/meganav/subnav-link-group'
import SubNavImageBlock from '/components/meganav/subnav-image-block'

const MegaNavSection = React.forwardRef((props, ref) => {
const linkGroups = navMap[props.id].linkGroups
let imageLinkBlocks
if (navMap[props.id].imageLinkBlocks) {
imageLinkBlocks = navMap[props.id].imageLinkBlocks
}
return (
<div
className={`
megamenu-section
${props.activeMenu === ref ? 'active' : ''}
`}
>
<SubNavButton
aria-expanded={props.activeMenu === ref}
buttonName={props.buttonName}
className="megamenu-navitem header-main-item"
idRef={props.id}
onClick={(ref) => { props.onClick(ref) }}
ref={ref}
>
</SubNavButton>

<div className="megamenu-submenu" role="region" aria-labelledby={props.id}>
{linkGroups.map((group, index) => {
return <SubNavLinkGroup key={index} headerText={group.headerText} items={group.items} logoLinkRef={props.logoLinkRef} />
})}
{imageLinkBlocks && imageLinkBlocks.map((block, index) => {
const imageUrl = LoadedImageUrl(imageMap, block.imgSrc)
const iconUrl = LoadedImageUrl(imageMap, block.iconSrc)
return <SubNavImageBlock key={index} imgSrc={imageUrl} iconSrc={iconUrl} linkText={block.linkText} url={block.url} />
})}
</div>
</div>
)
})

export default MegaNavSection
47 changes: 0 additions & 47 deletions exercise2-cypress-components/meganav.spec.js

This file was deleted.

16 changes: 16 additions & 0 deletions exercise2-cypress-components/meganav.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as React from 'react'
import { mount } from '@cypress/react'

import MegaNav from 'components/meganav'

describe('MegaNav', () => {
beforeEach(() => {
mount(<MegaNav />)
})

it('should operate with the keyboard via toggle buttons', () => {
cy.get('[data-testid="megamenu-section1"]').focus().click()

cy.focused().should('have.attr', 'aria-expanded', 'true')
})
})
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@
"@testing-library/jest-dom": "^5.15.0",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^14.1.1",
"axe-core": "^4.3.5",
"axe-core": "^4.4.1",
"babel-jest": "^27.3.1",
"babel-loader": "^8.2.3",
"copy-webpack-plugin": "6",
"cypress": "^9.0.0",
"cypress-axe": "^0.13.0",
"cypress-axe": "^0.14.0",
"cypress-real-events": "^1.5.1",
"jest": "^27.3.1",
"jest-puppeteer": "^6.0.0",
Expand Down
Loading

0 comments on commit fcd0411

Please sign in to comment.