1
0

radio-group.spec.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. import { haveAttribute, haveFocus, html, notHaveFocus, test } from '../../../utils'
  2. test('it works using x-model',
  3. [html`
  4. <main x-data="{ active: null, access: [
  5. {
  6. id: 'access-1',
  7. name: 'Public access',
  8. description: 'This project would be available to anyone who has the link',
  9. disabled: false,
  10. },
  11. {
  12. id: 'access-2',
  13. name: 'Private to Project Members',
  14. description: 'Only members of this project would be able to access',
  15. disabled: false,
  16. },
  17. {
  18. id: 'access-3',
  19. name: 'Private to you',
  20. description: 'You are the only one able to access this project',
  21. disabled: true,
  22. },
  23. {
  24. id: 'access-4',
  25. name: 'Private to you',
  26. description: 'You are the only one able to access this project',
  27. disabled: false,
  28. },
  29. ]}">
  30. <div x-radio-group x-model="active">
  31. <fieldset>
  32. <legend>
  33. <h2 x-radio-group:label>Privacy setting</h2>
  34. </legend>
  35. <div>
  36. <template x-for="({ id, name, description, disabled }, i) in access" :key="id">
  37. <div :option="id" x-radio-group:option :value="id" :disabled="disabled">
  38. <span x-radio-group:label x-text="name"></span>
  39. <span x-radio-group:description x-text="description"></span>
  40. </div>
  41. </template>
  42. </div>
  43. </fieldset>
  44. </div>
  45. <input x-model="active" type="hidden">
  46. </main>
  47. `],
  48. ({ get }) => {
  49. get('input').should(haveAttribute('value', ''))
  50. get('[option="access-2"]').click()
  51. get('input').should(haveAttribute('value', 'access-2'))
  52. get('[option="access-4"]').click()
  53. get('input').should(haveAttribute('value', 'access-4'))
  54. },
  55. )
  56. test('cannot select any option when the group is disabled',
  57. [html`
  58. <main x-data="{ active: null, access: [
  59. {
  60. id: 'access-1',
  61. name: 'Public access',
  62. description: 'This project would be available to anyone who has the link',
  63. disabled: false,
  64. },
  65. {
  66. id: 'access-2',
  67. name: 'Private to Project Members',
  68. description: 'Only members of this project would be able to access',
  69. disabled: false,
  70. },
  71. {
  72. id: 'access-3',
  73. name: 'Private to you',
  74. description: 'You are the only one able to access this project',
  75. disabled: true,
  76. },
  77. {
  78. id: 'access-4',
  79. name: 'Private to you',
  80. description: 'You are the only one able to access this project',
  81. disabled: false,
  82. },
  83. ]}">
  84. <div x-radio-group x-model="active" :disabled="true">
  85. <fieldset>
  86. <legend>
  87. <h2 x-radio-group:label>Privacy setting</h2>
  88. </legend>
  89. <div>
  90. <template x-for="({ id, name, description, disabled }, i) in access" :key="id">
  91. <div :option="id" x-radio-group:option :value="id" :disabled="disabled">
  92. <span x-radio-group:label x-text="name"></span>
  93. <span x-radio-group:description x-text="description"></span>
  94. </div>
  95. </template>
  96. </div>
  97. </fieldset>
  98. </div>
  99. <input x-model="active" type="hidden">
  100. </main>
  101. `],
  102. ({ get }) => {
  103. get('input').should(haveAttribute('value', ''))
  104. get('[option="access-1"]').click()
  105. get('input').should(haveAttribute('value', ''))
  106. },
  107. )
  108. test('cannot select a disabled option',
  109. [html`
  110. <main x-data="{ active: null, access: [
  111. {
  112. id: 'access-1',
  113. name: 'Public access',
  114. description: 'This project would be available to anyone who has the link',
  115. disabled: false,
  116. },
  117. {
  118. id: 'access-2',
  119. name: 'Private to Project Members',
  120. description: 'Only members of this project would be able to access',
  121. disabled: false,
  122. },
  123. {
  124. id: 'access-3',
  125. name: 'Private to you',
  126. description: 'You are the only one able to access this project',
  127. disabled: true,
  128. },
  129. {
  130. id: 'access-4',
  131. name: 'Private to you',
  132. description: 'You are the only one able to access this project',
  133. disabled: false,
  134. },
  135. ]}">
  136. <div x-radio-group x-model="active">
  137. <fieldset>
  138. <legend>
  139. <h2 x-radio-group:label>Privacy setting</h2>
  140. </legend>
  141. <div>
  142. <template x-for="({ id, name, description, disabled }, i) in access" :key="id">
  143. <div :option="id" x-radio-group:option :value="id" :disabled="disabled">
  144. <span x-radio-group:label x-text="name"></span>
  145. <span x-radio-group:description x-text="description"></span>
  146. </div>
  147. </template>
  148. </div>
  149. </fieldset>
  150. </div>
  151. <input x-model="active" type="hidden">
  152. </main>
  153. `],
  154. ({ get }) => {
  155. get('input').should(haveAttribute('value', ''))
  156. get('[option="access-3"]').click()
  157. get('input').should(haveAttribute('value', ''))
  158. },
  159. )
  160. test('keyboard navigation works',
  161. [html`
  162. <main x-data="{ active: null, access: [
  163. {
  164. id: 'access-1',
  165. name: 'Public access',
  166. description: 'This project would be available to anyone who has the link',
  167. disabled: false,
  168. },
  169. {
  170. id: 'access-2',
  171. name: 'Private to Project Members',
  172. description: 'Only members of this project would be able to access',
  173. disabled: false,
  174. },
  175. {
  176. id: 'access-3',
  177. name: 'Private to you',
  178. description: 'You are the only one able to access this project',
  179. disabled: true,
  180. },
  181. {
  182. id: 'access-4',
  183. name: 'Private to you',
  184. description: 'You are the only one able to access this project',
  185. disabled: false,
  186. },
  187. ]}">
  188. <div x-radio-group x-model="active">
  189. <fieldset>
  190. <legend>
  191. <h2 x-radio-group:label>Privacy setting</h2>
  192. </legend>
  193. <div>
  194. <template x-for="({ id, name, description, disabled }, i) in access" :key="id">
  195. <div :option="id" x-radio-group:option :value="id" :disabled="disabled">
  196. <span x-radio-group:label x-text="name"></span>
  197. <span x-radio-group:description x-text="description"></span>
  198. </div>
  199. </template>
  200. </div>
  201. </fieldset>
  202. </div>
  203. <input x-model="active" type="hidden">
  204. </main>
  205. `],
  206. ({ get }) => {
  207. get('input').should(haveAttribute('value', ''))
  208. get('[option="access-1"]').focus().type('{downarrow}')
  209. get('[option="access-2"]').should(haveFocus()).type('{downarrow}')
  210. get('[option="access-4"]').should(haveFocus()).type('{downarrow}')
  211. get('[option="access-1"]').should(haveFocus())
  212. },
  213. )
  214. test('has accessibility attributes',
  215. [html`
  216. <main x-data="{ active: null, options: [
  217. {
  218. id: 'access-1',
  219. name: 'Public access',
  220. description: 'This project would be available to anyone who has the link',
  221. disabled: false,
  222. },
  223. {
  224. id: 'access-2',
  225. name: 'Private to Project Members',
  226. description: 'Only members of this project would be able to access',
  227. disabled: false,
  228. },
  229. {
  230. id: 'access-3',
  231. name: 'Private to you',
  232. description: 'You are the only one able to access this project',
  233. disabled: true,
  234. },
  235. {
  236. id: 'access-4',
  237. name: 'Private to you',
  238. description: 'You are the only one able to access this project',
  239. disabled: false,
  240. },
  241. ]}">
  242. <div x-radio-group group x-model="active">
  243. <fieldset>
  244. <legend>
  245. <h2 x-radio-group:label>Privacy setting</h2>
  246. <p x-radio-group:description>Some description</p>
  247. </legend>
  248. <div>
  249. <template x-for="({ id, name, description, disabled }, i) in options" :key="id">
  250. <div :option="id" x-radio-group:option="({ value: id, disabled: disabled })">
  251. <span :label="id" x-radio-group:label x-text="name"></span>
  252. <span :description="id" x-radio-group:description x-text="description"></span>
  253. </div>
  254. </template>
  255. </div>
  256. </fieldset>
  257. </div>
  258. </main>
  259. `],
  260. ({ get }) => {
  261. get('[group]').should(haveAttribute('role', 'radiogroup'))
  262. .should(haveAttribute('aria-labelledby', 'alpine-radiogroup-label-1'))
  263. .should(haveAttribute('aria-describedby', 'alpine-radiogroup-description-1'))
  264. get('h2').should(haveAttribute('id', 'alpine-radiogroup-label-1'))
  265. get('p').should(haveAttribute('id', 'alpine-radiogroup-description-1'))
  266. get('[option="access-1"]')
  267. .should(haveAttribute('tabindex', 0))
  268. for (i in 4) {
  269. get(`[option="access-${i}"]`)
  270. .should(haveAttribute('role', 'radio'))
  271. .should(haveAttribute('aria-disabled', 'false'))
  272. .should(haveAttribute('aria-labelledby', `alpine-radiogroup-label-${i + 1}`))
  273. .should(haveAttribute('aria-describedby', `alpine-radiogroup-description-${i + 1}`))
  274. get(`[label="access-${i}"]`)
  275. .should(haveAttribute('id', `alpine-radiogroup-label-${i + 1}`))
  276. get(`[description="access-${i}"]`)
  277. .should(haveAttribute('id', `alpine-radiogroup-description-${i + 1}`))
  278. }
  279. get('[option="access-1"]')
  280. .click()
  281. .should(haveAttribute('aria-checked', 'true'))
  282. },
  283. )