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
@@ -34,8 +34,16 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
34
34
  await openPickerBtn.click();
35
35
  const startDate = await DateRangePickerCO.getRangeStartDay();
36
36
  const endDate = await DateRangePickerCO.getRangeEndDay();
37
- await expect(startDate).toHaveAttribute('aria-label', 'February third 2020, Monday');
38
- await expect(endDate).toHaveAttribute('aria-label', 'February eighth 2020, Saturday');
37
+ // PUI-18279 (a11y): days inside the selected range announce the whole range instead of a
38
+ // bare weekday label, so screen-reader users hear the full selection on every range day.
39
+ await expect(startDate).toHaveAttribute(
40
+ 'aria-label',
41
+ 'February third 2020, range from February third 2020 to February eighth 2020 selected.',
42
+ );
43
+ await expect(endDate).toHaveAttribute(
44
+ 'aria-label',
45
+ 'February eighth 2020, range from February third 2020 to February eighth 2020 selected.',
46
+ );
39
47
  });
40
48
  it('03: should change the text input to the picked date (mouse)', async () => {
41
49
  const exampleDate1 = await DateRangePickerCO.getDayOnCalendarByIndex(16);
@@ -55,24 +63,78 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
55
63
  await expect(endingDay).toHaveValue(expect.stringContaining('09'));
56
64
  await expect(endingYear).toHaveValue(expect.stringContaining('2020'));
57
65
  });
58
- it('04: should change the text input to the picked date (KB)', async () => {
59
- await browser.keys(Key.ArrowDown);
60
- await browser.keys(Key.Return);
66
+ // Keyboard range selection previously lived here as a 4th step, but it re-picked over the range
67
+ // typed in test 01 (a stateful re-pick whose result is hard to reason about). It now has
68
+ // dedicated, deterministic, fresh-state coverage in the PUI-15572 describe below (mouse +
69
+ // keyboard + auto-ordering).
70
+ });
71
+
72
+ // PUI-15572 (WCAG 3.2.2 On Input): completing the range must close the calendar automatically and
73
+ // return focus to the trigger so the user knows the selection succeeded. beforeEach reloads a
74
+ // fresh empty picker so each scenario is independent (the stateful Basic flow above re-picks over
75
+ // an existing range and is intentionally not used to assert closure). The story fixes
76
+ // onCalendarOpenFocusedDay to 12/27/2000, so keyboard navigation lands on deterministic days.
77
+ describe('PUI-18775 - DSControlledDateRangePicker:: calendar closes on completed range -Func', () => {
78
+ beforeEach('loading page', async () => {
79
+ const errorOnGo = await DateRangePickerCO.basic.go();
80
+ if (errorOnGo) throw errorOnGo;
81
+ });
82
+
83
+ it('01: should stay open on start pick, then close and refocus trigger on end pick (mouse)', async () => {
84
+ const openPickerBtn = await DateRangePickerCO.getPickerBtn();
85
+ await openPickerBtn.click();
86
+ const dialog = await DateRangePickerCO.getCalendarDialog();
87
+ await expect(dialog).toBeDisplayedInViewport();
88
+
89
+ // first pick = start date -> range incomplete, calendar must stay open
90
+ await (await DateRangePickerCO.getDayOnCalendarByIndex(16)).click();
91
+ await expect(dialog).toBeDisplayedInViewport();
92
+
93
+ // second pick = end date -> range complete, calendar must close and focus returns to trigger
94
+ await (await DateRangePickerCO.getDayOnCalendarByIndex(20)).click();
95
+ await expect(dialog).not.toBeDisplayedInViewport();
96
+ await expect(openPickerBtn).toBeFocused();
97
+ });
98
+
99
+ it('02: should complete the range via keyboard, closing the calendar and refocusing the trigger', async () => {
100
+ const openPickerBtn = await DateRangePickerCO.getPickerBtn();
101
+ await openPickerBtn.click();
102
+ const dialog = await DateRangePickerCO.getCalendarDialog();
103
+ await expect(dialog).toBeDisplayedInViewport();
104
+
105
+ // focus opens on Dec 27 2000; ArrowRight -> Dec 28, Enter picks the start (range incomplete)
61
106
  await browser.keys(Key.ArrowRight);
107
+ await browser.keys(Key.Enter);
108
+ await expect(dialog).toBeDisplayedInViewport();
109
+
110
+ // ArrowRight x2 -> Dec 30, Enter completes the range -> calendar closes and focus returns
62
111
  await browser.keys(Key.ArrowRight);
63
- await browser.keys(Key.Space);
64
- const startingMonth = await DateRangePickerCO.getMonthInputByIndex(0);
65
- const startingDay = await DateRangePickerCO.getDayInputByIndex(0);
66
- const startingYear = await DateRangePickerCO.getYearInputByIndex(0);
67
- const endingMonth = await DateRangePickerCO.getMonthInputByIndex(1);
68
- const endingDay = await DateRangePickerCO.getDayInputByIndex(1);
69
- const endingYear = await DateRangePickerCO.getYearInputByIndex(1);
70
- await expect(startingMonth).toHaveValue(expect.stringContaining('02'));
71
- await expect(startingDay).toHaveValue(expect.stringContaining('14'));
72
- await expect(startingYear).toHaveValue(expect.stringContaining('2020'));
73
- await expect(endingMonth).toHaveValue(expect.stringContaining('02'));
74
- await expect(endingDay).toHaveValue(expect.stringContaining('16'));
75
- await expect(endingYear).toHaveValue(expect.stringContaining('2020'));
112
+ await browser.keys(Key.ArrowRight);
113
+ await browser.keys(Key.Enter);
114
+ await expect(dialog).not.toBeDisplayedInViewport();
115
+ await expect(openPickerBtn).toBeFocused();
116
+
117
+ await expect(await DateRangePickerCO.getMonthInputByIndex(0)).toHaveValue(expect.stringContaining('12'));
118
+ await expect(await DateRangePickerCO.getDayInputByIndex(0)).toHaveValue(expect.stringContaining('28'));
119
+ await expect(await DateRangePickerCO.getMonthInputByIndex(1)).toHaveValue(expect.stringContaining('12'));
120
+ await expect(await DateRangePickerCO.getDayInputByIndex(1)).toHaveValue(expect.stringContaining('30'));
121
+ });
122
+
123
+ it('03: should auto-order the range when the completing pick precedes the start pick', async () => {
124
+ const openPickerBtn = await DateRangePickerCO.getPickerBtn();
125
+ await openPickerBtn.click();
126
+ const dialog = await DateRangePickerCO.getCalendarDialog();
127
+
128
+ // pick the start (Dec 28), then pick an earlier day (ArrowUp = -1 week -> Dec 21)
129
+ await browser.keys(Key.ArrowRight);
130
+ await browser.keys(Key.Enter);
131
+ await browser.keys(Key.ArrowUp);
132
+ await browser.keys(Key.Enter);
133
+
134
+ // the earlier day becomes the start (from < to) and the range completes -> calendar closes
135
+ await expect(dialog).not.toBeDisplayedInViewport();
136
+ await expect(await DateRangePickerCO.getDayInputByIndex(0)).toHaveValue(expect.stringContaining('21'));
137
+ await expect(await DateRangePickerCO.getDayInputByIndex(1)).toHaveValue(expect.stringContaining('28'));
76
138
  });
77
139
  });
