dimsum-e2e-tests 3.62.1 → 3.70.0-alpha.11

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 (325) hide show
  1. package/CHANGELOG.md +2244 -286
  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/DSComboboxCO.js +2 -2
  112. package/ds-controlled-form/ds-combobox/creatable/DSCombobox.creatable-tooltip.func.spec.js +47 -0
  113. package/ds-controlled-form/ds-combobox/creatable/DSCombobox.creatable.visual.spec.js +12 -21
  114. package/ds-controlled-form/ds-combobox/disabled/DSCombobox.disabled.visual.spec.js +6 -1
  115. package/ds-controlled-form/ds-controlled-checkbox/Basic/DSControlledCheckbox.axe-core.basic.func.spec.js +4 -4
  116. package/ds-controlled-form/ds-controlled-checkbox/Basic/DSControlledCheckbox.basic.visual.spec.js +56 -0
  117. package/ds-controlled-form/ds-controlled-checkbox/DSControlledCheckboxCO.js +55 -2
  118. package/ds-controlled-form/ds-controlled-checkbox/Disabled/DSControlledCheckbox.axe-core.disabled.func.spec.js +1 -1
  119. package/ds-controlled-form/ds-controlled-checkbox/Disabled/DSControlledCheckbox.disabled.visual.spec.js +1 -1
  120. package/ds-controlled-form/ds-controlled-checkbox/HasError/DSControlledCheckbox.axe-core.hasError.func.spec.js +4 -4
  121. package/ds-controlled-form/ds-controlled-checkbox/HasError/DSControlledCheckbox.has-error.visual.spec.js +71 -1
  122. package/ds-controlled-form/ds-controlled-checkbox/Mixed/DSControlledCheckbox.axe-core.mixed.func.spec.js +4 -4
  123. package/ds-controlled-form/ds-controlled-checkbox/Mixed/DSControlledCheckbox.mixed.visual.spec.js +1 -1
  124. package/ds-controlled-form/ds-controlled-checkbox/ReadOnly/DSControlledCheckbox.axe-core.read-only.func.spec.js +3 -3
  125. package/ds-controlled-form/ds-controlled-checkbox/ReadOnly/DSControlledCheckbox.read-only.visual.spec.js +1 -1
  126. package/ds-controlled-form/ds-controlled-checkbox/WithTooltip/DSControlledCheckbox.axe-core.with-tooltip.func.spec.js +1 -1
  127. package/ds-controlled-form/ds-controlled-checkbox/WithTooltip/DSControlledCheckbox.with-tooltip.visual.spec.js +1 -3
  128. package/ds-controlled-form/ds-controlled-checkbox/WrapLabel/DSControlledCheckbox.axe-core.wrap-label.func.spec.js +1 -1
  129. package/ds-controlled-form/ds-controlled-checkbox/WrapLabel/DSControlledCheckbox.wrap-label.visual.spec.js +1 -1
  130. package/ds-controlled-form/ds-controlled-checkbox/aria-disabled/DSControlledCheckbox.aria-disabled.visual.spec.js +2 -6
  131. package/ds-controlled-form/ds-controlled-checkbox/aria-disabled/DSControlledCheckbox.axe-core.aria-disabled.func.spec.js +1 -1
  132. package/ds-controlled-form/ds-controlled-checkbox/slots/DSControlledCheckbox.slots.func.spec.js +78 -0
  133. package/ds-controlled-form/ds-controlled-checkbox/theme-font/DSControlledCheckbox.theme-font.func.spec.js +30 -0
  134. package/ds-controlled-form/ds-controlled-checkbox-group/DSControlledCheckboxGroup.axe-core.func.spec.js +4 -4
  135. package/ds-controlled-form/ds-controlled-checkbox-group/DSControlledCheckboxGroup.visual.spec.js +1 -1
  136. package/ds-controlled-form/ds-controlled-inputgroup/DSControlledInputGroupCO.js +1 -1
  137. package/ds-controlled-form/ds-controlled-radio/DSControlledRadioCO.js +50 -1
  138. package/ds-controlled-form/ds-controlled-radio/aria-disabled/DSControlledRadio.aria-disabled.axe-core.func.spec.js +16 -2
  139. package/ds-controlled-form/ds-controlled-radio/aria-disabled/DSControlledRadio.aria-disabled.func.spec.js +37 -0
  140. package/ds-controlled-form/ds-controlled-radio/slots/DSControlledRadio.slots.func.spec.js +78 -0
  141. package/ds-controlled-form/ds-controlled-radio/theme-font/DSControlledRadio.theme-font.func.spec.js +30 -0
  142. package/ds-controlled-form/react-hook-form/ReactHook.func.spec.js +1 -3
  143. package/ds-data-table-async/DSDataTableCO.js +189 -12
  144. package/ds-data-table-async/basic/DSDataTable.basic.visual.spec.js +1 -1
  145. package/ds-data-table-async/components/FilterBarCO.js +7 -0
  146. package/ds-data-table-async/components/FiltersCO.js +1 -1
  147. package/ds-data-table-async/components/HeaderCO.js +59 -11
  148. package/ds-data-table-async/dnd/DSDataTable.dnd-keyboard-scroll.func.spec.js +51 -0
  149. package/ds-data-table-async/filter-menu-close/DSDataTable.filter-menu-close.func.spec.js +77 -0
  150. package/ds-data-table-async/filter-popover-boundary/DSDataTable.filter-popover-boundary.func.spec.js +98 -0
  151. package/ds-data-table-async/filters/DSDataTable.filters-creatable-active-descendant.func.spec.js +51 -0
  152. package/ds-data-table-async/filters/DSDataTable.filters-creatable.func.spec.js +55 -0
  153. package/ds-data-table-async/filters/DSDataTable.filters.axe-core.func.spec.js +11 -9
  154. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-creatablemultiselect.keyboard.func.spec.js +2 -2
  155. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-creatableselect.keyboard.func.spec.js +2 -2
  156. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2.axe-core.func.spec.js +45 -29
  157. package/ds-data-table-async/filtersV2/pill-label/DSDataTable.pillLabel.axe-core.func.spec.js +23 -0
  158. package/ds-data-table-async/filtersV2/pill-label/DSDataTable.pillLabel.func.spec.js +50 -0
  159. package/ds-data-table-async/filtersV2/pill-label/DSDataTable.pillLabel.visual.spec.js +21 -0
  160. package/ds-data-table-async/header-affordances/DSDataTable.header-affordances.func.spec.js +92 -0
  161. package/ds-data-table-async/helpers/getInputSelection.js +6 -0
  162. package/ds-data-table-async/helpers/index.js +1 -0
  163. package/ds-data-table-async/keyboard-scroll/DSDataTable.keyboard-scroll.func.spec.js +39 -0
  164. package/ds-data-table-async/menubutton/DSDataTable.MenuButton.keyboard.func.spec.js +8 -7
  165. package/ds-data-table-async/menubutton/DSDataTable.MenuButton.mouse.func.spec.js +6 -7
  166. package/ds-data-table-async/pagination/DSDataTable.pagination.func.spec.js +3 -2
  167. package/ds-data-table-async/resizable/DSDataTable.resize-min-clamp.func.spec.js +72 -0
  168. package/ds-data-table-async/resizable/DSDataTable.resizerA11y.axe-core.func.spec.js +42 -0
  169. package/ds-data-table-async/resizable/DSDataTable.resizerA11y.func.spec.js +98 -0
  170. package/ds-data-table-async/textwrapping/DSDataTable.header-wrap-alignment.axe-core.func.spec.js +23 -0
  171. package/ds-data-table-async/textwrapping/DSDataTable.header-wrap-alignment.visual.spec.js +106 -0
  172. package/ds-data-table-async/textwrapping/DSDataTable.text-wrap-toolbar.visual.spec.js +27 -0
  173. package/ds-data-table-async/toggle-cell-focus/DSDataTable.toggle-cell-enter-focus.func.spec.js +31 -0
  174. package/ds-data-table-async/vissibility/DSDataTable.vissibility.visual.spec.js +2 -0
  175. package/ds-dataviz/DSDataViz.axis.visual.spec.js +1 -2
  176. package/ds-dataviz/DSDataViz.ticks.visual.spec.js +1 -2
  177. package/ds-dataviz/DSDataVizCO.js +2 -0
  178. package/ds-dataviz/axecore/DSDataViz.axis.axe-core.func.spec.js +1 -1
  179. package/ds-dialog/DSDialog.visual.spec.js +16 -31
  180. package/ds-dialog/DSDialogCO.js +58 -0
  181. package/ds-dialog/alert-dialog/DSDialog.alert-dialog-critical.axe-core.func.spec.js +27 -0
  182. package/ds-dialog/alert-dialog/DSDialog.alert-dialog-critical.func.spec.js +56 -0
  183. package/ds-dialog/alert-dialog/DSDialog.alert-dialog-critical.visual.spec.js +20 -0
  184. package/ds-dialog/alert-dialog/DSDialog.alert-dialog-dismissible.axe-core.func.spec.js +25 -0
  185. package/ds-dialog/alert-dialog/DSDialog.alert-dialog-dismissible.func.spec.js +52 -0
  186. package/ds-dialog/alert-dialog/DSDialog.alert-dialog-dismissible.visual.spec.js +20 -0
  187. package/ds-dialog/axe-core/DSDialog.accessible-form.axe-core.func.spec.js +25 -0
  188. package/ds-dialog/axe-core/DSDialog.basic.axe-core.func.spec.js +25 -0
  189. package/ds-dialog/axe-core/DSDialog.centered.axe-core.func.spec.js +25 -0
  190. package/ds-dialog/axe-core/DSDialog.decision.axe-core.func.spec.js +57 -0
  191. package/ds-dialog/axe-core/DSDialog.long-body.axe-core.func.spec.js +25 -0
  192. package/ds-dialog/axe-core/DSDialog.warning.axe-core.func.spec.js +24 -0
  193. package/ds-dialog/axe-core/DSDialog.wizard.axe-core.func.spec.js +28 -0
  194. package/ds-dialog/click-outside/DSDialog.click-outside.func.spec.js +31 -0
  195. package/ds-dialog/esc-close/DSDialog.esc-close.func.spec.js +31 -0
  196. package/ds-dialog/flexible-heading-level/DSDialog.flexible-heading-level.axe-core.func.spec.js +46 -0
  197. package/ds-dialog/flexible-heading-level/DSDialog.flexible-heading-level.func.spec.js +50 -0
  198. package/ds-dialog/form-dialog-datepicker/DSDialog.form-datepicker.axe-core.func.spec.js +25 -0
  199. package/ds-dialog/form-dialog-datepicker/DSDialog.form-datepicker.visual.spec.js +37 -0
  200. package/ds-dialog/single-button-footer/DSDialog.single-button-footer.axe-core.func.spec.js +25 -0
  201. package/ds-dialog/single-button-footer/DSDialog.single-button-footer.visual.spec.js +20 -0
  202. package/ds-dialog/size-variants/DSDialog.size-variants.visual.spec.js +116 -0
  203. package/ds-floating-context/DSFloatingContextCO.js +10 -0
  204. package/ds-floating-context/placement/DSFloatingContext.placement.visual.spec.js +48 -0
  205. package/ds-form-combobox-multi/DSComboboxMultiCO.js +38 -11
  206. package/ds-form-combobox-multi/aria-busy-loading/DSComboboxMulti.aria-busy-loading.axe-core.func.spec.js +55 -0
  207. package/ds-form-combobox-multi/aria-busy-loading/DSComboboxMulti.aria-busy-loading.func.spec.js +57 -0
  208. package/ds-form-combobox-multi/aria-disabled/DSComboboxMulti.aria-disabled.visual.spec.js +19 -2
  209. package/ds-form-combobox-multi/disabled/DSComboboxMulti.disabled.axe-core.func.spec.js +24 -0
  210. package/ds-form-combobox-multi/disabled/DSComboboxMulti.disabled.mouse.func.spec.js +0 -2
  211. package/ds-form-combobox-multi/disabled/DSComboboxMulti.disabled.visual.spec.js +22 -0
  212. package/ds-form-combobox-multi/grouped/DSComboboxMulti.grouped.visual.spec.js +42 -0
  213. package/ds-form-combobox-multi/inline/DSComboboxMulti.inline.visual.spec.js +21 -0
  214. package/ds-form-combobox-multi/pills/DSComboboxMulti.pills.func.spec.js +59 -0
  215. package/ds-form-combobox-multi/pills/DSComboboxMulti.pills.visual.spec.js +39 -0
  216. package/ds-form-combobox-multi/skeleton/DSComboboxMulti.skeleton.visual.spec.js +25 -0
  217. package/ds-form-combobox-multi/theme-font/DSComboboxMulti.theme-font.func.spec.js +38 -0
  218. package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.axe-core.func.spec.js +39 -0
  219. package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.func.spec.js +39 -0
  220. package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.visual.spec.js +29 -0
  221. package/ds-form-combobox-single/DSComboboxSingleCO.js +27 -11
  222. package/ds-form-combobox-single/aria-busy-loading/DSComboboxSingle.aria-busy-loading.axe-core.func.spec.js +49 -0
  223. package/ds-form-combobox-single/aria-busy-loading/DSComboboxSingle.aria-busy-loading.func.spec.js +54 -0
  224. package/ds-form-combobox-single/aria-disabled/DSComboboxSingle.aria-disabled.visual.spec.js +18 -0
  225. package/ds-form-combobox-single/creatable/DSComboboxSingle.creatable.visual.spec.js +30 -0
  226. package/ds-form-combobox-single/disabled/DSComboboxSingle.disabled.axe-core.func.spec.js +24 -0
  227. package/ds-form-combobox-single/disabled/DSComboboxSingle.disabled.mouse.func.spec.js +0 -2
  228. package/ds-form-combobox-single/disabled/DSComboboxSingle.disabled.visual.spec.js +22 -0
  229. package/ds-form-combobox-single/grouped/DSComboboxSingle.grouped.visual.spec.js +45 -0
  230. package/ds-form-combobox-single/inline/DSComboboxSingle.inline.visual.spec.js +23 -0
  231. package/ds-form-combobox-single/skeleton/DSComboboxSingle.skeleton.visual.spec.js +25 -0
  232. package/ds-form-combobox-single/theme-font/DSComboboxSingle.theme-font.func.spec.js +34 -0
  233. package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.axe-core.func.spec.js +39 -0
  234. package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.func.spec.js +39 -0
  235. package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.visual.spec.js +29 -0
  236. package/ds-form-date-range-picker/DateRangePicker.axe-core.spec.js +5 -0
  237. package/ds-form-date-range-picker/DateRangePicker.functional.spec.js +80 -18
  238. package/ds-form-date-range-picker/DateRangePickerCO.js +19 -0
  239. package/ds-form-date-range-picker/date-segment-aria-labels/DateRangePicker.date-segment-aria-labels.func.spec.js +66 -0
  240. package/ds-form-date-range-picker/grouped-field-error-announcement/DateRangePicker.grouped-field-error-announcement.func.spec.js +59 -0
  241. package/ds-form-date-range-picker/picker-callbacks/DateRangePicker.picker-callbacks.func.spec.js +36 -0
  242. package/ds-form-date-time-picker/DSControlledDateTimePickerCO.js +7 -0
  243. package/ds-form-date-time-picker/date-time-full/DateTimeFull.axe-core.func.spec.js +8 -1
  244. package/ds-form-date-time-picker/date-time-full/DateTimePicker.DateTimeFull.visual.spec.js +9 -0
  245. package/ds-form-date-time-picker/partial-date-open-focus/DateTimePicker.partial-date-open-focus.func.spec.js +45 -0
  246. package/ds-form-native-select/NativeSelect.axe-core.func.spec.js +39 -0
  247. package/ds-form-native-select/NativeSelect.visual.spec.js +33 -0
  248. package/ds-form-native-select/NativeSelectCO.js +6 -0
  249. package/ds-form-native-select/option-selection/NativeSelect.option-selection.func.spec.js +25 -0
  250. package/ds-form-toggle/DSToggle.func.spec.js +20 -23
  251. package/ds-form-toggle/DSToggleCO.js +11 -2
  252. package/ds-global-header/GlobalHeader.announcements.func.spec.js +27 -0
  253. package/ds-global-header/GlobalHeader.axe-core.func.spec.js +41 -11
  254. package/ds-global-header/GlobalHeader.func.spec.js +70 -1
  255. package/ds-global-header/GlobalHeader.visual.spec.js +31 -0
  256. package/ds-global-header/GlobalHeaderCO.js +120 -2
  257. package/ds-global-header/app-picker-passthrough/GlobalHeader.app-picker-passthrough.func.spec.js +113 -0
  258. package/ds-global-header/popup-menu-focus/GlobalHeader.popup-menu-focus.func.spec.js +63 -0
  259. package/ds-global-header/popup-menu-slots/GlobalHeader.popup-menu-slots.func.spec.js +70 -0
  260. package/ds-global-header/search-toggle-slots/GlobalHeader.search-toggle-slots.func.spec.js +118 -0
  261. package/ds-global-header/toolbar-item-attributes/GlobalHeader.toolbar-item-attributes.func.spec.js +53 -0
  262. package/ds-grid/DSGridCO.js +20 -0
  263. package/ds-grid/layout-mode/DSGrid.layout-mode.func.spec.js +51 -0
  264. package/ds-grid/layout-mode/DSGrid.layout-mode.visual.spec.js +22 -0
  265. package/ds-hooks/DSHook.UseFontSizeMedia.visual.spec.js +5 -2
  266. package/ds-hooks/DSHook.usetree.func.spec.js +3 -2
  267. package/ds-hooks/DSHookCO.js +56 -23
  268. package/ds-hooks/useFocusStack/DSHook.useFocusStack.func.spec.js +83 -0
  269. package/ds-hooks/useFocusTrap/UseFocusTrapCO.js +2 -0
  270. package/ds-hooks/useFocusTrap/UseFocusTrapToggle.func.spec.js +48 -0
  271. package/ds-hooks/useMask/Number/UseNumberMask.axe-core.func.spec.js +48 -0
  272. package/ds-leftnavigation/LeftNavigationCO.js +2 -2
  273. package/ds-menu-button/slots/DSMenuButton.slots.axe-core.func.spec.js +28 -0
  274. package/ds-menu-button/slots/DSMenuButton.slots.func.spec.js +19 -0
  275. package/ds-modal-slide/ModalSlideCO.js +46 -0
  276. package/ds-modal-slide/custom-header/ModalSlide.customHeader.focusRing.visual.spec.js +2 -1
  277. package/ds-modal-slide/heading-level/ModalSlide.headingLevel.axe-core.func.spec.js +25 -0
  278. package/ds-modal-slide/heading-level/ModalSlide.headingLevel.func.spec.js +25 -0
  279. package/ds-modal-slide/slots/ModalSlide.slots.func.spec.js +74 -0
  280. package/ds-modal-slide/slots/ModalSlide.slots.visual.spec.js +27 -0
  281. package/ds-notification-badge/DSNotificationBadge.visual.spec.js +17 -20
  282. package/ds-page-layout/PageLayoutCO.js +4 -4
  283. package/ds-pills-v2/DSPillsV2CO.js +12 -0
  284. package/ds-pills-v2/apply-aria-disabled/DSPills.applyAriaDisabled.func.spec.js +53 -0
  285. package/ds-pills-v2/apply-aria-disabled/DSPills.applyAriaDisabled.visual.spec.js +26 -0
  286. package/ds-pills-v2/disabled/DSPills.disabled.func.spec.js +53 -0
  287. package/ds-pills-v2/disabled/DSPills.disabled.visual.spec.js +33 -0
  288. package/ds-progress-indicator/DSProgressIndicator.axe-core.func.spec.js +2 -0
  289. package/ds-progress-indicator/DSProgressIndicatorCO.js +1 -1
  290. package/ds-query-builder/DSQueryBuilder.visual.spec.js +6 -6
  291. package/ds-shuttle-v2/DSShuttleV2CO.js +15 -1
  292. package/ds-shuttle-v2/breadcrumb-a11y/DSShuttleV2.breadcrumb-a11y.func.spec.js +43 -0
  293. package/ds-shuttle-v2/explicit-selection-ui/DSShuttleV2.explicit-selection-ui.func.spec.js +37 -0
  294. package/ds-shuttle-v2/explicit-selection-ui/DSShuttleV2.explicit-selection-ui.visual.spec.js +30 -0
  295. package/ds-shuttle-v2/extra/DSShuttleV2.extra.visual.spec.js +8 -3
  296. package/ds-shuttle-v2/items/DSShuttleV2.items.func.spec.js +4 -2
  297. package/ds-shuttle-v2/skipped/DSShuttleV2.extra.axe-core.skipped.js +1 -1
  298. package/ds-shuttle-v2/skipped/DSShuttleV2.filter.axe-core.skipped.js +1 -1
  299. package/ds-shuttle-v2/skipped/DSShuttleV2.globalcheckbox.axe-core.skipped.js +1 -1
  300. package/ds-shuttle-v2/skipped/DSShuttleV2.items.axe-core.skipped.js +3 -3
  301. package/ds-shuttle-v2/skipped/DSShuttleV2.skipped.js +5 -5
  302. package/ds-slider-v2/DSSliderV2.func.spec.js +36 -25
  303. package/ds-slider-v2/DSSliderV2CO.js +10 -0
  304. package/ds-slider-v2/min-range/DSSliderV2.min-range.func.spec.js +69 -0
  305. package/ds-tab-button/DSTabButton.func.spec.js +1 -1
  306. package/ds-tabs/DSTabs.visual.spec.js +1 -2
  307. package/ds-tabs/DSTabsCO.js +2 -2
  308. package/ds-tabs/with-carousel/DSTabs.with-carousel.func.spec.js +22 -7
  309. package/ds-tabs/with-carousel/DSTabs.with-carousel.visual.spec.js +9 -9
  310. package/ds-tooltip-v3/DSTooltipV3CO.js +21 -0
  311. package/ds-tooltip-v3/aria-tooltip-pattern/DSTooltipV3.aria-tooltip-pattern.axe-core.func.spec.js +23 -0
  312. package/ds-tooltip-v3/aria-tooltip-pattern/DSTooltipV3.aria-tooltip-pattern.func.spec.js +29 -0
  313. package/ds-tooltip-v3/dialog/DSTooltipV3.dialog.func.spec.js +45 -0
  314. package/ds-tooltip-v3/dialog/DSTooltipV3.dialog.visual.spec.js +29 -0
  315. package/ds-treeview/DSTreeViewCO.js +25 -2
  316. package/ds-treeview/dragAndDrop/TreeView-dnd_keyboard.func.spec.js +96 -0
  317. package/ds-typography/DSTypographyCO.js +10 -0
  318. package/ds-typography/theme-font/DSTypography.theme-font.func.spec.js +30 -0
  319. package/package.json +149 -154
  320. package/paths.js +12 -6
  321. package/ds-card-v3/disabled/DSCardV3.disabled.visual.spec.js +0 -17
  322. package/ds-chat-tile/TileCO.js +0 -35
  323. package/ds-hooks/DSHook.func.spec.js +0 -60
  324. package/ds-hooks/useFocusStack/DSHook.useFocusStack.skipped.js +0 -57
  325. package/ds-treeview/dragAndDrop/TreeView-dnd_mouse.func.spec.js +0 -61
