| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- import { useState } from 'react'
- import {
- OLModal,
- OLModalHeader,
- OLModalBody,
- OLModalFooter,
- OLModalTitle,
- } from '@/shared/components/ol/ol-modal'
- import { Select } from '@/shared/components/select'
- type TestItem = {
- key: string
- label: string
- }
- function Modal({ backdrop }: { backdrop?: boolean | 'static' } = {}) {
- const [isModalOpen, setIsModalOpen] = useState(false)
- const testItems: TestItem[] = [
- { key: 'item1', label: 'First Item' },
- { key: 'item2', label: 'Second Item' },
- { key: 'item3', label: 'Third Item' },
- ]
- return (
- <div>
- <button onClick={() => setIsModalOpen(true)}>Open modal</button>
- <OLModal
- show={isModalOpen}
- onHide={() => setIsModalOpen(false)}
- backdrop={backdrop}
- >
- <OLModalHeader>
- <OLModalTitle>This is a focus trap modal</OLModalTitle>
- </OLModalHeader>
- <OLModalBody>
- <p>This is for testing the modal behaviour</p>
- <label htmlFor="modal-input">Enter text: </label>
- <input id="modal-input" />
- <Select
- items={testItems}
- itemToKey={item => item.key}
- itemToString={item => item?.label || ''}
- dataTestId="test-select"
- defaultText="Select an item"
- />
- </OLModalBody>
- <OLModalFooter>
- <button onClick={() => setIsModalOpen(false)}>Close the modal</button>
- </OLModalFooter>
- </OLModal>
- </div>
- )
- }
- describe('<OLModal />', function () {
- it('dismisses on single Escape key press', function () {
- cy.mount(<Modal />)
- cy.findByRole('button', { name: 'Open modal' }).should('be.visible')
- cy.findByRole('dialog').should('not.exist')
- cy.findByRole('button', { name: 'Open modal' }).click()
- cy.findByRole('dialog').should('be.visible')
- cy.findByLabelText(/enter text/i).should('be.visible')
- cy.findByRole('button', { name: 'Close dialog' }).click()
- // Modal should hide with single escape (escapeDeactivates: false means FocusTrap doesn't handle it)
- cy.findByRole('dialog').should('not.exist')
- cy.findByRole('button', { name: 'Open modal' }).should('be.visible')
- })
- it('dismisses when clicking outside of the modal (backdrop: true)', function () {
- cy.mount(<Modal />)
- cy.findByRole('button', { name: 'Open modal' }).click()
- cy.findByRole('dialog').should('be.visible')
- cy.get('body').click(0, 0)
- cy.findByRole('dialog').should('not.exist')
- })
- it('does not dismiss when clicking outside of the modal (backdrop: "static")', function () {
- cy.mount(<Modal backdrop="static" />)
- cy.findByRole('button', { name: 'Open modal' }).click()
- cy.findByRole('dialog').should('be.visible')
- cy.get('body').click(0, 0)
- cy.findByRole('dialog').should('be.visible')
- })
- it('traps focus within modal', function () {
- cy.mount(<Modal />)
- cy.findByRole('button', { name: 'Open modal' }).click()
- cy.findByRole('dialog').should('be.visible')
- cy.findByRole('button', { name: 'Close dialog' }).should('be.focused')
- cy.focused().tab()
- cy.findByLabelText(/enter text/i).should('be.focused')
- cy.focused().tab()
- cy.get('[data-testid="test-select"]').should('be.focused')
- cy.focused().tab()
- cy.findByRole('button', { name: 'Close the modal' }).should('be.focused')
- cy.focused().tab()
- cy.findByRole('button', { name: 'Close dialog' }).should('be.focused')
- cy.focused().tab({ shift: true })
- cy.findByRole('button', { name: 'Close the modal' }).should('be.focused')
- })
- it('closes select menus when the modal container is clicked on', function () {
- cy.mount(<Modal />)
- cy.findByRole('button', { name: 'Open modal' }).click()
- cy.get('[data-testid="test-select"]').click()
- cy.contains('First Item').should('be.visible')
- cy.contains('Second Item').should('be.visible')
- cy.contains('Third Item').should('be.visible')
- cy.findByText('This is for testing the modal behaviour').click()
- cy.contains('First Item').should('not.exist')
- cy.contains('Second Item').should('not.exist')
- cy.contains('Third Item').should('not.exist')
- })
- it('restores focus to trigger button after modal closes', function () {
- cy.mount(<Modal />)
- cy.findByRole('button', { name: 'Open modal' }).click()
- cy.findByRole('dialog').should('be.visible')
- cy.findByRole('button', { name: 'Close the modal' }).click()
- cy.findByRole('dialog').should('not.exist')
- cy.findByRole('button', { name: 'Open modal' }).should('be.focused')
- cy.focused().should('not.match', 'body')
- })
- it('closes modal when clicking close button (X)', function () {
- cy.mount(<Modal />)
- cy.findByRole('button', { name: 'Open modal' }).click()
- cy.findByRole('dialog').should('be.visible')
- cy.findByRole('button', { name: 'Close dialog' }).click()
- cy.findByRole('dialog').should('not.exist')
- })
- it('dismisses on Escape key with backdrop="static"', function () {
- cy.mount(<Modal backdrop="static" />)
- cy.findByRole('button', { name: 'Open modal' }).click()
- cy.findByRole('dialog').should('be.visible')
- cy.findByRole('button', { name: 'Close dialog' }).click()
- cy.findByRole('dialog').should('not.exist')
- })
- })
|