78
140
 
@@ -30,6 +30,8 @@ export default class DateRangePickerCO extends PageObject {
30
30
  'apply-aria-disabled-invalid-selection-test',
31
31
  );
32
32
 
33
+ static pickerCallbacks = new Urlbuilder(PATH_E2E_CONTROLLED_FORM_DATE_RANGE_PICKER, 'picker-callbacks-test');
34
+
33
35
  // Story elements
34
36
 
35
37
  static getNextMonthBtn = async () => $('[data-testid="ds-controlled-date-time-picker-calendar-next-month"]');
@@ -56,11 +58,22 @@ export default class DateRangePickerCO extends PageObject {
56
58
  static getYearInputByIndex = async (index = 0) =>
57
59
  $$('[data-testid="ds-controlled-date-time-picker-year-input"]')[index];
58
60
 
61
+ // Grouped field (DSFormLayoutBlockItem isGroup) a11y wiring
62
+ static getNamedGroupByLabel = async (label) => $$(`[role="group"][aria-label="${label}"]`);
63
+
64
+ static getFieldsetContainer = async () => $('[data-testid="ds-formlayoutblockitem-container"]');
65
+
66
+ static getValidationAlert = async () => $('[data-testid="ds-formlayoutblockitem-error-message"]');
67
+
59
68
  static getClearableBtns = async () => $$(`[data-testid="ds-controlled-date-time-picker-clear-btn"]`);
60
69
 
61
70
  static getClearableByIndex = async (index = 0) =>
62
71
  $$(`[data-testid="ds-controlled-date-time-picker-clear-btn"]`)[index];
63
72
 
73
+ static getOpenCallbackCount = async () => $('[data-testid="picker-open-count"]');
74
+
75
+ static getCloseCallbackCount = async () => $('[data-testid="picker-close-count"]');
76
+
64
77
  // TimeInput
65
78
  static getHourInput = async () => $('[data-testid="ds-controlled-date-time-picker-hour-input"]');
66
79
 
@@ -111,6 +124,12 @@ export default class DateRangePickerCO extends PageObject {
111
124
  return $(`[data-testid="ds-controlled-date-time-picker-calendar-context-content-wrapper"]`);
112
125
  }
113
126
 
127
+ // The open calendar popover is the modal dialog (role="dialog"); it is the same DOM node as
128
+ // the contextual-menu wrapper above, exposed here under an accessibility-semantic name.
129
+ static async getCalendarDialog() {
130
+ return $(`[data-testid="ds-controlled-date-time-picker-calendar-context-content-wrapper"]`);
131
+ }
132
+
114
133
  static async getCalendarHeaderLabel() {
115
134
  return $(`[data-testid="ds-controlled-date-time-picker-calendar-header-label"]`);
116
135
  }
@@ -0,0 +1,66 @@
1
+ import { Key } from 'webdriverio';
2
+ import DateRangePickerCO from '../DateRangePickerCO';
3
+
4
+ // Tests for the fix introduced in PUI-15569 (lack of clear distinction between start and end date
5
+ // fields). Each day/month/year segment now carries a distinguishing name-only aria-label that
6
+ // encodes which date it belongs to ("Start date month" / "End date year" ...) while per-field value
7
+ // still lives on role="spinbutton" + aria-valuetext. This fix (commit d1ded9edc7b) reversed the
8
+ // earlier PUI-15568 name-only labels ("month"/"day"/"year"), which is why the label strings changed.
9
+ // Chrome-only: pure DOM-attribute assertions are identical across browsers.
10
+
11
+ // Asserts a single segment input carries its full distinguishing aria-label, spinbutton role,
12
+ // empty value-text, and none of the leaked phrases the earlier defect used to inject into the label.
13
+ const assertDistinguishingEmptySegment = async (input, label) => {
14
+ await expect(input).toHaveAttribute('aria-label', label);
15
+ await expect(input).toHaveAttribute('role', 'spinbutton');
16
+ await expect(input).toHaveAttribute('aria-valuetext', 'empty');
17
+ const ariaLabel = await input.getAttribute('aria-label');
18
+ expect(ariaLabel).not.toContain('input field');
19
+ expect(ariaLabel).not.toContain('current values');
20
+ };
21
+
22
+ if (
23
+ (!browser.capabilities['ice:options'].isPhone &&
24
+ !browser.capabilities['ice:options'].isTablet &&
25
+ browser.capabilities.browserName === 'chrome') ||
26
+ browser.capabilities.browserName === 'Chrome'
27
+ ) {
28
+ describe('PUI-18653 - DSControlledDateRangePicker:: start and end date segment aria-labels - Func', () => {
29
+ before('loading page', async () => {
30
+ const errorOnGo = await DateRangePickerCO.basic.go();
31
+ if (errorOnGo) throw errorOnGo;
32
+ });
33
+
34
+ // Static reads on the empty initial state — consolidated into one it() (no interaction).
35
+ // index 0 = Start date group, index 1 = End date group.
36
+ it('01: each segment names its own date (start/end) with a spinbutton role and empty value', async () => {
37
+ // Start date group
38
+ await assertDistinguishingEmptySegment(await DateRangePickerCO.getMonthInputByIndex(0), 'Start date month');
39
+ await assertDistinguishingEmptySegment(await DateRangePickerCO.getDayInputByIndex(0), 'Start date day');
40
+ await assertDistinguishingEmptySegment(await DateRangePickerCO.getYearInputByIndex(0), 'Start date year');
41
+ // End date group
42
+ await assertDistinguishingEmptySegment(await DateRangePickerCO.getMonthInputByIndex(1), 'End date month');
43
+ await assertDistinguishingEmptySegment(await DateRangePickerCO.getDayInputByIndex(1), 'End date day');
44
+ await assertDistinguishingEmptySegment(await DateRangePickerCO.getYearInputByIndex(1), 'End date year');
45
+ });
46
+
47
+ it('02: filling one segment does not leak its value into sibling aria-labels', async () => {
48
+ const month = await DateRangePickerCO.getMonthInputByIndex(0);
49
+ await month.click();
50
+ await browser.keys(Key.ArrowUp); // 01 / January
51
+ await browser.keys(Key.ArrowUp); // 02 / February
52
+
53
+ // filled field announces its OWN value via aria-valuetext; label stays the distinguishing name
54
+ await expect(month).toHaveAttribute('aria-label', 'Start date month');
55
+ await expect(month).toHaveAttribute('aria-valuetext', 'February');
56
+
57
+ // siblings keep their distinguishing names + empty value — no "February" leaks into their labels
58
+ const day = await DateRangePickerCO.getDayInputByIndex(0);
59
+ const year = await DateRangePickerCO.getYearInputByIndex(0);
60
+ await expect(day).toHaveAttribute('aria-label', 'Start date day');
61
+ await expect(day).toHaveAttribute('aria-valuetext', 'empty');
62
+ await expect(year).toHaveAttribute('aria-label', 'Start date year');
63
+ await expect(year).toHaveAttribute('aria-valuetext', 'empty');
64
+ });
65
+ });
66
+ }
@@ -0,0 +1,59 @@
1
+ import DateRangePickerCO from '../DateRangePickerCO';
2
+
3
+ // Tests for the fix introduced in PUI-15570 (feedback message announced as part of the group heading
4
+ // and not programmatically associated with any field). When the range picker sits inside a
5
+ // DSFormLayoutBlockItem isGroup fieldset, the fix (commit d1ded9edc7b) removed the nested named
6
+ // role="group" (aria-label="Start date"/"End date") that collided with the fieldset legend, so the
7
+ // legend + validation message now announce correctly. Each field self-identifies via its own
8
+ // aria-label and is marked aria-invalid, telling the user exactly which fields contain errors, while
9
+ // the validation message is announced separately via role="alert".
10
+ // Chrome-only: pure DOM-attribute assertions are identical across browsers.
11
+
12
+ // Asserts a single segment input is marked invalid and keeps its distinguishing name in the error state.
13
+ const assertInvalidNamedSegment = async (input, label) => {
14
+ await expect(input).toHaveAttribute('aria-label', label);
15
+ await expect(input).toHaveAttribute('role', 'spinbutton');
16
+ await expect(input).toHaveAttribute('aria-invalid', 'true');
17
+ };
18
+
19
+ if (
20
+ (!browser.capabilities['ice:options'].isPhone &&
21
+ !browser.capabilities['ice:options'].isTablet &&
22
+ browser.capabilities.browserName === 'chrome') ||
23
+ browser.capabilities.browserName === 'Chrome'
24
+ ) {
25
+ describe('PUI-18711 - DSControlledDateRangePicker:: grouped field error announcement - Func', () => {
26
+ before('loading page', async () => {
27
+ const errorOnGo = await DateRangePickerCO.invalidSelection.go();
28
+ if (errorOnGo) throw errorOnGo;
29
+ });
30
+
31
+ // Static reads on the error-state load — consolidated into one it() (no interaction).
32
+ it('01: drops the nested named group, marks each named field invalid, announces error via alert', async () => {
33
+ // Regression guard for the fix: the nested named role="group" wrappers are gone, so they no
34
+ // longer compete with the DSFormLayoutBlockItem fieldset legend / validation message.
35
+ const startNamedGroups = await DateRangePickerCO.getNamedGroupByLabel('Start date');
36
+ const endNamedGroups = await DateRangePickerCO.getNamedGroupByLabel('End date');
37
+ expect(startNamedGroups.length).toBe(0);
38
+ expect(endNamedGroups.length).toBe(0);
39
+
40
+ // The grouping is still provided by the fieldset container.
41
+ await expect(await DateRangePickerCO.getFieldsetContainer()).toBeExisting();
42
+
43
+ // Each field self-identifies (start/end) and is flagged invalid — tells the user which fields
44
+ // contain errors. index 0 = Start date group, index 1 = End date group.
45
+ await assertInvalidNamedSegment(await DateRangePickerCO.getMonthInputByIndex(0), 'Start date month');
46
+ await assertInvalidNamedSegment(await DateRangePickerCO.getDayInputByIndex(0), 'Start date day');
47
+ await assertInvalidNamedSegment(await DateRangePickerCO.getYearInputByIndex(0), 'Start date year');
48
+ await assertInvalidNamedSegment(await DateRangePickerCO.getMonthInputByIndex(1), 'End date month');
49
+ await assertInvalidNamedSegment(await DateRangePickerCO.getDayInputByIndex(1), 'End date day');
50
+ await assertInvalidNamedSegment(await DateRangePickerCO.getYearInputByIndex(1), 'End date year');
51
+
52
+ // The validation message is a separate element announced on its own via role="alert".
53
+ const alert = await DateRangePickerCO.getValidationAlert();
54
+ await expect(alert).toBeExisting();
55
+ await expect(alert).toHaveAttribute('role', 'alert');
56
+ await expect(alert).toHaveText('The selected range is not valid', { containing: true });
57
+ });
58
+ });
59
+ }
@@ -0,0 +1,36 @@
1
+ import { Key } from 'webdriverio';
2
+ import DateRangePickerCO from '../DateRangePickerCO';
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
+ // Tests for the fix introduced in PUI-18907 (forward picker open and close callbacks).
11
+ describe('PUI-19082 - DSControlledDateRangePicker:: picker open and close callbacks - Func', () => {
12
+ before('loading page', async () => {
13
+ const errorOnGo = await DateRangePickerCO.pickerCallbacks.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ });
16
+
17
+ it('01: should invoke onPickerOpen when the calendar opens', async () => {
18
+ const calendarTrigger = await DateRangePickerCO.getPickerBtn();
19
+ const openCallbackCount = await DateRangePickerCO.getOpenCallbackCount();
20
+
21
+ await expect(openCallbackCount).toHaveText('0');
22
+ await calendarTrigger.click();
23
+ await expect(await DateRangePickerCO.getCalendarDialog()).toBeDisplayedInViewport();
24
+ await expect(openCallbackCount).toHaveText('1');
25
+ });
26
+
27
+ it('02: should invoke onPickerClose when the calendar closes', async () => {
28
+ const closeCallbackCount = await DateRangePickerCO.getCloseCallbackCount();
29
+
30
+ await expect(closeCallbackCount).toHaveText('0');
31
+ await browser.keys(Key.Escape);
32
+ await expect(await DateRangePickerCO.getCalendarDialog()).not.toBeDisplayedInViewport();
33
+ await expect(closeCallbackCount).toHaveText('1');
34
+ });
35
+ });
36
+ }
@@ -281,6 +281,13 @@ export default class DSDateTimePickerCO extends PageObject {
281
281
  static getCalendarSelectedFocusedDay = async () =>
282
282
  $(`[data-testid="ds-controlled-date-time-picker-calendar-selected-focused-day"]`);
283
283
 
284
+ // Non-current-month day cells only carry the `notCurrentMonth` wrapper class (they share the
285
+ // generic calendar-day data-testid), so this class is the only distinguishing selector. The grid
286
+ // renders leading/trailing spillover cells that are hidden, so index 0 is a hidden filler — use
287
+ // index 1 for the first visible non-current-month day. PUI-14872.
288
+ static getCalendarNotCurrentMonthDayByIndex = async (index = 0) =>
289
+ $$(`.notCurrentMonth button[data-testid="ds-controlled-date-time-picker-calendar-day"]`)[index];
290
+
284
291
  // TIMEWHEEL
285
292
  static getTimeWheelHeaderLabel = async () =>
286
293
  $(`[data-testid="ds-controlled-date-time-picker-timewheel-header-label"]`);
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable prettier/prettier */
2
2
  /* eslint-disable max-len */
3
3
  /* eslint-disable max-lines */
4
- import { axeCoreCheck } from '../../helpers';
4
+ import { axeCoreCheck, mouseOver } from '../../helpers';
5
5
  import DateTimePickerCO from '../DSControlledDateTimePickerCO';
6
6
 
7
7
  if (
@@ -21,5 +21,12 @@ if (
21
21
  const result = await axeCoreCheck();
22
22
  expect(result.length).toBe(0);
23
23
  });
24
+ it('02: should pass axe-core color-contrast while hovering a non-current-month day', async () => {
25
+ const notCurrentMonthDay = await DateTimePickerCO.getCalendarNotCurrentMonthDayByIndex(1);
26
+ await notCurrentMonthDay.waitForDisplayed();
27
+ await mouseOver(notCurrentMonthDay);
28
+ const result = await axeCoreCheck();
29
+ expect(result.length).toBe(0);
30
+ });
24
31
  });
