dialog.spec.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. import { beVisible, haveAttribute, haveText, html, notBeVisible, notExist, test } from '../../../utils'
  2. test('has accessibility attributes',
  3. [html`
  4. <div x-data="{ open: false }">
  5. <button @click="open = ! open">Toggle</button>
  6. <article x-dialog x-model="open">
  7. Dialog Contents!
  8. </article>
  9. </div>
  10. `],
  11. ({ get }) => {
  12. get('article').should(haveAttribute('role', 'dialog'))
  13. get('article').should(haveAttribute('aria-modal', 'true'))
  14. },
  15. )
  16. test('works with x-model',
  17. [html`
  18. <div x-data="{ open: false }">
  19. <button @click="open = ! open">Toggle</button>
  20. <article x-dialog x-model="open">
  21. Dialog Contents!
  22. </article>
  23. </div>
  24. `],
  25. ({ get }) => {
  26. get('article').should(notBeVisible())
  27. get('button').click()
  28. get('article').should(beVisible())
  29. get('button').click()
  30. get('article').should(notBeVisible())
  31. },
  32. )
  33. test('works with open prop and close event',
  34. [html`
  35. <div x-data="{ open: false }">
  36. <button @click="open = ! open">Toggle</button>
  37. <article x-dialog :open="open" @close="open = false">
  38. Dialog Contents!
  39. </article>
  40. </div>
  41. `],
  42. ({ get }) => {
  43. get('article').should(notBeVisible())
  44. get('button').click()
  45. get('article').should(beVisible())
  46. },
  47. )
  48. test('works with static prop',
  49. [html`
  50. <div x-data="{ open: false }">
  51. <button @click="open = ! open">Toggle</button>
  52. <template x-if="open">
  53. <article x-dialog static>
  54. Dialog Contents!
  55. </article>
  56. </template>
  57. </div>
  58. `],
  59. ({ get }) => {
  60. get('article').should(notExist())
  61. get('button').click()
  62. get('article').should(beVisible())
  63. },
  64. )
  65. test('pressing escape closes modal',
  66. [html`
  67. <div x-data="{ open: false }">
  68. <button @click="open = ! open">Toggle</button>
  69. <article x-dialog x-model="open">
  70. Dialog Contents!
  71. <input type="text">
  72. </article>
  73. </div>
  74. `],
  75. ({ get }) => {
  76. get('article').should(notBeVisible())
  77. get('button').click()
  78. get('article').should(beVisible())
  79. get('input').type('{esc}')
  80. get('article').should(notBeVisible())
  81. },
  82. )
  83. test('x-dialog:panel allows for click away',
  84. [html`
  85. <div x-data="{ open: true }">
  86. <h1>Click away on me</h1>
  87. <article x-dialog x-model="open">
  88. <div x-dialog:panel>
  89. Dialog Contents!
  90. </div>
  91. </article>
  92. </div>
  93. `],
  94. ({ get }) => {
  95. get('article').should(beVisible())
  96. get('h1').click()
  97. get('article').should(notBeVisible())
  98. },
  99. )
  100. test('x-dialog:overlay closes dialog when clicked on',
  101. [html`
  102. <div x-data="{ open: true }">
  103. <h1>Click away on me</h1>
  104. <article x-dialog x-model="open">
  105. <main x-dialog:overlay>
  106. Some Overlay
  107. </main>
  108. <div>
  109. Dialog Contents!
  110. </div>
  111. </article>
  112. </div>
  113. `],
  114. ({ get }) => {
  115. get('article').should(beVisible())
  116. get('h1').click()
  117. get('article').should(beVisible())
  118. get('main').click()
  119. get('article').should(notBeVisible())
  120. },
  121. )
  122. test('x-dialog:title',
  123. [html`
  124. <article x-data x-dialog>
  125. <h1 x-dialog:title>Dialog Title</h1>
  126. </article>
  127. `],
  128. ({ get }) => {
  129. get('article').should(haveAttribute('aria-labelledby', 'alpine-dialog-title-1'))
  130. get('h1').should(haveAttribute('id', 'alpine-dialog-title-1'))
  131. },
  132. )
  133. test('x-dialog:description',
  134. [html`
  135. <article x-data x-dialog>
  136. <p x-dialog:description>Dialog Title</p>
  137. </article>
  138. `],
  139. ({ get }) => {
  140. get('article').should(haveAttribute('aria-describedby', 'alpine-dialog-description-1'))
  141. get('p').should(haveAttribute('id', 'alpine-dialog-description-1'))
  142. },
  143. )
  144. test('$modal.open exposes internal "open" state',
  145. [html`
  146. <div x-data="{ open: false }">
  147. <button @click="open = ! open">Toggle</button>
  148. <article x-dialog x-model="open">
  149. Dialog Contents!
  150. <h2 x-text="$dialog.open"></h2>
  151. </article>
  152. </div>
  153. `],
  154. ({ get }) => {
  155. get('h2').should(haveText('false'))
  156. get('button').click()
  157. get('h2').should(haveText('true'))
  158. },
  159. )
  160. test('works with x-teleport',
  161. [html`
  162. <div x-data="{ open: false }">
  163. <button @click="open = ! open">Toggle</button>
  164. <template x-teleport="body">
  165. <article x-dialog x-model="open">
  166. Dialog Contents!
  167. </article>
  168. </template>
  169. </div>
  170. `],
  171. ({ get }) => {
  172. get('article').should(notBeVisible())
  173. get('button').click()
  174. get('article').should(beVisible())
  175. get('button').click()
  176. get('article').should(notBeVisible())
  177. },
  178. )
  179. // Skipping these two tests as anything focus related seems to be flaky
  180. // with cypress, but fine in a real browser.
  181. // test('x-dialog traps focus'...
  182. // test('initial-focus prop'...