@@ -1,7 +1,19 @@
1
1
  import { Key } from 'webdriverio';
2
2
  import GlobalHeader from './GlobalHeaderCO';
3
3
 
4
- if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
4
+ // Asserts the search-toggle spinbutton reflects the expected selected-result state.
5
+ const expectSelectedResult = async (valuenow, valuetext) => {
6
+ const spinButton = await GlobalHeader.getSearchToggleSpinbutton();
7
+ await expect(spinButton).toHaveAttribute('aria-valuenow', valuenow);
8
+ await expect(spinButton).toHaveAttribute('aria-valuetext', valuetext);
9
+ };
10
+
11
+ if (
12
+ (!browser.capabilities['ice:options'].isPhone &&
13
+ !browser.capabilities['ice:options'].isTablet &&
14
+ browser.capabilities.browserName === 'chrome') ||
15
+ browser.capabilities.browserName === 'Chrome'
16
+ ) {
5
17
  describe('PUI-10036 - GlobalHeader: title and aria attributes', () => {
6
18
  before(async () => {
7
19
  const errorOnGo = await GlobalHeader.customAttributes.go();
@@ -80,4 +92,61 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
80
92
  await expect(firstToolbarItem).not.toBeFocused();
81
93
  });
82
94
  });
95
+
96
+ // Tests for the fix in PUI-17974 (SearchToggle arrow navigation could not start with ArrowDown nor cycle)
97
+ describe('PUI-18772 - GlobalHeader: SearchToggle result navigation with ArrowDown -Func', () => {
98
+ before(async () => {
99
+ const errorOnGo = await GlobalHeader.withSearchToggleURL.go();
100
+ if (errorOnGo) throw errorOnGo;
101
+ await GlobalHeader.openAndPopulateSearchToggle();
102
+ });
103
+ it('01: should be idle (no result selected) before navigation starts', async () => {
104
+ await expectSelectedResult('0', '3 total results');
105
+ });
106
+ it('02: should start navigation on last result when pressing ArrowDown from idle', async () => {
107
+ await browser.keys(Key.ArrowDown);
108
+ await expectSelectedResult('3', 'result 3 of 3');
109
+ });
110
+ it('03: should move to the previous result on subsequent ArrowDown', async () => {
111
+ await browser.keys(Key.ArrowDown);
112
+ await expectSelectedResult('2', 'result 2 of 3');
113
+ });
114
+ it('04: should reach the first result on ArrowDown', async () => {
115
+ await browser.keys(Key.ArrowDown);
116
+ await expectSelectedResult('1', 'result 1 of 3');
117
+ });
118
+ it('05: should cycle from the first result back to the last on ArrowDown', async () => {
119
+ await browser.keys(Key.ArrowDown);
120
+ await expectSelectedResult('3', 'result 3 of 3');
121
+ });
122
+ });
123
+
124
+ // Tests for the fix in PUI-17974 (SearchToggle arrow navigation could not start with ArrowDown nor cycle)
125
+ describe('PUI-18773 - GlobalHeader: SearchToggle result navigation with ArrowUp -Func', () => {
126
+ // same setup as above; here the ArrowUp navigation is exercised from idle
127
+ before(async () => {
128
+ const errorOnGo = await GlobalHeader.withSearchToggleURL.go();
129
+ if (errorOnGo) throw errorOnGo;
130
+ await GlobalHeader.openAndPopulateSearchToggle();
131
+ });
132
+ it('01: should be idle (no result selected) before navigation starts', async () => {
133
+ await expectSelectedResult('0', '3 total results');
134
+ });
135
+ it('02: should start navigation on the first result when pressing ArrowUp from idle', async () => {
136
+ await browser.keys(Key.ArrowUp);
137
+ await expectSelectedResult('1', 'result 1 of 3');
138
+ });
139
+ it('03: should move to the next result on subsequent ArrowUp', async () => {
140
+ await browser.keys(Key.ArrowUp);
141
+ await expectSelectedResult('2', 'result 2 of 3');
142
+ });
143
+ it('04: should reach the last result on ArrowUp', async () => {
144
+ await browser.keys(Key.ArrowUp);
145
+ await expectSelectedResult('3', 'result 3 of 3');
146
+ });
147
+ it('05: should cycle from the last result back to the first on ArrowUp', async () => {
148
+ await browser.keys(Key.ArrowUp);
149
+ await expectSelectedResult('1', 'result 1 of 3');
150
+ });
151
+ });
83
152
  }