25
32
  }
@@ -45,5 +45,14 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
45
45
  );
46
46
  await expect(snapshot).toEqual(0);
47
47
  });
48
+ it('05: should keep readable contrast when hovering a non-current-month day', async () => {
49
+ const notCurrentMonthDay = await DateTimePickerCO.getCalendarNotCurrentMonthDayByIndex(1);
50
+ await notCurrentMonthDay.waitForDisplayed();
51
+ await mouseOver(notCurrentMonthDay);
52
+ const snapshot = await browser.checkSnapshot(
53
+ DateTimePickerCO.snapshotPath('date-time-full-not-current-month-day-hover'),
54
+ );
55
+ await expect(snapshot).toEqual(0);
56
+ });
48
57
  });
49
58
  }
@@ -0,0 +1,45 @@
1
+ import DateTimePickerCO from '../DSControlledDateTimePickerCO';
2
+ import { type } from '../../helpers';
3
+
4
+ // Tests for the fix introduced in PUI-15900 (focus lost when the input holds a partial date
5
+ // while onCalendarOpenFocusedDay is set — the displayed month must follow the focused day so
6
+ // the prop date is rendered and receives focus on open).
7
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
8
+ describe('PUI-18784 - DSControlledDateTimePicker:: focus on calendar open with partial date -Func', () => {
9
+ beforeEach('loading page', async () => {
10
+ const errorOnGo = await DateTimePickerCO.emptyDatePickerStartingMonth.go();
11
+ if (errorOnGo) throw errorOnGo;
12
+ });
13
+
14
+ it('01: empty input focuses the onCalendarOpenFocusedDay day (Dec 27) on open', async () => {
15
+ const trigger = await DateTimePickerCO.getTrigger();
16
+ await trigger.click();
17
+
18
+ const focusedDay = await DateTimePickerCO.getCalendarFocusedDay();
19
+ await expect(focusedDay).toHaveText('27');
20
+ await expect(focusedDay).toBeFocused();
21
+ });
22
+
23
+ it('02: partial month still focuses the onCalendarOpenFocusedDay day (Dec 27) on open', async () => {
24
+ const month = await DateTimePickerCO.getMonthInput();
25
+ await month.click();
26
+ await type('1'); // partial date — month typed, no day/year
27
+
28
+ const trigger = await DateTimePickerCO.getTrigger();
29
+ await trigger.click();
30
+
31
+ // grid follows the focused day's month (December) so the prop date is visible + focused
32
+ const focusedDay = await DateTimePickerCO.getCalendarFocusedDay();
33
+ await expect(focusedDay).toHaveText('27');
34
+ await expect(focusedDay).toBeFocused();
35
+
36
+ // the displayed month must be December 2000 (the prop's month), not the typed January
37
+ const headerLabel = await DateTimePickerCO.getCalendarHeaderLabel();
38
+ await expect(headerLabel).toHaveText('December 2000');
39
+
40
+ // focus must NOT have landed on the previous-month navigation button
41
+ const prevMonthBtn = await DateTimePickerCO.getCalendarPrevMonthBtn();
42
+ await expect(prevMonthBtn).not.toBeFocused();
43
+ });
44
+ });
45
+ }
@@ -54,4 +54,43 @@ if (
54
54
  expect(result.length).toBe(0);
55
55
  });
