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,118 @@
1
+ import { Key } from 'webdriverio';
2
+ import GlobalHeaderCO from '../GlobalHeaderCO';
3
+ import { type } from '../../helpers';
4
+
5
+ // Tests for the ds-search-toggle changes in PUI-18647:
6
+ //
7
+ // - (NEW) item-level attributes now land on the item's ROOT CONTAINER, not on the trigger button as
8
+ // with the sibling item types. The type declared that surface on its configuration type and
9
+ // forwarded none of it, so data-public on a search-toggle entry appeared nowhere.
10
+ // - (RENAMED) that container's data-testid moved from `ds-global-header-menubar-item-searchtoggle-
11
+ // container` to `ds-globalheader-menubar-item-searchtoggle-container`. The element itself is
12
+ // unchanged; commit 295f110651c dropped its legacy override in constants/index.ts, so the
13
+ // auto-generated post-convention value now wins. Asserted as the DOM currently renders it — if
14
+ // the legacy override is restored, this expectation flips back to the hyphenated spelling.
15
+ // - (BREAKING) the two spinbutton result-navigation identifiers were INVERTED: the control that
16
+ // triggered NEXT was slotted as PREVIOUS and vice versa. The accessible names were always right,
17
+ // so testid and accessible name now agree. This is the one breaking change for QA here.
18
+ // - (FIX) Escape was handled twice — on the input and again on the container it bubbles to — so one
19
+ // press collapsed twice and called onClear three times. It now fires once.
20
+ //
21
+ // Chrome only: attribute assertions plus click-to-state-change, both engine-independent. The
22
+ // `|| 'Chrome'` arm is mandatory (BrowserStack capitalises browserName; a lowercase-only guard
23
+ // registers zero tests and still exits 0).
24
+ if (
25
+ (!browser.capabilities['ice:options'].isPhone &&
26
+ !browser.capabilities['ice:options'].isTablet &&
27
+ browser.capabilities.browserName === 'chrome') ||
28
+ browser.capabilities.browserName === 'Chrome'
29
+ ) {
30
+ describe('PUI-19019 - GlobalHeader:: search-toggle item slots and result controls - Func', () => {
31
+ before('loading page', async () => {
32
+ const errorOnGo = await GlobalHeaderCO.searchToggleSlotsURL.go();
33
+ if (errorOnGo) throw errorOnGo;
34
+ });
35
+
36
+ it('01: should forward item-level attributes to the new item container while collapsed', async () => {
37
+ const container = await GlobalHeaderCO.getSearchToggleContainer();
38
+ await container.waitForDisplayed();
39
+ await expect(container).toHaveAttribute('data-dimsum-slot', 'dsGlobalheaderMenubarItemSearchtoggleContainer');
40
+
41
+ const publicTestIds = await GlobalHeaderCO.getPublicNodeTestIds();
42
+ await expect(publicTestIds).toEqual(['ds-globalheader-menubar-item-searchtoggle-container', 'gh-toolbar-item']);
43
+
44
+ const dsTypedFlag = await GlobalHeaderCO.getDsTypedItemExistFlag();
45
+ await expect(dsTypedFlag).toHaveText('No');
46
+ });
47
+
48
+ it('02: should expose the full search-toggle slot surface once expanded', async () => {
49
+ await (await GlobalHeaderCO.getGHToolbarItem(0)).click();
50
+ await (await GlobalHeaderCO.getSearchToggleInput()).waitForDisplayed();
51
+
52
+ const publicTestIds = await GlobalHeaderCO.getPublicNodeTestIds();
53
+ await expect(publicTestIds).toEqual([
54
+ 'ds-globalheader-menubar-item-searchtoggle-container',
55
+ 'gh-toolbar-item',
56
+ 'ds-globalheader-searchtoggle-expanded-content-wrapper',
57
+ 'ds-globalheader-searchtoggle-textinput',
58
+ 'ds-globalheader-searchtoggle-spinbutton-wrapper',
59
+ 'ds-globalheader-searchtoggle-spinbutton-text',
60
+ 'ds-globalheader-searchtoggle-spinbutton-separator',
61
+ 'ds-globalheader-searchtoggle-spinbutton-next',
62
+ 'ds-globalheader-searchtoggle-spinbutton-prev',
63
+ ]);
64
+ });
65
+
66
+ it('03: should match each spinbutton data-testid to its accessible name', async () => {
67
+ // The un-inversion. Note the DOM order is next-then-prev, which is what made the original
68
+ // swap easy to miss — so identity is read off the accessible name, never off position.
69
+ await expect(await GlobalHeaderCO.getSearchTogglePrevButton()).toHaveAttribute(
70
+ 'aria-label',
71
+ 'Previous search result',
72
+ );
73
+ await expect(await GlobalHeaderCO.getSearchToggleNextButton()).toHaveAttribute(
74
+ 'aria-label',
75
+ 'Next search result',
76
+ );
77
+ });
78
+
79
+ it('04: should navigate results forward with next and backward with prev', async () => {
80
+ const input = await GlobalHeaderCO.getSearchToggleInput();
81
+ await input.click();
82
+ await type('L');
83
+
84
+ const spinbuttonText = await GlobalHeaderCO.getSearchToggleSpinbutton();
85
+ await browser.waitUntil(async () => (await spinbuttonText.getText()) === '4', {
86
+ timeout: 3000,
87
+ timeoutMsg: 'search results did not populate after typing',
88
+ });
89
+
90
+ // Four rows match "L"; the first hit is row 0 and the last is row 4.
91
+ await (await GlobalHeaderCO.getSearchToggleNextButton()).click();
92
+ await expect(spinbuttonText).toHaveText('1 / 4');
93
+ const firstMatch = await GlobalHeaderCO.getSearchableRowByIndex(0);
94
+ await expect(await GlobalHeaderCO.isRowHighlighted(firstMatch)).toBe(true);
95
+
96
+ // Prev from the first result wraps to the last, proving the control moves backward.
97
+ await (await GlobalHeaderCO.getSearchTogglePrevButton()).click();
98
+ await expect(spinbuttonText).toHaveText('4 / 4');
99
+ const lastMatch = await GlobalHeaderCO.getSearchableRowByIndex(4);
100
+ await expect(await GlobalHeaderCO.isRowHighlighted(lastMatch)).toBe(true);
101
+ });
102
+
103
+ it('05: should collapse, clear and return focus on a single Escape', async () => {
104
+ await (await GlobalHeaderCO.getSearchToggleInput()).click();
105
+ await browser.keys(Key.Escape);
106
+
107
+ await expect(await GlobalHeaderCO.getSearchToggleInput()).not.toBeDisplayed();
108
+ await expect(await GlobalHeaderCO.getGHToolbarItem(0)).toBeFocused();
109
+
110
+ // Collapsing clears the query, so the highlight is gone and the reachable surface is back to
111
+ // the two collapsed-state nodes.
112
+ const lastMatch = await GlobalHeaderCO.getSearchableRowByIndex(4);
113
+ await expect(await GlobalHeaderCO.isRowHighlighted(lastMatch)).toBe(false);
114
+ const publicTestIds = await GlobalHeaderCO.getPublicNodeTestIds();
115
+ await expect(publicTestIds).toEqual(['ds-globalheader-menubar-item-searchtoggle-container', 'gh-toolbar-item']);
116
+ });
117
+ });
118
+ }
@@ -0,0 +1,53 @@
1
+ import GlobalHeaderCO from '../GlobalHeaderCO';
2
+
3
+ // Tests for the contract formalised in PUI-18647: item-level global attributes are forwarded to
4
+ // whatever an out-of-the-box toolbar item renders as its root. The typeless (icon button) item
5
+ // already behaved this way before the refactor — this pins the baseline so the widened contract
6
+ // cannot quietly move it.
7
+ //
8
+ // Also guards the `type` discriminator: it routes the item internally and must never reach the DOM,
9
+ // because `type` is a reserved HTML attribute.
10
+ //
11
+ // Chrome only: every assertion is a DOM attribute or a rendered text value, identical in every
12
+ // engine. The `|| 'Chrome'` arm is mandatory — BrowserStack capitalises browserName, and a
13
+ // lowercase-only guard registers zero tests while still exiting 0.
14
+ if (
15
+ (!browser.capabilities['ice:options'].isPhone &&
16
+ !browser.capabilities['ice:options'].isTablet &&
17
+ browser.capabilities.browserName === 'chrome') ||
18
+ browser.capabilities.browserName === 'Chrome'
19
+ ) {
20
+ describe('PUI-19016 - GlobalHeader:: typeless toolbar item attributes and onClick - Func', () => {
21
+ before('loading page', async () => {
22
+ const errorOnGo = await GlobalHeaderCO.iconButtonItemURL.go();
23
+ if (errorOnGo) throw errorOnGo;
24
+ });
25
+
26
+ it('01: should forward item-level attributes only to the rendered button', async () => {
27
+ const button = await GlobalHeaderCO.getGHToolbarItem(0);
28
+ await button.waitForDisplayed();
29
+
30
+ // The story wires data-public at item level only, so the button is the single element that may
31
+ // carry it. Asserting the whole collection rather than just the button is what catches the
32
+ // attribute leaking onto an ancestor.
33
+ const publicTestIds = await GlobalHeaderCO.getPublicNodeTestIds();
34
+ await expect(publicTestIds).toEqual(['gh-toolbar-item']);
35
+
36
+ await expect(button).toHaveAttribute('data-dimsum-slot', 'dsGlobalheaderMenubarItemButton');
37
+ // The button's own type, not the toolbar item's routing discriminator.
38
+ await expect(button).toHaveAttribute('type', 'button');
39
+
40
+ const dsTypedFlag = await GlobalHeaderCO.getDsTypedItemExistFlag();
41
+ await expect(dsTypedFlag).toHaveText('No');
42
+ });
43
+
44
+ it('02: should forward the item-level onClick handler to the rendered button', async () => {
45
+ const clickCount = await GlobalHeaderCO.getClickCount();
46
+ await expect(clickCount).toHaveText('0');
47
+
48
+ await (await GlobalHeaderCO.getGHToolbarItem(0)).click();
49
+
50
+ await expect(clickCount).toHaveText('1');
51
+ });
52
+ });
53
+ }
@@ -43,6 +43,8 @@ export default class DSGridCO extends PageObject {
43
43
 
44
44
  static breakpointsV2 = new Urlbuilder(PATH_E2E_GRID, 'with-breakpoints-v-2-test');
45
45
 
46
+ static layoutMode = new Urlbuilder(PATH_E2E_GRID, 'with-layout-mode-test');
47
+
46
48
  static getUrl(component = 'basic') {
47
49
  return PageObject.getUrl(PATH_E2E_GRID, component);
48
50
  }
@@ -70,6 +72,24 @@ export default class DSGridCO extends PageObject {
70
72
  return $(`//div[text()="Scrollable Body"]`);
71
73
  }
72
74
 
75
+ static async getGridByTestId(testId) {
76
+ return $(`[data-testid="${testId}"]`);
77
+ }
78
+
79
+ // Computed grid-template-columns, e.g. "640px 640px 640px". Returned as a string so callers can
80
+ // compare two grids to each other without depending on the resolved px values.
81
+ static async getResolvedColumns(testId) {
82
+ const grid = await this.getGridByTestId(testId);
83
+ await grid.waitForDisplayed();
84
+ return String((await grid.getCSSProperty('grid-template-columns')).value);
85
+ }
86
+
87
+ // Number of resolved column tracks. This is the only cross-browser-stable signal of which
88
+ // breakpoint definition won, and it never asserts px values.
89
+ static async getResolvedColumnCount(testId) {
90
+ return (await this.getResolvedColumns(testId)).trim().split(/\s+/).filter(Boolean).length;
91
+ }
92
+
73
93
  // Snapshots
74
94
  static snapshotPath(example = 'basic') {
75
95
  return PageObject.getSnapshotPathBuilder('Grid', example);
@@ -0,0 +1,51 @@
1
+ import DSGridCO from '../DSGridCO';
2
+
3
+ // Coverage for the withLayoutMode opt-in shipped in PUI-17417: an opted-in Grid collapses its
4
+ // responsive cols/rows/span OBJECT definitions to the single value selected by the ancestor
5
+ // DSLayoutProvider layoutMode instead of the viewport media-query ladder. The feature has no DOM
6
+ // footprint - the only observable effect is the emitted CSS, since the collapsed array takes the
7
+ // Array.isArray branch of manageCols and emits ONE unconditional grid-template-columns. So we
8
+ // assert the resolved column COUNT (whitespace separated tracks of the computed value), never the
9
+ // px values. Chrome only: a computed CSS read is identical across engines.
10
+ if (
11
+ (!browser.capabilities['ice:options'].isPhone &&
12
+ !browser.capabilities['ice:options'].isTablet &&
13
+ browser.capabilities.browserName === 'chrome') ||
14
+ browser.capabilities.browserName === 'Chrome'
15
+ ) {
16
+ describe('PUI-18978 - DSGrid:: withLayoutMode breakpoint resolution - Func', () => {
17
+ before('loading page', async () => {
18
+ const errorOnGo = await DSGridCO.layoutMode.go();
19
+ if (errorOnGo) throw errorOnGo;
20
+ });
21
+
22
+ it('01: should resolve cols from the ancestor layoutMode when opted in', async () => {
23
+ await expect(await DSGridCO.getResolvedColumnCount('ds-grid-layout-mode-l')).toEqual(3);
24
+ await expect(await DSGridCO.getResolvedColumnCount('ds-grid-layout-mode-m')).toEqual(2);
25
+ await expect(await DSGridCO.getResolvedColumnCount('ds-grid-layout-mode-s')).toEqual(1);
26
+ });
27
+
28
+ it('02: should honor an explicit xsmall definition, keeping xs distinct from s', async () => {
29
+ await expect(await DSGridCO.getResolvedColumnCount('ds-grid-layout-mode-xs-explicit')).toEqual(1);
30
+ await expect(await DSGridCO.getResolvedColumnCount('ds-grid-layout-mode-s-explicit')).toEqual(2);
31
+ });
32
+
33
+ it('03: should resolve xs to the small definition when xsmall is not declared', async () => {
34
+ await expect(await DSGridCO.getResolvedColumnCount('ds-grid-layout-mode-xs-backfilled')).toEqual(1);
35
+ });
36
+
37
+ it('04: should ignore the ancestor layoutMode when not opted in', async () => {
38
+ // Width independent invariant: opting out inside a provider must render exactly what the same
39
+ // grid renders with no provider at all. The layoutMode path can never satisfy this.
40
+ const optedOut = await DSGridCO.getResolvedColumns('ds-grid-opt-out-in-provider');
41
+ const noProvider = await DSGridCO.getResolvedColumns('ds-grid-opt-out-no-provider');
42
+ await expect(optedOut).toEqual(noProvider);
43
+
44
+ // The failure mode being guarded against is the provider mode s leaking in, which is exactly
45
+ // 1 column. The correct value is whatever the viewport resolves to (3 above 1024px), so we
46
+ // assert more than one column rather than pinning a viewport width.
47
+ const columnCount = await DSGridCO.getResolvedColumnCount('ds-grid-opt-out-in-provider');
48
+ await expect(columnCount).toBeGreaterThan(1);
49
+ });
50
+ });
51
+ }
@@ -0,0 +1,22 @@
1
+ import DSGridCO from '../DSGridCO';
2
+
3
+ // Coverage for the withLayoutMode opt-in shipped in PUI-17417. Every grid in the story shares one
4
+ // responsive cols definition and one viewport width, so this single snapshot is the human readable
5
+ // proof that each grid lays out for the DSLayoutProvider mode of the container it lives in - and
6
+ // that the two opted-out grids stay viewport driven.
7
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
8
+ describe('PUI-18979 - DSGrid:: withLayoutMode breakpoint resolution - Visual', () => {
9
+ before('loading page', async () => {
10
+ const errorOnGo = await DSGridCO.layoutMode.go();
11
+ if (errorOnGo) throw errorOnGo;
12
+ });
13
+
14
+ it('01: should display each grid laid out for its own LayoutProvider mode', async () => {
15
+ const firstGrid = await DSGridCO.getGridByTestId('ds-grid-layout-mode-l');
16
+ await firstGrid.waitForDisplayed();
17
+
18
+ const snapshot = await browser.percyCheckScreenshot(DSGridCO.snapshotPath('layout-mode'));
19
+ await expect(snapshot).toEqual(0);
20
+ });
21
+ });
22
+ }
@@ -7,6 +7,7 @@ describe('PUI-11669 - UseFontSizeMedia:: Basic ', () => {
7
7
  if (errorOnGo) throw errorOnGo;
8
8
  });
9
9
  it('01: should render correctly initial font size values (4 columns)', async () => {
10
+ await DSHookCO.waitForColumnCount(4);
10
11
  const snapshot = await browser.checkSnapshot(DSHookCO.snapshotPath('use-font-size-media-initial-values'));
11
12
  await expect(snapshot).toEqual(0);
12
13
  });
@@ -15,12 +16,14 @@ describe('PUI-11669 - UseFontSizeMedia:: Basic ', () => {
15
16
  !browser.capabilities?.['bstack:options']?.deviceName?.includes('iPad')
16
17
  ) {
17
18
  it('02: should increase font size correctly (1 column)', async () => {
18
- await DSHookCO.increaseFontSize(10);
19
+ await DSHookCO.setFontSizeForRatio(DSHookCO.FONT_SIZE_RATIOS.large);
20
+ await DSHookCO.waitForColumnCount(1);
19
21
  const snapshot = await browser.checkSnapshot(DSHookCO.snapshotPath('use-font-size-media-increase-size'));
20
22
  await expect(snapshot).toEqual(0);
21
23
  });
22
24
  it('03: should decrease font size correctly (2 columns)', async () => {
23
- await DSHookCO.decreaseFontSize(2);
25
+ await DSHookCO.setFontSizeForRatio(DSHookCO.FONT_SIZE_RATIOS.medium);
26
+ await DSHookCO.waitForColumnCount(2);
24
27
  const snapshot = await browser.checkSnapshot(DSHookCO.snapshotPath('use-font-size-media-decrease-size'));
25
28
  await expect(snapshot).toEqual(0);
26
29
  });
@@ -107,8 +107,9 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
107
107
  const drillFirstItemBtn = await DSHookCO.getDrillThisBtnByIndex(0);
108
108
  await drillFirstItemBtn.click();
109
109
  const drillFirstChildBtn = await DSHookCO.getDrillThisBtnByIndex(0);
110
- const isDisabled = await drillFirstChildBtn.getAttribute('aria-disabled');
111
- await expect(isDisabled).toBe('true');
110
+ // Since PUI-17909 DSButtonV2 renders the native `disabled` attribute and intentionally omits
111
+ // aria-disabled (that is reserved for applyAriaDisabled/readOnly), so assert the native disabled state.
112
+ await expect(drillFirstChildBtn).toBeDisabled();
112
113
  });
113
114
  });
