modal.spec.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { useState } from 'react'
  2. import {
  3. OLModal,
  4. OLModalHeader,
  5. OLModalBody,
  6. OLModalFooter,
  7. OLModalTitle,
  8. } from '@/shared/components/ol/ol-modal'
  9. function Modal({ backdrop }: { backdrop?: boolean | 'static' } = {}) {
  10. const [isModalOpen, setIsModalOpen] = useState(false)
  11. return (
  12. <div>
  13. <button onClick={() => setIsModalOpen(true)}>Open modal</button>
  14. <OLModal
  15. show={isModalOpen}
  16. onHide={() => setIsModalOpen(false)}
  17. backdrop={backdrop}
  18. >
  19. <OLModalHeader>
  20. <OLModalTitle>This is a focus trap modal</OLModalTitle>
  21. </OLModalHeader>
  22. <OLModalBody>
  23. <p>This is for testing the modal behaviour</p>
  24. <label htmlFor="modal-input">Enter text:&nbsp;</label>
  25. <input id="modal-input" />
  26. </OLModalBody>
  27. <OLModalFooter>
  28. <button onClick={() => setIsModalOpen(false)}>Close the modal</button>
  29. </OLModalFooter>
  30. </OLModal>
  31. </div>
  32. )
  33. }
  34. describe('<OLModal />', function () {
  35. it('dismisses on single Escape key press', function () {
  36. cy.mount(<Modal />)
  37. cy.findByRole('button', { name: 'Open modal' }).should('be.visible')
  38. cy.findByRole('dialog').should('not.exist')
  39. cy.findByRole('button', { name: 'Open modal' }).click()
  40. cy.findByRole('dialog').should('be.visible')
  41. cy.findByLabelText(/enter text/i).should('be.visible')
  42. cy.findByRole('button', { name: 'Close dialog' }).click()
  43. // Modal should hide with single escape (escapeDeactivates: false means FocusTrap doesn't handle it)
  44. cy.findByRole('dialog').should('not.exist')
  45. cy.findByRole('button', { name: 'Open modal' }).should('be.visible')
  46. })
  47. it('dismisses when clicking outside of the modal (backdrop: true)', function () {
  48. cy.mount(<Modal />)
  49. cy.findByRole('button', { name: 'Open modal' }).click()
  50. cy.findByRole('dialog').should('be.visible')
  51. cy.get('body').click(0, 0)
  52. cy.findByRole('dialog').should('not.exist')
  53. })
  54. it('does not dismiss when clicking outside of the modal (backdrop: "static")', function () {
  55. cy.mount(<Modal backdrop="static" />)
  56. cy.findByRole('button', { name: 'Open modal' }).click()
  57. cy.findByRole('dialog').should('be.visible')
  58. cy.get('body').click(0, 0)
  59. cy.findByRole('dialog').should('be.visible')
  60. })
  61. it('traps focus within modal', function () {
  62. cy.mount(<Modal />)
  63. cy.findByRole('button', { name: 'Open modal' }).click()
  64. cy.findByRole('dialog').should('be.visible')
  65. cy.findByRole('button', { name: 'Close dialog' }).should('be.focused')
  66. cy.focused().tab()
  67. cy.findByLabelText(/enter text/i).should('be.focused')
  68. cy.focused().tab()
  69. cy.findByRole('button', { name: 'Close the modal' }).should('be.focused')
  70. cy.focused().tab()
  71. cy.findByRole('button', { name: 'Close dialog' }).should('be.focused')
  72. cy.focused().tab({ shift: true })
  73. cy.findByRole('button', { name: 'Close the modal' }).should('be.focused')
  74. })
  75. it('restores focus to trigger button after modal closes', function () {
  76. cy.mount(<Modal />)
  77. cy.findByRole('button', { name: 'Open modal' }).click()
  78. cy.findByRole('dialog').should('be.visible')
  79. cy.findByRole('button', { name: 'Close the modal' }).click()
  80. cy.findByRole('dialog').should('not.exist')
  81. cy.findByRole('button', { name: 'Open modal' }).should('be.focused')
  82. cy.focused().should('not.match', 'body')
  83. })
  84. it('closes modal when clicking close button (X)', function () {
  85. cy.mount(<Modal />)
  86. cy.findByRole('button', { name: 'Open modal' }).click()
  87. cy.findByRole('dialog').should('be.visible')
  88. cy.findByRole('button', { name: 'Close dialog' }).click()
  89. cy.findByRole('dialog').should('not.exist')
  90. })
  91. it('dismisses on Escape key with backdrop="static"', function () {
  92. cy.mount(<Modal backdrop="static" />)
  93. cy.findByRole('button', { name: 'Open modal' }).click()
  94. cy.findByRole('dialog').should('be.visible')
  95. cy.findByRole('button', { name: 'Close dialog' }).click()
  96. cy.findByRole('dialog').should('not.exist')
  97. })
  98. })