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
@@ -1,3 +1,4 @@
1
+ import { Key } from 'webdriverio';
1
2
  import { axeCoreCheck } from '../../../helpers';
2
3
  import DSControlledRadioCO from '../DSControlledRadioCO';
3
4
 
@@ -13,10 +14,23 @@ if (
13
14
  if (errorOnGo) throw errorOnGo;
14
15
  });
15
16
  it('01: should display radio with aria-disabled and pass axe-core scann', async () => {
16
- const radio = await DSControlledRadioCO.getRadioByIndex(1);
17
+ const result = await axeCoreCheck();
18
+ await expect(result).toHaveLength(0);
19
+ });
20
+ it('02: should focus and select first radio with aria-disabled and pass axe-core scann', async () => {
21
+ const radio = await DSControlledRadioCO.getRadioByIndex(0);
17
22
  await radio.click();
23
+ await expect(radio).toBeFocused();
24
+ await expect(radio).toBeSelected();
25
+ const result = await axeCoreCheck();
26
+ await expect(result).toHaveLength(0);
27
+ });
28
+ it('03: should focus second radio with aria-disabled and pass axe-core scann', async () => {
29
+ await browser.keys(Key.ArrowDown);
30
+ const radio = await DSControlledRadioCO.getRadioByIndex(1);
31
+ await expect(radio).toBeFocused();
18
32
  const result = await axeCoreCheck();
19
- expect(result.length).toBe(0);
33
+ await expect(result).toHaveLength(0);
20
34
  });
21
35
  });
22
36
  }