56
56
  });
57
+
58
+ describe('PUI-16464 - NativeSelect: ApplyAriaDisabled -AxeCore', () => {
59
+ before(async () => {
60
+ const errorOnGo = await NativeSelect.applyAriaDisabledURL.go();
61
+ if (errorOnGo) throw errorOnGo;
62
+ });
63
+ it('01: should have applyAriaDisabled native select and pass axe-core scan', async () => {
64
+ const nativeSelect = await NativeSelect.getRootByIndex(0);
65
+ await nativeSelect.waitForDisplayed();
66
+ const result = await axeCoreCheck();
67
+ expect(result.length).toBe(0);
68
+ });
69
+ });
70
+
71
+ describe('PUI-16464 - NativeSelect: ReadOnly -AxeCore', () => {
72
+ before(async () => {
73
+ const errorOnGo = await NativeSelect.readOnlyURL.go();
74
+ if (errorOnGo) throw errorOnGo;
75
+ });
76
+ it('01: should have readOnly native select and pass axe-core scan', async () => {
77
+ const nativeSelect = await NativeSelect.getRootByIndex(0);
78
+ await nativeSelect.waitForDisplayed();
79
+ const result = await axeCoreCheck();
80
+ expect(result.length).toBe(0);
81
+ });
82
+ });
83
+
84
+ describe('PUI-16464 - NativeSelect: ApplyAriaDisabled + hasError -AxeCore', () => {
85
+ before(async () => {
86
+ const errorOnGo = await NativeSelect.applyAriaDisabledWithErrorURL.go();
87
+ if (errorOnGo) throw errorOnGo;
88
+ });
89
+ it('01: should have applyAriaDisabled + hasError native select and pass axe-core scan', async () => {
90
+ const nativeSelect = await NativeSelect.getRootByIndex(0);
91
+ await nativeSelect.waitForDisplayed();
92
+ const result = await axeCoreCheck();
93
+ expect(result.length).toBe(0);
94
+ });
95
+ });
57
96
  }
