@patternfly/elements 3.0.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (371) hide show
  1. package/custom-elements.json +8857 -8783
  2. package/form-control.css +127 -0
  3. package/package.json +12 -25
  4. package/pf-accordion/pf-accordion-header.css +23 -0
  5. package/pf-accordion/pf-accordion-header.d.ts +52 -43
  6. package/pf-accordion/pf-accordion-header.js +130 -87
  7. package/pf-accordion/pf-accordion-header.js.map +1 -1
  8. package/pf-accordion/pf-accordion-panel.css +15 -0
  9. package/pf-accordion/pf-accordion-panel.d.ts +27 -25
  10. package/pf-accordion/pf-accordion-panel.js +29 -43
  11. package/pf-accordion/pf-accordion-panel.js.map +1 -1
  12. package/pf-accordion/pf-accordion.d.ts +122 -65
  13. package/pf-accordion/pf-accordion.js +283 -94
  14. package/pf-accordion/pf-accordion.js.map +1 -1
  15. package/pf-accordion/test/pf-accordion.e2e.js +12 -0
  16. package/pf-accordion/test/pf-accordion.e2e.js.map +1 -1
  17. package/pf-accordion/test/pf-accordion.spec.js +366 -350
  18. package/pf-accordion/test/pf-accordion.spec.js.map +1 -1
  19. package/pf-avatar/pf-avatar.css +50 -24
  20. package/pf-avatar/pf-avatar.d.ts +29 -3
  21. package/pf-avatar/pf-avatar.js +51 -9
  22. package/pf-avatar/pf-avatar.js.map +1 -1
  23. package/pf-avatar/test/pf-avatar.e2e.js +12 -0
  24. package/pf-avatar/test/pf-avatar.e2e.js.map +1 -1
  25. package/pf-avatar/test/pf-avatar.spec.js +2 -3
  26. package/pf-avatar/test/pf-avatar.spec.js.map +1 -1
  27. package/pf-back-to-top/pf-back-to-top.css +10 -0
  28. package/pf-back-to-top/pf-back-to-top.d.ts +14 -18
  29. package/pf-back-to-top/pf-back-to-top.js +9 -30
  30. package/pf-back-to-top/pf-back-to-top.js.map +1 -1
  31. package/pf-back-to-top/test/pf-back-to-top.e2e.js +12 -0
  32. package/pf-back-to-top/test/pf-back-to-top.e2e.js.map +1 -1
  33. package/pf-background-image/pf-background-image.d.ts +4 -4
  34. package/pf-background-image/pf-background-image.js +1 -12
  35. package/pf-background-image/pf-background-image.js.map +1 -1
  36. package/pf-background-image/test/pf-background-image.e2e.js +12 -0
  37. package/pf-background-image/test/pf-background-image.e2e.js.map +1 -1
  38. package/pf-badge/pf-badge.css +4 -0
  39. package/pf-badge/pf-badge.d.ts +26 -22
  40. package/pf-badge/pf-badge.js +14 -27
  41. package/pf-badge/pf-badge.js.map +1 -1
  42. package/pf-badge/test/pf-badge.e2e.js +12 -0
  43. package/pf-badge/test/pf-badge.e2e.js.map +1 -1
  44. package/pf-banner/pf-banner.d.ts +16 -16
  45. package/pf-banner/pf-banner.js +1 -24
  46. package/pf-banner/pf-banner.js.map +1 -1
  47. package/pf-banner/test/pf-banner.e2e.js +12 -0
  48. package/pf-banner/test/pf-banner.e2e.js.map +1 -1
  49. package/pf-button/pf-button.css +22 -12
  50. package/pf-button/pf-button.d.ts +128 -122
  51. package/pf-button/pf-button.js +95 -172
  52. package/pf-button/pf-button.js.map +1 -1
  53. package/pf-button/test/pf-button.e2e.js +12 -0
  54. package/pf-button/test/pf-button.e2e.js.map +1 -1
  55. package/pf-card/pf-card.css +172 -43
  56. package/pf-card/pf-card.d.ts +41 -38
  57. package/pf-card/pf-card.js +37 -54
  58. package/pf-card/pf-card.js.map +1 -1
  59. package/pf-card/test/pf-card.e2e.js +12 -0
  60. package/pf-card/test/pf-card.e2e.js.map +1 -1
  61. package/pf-chip/pf-chip-group.css +9 -6
  62. package/pf-chip/pf-chip-group.d.ts +27 -14
  63. package/pf-chip/pf-chip-group.js +65 -94
  64. package/pf-chip/pf-chip-group.js.map +1 -1
  65. package/pf-chip/pf-chip.d.ts +20 -9
  66. package/pf-chip/pf-chip.js +1 -8
  67. package/pf-chip/pf-chip.js.map +1 -1
  68. package/pf-chip/test/pf-chip-group.spec.js +42 -22
  69. package/pf-chip/test/pf-chip-group.spec.js.map +1 -1
  70. package/pf-chip/test/pf-chip.e2e.js +12 -0
  71. package/pf-chip/test/pf-chip.e2e.js.map +1 -1
  72. package/pf-clipboard-copy/pf-clipboard-copy.css +83 -85
  73. package/pf-clipboard-copy/pf-clipboard-copy.d.ts +53 -18
  74. package/pf-clipboard-copy/pf-clipboard-copy.js +55 -44
  75. package/pf-clipboard-copy/pf-clipboard-copy.js.map +1 -1
  76. package/pf-clipboard-copy/test/pf-clipboard-copy.e2e.js +12 -0
  77. package/pf-clipboard-copy/test/pf-clipboard-copy.e2e.js.map +1 -1
  78. package/pf-code-block/pf-code-block.css +7 -4
  79. package/pf-code-block/pf-code-block.d.ts +4 -25
  80. package/pf-code-block/pf-code-block.js +44 -23
  81. package/pf-code-block/pf-code-block.js.map +1 -1
  82. package/pf-code-block/test/pf-code-block.e2e.js +12 -0
  83. package/pf-code-block/test/pf-code-block.e2e.js.map +1 -1
  84. package/pf-dropdown/context.d.ts +2 -3
  85. package/pf-dropdown/context.js.map +1 -1
  86. package/pf-dropdown/pf-dropdown-group.d.ts +3 -9
  87. package/pf-dropdown/pf-dropdown-group.js +1 -5
  88. package/pf-dropdown/pf-dropdown-group.js.map +1 -1
  89. package/pf-dropdown/pf-dropdown-item.d.ts +21 -27
  90. package/pf-dropdown/pf-dropdown-item.js +1 -37
  91. package/pf-dropdown/pf-dropdown-item.js.map +1 -1
  92. package/pf-dropdown/pf-dropdown-menu.d.ts +4 -10
  93. package/pf-dropdown/pf-dropdown-menu.js +23 -23
  94. package/pf-dropdown/pf-dropdown-menu.js.map +1 -1
  95. package/pf-dropdown/pf-dropdown.d.ts +8 -24
  96. package/pf-dropdown/pf-dropdown.js +1 -26
  97. package/pf-dropdown/pf-dropdown.js.map +1 -1
  98. package/pf-dropdown/test/pf-dropdown.e2e.js +12 -0
  99. package/pf-dropdown/test/pf-dropdown.e2e.js.map +1 -1
  100. package/pf-icon/pf-icon.css +22 -0
  101. package/pf-icon/pf-icon.d.ts +93 -4
  102. package/pf-icon/pf-icon.js +191 -13
  103. package/pf-icon/pf-icon.js.map +1 -1
  104. package/pf-icon/test/pf-icon.e2e.js +12 -0
  105. package/pf-icon/test/pf-icon.e2e.js.map +1 -1
  106. package/pf-icon/test/pf-icon.spec.js +102 -88
  107. package/pf-icon/test/pf-icon.spec.js.map +1 -1
  108. package/pf-jump-links/pf-jump-links-item.d.ts +4 -11
  109. package/pf-jump-links/pf-jump-links-item.js +8 -15
  110. package/pf-jump-links/pf-jump-links-item.js.map +1 -1
  111. package/pf-jump-links/pf-jump-links-list.d.ts +2 -2
  112. package/pf-jump-links/pf-jump-links-list.js +1 -5
  113. package/pf-jump-links/pf-jump-links-list.js.map +1 -1
  114. package/pf-jump-links/pf-jump-links.d.ts +2 -2
  115. package/pf-jump-links/pf-jump-links.js +23 -62
  116. package/pf-jump-links/pf-jump-links.js.map +1 -1
  117. package/pf-jump-links/test/pf-jump-links.e2e.js +12 -0
  118. package/pf-jump-links/test/pf-jump-links.e2e.js.map +1 -1
  119. package/pf-label/pf-label.css +38 -5
  120. package/pf-label/pf-label.d.ts +65 -69
  121. package/pf-label/pf-label.js +49 -90
  122. package/pf-label/pf-label.js.map +1 -1
  123. package/pf-label/test/pf-label.e2e.js +12 -0
  124. package/pf-label/test/pf-label.e2e.js.map +1 -1
  125. package/pf-label/test/pf-label.spec.js +26 -16
  126. package/pf-label/test/pf-label.spec.js.map +1 -1
  127. package/pf-modal/pf-modal.d.ts +17 -22
  128. package/pf-modal/pf-modal.js +13 -39
  129. package/pf-modal/pf-modal.js.map +1 -1
  130. package/pf-modal/test/pf-modal.e2e.js +12 -0
  131. package/pf-modal/test/pf-modal.e2e.js.map +1 -1
  132. package/pf-panel/pf-panel.d.ts +31 -3
  133. package/pf-panel/pf-panel.js +1 -10
  134. package/pf-panel/pf-panel.js.map +1 -1
  135. package/pf-panel/test/pf-panel.e2e.js +12 -0
  136. package/pf-panel/test/pf-panel.e2e.js.map +1 -1
  137. package/pf-popover/pf-popover.d.ts +66 -84
  138. package/pf-popover/pf-popover.js +33 -150
  139. package/pf-popover/pf-popover.js.map +1 -1
  140. package/pf-popover/test/pf-popover.e2e.js +12 -0
  141. package/pf-popover/test/pf-popover.e2e.js.map +1 -1
  142. package/pf-popover/test/pf-popover.spec.js +0 -11
  143. package/pf-popover/test/pf-popover.spec.js.map +1 -1
  144. package/pf-progress/pf-progress.d.ts +40 -40
  145. package/pf-progress/pf-progress.js +1 -61
  146. package/pf-progress/pf-progress.js.map +1 -1
  147. package/pf-progress/test/pf-progress.e2e.js +12 -0
  148. package/pf-progress/test/pf-progress.e2e.js.map +1 -1
  149. package/pf-progress-stepper/pf-progress-step.d.ts +2 -3
  150. package/pf-progress-stepper/pf-progress-step.js +4 -14
  151. package/pf-progress-stepper/pf-progress-step.js.map +1 -1
  152. package/pf-progress-stepper/pf-progress-stepper.d.ts +118 -2
  153. package/pf-progress-stepper/pf-progress-stepper.js +10 -12
  154. package/pf-progress-stepper/pf-progress-stepper.js.map +1 -1
  155. package/pf-progress-stepper/test/pf-progress-stepper.e2e.js +12 -0
  156. package/pf-progress-stepper/test/pf-progress-stepper.e2e.js.map +1 -1
  157. package/pf-select/pf-option-group.d.ts +2 -2
  158. package/pf-select/pf-option-group.js +1 -5
  159. package/pf-select/pf-option-group.js.map +1 -1
  160. package/pf-select/pf-option.css +1 -1
  161. package/pf-select/pf-option.d.ts +4 -4
  162. package/pf-select/pf-option.js +20 -30
  163. package/pf-select/pf-option.js.map +1 -1
  164. package/pf-select/pf-select.css +14 -6
  165. package/pf-select/pf-select.d.ts +183 -40
  166. package/pf-select/pf-select.js +185 -260
  167. package/pf-select/pf-select.js.map +1 -1
  168. package/pf-select/test/pf-select.e2e.js +12 -0
  169. package/pf-select/test/pf-select.e2e.js.map +1 -1
  170. package/pf-select/test/pf-select.spec.js +1292 -613
  171. package/pf-select/test/pf-select.spec.js.map +1 -1
  172. package/pf-spinner/pf-spinner.css +27 -17
  173. package/pf-spinner/pf-spinner.d.ts +21 -17
  174. package/pf-spinner/pf-spinner.js +20 -24
  175. package/pf-spinner/pf-spinner.js.map +1 -1
  176. package/pf-spinner/test/pf-spinner.e2e.js +12 -0
  177. package/pf-spinner/test/pf-spinner.e2e.js.map +1 -1
  178. package/pf-switch/pf-switch.css +39 -13
  179. package/pf-switch/pf-switch.d.ts +48 -34
  180. package/pf-switch/pf-switch.js +114 -43
  181. package/pf-switch/pf-switch.js.map +1 -1
  182. package/pf-switch/test/pf-switch.e2e.js +12 -0
  183. package/pf-switch/test/pf-switch.e2e.js.map +1 -1
  184. package/pf-table/pf-caption.d.ts +2 -2
  185. package/pf-table/pf-caption.js +1 -4
  186. package/pf-table/pf-caption.js.map +1 -1
  187. package/pf-table/pf-table.d.ts +424 -424
  188. package/pf-table/pf-table.js +7 -645
  189. package/pf-table/pf-table.js.map +1 -1
  190. package/pf-table/pf-tbody.d.ts +2 -2
  191. package/pf-table/pf-tbody.js +1 -4
  192. package/pf-table/pf-tbody.js.map +1 -1
  193. package/pf-table/pf-td.d.ts +2 -2
  194. package/pf-table/pf-td.js +1 -4
  195. package/pf-table/pf-td.js.map +1 -1
  196. package/pf-table/pf-th.d.ts +2 -2
  197. package/pf-table/pf-th.js +1 -4
  198. package/pf-table/pf-th.js.map +1 -1
  199. package/pf-table/pf-thead.d.ts +2 -2
  200. package/pf-table/pf-thead.js +1 -4
  201. package/pf-table/pf-thead.js.map +1 -1
  202. package/pf-table/pf-tr.d.ts +1 -1
  203. package/pf-table/pf-tr.js +1 -4
  204. package/pf-table/pf-tr.js.map +1 -1
  205. package/pf-table/test/pf-table.e2e.js +12 -0
  206. package/pf-table/test/pf-table.e2e.js.map +1 -1
  207. package/pf-tabs/context.d.ts +2 -3
  208. package/pf-tabs/context.js.map +1 -1
  209. package/pf-tabs/pf-tab-panel.d.ts +3 -5
  210. package/pf-tabs/pf-tab-panel.js +1 -7
  211. package/pf-tabs/pf-tab-panel.js.map +1 -1
  212. package/pf-tabs/pf-tab.d.ts +37 -37
  213. package/pf-tabs/pf-tab.js +16 -54
  214. package/pf-tabs/pf-tab.js.map +1 -1
  215. package/pf-tabs/pf-tabs.d.ts +36 -37
  216. package/pf-tabs/pf-tabs.js +40 -78
  217. package/pf-tabs/pf-tabs.js.map +1 -1
  218. package/pf-tabs/test/pf-tabs.e2e.js +12 -0
  219. package/pf-tabs/test/pf-tabs.e2e.js.map +1 -1
  220. package/pf-tabs/test/pf-tabs.spec.js +11 -12
  221. package/pf-tabs/test/pf-tabs.spec.js.map +1 -1
  222. package/pf-text-area/pf-text-area.d.ts +128 -134
  223. package/pf-text-area/pf-text-area.js +7 -131
  224. package/pf-text-area/pf-text-area.js.map +1 -1
  225. package/pf-text-area/test/pf-text-area.e2e.js +12 -0
  226. package/pf-text-area/test/pf-text-area.e2e.js.map +1 -1
  227. package/pf-text-input/pf-text-input.d.ts +129 -135
  228. package/pf-text-input/pf-text-input.js +7 -132
  229. package/pf-text-input/pf-text-input.js.map +1 -1
  230. package/pf-text-input/test/pf-text-input.e2e.js +12 -0
  231. package/pf-text-input/test/pf-text-input.e2e.js.map +1 -1
  232. package/pf-tile/pf-tile.d.ts +21 -20
  233. package/pf-tile/pf-tile.js +18 -35
  234. package/pf-tile/pf-tile.js.map +1 -1
  235. package/pf-tile/test/pf-tile.e2e.js +12 -0
  236. package/pf-tile/test/pf-tile.e2e.js.map +1 -1
  237. package/pf-timestamp/pf-timestamp.d.ts +2 -2
  238. package/pf-timestamp/pf-timestamp.js +1 -3
  239. package/pf-timestamp/pf-timestamp.js.map +1 -1
  240. package/pf-timestamp/test/pf-timestamp.e2e.js +12 -0
  241. package/pf-timestamp/test/pf-timestamp.e2e.js.map +1 -1
  242. package/pf-tooltip/pf-tooltip.d.ts +51 -50
  243. package/pf-tooltip/pf-tooltip.js +26 -106
  244. package/pf-tooltip/pf-tooltip.js.map +1 -1
  245. package/pf-tooltip/test/pf-tooltip.e2e.js +12 -0
  246. package/pf-tooltip/test/pf-tooltip.e2e.js.map +1 -1
  247. package/pfe.min.js +1194 -1002
  248. package/pfe.min.js.map +4 -4
  249. package/react/pf-accordion/pf-accordion-header.js +2 -2
  250. package/react/pf-accordion/pf-accordion-panel.js +2 -2
  251. package/react/pf-accordion/pf-accordion.js +2 -2
  252. package/react/pf-avatar/pf-avatar.d.ts +1 -1
  253. package/react/pf-avatar/pf-avatar.js +5 -3
  254. package/react/pf-back-to-top/pf-back-to-top.js +2 -2
  255. package/react/pf-background-image/pf-background-image.js +2 -2
  256. package/react/pf-badge/pf-badge.js +2 -2
  257. package/react/pf-banner/pf-banner.js +2 -2
  258. package/react/pf-button/pf-button.js +2 -2
  259. package/react/pf-card/pf-card.js +2 -2
  260. package/react/pf-chip/pf-chip-group.js +2 -2
  261. package/react/pf-chip/pf-chip.js +2 -2
  262. package/react/pf-clipboard-copy/pf-clipboard-copy.d.ts +1 -1
  263. package/react/pf-clipboard-copy/pf-clipboard-copy.js +5 -3
  264. package/react/pf-code-block/pf-code-block.js +2 -2
  265. package/react/pf-dropdown/pf-dropdown-group.js +2 -2
  266. package/react/pf-dropdown/pf-dropdown-item.js +2 -2
  267. package/react/pf-dropdown/pf-dropdown-menu.js +2 -2
  268. package/react/pf-dropdown/pf-dropdown.js +2 -2
  269. package/react/pf-icon/pf-icon.js +2 -2
  270. package/react/pf-jump-links/pf-jump-links-item.js +2 -2
  271. package/react/pf-jump-links/pf-jump-links-list.js +2 -2
  272. package/react/pf-jump-links/pf-jump-links.js +2 -2
  273. package/react/pf-label/pf-label.js +2 -2
  274. package/react/pf-modal/pf-modal.js +2 -2
  275. package/react/pf-panel/pf-panel.js +2 -2
  276. package/react/pf-popover/pf-popover.js +2 -2
  277. package/react/pf-progress/pf-progress.js +2 -2
  278. package/react/pf-progress-stepper/pf-progress-step.js +2 -2
  279. package/react/pf-progress-stepper/pf-progress-stepper.js +2 -2
  280. package/react/pf-select/pf-option-group.js +2 -2
  281. package/react/pf-select/pf-option.js +2 -2
  282. package/react/pf-select/pf-select.d.ts +1 -1
  283. package/react/pf-select/pf-select.js +2 -3
  284. package/react/pf-spinner/pf-spinner.js +2 -2
  285. package/react/pf-switch/pf-switch.js +2 -2
  286. package/react/pf-table/pf-caption.js +2 -2
  287. package/react/pf-table/pf-table.js +2 -2
  288. package/react/pf-table/pf-tbody.js +2 -2
  289. package/react/pf-table/pf-td.js +2 -2
  290. package/react/pf-table/pf-th.js +2 -2
  291. package/react/pf-table/pf-thead.js +2 -2
  292. package/react/pf-table/pf-tr.js +2 -2
  293. package/react/pf-tabs/pf-tab-panel.js +2 -2
  294. package/react/pf-tabs/pf-tab.js +2 -2
  295. package/react/pf-tabs/pf-tabs.js +2 -2
  296. package/react/pf-text-area/pf-text-area.js +2 -2
  297. package/react/pf-text-input/pf-text-input.js +2 -2
  298. package/react/pf-tile/pf-tile.js +2 -2
  299. package/react/pf-timestamp/pf-timestamp.js +2 -2
  300. package/react/pf-tooltip/pf-tooltip.js +2 -2
  301. package/pf-accordion/BaseAccordion.d.ts +0 -61
  302. package/pf-accordion/BaseAccordion.js +0 -269
  303. package/pf-accordion/BaseAccordion.js.map +0 -1
  304. package/pf-accordion/BaseAccordionHeader.css +0 -39
  305. package/pf-accordion/BaseAccordionHeader.d.ts +0 -29
  306. package/pf-accordion/BaseAccordionHeader.js +0 -128
  307. package/pf-accordion/BaseAccordionHeader.js.map +0 -1
  308. package/pf-accordion/BaseAccordionPanel.css +0 -27
  309. package/pf-accordion/BaseAccordionPanel.d.ts +0 -7
  310. package/pf-accordion/BaseAccordionPanel.js +0 -33
  311. package/pf-accordion/BaseAccordionPanel.js.map +0 -1
  312. package/pf-avatar/BaseAvatar.css +0 -13
  313. package/pf-avatar/BaseAvatar.d.ts +0 -23
  314. package/pf-avatar/BaseAvatar.js +0 -62
  315. package/pf-avatar/BaseAvatar.js.map +0 -1
  316. package/pf-back-to-top/demo/demo.css +0 -25
  317. package/pf-badge/BaseBadge.css +0 -6
  318. package/pf-badge/BaseBadge.d.ts +0 -18
  319. package/pf-badge/BaseBadge.js +0 -16
  320. package/pf-badge/BaseBadge.js.map +0 -1
  321. package/pf-button/BaseButton.css +0 -68
  322. package/pf-button/BaseButton.d.ts +0 -51
  323. package/pf-button/BaseButton.js +0 -84
  324. package/pf-button/BaseButton.js.map +0 -1
  325. package/pf-card/BaseCard.css +0 -36
  326. package/pf-card/BaseCard.d.ts +0 -24
  327. package/pf-card/BaseCard.js +0 -51
  328. package/pf-card/BaseCard.js.map +0 -1
  329. package/pf-clipboard-copy/BaseClipboardCopy.css +0 -6
  330. package/pf-clipboard-copy/BaseClipboardCopy.d.ts +0 -18
  331. package/pf-clipboard-copy/BaseClipboardCopy.js +0 -25
  332. package/pf-clipboard-copy/BaseClipboardCopy.js.map +0 -1
  333. package/pf-code-block/BaseCodeBlock.css +0 -7
  334. package/pf-code-block/BaseCodeBlock.d.ts +0 -8
  335. package/pf-code-block/BaseCodeBlock.js +0 -22
  336. package/pf-code-block/BaseCodeBlock.js.map +0 -1
  337. package/pf-icon/BaseIcon.css +0 -22
  338. package/pf-icon/BaseIcon.d.ts +0 -41
  339. package/pf-icon/BaseIcon.js +0 -144
  340. package/pf-icon/BaseIcon.js.map +0 -1
  341. package/pf-label/BaseLabel.css +0 -44
  342. package/pf-label/BaseLabel.d.ts +0 -30
  343. package/pf-label/BaseLabel.js +0 -29
  344. package/pf-label/BaseLabel.js.map +0 -1
  345. package/pf-spinner/BaseSpinner.css +0 -20
  346. package/pf-spinner/BaseSpinner.d.ts +0 -27
  347. package/pf-spinner/BaseSpinner.js +0 -45
  348. package/pf-spinner/BaseSpinner.js.map +0 -1
  349. package/pf-switch/BaseSwitch.css +0 -36
  350. package/pf-switch/BaseSwitch.d.ts +0 -19
  351. package/pf-switch/BaseSwitch.js +0 -109
  352. package/pf-switch/BaseSwitch.js.map +0 -1
  353. package/pf-tabs/BaseTab.css +0 -60
  354. package/pf-tabs/BaseTab.d.ts +0 -32
  355. package/pf-tabs/BaseTab.js +0 -83
  356. package/pf-tabs/BaseTab.js.map +0 -1
  357. package/pf-tabs/BaseTabPanel.css +0 -7
  358. package/pf-tabs/BaseTabPanel.d.ts +0 -7
  359. package/pf-tabs/BaseTabPanel.js +0 -36
  360. package/pf-tabs/BaseTabPanel.js.map +0 -1
  361. package/pf-tabs/BaseTabs.css +0 -86
  362. package/pf-tabs/BaseTabs.d.ts +0 -38
  363. package/pf-tabs/BaseTabs.js +0 -221
  364. package/pf-tabs/BaseTabs.js.map +0 -1
  365. package/pf-tile/BaseTile.d.ts +0 -13
  366. package/pf-tile/BaseTile.js +0 -28
  367. package/pf-tile/BaseTile.js.map +0 -1
  368. package/pf-tooltip/BaseTooltip.css +0 -70
  369. package/pf-tooltip/BaseTooltip.d.ts +0 -16
  370. package/pf-tooltip/BaseTooltip.js +0 -54
  371. package/pf-tooltip/BaseTooltip.js.map +0 -1