@@ -0,0 +1,37 @@
1
+ import { Key } from 'webdriverio';
2
+ import DSControlledRadioCO from '../DSControlledRadioCO';
3
+
4
+ if (
5
+ !browser.capabilities['ice:options'].isPhone &&
6
+ !browser.capabilities['ice:options'].isTablet &&
7
+ (browser.capabilities.browserName === 'Chrome' || browser.capabilities.browserName === 'chrome')
8
+ ) {
9
+ describe('PUI-18777 - DSControlledRadio:: aria-disabled group Tab navigation - Func', () => {
10
+ before('loading page', async () => {
11
+ const errorOnGo = await DSControlledRadioCO.applyAriaDisabled.go();
12
+ if (errorOnGo) throw errorOnGo;
13
+ });
14
+
15
+ it('01: should focus the checked option when tabbing into the aria-disabled group', async () => {
16
+ const firstRadio = await DSControlledRadioCO.getRadioByIndex(0);
17
+ await browser.keys(Key.Tab);
18
+ await expect(firstRadio).toBeFocused();
19
+ await expect(firstRadio).toBeSelected();
20
+ });
21
+ it('02: should focus the second option when arrow down is pressed', async () => {
22
+ const secondRadio = await DSControlledRadioCO.getRadioByIndex(1);
23
+ await browser.keys(Key.ArrowDown);
24
+ await expect(secondRadio).toBeFocused();
25
+ });
26
+
27
+ it('03: should tab out of the group instead of moving to the next option', async () => {
28
+ const firstRadio = await DSControlledRadioCO.getRadioByIndex(0);
29
+ const secondRadio = await DSControlledRadioCO.getRadioByIndex(1);
30
+ const thirdRadio = await DSControlledRadioCO.getRadioByIndex(2);
31
+ await browser.keys(Key.Tab);
32
+ await expect(firstRadio).not.toBeFocused();
33
+ await expect(secondRadio).not.toBeFocused();
34
+ await expect(thirdRadio).not.toBeFocused();
35
+ });
36
+ });
37
+ }
@@ -0,0 +1,78 @@
1
+ import DSControlledRadioCO from '../DSControlledRadioCO';
2
+
3
+ // Slot surface added when the DSControlledRadio label moved to DSTypography under PUI-18774:
4
+ // label-typography, truncated-label, tooltip-container and tooltip-text. The tooltip pair only
5
+ // exists while the label is truncated AND hovered, which is why this lives in E2E rather than in
6
+ // the package's jest slot tests.
7
+ if (
8
+ (!browser.capabilities['ice:options'].isPhone &&
9
+ !browser.capabilities['ice:options'].isTablet &&
10
+ browser.capabilities.browserName === 'chrome') ||
11
+ browser.capabilities.browserName === 'Chrome'
12
+ ) {
13
+ describe('PUI-18975 - DSControlledRadio:: label typography and tooltip slots - Func', () => {
14
+ before('loading page', async () => {
15
+ const errorOnGo = await DSControlledRadioCO.slotsTest.go();
16
+ if (errorOnGo) throw errorOnGo;
17
+ });
18
+
19
+ it('01: should have custom aria-* for each rendered label slot', async () => {
20
+ const root = await DSControlledRadioCO.getSlotsRoot();
21
+ const inputWrapper = await DSControlledRadioCO.getSlotsInputWrapper();
22
+ const input = await DSControlledRadioCO.getSlotsInput();
23
+ const label = await DSControlledRadioCO.getSlotsLabel();
24
+ const labelTypography = await DSControlledRadioCO.getSlotsLabelTypography();
25
+ const truncatedLabel = await DSControlledRadioCO.getSlotsTruncatedLabel();
26
+ await expect(root).toHaveAttribute('aria-label', 'root aria');
27
+ await expect(inputWrapper).toHaveAttribute('aria-label', 'inputwrapper aria');
28
+ await expect(input).toHaveAttribute('aria-label', 'input aria');
29
+ await expect(label).toHaveAttribute('aria-label', 'label aria');
30
+ await expect(labelTypography).toHaveAttribute('aria-label', 'labeltypography aria');
31
+ await expect(truncatedLabel).toHaveAttribute('aria-label', 'truncatedlabel aria');
32
+ });
33
+
34
+ it('02: should have custom data-* for each rendered label slot', async () => {
35
+ const root = await DSControlledRadioCO.getSlotsRoot();
36
+ const inputWrapper = await DSControlledRadioCO.getSlotsInputWrapper();
37
+ const input = await DSControlledRadioCO.getSlotsInput();
38
+ const label = await DSControlledRadioCO.getSlotsLabel();
39
+ const labelTypography = await DSControlledRadioCO.getSlotsLabelTypography();
40
+ const truncatedLabel = await DSControlledRadioCO.getSlotsTruncatedLabel();
41
+ await expect(root).toHaveAttribute('data-testid', 'root data');
42
+ await expect(inputWrapper).toHaveAttribute('data-testid', 'inputwrapper data');
43
+ await expect(input).toHaveAttribute('data-testid', 'input data');
44
+ await expect(label).toHaveAttribute('data-testid', 'label data');
45
+ await expect(labelTypography).toHaveAttribute('data-testid', 'labeltypography data');
46
+ await expect(truncatedLabel).toHaveAttribute('data-testid', 'truncatedlabel data');
47
+ });
48
+
49
+ it('03: should have custom lang for each rendered label slot', async () => {
50
+ const root = await DSControlledRadioCO.getSlotsRoot();
51
+ const inputWrapper = await DSControlledRadioCO.getSlotsInputWrapper();
52
+ const input = await DSControlledRadioCO.getSlotsInput();
53
+ const label = await DSControlledRadioCO.getSlotsLabel();
54
+ const labelTypography = await DSControlledRadioCO.getSlotsLabelTypography();
55
+ const truncatedLabel = await DSControlledRadioCO.getSlotsTruncatedLabel();
56
+ await expect(root).toHaveAttribute('lang', 'ja');
57
+ await expect(inputWrapper).toHaveAttribute('lang', 'it');
58
+ await expect(input).toHaveAttribute('lang', 'de');
59
+ await expect(label).toHaveAttribute('lang', 'fr');
60
+ await expect(labelTypography).toHaveAttribute('lang', 'es');
61
+ await expect(truncatedLabel).toHaveAttribute('lang', 'pt');
62
+ });
63
+
64
+ it('04: should have custom aria-*, data-* and lang for the tooltip slots on hover', async () => {
65
+ const truncatedLabel = await DSControlledRadioCO.getSlotsTruncatedLabel();
66
+ await truncatedLabel.moveTo();
67
+ const tooltipContainer = await DSControlledRadioCO.getSlotsTooltipContainer();
68
+ await tooltipContainer.waitForDisplayed();
69
+ const tooltipText = await DSControlledRadioCO.getSlotsTooltipText();
70
+ await expect(tooltipContainer).toHaveAttribute('aria-label', 'tooltipcontainer aria');
71
+ await expect(tooltipContainer).toHaveAttribute('data-testid', 'tooltipcontainer data');
72
+ await expect(tooltipContainer).toHaveAttribute('lang', 'zh');
73
+ await expect(tooltipText).toHaveAttribute('aria-label', 'tooltiptext aria');
74
+ await expect(tooltipText).toHaveAttribute('data-testid', 'tooltiptext data');
75
+ await expect(tooltipText).toHaveAttribute('lang', 'ru');
76
+ });
77
+ });
78
+ }
@@ -0,0 +1,30 @@
1
+ import DSControlledRadioCO from '../DSControlledRadioCO';
2
+
3
+ // Tests the theme-driven font-family mechanism shipped under PUI-18210
4
+ // (the radio label renders through DSTypography, which reads theme.fonts.default,
5
+ // falling back to proxima-nova). Theme-agnostic: uses a sentinel font, never the
6
+ // dsConsumer POC theme values, so it survives any future theme change.
7
+ if (
8
+ (!browser.capabilities['ice:options'].isPhone &&
9
+ !browser.capabilities['ice:options'].isTablet &&
10
+ browser.capabilities.browserName === 'chrome') ||
11
+ browser.capabilities.browserName === 'Chrome'
12
+ ) {
13
+ describe('PUI-18800 - DSControlledRadio:: theme font-family wiring - Func', () => {
14
+ before('loading page', async () => {
15
+ const errorOnGo = await DSControlledRadioCO.themeFontURL.go();
16
+ if (errorOnGo) throw errorOnGo;
17
+ });
18
+
19
+ it('01: should read label font-family from theme with proxima-nova fallback', async () => {
20
+ const themed = await DSControlledRadioCO.getThemedRadioLabel();
21
+ await themed.waitForDisplayed();
22
+ const themedFont = (await themed.getCSSProperty('font-family')).value.toLowerCase();
23
+ await expect(themedFont).toContain('sentinelfont');
24
+
25
+ const fallback = await DSControlledRadioCO.getFallbackRadioLabel();
26
+ const fallbackFont = (await fallback.getCSSProperty('font-family')).value.toLowerCase();
27
+ await expect(fallbackFont).toContain('proxima-nova');
28
+ });
29
+ });
30
+ }
@@ -67,9 +67,7 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
67
67
  const input = await ReactHookCO.getMonthInputsByIndex(2);
