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.
- package/CHANGELOG.md +1079 -721
- package/ds-accordion/DSAccordion.visual.spec.js +6 -0
- package/ds-accordion/DSAccordionCO.js +15 -3
- package/ds-accordion/QA_NOTES.md +105 -0
- package/ds-accordion/controlled/DSAccordion.controlled.func.spec.js +23 -0
- package/ds-accordion/header-structure/DSAccordion.header-structure.func.spec.js +65 -0
- package/ds-accordion/input-inside/DSAccordion.input-inside.func.spec.js +19 -0
- package/ds-apppicker/DSAppPickerCO.js +101 -3
- package/ds-apppicker/aria-pattern/DSAppPicker.aria-pattern.func.spec.js +100 -0
- package/ds-apppicker/basic/DSAppPicker.basic.keyboard-nav.func.spec.js +18 -7
- package/ds-apppicker/closeAfterSelection/DSAppPicker.closeAfterSelection.func.spec.js +1 -1
- package/ds-apppicker/custom-trigger-focus/DSAppPicker.custom-trigger-focus.func.spec.js +82 -0
- package/ds-apppicker/label-expansion-dismissal/DSAppPicker.label-expansion-dismissal.visual.spec.js +108 -0
- package/ds-apppicker/reflow/DSAppPicker.reflow.func.spec.js +32 -0
- package/ds-apppicker/reflow/DSAppPicker.reflow.visual.spec.js +5 -6
- package/ds-apppicker/truncation/DSAppPicker.truncation.visual.spec.js +5 -9
- package/ds-autocomplete/DSAutocomplete.visual.spec.js +34 -0
- package/ds-autocomplete/DSAutocompleteCO.js +36 -1
- package/ds-autocomplete/aria-busy-loading/DSAutocomplete.aria-busy-loading.axe-core.func.spec.js +50 -0
- package/ds-autocomplete/aria-busy-loading/DSAutocomplete.aria-busy-loading.func.spec.js +122 -0
- package/ds-autocomplete/aria-busy-loading/DSAutocomplete.aria-busy-loading.visual.spec.js +48 -0
- package/ds-autocomplete/slots/DSAutocomplete.slots.func.spec.js +6 -1
- package/ds-banner/DSBanner.text-resize.visual.spec.js +5 -2
- package/ds-banner/DSBannerCO.js +4 -0
- package/ds-button-v3/DSButtonV3.aria-disabled-attribute.func.spec.js +33 -0
- package/ds-button-v3/DSButtonV3CO.js +10 -0
- package/ds-button-v3/theme-font/DSButtonV3.theme-font.func.spec.js +30 -0
- package/ds-card/DSCard.cardv2_v1.func.spec.js +54 -0
- package/ds-card/DSCard.cardv2_v1.visual.spec.js +29 -0
- package/ds-card/DSCardCO.js +50 -0
- package/ds-card/detail-slots/DSCard.detail-slots.axe-core.func.spec.js +29 -0
- package/ds-card/detail-slots/DSCard.detail-slots.func.spec.js +72 -0
- package/ds-card/detail-slots/DSCard.detail-slots.visual.spec.js +19 -0
- package/ds-card-v3/DSCardV3CO.js +93 -1
- package/ds-card-v3/accordion/DSCardV3.accordion-aria-structure.func.spec.js +41 -0
- package/ds-card-v3/accordion/DSCardV3.accordion-aria.keyboard.func.spec.js +49 -0
- package/ds-card-v3/accordion/DSCardV3.accordion.axe-core.func.spec.js +28 -0
- package/ds-card-v3/accordion/DSCardV3.accordion.visual.spec.js +4 -6
- package/ds-card-v3/action/DSCardV3.action.axe-core.func.spec.js +24 -0
- package/ds-card-v3/action/DSCardV3.action.func.spec.js +53 -0
- package/ds-card-v3/action/DSCardV3.action.visual.spec.js +28 -0
- package/ds-card-v3/drag-n-drop/DSCardV3.DnD.axe-core.func.spec.js +42 -0
- package/ds-card-v3/drag-n-drop/DSCardV3.DnD.func.spec.js +129 -0
- package/ds-card-v3/drag-n-drop/DSCardV3.DnD.reorder.func.spec.js +73 -0
- package/ds-card-v3/drag-n-drop/DSCardV3.DnD.visual.spec.js +5 -12
- package/ds-card-v3/global-attributes/DSCardV3.global-attributes.axe-core.func.spec.js +33 -0
- package/ds-card-v3/global-attributes/DSCardV3.global-attributes.visual.spec.js +20 -0
- package/ds-card-v3/multi-select/DSCardV3.multi-select.aria-grouping.func.spec.js +24 -0
- package/ds-card-v3/multi-select/DSCardV3.multiselect.axe-core.func.spec.js +47 -0
- package/ds-card-v3/multi-select/DSCardV3.multiselect.keyboard.func.spec.js +65 -0
- package/ds-card-v3/multi-select/DSCardV3.multiselect.visual.spec.js +17 -0
- package/ds-card-v3/multiple-action/DSCardV3.multiple-action.axe-core.func.spec.js +35 -0
- package/ds-card-v3/multiple-action/DSCardV3.multiple-action.func.spec.js +53 -0
- package/ds-card-v3/multiple-action/DSCardV3.multiple-action.visual.spec.js +18 -0
- package/ds-card-v3/multiple-control/DSCardV3.multi-control.axe-core.func.spec.js +34 -0
- package/ds-card-v3/multiple-control/DSCardV3.multi-control.func.spec.js +26 -0
- package/ds-card-v3/multiple-control/DSCardV3.multi-control.visual.spec.js +29 -0
- package/ds-card-v3/no-action/DSCardV3.no-action.axe-core.func.spec.js +22 -0
- package/ds-card-v3/no-action/DSCardV3.no-action.func.spec.js +23 -0
- package/ds-card-v3/no-action/DSCardV3.no-action.visual.spec.js +15 -0
- package/ds-card-v3/notification-badges/DSCardV3.notification-badges.axe-core.func.spec.js +33 -0
- package/ds-card-v3/notification-badges/DSCardV3.notification-badges.func.spec.js +19 -0
- package/ds-card-v3/notification-badges/DSCardV3.notification-badges.visual.spec.js +28 -0
- package/ds-card-v3/reflow/DSCardV3.reflow.axe-core.func.spec.js +28 -0
- package/ds-card-v3/reflow/DSCardV3.reflow.func.spec.js +36 -0
- package/ds-card-v3/reflow/DSCardV3.reflow.visual.spec.js +3 -2
- package/ds-card-v3/single-select/DSCardV3.single-select.aria-grouping.func.spec.js +24 -0
- package/ds-card-v3/single-select/DSCardV3.single-select.axe-core.func.spec.js +37 -0
- package/ds-card-v3/single-select/DSCardV3.single-select.visual.spec.js +1 -2
- package/ds-card-v3/slots/DSCardV3.slots.visual.spec.js +1 -2
- package/ds-card-v3/variant-accented/DSCardV3.variant-accented.axe-core.func.spec.js +45 -0
- package/ds-card-v3/variant-accented/DSCardV3.variant-accented.func.spec.js +28 -0
- package/ds-card-v3/variant-accented/DSCardV3.variant-accented.visual.spec.js +35 -0
- package/ds-card-v3/variant-accented-disabled/DSCardV3.variant-accented-disabled.axe-core.func.spec.js +35 -0
- package/ds-card-v3/variant-accented-disabled/DSCardV3.variant-accented-disabled.func.spec.js +53 -0
- package/ds-card-v3/variant-accented-disabled/DSCardV3.variant-accented-disabled.visual.spec.js +28 -0
- package/ds-card-v3/variant-disabled/DSCardV3.variant-disabled.axe-core.func.spec.js +22 -0
- package/ds-card-v3/variant-disabled/DSCardV3.variant-disabled.func.spec.js +61 -0
- package/ds-card-v3/variant-disabled/DSCardV3.variant-disabled.visual.spec.js +20 -0
- package/ds-card-v3/variant-disabled/DSCardV3.variantDisabled-non-interactive.func.spec.js +25 -0
- package/ds-chat/DSChat.axe-core.func.spec.js +2 -2
- package/ds-chat/DSChat.visual.spec.js +4 -4
- package/ds-chat/DSChatCO.js +18 -24
- package/ds-chat/bubbles/slots/DSChatBubble.slots.axe-core.func.spec.js +24 -0
- package/ds-chat/bubbles/slots/DSChatBubble.slots.func.spec.js +49 -0
- package/ds-chat/bubbles/slots/DSChatBubble.slots.visual.spec.js +25 -0
- package/ds-chat/card/slots/DSChatCard.slots.axe-core.func.spec.js +24 -0
- package/ds-chat/card/slots/DSChatCard.slots.func.spec.js +47 -0
- package/ds-chat/card/slots/DSChatCard.slots.visual.spec.js +18 -0
- package/ds-chat/card/truncated-text/DSChatCard.truncated-text.func.spec.js +32 -0
- package/ds-chat/card/truncated-text/DSChatCard.truncated-text.visual.spec.js +26 -0
- package/ds-chat/card/with-notification-badges/DSChatCard.with-notification-badges.axe-core.func.spec.js +23 -0
- package/ds-chat/card/with-notification-badges/DSChatCard.with-notification-badges.visual.spec.js +17 -0
- package/ds-chat/components/BubbleCO.js +46 -3
- package/ds-chat/components/CardCO.js +75 -0
- package/ds-chat/components/ComposerCO.js +6 -6
- package/ds-chat/components/FloatingButtonCO.js +5 -3
- package/ds-chat/components/HeaderCO.js +2 -2
- package/ds-chat/components/TileCO.js +82 -0
- package/ds-chat/components/index.js +3 -2
- package/ds-chat/floatingbutton/DSChat-floating-button.visual.spec.js +1 -1
- package/ds-chat/loadmore/DSChat-loadmore.func.spec.js +1 -1
- package/{ds-chat-tile → ds-chat/tile}/DSChat-tile.axe-core.func.spec.js +2 -2
- package/{ds-chat-tile → ds-chat/tile}/DSChat-tile.func.spec.js +1 -1
- package/{ds-chat-tile → ds-chat/tile}/DSChat-tile.visual.spec.js +2 -2
- package/{ds-chat-tile → ds-chat/tile}/aria-disabled/DSChat-tile.aria-disabled.axe-core.func.spec.js +2 -2
- package/{ds-chat-tile → ds-chat/tile}/aria-disabled/DSChat-tile.aria-disabled.visual.spec.js +1 -1
- package/ds-chat/tile/slots/DSChatTile.slots.func.spec.js +53 -0
- package/ds-chat/tile/slots/DSChatTile.slots.visual.spec.js +18 -0
- package/ds-chip/label-expansion-dismissal/DSChip.label-expansion-dismissal.visual.spec.js +84 -0
- package/ds-controlled-form/ds-combobox/creatable/DSCombobox.creatable-tooltip.func.spec.js +47 -0
- package/ds-controlled-form/ds-combobox/creatable/DSCombobox.creatable.visual.spec.js +12 -21
- package/ds-controlled-form/ds-combobox/disabled/DSCombobox.disabled.visual.spec.js +6 -1
- package/ds-controlled-form/ds-controlled-checkbox/Basic/DSControlledCheckbox.axe-core.basic.func.spec.js +4 -4
- package/ds-controlled-form/ds-controlled-checkbox/Basic/DSControlledCheckbox.basic.visual.spec.js +56 -0
- package/ds-controlled-form/ds-controlled-checkbox/DSControlledCheckboxCO.js +54 -1
- package/ds-controlled-form/ds-controlled-checkbox/Disabled/DSControlledCheckbox.axe-core.disabled.func.spec.js +1 -1
- package/ds-controlled-form/ds-controlled-checkbox/Disabled/DSControlledCheckbox.disabled.visual.spec.js +1 -1
- package/ds-controlled-form/ds-controlled-checkbox/HasError/DSControlledCheckbox.axe-core.hasError.func.spec.js +4 -4
- package/ds-controlled-form/ds-controlled-checkbox/HasError/DSControlledCheckbox.has-error.visual.spec.js +71 -1
- package/ds-controlled-form/ds-controlled-checkbox/Mixed/DSControlledCheckbox.axe-core.mixed.func.spec.js +4 -4
- package/ds-controlled-form/ds-controlled-checkbox/Mixed/DSControlledCheckbox.mixed.visual.spec.js +1 -1
- package/ds-controlled-form/ds-controlled-checkbox/ReadOnly/DSControlledCheckbox.axe-core.read-only.func.spec.js +3 -3
- package/ds-controlled-form/ds-controlled-checkbox/ReadOnly/DSControlledCheckbox.read-only.visual.spec.js +1 -1
- package/ds-controlled-form/ds-controlled-checkbox/WithTooltip/DSControlledCheckbox.axe-core.with-tooltip.func.spec.js +1 -1
- package/ds-controlled-form/ds-controlled-checkbox/WithTooltip/DSControlledCheckbox.with-tooltip.visual.spec.js +1 -3
- package/ds-controlled-form/ds-controlled-checkbox/WrapLabel/DSControlledCheckbox.axe-core.wrap-label.func.spec.js +1 -1
- package/ds-controlled-form/ds-controlled-checkbox/WrapLabel/DSControlledCheckbox.wrap-label.visual.spec.js +1 -1
- package/ds-controlled-form/ds-controlled-checkbox/aria-disabled/DSControlledCheckbox.aria-disabled.visual.spec.js +2 -6
- package/ds-controlled-form/ds-controlled-checkbox/aria-disabled/DSControlledCheckbox.axe-core.aria-disabled.func.spec.js +1 -1
- package/ds-controlled-form/ds-controlled-checkbox/slots/DSControlledCheckbox.slots.func.spec.js +78 -0
- package/ds-controlled-form/ds-controlled-checkbox/theme-font/DSControlledCheckbox.theme-font.func.spec.js +30 -0
- package/ds-controlled-form/ds-controlled-checkbox-group/DSControlledCheckboxGroup.axe-core.func.spec.js +4 -4
- package/ds-controlled-form/ds-controlled-checkbox-group/DSControlledCheckboxGroup.visual.spec.js +1 -1
- package/ds-controlled-form/ds-controlled-radio/DSControlledRadioCO.js +50 -1
- package/ds-controlled-form/ds-controlled-radio/aria-disabled/DSControlledRadio.aria-disabled.axe-core.func.spec.js +16 -2
- package/ds-controlled-form/ds-controlled-radio/aria-disabled/DSControlledRadio.aria-disabled.func.spec.js +37 -0
- package/ds-controlled-form/ds-controlled-radio/slots/DSControlledRadio.slots.func.spec.js +78 -0
- package/ds-controlled-form/ds-controlled-radio/theme-font/DSControlledRadio.theme-font.func.spec.js +30 -0
- package/ds-controlled-form/react-hook-form/ReactHook.func.spec.js +1 -3
- package/ds-data-table-async/DSDataTableCO.js +187 -10
- package/ds-data-table-async/basic/DSDataTable.basic.visual.spec.js +1 -1
- package/ds-data-table-async/components/FilterBarCO.js +7 -0
- package/ds-data-table-async/components/FiltersCO.js +1 -1
- package/ds-data-table-async/components/HeaderCO.js +37 -1
- package/ds-data-table-async/dnd/DSDataTable.dnd-keyboard-scroll.func.spec.js +51 -0
- package/ds-data-table-async/filter-menu-close/DSDataTable.filter-menu-close.func.spec.js +77 -0
- package/ds-data-table-async/filter-popover-boundary/DSDataTable.filter-popover-boundary.func.spec.js +98 -0
- package/ds-data-table-async/filters/DSDataTable.filters-creatable-active-descendant.func.spec.js +51 -0
- package/ds-data-table-async/filters/DSDataTable.filters-creatable.func.spec.js +55 -0
- package/ds-data-table-async/filters/DSDataTable.filters.axe-core.func.spec.js +11 -9
- package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-creatablemultiselect.keyboard.func.spec.js +2 -2
- package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-creatableselect.keyboard.func.spec.js +2 -2
- package/ds-data-table-async/filtersV2/DSDataTable.filtersV2.axe-core.func.spec.js +45 -29
- package/ds-data-table-async/filtersV2/pill-label/DSDataTable.pillLabel.axe-core.func.spec.js +23 -0
- package/ds-data-table-async/filtersV2/pill-label/DSDataTable.pillLabel.func.spec.js +50 -0
- package/ds-data-table-async/filtersV2/pill-label/DSDataTable.pillLabel.visual.spec.js +21 -0
- package/ds-data-table-async/header-affordances/DSDataTable.header-affordances.func.spec.js +92 -0
- package/ds-data-table-async/helpers/getInputSelection.js +6 -0
- package/ds-data-table-async/helpers/index.js +1 -0
- package/ds-data-table-async/keyboard-scroll/DSDataTable.keyboard-scroll.func.spec.js +39 -0
- package/ds-data-table-async/menubutton/DSDataTable.MenuButton.keyboard.func.spec.js +8 -7
- package/ds-data-table-async/menubutton/DSDataTable.MenuButton.mouse.func.spec.js +6 -7
- package/ds-data-table-async/pagination/DSDataTable.pagination.func.spec.js +3 -2
- package/ds-data-table-async/resizable/DSDataTable.resize-min-clamp.func.spec.js +72 -0
- package/ds-data-table-async/resizable/DSDataTable.resizerA11y.axe-core.func.spec.js +42 -0
- package/ds-data-table-async/resizable/DSDataTable.resizerA11y.func.spec.js +98 -0
- package/ds-data-table-async/textwrapping/DSDataTable.header-wrap-alignment.axe-core.func.spec.js +23 -0
- package/ds-data-table-async/textwrapping/DSDataTable.header-wrap-alignment.visual.spec.js +106 -0
- package/ds-data-table-async/textwrapping/DSDataTable.text-wrap-toolbar.visual.spec.js +27 -0
- package/ds-data-table-async/toggle-cell-focus/DSDataTable.toggle-cell-enter-focus.func.spec.js +31 -0
- package/ds-data-table-async/vissibility/DSDataTable.vissibility.visual.spec.js +2 -0
- package/ds-dataviz/DSDataViz.axis.visual.spec.js +1 -2
- package/ds-dataviz/DSDataViz.ticks.visual.spec.js +1 -2
- package/ds-dataviz/DSDataVizCO.js +2 -0
- package/ds-dataviz/axecore/DSDataViz.axis.axe-core.func.spec.js +1 -1
- package/ds-floating-context/DSFloatingContextCO.js +10 -0
- package/ds-floating-context/placement/DSFloatingContext.placement.visual.spec.js +48 -0
- package/ds-form-combobox-multi/DSComboboxMultiCO.js +36 -9
- package/ds-form-combobox-multi/aria-busy-loading/DSComboboxMulti.aria-busy-loading.axe-core.func.spec.js +55 -0
- package/ds-form-combobox-multi/aria-busy-loading/DSComboboxMulti.aria-busy-loading.func.spec.js +57 -0
- package/ds-form-combobox-multi/aria-disabled/DSComboboxMulti.aria-disabled.visual.spec.js +19 -2
- package/ds-form-combobox-multi/disabled/DSComboboxMulti.disabled.axe-core.func.spec.js +24 -0
- package/ds-form-combobox-multi/disabled/DSComboboxMulti.disabled.mouse.func.spec.js +0 -2
- package/ds-form-combobox-multi/disabled/DSComboboxMulti.disabled.visual.spec.js +22 -0
- package/ds-form-combobox-multi/grouped/DSComboboxMulti.grouped.visual.spec.js +42 -0
- package/ds-form-combobox-multi/inline/DSComboboxMulti.inline.visual.spec.js +21 -0
- package/ds-form-combobox-multi/pills/DSComboboxMulti.pills.func.spec.js +59 -0
- package/ds-form-combobox-multi/pills/DSComboboxMulti.pills.visual.spec.js +39 -0
- package/ds-form-combobox-multi/skeleton/DSComboboxMulti.skeleton.visual.spec.js +25 -0
- package/ds-form-combobox-multi/theme-font/DSComboboxMulti.theme-font.func.spec.js +38 -0
- package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.axe-core.func.spec.js +39 -0
- package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.func.spec.js +39 -0
- package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.visual.spec.js +29 -0
- package/ds-form-combobox-single/DSComboboxSingleCO.js +25 -9
- package/ds-form-combobox-single/aria-busy-loading/DSComboboxSingle.aria-busy-loading.axe-core.func.spec.js +49 -0
- package/ds-form-combobox-single/aria-busy-loading/DSComboboxSingle.aria-busy-loading.func.spec.js +54 -0
- package/ds-form-combobox-single/aria-disabled/DSComboboxSingle.aria-disabled.visual.spec.js +18 -0
- package/ds-form-combobox-single/creatable/DSComboboxSingle.creatable.visual.spec.js +30 -0
- package/ds-form-combobox-single/disabled/DSComboboxSingle.disabled.axe-core.func.spec.js +24 -0
- package/ds-form-combobox-single/disabled/DSComboboxSingle.disabled.mouse.func.spec.js +0 -2
- package/ds-form-combobox-single/disabled/DSComboboxSingle.disabled.visual.spec.js +22 -0
- package/ds-form-combobox-single/grouped/DSComboboxSingle.grouped.visual.spec.js +45 -0
- package/ds-form-combobox-single/inline/DSComboboxSingle.inline.visual.spec.js +23 -0
- package/ds-form-combobox-single/skeleton/DSComboboxSingle.skeleton.visual.spec.js +25 -0
- package/ds-form-combobox-single/theme-font/DSComboboxSingle.theme-font.func.spec.js +34 -0
- package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.axe-core.func.spec.js +39 -0
- package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.func.spec.js +39 -0
- package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.visual.spec.js +29 -0
- package/ds-form-date-range-picker/DateRangePicker.axe-core.spec.js +5 -0
- package/ds-form-date-range-picker/DateRangePicker.functional.spec.js +80 -18
- package/ds-form-date-range-picker/DateRangePickerCO.js +19 -0
- package/ds-form-date-range-picker/date-segment-aria-labels/DateRangePicker.date-segment-aria-labels.func.spec.js +66 -0
- package/ds-form-date-range-picker/grouped-field-error-announcement/DateRangePicker.grouped-field-error-announcement.func.spec.js +59 -0
- package/ds-form-date-range-picker/picker-callbacks/DateRangePicker.picker-callbacks.func.spec.js +36 -0
- package/ds-form-date-time-picker/DSControlledDateTimePickerCO.js +7 -0
- package/ds-form-date-time-picker/date-time-full/DateTimeFull.axe-core.func.spec.js +8 -1
- package/ds-form-date-time-picker/date-time-full/DateTimePicker.DateTimeFull.visual.spec.js +9 -0
- package/ds-form-date-time-picker/partial-date-open-focus/DateTimePicker.partial-date-open-focus.func.spec.js +45 -0
- package/ds-form-native-select/NativeSelect.axe-core.func.spec.js +39 -0
- package/ds-form-native-select/NativeSelect.visual.spec.js +33 -0
- package/ds-form-native-select/NativeSelectCO.js +6 -0
- package/ds-form-native-select/option-selection/NativeSelect.option-selection.func.spec.js +25 -0
- package/ds-form-toggle/DSToggle.func.spec.js +20 -23
- package/ds-form-toggle/DSToggleCO.js +11 -2
- package/ds-global-header/GlobalHeader.announcements.func.spec.js +27 -0
- package/ds-global-header/GlobalHeader.axe-core.func.spec.js +15 -15
- package/ds-global-header/GlobalHeader.func.spec.js +70 -1
- package/ds-global-header/GlobalHeaderCO.js +120 -2
- package/ds-global-header/app-picker-passthrough/GlobalHeader.app-picker-passthrough.func.spec.js +113 -0
- package/ds-global-header/popup-menu-focus/GlobalHeader.popup-menu-focus.func.spec.js +63 -0
- package/ds-global-header/popup-menu-slots/GlobalHeader.popup-menu-slots.func.spec.js +70 -0
- package/ds-global-header/search-toggle-slots/GlobalHeader.search-toggle-slots.func.spec.js +118 -0
- package/ds-global-header/toolbar-item-attributes/GlobalHeader.toolbar-item-attributes.func.spec.js +53 -0
- package/ds-grid/DSGridCO.js +20 -0
- package/ds-grid/layout-mode/DSGrid.layout-mode.func.spec.js +51 -0
- package/ds-grid/layout-mode/DSGrid.layout-mode.visual.spec.js +22 -0
- package/ds-hooks/DSHook.UseFontSizeMedia.visual.spec.js +5 -2
- package/ds-hooks/DSHook.usetree.func.spec.js +3 -2
- package/ds-hooks/DSHookCO.js +56 -23
- package/ds-hooks/useFocusStack/DSHook.useFocusStack.func.spec.js +83 -0
- package/ds-hooks/useFocusTrap/UseFocusTrapCO.js +2 -0
- package/ds-hooks/useFocusTrap/UseFocusTrapToggle.func.spec.js +48 -0
- package/ds-hooks/useMask/Number/UseNumberMask.axe-core.func.spec.js +48 -0
- package/ds-menu-button/DSMenuButtonCO.js +23 -0
- package/ds-menu-button/slots/DSMenuButton.slots.axe-core.func.spec.js +28 -0
- package/ds-menu-button/slots/DSMenuButton.slots.func.spec.js +59 -0
- package/ds-menu-button/slots/DSMenuButton.slots.visual.spec.js +26 -0
- package/ds-modal-slide/ModalSlideCO.js +7 -0
- package/ds-modal-slide/custom-header/ModalSlide.customHeader.focusRing.visual.spec.js +2 -1
- package/ds-modal-slide/heading-level/ModalSlide.headingLevel.axe-core.func.spec.js +25 -0
- package/ds-modal-slide/heading-level/ModalSlide.headingLevel.func.spec.js +25 -0
- package/ds-modal-slide/slots/ModalSlide.slots.func.spec.js +18 -0
- package/ds-notification-badge/DSNotificationBadge.visual.spec.js +17 -20
- package/ds-page-layout/PageLayoutCO.js +4 -4
- package/ds-pills-v2/DSPillsV2CO.js +12 -0
- package/ds-pills-v2/apply-aria-disabled/DSPills.applyAriaDisabled.func.spec.js +53 -0
- package/ds-pills-v2/apply-aria-disabled/DSPills.applyAriaDisabled.visual.spec.js +26 -0
- package/ds-pills-v2/disabled/DSPills.disabled.func.spec.js +53 -0
- package/ds-pills-v2/disabled/DSPills.disabled.visual.spec.js +33 -0
- package/ds-progress-indicator/DSProgressIndicator.axe-core.func.spec.js +2 -0
- package/ds-progress-indicator/DSProgressIndicatorCO.js +1 -1
- package/ds-query-builder/DSQueryBuilder.visual.spec.js +6 -6
- package/ds-shuttle-v2/DSShuttleV2CO.js +15 -1
- package/ds-shuttle-v2/breadcrumb-a11y/DSShuttleV2.breadcrumb-a11y.func.spec.js +43 -0
- package/ds-shuttle-v2/explicit-selection-ui/DSShuttleV2.explicit-selection-ui.func.spec.js +37 -0
- package/ds-shuttle-v2/explicit-selection-ui/DSShuttleV2.explicit-selection-ui.visual.spec.js +30 -0
- package/ds-shuttle-v2/extra/DSShuttleV2.extra.visual.spec.js +8 -3
- package/ds-shuttle-v2/items/DSShuttleV2.items.func.spec.js +4 -2
- package/ds-shuttle-v2/skipped/DSShuttleV2.extra.axe-core.skipped.js +1 -1
- package/ds-shuttle-v2/skipped/DSShuttleV2.filter.axe-core.skipped.js +1 -1
- package/ds-shuttle-v2/skipped/DSShuttleV2.globalcheckbox.axe-core.skipped.js +1 -1
- package/ds-shuttle-v2/skipped/DSShuttleV2.items.axe-core.skipped.js +3 -3
- package/ds-shuttle-v2/skipped/DSShuttleV2.skipped.js +5 -5
- package/ds-slider-v2/DSSliderV2.func.spec.js +36 -25
- package/ds-slider-v2/DSSliderV2CO.js +10 -0
- package/ds-slider-v2/min-range/DSSliderV2.min-range.func.spec.js +69 -0
- package/ds-tab-button/DSTabButton.func.spec.js +1 -1
- package/ds-tabs/DSTabsCO.js +4 -0
- package/ds-tabs/notification-badge/DSTabs.notification-badge.axe-core.func.spec.js +28 -0
- package/ds-tabs/notification-badge/DSTabs.notification-badge.func.spec.js +51 -0
- package/ds-tooltip-v3/DSTooltipV3CO.js +21 -0
- package/ds-tooltip-v3/aria-tooltip-pattern/DSTooltipV3.aria-tooltip-pattern.axe-core.func.spec.js +23 -0
- package/ds-tooltip-v3/aria-tooltip-pattern/DSTooltipV3.aria-tooltip-pattern.func.spec.js +29 -0
- package/ds-tooltip-v3/dialog/DSTooltipV3.dialog.func.spec.js +45 -0
- package/ds-tooltip-v3/dialog/DSTooltipV3.dialog.visual.spec.js +29 -0
- package/ds-treeview/DSTreeViewCO.js +23 -0
- package/ds-treeview/dragAndDrop/TreeView-dnd_keyboard.func.spec.js +96 -0
- package/ds-typography/DSTypographyCO.js +10 -0
- package/ds-typography/theme-font/DSTypography.theme-font.func.spec.js +30 -0
- package/package.json +150 -153
- package/paths.js +16 -6
- package/ds-card-v3/disabled/DSCardV3.disabled.visual.spec.js +0 -17
- package/ds-chat-tile/TileCO.js +0 -35
- package/ds-hooks/DSHook.func.spec.js +0 -60
- package/ds-hooks/useFocusStack/DSHook.useFocusStack.skipped.js +0 -57
- package/ds-treeview/dragAndDrop/TreeView-dnd_mouse.func.spec.js +0 -61
|
@@ -36,8 +36,17 @@ export default class DSToggleCO extends PageObject {
|
|
|
36
36
|
return $$('[data-testid="ds-controlled-toggle-checkbox"]')[index];
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
// The on/off state is exposed semantically via aria-checked on the role="switch"
|
|
40
|
+
// button. Post PUI-16323 the visible ON/OFF label is aria-hidden and purely
|
|
41
|
+
// presentational, so state must be read from aria-checked, not the label text.
|
|
42
|
+
static async getSwitch(index = 0) {
|
|
43
|
+
return $$('button[role="switch"]')[index];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Presentational ON/OFF label (aria-hidden). Targeted via its stable slot
|
|
47
|
+
// data-testid so we can assert the visible text tracks the state.
|
|
48
|
+
static async getStateLabel(index = 0) {
|
|
49
|
+
return $$('[data-testid="ds-formtoggle-text-wrapper"]')[index];
|
|
41
50
|
}
|
|
42
51
|
|
|
43
52
|
static async getTooltip() {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import GlobalHeader from './GlobalHeaderCO';
|
|
2
|
+
|
|
3
|
+
if (
|
|
4
|
+
(!browser.capabilities['ice:options'].isPhone &&
|
|
5
|
+
!browser.capabilities['ice:options'].isTablet &&
|
|
6
|
+
browser.capabilities.browserName === 'chrome') ||
|
|
7
|
+
browser.capabilities.browserName === 'Chrome'
|
|
8
|
+
) {
|
|
9
|
+
describe('PUI-18771 - GlobalHeader: SearchToggle result announcement -Func', () => {
|
|
10
|
+
before(async () => {
|
|
11
|
+
const errorOnGo = await GlobalHeader.withSearchToggleURL.go();
|
|
12
|
+
if (errorOnGo) throw errorOnGo;
|
|
13
|
+
await GlobalHeader.openAndPopulateSearchToggle();
|
|
14
|
+
});
|
|
15
|
+
it('01: search input should expose the accessible name guiding users to the result navigation', async () => {
|
|
16
|
+
const searchInput = await GlobalHeader.getSearchToggleInput();
|
|
17
|
+
await expect(searchInput).toHaveAttribute(
|
|
18
|
+
'aria-label',
|
|
19
|
+
'Search among the content of the page. Press Tab twice to reach the result navigation.',
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
it('02: results spinbutton should announce the total result count after typing', async () => {
|
|
23
|
+
const spinButton = await GlobalHeader.getSearchToggleSpinbutton();
|
|
24
|
+
await expect(spinButton).toHaveAttribute('aria-valuetext', '3 total results');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
@@ -19,14 +19,14 @@ if (
|
|
|
19
19
|
await browser.keys(Key.Tab);
|
|
20
20
|
await browser.keys(Key.Tab);
|
|
21
21
|
const result = await axeCoreCheck();
|
|
22
|
-
expect(result
|
|
22
|
+
await expect(result).toHaveLength(0);
|
|
23
23
|
});
|
|
24
24
|
it('02: should have global header with expanded appPicker and pass axe-core scan', async () => {
|
|
25
25
|
await browser.keys(Key.Tab);
|
|
26
26
|
await browser.keys(Key.Enter);
|
|
27
27
|
|
|
28
28
|
const result = await axeCoreCheck();
|
|
29
|
-
expect(result
|
|
29
|
+
await expect(result).toHaveLength(0);
|
|
30
30
|
});
|
|
31
31
|
it('03: should have global header with expanded menu-list and pass axe-core scan', async () => {
|
|
32
32
|
await browser.keys(Key.Escape);
|
|
@@ -34,7 +34,7 @@ if (
|
|
|
34
34
|
await browser.keys(Key.Tab);
|
|
35
35
|
await browser.keys(Key.Enter);
|
|
36
36
|
const result = await axeCoreCheck();
|
|
37
|
-
expect(result
|
|
37
|
+
await expect(result).toHaveLength(0);
|
|
38
38
|
});
|
|
39
39
|
});
|
|
40
40
|
|
|
@@ -47,12 +47,12 @@ if (
|
|
|
47
47
|
const globalHeader = await GlobalHeaderCO.getGlobalHeader();
|
|
48
48
|
await globalHeader.waitForDisplayed();
|
|
49
49
|
const result = await axeCoreCheck();
|
|
50
|
-
expect(result
|
|
50
|
+
await expect(result).toHaveLength(0);
|
|
51
51
|
});
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
// Skipped due to defect PUI-17970
|
|
55
|
-
describe
|
|
55
|
+
describe('PUI-12447 - GlobalHeader: toggle search -AxeCore', () => {
|
|
56
56
|
before(async () => {
|
|
57
57
|
const errorOnGo = await GlobalHeaderCO.withSearchToggleURL.go();
|
|
58
58
|
if (errorOnGo) throw errorOnGo;
|
|
@@ -61,19 +61,19 @@ if (
|
|
|
61
61
|
const globalHeader = await GlobalHeaderCO.getGlobalHeader();
|
|
62
62
|
await globalHeader.waitForDisplayed();
|
|
63
63
|
const result = await axeCoreCheck();
|
|
64
|
-
expect(result
|
|
64
|
+
await expect(result).toHaveLength(0);
|
|
65
65
|
});
|
|
66
66
|
it('02: should have global header with toggle-search expanded and pass axe-core scan', async () => {
|
|
67
67
|
const toggleSearch = await GlobalHeaderCO.getGHToolbarItem(0);
|
|
68
68
|
await toggleSearch.click();
|
|
69
69
|
await type('Hola');
|
|
70
70
|
const result = await axeCoreCheck();
|
|
71
|
-
expect(result
|
|
71
|
+
await expect(result).toHaveLength(0);
|
|
72
72
|
});
|
|
73
73
|
it('03: should have global header with populated toggle-search and pass axe-core scan', async () => {
|
|
74
74
|
await type('Hola');
|
|
75
75
|
const result = await axeCoreCheck();
|
|
76
|
-
expect(result
|
|
76
|
+
await expect(result).toHaveLength(0);
|
|
77
77
|
});
|
|
78
78
|
});
|
|
79
79
|
|
|
@@ -86,12 +86,12 @@ if (
|
|
|
86
86
|
const globalHeader = await GlobalHeaderCO.getGlobalHeader();
|
|
87
87
|
await globalHeader.waitForDisplayed();
|
|
88
88
|
const result = await axeCoreCheck();
|
|
89
|
-
expect(result
|
|
89
|
+
await expect(result).toHaveLength(0);
|
|
90
90
|
});
|
|
91
91
|
});
|
|
92
92
|
|
|
93
93
|
// Skipped due to defect PUI-17970
|
|
94
|
-
describe
|
|
94
|
+
describe('PUI-18379 - GlobalHeader: with search toggle -AxeCore', () => {
|
|
95
95
|
before(async () => {
|
|
96
96
|
const errorOnGo = await GlobalHeaderCO.withSearchToggleURL.go();
|
|
97
97
|
if (errorOnGo) throw errorOnGo;
|
|
@@ -103,7 +103,7 @@ if (
|
|
|
103
103
|
await expect(toggleSearch).toHaveAttribute('aria-expanded', 'false');
|
|
104
104
|
await expect(toggleSearch).toHaveAttribute('aria-controls');
|
|
105
105
|
const result = await axeCoreCheck();
|
|
106
|
-
expect(result
|
|
106
|
+
await expect(result).toHaveLength(0);
|
|
107
107
|
});
|
|
108
108
|
it('02: should have global header with search toggle expanded and pass axe-core scan', async () => {
|
|
109
109
|
const toggleSearch = await GlobalHeaderCO.getGHToolbarItem(0);
|
|
@@ -111,17 +111,17 @@ if (
|
|
|
111
111
|
await expect(toggleSearch).toHaveAttribute('aria-expanded', 'true');
|
|
112
112
|
await expect(toggleSearch).toHaveAttribute('aria-controls', /^ds-global-header/);
|
|
113
113
|
const result = await axeCoreCheck();
|
|
114
|
-
expect(result
|
|
114
|
+
await expect(result).toHaveLength(0);
|
|
115
115
|
});
|
|
116
116
|
it('03: should have global header with populated search toggle and pass axe-core scan', async () => {
|
|
117
117
|
await type('Labor');
|
|
118
118
|
const result = await axeCoreCheck();
|
|
119
|
-
expect(result
|
|
119
|
+
await expect(result).toHaveLength(0);
|
|
120
120
|
});
|
|
121
121
|
});
|
|
122
122
|
|
|
123
123
|
// Skipped due to defect PUI-17970
|
|
124
|
-
describe
|
|
124
|
+
describe('PUI-16270 - GlobalHeader: Controled with Iframe -AxeCore', () => {
|
|
125
125
|
before(async () => {
|
|
126
126
|
const errorOnGo = await GlobalHeaderCO.iframeURL.go();
|
|
127
127
|
if (errorOnGo) throw errorOnGo;
|
|
@@ -130,7 +130,7 @@ if (
|
|
|
130
130
|
const globalHeader = await GlobalHeaderCO.getGlobalHeader();
|
|
131
131
|
await globalHeader.waitForDisplayed();
|
|
132
132
|
const result = await axeCoreCheck({ extraDisabledRules: ['landmark-one-main'] });
|
|
133
|
-
expect(result
|
|
133
|
+
await expect(result).toHaveLength(0);
|
|
134
134
|
});
|
|
135
135
|
});
|
|
136
136
|
}
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { Key } from 'webdriverio';
|
|
2
2
|
import GlobalHeader from './GlobalHeaderCO';
|
|
3
3
|
|
|
4
|
-
|
|
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
|
}
|
|
@@ -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) {
|
package/ds-global-header/app-picker-passthrough/GlobalHeader.app-picker-passthrough.func.spec.js
ADDED
|
@@ -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
|
+
}
|