dimsum-e2e-tests 3.70.0-next.4 → 3.70.0-next.40
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 +204 -0
- package/ds-accordion/DSAccordion.visual.spec.js +6 -0
- package/ds-accordion/DSAccordionCO.js +11 -3
- package/ds-accordion/controlled/DSAccordion.controlled.func.spec.js +23 -0
- package/ds-accordion/header-structure/DSAccordion.header-structure.func.spec.js +49 -0
- package/ds-accordion/input-inside/DSAccordion.input-inside.func.spec.js +17 -0
- package/ds-accordion-native/DSAccordionNative.axe-core.func.spec.js +135 -0
- package/ds-accordion-native/DSAccordionNative.func.spec.js +200 -0
- package/ds-accordion-native/DSAccordionNative.visual.spec.js +158 -0
- package/ds-accordion-native/DSAccordionNativeCO.js +161 -0
- package/ds-accordion-native/QA_NOTES.md +88 -0
- package/ds-accordion-native/aria-disabled/DSAccordionNative.aria-disabled.axe-core.func.spec.js +25 -0
- package/ds-accordion-native/aria-disabled/DSAccordionNative.aria-disabled.visual.spec.js +28 -0
- package/ds-accordion-native/controlled/DSAccordionNative.controlled.func.spec.js +22 -0
- package/ds-accordion-native/header-structure/DSAccordionNative.header-structure.func.spec.js +53 -0
- package/ds-accordion-native/input-inside/DSAccordionNative.input-inside.func.spec.js +16 -0
- package/ds-accordion-native/role/DSAccordionNative.role-heading.func.spec.js +27 -0
- package/ds-accordion-native/scrollable-content/DSAccordionNative.scrollable-content.visual.spec.js +49 -0
- package/ds-accordion-native/slots/DSAccordionNative.slots.axe-core.func.spec.js +25 -0
- package/ds-accordion-native/slots/DSAccordionNative.slots.func.spec.js +73 -0
- package/ds-accordion-native/slots/DSAccordionNative.slots.visual.spec.js +21 -0
- package/ds-accordion-native/wrapLabel/DSAccordionNative.wrap-label.visual.spec.js +21 -0
- package/ds-apppicker/DSAppPickerCO.js +1 -1
- package/ds-autocomplete/DSAutocomplete.visual.spec.js +34 -0
- package/ds-autocomplete/DSAutocompleteCO.js +2 -0
- package/ds-card-v3/DSCardV3CO.js +14 -0
- package/ds-card-v3/accordion/DSCardV3.accordion-aria-structure.func.spec.js +41 -0
- package/ds-card-v3/disabled/DSCardV3.disabled-non-interactive.func.spec.js +25 -0
- package/ds-card-v3/multi-select/DSCardV3.multi-select.aria-grouping.func.spec.js +24 -0
- package/ds-card-v3/single-select/DSCardV3.single-select.aria-grouping.func.spec.js +24 -0
- package/ds-chat/DSChat.axe-core.func.spec.js +2 -2
- package/ds-chat/DSChat.visual.spec.js +3 -3
- package/ds-chat/DSChatCO.js +17 -23
- 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 +77 -0
- package/ds-chat/components/ComposerCO.js +6 -6
- package/ds-chat/components/FloatingButtonCO.js +2 -2
- 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/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-controlled-form/ds-combobox/DSComboboxCO.js +2 -2
- package/ds-controlled-form/ds-controlled-checkbox/DSControlledCheckboxCO.js +1 -1
- package/ds-controlled-form/ds-controlled-inputgroup/DSControlledInputGroupCO.js +1 -1
- package/ds-data-table-async/DSDataTableCO.js +14 -12
- package/ds-data-table-async/basic/DSDataTable.basic.visual.spec.js +1 -1
- package/ds-data-table-async/components/FiltersCO.js +1 -1
- 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-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 +11 -3
- 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 +15 -0
- package/ds-form-combobox-multi/disabled/DSComboboxMulti.disabled.axe-core.func.spec.js +24 -0
- 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/skeleton/DSComboboxMulti.skeleton.visual.spec.js +25 -0
- package/ds-form-combobox-single/DSComboboxSingleCO.js +11 -3
- 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/disabled/DSComboboxSingle.disabled.axe-core.func.spec.js +24 -0
- 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-date-range-picker/date-segment-aria-labels/DateRangePicker.date-segment-aria-labels.func.spec.js +64 -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-leftnavigation/LeftNavigationCO.js +2 -2
- package/ds-menu-button/DSMenuButtonCO.js +23 -0
- package/ds-menu-button/slots/DSMenuButton.slots.func.spec.js +40 -0
- package/ds-menu-button/slots/DSMenuButton.slots.visual.spec.js +26 -0
- package/ds-modal-slide/ModalSlideCO.js +39 -0
- package/ds-modal-slide/custom-header/ModalSlide.customHeader.focusRing.visual.spec.js +2 -1
- package/ds-modal-slide/slots/ModalSlide.slots.func.spec.js +74 -0
- package/ds-modal-slide/slots/ModalSlide.slots.visual.spec.js +27 -0
- package/ds-notification-badge/DSNotificationBadge.visual.spec.js +17 -20
- package/ds-page-layout/PageLayoutCO.js +4 -4
- package/ds-progress-indicator/DSProgressIndicator.axe-core.func.spec.js +2 -0
- package/ds-progress-indicator/DSProgressIndicatorCO.js +1 -1
- package/ds-shuttle-v2/DSShuttleV2CO.js +11 -1
- 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 +27 -0
- 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-tab-button/DSTabButton.func.spec.js +1 -1
- 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 +25 -2
- package/ds-treeview/dragAndDrop/TreeView-dnd_keyboard.func.spec.js +96 -0
- package/package.json +150 -152
- package/paths.js +9 -1
- package/ds-chat-tile/TileCO.js +0 -35
- package/ds-treeview/dragAndDrop/TreeView-dnd_mouse.func.spec.js +0 -61
|
@@ -8,8 +8,12 @@ export default class DSTooltipV3CO extends PageObject {
|
|
|
8
8
|
|
|
9
9
|
static uncontrolledTestUrl = new Urlbuilder(PATH_E2E_TOOLTIP_V3, 'uncontrolled-test');
|
|
10
10
|
|
|
11
|
+
static basicTestUrl = new Urlbuilder(PATH_E2E_TOOLTIP_V3, 'basic-test');
|
|
12
|
+
|
|
11
13
|
static slotsURL = new Urlbuilder(PATH_E2E_TOOLTIP_V3, 'slots-test');
|
|
12
14
|
|
|
15
|
+
static inADialogTestUrl = new Urlbuilder(PATH_E2E_TOOLTIP_V3, 'in-a-dialog-test');
|
|
16
|
+
|
|
13
17
|
// Snapshots
|
|
14
18
|
static snapshotPath(example = 'basic') {
|
|
15
19
|
return PageObject.getSnapshotPathBuilder('TooltipV3', example);
|
|
@@ -20,10 +24,27 @@ export default class DSTooltipV3CO extends PageObject {
|
|
|
20
24
|
return $('[data-testid="ds-tooltip-v3-tooltip-text-wrapper"]');
|
|
21
25
|
}
|
|
22
26
|
|
|
27
|
+
static async getBasicTestTriggerButton() {
|
|
28
|
+
return $('button[aria-describedby="basic-tooltip"]');
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
static async getTooltipContentByIndex(index = 0) {
|
|
24
32
|
return $$('[data-testid="ds-tooltip-v3-tooltip-text-wrapper"] [data-testid="ds-typography-element"]')[index];
|
|
25
33
|
}
|
|
26
34
|
|
|
35
|
+
// "tooltip in a dialog" selectors (PUI-18012 dismissal mechanism)
|
|
36
|
+
static async getOpenDialogButton() {
|
|
37
|
+
return $('[data-testid="open-dialog-button"]');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static async getDialogContainer() {
|
|
41
|
+
return $('[data-testid="ds-dialog-container"]');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static async getInADialogTriggerButton() {
|
|
45
|
+
return $('button[aria-describedby="in-a-dialog-tooltip"]');
|
|
46
|
+
}
|
|
47
|
+
|
|
27
48
|
// slot selectors
|
|
28
49
|
static async getRootSlot() {
|
|
29
50
|
return $('[data-dimsum-slot="dsTooltipv3Root"]');
|
package/ds-tooltip-v3/aria-tooltip-pattern/DSTooltipV3.aria-tooltip-pattern.axe-core.func.spec.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import DSTooltipV3CO from '../DSTooltipV3CO';
|
|
2
|
+
import { axeCoreCheck } from '../../helpers';
|
|
3
|
+
|
|
4
|
+
if (
|
|
5
|
+
(!browser.capabilities['ice:options'].isPhone &&
|
|
6
|
+
!browser.capabilities['ice:options'].isTablet &&
|
|
7
|
+
browser.capabilities.browserName === 'chrome') ||
|
|
8
|
+
browser.capabilities.browserName === 'Chrome'
|
|
9
|
+
) {
|
|
10
|
+
describe('PUI-18498 - TooltipV3:: WAI-ARIA tooltip pattern - AxeCore', () => {
|
|
11
|
+
before('loading page', async () => {
|
|
12
|
+
const errorOnGo = await DSTooltipV3CO.basicTestUrl.go();
|
|
13
|
+
if (errorOnGo) throw errorOnGo;
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('01: should render the basic tooltip pattern and pass axe-core scan', async () => {
|
|
17
|
+
const tooltipContainer = await DSTooltipV3CO.getTooltip();
|
|
18
|
+
await tooltipContainer.waitForDisplayed();
|
|
19
|
+
const result = await axeCoreCheck();
|
|
20
|
+
expect(result.length).toBe(0);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import DSTooltipV3CO from '../DSTooltipV3CO';
|
|
2
|
+
|
|
3
|
+
// Tests for the fix introduced in PUI-18011 / PUI-18010:
|
|
4
|
+
// the tooltip container must expose role="tooltip" and its `id` so that consumers
|
|
5
|
+
// can wire `aria-describedby` from the trigger element (W3C WAI-ARIA tooltip pattern).
|
|
6
|
+
if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
|
|
7
|
+
describe('PUI-18495 - TooltipV3:: WAI-ARIA tooltip pattern (role + aria-describedby) - func', () => {
|
|
8
|
+
before('loading page', async () => {
|
|
9
|
+
const errorOnGo = await DSTooltipV3CO.basicTestUrl.go();
|
|
10
|
+
if (errorOnGo) throw errorOnGo;
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('01: should expose role="tooltip", a matching id on the container and aria-describedby on trigger', async () => {
|
|
14
|
+
const tooltipContainer = await DSTooltipV3CO.getTooltip();
|
|
15
|
+
const triggerButton = await DSTooltipV3CO.getBasicTestTriggerButton();
|
|
16
|
+
|
|
17
|
+
await expect(tooltipContainer).toBeExisting();
|
|
18
|
+
await expect(tooltipContainer).toHaveAttribute('role', 'tooltip');
|
|
19
|
+
await expect(tooltipContainer).toHaveAttribute('id', 'basic-tooltip');
|
|
20
|
+
|
|
21
|
+
await expect(triggerButton).toBeExisting();
|
|
22
|
+
await expect(triggerButton).toHaveAttribute('aria-describedby', 'basic-tooltip');
|
|
23
|
+
|
|
24
|
+
const containerId = await tooltipContainer.getAttribute('id');
|
|
25
|
+
const triggerDescribedBy = await triggerButton.getAttribute('aria-describedby');
|
|
26
|
+
await expect(containerId).toBe(triggerDescribedBy);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Key } from 'webdriverio';
|
|
2
|
+
import { mouseOver } from '../../helpers';
|
|
3
|
+
import DSTooltipV3CO from '../DSTooltipV3CO';
|
|
4
|
+
|
|
5
|
+
// Tests for the fix introduced in PUI-18012 (a tooltip inside a dialog must be dismissible with ESC
|
|
6
|
+
// without closing the dialog — WCAG 2.2 SC 1.4.13 Content on Hover or Focus, Dismissible).
|
|
7
|
+
if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
|
|
8
|
+
describe('PUI-18592 - TooltipV3:: dismissal and behavior of a tooltip inside a dialog -Func', () => {
|
|
9
|
+
before('loading page', async () => {
|
|
10
|
+
const errorOnGo = await DSTooltipV3CO.inADialogTestUrl.go();
|
|
11
|
+
if (errorOnGo) throw errorOnGo;
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('01: should open the dialog and show the tooltip with its text on hover', async () => {
|
|
15
|
+
const openButton = await DSTooltipV3CO.getOpenDialogButton();
|
|
16
|
+
await openButton.click();
|
|
17
|
+
|
|
18
|
+
const dialog = await DSTooltipV3CO.getDialogContainer();
|
|
19
|
+
await expect(dialog).toBeDisplayed();
|
|
20
|
+
|
|
21
|
+
const trigger = await DSTooltipV3CO.getInADialogTriggerButton();
|
|
22
|
+
await mouseOver(trigger);
|
|
23
|
+
|
|
24
|
+
const tooltip = await DSTooltipV3CO.getTooltip();
|
|
25
|
+
await expect(tooltip).toBeDisplayed();
|
|
26
|
+
await expect(tooltip).toHaveText(expect.stringContaining('Tooltip text 3'));
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('02: should dismiss only the tooltip on ESC, keeping the dialog open', async () => {
|
|
30
|
+
const tooltip = await DSTooltipV3CO.getTooltip();
|
|
31
|
+
await browser.keys(Key.Escape);
|
|
32
|
+
|
|
33
|
+
await expect(tooltip).not.toBeDisplayed();
|
|
34
|
+
const dialog = await DSTooltipV3CO.getDialogContainer();
|
|
35
|
+
await expect(dialog).toBeDisplayed();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('03: should close the dialog on a subsequent ESC once the tooltip is dismissed', async () => {
|
|
39
|
+
await browser.keys(Key.Escape);
|
|
40
|
+
|
|
41
|
+
const dialog = await DSTooltipV3CO.getDialogContainer();
|
|
42
|
+
await expect(dialog).not.toBeDisplayed();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { mouseOver } from '../../helpers';
|
|
2
|
+
import DSTooltipV3CO from '../DSTooltipV3CO';
|
|
3
|
+
|
|
4
|
+
// Visual coverage for PUI-18012: how a tooltip looks when displayed inside a dialog.
|
|
5
|
+
if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
|
|
6
|
+
describe('PUI-18593 - TooltipV3:: tooltip displayed inside a dialog -Visual', () => {
|
|
7
|
+
before('loading page', async () => {
|
|
8
|
+
const errorOnGo = await DSTooltipV3CO.inADialogTestUrl.go();
|
|
9
|
+
if (errorOnGo) throw errorOnGo;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('01: should display the tooltip inside the open dialog', async () => {
|
|
13
|
+
const openButton = await DSTooltipV3CO.getOpenDialogButton();
|
|
14
|
+
await openButton.click();
|
|
15
|
+
|
|
16
|
+
const dialog = await DSTooltipV3CO.getDialogContainer();
|
|
17
|
+
await expect(dialog).toBeDisplayed();
|
|
18
|
+
|
|
19
|
+
const trigger = await DSTooltipV3CO.getInADialogTriggerButton();
|
|
20
|
+
await mouseOver(trigger);
|
|
21
|
+
|
|
22
|
+
const tooltip = await DSTooltipV3CO.getTooltip();
|
|
23
|
+
await expect(tooltip).toBeDisplayed();
|
|
24
|
+
|
|
25
|
+
const snapshot = await browser.percyCheckScreenshot(DSTooltipV3CO.snapshotPath('tooltip-in-dialog'));
|
|
26
|
+
await expect(snapshot).toEqual(0);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -226,7 +226,7 @@ export default class DSTreeViewCO extends PageObject {
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
static async getElementsTexts() {
|
|
229
|
-
return $$('[data-testid="
|
|
229
|
+
return $$('[data-testid="tree-item-content"]');
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
static async getCollapseBtn() {
|
|
@@ -241,6 +241,12 @@ export default class DSTreeViewCO extends PageObject {
|
|
|
241
241
|
return (await $$('[data-testid="drag-handle"]'))[index];
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
+
// Drag handles carry a stable id of the form `${itemId}-drag-handle`, so this selects a row's
|
|
245
|
+
// handle independent of its current position/index (which shifts with the expansion state).
|
|
246
|
+
static async getDragHandleByItemId(itemId) {
|
|
247
|
+
return $(`[id="${itemId}-drag-handle"]`);
|
|
248
|
+
}
|
|
249
|
+
|
|
244
250
|
static async getFirstDragHandle() {
|
|
245
251
|
return $$('[data-testid="drag-handle"]')[0];
|
|
246
252
|
}
|
|
@@ -269,7 +275,7 @@ export default class DSTreeViewCO extends PageObject {
|
|
|
269
275
|
}
|
|
270
276
|
|
|
271
277
|
static async getTooltip() {
|
|
272
|
-
return $('[data-testid="
|
|
278
|
+
return $('[data-testid="ds-floating-wrapper-root"]');
|
|
273
279
|
}
|
|
274
280
|
|
|
275
281
|
static async noItemsFound() {
|
|
@@ -317,6 +323,23 @@ export default class DSTreeViewCO extends PageObject {
|
|
|
317
323
|
]);
|
|
318
324
|
}
|
|
319
325
|
|
|
326
|
+
// Expands a row identified by its content text, but only if it is currently collapsed.
|
|
327
|
+
// Idempotent on purpose: after a drag-and-drop, whether the target group is auto-expanded
|
|
328
|
+
// varies by browser, so a blind toggle would re-collapse an already-expanded row.
|
|
329
|
+
static async ensureRowExpandedByText(text) {
|
|
330
|
+
return browser.execute((rowText) => {
|
|
331
|
+
const items = Array.from(document.querySelectorAll('[data-testid="tree-item"]'));
|
|
332
|
+
const item = items.find((node) => {
|
|
333
|
+
const content = node.querySelector('[data-testid="tree-item-content"]');
|
|
334
|
+
return content && content.textContent.trim() === rowText;
|
|
335
|
+
});
|
|
336
|
+
if (item && item.getAttribute('aria-expanded') === 'false') {
|
|
337
|
+
const toggle = item.querySelector('[data-testid="tree-item-expand-toggle"]');
|
|
338
|
+
if (toggle) toggle.click();
|
|
339
|
+
}
|
|
340
|
+
}, text);
|
|
341
|
+
}
|
|
342
|
+
|
|
320
343
|
static async isExpanded(index) {
|
|
321
344
|
return (await this.getRow(index)).getAttribute('aria-expanded');
|
|
322
345
|
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/* eslint-disable wdio/no-pause */
|
|
2
|
+
import { Key } from 'webdriverio';
|
|
3
|
+
import DSTreeViewCO from '../DSTreeViewCO';
|
|
4
|
+
|
|
5
|
+
// The TreeView uses @dnd-kit (pointer + keyboard sensors), not HTML5 native drag.
|
|
6
|
+
// WDIO's mouse `.dragAndDrop()` only actuates the pointer sensor reliably under
|
|
7
|
+
// geckodriver (Firefox); Chromedriver/safaridriver synthesize the drag differently,
|
|
8
|
+
// so the mouse-driven version of these tests passed only in Firefox. These tests are
|
|
9
|
+
// therefore driven through the dnd-kit keyboard sensor (Space to pick up, ArrowDown
|
|
10
|
+
// to move/nest, Space to drop), which is deterministic and stable across all browsers
|
|
11
|
+
// — mirroring the keyboard-driven dnd tests in ds-data-table-async. Do not convert
|
|
12
|
+
// back to mouse `.dragAndDrop()`.
|
|
13
|
+
|
|
14
|
+
if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
|
|
15
|
+
describe('PUI-11320 - TreeView, Basic Drag and Drop Functionality (keyboard)', () => {
|
|
16
|
+
before(async () => {
|
|
17
|
+
const errorOnGo = await DSTreeViewCO.dragAndDrop.go();
|
|
18
|
+
if (errorOnGo) throw errorOnGo;
|
|
19
|
+
});
|
|
20
|
+
it('01: drag and drop in the same position - parent item', async () => {
|
|
21
|
+
const dragHandleFirstRow = await DSTreeViewCO.getDragHandle(0);
|
|
22
|
+
await dragHandleFirstRow.click();
|
|
23
|
+
await browser.keys(Key.Space); // pick up
|
|
24
|
+
await browser.pause(300);
|
|
25
|
+
await browser.keys(Key.Space); // drop in place
|
|
26
|
+
await browser.pause(300);
|
|
27
|
+
const firstRow = await DSTreeViewCO.getRowContent(0);
|
|
28
|
+
await expect(firstRow).toHaveText(expect.stringContaining('Parent. id: 1'));
|
|
29
|
+
});
|
|
30
|
+
it('02: drag and drop in the same position - child item', async () => {
|
|
31
|
+
const expandableBtnFirstRow = await DSTreeViewCO.getToggleBtn(0);
|
|
32
|
+
await expandableBtnFirstRow.click();
|
|
33
|
+
await browser.pause(300);
|
|
34
|
+
const dragHandleFirstChild = await DSTreeViewCO.getDragHandle(1);
|
|
35
|
+
await dragHandleFirstChild.click();
|
|
36
|
+
await browser.keys(Key.Space); // pick up
|
|
37
|
+
await browser.pause(300);
|
|
38
|
+
await browser.keys(Key.Space); // drop in place
|
|
39
|
+
await browser.pause(300);
|
|
40
|
+
const firstChildRow = await DSTreeViewCO.getRowContent(1);
|
|
41
|
+
await expect(firstChildRow).toHaveText(expect.stringContaining('Child of 1. id: 2'));
|
|
42
|
+
});
|
|
43
|
+
it('03: drag a parent and drop it in another parent', async () => {
|
|
44
|
+
const dragHandleParentId1 = await DSTreeViewCO.getDragHandle(0);
|
|
45
|
+
await dragHandleParentId1.click();
|
|
46
|
+
await browser.keys(Key.Space); // pick up Parent id 1
|
|
47
|
+
await browser.pause(300);
|
|
48
|
+
await browser.keys(Key.ArrowDown); // move into Parent id 4
|
|
49
|
+
await browser.pause(300);
|
|
50
|
+
await browser.keys(Key.Space); // drop
|
|
51
|
+
await browser.pause(300);
|
|
52
|
+
await DSTreeViewCO.expandCollapseAll();
|
|
53
|
+
await browser.pause(300);
|
|
54
|
+
const firstRow = await DSTreeViewCO.getRowContent(0);
|
|
55
|
+
await expect(firstRow).toHaveText(expect.stringContaining('Parent. id: 4'));
|
|
56
|
+
});
|
|
57
|
+
// Safari's WebKit driver is non-deterministic for TreeView keyboard drag-and-drop (the drag
|
|
58
|
+
// intermittently fails to nest the item), so this scenario is not registered on Safari —
|
|
59
|
+
// consistent with PUI-8198, which is also skipped on Safari. It still runs on Chrome, Edge and
|
|
60
|
+
// Firefox.
|
|
61
|
+
if (browser.capabilities.browserName !== 'Safari') {
|
|
62
|
+
it('04: drag a child of a parent and drop it in another parent with no children', async () => {
|
|
63
|
+
// Make the dragged child (id 3) visible regardless of the expansion state the previous test
|
|
64
|
+
// left behind (expandCollapseAll is browser-dependent), then select it by its stable handle
|
|
65
|
+
// id instead of an absolute index — an absolute index points at the wrong row when an
|
|
66
|
+
// ancestor group is collapsed.
|
|
67
|
+
await DSTreeViewCO.ensureRowExpandedByText('Parent. id: 4');
|
|
68
|
+
await DSTreeViewCO.ensureRowExpandedByText('Parent. id: 1');
|
|
69
|
+
await browser.pause(300);
|
|
70
|
+
const dragHandleChildOfParent1 = await DSTreeViewCO.getDragHandleByItemId(3);
|
|
71
|
+
await dragHandleChildOfParent1.click();
|
|
72
|
+
await browser.keys(Key.Space); // pick up Child of 1. Also parent. id 3
|
|
73
|
+
await browser.pause(300);
|
|
74
|
+
await browser.keys(Key.ArrowDown); // move into Item with no children. id 7
|
|
75
|
+
await browser.pause(300);
|
|
76
|
+
await browser.keys(Key.Space); // drop
|
|
77
|
+
await browser.pause(300);
|
|
78
|
+
// Reveal the dragged child by expanding its new parent (id 7), but only when collapsed.
|
|
79
|
+
// expandCollapseAll() is avoided: it is a focus-dependent toggle that behaves inconsistently
|
|
80
|
+
// across browsers after a keyboard drop, and whether the drop auto-expands id 7 also varies.
|
|
81
|
+
await DSTreeViewCO.ensureRowExpandedByText('Item with no children. id: 7');
|
|
82
|
+
await browser.pause(300);
|
|
83
|
+
|
|
84
|
+
// Assert relative to id 7 rather than an absolute row index: the exact indices depend on how
|
|
85
|
+
// many ancestor groups are expanded (which varies across browsers). The dragged child (id 3)
|
|
86
|
+
// is always the row immediately after its new parent (id 7).
|
|
87
|
+
const rowContents = await DSTreeViewCO.getElementsTexts();
|
|
88
|
+
// WebdriverIO's element-array `.map()` is an async helper that resolves to the values
|
|
89
|
+
// directly — do not wrap it in Promise.all (that passes a Promise to Promise.all).
|
|
90
|
+
const rowTexts = await rowContents.map((row) => row.getText());
|
|
91
|
+
const parentId7Index = rowTexts.indexOf('Item with no children. id: 7');
|
|
92
|
+
await expect(rowTexts[parentId7Index + 1]).toEqual('Child of 1. Also parent. id: 3');
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|