114
115
  }
@@ -1,20 +1,21 @@
1
1
  /* eslint-disable import/no-relative-packages */
2
- import {
3
- PATH_HOOKS,
4
- PATH_HOOKS_BLUR_OUT,
5
- PATH_HOOKS_FIRST_FOCUS_IN,
6
- PATH_E2E_HOOKS,
7
- PATH_E2E_USE_FONT_SIZE_DETECTOR,
8
- PATH_E2E_USE_FONT_SIZE_MEDIA,
9
- } from '../paths';
10
- import { PageObject, Urlbuilder, getElementByIndex } from '../helpers';
2
+ import { PATH_HOOKS, PATH_E2E_HOOKS, PATH_E2E_USE_FONT_SIZE_DETECTOR, PATH_E2E_USE_FONT_SIZE_MEDIA } from '../paths';
3
+ import { PageObject, Urlbuilder, getElementByIndex, setTextSize } from '../helpers';
4
+
5
+ // useFontSizeDetector reduces the page to a single number:
6
+ // ratio = floor(documentElement.clientWidth / heightOf(#DS_FONT_DETECTOR))
7
+ // and useFontsizeMedia buckets it against BREAKPOINTS (ds-hooks-fontsize-detector):
8
+ // ratio <= 30 -> largeFont | 31..40 -> mediumFont | > 40 -> smallFont
9
+ // The ratio depends on the viewport width, which BrowserStack decides per platform,
10
+ // so a hardcoded font size lands in a different bucket on every browser. Aim at the
11
+ // middle of each bucket instead and let setFontSizeForRatio solve for the px.
12
+ const FONT_DETECTOR_SELECTOR = '[data-testid="DS_FONT_DETECTOR"]';
13
+ const FONT_SIZE_RATIOS = { large: 25, medium: 35, small: 50 };
11
14
 
