dimsum-e2e-tests 3.70.0-next.7 → 3.70.0-next.71

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 (297) hide show
  1. package/CHANGELOG.md +1079 -721
  2. package/ds-accordion/DSAccordion.visual.spec.js +6 -0
  3. package/ds-accordion/DSAccordionCO.js +15 -3
  4. package/ds-accordion/QA_NOTES.md +105 -0
  5. package/ds-accordion/controlled/DSAccordion.controlled.func.spec.js +23 -0
  6. package/ds-accordion/header-structure/DSAccordion.header-structure.func.spec.js +65 -0
  7. package/ds-accordion/input-inside/DSAccordion.input-inside.func.spec.js +19 -0
  8. package/ds-apppicker/DSAppPickerCO.js +101 -3
  9. package/ds-apppicker/aria-pattern/DSAppPicker.aria-pattern.func.spec.js +100 -0
  10. package/ds-apppicker/basic/DSAppPicker.basic.keyboard-nav.func.spec.js +18 -7
  11. package/ds-apppicker/closeAfterSelection/DSAppPicker.closeAfterSelection.func.spec.js +1 -1
  12. package/ds-apppicker/custom-trigger-focus/DSAppPicker.custom-trigger-focus.func.spec.js +82 -0
  13. package/ds-apppicker/label-expansion-dismissal/DSAppPicker.label-expansion-dismissal.visual.spec.js +108 -0
  14. package/ds-apppicker/reflow/DSAppPicker.reflow.func.spec.js +32 -0
  15. package/ds-apppicker/reflow/DSAppPicker.reflow.visual.spec.js +5 -6
  16. package/ds-apppicker/truncation/DSAppPicker.truncation.visual.spec.js +5 -9
  17. package/ds-autocomplete/DSAutocomplete.visual.spec.js +34 -0
  18. package/ds-autocomplete/DSAutocompleteCO.js +36 -1
  19. package/ds-autocomplete/aria-busy-loading/DSAutocomplete.aria-busy-loading.axe-core.func.spec.js +50 -0
  20. package/ds-autocomplete/aria-busy-loading/DSAutocomplete.aria-busy-loading.func.spec.js +122 -0
  21. package/ds-autocomplete/aria-busy-loading/DSAutocomplete.aria-busy-loading.visual.spec.js +48 -0
  22. package/ds-autocomplete/slots/DSAutocomplete.slots.func.spec.js +6 -1
  23. package/ds-banner/DSBanner.text-resize.visual.spec.js +5 -2
  24. package/ds-banner/DSBannerCO.js +4 -0
  25. package/ds-button-v3/DSButtonV3.aria-disabled-attribute.func.spec.js +33 -0
  26. package/ds-button-v3/DSButtonV3CO.js +10 -0
  27. package/ds-button-v3/theme-font/DSButtonV3.theme-font.func.spec.js +30 -0
  28. package/ds-card/DSCard.cardv2_v1.func.spec.js +54 -0
  29. package/ds-card/DSCard.cardv2_v1.visual.spec.js +29 -0
  30. package/ds-card/DSCardCO.js +50 -0
  31. package/ds-card/detail-slots/DSCard.detail-slots.axe-core.func.spec.js +29 -0
  32. package/ds-card/detail-slots/DSCard.detail-slots.func.spec.js +72 -0
  33. package/ds-card/detail-slots/DSCard.detail-slots.visual.spec.js +19 -0
  34. package/ds-card-v3/DSCardV3CO.js +93 -1
  35. package/ds-card-v3/accordion/DSCardV3.accordion-aria-structure.func.spec.js +41 -0
  36. package/ds-card-v3/accordion/DSCardV3.accordion-aria.keyboard.func.spec.js +49 -0
  37. package/ds-card-v3/accordion/DSCardV3.accordion.axe-core.func.spec.js +28 -0
  38. package/ds-card-v3/accordion/DSCardV3.accordion.visual.spec.js +4 -6
  39. package/ds-card-v3/action/DSCardV3.action.axe-core.func.spec.js +24 -0
  40. package/ds-card-v3/action/DSCardV3.action.func.spec.js +53 -0
  41. package/ds-card-v3/action/DSCardV3.action.visual.spec.js +28 -0
  42. package/ds-card-v3/drag-n-drop/DSCardV3.DnD.axe-core.func.spec.js +42 -0
  43. package/ds-card-v3/drag-n-drop/DSCardV3.DnD.func.spec.js +129 -0
  44. package/ds-card-v3/drag-n-drop/DSCardV3.DnD.reorder.func.spec.js +73 -0
  45. package/ds-card-v3/drag-n-drop/DSCardV3.DnD.visual.spec.js +5 -12
  46. package/ds-card-v3/global-attributes/DSCardV3.global-attributes.axe-core.func.spec.js +33 -0
  47. package/ds-card-v3/global-attributes/DSCardV3.global-attributes.visual.spec.js +20 -0
  48. package/ds-card-v3/multi-select/DSCardV3.multi-select.aria-grouping.func.spec.js +24 -0
  49. package/ds-card-v3/multi-select/DSCardV3.multiselect.axe-core.func.spec.js +47 -0
  50. package/ds-card-v3/multi-select/DSCardV3.multiselect.keyboard.func.spec.js +65 -0
  51. package/ds-card-v3/multi-select/DSCardV3.multiselect.visual.spec.js +17 -0
  52. package/ds-card-v3/multiple-action/DSCardV3.multiple-action.axe-core.func.spec.js +35 -0
  53. package/ds-card-v3/multiple-action/DSCardV3.multiple-action.func.spec.js +53 -0
  54. package/ds-card-v3/multiple-action/DSCardV3.multiple-action.visual.spec.js +18 -0
  55. package/ds-card-v3/multiple-control/DSCardV3.multi-control.axe-core.func.spec.js +34 -0
  56. package/ds-card-v3/multiple-control/DSCardV3.multi-control.func.spec.js +26 -0
  57. package/ds-card-v3/multiple-control/DSCardV3.multi-control.visual.spec.js +29 -0
  58. package/ds-card-v3/no-action/DSCardV3.no-action.axe-core.func.spec.js +22 -0
  59. package/ds-card-v3/no-action/DSCardV3.no-action.func.spec.js +23 -0
  60. package/ds-card-v3/no-action/DSCardV3.no-action.visual.spec.js +15 -0
  61. package/ds-card-v3/notification-badges/DSCardV3.notification-badges.axe-core.func.spec.js +33 -0
  62. package/ds-card-v3/notification-badges/DSCardV3.notification-badges.func.spec.js +19 -0
  63. package/ds-card-v3/notification-badges/DSCardV3.notification-badges.visual.spec.js +28 -0
  64. package/ds-card-v3/reflow/DSCardV3.reflow.axe-core.func.spec.js +28 -0
  65. package/ds-card-v3/reflow/DSCardV3.reflow.func.spec.js +36 -0
  66. package/ds-card-v3/reflow/DSCardV3.reflow.visual.spec.js +3 -2
  67. package/ds-card-v3/single-select/DSCardV3.single-select.aria-grouping.func.spec.js +24 -0
  68. package/ds-card-v3/single-select/DSCardV3.single-select.axe-core.func.spec.js +37 -0
  69. package/ds-card-v3/single-select/DSCardV3.single-select.visual.spec.js +1 -2
  70. package/ds-card-v3/slots/DSCardV3.slots.visual.spec.js +1 -2
  71. package/ds-card-v3/variant-accented/DSCardV3.variant-accented.axe-core.func.spec.js +45 -0
  72. package/ds-card-v3/variant-accented/DSCardV3.variant-accented.func.spec.js +28 -0
  73. package/ds-card-v3/variant-accented/DSCardV3.variant-accented.visual.spec.js +35 -0
  74. package/ds-card-v3/variant-accented-disabled/DSCardV3.variant-accented-disabled.axe-core.func.spec.js +35 -0
  75. package/ds-card-v3/variant-accented-disabled/DSCardV3.variant-accented-disabled.func.spec.js +53 -0
  76. package/ds-card-v3/variant-accented-disabled/DSCardV3.variant-accented-disabled.visual.spec.js +28 -0
  77. package/ds-card-v3/variant-disabled/DSCardV3.variant-disabled.axe-core.func.spec.js +22 -0
  78. package/ds-card-v3/variant-disabled/DSCardV3.variant-disabled.func.spec.js +61 -0
  79. package/ds-card-v3/variant-disabled/DSCardV3.variant-disabled.visual.spec.js +20 -0
  80. package/ds-card-v3/variant-disabled/DSCardV3.variantDisabled-non-interactive.func.spec.js +25 -0
  81. package/ds-chat/DSChat.axe-core.func.spec.js +2 -2
  82. package/ds-chat/DSChat.visual.spec.js +4 -4
  83. package/ds-chat/DSChatCO.js +18 -24
  84. package/ds-chat/bubbles/slots/DSChatBubble.slots.axe-core.func.spec.js +24 -0
  85. package/ds-chat/bubbles/slots/DSChatBubble.slots.func.spec.js +49 -0
  86. package/ds-chat/bubbles/slots/DSChatBubble.slots.visual.spec.js +25 -0
  87. package/ds-chat/card/slots/DSChatCard.slots.axe-core.func.spec.js +24 -0
  88. package/ds-chat/card/slots/DSChatCard.slots.func.spec.js +47 -0
  89. package/ds-chat/card/slots/DSChatCard.slots.visual.spec.js +18 -0
  90. package/ds-chat/card/truncated-text/DSChatCard.truncated-text.func.spec.js +32 -0
  91. package/ds-chat/card/truncated-text/DSChatCard.truncated-text.visual.spec.js +26 -0
  92. package/ds-chat/card/with-notification-badges/DSChatCard.with-notification-badges.axe-core.func.spec.js +23 -0
  93. package/ds-chat/card/with-notification-badges/DSChatCard.with-notification-badges.visual.spec.js +17 -0
  94. package/ds-chat/components/BubbleCO.js +46 -3
  95. package/ds-chat/components/CardCO.js +75 -0
  96. package/ds-chat/components/ComposerCO.js +6 -6
  97. package/ds-chat/components/FloatingButtonCO.js +5 -3
  98. package/ds-chat/components/HeaderCO.js +2 -2
  99. package/ds-chat/components/TileCO.js +82 -0
  100. package/ds-chat/components/index.js +3 -2
  101. package/ds-chat/floatingbutton/DSChat-floating-button.visual.spec.js +1 -1
  102. package/ds-chat/loadmore/DSChat-loadmore.func.spec.js +1 -1
  103. package/{ds-chat-tile → ds-chat/tile}/DSChat-tile.axe-core.func.spec.js +2 -2
  104. package/{ds-chat-tile → ds-chat/tile}/DSChat-tile.func.spec.js +1 -1
  105. package/{ds-chat-tile → ds-chat/tile}/DSChat-tile.visual.spec.js +2 -2
  106. package/{ds-chat-tile → ds-chat/tile}/aria-disabled/DSChat-tile.aria-disabled.axe-core.func.spec.js +2 -2
  107. package/{ds-chat-tile → ds-chat/tile}/aria-disabled/DSChat-tile.aria-disabled.visual.spec.js +1 -1
  108. package/ds-chat/tile/slots/DSChatTile.slots.func.spec.js +53 -0
  109. package/ds-chat/tile/slots/DSChatTile.slots.visual.spec.js +18 -0
  110. package/ds-chip/label-expansion-dismissal/DSChip.label-expansion-dismissal.visual.spec.js +84 -0
  111. package/ds-controlled-form/ds-combobox/creatable/DSCombobox.creatable-tooltip.func.spec.js +47 -0
  112. package/ds-controlled-form/ds-combobox/creatable/DSCombobox.creatable.visual.spec.js +12 -21
  113. package/ds-controlled-form/ds-combobox/disabled/DSCombobox.disabled.visual.spec.js +6 -1
  114. package/ds-controlled-form/ds-controlled-checkbox/Basic/DSControlledCheckbox.axe-core.basic.func.spec.js +4 -4
  115. package/ds-controlled-form/ds-controlled-checkbox/Basic/DSControlledCheckbox.basic.visual.spec.js +56 -0
  116. package/ds-controlled-form/ds-controlled-checkbox/DSControlledCheckboxCO.js +54 -1
  117. package/ds-controlled-form/ds-controlled-checkbox/Disabled/DSControlledCheckbox.axe-core.disabled.func.spec.js +1 -1
  118. package/ds-controlled-form/ds-controlled-checkbox/Disabled/DSControlledCheckbox.disabled.visual.spec.js +1 -1
  119. package/ds-controlled-form/ds-controlled-checkbox/HasError/DSControlledCheckbox.axe-core.hasError.func.spec.js +4 -4
  120. package/ds-controlled-form/ds-controlled-checkbox/HasError/DSControlledCheckbox.has-error.visual.spec.js +71 -1
  121. package/ds-controlled-form/ds-controlled-checkbox/Mixed/DSControlledCheckbox.axe-core.mixed.func.spec.js +4 -4
  122. package/ds-controlled-form/ds-controlled-checkbox/Mixed/DSControlledCheckbox.mixed.visual.spec.js +1 -1
  123. package/ds-controlled-form/ds-controlled-checkbox/ReadOnly/DSControlledCheckbox.axe-core.read-only.func.spec.js +3 -3
  124. package/ds-controlled-form/ds-controlled-checkbox/ReadOnly/DSControlledCheckbox.read-only.visual.spec.js +1 -1
  125. package/ds-controlled-form/ds-controlled-checkbox/WithTooltip/DSControlledCheckbox.axe-core.with-tooltip.func.spec.js +1 -1
  126. package/ds-controlled-form/ds-controlled-checkbox/WithTooltip/DSControlledCheckbox.with-tooltip.visual.spec.js +1 -3
  127. package/ds-controlled-form/ds-controlled-checkbox/WrapLabel/DSControlledCheckbox.axe-core.wrap-label.func.spec.js +1 -1
  128. package/ds-controlled-form/ds-controlled-checkbox/WrapLabel/DSControlledCheckbox.wrap-label.visual.spec.js +1 -1
  129. package/ds-controlled-form/ds-controlled-checkbox/aria-disabled/DSControlledCheckbox.aria-disabled.visual.spec.js +2 -6
  130. package/ds-controlled-form/ds-controlled-checkbox/aria-disabled/DSControlledCheckbox.axe-core.aria-disabled.func.spec.js +1 -1
  131. package/ds-controlled-form/ds-controlled-checkbox/slots/DSControlledCheckbox.slots.func.spec.js +78 -0
  132. package/ds-controlled-form/ds-controlled-checkbox/theme-font/DSControlledCheckbox.theme-font.func.spec.js +30 -0
  133. package/ds-controlled-form/ds-controlled-checkbox-group/DSControlledCheckboxGroup.axe-core.func.spec.js +4 -4
  134. package/ds-controlled-form/ds-controlled-checkbox-group/DSControlledCheckboxGroup.visual.spec.js +1 -1
  135. package/ds-controlled-form/ds-controlled-radio/DSControlledRadioCO.js +50 -1
  136. package/ds-controlled-form/ds-controlled-radio/aria-disabled/DSControlledRadio.aria-disabled.axe-core.func.spec.js +16 -2
  137. package/ds-controlled-form/ds-controlled-radio/aria-disabled/DSControlledRadio.aria-disabled.func.spec.js +37 -0
  138. package/ds-controlled-form/ds-controlled-radio/slots/DSControlledRadio.slots.func.spec.js +78 -0
  139. package/ds-controlled-form/ds-controlled-radio/theme-font/DSControlledRadio.theme-font.func.spec.js +30 -0
  140. package/ds-controlled-form/react-hook-form/ReactHook.func.spec.js +1 -3
  141. package/ds-data-table-async/DSDataTableCO.js +187 -10
  142. package/ds-data-table-async/basic/DSDataTable.basic.visual.spec.js +1 -1
  143. package/ds-data-table-async/components/FilterBarCO.js +7 -0
  144. package/ds-data-table-async/components/FiltersCO.js +1 -1
  145. package/ds-data-table-async/components/HeaderCO.js +37 -1
  146. package/ds-data-table-async/dnd/DSDataTable.dnd-keyboard-scroll.func.spec.js +51 -0
  147. package/ds-data-table-async/filter-menu-close/DSDataTable.filter-menu-close.func.spec.js +77 -0
  148. package/ds-data-table-async/filter-popover-boundary/DSDataTable.filter-popover-boundary.func.spec.js +98 -0
  149. package/ds-data-table-async/filters/DSDataTable.filters-creatable-active-descendant.func.spec.js +51 -0
  150. package/ds-data-table-async/filters/DSDataTable.filters-creatable.func.spec.js +55 -0
  151. package/ds-data-table-async/filters/DSDataTable.filters.axe-core.func.spec.js +11 -9
  152. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-creatablemultiselect.keyboard.func.spec.js +2 -2
  153. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-creatableselect.keyboard.func.spec.js +2 -2
  154. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2.axe-core.func.spec.js +45 -29
  155. package/ds-data-table-async/filtersV2/pill-label/DSDataTable.pillLabel.axe-core.func.spec.js +23 -0
  156. package/ds-data-table-async/filtersV2/pill-label/DSDataTable.pillLabel.func.spec.js +50 -0
  157. package/ds-data-table-async/filtersV2/pill-label/DSDataTable.pillLabel.visual.spec.js +21 -0
  158. package/ds-data-table-async/header-affordances/DSDataTable.header-affordances.func.spec.js +92 -0
  159. package/ds-data-table-async/helpers/getInputSelection.js +6 -0
  160. package/ds-data-table-async/helpers/index.js +1 -0
  161. package/ds-data-table-async/keyboard-scroll/DSDataTable.keyboard-scroll.func.spec.js +39 -0
  162. package/ds-data-table-async/menubutton/DSDataTable.MenuButton.keyboard.func.spec.js +8 -7
  163. package/ds-data-table-async/menubutton/DSDataTable.MenuButton.mouse.func.spec.js +6 -7
  164. package/ds-data-table-async/pagination/DSDataTable.pagination.func.spec.js +3 -2
  165. package/ds-data-table-async/resizable/DSDataTable.resize-min-clamp.func.spec.js +72 -0
  166. package/ds-data-table-async/resizable/DSDataTable.resizerA11y.axe-core.func.spec.js +42 -0
  167. package/ds-data-table-async/resizable/DSDataTable.resizerA11y.func.spec.js +98 -0
  168. package/ds-data-table-async/textwrapping/DSDataTable.header-wrap-alignment.axe-core.func.spec.js +23 -0
  169. package/ds-data-table-async/textwrapping/DSDataTable.header-wrap-alignment.visual.spec.js +106 -0
  170. package/ds-data-table-async/textwrapping/DSDataTable.text-wrap-toolbar.visual.spec.js +27 -0
  171. package/ds-data-table-async/toggle-cell-focus/DSDataTable.toggle-cell-enter-focus.func.spec.js +31 -0
  172. package/ds-data-table-async/vissibility/DSDataTable.vissibility.visual.spec.js +2 -0
  173. package/ds-dataviz/DSDataViz.axis.visual.spec.js +1 -2
  174. package/ds-dataviz/DSDataViz.ticks.visual.spec.js +1 -2
  175. package/ds-dataviz/DSDataVizCO.js +2 -0
  176. package/ds-dataviz/axecore/DSDataViz.axis.axe-core.func.spec.js +1 -1
  177. package/ds-floating-context/DSFloatingContextCO.js +10 -0
  178. package/ds-floating-context/placement/DSFloatingContext.placement.visual.spec.js +48 -0
  179. package/ds-form-combobox-multi/DSComboboxMultiCO.js +36 -9
  180. package/ds-form-combobox-multi/aria-busy-loading/DSComboboxMulti.aria-busy-loading.axe-core.func.spec.js +55 -0
  181. package/ds-form-combobox-multi/aria-busy-loading/DSComboboxMulti.aria-busy-loading.func.spec.js +57 -0
  182. package/ds-form-combobox-multi/aria-disabled/DSComboboxMulti.aria-disabled.visual.spec.js +19 -2
  183. package/ds-form-combobox-multi/disabled/DSComboboxMulti.disabled.axe-core.func.spec.js +24 -0
  184. package/ds-form-combobox-multi/disabled/DSComboboxMulti.disabled.mouse.func.spec.js +0 -2
  185. package/ds-form-combobox-multi/disabled/DSComboboxMulti.disabled.visual.spec.js +22 -0
  186. package/ds-form-combobox-multi/grouped/DSComboboxMulti.grouped.visual.spec.js +42 -0
  187. package/ds-form-combobox-multi/inline/DSComboboxMulti.inline.visual.spec.js +21 -0
  188. package/ds-form-combobox-multi/pills/DSComboboxMulti.pills.func.spec.js +59 -0
  189. package/ds-form-combobox-multi/pills/DSComboboxMulti.pills.visual.spec.js +39 -0
  190. package/ds-form-combobox-multi/skeleton/DSComboboxMulti.skeleton.visual.spec.js +25 -0
  191. package/ds-form-combobox-multi/theme-font/DSComboboxMulti.theme-font.func.spec.js +38 -0
  192. package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.axe-core.func.spec.js +39 -0
  193. package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.func.spec.js +39 -0
  194. package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.visual.spec.js +29 -0
  195. package/ds-form-combobox-single/DSComboboxSingleCO.js +25 -9
  196. package/ds-form-combobox-single/aria-busy-loading/DSComboboxSingle.aria-busy-loading.axe-core.func.spec.js +49 -0
  197. package/ds-form-combobox-single/aria-busy-loading/DSComboboxSingle.aria-busy-loading.func.spec.js +54 -0
  198. package/ds-form-combobox-single/aria-disabled/DSComboboxSingle.aria-disabled.visual.spec.js +18 -0
  199. package/ds-form-combobox-single/creatable/DSComboboxSingle.creatable.visual.spec.js +30 -0
  200. package/ds-form-combobox-single/disabled/DSComboboxSingle.disabled.axe-core.func.spec.js +24 -0
  201. package/ds-form-combobox-single/disabled/DSComboboxSingle.disabled.mouse.func.spec.js +0 -2
  202. package/ds-form-combobox-single/disabled/DSComboboxSingle.disabled.visual.spec.js +22 -0
  203. package/ds-form-combobox-single/grouped/DSComboboxSingle.grouped.visual.spec.js +45 -0
  204. package/ds-form-combobox-single/inline/DSComboboxSingle.inline.visual.spec.js +23 -0
  205. package/ds-form-combobox-single/skeleton/DSComboboxSingle.skeleton.visual.spec.js +25 -0
  206. package/ds-form-combobox-single/theme-font/DSComboboxSingle.theme-font.func.spec.js +34 -0
  207. package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.axe-core.func.spec.js +39 -0
  208. package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.func.spec.js +39 -0
  209. package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.visual.spec.js +29 -0
  210. package/ds-form-date-range-picker/DateRangePicker.axe-core.spec.js +5 -0
  211. package/ds-form-date-range-picker/DateRangePicker.functional.spec.js +80 -18
  212. package/ds-form-date-range-picker/DateRangePickerCO.js +19 -0
  213. package/ds-form-date-range-picker/date-segment-aria-labels/DateRangePicker.date-segment-aria-labels.func.spec.js +66 -0
  214. package/ds-form-date-range-picker/grouped-field-error-announcement/DateRangePicker.grouped-field-error-announcement.func.spec.js +59 -0
  215. package/ds-form-date-range-picker/picker-callbacks/DateRangePicker.picker-callbacks.func.spec.js +36 -0
  216. package/ds-form-date-time-picker/DSControlledDateTimePickerCO.js +7 -0
  217. package/ds-form-date-time-picker/date-time-full/DateTimeFull.axe-core.func.spec.js +8 -1
  218. package/ds-form-date-time-picker/date-time-full/DateTimePicker.DateTimeFull.visual.spec.js +9 -0
  219. package/ds-form-date-time-picker/partial-date-open-focus/DateTimePicker.partial-date-open-focus.func.spec.js +45 -0
  220. package/ds-form-native-select/NativeSelect.axe-core.func.spec.js +39 -0
  221. package/ds-form-native-select/NativeSelect.visual.spec.js +33 -0
  222. package/ds-form-native-select/NativeSelectCO.js +6 -0
  223. package/ds-form-native-select/option-selection/NativeSelect.option-selection.func.spec.js +25 -0
  224. package/ds-form-toggle/DSToggle.func.spec.js +20 -23
  225. package/ds-form-toggle/DSToggleCO.js +11 -2
  226. package/ds-global-header/GlobalHeader.announcements.func.spec.js +27 -0
  227. package/ds-global-header/GlobalHeader.axe-core.func.spec.js +15 -15
  228. package/ds-global-header/GlobalHeader.func.spec.js +70 -1
  229. package/ds-global-header/GlobalHeaderCO.js +120 -2
  230. package/ds-global-header/app-picker-passthrough/GlobalHeader.app-picker-passthrough.func.spec.js +113 -0
  231. package/ds-global-header/popup-menu-focus/GlobalHeader.popup-menu-focus.func.spec.js +63 -0
  232. package/ds-global-header/popup-menu-slots/GlobalHeader.popup-menu-slots.func.spec.js +70 -0
  233. package/ds-global-header/search-toggle-slots/GlobalHeader.search-toggle-slots.func.spec.js +118 -0
  234. package/ds-global-header/toolbar-item-attributes/GlobalHeader.toolbar-item-attributes.func.spec.js +53 -0
  235. package/ds-grid/DSGridCO.js +20 -0
  236. package/ds-grid/layout-mode/DSGrid.layout-mode.func.spec.js +51 -0
  237. package/ds-grid/layout-mode/DSGrid.layout-mode.visual.spec.js +22 -0
  238. package/ds-hooks/DSHook.UseFontSizeMedia.visual.spec.js +5 -2
  239. package/ds-hooks/DSHook.usetree.func.spec.js +3 -2
  240. package/ds-hooks/DSHookCO.js +56 -23
  241. package/ds-hooks/useFocusStack/DSHook.useFocusStack.func.spec.js +83 -0
  242. package/ds-hooks/useFocusTrap/UseFocusTrapCO.js +2 -0
  243. package/ds-hooks/useFocusTrap/UseFocusTrapToggle.func.spec.js +48 -0
  244. package/ds-hooks/useMask/Number/UseNumberMask.axe-core.func.spec.js +48 -0
  245. package/ds-menu-button/DSMenuButtonCO.js +23 -0
  246. package/ds-menu-button/slots/DSMenuButton.slots.axe-core.func.spec.js +28 -0
  247. package/ds-menu-button/slots/DSMenuButton.slots.func.spec.js +59 -0
  248. package/ds-menu-button/slots/DSMenuButton.slots.visual.spec.js +26 -0
  249. package/ds-modal-slide/ModalSlideCO.js +7 -0
  250. package/ds-modal-slide/custom-header/ModalSlide.customHeader.focusRing.visual.spec.js +2 -1
  251. package/ds-modal-slide/heading-level/ModalSlide.headingLevel.axe-core.func.spec.js +25 -0
  252. package/ds-modal-slide/heading-level/ModalSlide.headingLevel.func.spec.js +25 -0
  253. package/ds-modal-slide/slots/ModalSlide.slots.func.spec.js +18 -0
  254. package/ds-notification-badge/DSNotificationBadge.visual.spec.js +17 -20
  255. package/ds-page-layout/PageLayoutCO.js +4 -4
  256. package/ds-pills-v2/DSPillsV2CO.js +12 -0
  257. package/ds-pills-v2/apply-aria-disabled/DSPills.applyAriaDisabled.func.spec.js +53 -0
  258. package/ds-pills-v2/apply-aria-disabled/DSPills.applyAriaDisabled.visual.spec.js +26 -0
  259. package/ds-pills-v2/disabled/DSPills.disabled.func.spec.js +53 -0
  260. package/ds-pills-v2/disabled/DSPills.disabled.visual.spec.js +33 -0
  261. package/ds-progress-indicator/DSProgressIndicator.axe-core.func.spec.js +2 -0
  262. package/ds-progress-indicator/DSProgressIndicatorCO.js +1 -1
  263. package/ds-query-builder/DSQueryBuilder.visual.spec.js +6 -6
  264. package/ds-shuttle-v2/DSShuttleV2CO.js +15 -1
  265. package/ds-shuttle-v2/breadcrumb-a11y/DSShuttleV2.breadcrumb-a11y.func.spec.js +43 -0
  266. package/ds-shuttle-v2/explicit-selection-ui/DSShuttleV2.explicit-selection-ui.func.spec.js +37 -0
  267. package/ds-shuttle-v2/explicit-selection-ui/DSShuttleV2.explicit-selection-ui.visual.spec.js +30 -0
  268. package/ds-shuttle-v2/extra/DSShuttleV2.extra.visual.spec.js +8 -3
  269. package/ds-shuttle-v2/items/DSShuttleV2.items.func.spec.js +4 -2
  270. package/ds-shuttle-v2/skipped/DSShuttleV2.extra.axe-core.skipped.js +1 -1
  271. package/ds-shuttle-v2/skipped/DSShuttleV2.filter.axe-core.skipped.js +1 -1
  272. package/ds-shuttle-v2/skipped/DSShuttleV2.globalcheckbox.axe-core.skipped.js +1 -1
  273. package/ds-shuttle-v2/skipped/DSShuttleV2.items.axe-core.skipped.js +3 -3
  274. package/ds-shuttle-v2/skipped/DSShuttleV2.skipped.js +5 -5
  275. package/ds-slider-v2/DSSliderV2.func.spec.js +36 -25
  276. package/ds-slider-v2/DSSliderV2CO.js +10 -0
  277. package/ds-slider-v2/min-range/DSSliderV2.min-range.func.spec.js +69 -0
  278. package/ds-tab-button/DSTabButton.func.spec.js +1 -1
  279. package/ds-tabs/DSTabsCO.js +4 -0
  280. package/ds-tabs/notification-badge/DSTabs.notification-badge.axe-core.func.spec.js +28 -0
  281. package/ds-tabs/notification-badge/DSTabs.notification-badge.func.spec.js +51 -0
  282. package/ds-tooltip-v3/DSTooltipV3CO.js +21 -0
  283. package/ds-tooltip-v3/aria-tooltip-pattern/DSTooltipV3.aria-tooltip-pattern.axe-core.func.spec.js +23 -0
  284. package/ds-tooltip-v3/aria-tooltip-pattern/DSTooltipV3.aria-tooltip-pattern.func.spec.js +29 -0
  285. package/ds-tooltip-v3/dialog/DSTooltipV3.dialog.func.spec.js +45 -0
  286. package/ds-tooltip-v3/dialog/DSTooltipV3.dialog.visual.spec.js +29 -0
  287. package/ds-treeview/DSTreeViewCO.js +23 -0
  288. package/ds-treeview/dragAndDrop/TreeView-dnd_keyboard.func.spec.js +96 -0
  289. package/ds-typography/DSTypographyCO.js +10 -0
  290. package/ds-typography/theme-font/DSTypography.theme-font.func.spec.js +30 -0
  291. package/package.json +150 -153
  292. package/paths.js +16 -6
  293. package/ds-card-v3/disabled/DSCardV3.disabled.visual.spec.js +0 -17
  294. package/ds-chat-tile/TileCO.js +0 -35
  295. package/ds-hooks/DSHook.func.spec.js +0 -60
  296. package/ds-hooks/useFocusStack/DSHook.useFocusStack.skipped.js +0 -57
  297. package/ds-treeview/dragAndDrop/TreeView-dnd_mouse.func.spec.js +0 -61