@@ -164,4 +164,35 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
164
164
  await expect(snapshot).toEqual(0);
165
165
  });
166
166
  });
167
+
168
+ describe('PUI-18378 - GlobalHeader: with SearchToggle -Visual', () => {
169
+ before(async () => {
170
+ const errorOnGo = await GlobalHeader.withSearchToggleURL.go();
171
+ if (errorOnGo) throw errorOnGo;
172
+ });
173
+ it('01: should display global header with expanded search toggle', async () => {
174
+ await browser.eyesOpen();
175
+ const searchToggleTrigger = await GlobalHeader.getGHToolbarItem(0);
176
+ await searchToggleTrigger.click();
177
+ const snapshot = await browser.eyesCheckSnapshot(GlobalHeader.snapshotPath('global-with-searchbox-open'));
178
+ await expect(snapshot).toEqual(0);
179
+ });
180
+ it('02: should display global header with populated search toggle', async () => {
181
+ await browser.eyesOpen();
182
+ await browser.keys(Key.Tab);
183
+ await browser.keys('Labor');
184
+ const snapshot = await browser.eyesCheckSnapshot(GlobalHeader.snapshotPath('global-with-searchbox-populated'));
185
+ await expect(snapshot).toEqual(0);
186
+ });
187
+ it('03: should display global header with focused spinbutton and highlighted result', async () => {
188
+ await browser.eyesOpen();
189
+ await browser.keys(Key.Tab);
190
+ await browser.keys(Key.Tab);
191
+ await browser.keys(Key.ArrowUp);
192
+ const globalHeader = await GlobalHeader.getGlobalHeader();
193
+ await globalHeader.waitForDisplayed();
194
+ const snapshot = await browser.eyesCheckSnapshot(GlobalHeader.snapshotPath('global-with-searchbox-highlight'));
195
+ await expect(snapshot).toEqual(0);
196
+ });
197
+ });
167
198
  }
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable import/no-relative-packages */
2
- import { PATH_E2E_GLOBAL_HEADER } from '../paths';
3
- import { PageObject, Urlbuilder } from '../helpers';
2
+ import { PATH_E2E_GLOBAL_HEADER, PATH_E2E_GLOBAL_HEADER_PUI18647 } from '../paths';
3
+ import { PageObject, Urlbuilder, getElementByIndex, type } from '../helpers';
4
4
 