@@ -0,0 +1,33 @@
1
+ import NativeSelect from './NativeSelectCO';
2
+
3
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
4
+ describe('PUI-18537 - NativeSelect:: basic state -Visual', () => {
5
+ before('loading page', async () => {
6
+ const errorOnGo = await NativeSelect.controlledURL.go();
7
+ if (errorOnGo) throw errorOnGo;
8
+ });
9
+
10
+ it('01: should render the basic controlled native select', async () => {
11
+ const root = await NativeSelect.getRootByIndex(0);
12
+ await root.waitForDisplayed();
13
+ const snapshot = await browser.percyCheckScreenshot(NativeSelect.snapshotPath('basic'));
14
+ await expect(snapshot).toEqual(0);
15
+ });
16
+ });
17
+
18
+ // Coverage for the fix introduced in PUI-14617
19
+ // (disabled-state colors aligned with Combobox disabled-state colors to meet WCAG 1.4.3).
20
+ describe('PUI-18538 - NativeSelect:: disabled state -Visual', () => {
21
+ before('loading page', async () => {
22
+ const errorOnGo = await NativeSelect.disabledURL.go();
23
+ if (errorOnGo) throw errorOnGo;
24
+ });
25
+
26
+ it('01: should render the disabled native select', async () => {
27
+ const root = await NativeSelect.getRootByIndex(0);
28
+ await root.waitForDisplayed();
29
+ const snapshot = await browser.percyCheckScreenshot(NativeSelect.snapshotPath('disabled'));
30
+ await expect(snapshot).toEqual(0);
31
+ });
32
+ });
33
+ }
@@ -11,6 +11,12 @@ export default class NativeSelect extends PageObject {
11
11
 
12
12
  static disabledURL = new Urlbuilder(PATH_E2E_NATIVE_SELECT, 'disabled-test');
13
13
 
14
+ static applyAriaDisabledURL = new Urlbuilder(PATH_E2E_NATIVE_SELECT, 'apply-aria-disabled-test');
15
+
16
+ static readOnlyURL = new Urlbuilder(PATH_E2E_NATIVE_SELECT, 'read-only-test');
17
+
18
+ static applyAriaDisabledWithErrorURL = new Urlbuilder(PATH_E2E_NATIVE_SELECT, 'apply-aria-disabled-with-error-test');
19
+
14
20
  // Selectors
15
21
  static async getInputSlotByIndex(index = 0) {
16
22
  return $$(`[data-dimsum-slot="dsNativeselectInput"]`)[index];
@@ -0,0 +1,25 @@
1
+ import NativeSelect from '../NativeSelectCO';
2
+
3
+ // Tests for the option selection behavior of the native select introduced in PUI-14617.
4
+ // Selecting an option must update the <select> value (options use value={index}).
5
+ // Uses the WebDriver native select command (selectByIndex) so the native popup is opened and an
6
+ // option committed the same way in every browser — simulated keystrokes on the OS-drawn popup are
7
+ // not reachable by WebDriver on macOS/Safari, which is why a keystroke-based assertion is not portable.
8
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
9
+ describe('PUI-18563 - NativeSelect:: Option selection updates value -Func', () => {
10
+ before(async () => {
11
+ const errorOnGo = await NativeSelect.controlledURL.go();
12
+ if (errorOnGo) throw errorOnGo;
13
+ });
14
+
15
+ it('01: should update the value when selecting an option from the popup', async () => {
16
+ const nativeSelect = await NativeSelect.getRootByIndex(0);
17
+ await nativeSelect.waitForDisplayed();
18
+
19
+ const input = await NativeSelect.getInputSlotByIndex(0);
20
+ await input.selectByIndex(2);
21
+
22
+ await expect(input).toHaveValue('2');
23
+ });
24
+ });
25
+ }
@@ -11,14 +11,16 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
11
11
  await (await DSToggleCO.getToggle()).waitForExist();
12
12
  });