@@ -0,0 +1,77 @@
1
+ import DSDataTableCO from '../DSDataTableCO';
2
+ import { HeaderCO, FiltersCO } from '../components';
3
+
4
+ // Tests for the fix introduced in PUI-18785 (an open per-column filter menu did not close when the
5
+ // user clicked that column's header cell, grabbed its drag-and-drop handle, or grabbed its resize
6
+ // handle — the filter popover's floating reference is the whole header cell, so the click-outside
7
+ // detection never saw any of those interactions as "outside", and the menu could be dragged around
8
+ // the table while open).
9
+ //
10
+ // The SortByColumn story is the repro combination named in the defect: per-column filters +
11
+ // dragAndDropColumns + isResizeable on the same table.
12
+ //
13
+ // The target is the Country column: it is filterable but canSort is false, so a header click has
14
+ // only the filter to close and never also triggers a sort — the assertions stay about the menu and
15
+ // nothing else. That also makes FiltersCO.openFilterPopperByColumnName safe to use here even though
16
+ // it clicks the header cell to reveal the affordance; hovering instead is not portable, because in
17
+ // Safari the filter button stays aria-hidden/tabindex="-1" and never becomes interactable.
18
+ //
19
+ // Deviation from the ticket, asserted deliberately: PUI-18785's Expected Results asked that a
20
+ // column "should not be draggable while its filter menu is open". The shipped fix instead closes
21
+ // the menu and lets the same single gesture continue into the drag/resize, so these tests assert
22
+ // that shipped behavior — the menu closes, and the interaction is not swallowed just to close it.
23
+ const COUNTRY_COLUMN = 'country';
24
+ const COUNTRY_COLUMN_INDEX = 3;
25
+
26
+ const openCountryFilterMenu = async () => {
27
+ await FiltersCO.openFilterPopperByColumnName(COUNTRY_COLUMN);
28
+ await expect(await FiltersCO.getFilterMenuContent()).toBeDisplayed();
29
+ };
30
+
31
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
32
+ describe('PUI-18887 - DSDataTable:: filter menu closes on header, drag and resize - Func', () => {
33
+ beforeEach(async () => {
34
+ const errorOnGo = await DSDataTableCO.sortByColumn.go();
35
+ if (errorOnGo) throw errorOnGo;
36
+ await DSDataTableCO.waitForDataTable();
37
+ });
38
+
39
+ it('01: clicking the column header closes an open filter menu and keeps the trigger', async () => {
40
+ await openCountryFilterMenu();
41
+
42
+ const countryHeader = await HeaderCO.getHeaderCellByText(COUNTRY_COLUMN);
43
+ await countryHeader.click();
44
+
45
+ await expect(await FiltersCO.getFilterMenuContent()).not.toBeDisplayed();
46
+ // Closing the menu must not take its own trigger with it. An over-broad fix that removed the
47
+ // whole filter affordance would still satisfy the assertion above, so the trigger is checked
48
+ // explicitly. Existence rather than visibility: the filter button is toggled with display:none
49
+ // by the header's own affordance logic, so a visibility assertion would be testing that
50
+ // unrelated hover/active state instead of the fix.
51
+ const filterBtn = await FiltersCO.getHeaderCellFilterButtonByHeaderCell(countryHeader, 0);
52
+ await expect(filterBtn).toBeExisting();
53
+ });
54
+
55
+ it('02: activating the column drag handle closes an open filter menu', async () => {
56
+ await openCountryFilterMenu();
57
+
58
+ const countryHeader = await HeaderCO.getHeaderCellByText(COUNTRY_COLUMN);
59
+ const dragHandle = await HeaderCO.getHeaderCellDragHandler(countryHeader);
60
+ await dragHandle.click();
61
+
62
+ await expect(await FiltersCO.getFilterMenuContent()).not.toBeDisplayed();
63
+ });
64
+
65
+ it('03: grabbing the column resize handle closes an open filter menu', async () => {
66
+ await openCountryFilterMenu();
67
+
68
+ // A real press-move-release on the 4px handle, which is what fires onResizeStart. Asserting
69
+ // the resize itself is out of scope here — that is PUI-18764's job; this test only proves the
70
+ // press reaches the resizer and closes the menu.
71
+ const resizer = await HeaderCO.getResizeHandler(COUNTRY_COLUMN_INDEX);
72
+ await resizer.dragAndDrop({ x: 30, y: 0 });
73
+
74
+ await expect(await FiltersCO.getFilterMenuContent()).not.toBeDisplayed();
75
+ });
76
+ });
77
+ }
@@ -0,0 +1,98 @@
1
+ import DSDataTableCO from '../DSDataTableCO';
2
+ import { FiltersCO } from '../components';
3
+
4
+ // Tests for the fix introduced in PUI-17187 (the filter trigger lives inside DataTable's own
5
+ // horizontally-scrollable container, but the popover only clipped against the browser viewport, so
6
+ // once its column scrolled near the table's edge the popover kept tracking the trigger's raw screen
7
+ // position and spilled out over the rest of the page). The fix passes the scroll container as
8
+ // ds-floating-context's boundaryElement, which clamps the popover to the table and hides it — without
9
+ // closing it — once the trigger is fully scrolled away.
10
+ //
11
+ // The Pui17136FilterWidthCollapse story is the repro named in the defect: a 400px-wide table with
12
+ // colsLayoutStyle="fixed" and nine filterable columns, so there is real horizontal overflow.
13
+ //
14
+ // The Name column is targeted rather than the ticket's Number range column: it sits near the left
15
+ // edge, so scrolling right drives it against the table's OWN left edge, which is the geometry the
16
+ // fix is about, and it is reachable without scrolling first. Both columns exercise the same
17
+ // boundaryElement math.
18
+ const TARGET_COLUMN = 'name';
19
+
20
+ // The popover repositions on a debounce, so every geometry assertion polls rather than sampling once.
21
+ const SETTLE_TIMEOUT = 5000;
22
+
23
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
24
+ describe('PUI-18888 - DSDataTable:: filter popover clamped to the table on horizontal scroll - Func', () => {
25
+ beforeEach(async () => {
26
+ const errorOnGo = await DSDataTableCO.filterWidthCollapse.go();
27
+ if (errorOnGo) throw errorOnGo;
28
+ await DSDataTableCO.waitForDataTable();
29
+ await FiltersCO.openFilterPopperByColumnName(TARGET_COLUMN);
30
+ await expect(await FiltersCO.getFilterMenuContent()).toBeDisplayed();
31
+ });
32
+
33
+ it('01: should keep the popover inside the table bounds while its column is clipped', async () => {
34
+ const geometry = await DSDataTableCO.getColumnScrollGeometry(TARGET_COLUMN);
35
+ expect(geometry).not.toBe(null);
36
+
37
+ // Leave a 20px sliver of the column visible at the scrollport's left edge: the trigger is
38
+ // partially clipped by the table itself, which is exactly the PUI-17187 repro state.
39
+ const partiallyClipped = Math.min(geometry.colRight - 20, geometry.maxScrollLeft);
40
+ expect(partiallyClipped).toBeGreaterThan(0);
41
+ await DSDataTableCO.setScrollableContainerScrollLeft(partiallyClipped);
42
+
43
+ await browser.waitUntil(
44
+ async () => {
45
+ const rects = await DSDataTableCO.getFilterPopoverBoundaryRects();
46
+ if (!rects) return false;
47
+ // 1px of tolerance for sub-pixel layout rounding.
48
+ return rects.popoverLeft >= rects.containerLeft - 1 && rects.popoverRight <= rects.containerRight + 1;
49
+ },
50
+ {
51
+ timeout: SETTLE_TIMEOUT,
52
+ timeoutMsg: 'filter popover was not clamped inside the table scrollport after horizontal scroll',
53
+ },
54
+ );
55
+ });
56
+
57
+ it('02: should hide the popover without closing it once its column scrolls out of view', async () => {
58
+ const geometry = await DSDataTableCO.getColumnScrollGeometry(TARGET_COLUMN);
59
+ expect(geometry).not.toBe(null);
60
+
61
+ // Precondition, asserted rather than assumed: the table must be able to scroll far enough to
62
+ // push the column past its left edge. If it cannot, clamping to maxScrollLeft would leave the
63
+ // column visible and the hide assertion below would fail with a misleading message.
64
+ expect(geometry.maxScrollLeft).toBeGreaterThan(geometry.colRight);
65
+ await DSDataTableCO.setScrollableContainerScrollLeft(geometry.colRight + 1);
66
+
67
+ await browser.waitUntil(
68
+ async () => {
69
+ const rects = await DSDataTableCO.getFilterPopoverBoundaryRects();
70
+ return Boolean(rects) && rects.opacity === '0' && rects.pointerEvents === 'none';
71
+ },
72
+ {
73
+ timeout: SETTLE_TIMEOUT,
74
+ timeoutMsg: 'filter popover was not hidden after its column scrolled out of view',
75
+ },
76
+ );
77
+
78
+ // Hidden, not closed: the popover is still mounted, so scrolling back restores it instead of
79
+ // the user having to reopen the filter. getFilterPopoverBoundaryRects returning a value at all
80
+ // already proves the node is in the DOM; assert it explicitly so the intent is not implicit.
81
+ await expect(await FiltersCO.getFilterMenuContent()).toBeExisting();
82
+
83
+ await DSDataTableCO.setScrollableContainerScrollLeft(0);
84
+
85
+ await browser.waitUntil(
86
+ async () => {
87
+ const rects = await DSDataTableCO.getFilterPopoverBoundaryRects();
88
+ return Boolean(rects) && rects.opacity === '1' && rects.pointerEvents === 'auto';
89
+ },
90
+ {
91
+ timeout: SETTLE_TIMEOUT,
92
+ timeoutMsg: 'filter popover did not reappear after scrolling its column back into view',
93
+ },
94
+ );
95
+ await expect(await FiltersCO.getFilterMenuContent()).toBeDisplayed();
96
+ });
97
+ });
98
+ }
@@ -0,0 +1,51 @@
1
+ import { Key } from 'webdriverio';
2
+ import DSDataTableCO from '../DSDataTableCO';
3
+ import { FiltersCO } from '../components';
4
+ import { type } from '../../helpers';
5
+
6
+ // Tests for the fix introduced in PUI-15735. The Name column derives its filter options from the
7
+ // *filtered* data, so a value created in the filter is dropped from the options on the next render;
8
+ // getFirstOption() used to focus it anyway, leaving aria-activedescendant pointing at a dead id.
9
+ const describeActiveDescendant = ({ activeDescendant, optionIds }) => {
10
+ if (activeDescendant === null) return 'input-missing';
11
+ if (activeDescendant === '') return 'none';
12
+ return optionIds.includes(activeDescendant) ? 'rendered-option' : `orphan:${activeDescendant}`;
13
+ };
14
+
15
+ const VALID_ACTIVE_DESCENDANT = /^(none|rendered-option)$/;
16
+
17
+ if (
18
+ (!browser.capabilities['ice:options'].isPhone &&
19
+ !browser.capabilities['ice:options'].isTablet &&
20
+ browser.capabilities.browserName === 'chrome') ||
21
+ browser.capabilities.browserName === 'Chrome'
22
+ ) {
23
+ describe('PUI-18882 - DSDataTable:: creatable filter aria-activedescendant validity - Func', () => {
24
+ beforeEach('loading page', async () => {
25
+ const errorOnGo = await DSDataTableCO.filteredCreatable.go();
26
+ if (errorOnGo) throw errorOnGo;
27
+ await DSDataTableCO.waitForDataTable();
28
+ });
29
+ it('01: reopening the filter after an Enter-created option keeps the id valid', async () => {
30
+ await FiltersCO.openFilterPopperByColumnName('name');
31
+ await type('Juan');
32
+ await browser.keys(Key.Enter);
33
+ // Reopening is the regression path for the getFirstOption() half: it runs when the menu
34
+ // mounts, and by then the created value is gone from the Name column's derived options.
35
+ await FiltersCO.openFilterPopperByColumnName('name');
36
+ const state = await DSDataTableCO.getFilterActiveDescendantState();
37
+ await expect(describeActiveDescendant(state)).toMatch(VALID_ACTIVE_DESCENDANT);
38
+ });
39
+ it('02: creating an option by mouse click clears the stale focus target', async () => {
40
+ // The multi-select creatable column, not the single-select one: selecting in a single-select
41
+ // filter closes the popper, leaving no input to read, and reopening would let the
42
+ // getFirstOption() guard mask this half of the fix. Multi-select keeps the menu open, so the
43
+ // assertion lands on the state handleOnCreateClick's setFocusOptionIdx('') is responsible for.
44
+ await FiltersCO.openFilterPopperByColumnName('position');
45
+ await type('Zulu dev');
46
+ await (await FiltersCO.getFilterMultiSelectMenuItem(0)).click();
47
+ const state = await DSDataTableCO.getFilterActiveDescendantState();
48
+ await expect(describeActiveDescendant(state)).toMatch(VALID_ACTIVE_DESCENDANT);
49
+ });
50
+ });
51
+ }
@@ -4,8 +4,13 @@ import { Key } from 'webdriverio';
4
4
  import DSDataTableCO from '../DSDataTableCO';
