trap.spec.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import { haveText, test, html, haveFocus, notHaveAttribute, haveAttribute } from '../../utils'
  2. test('can trap focus',
  3. [html`
  4. <div x-data="{ open: false }">
  5. <input type="text" id="1">
  6. <button id="2" @click="open = true">open</button>
  7. <div>
  8. <div x-trap="open">
  9. <input type="text" id="3">
  10. <button @click="open = false" id="4">close</button>
  11. </div>
  12. </div>
  13. </div>
  14. `],
  15. ({ get }, reload) => {
  16. get('#1').click()
  17. get('#1').should(haveFocus())
  18. get('#2').click()
  19. get('#3').should(haveFocus())
  20. cy.focused().tab()
  21. get('#4').should(haveFocus())
  22. cy.focused().tab()
  23. get('#3').should(haveFocus())
  24. cy.focused().tab({shift: true})
  25. get('#4').should(haveFocus())
  26. cy.focused().click()
  27. get('#2').should(haveFocus())
  28. },
  29. )
  30. test('works with clone',
  31. [html`
  32. <div id="foo" x-data="{
  33. open: false,
  34. triggerClone() {
  35. var original = document.getElementById('foo');
  36. var copy = original.cloneNode(true);
  37. Alpine.clone(original, copy);
  38. var p = document.createElement('p');
  39. p.textContent = 'bar';
  40. copy.appendChild(p);
  41. original.parentNode.replaceChild(copy, original);
  42. }
  43. }">
  44. <button id="one" @click="open = true">Trap</button>
  45. <div x-trap="open">
  46. <input type="text">
  47. <button id="two" @click="triggerClone()">Test</button>
  48. </div>
  49. </div>
  50. `],
  51. ({ get, wait }, reload) => {
  52. get('#one').click()
  53. get('#two').click()
  54. get('p').should(haveText('bar'))
  55. }
  56. )
  57. test('can trap focus with inert',
  58. [html`
  59. <div x-data="{ open: false }">
  60. <h1>I should have aria-hidden when outside trap</h1>
  61. <button id="open" @click="open = true">open</button>
  62. <div x-trap.inert="open">
  63. <button @click="open = false" id="close">close</button>
  64. </div>
  65. </div>
  66. `],
  67. ({ get }, reload) => {
  68. get('#open').should(notHaveAttribute('aria-hidden', 'true'))
  69. get('#open').click()
  70. get('#open').should(haveAttribute('aria-hidden', 'true'))
  71. get('#close').click()
  72. get('#open').should(notHaveAttribute('aria-hidden', 'true'))
  73. },
  74. )
  75. test('can trap focus with noscroll',
  76. [html`
  77. <div x-data="{ open: false }">
  78. <button id="open" @click="open = true">open</button>
  79. <div x-trap.noscroll="open">
  80. <button @click="open = false" id="close">close</button>
  81. </div>
  82. <div style="height: 100vh">&nbsp;</div>
  83. </div>
  84. `],
  85. ({ get, window }, reload) => {
  86. window().then((win) => {
  87. let scrollbarWidth = win.innerWidth - win.document.documentElement.clientWidth
  88. get('#open').click()
  89. get('html').should(haveAttribute('style', `overflow: hidden; padding-right: ${scrollbarWidth}px;`))
  90. get('#close').click()
  91. get('html').should(notHaveAttribute('style', `overflow: hidden; padding-right: ${scrollbarWidth}px;`))
  92. })
  93. },
  94. )