5
5
  export default class GlobalHeader extends PageObject {
6
6
  static basicURL = new Urlbuilder(PATH_E2E_GLOBAL_HEADER, 'basic');
@@ -31,6 +31,19 @@ export default class GlobalHeader extends PageObject {
31
31
 
32
32
  static withLayoutProvider = new Urlbuilder(PATH_E2E_GLOBAL_HEADER, 'with-layout-provider');
33
33
 
34
+ // PUI-18647 — one story per out-of-the-box toolbar item type, each a minimal header carrying only
35
+ // that item with every injection point wired to data-public="true".
36
+ static appPickerPassthroughURL = new Urlbuilder(PATH_E2E_GLOBAL_HEADER_PUI18647, 'app-picker-contract-passthrough');
37
+
38
+ static iconButtonItemURL = new Urlbuilder(PATH_E2E_GLOBAL_HEADER_PUI18647, 'icon-button-item-attributes');
39
+
40
+ static popupMenuSlotSurfaceURL = new Urlbuilder(PATH_E2E_GLOBAL_HEADER_PUI18647, 'popup-menu-slot-surface');
41
+
42
+ static searchToggleSlotsURL = new Urlbuilder(
43
+ PATH_E2E_GLOBAL_HEADER_PUI18647,
44
+ 'search-toggle-item-attributes-and-slots',
45
+ );
46
+
34
47
  // Selectors
35
48
  static async getGHBreadcrumbBtn(label) {
36
49
  return $(`//a[@data-testid="gh-breadcrumb-btn"]/span[contains(text(),"${label}")]/ancestor::a`);
@@ -84,6 +97,111 @@ export default class GlobalHeader extends PageObject {
84
97
  return $('button*=Skip');
85
98
  }
86
99
 
100
+ static async getSearchToggleInput() {
101
+ return $('[data-testid="ds-globalheader-searchtoggle-textinput"]');
102
+ }
103
+
104
+ static async getSearchToggleSpinbutton() {
105
+ return $('[data-testid="ds-globalheader-searchtoggle-spinbutton-text"]');
106
+ }
107
+
108
+ // Opens the search toggle, runs a query, and focuses the populated results spinbutton
109
+ // so result navigation can be exercised. Waits for results to load before returning.
110
+ static async openAndPopulateSearchToggle(searchText = 'Labor') {
111
+ const toggleSearch = await GlobalHeader.getGHToolbarItem(0);
112
+ await toggleSearch.click();
113
+ const searchInput = await GlobalHeader.getSearchToggleInput();
114
+ await searchInput.click();
115
+ await type(searchText);
116
+ const spinButton = await GlobalHeader.getSearchToggleSpinbutton();
117
+ await browser.waitUntil(async () => (await spinButton.getText()) !== 'n/a', {
118
+ timeout: 3000,
119
+ timeoutMsg: 'search results did not populate after typing',
120
+ });
121
+ await spinButton.click();
122
+ }
123
+
124
+ // PUI-18647 selectors
125
+
126
+ // Every element the stories wire to data-public="true". The assertions read this collection rather
127
+ // than probing one testid at a time: the contract under test is "the whole surface is reachable",
128
+ // so a slot silently dropping out has to fail the count, not slip through an unasserted gap.
129
+ static async getPublicNodes() {
130
+ return $$('[data-public="true"]');
131
+ }
132
+
133
+ static async getPublicNodeTestIds() {
134
+ const nodes = await GlobalHeader.getPublicNodes();
135
+ return Promise.all(Array.from({ length: nodes.length }, (_, index) => nodes[index].getAttribute('data-testid')));
136
+ }
137
+
138
+ // The stories render "Yes" here if any element in the page carries a type="ds-*" attribute. The
139
+ // toolbar `type` discriminator is internal routing and must never reach the DOM — `type` is a
140
+ // reserved HTML attribute.
141
+ static async getDsTypedItemExistFlag() {
142
+ return $('[data-testid="pui18647-ds-typed-item-exist"]');
143
+ }
144
+
145
+ static async getClickCount() {
146
+ return $('[data-testid="pui18647-click-count"]');
147
+ }
148
+
149
+ // A custom TriggerComponent handed to the app-picker item through componentProps. Its presence is
150
+ // what proves componentProps reaches DSAppPicker at all: it replaces the built-in trigger, so
151
+ // there is no `gh-toolbar-item` button in that story.
152
+ static async getAppPickerCustomTrigger() {
153
+ return $('[data-testid="pui18647-gh-apppicker-trigger-component"]');
154
+ }
155
+
156
+ // The popup-menu item's own root. Before PUI-18647 this element was an unstyled wrapper with no
157
+ // slot and no data-testid, so the item as a whole had no injection point.
158
+ static async getPopupMenuContainer() {
159
+ return $('[data-testid="ds-globalheader-menubar-item-popupmenu-container"]');
160
+ }
161
+
162
+ static async getPopupMenuItemButtons() {
163
+ return $$('[data-testid="ds-global-header-menubar-item-popupmenu-item-button"]');
164
+ }
165
+
166
+ static async getPopupMenuItemButtonByIndex(index = 0) {
167
+ return getElementByIndex(GlobalHeader.getPopupMenuItemButtons, index);
168
+ }
169
+
170
+ // The search-toggle item's root container. Item-level global attributes land HERE for this item
171
+ // type, not on the trigger button as with the sibling types.
172
+ static async getSearchToggleContainer() {
173
+ return $('[data-testid="ds-globalheader-menubar-item-searchtoggle-container"]');
174
+ }
175
+
176
+ static async getSearchTogglePrevButton() {
177
+ return $('[data-testid="ds-globalheader-searchtoggle-spinbutton-prev"]');
178
+ }
179
+
180
+ static async getSearchToggleNextButton() {
181
+ return $('[data-testid="ds-globalheader-searchtoggle-spinbutton-next"]');
182
+ }
183
+
184
+ // A neutral, non-focusable target outside any open overlay, used to assert that dismissing by
185
+ // pointer leaves focus where the click put it instead of yanking it back to the trigger.
186
+ // Anchored on a data-testid rather than on a tag: $('h1') matches Storybook's own hidden
187
+ // "No Preview" heading first, which is not clickable and is not part of the story at all.
188
+ static async getOutsideClickTarget() {
189
+ return GlobalHeader.getDsTypedItemExistFlag();
190
+ }
191
+
192
+ static async getSearchableRowByIndex(index = 0) {
193
+ return $(`[data-testid="pui18647-row-${index}"]`);
194
+ }
195
+
196
+ // The stories highlight the current result with an inline khaki background, so the selected row is
197
+ // read off the computed style rather than a semantic attribute — there is no semantic one to read.
198
+ // Matched on the rgb channels only: browsers disagree on whether to emit `rgb(...)` or `rgba(...,1)`
199
+ // and on internal spacing, and none of that is what the assertion is about.
200
+ static async isRowHighlighted(row) {
201
+ const { value } = await row.getCSSProperty('background-color');
202
+ return String(value).replace(/\s/g, '').includes('240,230,140');
203
+ }
204
+
87
205
  // Slots
88
206
 
89
207
  static async getGHBreadcrumbChevronlotByIndex(index = 0) {
@@ -0,0 +1,113 @@
1
+ import { Key } from 'webdriverio';
2
+ import GlobalHeaderCO from '../GlobalHeaderCO';
3
+ import DSAppPickerCO from '../../ds-apppicker/DSAppPickerCO';
4
+
5
+ // Tests for the fix in PUI-18647. Only a hand-maintained subset of props reached the out-of-the-box
6
+ // GlobalHeader -> DSAppPicker item; the rest were silently dropped, so the item could not customise
7
+ // the picker's slots at all. The reported symptom was `dsApppickerChip={{ 'data-public': true }}`
8
+ // never arriving, leaving LogRocket masking the app icons and labels (blocks ENCW-136789).
9
+ //
10
+ // The hand-off is now a full contract passthrough, which this spec proves along three channels:
11
+ // 1. the nine DSAppPicker slot props,
12
+ // 2. non-slot members of the same contract — TriggerComponent, onOpen/onClose, id,
13
+ // 3. GlobalHeader's own slots, which had to keep working across the refactor.
14
+ //
15
+ // Two a11y changes ride along and are pinned here because QA selectors depend on them: the trigger's
16
+ // aria-haspopup is now "dialog" rather than "true", and it no longer carries aria-expanded (a dialog
17
+ // announces its open state by being present). Open state is therefore asserted via the panel, never
18
+ // via the attribute.
19
+ //
20
+ // Chrome only: DOM attributes plus programmatic focus landings, identical in every engine. The
21
+ // `|| 'Chrome'` arm is mandatory (BrowserStack capitalises browserName; a lowercase-only guard
22
+ // registers zero tests and still exits 0).
23
+ if (
24
+ (!browser.capabilities['ice:options'].isPhone &&
25
+ !browser.capabilities['ice:options'].isTablet &&
26
+ browser.capabilities.browserName === 'chrome') ||
27
+ browser.capabilities.browserName === 'Chrome'
28
+ ) {
29
+ describe('PUI-19015 - GlobalHeader:: app-picker componentProps contract passthrough - Func', () => {
30
+ before('loading page', async () => {
31
+ const errorOnGo = await GlobalHeaderCO.appPickerPassthroughURL.go();
32
+ if (errorOnGo) throw errorOnGo;
33
+ });
34
+
35
+ it('01: should render the custom trigger handed through componentProps', async () => {
36
+ const trigger = await GlobalHeaderCO.getAppPickerCustomTrigger();
37
+ await trigger.waitForDisplayed();
38
+ await expect(trigger).toHaveText('Apps');
39
+
40
+ // componentProps.id reaches DSAppPicker and namespaces the generated trigger id.
41
+ await expect(await trigger.getAttribute('id')).toBe('pui18647-gh-apppicker-dialog-trigger-btn');
42
+
43
+ await expect(trigger).toHaveAttribute('aria-haspopup', 'dialog');
44
+ // Absent by design — asserting the panel is present is the supported way to read open state.
45
+ await expect(await trigger.getAttribute('aria-expanded')).toBe(null);
46
+
47
+ const dsTypedFlag = await GlobalHeaderCO.getDsTypedItemExistFlag();
48
+ await expect(dsTypedFlag).toHaveText('No');
49
+ });
50
+
51
+ it("02: should keep forwarding GlobalHeader's own slots while the picker is closed", async () => {
52
+ const publicTestIds = await GlobalHeaderCO.getPublicNodeTestIds();
53
+ await expect(publicTestIds).toEqual([
54
+ 'ds-global-header',
55
+ 'ds-global-header-logo-container',
56
+ 'ds-global-header-menubar-container',
57
+ 'ds-global-header-menubar-list',
58
+ 'ds-global-header-menubar-item',
59
+ ]);
60
+ });
61
+
62
+ it('03: should forward every app-picker slot prop and the onOpen callback', async () => {
63
+ await (await GlobalHeaderCO.getAppPickerCustomTrigger()).click();
64
+ await (await DSAppPickerCO.getAppPickerRoot()).waitForDisplayed();
65
+
66
+ // The story's onOpen re-scans the document, so the table only grows if that callback arrived
67
+ // too — the count below is simultaneously the slot assertion and the onOpen assertion.
68
+ const publicTestIds = await GlobalHeaderCO.getPublicNodeTestIds();
69
+ const countOf = (testId) => publicTestIds.filter((id) => id === testId).length;
70
+
71
+ // Three apps, two custom apps, one separator between the two sections.
72
+ await expect(countOf('ds-apppicker-root')).toBe(1);
73
+ await expect(countOf('ds-apppicker-group')).toBe(2);
74
+ await expect(countOf('ds-apppicker-row')).toBe(3);
75
+ await expect(countOf('ds-apppicker-title')).toBe(2);
76
+ await expect(countOf('ds-apppicker-item')).toBe(5);
77
+ await expect(countOf('ds-apppicker-separator')).toBe(1);
78
+ await expect(countOf('ds-apppicker-floating-wrapper')).toBe(1);
79
+ // dsApppickerChip — the prop the defect was raised about. One tagged node per app.
80
+ await expect(countOf('app-picker__chip')).toBe(5);
81
+
82
+ // The panel is a dialog named by the custom trigger, so the widened contract did not cost the
83
+ // picker its ARIA pattern.
84
+ const dialog = await DSAppPickerCO.getFloatingWrapper();
85
+ await expect(dialog).toHaveAttribute('role', 'dialog');
86
+ await expect(await dialog.getAttribute('aria-labelledby')).toBe(
87
+ await (await GlobalHeaderCO.getAppPickerCustomTrigger()).getAttribute('id'),
88
+ );
89
+
90
+ const dsTypedFlag = await GlobalHeaderCO.getDsTypedItemExistFlag();
91
+ await expect(dsTypedFlag).toHaveText('No');
92
+ });
93
+
94
+ it('04: should open onto the selected app with ArrowDown and ArrowUp', async () => {
95
+ // The toolbar is a menubar, so it opts the picker into openAndFocusOnArrowKeys. 'Reports' is
96
+ // the third app, so "landed on the selected app" cannot be read as "landed on the first app".
97
+ await browser.keys(Key.Escape);
98
+ const trigger = await GlobalHeaderCO.getAppPickerCustomTrigger();
99
+ await expect(trigger).toBeFocused();
100
+
101
+ await browser.keys(Key.ArrowDown);
102
+ await (await DSAppPickerCO.getAppPickerRoot()).waitForDisplayed();
103
+ await expect(await DSAppPickerCO.getChipByLabel('Reports')).toBeFocused();
104
+
105
+ // ArrowUp opens nothing before this change; it now lands on the same selected app.
106
+ await browser.keys(Key.Escape);
107
+ await expect(trigger).toBeFocused();
108
+ await browser.keys(Key.ArrowUp);
109
+ await (await DSAppPickerCO.getAppPickerRoot()).waitForDisplayed();
110
+ await expect(await DSAppPickerCO.getChipByLabel('Reports')).toBeFocused();
111
+ });
112
+ });
113
+ }
@@ -0,0 +1,63 @@
1
+ import { Key } from 'webdriverio';
2
+ import GlobalHeaderCO from '../GlobalHeaderCO';
3
+
4
+ // Tests for the popup-menu focus fixes shipped with PUI-18647:
5
+ //
6
+ // - (NEW) ArrowDown on the trigger opens onto the FIRST item; ArrowUp opens onto the LAST. ArrowUp
7
+ // did not open the menu at all before.
8
+ // - (FIX) Clicking outside no longer drags focus back to the trigger. It stays where the click put
9
+ // it, so focus is no longer lost arbitrarily on a pointer dismissal.
10
+ // - (unchanged) Escape still closes and returns focus to the trigger.
11
+ //
12
+ // Full browser matrix on purpose: pointer-driven dismissal and where focus settles afterwards is
13
+ // precisely the behaviour engines implement differently.
14
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
15
+ describe('PUI-19018 - GlobalHeader:: popup-menu open and focus return paths - Func', () => {
16
+ before('loading page', async () => {
17
+ const errorOnGo = await GlobalHeaderCO.popupMenuSlotSurfaceURL.go();
18
+ if (errorOnGo) throw errorOnGo;
19
+ });
20
+
21
+ it('01: should open onto the first menu item with ArrowDown', async () => {
22
+ // Focused programmatically rather than by clicking: a click would open the menu, and closing it
23
+ // again to get back to "closed trigger, focused" makes the starting state depend on where a
24
+ // dismissal leaves focus, which varies by engine. The ArrowDown behaviour is the case here.
25
+ const trigger = await GlobalHeaderCO.getGHToolbarItem(0);
26
+ await trigger.waitForDisplayed();
27
+ await browser.execute((el) => el.focus(), trigger);
28
+ await expect(trigger).toBeFocused();
29
+
30
+ await browser.keys(Key.ArrowDown);
31
+ await (await GlobalHeaderCO.getPopupContent()).waitForDisplayed();
32
+
33
+ const firstItem = await GlobalHeaderCO.getPopupMenuItemButtonByIndex(0);
34
+ await expect(firstItem).toBeFocused();
35
+ await expect(firstItem).toHaveText('Preferences');
36
+ });
37
+
38
+ it('02: should close and return focus to the trigger on Escape', async () => {
39
+ await browser.keys(Key.Escape);
40
+
41
+ await expect(await GlobalHeaderCO.getPopupContent()).not.toBeDisplayed();
42
+ await expect(await GlobalHeaderCO.getGHToolbarItem(0)).toBeFocused();
43
+ });
44
+
45
+ it('03: should open onto the last menu item with ArrowUp', async () => {
46
+ await browser.keys(Key.ArrowUp);
47
+ await (await GlobalHeaderCO.getPopupContent()).waitForDisplayed();
48
+
49
+ const lastItem = await GlobalHeaderCO.getPopupMenuItemButtonByIndex(1);
50
+ await expect(lastItem).toBeFocused();
51
+ await expect(lastItem).toHaveText('Sign out');
52
+ });
53
+
54
+ it('04: should close without returning focus to the trigger on an outside click', async () => {
55
+ await (await GlobalHeaderCO.getOutsideClickTarget()).click();
56
+
57
+ await expect(await GlobalHeaderCO.getPopupContent()).not.toBeDisplayed();
58
+ // The heading is not focusable, so focus settles on the body. The point is only that it did
59
+ // NOT get pulled back to the trigger, which is what used to happen.
60
+ await expect(await GlobalHeaderCO.getGHToolbarItem(0)).not.toBeFocused();
61
+ });
62
+ });
63
+ }
@@ -0,0 +1,70 @@
1
+ import { Key } from 'webdriverio';
2
+ import GlobalHeaderCO from '../GlobalHeaderCO';
3
+
4
+ // Tests for the new slot introduced in PUI-18647. The ds-popup-menu item's outermost element used to
5
+ // be an unstyled wrapper with no slot and no data-testid, so the item as a whole had no injection
6
+ // point — nowhere to reach it, nowhere for xstyled props to land. It is now
7
+ // `dsGlobalheaderMenubarItemPopupmenuContainer` / `ds-globalheader-menubar-item-popupmenu-container`.
8
+ //
9
+ // The change is additive: every pre-existing slot name and data-testid in this subtree is unchanged
10
+ // and sits in the same DOM position, so no existing selector moves. Both the new and the pre-existing
11
+ // slots are asserted here so a regression in either fails.
12
+ //
13
+ // Chrome only — pure DOM attribute assertions. The `|| 'Chrome'` arm is mandatory (BrowserStack
14
+ // capitalises browserName; a lowercase-only guard silently registers zero tests and still exits 0).
15
+ if (
16
+ (!browser.capabilities['ice:options'].isPhone &&
17
+ !browser.capabilities['ice:options'].isTablet &&
18
+ browser.capabilities.browserName === 'chrome') ||
19
+ browser.capabilities.browserName === 'Chrome'
20
+ ) {
21
+ describe('PUI-19017 - GlobalHeader:: popup-menu item slot surface - Func', () => {
22
+ before('loading page', async () => {
23
+ const errorOnGo = await GlobalHeaderCO.popupMenuSlotSurfaceURL.go();
24
+ if (errorOnGo) throw errorOnGo;
25
+ });
26
+
27
+ it('01: should expose the new item container slot while the menu is closed', async () => {
28
+ const container = await GlobalHeaderCO.getPopupMenuContainer();
29
+ await container.waitForDisplayed();
30
+ await expect(container).toHaveAttribute('data-dimsum-slot', 'dsGlobalheaderMenubarItemPopupmenuContainer');
31
+
32
+ // Closed, the reachable surface is the item container plus the trigger button. Item-level
33
+ // attributes land on the TRIGGER for this item type, not on the container.
34
+ const publicTestIds = await GlobalHeaderCO.getPublicNodeTestIds();
35
+ await expect(publicTestIds).toEqual(['ds-globalheader-menubar-item-popupmenu-container', 'gh-toolbar-item']);
36
+
37
+ const dsTypedFlag = await GlobalHeaderCO.getDsTypedItemExistFlag();
38
+ await expect(dsTypedFlag).toHaveText('No');
39
+ });
40
+
41
+ it('02: should expose every popup-menu slot once the menu is open', async () => {
42
+ const trigger = await GlobalHeaderCO.getGHToolbarItem(0);
43
+ await trigger.click();
44
+ await (await GlobalHeaderCO.getPopupContent()).waitForDisplayed();
45
+
46
+ // Two options and one separator, so the per-item slots appear twice. The exact testid spelling
47
+ // is asserted rather than normalised: the container and the item label use `ds-globalheader-`
48
+ // while their siblings use `ds-global-header-`, and that inconsistency is what consumers'
49
+ // selectors have to match.
50
+ const publicTestIds = await GlobalHeaderCO.getPublicNodeTestIds();
51
+ await expect(publicTestIds).toEqual([
52
+ 'ds-globalheader-menubar-item-popupmenu-container',
53
+ 'gh-toolbar-item',
54
+ 'ds-global-header-menubar-item-popupmenu-list',
55
+ 'ds-global-header-menubar-item-popupmenu-item',
56
+ 'ds-global-header-menubar-item-popupmenu-item-button',
57
+ 'ds-globalheader-menubar-item-popupmenu-item-label',
58
+ 'ds-global-header-menubar-item-popupmenu-separator',
59
+ 'ds-global-header-menubar-item-popupmenu-item',
60
+ 'ds-global-header-menubar-item-popupmenu-item-button',
61
+ 'ds-globalheader-menubar-item-popupmenu-item-label',
62
+ ]);
63
+
64
+ const dsTypedFlag = await GlobalHeaderCO.getDsTypedItemExistFlag();
65
+ await expect(dsTypedFlag).toHaveText('No');
66
+
67
+ await browser.keys(Key.Escape);
68
+ });
69
+ });
70
+ }
@@ -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
+ }