12
15
  export default class DSHookCO extends PageObject {
13
- // Desktop
14
- static blurOut = new Urlbuilder(PATH_HOOKS_BLUR_OUT, 'basic');
15
-
16
- static firstFocusIn = new Urlbuilder(PATH_HOOKS_FIRST_FOCUS_IN, 'basic');
16
+ static FONT_SIZE_RATIOS = FONT_SIZE_RATIOS;
17
17
 
18
+ // Desktop
18
19
  static specificFocus = new Urlbuilder(PATH_HOOKS, 'use-on-specific-focus');
19
20
 
20
21
  static useDsTree = new Urlbuilder(PATH_E2E_HOOKS, 'use-ds-tree-test');
@@ -33,16 +34,6 @@ export default class DSHookCO extends PageObject {
33
34
 
34
35
  static getBtnByIndex = async (index) => getElementByIndex(this.getBtns, index);
35
36
 
36
- static async getH3s() {
37
- return $$('div h3');
38
- }
39
-
40
- // mostly used
41
- static getInfo = async () => getElementByIndex(this.getH3s, 3);
42
-
43
- // used for first focus in story
44
- static getInfo2 = async () => getElementByIndex(this.getH3s, 4);
45
-
46
37
  // Snapshots
47
38
  static snapshotPath(example = 'basic') {
48
39
  return PageObject.getSnapshotPathBuilder('Hook', example);
@@ -194,5 +185,47 @@ export default class DSHookCO extends PageObject {
194
185
  }
195
186
  }
196
187
 
188
+ // Solve for the root font size that puts the detector ratio at targetRatio, then
189
+ // apply it with setTextSize. The line-height factor is measured live instead of
190
+ // assumed: #DS_FONT_DETECTOR is a `<p>&nbsp;</p>` appended to body, so its height
191
+ // tracks the root font size by a constant that depends on the stylesheet.
192
+ static async setFontSizeForRatio(targetRatio) {
193
+ const fontSize = await browser.execute(
194
+ (ratio, detectorSelector) => {
195
+ const root = document.documentElement;
196
+ const detector = document.querySelector(detectorSelector);
197
+ if (!detector) return null;
198
+ const rootFontSize = parseFloat(window.getComputedStyle(root).fontSize);
199
+ const lineHeightFactor = detector.getBoundingClientRect().height / rootFontSize;
200
+ return Math.floor(root.clientWidth / (ratio * lineHeightFactor));
201
+ },
202
+ targetRatio,
203
+ FONT_DETECTOR_SELECTOR,
204
+ );
205
+ if (!fontSize) throw new Error(`${FONT_DETECTOR_SELECTOR} not found: useFontSizeDetector never mounted`);
206
+ await setTextSize(fontSize);
207
+ return fontSize;
208
+ }
209
+
197
210
  // utils
211
+
212
+ static async getResponsiveGrid() {
213
+ return $('[data-testid="fontsize-media-responsive-grid"]');
214
+ }
215
+
216
+ static async getColumnCount() {
217
+ const grid = await this.getResponsiveGrid();
218
+ const { value } = await grid.getCSSProperty('grid-template-columns');
219
+ return String(value).trim().split(/\s+/).filter(Boolean).length;
220
+ }
221
+
222
+ // The ResizeObserver behind useFontSizeDetector reports the new detector height a
223
+ // frame after the font size lands, so the grid reflows after setTextSize returns.
224
+ // Wait for the reflow instead of snapshotting a half-applied layout.
225
+ static async waitForColumnCount(expected) {
226
+ await browser.waitUntil(async () => (await this.getColumnCount()) === expected, {
227
+ timeout: 10000,
228
+ timeoutMsg: `expected the responsive grid to reflow to ${expected} column(s)`,
229
+ });
230
+ }
198
231
  }
@@ -0,0 +1,83 @@
1
+ /* eslint-disable max-len */
2
+ import { Key } from 'webdriverio';
3
+ import useFocusStackCO from './useFocusStackCO';
4
+ import { tabStops } from '../../helpers';
5
+ import DSPillsV2CO from '../../ds-pills-v2/DSPillsV2CO';
6
+ import DSButtonV3CO from '../../ds-button-v3/DSButtonV3CO';
7
+
8
+ if (
9
+ (!browser.capabilities['ice:options'].isPhone &&
10
+ !browser.capabilities['ice:options'].isTablet &&
11
+ browser.capabilities.browserName === 'chrome') ||
12
+ browser.capabilities.browserName === 'Chrome'
13
+ ) {
14
+ describe('PUI-13147: UseFocusStack for focus return -Func', () => {
15
+ before(async () => {
16
+ const errorOnGo = await useFocusStackCO.basicURL.go();
17
+ if (errorOnGo) throw errorOnGo;
18
+ });
19
+
20
+ it('01: should Tab x4 and have D focused', async () => {
21
+ await tabStops(4);
22
+ const typographys = (await useFocusStackCO.getTypographys()).length;
23
+ const pillD = await DSPillsV2CO.getCloseButtonByIndex(3);
24
+ // stack holds the three departed elements [C, B, A] -> 1 (h3) + 3
25
+ await expect(typographys).toEqual(4);
26
+ await expect(pillD).toBeFocused();
27
+ });
28
+
29
+ it('02: PUI-13301 - should click non-focused C, remove it, and keep focus on D (not B)', async () => {
30
+ // D is focused; click C (index 2) to remove it. Focus must return to D, the pre-click element.
31
+ const pillC = await DSPillsV2CO.getCloseButtonByIndex(2);
32
+ await pillC.click();
33
+ // C is gone, so the remaining pills are A, B, D, E, F, G -> D is now at index 2.
34
+ const pillD = await DSPillsV2CO.getCloseButtonByIndex(2);
35
+ const typographys = (await useFocusStackCO.getTypographys()).length;
36
+ // removed C does not linger; the stack reads [B, A] -> 1 (h3) + 2
37
+ await expect(typographys).toEqual(3);
38
+ await expect(pillD).toBeFocused();
39
+ });
40
+
41
+ it('03: should Tab forward to E, remove it, and return focus to D', async () => {
42
+ await tabStops(1);
43
+ const pillE = await DSPillsV2CO.getCloseButtonByIndex(3);
44
+ await expect(pillE).toBeFocused();
45
+ // remove the focused pill with the keyboard
46
+ await browser.keys(Key.Return);
47
+ // E removed, remaining pills are A, B, D, F, G -> D is at index 2
48
+ const pillD = await DSPillsV2CO.getCloseButtonByIndex(2);
49
+ const typographys = (await useFocusStackCO.getTypographys()).length;
50
+ await expect(typographys).toEqual(3);
51
+ await expect(pillD).toBeFocused();
52
+ });
53
+
54
+ it('04: should delete back through the stack until focus falls back to Reset', async () => {
55
+ // remove D (focused) -> B, remove B -> A, remove A -> no survivor left -> fallBackRef (Reset)
56
+ await browser.keys(Key.Return);
57
+ await browser.keys(Key.Return);
58
+ await browser.keys(Key.Return);
59
+ const reset = await DSButtonV3CO.getButtonByIndex(0);
60
+ const typographys = (await useFocusStackCO.getTypographys()).length;
61
+ // stack emptied -> only the h3 remains
62
+ await expect(typographys).toEqual(1);
63
+ await expect(reset).toBeFocused();
64
+ });
65
+
66
+ it('05: should click Reset and restore all removable pills', async () => {
67
+ await browser.keys(Key.Return);
68
+ const closeButtons = await DSPillsV2CO.getCloseButtons();
69
+ const typographys = (await useFocusStackCO.getTypographys()).length;
70
+ await expect(closeButtons).toHaveLength(7);
71
+ await expect(typographys).toEqual(1);
72
+ });
73
+ it('06: should mouse-remove E with an empty stack and fall back focus to Reset', async () => {
74
+ const pillE = await DSPillsV2CO.getCloseButtonByIndex(4);
75
+ await pillE.click();
76
+ const reset = await DSButtonV3CO.getButtonByIndex(0);
77
+ await expect(reset).toBeFocused();
78
+ // E is hidden, so 6 removable pills remain.
79
+ const closeButtons = await DSPillsV2CO.getCloseButtons();
80
+ await expect(closeButtons).toHaveLength(6);
81
+ });
82
+ });
83
+ }
@@ -5,4 +5,6 @@ import { PageObject, Urlbuilder } from '../../helpers';
5
5
  export default class UseFocusTrapCO extends PageObject {
6
6
  // Desktop
7
7
  static basicTest = new Urlbuilder(PATH_E2E_USE_FOCUS_TRAP, 'basic-test');
8
+
9
+ static toggleTest = new Urlbuilder(PATH_E2E_USE_FOCUS_TRAP, 'toggle-test');
8
10
  }
@@ -0,0 +1,48 @@
1
+ import { Key } from 'webdriverio';
2
+ import UseFocusTrapCO from './UseFocusTrapCO';
3
+ import DSButtonV3CO from '../../ds-button-v3/DSButtonV3CO';
4
+ import DSToggleCO from '../../ds-form-toggle/DSToggleCO';
5
+
6
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
7
+ describe('PUI-18855 - useFocusTrap:: toggle as firstElementRef cycles focus - Func', () => {
8
+ before(async () => {
9
+ const errorOnGo = await UseFocusTrapCO.toggleTest.go();
10
+ if (errorOnGo) throw errorOnGo;
11
+ });
12
+
13
+ it('01: should focus the toggle switch on the first tab', async () => {
14
+ await browser.keys(Key.Tab);
15
+ const toggle = await DSToggleCO.getToggleFocuseable();
16
+ await expect(toggle).toBeFocused();
17
+ });
18
+
19
+ it('02: should tab down to the last element of the trap', async () => {
20
+ await browser.keys(Key.Tab);
21
+ await browser.keys(Key.Tab);
22
+ await browser.keys(Key.Tab);
23
+ const lastElement = await DSButtonV3CO.getButtonByIndex(2);
24
+ await expect(lastElement).toBeFocused();
25
+ });
26
+
27
+ it('03: should tab on the last element and cycle back to the toggle', async () => {
28
+ await browser.keys(Key.Tab);
29
+ const toggle = await DSToggleCO.getToggleFocuseable();
30
+ await expect(toggle).toBeFocused();
31
+ });
32
+
33
+ it('04: should shift+tab on the toggle and cycle back to the last element', async () => {
34
+ await browser.keys([Key.Shift, Key.Tab]);
35
+ const lastElement = await DSButtonV3CO.getButtonByIndex(2);
36
+ await expect(lastElement).toBeFocused();
37
+ });
38
+
39
+ it('05: should keep the focus trapped over a second full cycle', async () => {
40
+ await browser.keys(Key.Tab);
41
+ await browser.keys(Key.Tab);
42
+ await browser.keys(Key.Tab);
43
+ await browser.keys(Key.Tab);
44
+ const lastElement = await DSButtonV3CO.getButtonByIndex(2);
45
+ await expect(lastElement).toBeFocused();
46
+ });
47
+ });
48
+ }
@@ -0,0 +1,48 @@
1
+ import UseMaskCO from '../useMaskCO';
2
+ import { axeCoreCheck } from '../../../helpers';
3
+
4
+ if (
5
+ (!browser.capabilities['ice:options'].isPhone &&
6
+ !browser.capabilities['ice:options'].isTablet &&
7
+ browser.capabilities.browserName === 'chrome') ||
8
+ browser.capabilities.browserName === 'Chrome'
9
+ ) {
10
+ // Accessibility coverage for the numeric mask stories, added alongside PUI-15648
11
+ // (critical mask information moved out of the placeholder and into the feedback
12
+ // message). The package had no axe-core coverage at all before these describes.
13
+ describe('PUI-18850 - useNumberMask:: Number - AxeCore Test', () => {
14
+ before(async () => {
15
+ const errorOnGo = await UseMaskCO.numberURL.go();
16
+ if (errorOnGo) throw errorOnGo;
17
+ });
18
+
19
+ it('01: should have no accessibility violations', async () => {
20
+ const result = await axeCoreCheck();
21
+ expect(result.length).toBe(0);
22
+ });
23
+ });
24
+
25
+ describe('PUI-18851 - useNumberMask:: Currency - AxeCore Test', () => {
26
+ before(async () => {
27
+ const errorOnGo = await UseMaskCO.currencyURL.go();
28
+ if (errorOnGo) throw errorOnGo;
29
+ });
30
+
31
+ it('01: should have no accessibility violations', async () => {
32
+ const result = await axeCoreCheck();
33
+ expect(result.length).toBe(0);
34
+ });
35
+ });
36
+
37
+ describe('PUI-18852 - useNumberMask:: Percent - AxeCore Test', () => {
38
+ before(async () => {
39
+ const errorOnGo = await UseMaskCO.percentURL.go();
40
+ if (errorOnGo) throw errorOnGo;
41
+ });
42
+
43
+ it('01: should have no accessibility violations', async () => {
44
+ const result = await axeCoreCheck();
45
+ expect(result.length).toBe(0);
46
+ });
47
+ });
48
+ }
@@ -21,6 +21,8 @@ export default class DSMenuButtonCO extends PageObject {
21
21
 
22
22
  static skeletonMenuItem = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'skeleton-menu-item-test');