13
13
  it('01: should change state to ON', async () => {
14
- await (await DSToggleCO.getToggle()).click();
15
- const toggleState = await DSToggleCO.getToggleState('ON');
16
- await expect(toggleState).toBeDisplayed();
14
+ await (await DSToggleCO.getSwitch()).click();
15
+ await expect(await DSToggleCO.getSwitch()).toHaveAttribute('aria-checked', 'true');
16
+ // the visible (presentational) label should track the state
17
+ await expect(await DSToggleCO.getStateLabel()).toHaveText('ON');
17
18
  });
18
19
  it('02: should change state to OFF', async () => {
19
- await (await DSToggleCO.getToggle()).click();
20
- const toggleState = await DSToggleCO.getToggleState('OFF');
21
- await expect(toggleState).toBeDisplayed();
20
+ await (await DSToggleCO.getSwitch()).click();
21
+ await expect(await DSToggleCO.getSwitch()).toHaveAttribute('aria-checked', 'false');
22
+ // the visible (presentational) label should track the state
23
+ await expect(await DSToggleCO.getStateLabel()).toHaveText('OFF');
22
24
  });
23
25
  });
24
26
  describe('PUI-6760 - DSControlledToggle:: states on/off - keyboard navigation', () => {
@@ -34,18 +36,15 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
34
36
  });