@@ -1,18 +1,19 @@
1
- import { expect, html, nextFrame } from '@open-wc/testing';
1
+ import { expect, html, aTimeout, nextFrame } from '@open-wc/testing';
2
2
  import { createFixture } from '@patternfly/pfe-tools/test/create-fixture.js';
3
3
  import { PfSelect } from '../pf-select.js';
4
4
  import { sendKeys } from '@web/test-runner-commands';
5
- import { a11ySnapshot } from '@patternfly/pfe-tools/test/a11y-snapshot.js';
6
- async function shiftHold() {
5
+ import { a11ySnapshot, querySnapshot } from '@patternfly/pfe-tools/test/a11y-snapshot.js';
6
+ import { clickElementAtCenter, clickElementAtOffset } from '@patternfly/pfe-tools/test/utils.js';
7
+ async function holdShift() {
7
8
  await sendKeys({ down: 'Shift' });
8
9
  }
9
- async function shiftRelease() {
10
+ async function releaseShift() {
10
11
  await sendKeys({ up: 'Shift' });
11
12
  }
12
- async function ctrlA() {
13
+ async function holdCtrl() {
13
14
  await sendKeys({ down: 'Control' });
14
- await sendKeys({ down: 'a' });
15
- await sendKeys({ up: 'a' });
15
+ }
16
+ async function releaseCtrl() {
16
17
  await sendKeys({ up: 'Control' });
17
18
  }
18
19
  function press(key) {
@@ -20,32 +21,334 @@ function press(key) {
20
21
  await sendKeys({ press: key });
21
22
  };
22
23
  }
23
- function getValues(element) {
24
- return [element.selected].flat().filter(x => !!x).map(x => x.value);
24
+ /**
25
+ * Compare selection to an array of strings
26
+ * @param element pf-select
27
+ * @returns a list of values of each selected option
28
+ */
29
+ function getSelectedOptionValues(element) {
30
+ return Array.from(element.querySelectorAll('[selected]'), x => x.value);
31
+ }
32
+ // a11yShapshot does not surface the options
33
+ function getVisibleOptionValues(element) {
34
+ return element.options.filter(x => !x.hidden).map(x => x.value);
35
+ }
36
+ // a11yShapshot does not surface the options
37
+ function getActiveOption(element) {
38
+ return element.options.find(x => x.active);
39
+ }
40
+ /**
41
+ * NOTE because of the copy-to-shadow-root shtick in ActivedescendantController,
42
+ * we can't just pick an option (from light dom);
43
+ * @param element pf-select
44
+ * @param index item index
45
+ */
46
+ async function clickItemAtIndex(element, index) {
47
+ const itemHeight = 44;
48
+ await clickElementAtOffset(element, [
49
+ 10,
50
+ element.offsetHeight + (itemHeight * (index + 1)) - itemHeight / 2,
51
+ ], {
52
+ allowOutOfBounds: true,
53
+ });
25
54
  }
26
55
  describe('<pf-select>', function () {
27
- let element;
28
- const updateComplete = () => element.updateComplete;
29
- const focus = () => element.focus();
30
- describe('simply instantiating', function () {
31
- it('imperatively instantiates', function () {
32
- expect(document.createElement('pf-select')).to.be.an.instanceof(PfSelect);
33
- });
34
- it('should upgrade', async function () {
35
- element = await createFixture(html `<pf-select></pf-select>`);
36
- const klass = customElements.get('pf-select');
37
- expect(element)
38
- .to.be.an.instanceOf(klass)
39
- .and
40
- .to.be.an.instanceOf(PfSelect);
56
+ it('imperatively instantiates', function () {
57
+ expect(document.createElement('pf-select')).to.be.an.instanceof(PfSelect);
58
+ });
59
+ it('should upgrade', async function () {
60
+ expect(await createFixture(html `<pf-select></pf-select>`))
61
+ .to.be.an.instanceOf(customElements.get('pf-select'))
62
+ .and
63
+ .to.be.an.instanceOf(PfSelect);
64
+ });
65
+ describe('with accessible-label attribute and 3 items', function () {
66
+ let element;
67
+ const updateComplete = () => element.updateComplete;
68
+ const focus = () => element.focus;
69
+ beforeEach(async function () {
70
+ element = await createFixture(html `
71
+ <pf-select accessible-label="label">
72
+ <pf-option value="1">1</pf-option>
73
+ <pf-option value="2">2</pf-option>
74
+ <pf-option value="3">3</pf-option>
75
+ </pf-select>`);
76
+ });
77
+ it('passes aXe audit', async function () {
78
+ await expect(element).to.be.accessible();
79
+ });
80
+ it('labels the combobox with the accessible-label attribuet', async function () {
81
+ expect(await a11ySnapshot()).to.axContainQuery({
82
+ role: 'combobox',
83
+ name: 'label',
84
+ });
85
+ });
86
+ it('does not have redundant role', async function () {
87
+ expect(element.shadowRoot?.firstElementChild).to.not.contain('[role="button"]');
88
+ });
89
+ it('sets aria-setsize="3" and aria-posinset on items', function () {
90
+ element.options.forEach((option, i) => {
91
+ expect(option).to.have.attr('aria-setsize', '3');
92
+ expect(option).to.have.attr('aria-posinset', `${i + 1}`);
93
+ });
94
+ });
95
+ describe('focus()', function () {
96
+ beforeEach(focus);
97
+ beforeEach(updateComplete);
98
+ describe('ArrowDown', function () {
99
+ beforeEach(press('ArrowDown'));
100
+ it('labels the listbox with the accessible-label attribute', async function () {
101
+ expect(await a11ySnapshot()).to.axContainQuery({
102
+ role: 'listbox',
103
+ name: 'label',
104
+ });
105
+ });
106
+ it('focuses on the first item', async function () {
107
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
108
+ });
109
+ describe('Space', function () {
110
+ beforeEach(press(' '));
111
+ beforeEach(updateComplete);
112
+ it('selects option 1', function () {
113
+ expect(getSelectedOptionValues(element)).to.deep.equal([
114
+ '1',
115
+ ]);
116
+ });
117
+ it('exposes selection to assistive technology', async function () {
118
+ expect(await a11ySnapshot()).to.axContainQuery({
119
+ role: 'combobox',
120
+ value: '1',
121
+ });
122
+ });
123
+ });
124
+ });
125
+ });
126
+ });
127
+ describe('with `placeholder` attribute and 3 items', function () {
128
+ let element;
129
+ const updateComplete = () => element.updateComplete;
130
+ const focus = () => element.focus;
131
+ beforeEach(async function () {
132
+ element = await createFixture(html `
133
+ <pf-select placeholder="placeholder">
134
+ <pf-option value="1">1</pf-option>
135
+ <pf-option value="2">2</pf-option>
136
+ <pf-option value="3">3</pf-option>
137
+ </pf-select>`);
138
+ });
139
+ it('passes aXe audit', async function () {
140
+ await expect(element).to.be.accessible();
141
+ });
142
+ it('labels the combobox with the placeholder attribute', async function () {
143
+ expect(await a11ySnapshot()).to.axContainQuery({
144
+ role: 'combobox',
145
+ name: 'placeholder',
146
+ });
147
+ });
148
+ it('does not have redundant role', async function () {
149
+ expect(element.shadowRoot?.firstElementChild).to.not.contain('[role="button"]');
150
+ });
151
+ it('sets aria-setsize="4" and aria-posinset on items', function () {
152
+ element.options.forEach((option, i) => {
153
+ expect(option).to.have.attr('aria-setsize', '4');
154
+ expect(option).to.have.attr('aria-posinset', `${i + 1}`);
155
+ });
156
+ });
157
+ describe('focus()', function () {
158
+ beforeEach(focus);
159
+ beforeEach(updateComplete);
160
+ describe('ArrowDown', function () {
161
+ beforeEach(press('ArrowDown'));
162
+ it('labels the listbox with the placeholder attribute', async function () {
163
+ expect(await a11ySnapshot()).to.axContainQuery({
164
+ role: 'listbox',
165
+ name: 'placeholder',
166
+ });
167
+ });
168
+ it('focuses on the placeholder item', async function () {
169
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('placeholder');
170
+ });
171
+ describe('Space', function () {
172
+ beforeEach(press(' '));
173
+ beforeEach(updateComplete);
174
+ it('selects nothing', async function () {
175
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
176
+ });
177
+ it('does not close the listbox nothing', function () {
178
+ expect(getSelectedOptionValues(element)).to.deep.equal([]);
179
+ });
180
+ describe('ArrowDown', function () {
181
+ beforeEach(press('ArrowDown'));
182
+ beforeEach(updateComplete);
183
+ it('focuses on the first item', async function () {
184
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
185
+ });
186
+ describe('Space', function () {
187
+ beforeEach(press(' '));
188
+ beforeEach(updateComplete);
189
+ it('selects option 1', function () {
190
+ expect(getSelectedOptionValues(element)).to.deep.equal([
191
+ '1',
192
+ ]);
193
+ });
194
+ it('exposes selection to assistive technology', async function () {
195
+ expect(await a11ySnapshot()).to.axContainQuery({
196
+ role: 'combobox',
197
+ value: '1',
198
+ });
199
+ });
200
+ });
201
+ });
202
+ });
203
+ });
204
+ });
205
+ });
206
+ describe('with 3 items and associated <label> elements', function () {
207
+ let element;
208
+ const updateComplete = () => element.updateComplete;
209
+ const focus = () => element.focus;
210
+ beforeEach(async function () {
211
+ element = await createFixture(html `
212
+ <pf-select id="select">
213
+ <pf-option value="1">1</pf-option>
214
+ <pf-option value="2">2</pf-option>
215
+ <pf-option value="3">3</pf-option>
216
+ </pf-select>
217
+ <label for="select">label1</label>
218
+ <label for="select">label2</label>
219
+ `);
220
+ });
221
+ it('passes aXe audit', async function () {
222
+ await expect(element).to.be.accessible();
223
+ });
224
+ it('does not have redundant role', async function () {
225
+ expect(element.shadowRoot?.firstElementChild).to.not.contain('[role="button"]');
226
+ });
227
+ it('labels the combobox with the label elements', async function () {
228
+ expect(await a11ySnapshot()).to.axContainQuery({
229
+ role: 'combobox',
230
+ name: 'label1label2',
231
+ });
232
+ });
233
+ it('sets aria-setsize="3" and aria-posinset on items', function () {
234
+ element.options.forEach((option, i) => {
235
+ expect(option).to.have.attr('aria-setsize', '3');
236
+ expect(option).to.have.attr('aria-posinset', `${i + 1}`);
237
+ });
238
+ });
239
+ describe('focus()', function () {
240
+ beforeEach(focus);
241
+ beforeEach(updateComplete);
242
+ describe('ArrowDown', function () {
243
+ beforeEach(press('ArrowDown'));
244
+ it('labels the listbox with the label elements', async function () {
245
+ expect(await a11ySnapshot()).to.axContainQuery({
246
+ role: 'listbox',
247
+ name: 'label1label2',
248
+ });
249
+ });
250
+ it('focuses on the first item', async function () {
251
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
252
+ });
253
+ describe('Space', function () {
254
+ beforeEach(press(' '));
255
+ beforeEach(updateComplete);
256
+ it('selects option 1', function () {
257
+ expect(getSelectedOptionValues(element)).to.deep.equal([
258
+ '1',
259
+ ]);
260
+ });
261
+ it('exposes selection to assistive technology', async function () {
262
+ expect(await a11ySnapshot()).to.axContainQuery({
263
+ role: 'combobox',
264
+ value: '1',
265
+ });
266
+ });
267
+ });
268
+ });
269
+ });
270
+ });
271
+ describe('in a deep shadow root', function () {
272
+ let element;
273
+ const focus = () => element.focus();
274
+ const updateComplete = () => element.updateComplete;
275
+ beforeEach(async function () {
276
+ const fixture = await createFixture(html `
277
+ <shadow-root>
278
+ <template shadowrootmode="open">
279
+ <shadow-root>
280
+ <template shadowrootmode="open">
281
+ <pf-select variant="single"
282
+ accessible-label="Choose a number"
283
+ placeholder="Choose a number">
284
+ <pf-option value="1">1</pf-option>
285
+ <pf-option value="2">2</pf-option>
286
+ <pf-option value="3">3</pf-option>
287
+ <pf-option value="4">4</pf-option>
288
+ <pf-option value="5">5</pf-option>
289
+ <pf-option value="6">6</pf-option>
290
+ <pf-option value="7">7</pf-option>
291
+ <pf-option value="8">8</pf-option>
292
+ </pf-select>
293
+ </template>
294
+ </shadow-root>
295
+ </template>
296
+ </shadow-root>`);
297
+ function attachShadowRoots(root) {
298
+ root?.querySelectorAll('template[shadowrootmode]').forEach(template => {
299
+ const mode = template.getAttribute('shadowrootmode');
300
+ const shadowRoot = template.parentElement?.attachShadow?.({ mode });
301
+ shadowRoot?.appendChild(template.content);
302
+ template.remove();
303
+ attachShadowRoots(shadowRoot);
304
+ });
305
+ }
306
+ attachShadowRoots(document);
307
+ const select = fixture.shadowRoot?.firstElementChild?.shadowRoot?.querySelector('pf-select');
308
+ if (select) {
309
+ element = select;
310
+ await element?.updateComplete;
311
+ }
312
+ else {
313
+ throw new Error('no element!');
314
+ }
315
+ });
316
+ describe('expanding', function () {
317
+ beforeEach(focus);
318
+ beforeEach(press('Enter'));
319
+ describe('ArrowDown', function () {
320
+ beforeEach(press('ArrowDown'));
321
+ beforeEach(updateComplete);
322
+ it('remains expanded', function () {
323
+ expect(element.expanded).to.be.true;
324
+ });
325
+ describe('ArrowDown', function () {
326
+ beforeEach(press('ArrowDown'));
327
+ beforeEach(updateComplete);
328
+ it('remains expanded', function () {
329
+ expect(element.expanded).to.be.true;
330
+ });
331
+ describe('Space', function () {
332
+ beforeEach(press(' '));
333
+ beforeEach(updateComplete);
334
+ it('closes', function () {
335
+ expect(element.expanded).to.be.false;
336
+ });
337
+ it('sets value', function () {
338
+ expect(element.value).to.equal('2');
339
+ });
340
+ });
341
+ });
342
+ });
41
343
  });
42
344
  });
43
- describe('variant="single"', function () {
345
+ describe('with 8 items', function () {
346
+ let element;
347
+ const updateComplete = () => element.updateComplete;
348
+ const focus = () => element.focus();
44
349
  beforeEach(async function () {
45
350
  element = await createFixture(html `
46
- <pf-select variant="single"
47
- accessible-label="Choose a number"
48
- placeholder="Choose a number">
351
+ <pf-select>
49
352
  <pf-option value="1">1</pf-option>
50
353
  <pf-option value="2">2</pf-option>
51
354
  <pf-option value="3">3</pf-option>
@@ -56,402 +359,538 @@ describe('<pf-select>', function () {
56
359
  <pf-option value="8">8</pf-option>
57
360
  </pf-select>`);
58
361
  });
59
- it('is accessible', async function () {
60
- await expect(element).to.be.accessible();
362
+ it('does not pass aXe audit', async function () {
363
+ await expect(element).to.not.be.accessible();
61
364
  });
62
- describe('without accessible label', function () {
63
- beforeEach(function () {
64
- element.accessibleLabel = undefined;
365
+ it('sets aria-setsize and aria-posinset on items', function () {
366
+ element.options.forEach((option, i) => {
367
+ expect(option).to.have.attr('aria-setsize', '8');
368
+ expect(option).to.have.attr('aria-posinset', `${i + 1}`);
65
369
  });
370
+ });
371
+ describe('click combobox button', function () {
372
+ beforeEach(() => clickElementAtCenter(element));
66
373
  beforeEach(updateComplete);
67
- it('fails accessibility audit', async function () {
374
+ it('does not pass aXe audit', async function () {
68
375
  await expect(element).to.not.be.accessible();
69
376
  });
70
- });
71
- describe('calling focus())', function () {
72
- beforeEach(function () {
73
- element.focus();
377
+ it('expands the listbox', async function () {
378
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
379
+ });
380
+ it('focuses on the first item', async function () {
381
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
382
+ });
383
+ describe('Tab', function () {
384
+ beforeEach(press('Tab'));
385
+ it('does not focus the combobox button', async function () {
386
+ expect(await a11ySnapshot()).to.not.have.axTreeFocusedNode;
387
+ });
74
388
  });
389
+ });
390
+ describe('focus()', function () {
391
+ beforeEach(focus);
75
392
  beforeEach(updateComplete);
76
- describe('pressing Enter', function () {
393
+ it('focuses on the combobox button', async function () {
394
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axRole('combobox');
395
+ });
396
+ it('does not expand the listbox', async function () {
397
+ expect(element.expanded).to.be.false;
398
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
399
+ });
400
+ describe('Enter', function () {
77
401
  beforeEach(press('Enter'));
78
402
  beforeEach(updateComplete);
79
- it('expands', async function () {
403
+ it('expands the listbox', async function () {
80
404
  expect(element.expanded).to.be.true;
81
- const snapshot = await a11ySnapshot();
82
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
83
- expect(listbox).to.be.ok;
405
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
84
406
  });
85
- it('focuses on the placeholder', async function () {
86
- const snapshot = await a11ySnapshot();
87
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
88
- const focused = listbox?.children?.find(x => x.focused);
89
- expect(focused?.name).to.equal('Choose a number');
407
+ it('focuses on the first item', async function () {
408
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
90
409
  });
91
410
  });
92
- describe('pressing Space', function () {
411
+ describe('Space', function () {
412
+ beforeEach(function () {
413
+ document.body.style.height = '8000px';
414
+ });
415
+ afterEach(function () {
416
+ document.body.style.height = 'initial';
417
+ });
93
418
  beforeEach(press(' '));
94
419
  beforeEach(updateComplete);
95
- it('expands', async function () {
96
- expect(element.expanded).to.be.true;
97
- const snapshot = await a11ySnapshot();
98
- expect(snapshot.children?.at(1)).to.be.ok;
99
- expect(snapshot.children?.at(1)?.role).to.equal('listbox');
420
+ beforeEach(() => aTimeout(300));
421
+ it('expands the listbox', async function () {
422
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
100
423
  });
101
- it('focuses on the placeholder', async function () {
102
- const snapshot = await a11ySnapshot();
103
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
104
- const focused = listbox?.children?.find(x => x.focused);
105
- expect(focused?.name).to.equal('Choose a number');
424
+ it('focuses on the first item', async function () {
425
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
426
+ });
427
+ it('does not scroll the screen', function () {
428
+ expect(window.scrollY).to.equal(0);
429
+ });
430
+ });
431
+ describe('Home', function () {
432
+ beforeEach(press('Home'));
433
+ beforeEach(updateComplete);
434
+ it('expands the listbox', async function () {
435
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
436
+ });
437
+ it('focuses on option 1', async function () {
438
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
439
+ });
440
+ });
441
+ describe('End', function () {
442
+ beforeEach(press('End'));
443
+ beforeEach(updateComplete);
444
+ it('expands the listbox', async function () {
445
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
446
+ });
447
+ it('focuses on option 8', async function () {
448
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('8');
106
449
  });
107
450
  });
108
- describe('pressing ArrowDown', function () {
451
+ describe('ArrowDown', function () {
109
452
  beforeEach(press('ArrowDown'));
110
453
  beforeEach(updateComplete);
111
- it('expands', async function () {
454
+ it('expands the listbox', async function () {
112
455
  expect(element.expanded).to.be.true;
113
- const snapshot = await a11ySnapshot();
114
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
115
- expect(listbox).to.be.ok;
456
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
116
457
  });
117
- it('focuses on option 1', async function () {
118
- const snapshot = await a11ySnapshot();
119
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
120
- const focused = listbox?.children?.find(x => x.focused);
121
- expect(focused?.name).to.equal('Choose a number');
458
+ it('focuses on the first item', async function () {
459
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
122
460
  });
123
- describe('then pressing ArrowUp', function () {
461
+ describe('ArrowUp', function () {
124
462
  beforeEach(press('ArrowUp'));
125
463
  beforeEach(updateComplete);
126
464
  it('focuses on the last option', async function () {
127
- const snapshot = await a11ySnapshot();
128
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
129
- const focused = listbox?.children?.find(x => x.focused);
130
- expect(focused?.name).to.equal('8');
465
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('8');
131
466
  });
132
- describe('then pressing ArrowDown', function () {
467
+ describe('ArrowDown', function () {
133
468
  beforeEach(press('ArrowDown'));
134
469
  beforeEach(updateComplete);
135
- it('focuses on the placeholder', async function () {
136
- const snapshot = await a11ySnapshot();
137
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
138
- const focused = listbox?.children?.find(x => x.focused);
139
- expect(focused?.name).to.equal('Choose a number');
470
+ it('focuses on option 1', async function () {
471
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
140
472
  });
141
473
  });
142
474
  });
143
- describe('then pressing ArrowDown', function () {
475
+ describe('ArrowDown', function () {
144
476
  beforeEach(press('ArrowDown'));
145
477
  beforeEach(updateComplete);
146
- it('focuses on option 1', async function () {
147
- const snapshot = await a11ySnapshot();
148
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
149
- const focused = listbox?.children?.find(x => x.focused);
150
- expect(focused?.name).to.equal('1');
478
+ it('focuses on option 2', async function () {
479
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('2');
151
480
  });
152
- describe('then pressing ArrowUp', function () {
481
+ describe('ArrowUp', function () {
153
482
  beforeEach(press('ArrowUp'));
154
483
  beforeEach(updateComplete);
155
- it('focuses on the placeholder', async function () {
156
- const snapshot = await a11ySnapshot();
157
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
158
- const focused = listbox?.children?.find(x => x.focused);
159
- expect(focused?.name).to.equal('Choose a number');
484
+ it('focuses on option 1', async function () {
485
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
486
+ });
487
+ });
488
+ describe('ArrowDown', function () {
489
+ beforeEach(press('ArrowDown'));
490
+ beforeEach(updateComplete);
491
+ it('focuses on option 3', async function () {
492
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('3');
493
+ });
494
+ describe('Enter', function () {
495
+ beforeEach(press('Enter'));
496
+ beforeEach(updateComplete);
497
+ it('selects option 3', function () {
498
+ expect(getSelectedOptionValues(element)).to.deep.equal([
499
+ '3',
500
+ ]);
501
+ });
502
+ it('exposes selection to assistive technology', async function () {
503
+ expect(await a11ySnapshot()).to.axContainQuery({
504
+ role: 'combobox',
505
+ value: '3',
506
+ });
507
+ });
508
+ it('hides the listbox', async function () {
509
+ expect(element.expanded).to.be.false;
510
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
511
+ });
512
+ describe('ArrowDown', function () {
513
+ beforeEach(press('ArrowDown'));
514
+ beforeEach(updateComplete);
515
+ it('expands the listbox', async function () {
516
+ expect(element.expanded).to.be.true;
517
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
518
+ });
519
+ describe('Home', function () {
520
+ beforeEach(press('Home'));
521
+ beforeEach(updateComplete);
522
+ it('focuses on option 1', async function () {
523
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
524
+ });
525
+ describe('Home', function () {
526
+ beforeEach(press('Home'));
527
+ beforeEach(updateComplete);
528
+ it('focuses on option 1', async function () {
529
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axName('1');
530
+ });
531
+ });
532
+ });
533
+ });
160
534
  });
161
535
  });
162
- describe('then pressing Enter', function () {
536
+ describe('Enter', function () {
163
537
  beforeEach(press('Enter'));
164
538
  beforeEach(updateComplete);
165
- it('selects option 1', function () {
166
- expect(getValues(element)).to.deep.equal(['1']);
539
+ it('selects option 2', function () {
540
+ expect(getSelectedOptionValues(element)).to.deep.equal(['2']);
541
+ });
542
+ it('exposes selection to assistive technology', async function () {
543
+ expect(await a11ySnapshot()).to.axContainQuery({
544
+ role: 'combobox',
545
+ value: '2',
546
+ });
167
547
  });
168
548
  });
169
549
  });
170
- describe('then pressing Space', function () {
550
+ describe('Space', function () {
171
551
  beforeEach(press(' '));
172
552
  beforeEach(updateComplete);
173
- it('closes', function () {
553
+ it('hides the listbox', async function () {
174
554
  expect(element.expanded).to.be.false;
555
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
175
556
  });
176
- it('hides the listbox', async function () {
177
- const snapshot = await a11ySnapshot();
178
- expect(snapshot.children?.find(x => x.role === 'listbox')).to.be.undefined;
557
+ it('focuses the combobox toggle', async function () {
558
+ expect(await a11ySnapshot())
559
+ .axTreeFocusedNode
560
+ .to.have.axRole('combobox');
179
561
  });
180
- it('focuses the button', async function () {
181
- const snapshot = await a11ySnapshot();
182
- const focused = snapshot.children?.find(x => x.focused);
183
- expect(focused?.role).to.equal('combobox');
184
- expect(focused?.haspopup).to.equal('listbox');
562
+ it('selects option 1', function () {
563
+ expect(getSelectedOptionValues(element)).to.deep.equal([
564
+ '1',
565
+ ]);
185
566
  });
186
- it('does not select anything', async function () {
187
- // because the placeholder was focused
188
- expect(getValues(element)).to.deep.equal([]);
567
+ it('exposes selection to assistive technology', async function () {
568
+ expect(await a11ySnapshot()).to.axContainQuery({
569
+ role: 'combobox',
570
+ value: '1',
571
+ });
189
572
  });
190
573
  });
191
- describe('then pressing Tab', function () {
574
+ describe('Tab', function () {
192
575
  beforeEach(press('Tab'));
193
576
  beforeEach(nextFrame);
194
577
  beforeEach(updateComplete);
195
- it('closes', function () {
196
- expect(element.expanded).to.be.false;
197
- });
198
578
  it('hides the listbox', async function () {
199
- const snapshot = await a11ySnapshot();
200
- expect(snapshot.children?.at(1)).to.be.undefined;
579
+ expect(element.expanded).to.be.false;
580
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
201
581
  });
202
- it('focuses the button', async function () {
203
- const snapshot = await a11ySnapshot();
204
- const focused = snapshot.children?.find(x => x.focused);
205
- expect(focused?.role).to.equal('combobox');
206
- expect(focused?.haspopup).to.equal('listbox');
582
+ it('does not focus on the combobox button', async function () {
583
+ expect(await a11ySnapshot()).to.not.have.axTreeFocusedNode;
207
584
  });
208
585
  });
209
- describe('then pressing Shift+Tab', function () {
210
- beforeEach(shiftHold);
586
+ describe('Shift+Tab', function () {
587
+ beforeEach(holdShift);
211
588
  beforeEach(press('Tab'));
212
- beforeEach(shiftRelease);
589
+ beforeEach(releaseShift);
213
590
  beforeEach(updateComplete);
214
- it('closes', function () {
215
- expect(element.expanded).to.be.false;
216
- });
217
591
  it('hides the listbox', async function () {
218
- const snapshot = await a11ySnapshot();
219
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
220
- expect(listbox).to.be.undefined;
592
+ expect(element.expanded).to.be.false;
593
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
221
594
  });
222
595
  it('focuses the button', async function () {
223
- const snapshot = await a11ySnapshot();
224
- const focused = snapshot.children?.find(x => x.focused);
225
- expect(focused?.role).to.equal('combobox');
226
- expect(focused?.haspopup).to.equal('listbox');
596
+ expect(await a11ySnapshot())
597
+ .axTreeFocusedNode
598
+ .to.have.axRole('combobox');
227
599
  });
228
600
  });
229
- describe('then pressing Escape', function () {
601
+ describe('Escape', function () {
230
602
  beforeEach(press('Escape'));
231
603
  beforeEach(nextFrame);
232
604
  beforeEach(updateComplete);
233
- it('closes', function () {
234
- expect(element.expanded).to.be.false;
235
- });
236
605
  it('hides the listbox', async function () {
237
- const snapshot = await a11ySnapshot();
238
- expect(snapshot.children?.at(1)).to.be.undefined;
606
+ expect(element.expanded).to.be.false;
607
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
239
608
  });
240
609
  it('focuses the button', async function () {
241
- const snapshot = await a11ySnapshot();
242
- const focused = snapshot.children?.find(x => x.focused);
243
- expect(focused?.role).to.equal('combobox');
244
- expect(focused?.haspopup).to.equal('listbox');
610
+ expect(await a11ySnapshot())
611
+ .axTreeFocusedNode
612
+ .to.have.axRole('combobox');
245
613
  });
246
614
  });
247
615
  });
248
616
  });
249
617
  });
250
- describe('variant="checkbox"', function () {
251
- beforeEach(async function () {
252
- element = await createFixture(html `
253
- <pf-select variant="checkbox"
254
- accessible-label="Check it out">
255
- <pf-option value="1">1</pf-option>
256
- <pf-option value="2">2</pf-option>
257
- <pf-option value="3">3</pf-option>
258
- <pf-option value="4">4</pf-option>
259
- <pf-option value="5">5</pf-option>
260
- <pf-option value="6">6</pf-option>
261
- <pf-option value="7">7</pf-option>
262
- <pf-option value="8">8</pf-option>
263
- </pf-select>`);
264
- });
265
- it('is accessible', async function () {
266
- await expect(element).to.be.accessible();
618
+ });
619
+ describe('<pf-select variant="checkbox">', function () {
620
+ let element;
621
+ let items;
622
+ const updateComplete = () => element.updateComplete;
623
+ const focus = () => element.focus();
624
+ beforeEach(async function () {
625
+ element = await createFixture(html `
626
+ <pf-select variant="checkbox"
627
+ placeholder="placeholder"
628
+ accessible-label="Check it out">
629
+ <pf-option value="1">1</pf-option>
630
+ <pf-option value="2">2</pf-option>
631
+ <pf-option value="3">3</pf-option>
632
+ <pf-option value="4">4</pf-option>
633
+ <pf-option value="5">5</pf-option>
634
+ <pf-option value="6">6</pf-option>
635
+ <pf-option value="7">7</pf-option>
636
+ <pf-option value="8">8</pf-option>
637
+ </pf-select>`);
638
+ items = Array.from(element.querySelectorAll('pf-option'));
639
+ });
640
+ it('is accessible', async function () {
641
+ await expect(element).to.be.accessible();
642
+ });
643
+ it('does not have redundant role', async function () {
644
+ expect(element.shadowRoot?.firstElementChild).to.not.contain('[role="button"]');
645
+ });
646
+ describe('focus()', function () {
647
+ beforeEach(focus);
648
+ beforeEach(updateComplete);
649
+ describe('Enter', function () {
650
+ beforeEach(press('Enter'));
651
+ beforeEach(updateComplete);
652
+ it('expands the listbox', async function () {
653
+ expect(element.expanded).to.be.true;
654
+ const snapshot = await a11ySnapshot();
655
+ expect(snapshot.children?.at(1)).to.be.ok;
656
+ expect(snapshot.children?.at(1)?.role).to.equal('listbox');
657
+ });
658
+ it('should NOT use checkbox role for options', async function () {
659
+ const snapshot = await a11ySnapshot();
660
+ expect(snapshot.children?.at(1)?.children?.filter(x => x.role === 'checkbox')?.length)
661
+ .to.equal(0);
662
+ });
267
663
  });
268
- describe('calling focus())', function () {
269
- beforeEach(function () {
270
- element.focus();
664
+ describe('Space', function () {
665
+ beforeEach(press(' '));
666
+ beforeEach(updateComplete);
667
+ it('expands the listbox', async function () {
668
+ expect(element.expanded).to.be.true;
669
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
271
670
  });
671
+ });
672
+ describe('ArrowDown', function () {
673
+ beforeEach(press('ArrowDown'));
272
674
  beforeEach(updateComplete);
273
- describe('pressing Enter', function () {
274
- beforeEach(press('Enter'));
675
+ it('expands the listbox', async function () {
676
+ expect(element.expanded).to.be.true;
677
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
678
+ });
679
+ it('focuses the placeholder', async function () {
680
+ expect(await a11ySnapshot()).to.have.axTreeFocusedNode.to.have.axName('placeholder');
681
+ });
682
+ describe('Shift+Tab', function () {
683
+ beforeEach(holdShift);
684
+ beforeEach(press('Tab'));
685
+ beforeEach(releaseShift);
275
686
  beforeEach(updateComplete);
276
- it('expands', async function () {
277
- expect(element.expanded).to.be.true;
278
- const snapshot = await a11ySnapshot();
279
- expect(snapshot.children?.at(1)).to.be.ok;
280
- expect(snapshot.children?.at(1)?.role).to.equal('listbox');
687
+ it('hides the listbox', async function () {
688
+ expect(element.expanded).to.be.false;
689
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
281
690
  });
282
- it('should NOT use checkbox role for options', async function () {
283
- const snapshot = await a11ySnapshot();
284
- expect(snapshot.children?.at(1)?.children?.filter(x => x.role === 'checkbox')?.length)
285
- .to.equal(0);
691
+ it('focuses the button', async function () {
692
+ expect(await a11ySnapshot())
693
+ .axTreeFocusedNode
694
+ .to.have.axRole('combobox');
286
695
  });
287
696
  });
288
- describe('pressing Space', function () {
289
- beforeEach(press(' '));
697
+ describe('Tab', function () {
698
+ beforeEach(press('Tab'));
699
+ beforeEach(nextFrame);
290
700
  beforeEach(updateComplete);
291
- it('expands', async function () {
292
- expect(element.expanded).to.be.true;
701
+ // a little extra sleep to de-flake this test
702
+ beforeEach(nextFrame);
703
+ beforeEach(updateComplete);
704
+ it('closes', function () {
705
+ expect(element.expanded).to.be.false;
706
+ });
707
+ it('hides the listbox', async function () {
293
708
  const snapshot = await a11ySnapshot();
294
- expect(snapshot.children?.at(1)).to.be.ok;
295
- expect(snapshot.children?.at(1)?.role).to.equal('listbox');
709
+ const listbox = snapshot.children?.find(x => x.role === 'listbox');
710
+ expect(listbox).to.be.undefined;
296
711
  });
297
712
  });
298
- describe('pressing ArrowDown', function () {
299
- beforeEach(press('ArrowDown'));
713
+ describe('Escape', function () {
714
+ beforeEach(press('Escape'));
300
715
  beforeEach(updateComplete);
301
- it('expands', async function () {
302
- expect(element.expanded).to.be.true;
716
+ it('closes', function () {
717
+ expect(element.expanded).to.be.false;
718
+ });
719
+ it('hides the listbox', async function () {
303
720
  const snapshot = await a11ySnapshot();
304
- expect(snapshot.children?.at(1)).to.be.ok;
305
- expect(snapshot.children?.at(1)?.role).to.equal('listbox');
721
+ expect(snapshot.children?.at(1)).to.be.undefined;
306
722
  });
307
- describe('then pressing Shift+Tab', function () {
308
- beforeEach(shiftHold);
309
- beforeEach(press('Tab'));
310
- beforeEach(shiftRelease);
311
- beforeEach(updateComplete);
312
- it('closes', async function () {
313
- expect(element.expanded).to.be.false;
314
- });
315
- it('hides the listbox', async function () {
316
- const snapshot = await a11ySnapshot();
317
- expect(snapshot.children?.at(1)).to.be.undefined;
318
- });
319
- it('focuses the button', async function () {
320
- const snapshot = await a11ySnapshot();
321
- expect(snapshot.children?.at(0)?.role).to.equal('combobox');
322
- expect(snapshot.children?.at(0)?.focused).to.be.true;
323
- });
723
+ it('focuses the button', async function () {
724
+ const snapshot = await a11ySnapshot();
725
+ const focused = querySnapshot(snapshot, { focused: true });
726
+ expect(focused?.role).to.equal('combobox');
324
727
  });
325
- describe('then pressing Tab', function () {
326
- beforeEach(press('Tab'));
327
- beforeEach(nextFrame);
328
- beforeEach(updateComplete);
329
- // a little extra sleep to de-flake this test
330
- beforeEach(nextFrame);
331
- beforeEach(updateComplete);
332
- it('closes', function () {
333
- expect(element.expanded).to.be.false;
334
- });
335
- it('hides the listbox', async function () {
336
- const snapshot = await a11ySnapshot();
337
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
338
- expect(listbox).to.be.undefined;
339
- });
728
+ });
729
+ describe('Ctrl-A', function () {
730
+ beforeEach(holdCtrl);
731
+ beforeEach(press('A'));
732
+ beforeEach(releaseCtrl);
733
+ beforeEach(updateComplete);
734
+ it('selects all', function () {
735
+ expect(element.selected.length).to.equal(items.length);
340
736
  });
341
- describe('then pressing Escape', function () {
342
- beforeEach(press('Escape'));
737
+ it('remains expanded', async function () {
738
+ expect(element.expanded).to.be.true;
739
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
740
+ });
741
+ describe('Ctrl-A', function () {
742
+ beforeEach(holdCtrl);
743
+ beforeEach(press('A'));
744
+ beforeEach(releaseCtrl);
343
745
  beforeEach(updateComplete);
344
- it('closes', function () {
345
- expect(element.expanded).to.be.false;
346
- });
347
- it('hides the listbox', async function () {
348
- const snapshot = await a11ySnapshot();
349
- expect(snapshot.children?.at(1)).to.be.undefined;
746
+ it('deselects all', function () {
747
+ expect(element.selected.length).to.equal(0);
350
748
  });
351
- it('focuses the button', async function () {
352
- const snapshot = await a11ySnapshot();
353
- const focused = snapshot.children?.find(x => x.focused);
354
- expect(focused?.role).to.equal('combobox');
749
+ it('remains expanded', async function () {
750
+ expect(element.expanded).to.be.true;
751
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
355
752
  });
356
753
  });
357
- describe('then pressing Space', function () {
754
+ });
755
+ describe('Space', function () {
756
+ it('does not select anything', function () {
757
+ expect(element.selected).to.deep.equal([]);
758
+ });
759
+ });
760
+ describe('ArrowDown', function () {
761
+ beforeEach(press('ArrowDown'));
762
+ beforeEach(updateComplete);
763
+ describe('Space', function () {
358
764
  beforeEach(press(' '));
359
765
  beforeEach(updateComplete);
360
766
  it('selects option 1', function () {
361
767
  // because the placeholder was focused
362
- expect(getValues(element)).to.deep.equal(['1']);
768
+ expect(getSelectedOptionValues(element)).to.deep.equal(['1']);
363
769
  });
364
770
  it('remains expanded', async function () {
365
771
  expect(element.expanded).to.be.true;
366
- const snapshot = await a11ySnapshot();
367
- expect(snapshot.children?.at(1)?.role).to.equal('listbox');
772
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
368
773
  });
369
- describe('then pressing ArrowDown', function () {
774
+ describe('ArrowDown', function () {
370
775
  beforeEach(press('ArrowDown'));
371
776
  beforeEach(updateComplete);
372
- it('focuses option 1', async function () {
777
+ it('focuses option 2', async function () {
373
778
  const snapshot = await a11ySnapshot();
374
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
375
- const focused = listbox?.children?.find(x => x.focused);
376
- expect(focused?.name).to.equal('2');
779
+ expect(snapshot).to.have.axQuery({
780
+ focused: true,
781
+ name: '2',
782
+ });
377
783
  });
378
- describe('then pressing Enter', function () {
784
+ describe('Enter', function () {
379
785
  beforeEach(press('Enter'));
380
786
  beforeEach(updateComplete);
381
787
  it('adds option 2 to selection', function () {
382
- expect(getValues(element)).to.deep.equal([
788
+ expect(getSelectedOptionValues(element)).to.deep.equal([
383
789
  '1',
384
790
  '2',
385
791
  ]);
386
792
  });
387
793
  it('remains expanded', async function () {
388
794
  expect(element.expanded).to.be.true;
389
- const snapshot = await a11ySnapshot();
390
- expect(snapshot.children?.at(1)?.role).to.equal('listbox');
795
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
391
796
  });
392
- describe('then holding Shift and pressing down arrow / enter twice in a row', function () {
393
- beforeEach(shiftHold);
394
- beforeEach(press('ArrowDown'));
395
- beforeEach(press('Enter'));
396
- beforeEach(press('ArrowDown'));
797
+ });
798
+ });
799
+ describe('holding Shift', function () {
800
+ beforeEach(holdShift);
801
+ afterEach(releaseShift);
802
+ describe('ArrowDown', function () {
803
+ beforeEach(press('ArrowDown'));
804
+ beforeEach(nextFrame);
805
+ it('adds option 2 to selection', function () {
806
+ expect(getSelectedOptionValues(element)).to.deep.equal([
807
+ '1',
808
+ '2',
809
+ ]);
810
+ });
811
+ describe('Enter', function () {
397
812
  beforeEach(press('Enter'));
398
- beforeEach(shiftRelease);
399
813
  beforeEach(updateComplete);
400
- it('adds options 2 and 3 to the selected list', function () {
401
- expect(getValues(element)).to.deep.equal([
814
+ it('makes no change', function () {
815
+ expect(getSelectedOptionValues(element)).to.deep.equal([
402
816
  '1',
403
817
  '2',
404
- '3',
405
- '4',
406
818
  ]);
407
819
  });
408
- describe('then pressing ArrowUp and Enter', function () {
409
- beforeEach(press('ArrowUp'));
410
- beforeEach(press('Enter'));
820
+ beforeEach(updateComplete);
821
+ describe('ArrowDown', function () {
822
+ beforeEach(press('ArrowDown'));
411
823
  beforeEach(updateComplete);
412
- it('deselects option 3', function () {
413
- expect(getValues(element)).to.deep.equal([
824
+ it('adds option 3 to the selected list', function () {
825
+ expect(getSelectedOptionValues(element)).to.deep.equal([
414
826
  '1',
415
827
  '2',
416
- '4',
828
+ '3',
417
829
  ]);
418
830
  });
419
- describe('then holding down Shift and pressing arrow up / enter twice in a row', function () {
420
- beforeEach(press('ArrowUp'));
831
+ describe('ArrowUp', function () {
421
832
  beforeEach(press('Enter'));
422
833
  beforeEach(updateComplete);
423
- beforeEach(press('ArrowUp'));
424
- beforeEach(press('Enter'));
425
- beforeEach(updateComplete);
426
- beforeEach(shiftRelease);
427
- beforeEach(updateComplete);
428
- it('deselects options 1 and 2', function () {
429
- expect(getValues(element)).to.deep.equal([
430
- '4',
834
+ it('makes no change to selection', function () {
835
+ expect(getSelectedOptionValues(element)).to.deep.equal([
836
+ '1',
837
+ '2',
838
+ '3',
431
839
  ]);
432
840
  });
433
- describe('then pressing Ctrl+A', function () {
434
- beforeEach(ctrlA);
435
- beforeEach(updateComplete);
436
- it('selects all options', function () {
437
- expect(getValues(element)).to.deep.equal([
438
- '1',
439
- '2',
440
- '3',
441
- '4',
442
- '5',
443
- '6',
444
- '7',
445
- '8',
446
- ]);
447
- });
448
- describe('then pressing Ctrl+A again', function () {
449
- beforeEach(ctrlA);
450
- beforeEach(updateComplete);
451
- it('deselects all options', function () {
452
- expect(getValues(element)).to.deep.equal([]);
453
- });
454
- });
841
+ });
842
+ });
843
+ });
844
+ });
845
+ });
846
+ });
847
+ });
848
+ describe('clicking the first item', function () {
849
+ beforeEach(() => clickElementAtCenter(items.at(0)));
850
+ beforeEach(updateComplete);
851
+ it('selects option 1', function () {
852
+ // because the placeholder was focused
853
+ expect(getSelectedOptionValues(element)).to.deep.equal([
854
+ '1',
855
+ ]);
856
+ });
857
+ it('remains expanded', async function () {
858
+ expect(element.expanded).to.be.true;
859
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
860
+ });
861
+ describe('holding Shift', function () {
862
+ beforeEach(holdShift);
863
+ afterEach(releaseShift);
864
+ describe('clicking the 7th item', function () {
865
+ beforeEach(() => clickElementAtCenter(items.at(6)));
866
+ it('remains expanded', async function () {
867
+ expect(element.expanded).to.be.true;
868
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
869
+ });
870
+ it('selects items 1-7', function () {
871
+ expect(getSelectedOptionValues(element)).to.deep.equal([
872
+ '1',
873
+ '2',
874
+ '3',
875
+ '4',
876
+ '5',
877
+ '6',
878
+ '7',
879
+ ]);
880
+ });
881
+ describe('releasing Shift', function () {
882
+ beforeEach(releaseShift);
883
+ describe('clicking 6th item', function () {
884
+ beforeEach(() => clickElementAtCenter(items.at(5)));
885
+ it('deselects item 6', function () {
886
+ expect(getSelectedOptionValues(element)).to.not.contain('6');
887
+ });
888
+ describe('holding Shift', function () {
889
+ beforeEach(holdShift);
890
+ describe('clicking 2nd item', function () {
891
+ beforeEach(() => clickElementAtCenter(items.at(1)));
892
+ it('deselects items 2-6', function () {
893
+ expect(getSelectedOptionValues(element)).to.deep.equal(['1', '7']);
455
894
  });
456
895
  });
457
896
  });
@@ -462,393 +901,633 @@ describe('<pf-select>', function () {
462
901
  });
463
902
  });
464
903
  });
465
- // try again when we implement activedescendant
466
- describe.skip('variant="typeahead"', function () {
904
+ });
905
+ describe('<pf-select variant="typeahead">', function () {
906
+ let element;
907
+ const label = 'label';
908
+ const placeholder = 'placeholder';
909
+ const updateComplete = () => element.updateComplete;
910
+ const focus = () => element.focus();
911
+ beforeEach(async function () {
912
+ element = await createFixture(html `
913
+ <pf-select variant="typeahead">
914
+ <pf-option>Blue</pf-option>
915
+ <pf-option>Green</pf-option>
916
+ <pf-option>Magenta</pf-option>
917
+ <pf-option>Orange</pf-option>
918
+ <pf-option>Purple</pf-option>
919
+ <pf-option>Periwinkle</pf-option>
920
+ <pf-option>Pink</pf-option>
921
+ <pf-option>Red</pf-option>
922
+ <pf-option>Yellow</pf-option>
923
+ </pf-select>`);
924
+ });
925
+ beforeEach(nextFrame);
926
+ it('does not have redundant role', async function () {
927
+ expect(element.shadowRoot?.firstElementChild).to.not.contain('[role="button"]');
928
+ });
929
+ it('labels the combobox input with the first option', async function () {
930
+ expect(await a11ySnapshot()).to.axContainQuery({
931
+ role: 'combobox',
932
+ name: 'Blue',
933
+ });
934
+ });
935
+ describe('with an `accessible-label` attribute', function () {
936
+ beforeEach(function () {
937
+ element.setAttribute('accessible-label', label);
938
+ });
939
+ beforeEach(nextFrame);
940
+ it('passes aXe audit', async function () {
941
+ await expect(element).to.be.accessible();
942
+ });
943
+ it('does not have redundant role', async function () {
944
+ expect(element.shadowRoot?.firstElementChild).to.not.contain('[role="button"]');
945
+ });
946
+ it('labels the combobox with the label', async function () {
947
+ expect(await a11ySnapshot()).to.axContainQuery({
948
+ role: 'combobox',
949
+ name: label,
950
+ });
951
+ });
952
+ it('labels the toggle button with the label', async function () {
953
+ expect(await a11ySnapshot()).to.axContainQuery({
954
+ role: 'button',
955
+ name: label,
956
+ });
957
+ });
958
+ describe('show()', function () {
959
+ beforeEach(() => element.show());
960
+ it('labels the listbox with the placeholder attribute', async function () {
961
+ expect(await a11ySnapshot()).to.axContainQuery({
962
+ role: 'listbox',
963
+ name: 'label',
964
+ });
965
+ });
966
+ });
967
+ });
968
+ describe('with a `placeholder` attribute', function () {
969
+ beforeEach(function () {
970
+ element.setAttribute('placeholder', placeholder);
971
+ });
972
+ beforeEach(nextFrame);
973
+ it('passes aXe audit', async function () {
974
+ await expect(element).to.be.accessible();
975
+ });
976
+ it('lists the placeholder as first among the options', function () {
977
+ expect(element.options.at(0)).to.have.text(placeholder);
978
+ });
979
+ it('does not have redundant role', async function () {
980
+ expect(element.shadowRoot?.firstElementChild).to.not.contain('[role="button"]');
981
+ });
982
+ it('labels the combobox with the placeholder', async function () {
983
+ expect(await a11ySnapshot()).to.axContainQuery({
984
+ role: 'combobox',
985
+ name: placeholder,
986
+ });
987
+ });
988
+ it('labels the toggle button with the placeholder', async function () {
989
+ expect(await a11ySnapshot()).to.axContainQuery({
990
+ role: 'button',
991
+ name: placeholder,
992
+ });
993
+ });
994
+ describe('show()', function () {
995
+ beforeEach(() => element.show());
996
+ it('labels the listbox with the placeholder attribute', async function () {
997
+ expect(await a11ySnapshot()).to.axContainQuery({
998
+ role: 'listbox',
999
+ name: 'placeholder',
1000
+ });
1001
+ });
1002
+ });
1003
+ });
1004
+ describe('clicking the toggle button', function () {
467
1005
  beforeEach(async function () {
468
- element = await createFixture(html `
469
- <pf-select variant="${'typeahead'}">
470
- <pf-option value="Blue">Blue</pf-option>
471
- <pf-option value="Green">Green</pf-option>
472
- <pf-option value="Magenta">Magenta</pf-option>
473
- <pf-option value="Orange">Orange</pf-option>
474
- <pf-option value="Purple">Purple</pf-option>
475
- <pf-option value="Pink">Pink</pf-option>
476
- <pf-option value="Red">Red</pf-option>
477
- <pf-option value="Yellow">Yellow</pf-option>
478
- </pf-select>`);
1006
+ await clickElementAtOffset(element, [-10, -10]);
1007
+ });
1008
+ it('shows the listbox', async function () {
1009
+ expect(element.expanded).to.be.true;
1010
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
479
1011
  });
480
- describe('custom filtering', function () {
1012
+ it('focuses the toggle button', async function () {
1013
+ expect(element.expanded).to.be.true;
1014
+ expect(await a11ySnapshot()).to.axContainQuery({
1015
+ focused: true,
1016
+ role: 'button',
1017
+ });
1018
+ });
1019
+ });
1020
+ describe('clicking the combobox input', function () {
1021
+ beforeEach(async function () {
1022
+ await clickElementAtOffset(element, [10, 10]);
1023
+ });
1024
+ it('shows the listbox', async function () {
1025
+ expect(element.expanded).to.be.true;
1026
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
1027
+ });
1028
+ it('focuses the combobox', async function () {
1029
+ expect(element.expanded).to.be.true;
1030
+ expect(await a11ySnapshot()).to.axContainQuery({
1031
+ focused: true,
1032
+ role: 'combobox',
1033
+ });
1034
+ });
1035
+ describe('clicking option 1', function () {
1036
+ beforeEach(async function () {
1037
+ await clickItemAtIndex(element, 0);
1038
+ });
1039
+ it('selects option 1', function () {
1040
+ expect(getSelectedOptionValues(element)).to.deep.equal([
1041
+ 'Blue',
1042
+ ]);
1043
+ });
1044
+ it('closes the listbox', async function () {
1045
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
1046
+ });
1047
+ });
1048
+ describe('clicking option 2', function () {
1049
+ beforeEach(async function () {
1050
+ await clickItemAtIndex(element, 1);
1051
+ });
1052
+ it('selects option 1', function () {
1053
+ expect(getSelectedOptionValues(element)).to.deep.equal([
1054
+ 'Green',
1055
+ ]);
1056
+ });
1057
+ it('closes the listbox', async function () {
1058
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
1059
+ });
1060
+ });
1061
+ });
1062
+ describe('focus()', function () {
1063
+ beforeEach(focus);
1064
+ beforeEach(updateComplete);
1065
+ it('focuses the combobox input', async function () {
1066
+ expect(await a11ySnapshot()).axTreeFocusedNode
1067
+ .to.have.axRole('combobox')
1068
+ .and
1069
+ .to.have.axName('Blue');
1070
+ });
1071
+ describe('"r"', function () {
1072
+ beforeEach(press('r'));
1073
+ beforeEach(updateComplete);
1074
+ it('only shows options that start with "r" or "R"', async function () {
1075
+ expect(getVisibleOptionValues(element)).to.deep.equal([
1076
+ 'Red',
1077
+ ]);
1078
+ });
1079
+ });
1080
+ describe('Space', function () {
481
1081
  beforeEach(function () {
482
- // @ts-expect-error: we intend to implement this in the next release
483
- element.customFilter = option =>
484
- // @ts-expect-error: TODO add filter feature
485
- new RegExp(element.filter).test(option.value);
1082
+ document.body.style.height = '8000px';
486
1083
  });
487
- beforeEach(focus);
1084
+ afterEach(function () {
1085
+ document.body.style.height = 'initial';
1086
+ });
1087
+ beforeEach(press(' '));
488
1088
  beforeEach(updateComplete);
489
- describe('typing "r"', function () {
490
- beforeEach(press('r'));
491
- beforeEach(updateComplete);
492
- it('shows options with "r" anywhere in them', async function () {
493
- const snapshot = await a11ySnapshot();
494
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
495
- expect(listbox?.children?.length).to.equal(3);
496
- expect(listbox?.children?.at(0)?.name).to.equal('Green');
497
- expect(listbox?.children?.at(1)?.name).to.equal('Orange');
498
- expect(listbox?.children?.at(2)?.name).to.equal('Purple');
499
- });
1089
+ beforeEach(() => aTimeout(300));
1090
+ it('does not expand the listbox', async function () {
1091
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
500
1092
  });
501
- describe('typing "R"', function () {
502
- beforeEach(press('R'));
503
- beforeEach(nextFrame);
504
- beforeEach(updateComplete);
505
- it('shows options that contain "R"', async function () {
506
- const snapshot = await a11ySnapshot();
507
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
508
- expect(listbox?.children?.length).to.equal(1);
509
- expect(listbox?.children?.at(0)?.name).to.equal('Red');
510
- });
1093
+ it('does not scroll the screen', function () {
1094
+ expect(window.scrollY).to.equal(0);
511
1095
  });
512
1096
  });
513
- describe('calling focus()', function () {
514
- beforeEach(focus);
1097
+ describe('ArrowDown', function () {
1098
+ beforeEach(press('ArrowDown'));
515
1099
  beforeEach(updateComplete);
516
- it('has a text input for typeahead', async function () {
517
- const snapshot = await a11ySnapshot();
518
- const [typeahead] = snapshot.children ?? [];
519
- expect(typeahead).to.deep.equal({
520
- role: 'combobox',
521
- name: 'Options',
522
- focused: true,
523
- autocomplete: 'both',
524
- haspopup: 'listbox',
525
- });
1100
+ beforeEach(() => aTimeout(200));
1101
+ it('shows the listbox', async function () {
1102
+ expect(element.expanded).to.be.true;
1103
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
1104
+ });
1105
+ it('focuses option 1', function () {
1106
+ expect(getActiveOption(element)).to.have.value('Blue');
526
1107
  });
527
- describe('typing "r"', function () {
528
- beforeEach(press('r'));
1108
+ it('does not move keyboard focus', async function () {
1109
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axRole('combobox');
1110
+ });
1111
+ describe('ArrowDown', function () {
1112
+ beforeEach(press('ArrowDown'));
529
1113
  beforeEach(updateComplete);
530
- it('only shows options that start with "r" or "R"', async function () {
531
- const snapshot = await a11ySnapshot();
532
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
533
- expect(listbox?.children?.every(x => x.name.toLowerCase().startsWith('r'))).to.be.true;
1114
+ it('focuses option 2', function () {
1115
+ expect(getActiveOption(element)).to.have.text('Green');
534
1116
  });
535
- });
536
- describe('setting filter to "*"', function () {
537
- beforeEach(function () {
538
- // @ts-expect-error: todo: add filter feature
539
- element.filter = '*';
1117
+ describe('Enter', function () {
1118
+ beforeEach(press('Enter'));
1119
+ beforeEach(updateComplete);
1120
+ it('selects option 2', function () {
1121
+ expect(getSelectedOptionValues(element)).to.deep.equal([
1122
+ 'Green',
1123
+ ]);
1124
+ });
1125
+ it('sets typeahead input to second option value', async function () {
1126
+ expect(await a11ySnapshot())
1127
+ .axTreeFocusedNode
1128
+ .to.have.axProperty('value', 'Green');
1129
+ });
1130
+ it('retains focus on combobox input', async function () {
1131
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axRole('combobox');
1132
+ });
1133
+ it('hides the listbox', async function () {
1134
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
1135
+ });
1136
+ describe('focus()', function () {
1137
+ beforeEach(focus);
1138
+ describe('ArrowDown', function () {
1139
+ beforeEach(press('ArrowDown'));
1140
+ beforeEach(updateComplete);
1141
+ it('focuses option 2', function () {
1142
+ expect(getActiveOption(element)).to.have.text('Green');
1143
+ });
1144
+ it('only shows option 2', function () {
1145
+ expect(getVisibleOptionValues(element)).to.deep.equal([
1146
+ 'Green',
1147
+ ]);
1148
+ });
1149
+ });
1150
+ });
540
1151
  });
1152
+ });
1153
+ describe('ArrowUp', function () {
1154
+ beforeEach(press('ArrowUp'));
541
1155
  beforeEach(updateComplete);
542
- it('does not error', async function () {
543
- const snapshot = await a11ySnapshot();
544
- const [, , listbox] = snapshot.children ?? [];
545
- expect(listbox?.children).to.not.be.ok;
1156
+ it('focuses the last item', async function () {
1157
+ expect(getActiveOption(element)).to.have.value('Yellow');
546
1158
  });
547
1159
  });
548
- describe('changing input value to "p"', function () {
549
- beforeEach(press('p'));
1160
+ });
1161
+ describe('"p"', function () {
1162
+ beforeEach(press('p'));
1163
+ beforeEach(updateComplete);
1164
+ it('shows the listbox and maintains focus', async function () {
1165
+ expect(await a11ySnapshot())
1166
+ .to.axContainRole('listbox')
1167
+ .and.axTreeFocusedNode
1168
+ .to.have.axRole('combobox')
1169
+ .and.to.have.axProperty('value', 'p');
1170
+ });
1171
+ it('only shows listbox items starting with the letter p', function () {
1172
+ expect(getVisibleOptionValues(element)).to.deep.equal([
1173
+ 'Purple',
1174
+ 'Periwinkle',
1175
+ 'Pink',
1176
+ ]);
1177
+ });
1178
+ describe('Backspace', function () {
1179
+ beforeEach(press('Backspace'));
550
1180
  beforeEach(updateComplete);
551
- it('only shows listbox items starting with the letter p', async function () {
552
- const snapshot = await a11ySnapshot();
553
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
554
- expect(listbox?.children?.length).to.equal(2);
555
- expect(listbox?.children?.at(0)?.name).to.equal('Purple');
556
- expect(listbox?.children?.at(1)?.name).to.equal('Pink');
1181
+ it('shows the listbox and maintains focus', async function () {
1182
+ expect(await a11ySnapshot())
1183
+ .to.axContainRole('listbox')
1184
+ .and.axTreeFocusedNode
1185
+ .to.have.axRole('combobox')
1186
+ .and.to.not.have.axProperty('value', 'p');
557
1187
  });
558
- it('maintains focus on the input', async function () {
559
- const snapshot = await a11ySnapshot();
560
- const focused = snapshot.children?.find(x => x.focused);
561
- expect(focused?.role).to.equal('combobox');
1188
+ it('all options are visible', async function () {
1189
+ expect(getVisibleOptionValues(element)).to.deep.equal([
1190
+ 'Blue',
1191
+ 'Green',
1192
+ 'Magenta',
1193
+ 'Orange',
1194
+ 'Purple',
1195
+ 'Periwinkle',
1196
+ 'Pink',
1197
+ 'Red',
1198
+ 'Yellow',
1199
+ ]);
562
1200
  });
563
- describe('pressing Backspace so input value is ""', function () {
564
- beforeEach(press('Backspace'));
565
- beforeEach(updateComplete);
566
- it('all options are visible', async function () {
567
- const snapshot = await a11ySnapshot();
568
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
569
- expect(listbox?.children?.length).to.equal(8);
570
- expect(listbox?.children?.at(0)?.name).to.equal('Blue');
571
- expect(listbox?.children?.at(1)?.name).to.equal('Green');
572
- expect(listbox?.children?.at(2)?.name).to.equal('Magenta');
573
- expect(listbox?.children?.at(3)?.name).to.equal('Orange');
574
- expect(listbox?.children?.at(4)?.name).to.equal('Purple');
575
- expect(listbox?.children?.at(5)?.name).to.equal('Pink');
576
- expect(listbox?.children?.at(6)?.name).to.equal('Red');
577
- expect(listbox?.children?.at(7)?.name).to.equal('Yellow');
578
- });
579
- });
580
- });
581
- describe('pressing ArrowDown', function () {
582
- beforeEach(press('ArrowDown'));
583
- beforeEach(nextFrame);
1201
+ });
1202
+ describe('"u"', function () {
1203
+ beforeEach(press('u'));
584
1204
  beforeEach(updateComplete);
585
- it('expands', async function () {
586
- expect(element.expanded).to.be.true;
587
- const snapshot = await a11ySnapshot();
588
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
589
- expect(listbox).to.be.ok;
590
- });
591
- it('selects the first item', async function () {
592
- const snapshot = await a11ySnapshot();
593
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
594
- const focused = listbox?.children?.find(x => x.focused);
595
- expect(focused).to.not.be.ok;
596
- const selected = listbox?.children?.find(x => x.selected);
597
- expect(selected).to.be.ok;
598
- expect(listbox?.children?.at(0)).to.equal(selected);
599
- });
600
- it('does not move keyboard focus', async function () {
601
- const snapshot = await a11ySnapshot();
602
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
603
- const focused = listbox?.children?.find(x => x.focused);
604
- expect(focused).to.not.be.ok;
1205
+ it('only shows the option "Purple"', function () {
1206
+ expect(getVisibleOptionValues(element)).to.deep.equal([
1207
+ 'Purple',
1208
+ ]);
605
1209
  });
606
- describe('then pressing ArrowDown', function () {
1210
+ describe('ArrowDown', function () {
607
1211
  beforeEach(press('ArrowDown'));
608
1212
  beforeEach(updateComplete);
609
- it('focuses the first option', async function () {
610
- const snapshot = await a11ySnapshot();
611
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
612
- const focused = listbox?.children?.find(x => x.focused);
613
- expect(focused).to.be.ok;
614
- expect(listbox?.children?.indexOf(focused)).to.equal(0);
615
- });
616
- describe('then pressing Enter', function () {
1213
+ it('focuses the option "Purple"', function () {
1214
+ expect(getActiveOption(element)).to.have.text('Purple');
1215
+ });
1216
+ describe('Enter', function () {
617
1217
  beforeEach(press('Enter'));
618
1218
  beforeEach(updateComplete);
619
- it('selects the second option', function () {
620
- expect(getValues(element)).to.deep.equal(['Green']);
621
- });
622
- it('sets typeahead input to second option value', async function () {
623
- const snapshot = await a11ySnapshot();
624
- const [combobox] = snapshot.children ?? [];
625
- expect(combobox?.value).to.equal('Green');
626
- });
627
- it('focuses on toggle button', async function () {
628
- const snapshot = await a11ySnapshot();
629
- const focused = snapshot.children?.find(x => x.focused);
630
- expect(focused?.role).to.equal('button');
631
- expect(focused?.haspopup).to.equal('listbox');
1219
+ it('selects the option "Purple"', function () {
1220
+ expect(getSelectedOptionValues(element)).to.deep.equal([
1221
+ 'Purple',
1222
+ ]);
632
1223
  });
633
- it('closes', async function () {
634
- expect(element.expanded).to.be.false;
635
- const snapshot = await a11ySnapshot();
636
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
637
- expect(listbox).to.be.undefined;
1224
+ describe('Backspace (x5)', function () {
1225
+ beforeEach(press('Backspace'));
1226
+ beforeEach(press('Backspace'));
1227
+ beforeEach(press('Backspace'));
1228
+ beforeEach(press('Backspace'));
1229
+ beforeEach(press('Backspace'));
1230
+ it('shows the options starting with "P"', function () {
1231
+ expect(getVisibleOptionValues(element)).to.deep.equal([
1232
+ 'Purple',
1233
+ 'Periwinkle',
1234
+ 'Pink',
1235
+ ]);
1236
+ });
1237
+ describe('Home', function () {
1238
+ beforeEach(press('Home'));
1239
+ it('retains focus on the option "Purple"', function () {
1240
+ expect(getActiveOption(element)).to.have.text('Purple');
1241
+ });
1242
+ it('moves cursor to start', function () {
1243
+ // WARNING: ties test to DOM structure
1244
+ const input = element.shadowRoot?.querySelector('input');
1245
+ expect(input?.selectionStart).to.equal(0);
1246
+ });
1247
+ });
1248
+ describe('End', function () {
1249
+ beforeEach(press('End'));
1250
+ it('retains focus on the option "Purple"', function () {
1251
+ expect(getActiveOption(element)).to.have.text('Purple');
1252
+ });
1253
+ it('moves cursor to start', function () {
1254
+ // WARNING: ties test to DOM structure
1255
+ const input = element.shadowRoot?.querySelector('input');
1256
+ expect(input?.selectionStart).to.equal(1);
1257
+ });
1258
+ });
638
1259
  });
639
1260
  });
640
1261
  });
641
1262
  });
642
1263
  });
643
1264
  });
644
- // try again when we implement activedescendant
645
- describe.skip('variant="typeaheadmulti"', function () {
646
- beforeEach(async function () {
647
- element = await createFixture(html `
648
- <pf-select variant="typeaheadmulti">
649
- <pf-option value="Amethyst">Amethyst</pf-option>
650
- <pf-option value="Beryl">Beryl</pf-option>
651
- <pf-option value="Chalcedony">Chalcedony</pf-option>
652
- <pf-option value="Diamond">Diamond</pf-option>
653
- <pf-option value="Emerald">Emerald</pf-option>
654
- <pf-option value="Fool's Gold">Fool's Gold</pf-option>
655
- <pf-option value="Garnet">Garnet</pf-option>
656
- <pf-option value="Halite">Halite</pf-option>
657
- <pf-option value="Iris">Iris</pf-option>
658
- </pf-select>`);
1265
+ describe.skip('setting filter to "*"', function () {
1266
+ beforeEach(function () {
1267
+ // @ts-expect-error: todo: add filter feature
1268
+ element.filter = '*';
659
1269
  });
660
- describe('calling focus()', function () {
661
- beforeEach(function () {
662
- element.focus();
1270
+ beforeEach(updateComplete);
1271
+ it('does not error', async function () {
1272
+ const snapshot = await a11ySnapshot();
1273
+ const [, , listbox] = snapshot.children ?? [];
1274
+ expect(listbox?.children).to.not.be.ok;
1275
+ });
1276
+ });
1277
+ describe.skip('custom filtering', function () {
1278
+ beforeEach(function () {
1279
+ // @ts-expect-error: we intend to implement this in the next release
1280
+ element.customFilter = option =>
1281
+ // @ts-expect-error: TODO add filter feature
1282
+ new RegExp(element.filter).test(option.value);
1283
+ });
1284
+ beforeEach(focus);
1285
+ beforeEach(updateComplete);
1286
+ describe('r', function () {
1287
+ beforeEach(press('r'));
1288
+ beforeEach(updateComplete);
1289
+ it('shows options that contain "r"', async function () {
1290
+ expect(getVisibleOptionValues(element)).to.deep.equal([
1291
+ 'Green',
1292
+ 'Orange',
1293
+ 'Purple',
1294
+ ]);
663
1295
  });
1296
+ });
1297
+ describe('typing "R"', function () {
1298
+ beforeEach(press('R'));
1299
+ beforeEach(nextFrame);
664
1300
  beforeEach(updateComplete);
665
- it('focuses the typeahead input', async function () {
666
- const snapshot = await a11ySnapshot();
667
- const [input] = snapshot.children ?? [];
668
- expect(input.focused).to.be.true;
669
- expect(input.role).to.equal('combobox');
1301
+ it('shows options that start with "r"', async function () {
1302
+ expect(getVisibleOptionValues(element)).to.deep.equal([
1303
+ 'Red',
1304
+ ]);
670
1305
  });
671
- describe('pressing ArrowDown', function () {
672
- beforeEach(press('ArrowDown'));
1306
+ });
1307
+ });
1308
+ });
1309
+ describe('<label for="select"><pf-select variant="typeahead">', function () {
1310
+ let element;
1311
+ beforeEach(async function () {
1312
+ element = await createFixture(html `
1313
+ <pf-select variant="typeahead" id="select">
1314
+ <pf-option value="1">1</pf-option>
1315
+ <pf-option value="2">2</pf-option>
1316
+ <pf-option value="3">3</pf-option>
1317
+ </pf-select>
1318
+ <label for="select">label1</label>
1319
+ <label for="select">label2</label>
1320
+ `);
1321
+ });
1322
+ it('passes aXe audit', async function () {
1323
+ await expect(element).to.be.accessible();
1324
+ });
1325
+ it('labels the combobox with the label elements', async function () {
1326
+ expect(await a11ySnapshot()).to.axContainQuery({
1327
+ role: 'combobox',
1328
+ name: 'label1label2',
1329
+ });
1330
+ });
1331
+ describe('show()', function () {
1332
+ beforeEach(() => element.show());
1333
+ it('labels the listbox with the placeholder attribute', async function () {
1334
+ expect(await a11ySnapshot()).to.axContainQuery({
1335
+ role: 'listbox',
1336
+ name: 'label1label2',
1337
+ });
1338
+ });
1339
+ });
1340
+ });
1341
+ // try again when we implement activedescendant
1342
+ describe.skip('<pf-select variant="typeaheadmulti">', function () {
1343
+ let element;
1344
+ const updateComplete = () => element.updateComplete;
1345
+ const focus = () => element.focus();
1346
+ beforeEach(async function () {
1347
+ element = await createFixture(html `
1348
+ <pf-select variant="typeaheadmulti">
1349
+ <pf-option value="Amethyst">Amethyst</pf-option>
1350
+ <pf-option value="Beryl">Beryl</pf-option>
1351
+ <pf-option value="Chalcedony">Chalcedony</pf-option>
1352
+ <pf-option value="Diamond">Diamond</pf-option>
1353
+ <pf-option value="Emerald">Emerald</pf-option>
1354
+ <pf-option value="Fool's Gold">Fool's Gold</pf-option>
1355
+ <pf-option value="Garnet">Garnet</pf-option>
1356
+ <pf-option value="Halite">Halite</pf-option>
1357
+ <pf-option value="Iris">Iris</pf-option>
1358
+ </pf-select>`);
1359
+ });
1360
+ describe('focus()', function () {
1361
+ beforeEach(focus);
1362
+ beforeEach(updateComplete);
1363
+ it('focuses the typeahead input', async function () {
1364
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axRole('combobox');
1365
+ });
1366
+ describe('ArrowDown', function () {
1367
+ beforeEach(press('ArrowDown'));
1368
+ beforeEach(updateComplete);
1369
+ it('shows the listbox', async function () {
1370
+ expect(element.expanded).to.be.true;
1371
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
1372
+ });
1373
+ it('focuses the first option', async function () {
1374
+ expect(getActiveOption(element)).to.have.property('value', 'Amethyst');
1375
+ });
1376
+ describe('Shift+Tab', function () {
1377
+ beforeEach(holdShift);
1378
+ beforeEach(press('Tab'));
1379
+ beforeEach(releaseShift);
673
1380
  beforeEach(updateComplete);
674
- it('expands', function () {
675
- expect(element.expanded).to.be.true;
1381
+ it('closes', function () {
1382
+ expect(element.expanded).to.be.false;
676
1383
  });
677
- it('shows the listbox', async function () {
678
- const snapshot = await a11ySnapshot();
679
- expect(snapshot.children?.find(x => x.role === 'listbox')).to.be.ok;
1384
+ it('hides the listbox', async function () {
1385
+ expect(element.expanded).to.be.false;
1386
+ expect(await a11ySnapshot()).to.not.axContainRole('listbox');
680
1387
  });
681
- it('focuses the first option', async function () {
682
- const snapshot = await a11ySnapshot();
683
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
684
- expect(listbox?.children?.find(x => x.focused)?.name).to.equal('Amethyst');
1388
+ it('focuses the toggle button', async function () {
1389
+ expect(await a11ySnapshot()).axTreeFocusedNode.to.have.axRole('combobox');
685
1390
  });
686
- describe('then pressing Shift+Tab', function () {
687
- beforeEach(shiftHold);
1391
+ describe('Shift+Tab', function () {
1392
+ beforeEach(holdShift);
688
1393
  beforeEach(press('Tab'));
689
- beforeEach(shiftRelease);
1394
+ beforeEach(releaseShift);
690
1395
  beforeEach(updateComplete);
691
- it('closes', function () {
692
- expect(element.expanded).to.be.false;
693
- });
694
- it('hides the listbox', async function () {
695
- const snapshot = await a11ySnapshot();
696
- expect(snapshot.children?.find(x => x.role === 'listbox')).to.be.undefined;
697
- });
698
- it('focuses the toggle button', async function () {
699
- const snapshot = await a11ySnapshot();
700
- const focused = snapshot?.children?.find(x => x.focused);
701
- expect(focused?.role).to.equal('button');
702
- expect(focused?.haspopup).to.equal('listbox');
703
- });
704
- describe('then pressing Shift+Tab', function () {
705
- beforeEach(shiftHold);
706
- beforeEach(press('Tab'));
707
- beforeEach(shiftRelease);
708
- beforeEach(updateComplete);
709
- it('focuses the combobox input', async function () {
710
- const snapshot = await a11ySnapshot();
711
- const focused = snapshot?.children?.find(x => x.focused);
712
- expect(focused?.role).to.equal('combobox');
713
- expect(focused?.haspopup).to.equal('listbox');
714
- });
1396
+ it('focuses the combobox input', async function () {
1397
+ expect(await a11ySnapshot())
1398
+ .axTreeFocusedNode
1399
+ .to.have.axRole('combobox');
715
1400
  });
716
1401
  });
717
- describe('then pressing ArrowDown', function () {
718
- beforeEach(press('ArrowDown'));
1402
+ });
1403
+ describe('ArrowDown', function () {
1404
+ beforeEach(press('ArrowDown'));
1405
+ beforeEach(updateComplete);
1406
+ describe('Enter', function () {
1407
+ beforeEach(press('Enter'));
719
1408
  beforeEach(updateComplete);
720
- describe('then pressing Enter', function () {
721
- beforeEach(press('Enter'));
722
- beforeEach(updateComplete);
723
- it('selects the second option', function () {
724
- expect(getValues(element)).to.deep.equal(['Beryl']);
725
- });
726
- it('focuses on second option', async function () {
727
- const snapshot = await a11ySnapshot();
728
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
729
- expect(listbox?.children?.find(x => x.focused)?.name).to.equal('Beryl');
730
- });
731
- it('remains expanded', async function () {
732
- expect(element.expanded).to.be.true;
733
- const snapshot = await a11ySnapshot();
734
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
735
- expect(listbox).to.be.ok;
1409
+ it('selects the second option', function () {
1410
+ expect(getSelectedOptionValues(element)).to.deep.equal(['Beryl']);
1411
+ });
1412
+ it('focuses on second option', async function () {
1413
+ expect(getActiveOption(element)).to.have.property('value', 'Beryl');
1414
+ });
1415
+ it('remains expanded', async function () {
1416
+ expect(element.expanded).to.be.true;
1417
+ expect(await a11ySnapshot()).to.axContainRole('listbox');
1418
+ });
1419
+ it('shows 1 chip', async function () {
1420
+ expect(await a11ySnapshot())
1421
+ .to.axContainQuery({
1422
+ role: 'button',
1423
+ name: 'Close',
1424
+ description: 'Beryl',
736
1425
  });
737
- it('shows 1 chip', async function () {
738
- const snapshot = await a11ySnapshot();
739
- const [, chip1close] = snapshot.children ?? [];
740
- expect(chip1close?.role).to.equal('button');
741
- expect(chip1close?.name).to.equal('Close');
742
- expect(chip1close?.description).to.equal('Beryl');
1426
+ });
1427
+ describe('ArrowUp', function () {
1428
+ beforeEach(press('ArrowUp'));
1429
+ beforeEach(updateComplete);
1430
+ it('focuses the first option', async function () {
1431
+ expect(getActiveOption(element)).to.equal('Amethyst');
1432
+ expect(await a11ySnapshot())
1433
+ .axTreeFocusedNode.to.have.axName('Amethyst');
743
1434
  });
744
- describe('then pressing ArrowUp', function () {
745
- beforeEach(press('ArrowUp'));
1435
+ describe('Enter', function () {
1436
+ beforeEach(press('Enter'));
746
1437
  beforeEach(updateComplete);
747
- it('focuses the first option', async function () {
748
- const snapshot = await a11ySnapshot();
749
- const listbox = snapshot.children?.find(x => x.role === 'listbox');
750
- const focused = listbox?.children?.find(x => x.focused);
751
- expect(focused?.name).to.equal('Amethyst');
1438
+ it('adds second option to selected values', function () {
1439
+ expect(getSelectedOptionValues(element)).to.deep.equal([
1440
+ 'Amethyst',
1441
+ 'Beryl',
1442
+ ]);
752
1443
  });
753
- describe('then pressing Enter', function () {
754
- beforeEach(press('Enter'));
1444
+ it('accessible combo button label should be "2 items selected"', async function () {
1445
+ expect(await a11ySnapshot())
1446
+ .axTreeFocusedNode
1447
+ .to.have.axRole('combobox')
1448
+ .and
1449
+ .to.have.axName('2 items selected');
1450
+ });
1451
+ it('shows 2 chips', async function () {
1452
+ expect(await a11ySnapshot())
1453
+ .to.axContainQuery({ role: 'button', name: 'Close', description: 'Amethyst' })
1454
+ .and
1455
+ .to.axContainQuery({ role: 'button', name: 'Close', description: 'Beryl' });
1456
+ });
1457
+ describe('Shift+Tab', function () {
1458
+ beforeEach(holdShift);
1459
+ beforeEach(press('Tab'));
1460
+ beforeEach(releaseShift);
755
1461
  beforeEach(updateComplete);
756
- it('adds second option to selected values', function () {
757
- expect(getValues(element)).to.deep.equal(['Amethyst', 'Beryl']);
758
- });
759
- it('accessible combo button label should be "2 items selected"', async function () {
760
- const snapshot = await a11ySnapshot();
761
- const button = snapshot.children?.find(x => x.role === 'combobox');
762
- expect(button?.name).to.equal('2 items selected');
1462
+ it('focuses the combobox input', async function () {
1463
+ expect(await a11ySnapshot())
1464
+ .axTreeFocusedNode
1465
+ .to.have.axRole('combobox');
763
1466
  });
764
- it('shows 2 chips', async function () {
765
- const snapshot = await a11ySnapshot();
766
- const [, chip1close, , chip2close] = snapshot.children ?? [];
767
- expect(chip1close?.role).to.equal('button');
768
- expect(chip1close?.name).to.equal('Close');
769
- expect(chip1close?.description).to.equal('Amethyst');
770
- expect(chip2close?.role).to.equal('button');
771
- expect(chip2close?.name).to.equal('Close');
772
- expect(chip2close?.description).to.equal('Beryl');
773
- });
774
- describe('then pressing Shift+Tab', function () {
775
- beforeEach(shiftHold);
1467
+ describe('Shift+Tab', function () {
1468
+ beforeEach(holdShift);
776
1469
  beforeEach(press('Tab'));
777
- beforeEach(shiftRelease);
1470
+ beforeEach(releaseShift);
778
1471
  beforeEach(updateComplete);
779
- it('focuses the toggle button', async function () {
780
- const snapshot = await a11ySnapshot();
781
- const focused = snapshot.children?.find(x => x.focused);
782
- expect(focused?.role).to.equal('button');
783
- expect(focused?.haspopup).to.equal('listbox');
1472
+ it('focuses the combobox input', async function () {
1473
+ expect(await a11ySnapshot())
1474
+ .axTreeFocusedNode
1475
+ .to.have.axRole('combobox');
784
1476
  });
785
- describe('then pressing Shift+Tab', function () {
786
- beforeEach(shiftHold);
1477
+ describe('Shift+Tab', function () {
1478
+ beforeEach(holdShift);
787
1479
  beforeEach(press('Tab'));
788
- beforeEach(shiftRelease);
1480
+ beforeEach(releaseShift);
789
1481
  beforeEach(updateComplete);
790
- it('focuses the combobox input', async function () {
791
- const snapshot = await a11ySnapshot();
792
- const focused = snapshot.children?.find(x => x.focused);
793
- expect(focused?.role).to.equal('combobox');
1482
+ it('focuses the last chip\'s close button', async function () {
1483
+ expect(await a11ySnapshot())
1484
+ .axTreeFocusedNode
1485
+ .to.have.axRole('button')
1486
+ .and
1487
+ .to.have.axName('Close')
1488
+ .and
1489
+ .to.have.axDescription('Beryl');
794
1490
  });
795
- describe('then pressing Shift+Tab', function () {
796
- beforeEach(shiftHold);
797
- beforeEach(press('Tab'));
798
- beforeEach(shiftRelease);
1491
+ describe('Space', function () {
1492
+ beforeEach(updateComplete);
1493
+ beforeEach(press(' '));
799
1494
  beforeEach(updateComplete);
800
- it('focuses the last chip\'s close button', async function () {
801
- const snapshot = await a11ySnapshot();
802
- const focused = snapshot.children?.find(x => x.focused);
803
- expect(focused?.role).to.equal('button');
804
- expect(focused?.name).to.equal('Close');
805
- expect(focused?.description).to.equal('Beryl');
1495
+ beforeEach(updateComplete);
1496
+ it('removes the second chip', async function () {
1497
+ expect(await a11ySnapshot()).to.not.have.axDescription('Beryl');
806
1498
  });
807
- describe('then pressing Space', function () {
808
- beforeEach(updateComplete);
809
- beforeEach(press(' '));
810
- beforeEach(updateComplete);
1499
+ it('removes the second option from the selected values', function () {
1500
+ expect(getSelectedOptionValues(element)).to.deep.equal([
1501
+ 'Amethyst',
1502
+ ]);
1503
+ });
1504
+ it('focuses the combobox', async function () {
1505
+ expect(await a11ySnapshot())
1506
+ .axTreeFocusedNode
1507
+ .to.have.axRole('combobox');
1508
+ });
1509
+ describe('Shift+Tab', function () {
1510
+ beforeEach(holdShift);
1511
+ beforeEach(press('Tab'));
1512
+ beforeEach(releaseShift);
811
1513
  beforeEach(updateComplete);
812
- it('removes the second chip', async function () {
813
- const snapshot = await a11ySnapshot();
814
- const [, chip1close, ...rest] = snapshot.children ?? [];
815
- expect(chip1close?.role).to.equal('button');
816
- expect(chip1close?.name).to.equal('Close');
817
- expect(chip1close?.description).to.equal('Amethyst');
818
- expect(rest.filter(x => 'description' in x)?.length).to.equal(0);
819
- });
820
- it('removes the second option from the selected values', function () {
821
- expect(getValues(element)).to.deep.equal(['Amethyst']);
822
- });
823
- it('focuses the combobox', async function () {
824
- const snapshot = await a11ySnapshot();
825
- const focused = snapshot.children?.find(x => x.focused);
826
- expect(focused?.role).to.equal('combobox');
1514
+ it('focuses the first chip', async function () {
1515
+ expect(await a11ySnapshot())
1516
+ .axTreeFocusedNode
1517
+ .to.have.axRole('combobox')
1518
+ .and
1519
+ .to.have.axDescription('Amethyst');
827
1520
  });
828
- describe('then pressing Shift+Tab', function () {
829
- beforeEach(shiftHold);
830
- beforeEach(press('Tab'));
831
- beforeEach(shiftRelease);
1521
+ describe('Space', function () {
1522
+ beforeEach(press(' '));
832
1523
  beforeEach(updateComplete);
833
- it('focuses the first chip', async function () {
834
- const snapshot = await a11ySnapshot();
835
- const focused = snapshot.children?.find(x => x.focused);
836
- expect(focused?.role).to.equal('button');
837
- expect(focused?.description).to.equal('Amethyst');
1524
+ it('removes all chips', async function () {
1525
+ expect(await a11ySnapshot()).to.not.axContainRole('button');
838
1526
  });
839
- describe('then pressing Space', function () {
840
- beforeEach(press(' '));
841
- beforeEach(updateComplete);
842
- it('removes all chips', async function () {
843
- const snapshot = await a11ySnapshot();
844
- expect(snapshot.children?.find(x => x.role === 'button' && x.name === 'Close'))
845
- .to.be.undefined;
846
- });
847
- it('focuses the typeahead input', async function () {
848
- const snapshot = await a11ySnapshot();
849
- const focused = snapshot.children?.find(x => x.focused);
850
- expect(focused?.role).to.equal('combobox');
851
- });
1527
+ it('focuses the combobox', async function () {
1528
+ expect(await a11ySnapshot())
1529
+ .axTreeFocusedNode
1530
+ .to.have.axRole('combobox');
852
1531
  });
853
1532
  });
854
1533
  });