23
23
 
24
+ static slotsTest = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'slots-test');
25
+
24
26
  // UseCases (E2E simplified versions)
25
27
  static cardExample = new Urlbuilder(PATH_MENU_BUTTON_USECASES, 'card-example-test');
26
28
 
@@ -85,6 +87,27 @@ export default class DSMenuButtonCO extends PageObject {
85
87
  return $(`${item} div span`);
86
88
  }
87
89
 
90
+ // Slots test selectors (by data-dimsum-slot)
91
+ static async getSlotsOpinionatedButtonRoot() {
92
+ return $('[data-dimsum-parent-slot="dsOpinionatedbuttonRoot"');
93
+ }
94
+
95
+ static async getSlotsFloatingWrapper() {
96
+ return $('[data-dimsum-parent-slot="dsFlyoutmenuFloatingWrapper"');
97
+ }
98
+
99
+ static async getSlotsFlyoutMenuRoot() {
100
+ return $('[data-dimsum-slot="dsFlyoutmenuRoot"]');
101
+ }
102
+
103
+ static async getSlotsListWrapper() {
104
+ return $('[data-dimsum-slot="dsFlyoutmenuListWrapper"]');
105
+ }
106
+
107
+ static async getSlotsMenuItemWrappers(index = 0) {
108
+ return $$('[data-dimsum-slot="dsMenuitemMenuItemWrapper"]')[index];
109
+ }
110
+
88
111
  // Snapshots
89
112
  static snapshotPath(example = 'basic') {
90
113
  return PageObject.getSnapshotPathBuilder('DSMenuItems', example, 'ds-menu-items');