35
37
  it('02: should change state to ON (Enter)', async () => {
36
38
  await browser.keys(Key.Enter);
37
- const toggleState = await DSToggleCO.getToggleState('ON');
38
- await expect(toggleState).toBeDisplayed();
39
+ await expect(await DSToggleCO.getSwitch()).toHaveAttribute('aria-checked', 'true');
39
40
  });
40
41
  it('03: should change state to OFF (Space)', async () => {
41
42
  await browser.keys(Key.Space);
42
- const toggleState = await DSToggleCO.getToggleState('OFF');
43
- await expect(toggleState).toBeDisplayed();
43
+ await expect(await DSToggleCO.getSwitch()).toHaveAttribute('aria-checked', 'false');
44
44
  });
45
45
  it('04: should change state to ON (Space)', async () => {
46
46
  await browser.keys(Key.Space);
47
- const toggleState = await DSToggleCO.getToggleState('ON');
48
- await expect(toggleState).toBeDisplayed();
47
+ await expect(await DSToggleCO.getSwitch()).toHaveAttribute('aria-checked', 'true');
49
48
  });
50
49
  });
51
50
 
@@ -56,10 +55,11 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
56
55
  await (await DSToggleCO.getToggle()).waitForExist();
57
56
  });
58
57
  it('01: should not change state in disabled toggle', async () => {
59
- const disabledToggle = await DSToggleCO.getToggleByIndex(0);
60
- await disabledToggle.click();
61
- const toggleState = await disabledToggle.$('//div[@disabled]//div[2]').getText();
62
- await expect(toggleState).toEqual('ON');
58
+ const disabledSwitch = await DSToggleCO.getSwitch(0);
59
+ const initialState = await disabledSwitch.getAttribute('aria-checked');
60
+ // click the container (the button itself is disabled and not interactable)
61
+ await (await DSToggleCO.getToggleByIndex(0)).click();
62
+ await expect(await DSToggleCO.getSwitch(0)).toHaveAttribute('aria-checked', initialState);
63
63
  });