5
5
  import { FilterBarCO, FiltersCO, RowCO } from '../components';
6
6
  import { type } from '../../helpers';
7
+ import { getInputSelection } from '../helpers';
7
8
  import DSComboboxCO from '../../ds-controlled-form/ds-combobox/DSComboboxCO';
8
9
 
10
+ // A value the Name column's data never contains, so only the creatable affordance is listed and
11
+ // the input keeps the full string for the caret/selection assertions.
12
+ const TYPED_FILTER_TEXT = 'aloha';
13
+
9
14
  if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
10
15
  describe('PUI-9203 - DataTable, Filter, Creatable single select filter', () => {
11
16
  before('loading page', async () => {
@@ -114,4 +119,54 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
114
119
  await expect(newOption).toEqual('New option');
115
120
  });
116
121
  });
122
+ // Tests for the fix introduced in PUI-15851 (a wrapper-level mousedown preventDefault() in the
123
+ // combobox's `inline` mode suppressed the browser's native caret placement and word selection,
124
+ // and a second click on the focused input blurred it, clearing the value and closing the menu).
125
+ //
126
+ // PUI-15851 was reopened and moved to 27.2: the fix traded away click-to-close on the combobox
127
+ // control (PUI-18919), a behavior ratified in PUI-15737 / PUI-15753 and encoded as QA acceptance
128
+ // criteria in PUI-15741 / PUI-15748. Until that interaction is redefined, the expectations below
129
+ // are not a stable contract, so this describe is describe.skip'd and PUI-18881 is back to a
130
+ // non-automated state.
131
+ //
132
+ // The rollback is PR #8307 (fix/PUI-18919, open against next as of 27.1). It reverts #8233
133
+ // wholesale: the wrapper-level mousedown preventDefault() is restored for clicks on the input,
134
+ // as is the hidden-span width measurement and the click handler that blurs the input on a second
135
+ // click. So once it merges all three cases below go red, not just case 03 — the caret and
136
+ // word-selection behavior they assert stops existing again. That is why the whole describe is
137
+ // skipped rather than case 03 alone. The cases are kept in tree rather than deleted because 01
138
+ // and 02 are not the disputed part and should be the starting point for the 27.2 coverage; only
139
+ // 03 (a second click keeps the value, focus and open menu) has to be re-written, once 27.2
140
+ // settles what a pointer click on the filter search input should do.
141
+ describe.skip('PUI-18881 - DSDataTable:: filter search input mouse caret and selection - Func', () => {
142
+ beforeEach('loading page', async () => {
143
+ const errorOnGo = await DSDataTableCO.filteredCreatable.go();
144
+ if (errorOnGo) throw errorOnGo;
145
+ await DSDataTableCO.waitForDataTable();
146
+ await FiltersCO.openFilterPopperByColumnName('name');
147
+ await type(TYPED_FILTER_TEXT);
148
+ });
149
+ it('01: clicking near the left edge moves the caret off the end of the text', async () => {
150
+ const input = await FiltersCO.getFilterSingleSelectInput();
151
+ // WDIO click offsets are relative to the element centre, so walk back to ~2px from the left
152
+ // edge instead of hardcoding a pixel — stays correct if padding or width changes.
153
+ const { width } = await input.getSize();
154
+ await input.click({ x: -Math.floor(width / 2) + 2, y: 0 });
155
+ const { start } = await getInputSelection(input);
156
+ await expect(start).toBeLessThan(TYPED_FILTER_TEXT.length);
157
+ });
158
+ it('02: double-clicking selects the word under the cursor', async () => {
159
+ const input = await FiltersCO.getFilterSingleSelectInput();
160
+ await input.doubleClick();
161
+ const { start, end } = await getInputSelection(input);
162
+ await expect(end - start).toBeGreaterThan(0);
163
+ });
164
+ it('03: a second click on the focused input keeps the value, focus and open menu', async () => {
165
+ const input = await FiltersCO.getFilterSingleSelectInput();
166
+ await input.click();
167
+ await expect(input).toHaveValue(TYPED_FILTER_TEXT);
168
+ await expect(input).toBeFocused();
169
+ await expect(await FiltersCO.getFilterSingleSelectPopper()).toBeDisplayed();
170
+ });
171
+ });
117
172
  }