68
68
  const inputValue = await input.getAttribute('aria-label');
69
69
  // eslint-disable-next-line max-len
70
- await expect(inputValue).toEqual(
71
- 'month input field, current values: November, twenty second, 3333, 4, 45, ante meridiem',
72
- );
70
+ await expect(inputValue).toEqual('month');
73
71
  });
74
72
  });
75
73
  }
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable import/no-relative-packages */
2
2
  /* eslint-disable max-lines */
3
+ import { Key } from 'webdriverio';
3
4
  import {
4
5
  PATH_E2E_DATATABLE,
5
6
  PATH_E2E_DATATABLE_DND,
@@ -32,6 +33,8 @@ export default class DataTableCO extends PageObject {
32
33
 
33
34
  static DndColumnsFixedWidth = new Urlbuilder(PATH_E2E_DATATABLE_DND, 'dnd-columns-fixed-width');
34
35
 
36
+ static keyboardDragScroll = new Urlbuilder(PATH_E2E_DATATABLE_DND, 'keyboard-drag-scroll-test');
37
+
35
38
  // Filters
36
39
 
37
40
  static singleSelect = new Urlbuilder(PATH_E2E_DATATABLE_FILTERS, 'single-select-filter');
@@ -134,6 +137,8 @@ export default class DataTableCO extends PageObject {
134
137
 
135
138
  static allFiltersV2 = new Urlbuilder(PATH_E2E_DATATABLE_FILTERS_V2, 'all-filters-v-2');
136
139
 
140
+ static pillLabelCustomization = new Urlbuilder(PATH_E2E_DATATABLE_FILTERS_V2, 'pill-label-customization-test');
141
+
137
142
  // ADVANCED
138
143
 
139
144
  static groupByCol = new Urlbuilder(PATH_E2E_DATATABLE_ADVANCED, 'group-by-column');
@@ -142,12 +147,10 @@ export default class DataTableCO extends PageObject {
142
147
 
143
148
  static performance = new Urlbuilder(PATH_E2E_DATATABLE_ADVANCED, 'performance');
144
149
 
145
- static emptyStateFullCustom = new Urlbuilder(PATH_E2E_DATATABLE_ADVANCED, 'empty-state-full-custom');
146
-
147
- static customCellRowHeader = new Urlbuilder(PATH_E2E_DATATABLE_ADVANCED, 'custom-cell-row-and-header');
148
-
149
150
  static responsive = new Urlbuilder(PATH_E2E_DATATABLE_ADVANCED, 'responsive');
150
151
 
152
+ static keyboardScrollIntoView = new Urlbuilder(PATH_E2E_DATATABLE_ADVANCED, 'keyboard-scroll-into-view-test');
153
+
151
154
  // ROW
152
155
 
153
156
  static selectWithNoControl = new Urlbuilder(PATH_E2E_DATATABLE_ROW, 'select-without-column');
@@ -162,10 +165,15 @@ export default class DataTableCO extends PageObject {
162
165
 
163
166
  static singleSelectDisabledSelectionUC = new Urlbuilder(PATH_E2E_DATATABLE, 'single-select-disabled-selection');
164
167
 
165
- static multiSelectDisabledSelectionUC = new Urlbuilder(PATH_E2E_DATATABLE, 'multi-select-disabled-selection');
168
+ static multiSelectDisabledSelectionUC = new Urlbuilder(PATH_E2E_DATATABLE_ROW, 'multi-select-disabled-selection');
166
169
 
167
170
  static multiSelectEmpty = new Urlbuilder(PATH_E2E_DATATABLE_ROW, 'multi-select-empty');
168
171
 
172
+ static multiSelectDisabledWithUniqueRowAccessor = new Urlbuilder(
173
+ PATH_E2E_DATATABLE_ROW,
174
+ 'multi-select-disabled-selection-with-unique-row-accessor',
175
+ );
176
+
169
177
  // Column
170
178
 
171
179
  static columnLayout = new Urlbuilder(PATH_E2E_DATATABLE_COLUMN, 'basic-column-layout');
@@ -194,10 +202,18 @@ export default class DataTableCO extends PageObject {
194
202
  'grouping-with-hidden-and-resizable-columns',
195
203
  );
196
204
 
205
+ // PUI-18812 removed the resizerA11yMode prop, so there is one resizer shape and one story. The
206
+ // "SeparatorMode" name is historical — kept to avoid churning this URL and every spec using it.
207
+ static resizerSeparatorMode = new Urlbuilder(PATH_E2E_DATATABLE_COLUMN, 'resizer-separator-mode-test');
208
+
197
209
  // Text Wrapping
198
210
 
199
211
  static textWrapTruncColumn = new Urlbuilder(PATH_E2E_DATATABLE_TEXT_WRAPPING, 'text-wrap-truncate-column');
200
212
 
213
+ static headerWrapAlignment = new Urlbuilder(PATH_E2E_DATATABLE_TEXT_WRAPPING, 'header-wrap-alignment-test');
214
+
215
+ static textWrapGlobalWithToolbar = new Urlbuilder(PATH_E2E_DATATABLE_TEXT_WRAPPING, 'text-wrap-global');
216
+
201
217
  // Toolbar
202
218
 
203
219
  static toolbarIntegration = new Urlbuilder(PATH_E2E_DATATABLE_TOOLBAR, 'toolbar-integration');
@@ -242,6 +258,8 @@ export default class DataTableCO extends PageObject {
242
258
 
243
259
  static pui16461SkeletonAndNoResults = new Urlbuilder(PATH_E2E_DATATABLE_STATES, 'pui-16461-skeleton-and-no-results');
244
260
 
261
+ static emptyStateFullCustom = new Urlbuilder(PATH_E2E_DATATABLE_STATES, 'empty-state-full-custom');
262
+
245
263
  // Cell
246
264
  static editableCells = new Urlbuilder(PATH_E2E_DATATABLE_CELL, 'editable-cells');
247
265
 
@@ -249,6 +267,8 @@ export default class DataTableCO extends PageObject {
249
267
 
250
268
  static customCellRowAndHeaderTest = new Urlbuilder(PATH_E2E_DATATABLE_CELL, 'custom-cell-row-and-header');
251
269
 
270
+ static toggleCellEnterFocus = new Urlbuilder(PATH_E2E_DATATABLE_CELL, 'toggle-cell-enter-focus-test');
271
+
252
272
  // Use Cases
253
273
 
254
274
  static integratedExampleWithFilters = new Urlbuilder(PATH_E2E_DATATABLE_USE_CASES, 'integrated-example-with-filters');
@@ -297,11 +317,6 @@ export default class DataTableCO extends PageObject {
297
317
 
298
318
  // eslint-disable-next-line max-len
299
319
 
300
- static multiSelectDisabledWithUniqueRowAccessor = new Urlbuilder(
301
- PATH_E2E_DATATABLE,
302
- 'multi-select-disabled-selection-with-unique-row-accessor',
303
- );
304
-
305
320
  static resizableWithConstrains = new Urlbuilder(PATH_E2E_DATATABLE, 'pui-8896-resizable-with-constrains');
306
321
 
307
322
  static memoizedSearchFilterTest = new Urlbuilder(PATH_E2E_DATATABLE, 'pui-12253-memoized-filter-component');
@@ -403,6 +418,10 @@ export default class DataTableCO extends PageObject {
403
418
  return $$('[data-testid="ds-button"]')[index];
404
419
  }
405
420
 
421
+ static getRowActionResult() {
422
+ return $('[data-testid="datatable-row-action-result"]');
423
+ }
424
+
406
425
  static async getSkipToButton() {
407
426
  return $(`[id="storybook-root"] button`);
408
427
  }
@@ -415,6 +434,164 @@ export default class DataTableCO extends PageObject {
415
434
  return $('[data-testid="ds-datatable-empty-state-wrapper"]');
416
435
  }
417
436
 
437
+ // PUI-18626 — keyboard scroll-into-view
438
+
439
+ static getRows = async () => $$('[data-testid="data-table-row"]');
440
+
441
+ static getFirstRow = async () => (await this.getRows())[0];
442
+
443
+ static pressArrow = async (direction = 'down', times = 1) => {
444
+ const key = direction === 'up' ? Key.ArrowUp : Key.ArrowDown;
445
+ for (let i = 0; i < times; i += 1) {
446
+ // eslint-disable-next-line no-await-in-loop
447
+ await browser.keys(key);
448
+ }
449
+ };
450
+
451
+ /**
452
+ * Reads live layout to verify the currently focused row is scrolled fully below the sticky
453
+ * header (not clipped) after keyboard navigation. Returns viewport-relative tops/bottom in px
454
+ * plus the scroll container scrollTop. Selectors live here (not in the spec) by convention.
455
+ */
456
+ static getUpwardNavGeometry = async () =>
457
+ browser.execute(() => {
458
+ const rowSel = '[data-testid="data-table-row"], [data-testid="ds-datatable-row"]';
459
+ const headSel = '[data-testid="ds-datatable-head-wrapper"]';
460
+ const vwSel = '[data-testid="data-table-scrollable-container"]';
461
+ const active = document.activeElement;
462
+ const row = active && active.closest ? active.closest(rowSel) : null;
463
+ const focused = row || active;
464
+ const head = document.querySelector(headSel);
465
+ const vw = document.querySelector(vwSel);
466
+ return {
467
+ hasRow: Boolean(row),
468
+ rowTop: focused ? focused.getBoundingClientRect().top : null,
469
+ headerBottom: head ? head.getBoundingClientRect().bottom : null,
470
+ containerTop: vw ? vw.getBoundingClientRect().top : null,
471
+ scrollTop: vw ? vw.scrollTop : null,
472
+ };
473
+ });
474
+
475
+ // PUI-15735 — creatable filter aria-activedescendant validity
476
+
477
+ /**
478
+ * Returns the combobox input's aria-activedescendant together with the ids of every option
479
+ * currently rendered in the listbox, in one round-trip. Valid states are an empty
480
+ * aria-activedescendant or one whose value appears in optionIds.
481
+ */
482
+ static getFilterActiveDescendantState = async () =>
483
+ browser.execute(() => {
484
+ const input = document.querySelector('[data-testid="combobox-input"]');
485
+ const options = Array.from(document.querySelectorAll('[data-testid="combobox-option"]'));
486
+ return {
487
+ activeDescendant: input ? input.getAttribute('aria-activedescendant') : null,
488
+ optionIds: options.map((option) => option.id),
489
+ };
490
+ });
491
+
492
+ // PUI-8826 — keyboard row drag must not smooth-scroll
493
+
494
+ /**
495
+ * Patches the DOM scroll APIs so every programmatic scroll from this point on records its
496
+ * `behavior`. dnd-kit calls scrollTo/scrollBy directly on the scroll container's DOM node rather
497
+ * than through React, so patching the shared prototype captures every call the drag makes.
498
+ * Install after the story is loaded and before the drag starts.
499
+ */
500
+ static installScrollSpy = async () =>
501
+ browser.execute(() => {
502
+ window.dimsumScrollCalls = [];
503
+ ['scrollTo', 'scrollBy'].forEach((methodName) => {
504
+ const original = Element.prototype[methodName];
505
+ // A function expression, not an arrow, so `this` stays the scrolled element.
506
+ Element.prototype[methodName] = function scrollSpy(...args) {
507
+ const [options] = args;
508
+ if (options && typeof options === 'object') {
509
+ window.dimsumScrollCalls.push({ method: methodName, behavior: options.behavior });
510
+ }
511
+ return original.apply(this, args);
512
+ };
513
+ });
514
+ });
515
+
516
+ static getScrollSpyCalls = async () => browser.execute(() => window.dimsumScrollCalls || []);
517
+
518
+ /** Scroll offset of the virtualized viewport — proves the drag actually scrolled the list. */
519
+ static getScrollableContainerScrollTop = async () =>
520
+ browser.execute(() => {
521
+ const container = document.querySelector('[data-testid="data-table-scrollable-container"]');
522
+ return container ? container.scrollTop : null;
523
+ });
524
+
525
+ /** Id-cell text of whichever row currently owns focus — the dragged row after a keyboard drop. */
526
+ static getFocusedRowIdCellText = async () =>
527
+ browser.execute(() => {
528
+ const active = document.activeElement;
529
+ const row = active && active.closest ? active.closest('[data-testid="data-table-row"]') : null;
530
+ const cells = row ? row.querySelectorAll('[data-testid="data-table-cell"]') : [];
531
+ // Cell 0 is the drag-handle cell; the id column follows it.
532
+ return cells.length > 1 ? cells[1].textContent.trim() : null;
533
+ });
534
+
535
+ // PUI-17187 — filter popover clamped to the table's own scrollport during horizontal scroll
536
+
537
+ /**
538
+ * Horizontal-scroll geometry of one column, read live instead of hardcoded. Returns the header
539
+ * cell's offset range inside the scrolled content plus the scrollport's own width, which is what
540
+ * the two scroll targets are derived from: colLeft - clientWidth + a sliver still leaves the
541
+ * column partially visible at the left edge, while colRight puts it fully out of view. Fixed-layout
542
+ * column widths shift with viewport and theme, so a hardcoded scrollLeft would be silently wrong
543
+ * on another browser or breakpoint.
544
+ */
545
+ static getColumnScrollGeometry = async (columnName) =>
546
+ browser.execute((name) => {
547
+ const container = document.querySelector('[data-testid="data-table-scrollable-container"]');
548
+ const headers = Array.from(document.querySelectorAll('[data-testid="data-table-header"]'));
549
+ const target = headers.find((header) => (header.textContent || '').toLowerCase().includes(name.toLowerCase()));
550
+ if (!container || !target) return null;
551
+ // Derived from bounding rects plus the CURRENT scrollLeft, not offsetLeft/offsetWidth:
552
+ // offsetLeft is measured against the nearest positioned ancestor, which is not guaranteed to
553
+ // be the scrolled content, so it silently yields the wrong scroll target. This form is exact
554
+ // regardless of which ancestor happens to be positioned.
555
+ const targetRect = target.getBoundingClientRect();
556
+ const containerRect = container.getBoundingClientRect();
557
+ const colLeft = targetRect.left - containerRect.left + container.scrollLeft;
558
+ return {
559
+ colLeft,
560
+ colRight: colLeft + targetRect.width,
561
+ clientWidth: container.clientWidth,
562
+ maxScrollLeft: container.scrollWidth - container.clientWidth,
563
+ };
564
+ }, columnName);
565
+
566
+ static setScrollableContainerScrollLeft = async (value) =>
567
+ browser.execute((next) => {
568
+ const container = document.querySelector('[data-testid="data-table-scrollable-container"]');
569
+ if (container) container.scrollLeft = next;
570
+ }, value);
571
+
572
+ /**
573
+ * Popover and scrollport horizontal bounds in one round-trip, so the two rects are always sampled
574
+ * from the same frame — reading them separately can straddle a reposition and compare a stale
575
+ * popover x against a fresh container x.
576
+ */
577
+ static getFilterPopoverBoundaryRects = async () =>
578
+ browser.execute(() => {
579
+ const popover = document.querySelector('[data-testid="data-table-filter-menu-content"]');
580
+ const container = document.querySelector('[data-testid="data-table-scrollable-container"]');
581
+ if (!popover || !container) return null;
582
+ const popoverRect = popover.getBoundingClientRect();
583
+ const containerRect = container.getBoundingClientRect();
584
+ const styles = window.getComputedStyle(popover);
585
+ return {
586
+ popoverLeft: popoverRect.left,
587
+ popoverRight: popoverRect.right,
588
+ containerLeft: containerRect.left,
589
+ containerRight: containerRect.right,
590
+ opacity: styles.opacity,
591
+ pointerEvents: styles.pointerEvents,
592
+ };
593
+ });
594
+
418
595
  // Snapshots
419
596
  static snapshotPath(example = 'basic') {
420
597
  return PageObject.getSnapshotPathBuilder('DataTable', example, 'ds-data-table');
@@ -20,7 +20,7 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
20
20
  });
21
21
  describe('PUI-6988 - DataTable, Custom cell and row header -visual.', async () => {
22
22
  before('loading page', async () => {
23
- const errorOnGo = await DSDataTableCO.customCellRowHeader.go();
23
+ const errorOnGo = await DSDataTableCO.customCellRowAndHeaderTest.go();
24
24
  if (errorOnGo) throw errorOnGo;
25
25
  await DSDataTableCO.waitForDataTable();
26
26
  });
@@ -70,6 +70,13 @@ export default class FilterBarCO extends PageObject {
70
70
 
71
71
  static getPillCloseButtonByIndex = async (index) => getElementByIndex(this.getAllPillCloseButtons, index);
72
72
 
73
+ // Label pill wrapper exposes role="group" + aria-label = the pill label text (pillLabel || Header).
74
+ static getLabelPillByName = async (name) => $(`[role="group"][aria-label="${name}"]`);
75
+
76
+ // SVG icon inside a label pill (found by its accessible name) — asserts a custom pill renderer drew
77
+ // its own icon. The label pill wrapper is the role="group" element; its descendant <svg> is the icon.
78
+ static getPillIconByName = async (name) => $(`[role="group"][aria-label="${name}"] svg`);
79
+
73
80
  static async getFilterBarDropDownOption(label) {
74
81
  return $(`[role=option][label="${label}"]`);
75
82
  }
@@ -145,7 +145,7 @@ export default class FiltersCO extends PageObject {
145
145
 
146
146
  static getFilterMenuContentSlot = async () => $('[data-dimsum-slot="dsDatatableFilterPopoverContent"]');
147
147
 
148
- static getFilterPopoverSlot = async () => $('[data-dimsum-slot="dsDatatableFilterPopover"]');
148
+ static getFilterPopoverSlot = async () => $('[data-dimsum-parent-slot="dsDatatableFilterPopover"]');
149
149
 
150
150
  static getFreeTextSearchWrapperSlot = async () => $('[data-dimsum-slot="dsDatatableFreeTextSearchWrapper"]');
151
151
 
@@ -51,7 +51,19 @@ export default class HeaderCO extends PageObject {
51
51
 
52
52
  static getHeadersWrapper = async () => $('[data-testid="ds-datatable-head-wrapper"]');
53
53
 
54
- static getResizeHandler = async (index) => $$('[data-testid="column"],[aria-label="Resize column"]')[index];
54
+ // PUI-17784 / PUI-18812 / PUI-18885: the resize handle went <input type="range" aria-label="Resize
55
+ // column"> -> <button role="application" aria-labelledby> -> back to a native <input type="range">
56
+ // named with a dynamic aria-label="Resize {column} column". Selecting on data-testid rather than
57
+ // aria-label is what kept this accessor stable across all of it (the original selector matched
58
+ // neither data-testid="column" nor the post-PUI-17784 naming).
59
+ static getResizeHandler = async (index) => $$('[data-testid="ds-datatable-resizer"]')[index];
60
+
61
+ static getResizeHandlers = async () => $$('[data-testid="ds-datatable-resizer"]');
62
+
63
+ static getLastResizeHandler = async () => {
64
+ const all = await this.getResizeHandlers();
65
+ return all[all.length - 1];
66
+ };
55
67
 
56
68
  static getFilterBtnByIndex = async (index) => $$('[data-testid="data-table-filter-menu-button"] button')[index];
57
69
 
@@ -60,6 +72,30 @@ export default class HeaderCO extends PageObject {
60
72
  return headerCell.$('[data-testid="data-table-sort-button"]');
61
73
  };
62
74
 
75
+ // Filter icon wrapper scoped to a single header cell. The wrapper span carries the
76
+ // display:none/opacity:0 "hide" styling driven by the header's hover/focus state (PUI-15154),
77
+ // so its isDisplayed() reflects filter-icon visibility for that specific column.
78
+ static getFilterButtonInHeader = async (index) => {
79
+ const headerCell = await this.getHeaderCellByIndex(index);
80
+ return headerCell.$('[data-testid="data-table-filter-menu-button"]');
81
+ };
82
+
83
+ // PUI-17786: a11y accessors for the resize handle. Targets the same [data-testid="ds-datatable-resizer"]
84
+ // as the getResizeHandler selector fix (separate PR); kept distinct so these a11y specs run standalone.
85
+ static getResizer = async (index) => $$('[data-testid="ds-datatable-resizer"]')[index];
86
+
87
+ // PUI-18885 removed getResizerLabelledByText: the resizer is named with aria-label directly, so
88
+ // there is no aria-labelledby reference left to resolve. Read the attribute in the spec and use
89
+ // getResizerComputedName below for what the browser actually computes.
90
+
91
+ /**
92
+ * The accessible name the BROWSER computes for the resizer, via the W3C WebDriver
93
+ * "Get Computed Label" endpoint — the accname algorithm's real output, not a re-implementation.
94
+ * Only meaningful while the handle is exposed: at rest it is aria-hidden, so it is outside the
95
+ * accessibility tree and has no computed name by design.
96
+ */
97
+ static getResizerComputedName = async (resizer) => resizer.getComputedLabel();
98
+
63
99
  // Snapshots
64
100
  static snapshotPath(example = 'basic') {
65
101
  return PageObject.getSnapshotPathBuilder('DataTable', example, 'ds-data-table');
@@ -0,0 +1,51 @@
1
+ import { Key } from 'webdriverio';
2
+ import DSDataTableCO from '../DSDataTableCO';
3
+ import { RowCO } from '../components';
4
+
5
+ // Tests for the fix introduced in PUI-8826. Holding ArrowDown during a keyboard row drag fired
6
+ // dnd-kit's default smooth scroll on every key-repeat keydown, re-targeting the in-flight scroll
7
+ // animation before it settled — this read as the dragged row "flickering". The fix pins the
8
+ // KeyboardSensor to scrollBehavior: 'auto', so repeated keydowns produce instant jumps instead.
9
+ const REPEATED_PRESSES = 15;
10
+
11
+ if (
12
+ (!browser.capabilities['ice:options'].isPhone &&
13
+ !browser.capabilities['ice:options'].isTablet &&
14
+ browser.capabilities.browserName === 'chrome') ||
15
+ browser.capabilities.browserName === 'Chrome'
16
+ ) {
17
+ describe('PUI-18883 - DSDataTable:: keyboard row drag scroll on held ArrowDown - Func', () => {
18
+ before('loading page', async () => {
19
+ const errorOnGo = await DSDataTableCO.keyboardDragScroll.go();
20
+ if (errorOnGo) throw errorOnGo;
21
+ await DSDataTableCO.waitForDataTable();
22
+ await DSDataTableCO.installScrollSpy();
23
+ });
24
+ it('01: the drag survives a burst of ArrowDown presses', async () => {
25
+ const dragHandle = await RowCO.getRowDragHlandlerByIndex(0);
26
+ await dragHandle.click();
27
+ await browser.keys(Key.Space);
28
+ await expect(dragHandle).toHaveAttribute('aria-pressed', 'true');
29
+
30
+ await DSDataTableCO.pressArrow('down', REPEATED_PRESSES);
31
+ // Still picked up and still holding focus — the repeat burst neither dropped the row nor
32
+ // stole focus mid-scroll.
33
+ await expect(dragHandle).toHaveAttribute('aria-pressed', 'true');
34
+ await expect(dragHandle).toBeFocused();
35
+ });
36
+ it('02: the burst scrolled the viewport and never used behavior "smooth"', async () => {
37
+ // Sanity first: a 200px viewport over 40 rows means the drag must have scrolled. Without
38
+ // this the behavior assertion below could pass without exercising the fix at all.
39
+ const scrollTop = await DSDataTableCO.getScrollableContainerScrollTop();
40
+ await expect(scrollTop).toBeGreaterThan(0);
41
+
42
+ const scrollCalls = await DSDataTableCO.getScrollSpyCalls();
43
+ await expect(scrollCalls.length).toBeGreaterThan(0);
44
+ await expect(scrollCalls.every((call) => call.behavior === 'auto')).toBe(true);
45
+ });
46
+ it('03: dropping with Space reorders the list and keeps the dragged row focused', async () => {
47
+ await browser.keys(Key.Space);
48
+ await expect(await DSDataTableCO.getFocusedRowIdCellText()).toBe('1');
49
+ });
50
+ });
51
+ }