64
64
  });
65
65
 
@@ -84,18 +84,15 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
84
84
  });
85
85
  it('03: should not change state on [Enter] key press', async () => {
86
86
  await browser.keys(Key.Enter);
87
- const toggleState = await DSToggleCO.getToggleState('OFF');
88
- await expect(toggleState).toBeDisplayed();
87
+ await expect(await DSToggleCO.getSwitch()).toHaveAttribute('aria-checked', 'false');
89
88
  });
90
89
  it('04: should not change state on [Space] key press', async () => {
91
90
  await browser.keys(Key.Space);
92
- const toggleState = await DSToggleCO.getToggleState('OFF');
93
- await expect(toggleState).toBeDisplayed();
91
+ await expect(await DSToggleCO.getSwitch()).toHaveAttribute('aria-checked', 'false');
94
92
  });
95
93
  it('05: should not change state on click', async () => {
96
- await (await DSToggleCO.getToggle()).click();
97
- const toggleState = await DSToggleCO.getToggleState('OFF');
98
- await expect(toggleState).toBeDisplayed();
94
+ await (await DSToggleCO.getSwitch()).click();
95
+ await expect(await DSToggleCO.getSwitch()).toHaveAttribute('aria-checked', 'false');
99
96
  });
100
97
  });
101
98
  describe('PUI-8814 - DSControlledToggle:: Tabbing', () => {