@@ -76,22 +76,24 @@ if (
76
76
  await expect(result.length).toBe(0);
77
77
  });
78
78
  });
79
- // unskip this test after PUI-15735 is fixed
80
- describe.skip('PUI-11443 - DataTable, Creatable single select filter - focus after clear input - AxeCore', () => {
81
- before('loading page', async () => {
79
+ // Tests for the fix introduced in PUI-15735 (aria-activedescendant pointed at an id no longer
80
+ // present in the rendered options after creating and selecting a filter option, tripping axe's
81
+ // aria-valid-attr-value). Repaired and unskipped under its own pre-existing ticket, PUI-11443.
82
+ // Only the Enter path is scanned: both create paths converge on the same DOM, and axe asserts a
83
+ // DOM state. Per-path precision lives in DSDataTable.filters-creatable-active-descendant.
84
+ describe('PUI-11443 - DSDataTable:: aria validity when creating a filter option - AxeCore', () => {
85
+ beforeEach('loading page', async () => {
82
86
  const errorOnGo = await DSDataTableCO.filteredCreatable.go();
83
87
  if (errorOnGo) throw errorOnGo;
84
88
  await DSDataTableCO.waitForDataTable();
85
- });
86
- it('01: should open the popup and generate a creatable option and pass axe-core scan', async () => {
87
- await FiltersCO.openFilterPopperByColumnName('name', 0);
89
+ await FiltersCO.openFilterPopperByColumnName('name');
88
90
  await type('Juan');
91
+ });
92
+ it('01: the creatable affordance shown while typing passes an axe-core scan', async () => {
89
93
  const result = await axeCoreCheck();
90
94
  await expect(result.length).toBe(0);
91
95
  });
92
- it('02: should open generate and accept creatable option and pass axe-core scan', async () => {
93
- await FiltersCO.openFilterPopperByColumnName('name', 0);
94
- await type('Juan');
96
+ it('02: creating and selecting the option with Enter passes an axe-core scan', async () => {
95
97
  await browser.keys(Key.Enter);
96
98
  const result = await axeCoreCheck();
97
99
  await expect(result.length).toBe(0);
@@ -5,7 +5,7 @@ import { FiltersCO } from '../components';
5
5
 
6
6
  if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
7
7
  // Forward keyboard navigation
8
- describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Multi Select, forward keyboard navigation', () => {
8
+ describe('PUI-18203 - DataTable:: Filters V2 - Creatable Multi Select, forward keyboard navigation', () => {
9
9
  before('loading page', async () => {
10
10
  const errorOnGo = await DSDataTableCO.creatableMultiSelectFilterV2.go();
11
11
  if (errorOnGo) throw errorOnGo;
@@ -38,7 +38,7 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
38
38
  });
39
39
 
40
40
  // Backward keyboard navigation
41
- describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Multi Select, backward keyboard navigation', () => {
41
+ describe('PUI-18204 - DataTable:: Filters V2 - Creatable Multi Select, backward keyboard navigation', () => {
42
42
  before('loading page', async () => {
43
43
  const errorOnGo = await DSDataTableCO.creatableMultiSelectFilterV2.go();
44
44
  if (errorOnGo) throw errorOnGo;
@@ -5,7 +5,7 @@ import { FiltersCO } from '../components';
5
5
 
6
6
  if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
7
7
  // Forward keyboard navigation
8
- describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Select, forward keyboard navigation', () => {
8
+ describe('PUI-18201 - DataTable:: Filters V2 - Creatable Select, forward keyboard navigation', () => {
9
9
  before('loading page', async () => {
10
10
  const errorOnGo = await DSDataTableCO.creatableSelectFilterV2.go();
11
11
  if (errorOnGo) throw errorOnGo;
@@ -38,7 +38,7 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
38
38
  });
39
39
 
40
40
  // Backward keyboard navigation
41
- describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Select, backward keyboard navigation', () => {
41
+ describe('PUI-18202 - DataTable:: Filters V2 - Creatable Select, backward keyboard navigation', () => {
42
42
  before('loading page', async () => {
43
43
  const errorOnGo = await DSDataTableCO.creatableSelectFilterV2.go();
44
44
  if (errorOnGo) throw errorOnGo;
@@ -1,37 +1,53 @@
1
1
  import DSDataTableCO from '../DSDataTableCO';
2
- import { FiltersCO } from '../components';
2
+ import { FilterBarCO, FiltersCO } from '../components';
3
3
  import { axeCoreCheck } from '../../helpers';
4
4
 
5
- if (browser.capabilities.browserName === 'chrome') {
6
- if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
7
- describe('PUI-18108 - DataTable:: Filters V2 - All Filter Types - Axe-Core', () => {
8
- before(async () => {
9
- const errorOnGo = await DSDataTableCO.allFiltersV2.go();
10
- if (errorOnGo) throw errorOnGo;
11
- await DSDataTableCO.waitForDataTable();
12
- });
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'chrome') ||
9
+ browser.capabilities.browserName === 'Chrome'
10
+ ) {
11
+ describe('PUI-18108 - DataTable:: Filters V2 - All Filter Types - Axe-Core', () => {
12
+ before(async () => {
13
+ const errorOnGo = await DSDataTableCO.allFiltersV2.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ await DSDataTableCO.waitForDataTable();
16
+ });
13
17
 
14
- it('01: should have no accessibility violations in default state', async () => {
15
- const result = await axeCoreCheck();
16
- expect(result.length).toBe(0);
17
- });
18
+ it('01: should have no accessibility violations in default state', async () => {
19
+ const result = await axeCoreCheck();
20
+ expect(result.length).toBe(0);
21
+ });
18
22
 
19
- it('02: should have no accessibility violations with filter popper open', async () => {
20
- await FiltersCO.openFilterPopperByColumnName('id');
21
- const footer = await FiltersCO.getFilterFooter();
22
- await footer.waitForDisplayed();
23
- const result = await axeCoreCheck();
24
- expect(result.length).toBe(0);
25
- });
23
+ it('02: should have no accessibility violations with filter popper open', async () => {
24
+ await FiltersCO.openFilterPopperByColumnName('id');
25
+ const footer = await FiltersCO.getFilterFooter();
26
+ await footer.waitForDisplayed();
27
+ // `scrollable-region-focusable` is a documented axe-core false positive for the filter
28
+ // popper option list: it reuses the DS combobox listbox (TanStack Virtual + container
29
+ // tabindex=-1 Firefox scroll workaround), leaving a residual scrollHeight. The options are
30
+ // fully keyboard-operable through the combobox widget model, so WCAG 2.1.1 is satisfied.
31
+ // Same disposition as the ds-combobox axe specs; dev team confirmed no real a11y issue.
32
+ const result = await axeCoreCheck({ extraDisabledRules: ['scrollable-region-focusable'] });
33
+ expect(result.length).toBe(0);
34
+ });
26
35
 
27
- it('03: should have no accessibility violations with applied filter and pills', async () => {
28
- const menuItem = await FiltersCO.getFilterSingleSelectMenuItem(0);
29
- await menuItem.click();
30
- const applyBtn = await FiltersCO.getFilterApplyButton();
31
- await applyBtn.click();
32
- const result = await axeCoreCheck();
33
- expect(result.length).toBe(0);
34
- });
36
+ it('03: should have no accessibility violations with applied filter and pills', async () => {
37
+ // Self-contained: re-open the single-select ('id') popper (openFilterPopperByColumnName
38
+ // clicks the header cell first, resetting any leftover popper state), pick an option and
39
+ // apply so a pill renders, then scan.
40
+ await FiltersCO.openFilterPopperByColumnName('id');
41
+ const footer = await FiltersCO.getFilterFooter();
42
+ await footer.waitForDisplayed();
43
+ const menuItem = await FiltersCO.getFilterSingleSelectMenuItem(0);
44
+ await menuItem.click();
45
+ const applyBtn = await FiltersCO.getFilterApplyButton();
46
+ await applyBtn.click();
47
+ const pills = await FilterBarCO.getAllPills();
48
+ await expect(pills.length).toBeGreaterThan(0);
49
+ const result = await axeCoreCheck({ extraDisabledRules: ['scrollable-region-focusable'] });
50
+ expect(result.length).toBe(0);
35
51
  });
36
- }
52
+ });
37
53
  }
@@ -0,0 +1,23 @@
1
+ import DSDataTableCO from '../../DSDataTableCO';
2
+ import { axeCoreCheck } from '../../../helpers';
3
+
4
+ // Tests for column.pillLabel added in PUI-8318 (custom pill labels must not introduce a11y violations)
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'chrome') ||
9
+ browser.capabilities.browserName === 'Chrome'
10
+ ) {
11
+ describe('PUI-18727 - DSDataTable:: custom filter pill label - Axe-Core', () => {
12
+ before(async () => {
13
+ const errorOnGo = await DSDataTableCO.pillLabelCustomization.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ await DSDataTableCO.waitForDataTable();
16
+ });
17
+
18
+ it('01: should have no accessibility violations with custom and default pill labels', async () => {
19
+ const result = await axeCoreCheck();
20
+ expect(result.length).toBe(0);
21
+ });
22
+ });
23
+ }
@@ -0,0 +1,50 @@
1
+ import DSDataTableCO from '../../DSDataTableCO';
2
+ import { FilterBarCO } from '../../components';
3
+
4
+ // Tests for column.pillLabel added in PUI-8318 (overrides Header as filter pill label + remove aria-label)
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'chrome') ||
9
+ browser.capabilities.browserName === 'Chrome'
10
+ ) {
11
+ describe('PUI-18726 - DSDataTable:: custom filter pill label - Func', () => {
12
+ before(async () => {
13
+ const errorOnGo = await DSDataTableCO.pillLabelCustomization.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ await DSDataTableCO.waitForDataTable();
16
+ });
17
+
18
+ it('01: should use pillLabel over Header on the OOTB pill label and remove aria-labels', async () => {
19
+ const roleLabel = await FilterBarCO.getLabelPillByName('Role');
20
+ await expect(roleLabel).toBeDisplayed();
21
+
22
+ const removeReact = await FilterBarCO.getPillCloseButtonByName('Remove React dev from Role');
23
+ await expect(removeReact).toBeExisting();
24
+
25
+ const removeFullstack = await FilterBarCO.getPillCloseButtonByName('Remove Fullstack dev from Role');
26
+ await expect(removeFullstack).toBeExisting();
27
+ });
28
+
29
+ it('02: should fall back to Header when the column has no pillLabel', async () => {
30
+ const nameLabel = await FilterBarCO.getLabelPillByName('Name');
31
+ await expect(nameLabel).toBeDisplayed();
32
+
33
+ const removeAlice = await FilterBarCO.getPillCloseButtonByName('Remove Alice from Name');
34
+ await expect(removeAlice).toBeExisting();
35
+ });
36
+
37
+ it('03: should render a fully custom pill (columnHeader + icon) via customPillRenderers', async () => {
38
+ const compensationLabel = await FilterBarCO.getLabelPillByName('Compensation');
39
+ await expect(compensationLabel).toBeDisplayed();
40
+
41
+ // Custom renderer draws its own icon — proves customPillRenderers replaces the OOTB pill content.
42
+ const customIcon = await FilterBarCO.getPillIconByName('Compensation');
43
+ await expect(customIcon).toBeExisting();
44
+
45
+ const removeAriaLabel = 'Remove 10000.00 - 90000.00 from Compensation';
46
+ const removeCompensation = await FilterBarCO.getPillCloseButtonByName(removeAriaLabel);
47
+ await expect(removeCompensation).toBeExisting();
48
+ });
49
+ });
50
+ }
@@ -0,0 +1,21 @@
1
+ /* eslint-disable wdio/no-pause */
2
+ import DSDataTableCO from '../../DSDataTableCO';
3
+
4
+ // Visual coverage for PUI-8318 filter pill customizations: the composable filter bar renders the
5
+ // OOTB pills (Role via pillLabel, Name via Header fallback) alongside a fully custom pill
6
+ // (Compensation) with a custom icon and a custom color, produced through customPillRenderers.
7
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
8
+ describe('PUI-18747 - DSDataTable:: custom filter pill rendering - Visual', () => {
9
+ before(async () => {
10
+ const errorOnGo = await DSDataTableCO.pillLabelCustomization.go();
11
+ if (errorOnGo) throw errorOnGo;
12
+ await DSDataTableCO.waitForDataTable();
13
+ });
14
+
15
+ it('01: should render OOTB and custom pills (icon + color) in the composable filter bar', async () => {
16
+ await browser.pause(300);
17
+ const snapshot = await browser.percyCheckScreenshot(DSDataTableCO.snapshotPath('pill-label-custom-pills'));
18
+ await expect(snapshot).toEqual(0);
19
+ });
20
+ });
21
+ }
@@ -0,0 +1,92 @@
1
+ import { mouseOver } from '../../helpers';
2
+ import DSDataTableCO from '../DSDataTableCO';
3
+ import { HeaderCO, RowCO } from '../components';
4
+
5
+ // Coverage for PUI-15154 (fixed): the column-header affordances — DnD drag handle, neutral sort
6
+ // caret and filter icon — stayed visibly stuck after focus/hover left the header (null-vs-null
7
+ // false match in the onBlur guard; missing resetAllHeadersExcept between columns). They must only
8
+ // show while the header has focus or hover. jsdom can't move real focus or hover, so this is
9
+ // verified in a real browser here (the shipped unit test fakes it with synthetic relatedTarget).
10
+ //
11
+ // SortByColumn columns: id(0) name(1, actively sorted) position(2) country(3) salary(4) date(5).
12
+ // position = drag handle + neutral sort caret + filter icon; date = the reported-bug column
13
+ // (drag handle + neutral sort caret, no filter). All columns are draggable.
14
+ const POSITION_COL = 2;
15
+ const DATE_COL = 5;
16
+
17
+ const expectAffordances = async (colIndex, shown, hasFilter) => {
18
+ const cell = await HeaderCO.getHeaderCellByIndex(colIndex);
19
+ const dragHandle = await HeaderCO.getHeaderCellDragHandler(cell);
20
+ const sortCaret = await HeaderCO.getSortBtnByIndex(colIndex);
21
+ if (shown) {
22
+ await expect(dragHandle).toBeExisting();
23
+ await expect(sortCaret).toBeDisplayed();
24
+ if (hasFilter) await expect(await HeaderCO.getFilterButtonInHeader(colIndex)).toBeDisplayed();
25
+ } else {
26
+ await expect(dragHandle).not.toBeExisting();
27
+ await expect(sortCaret).not.toBeDisplayed();
28
+ if (hasFilter) await expect(await HeaderCO.getFilterButtonInHeader(colIndex)).not.toBeDisplayed();
29
+ }
30
+ };
31
+
32
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
33
+ describe('PUI-18778 - DSDataTable:: header affordance visibility on focus and hover - Func', () => {
34
+ before(async () => {
35
+ const errorOnGo = await DSDataTableCO.sortByColumn.go();
36
+ if (errorOnGo) throw errorOnGo;
37
+ await DSDataTableCO.waitForDataTable();
38
+ });
39
+
40
+ it('01: focusing a column header shows its drag handle, sort caret and filter icon', async () => {
41
+ // Focus programmatically: the header cell has onClick=handleSort, so clicking it would also
42
+ // sort the column, and an actively-sorted column's caret then stays visible regardless of
43
+ // focus — masking the hide-on-blur behavior under test. Focusing fires onFocus without sorting.
44
+ await browser.execute((el) => el.focus(), await HeaderCO.getHeaderCellByIndex(POSITION_COL));
45
+ await expectAffordances(POSITION_COL, true, true);
46
+ });
47
+
48
+ it('02: clicking another column drag handle hides the first column drag handle', async () => {
49
+ // Marcos #2 (handle-to-handle): reveal + click column A's drag handle, then column B's.
50
+ // Focusing B's handle clears A via resetAllHeadersExcept, so A's handle no longer stays stuck.
51
+ const positionHeader = await HeaderCO.getHeaderCellByIndex(POSITION_COL);
52
+ await mouseOver(positionHeader);
53
+ const positionHandle = await HeaderCO.getHeaderCellDragHandler(positionHeader);
54
+ await positionHandle.waitForDisplayed({ timeout: 3000 });
55
+ await positionHandle.click();
56
+
57
+ const dateHeader = await HeaderCO.getHeaderCellByIndex(DATE_COL);
58
+ await mouseOver(dateHeader);
59
+ const dateHandle = await HeaderCO.getHeaderCellDragHandler(dateHeader);
60
+ await dateHandle.waitForDisplayed({ timeout: 3000 });
61
+ await dateHandle.click();
62
+
63
+ // Column A's (position) drag handle is gone; column B's (date) handle is present.
64
+ const positionCell = await HeaderCO.getHeaderCellByIndex(POSITION_COL);
65
+ await expect(await HeaderCO.getHeaderCellDragHandler(positionCell)).not.toBeExisting();
66
+ const dateCell = await HeaderCO.getHeaderCellByIndex(DATE_COL);
67
+ await expect(await HeaderCO.getHeaderCellDragHandler(dateCell)).toBeExisting();
68
+ });
69
+
70
+ it('03: blurring focus away entirely hides the affordances', async () => {
71
+ // Reported bug: focus leaves with nowhere to land. Ensure the pointer is off any header (so
72
+ // hover isn't keeping the column visible), then drop focus. onBlur fires with relatedTarget
73
+ // null and, since date has no filter, filterIconRef is null too: the null-vs-null false match
74
+ // that used to skip the reset (PUI-15154) must no longer keep the affordances stuck visible.
75
+ await mouseOver(await RowCO.getRowByIndex(3));
76
+ await browser.execute(() => {
77
+ if (document.activeElement instanceof HTMLElement) document.activeElement.blur();
78
+ });
79
+ await expectAffordances(DATE_COL, false, false);
80
+ });
81
+
82
+ it('04: hovering a column header shows its drag handle, sort caret and filter icon', async () => {
83
+ await mouseOver(await HeaderCO.getHeaderCellByIndex(POSITION_COL));
84
+ await expectAffordances(POSITION_COL, true, true);
85
+ });
86
+
87
+ it('05: moving the mouse away from the header hides the affordances', async () => {
88
+ await mouseOver(await RowCO.getRowByIndex(3));
89
+ await expectAffordances(POSITION_COL, false, true);
90
+ });
91
+ });
92
+ }