dimsum-e2e-tests 3.80.0-next.42 → 3.80.0-next.44
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 +8 -0
- package/ds-accordion/DSAccordionCO.js +4 -4
- package/ds-breadcrumb/DSBreadcrumb.visual.spec.js +0 -7
- package/ds-breadcrumb/DSBreadcrumbCO.js +18 -3
- package/{ds-dialog/axe-core/DSDialog.warning.axe-core.spec.func.js → ds-breadcrumb/slots/DSBreadcrumb.slots.axe-core.func.spec.js} +7 -8
- package/ds-breadcrumb/slots/DSBreadcrumb.slots.func.spec.js +38 -0
- package/ds-breadcrumb/slots/DSBreadcrumb.slots.visual.spec.js +17 -0
- package/ds-chat/DSChatCO.js +20 -0
- package/ds-chat/container/visible-elements/DSChat-container.visible-elements.func.spec.js +42 -0
- package/ds-chat/loadmore/keep-focus/DSChat-loadmore.keep-focus.func.spec.js +28 -0
- package/ds-controlled-form/ds-controlled-radio/DSControlledRadioCO.js +1 -1
- package/ds-dialog/DSDialogCO.js +1 -1
- package/ds-form-combobox-multi/virtualization/{DSComboboxMulti.virtualization.func.spec .js → DSComboboxMulti.virtualization.func.spec.js} +12 -7
- package/ds-form-layout-blocks/form-layout-block-item/DSFormLayoutBlockItemCO.js +1 -1
- package/ds-global-header/GlobalHeaderCO.js +1 -1
- package/ds-grid/DSGridCO.js +1 -1
- package/ds-image/DSImageCO.js +4 -4
- package/ds-indeterminate-progress-indicator/DSIndeterminateProgressIndicatorCO.js +1 -1
- package/ds-left-navigation-tree/LeftNavigationTreeCO.js +46 -0
- package/ds-left-navigation-tree/basic/LeftNavigationTree.aria-contract.func.spec.js +62 -0
- package/ds-left-navigation-tree/basic/LeftNavigationTree.axe-core.func.spec.js +28 -0
- package/ds-left-navigation-tree/basic/LeftNavigationTree.keyboard.func.spec.js +65 -0
- package/ds-leftnavigation/LeftNavigation.func.spec.js +38 -0
- package/ds-leftnavigation/LeftNavigationCO.js +20 -0
- package/ds-menu-button/DSMenuButtonCO.js +4 -4
- package/ds-query-builder/DSQueryBuilderCO.js +0 -2
- package/ds-svg/DSSvgCO.js +5 -5
- package/ds-tabs/DSTabs.visual.spec.js +3 -1
- package/ds-toast/DSToast.visual.spec.js +7 -3
- package/ds-toast/DSToastCO.js +1 -1
- package/ds-treeview/DSTreeViewCO.js +1 -1
- package/ds-typography/DSTypographyCO.js +4 -4
- package/helpers.js +35 -47
- package/package.json +149 -149
- package/paths.js +1 -0
- /package/ds-indeterminate-progress-indicator/{DSIndetermintateProgressIndicator.func.spec copy.js → DSIndetermintateProgressIndicator.func.spec.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [3.80.0-next.44](/github.com/intcx/PLATFORM-UI/compare/v3.80.0-next.43...v3.80.0-next.44) (2026-10-20)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package dimsum-e2e-tests
|
|
9
|
+
|
|
10
|
+
## [3.80.0-next.43](/github.com/intcx/PLATFORM-UI/compare/v3.80.0-next.42...v3.80.0-next.43) (2026-10-19)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package dimsum-e2e-tests
|
|
13
|
+
|
|
6
14
|
## [3.80.0-next.42](/github.com/intcx/PLATFORM-UI/compare/v3.80.0-next.41...v3.80.0-next.42) (2026-10-15)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package dimsum-e2e-tests
|
|
@@ -4,11 +4,11 @@ import { PageObject, Urlbuilder, getElementByIndex } from '../helpers';
|
|
|
4
4
|
|
|
5
5
|
export default class DSAccordionCO extends PageObject {
|
|
6
6
|
// Desktop
|
|
7
|
-
static basicURL = new Urlbuilder(PATH_E2E_ACCORDION, 'basic');
|
|
7
|
+
static basicURL = new Urlbuilder(PATH_E2E_ACCORDION, 'basic-test');
|
|
8
8
|
|
|
9
|
-
static multipleURL = new Urlbuilder(PATH_E2E_ACCORDION, 'multiple');
|
|
9
|
+
static multipleURL = new Urlbuilder(PATH_E2E_ACCORDION, 'multiple-test');
|
|
10
10
|
|
|
11
|
-
static customActions = new Urlbuilder(PATH_E2E_ACCORDION, 'render-custom-actions');
|
|
11
|
+
static customActions = new Urlbuilder(PATH_E2E_ACCORDION, 'render-custom-actions-test');
|
|
12
12
|
|
|
13
13
|
static headerControls = new Urlbuilder(PATH_E2E_ACCORDION, 'header-control-examples-test');
|
|
14
14
|
|
|
@@ -38,7 +38,7 @@ export default class DSAccordionCO extends PageObject {
|
|
|
38
38
|
|
|
39
39
|
static applyAriaDisabled = new Urlbuilder(PATH_E2E_ACCORDION, 'apply-aria-disabled-test');
|
|
40
40
|
|
|
41
|
-
static scrollableContent = new Urlbuilder(PATH_E2E_ACCORDION, 'scrollable-content');
|
|
41
|
+
static scrollableContent = new Urlbuilder(PATH_E2E_ACCORDION, 'scrollable-content-test');
|
|
42
42
|
|
|
43
43
|
static wrapLabel = new Urlbuilder(PATH_E2E_ACCORDION, 'wrap-label');
|
|
44
44
|
|
|
@@ -84,13 +84,6 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
|
|
|
84
84
|
const snapshot = await browser.eyesCheckSnapshot(DSBreadcrumbCO.snapshotPath('breadcrumb-above-title'));
|
|
85
85
|
await expect(snapshot).toEqual(0);
|
|
86
86
|
});
|
|
87
|
-
it('should show hovered editable title', async () => {
|
|
88
|
-
await browser.eyesOpen();
|
|
89
|
-
const title = await DSBreadcrumbCO.getEditableTitle();
|
|
90
|
-
await mouseOver(title);
|
|
91
|
-
const snapshot = await browser.eyesCheckSnapshot(DSBreadcrumbCO.snapshotPath('breadcrumb-hovered-title'));
|
|
92
|
-
await expect(snapshot).toEqual(0);
|
|
93
|
-
});
|
|
94
87
|
});
|
|
95
88
|
|
|
96
89
|
describe('PUI-9462 - Breadcrumb, Active - Visual Test', () => {
|
|
@@ -13,7 +13,7 @@ export default class DSBreadcrumbCO extends PageObject {
|
|
|
13
13
|
|
|
14
14
|
static activeURL = new Urlbuilder(PATH_E2E_BREADCRUMB, 'active-test');
|
|
15
15
|
|
|
16
|
-
static ucTruncatedURL = new Urlbuilder(PATH_E2E_BREADCRUMB, 'bread-crumb-truncated');
|
|
16
|
+
static ucTruncatedURL = new Urlbuilder(PATH_E2E_BREADCRUMB, 'bread-crumb-truncated-test');
|
|
17
17
|
|
|
18
18
|
static containerProps = new Urlbuilder(PATH_E2E_BREADCRUMB, 'container-props-test');
|
|
19
19
|
|
|
@@ -23,6 +23,8 @@ export default class DSBreadcrumbCO extends PageObject {
|
|
|
23
23
|
|
|
24
24
|
static asURL = new Urlbuilder(PATH_E2E_BREADCRUMB, 'as-test');
|
|
25
25
|
|
|
26
|
+
static slotsURL = new Urlbuilder(PATH_E2E_BREADCRUMB, 'slots-test');
|
|
27
|
+
|
|
26
28
|
// Snapshots
|
|
27
29
|
static snapshotPath(example = 'basic') {
|
|
28
30
|
return PageObject.getSnapshotPathBuilder('Breadcrumb', example);
|
|
@@ -65,8 +67,21 @@ export default class DSBreadcrumbCO extends PageObject {
|
|
|
65
67
|
return $(`[id="my-custom-id"]`);
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
static async
|
|
69
|
-
return $(
|
|
70
|
+
static async getContainerSlot() {
|
|
71
|
+
return $('[data-dimsum-slot="dsBreadcrumbContainer"]');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static async getListSlot() {
|
|
75
|
+
return $('[data-dimsum-slot="dsBreadcrumbList"]');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
static async getCrumbWrapperSlot() {
|
|
79
|
+
return $('[data-dimsum-slot="dsBreadcrumbCrumbWrapper"]');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// the link renders through DSTypography: its own slot is dsTypographyRoot, the breadcrumb slot is the parent one
|
|
83
|
+
static async getLinkSlot() {
|
|
84
|
+
return $('[data-dimsum-parent-slot="dsBreadcrumbLink"]');
|
|
70
85
|
}
|
|
71
86
|
|
|
72
87
|
static async getItemColor(text) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import DSDialog from '../DSDialogCO';
|
|
2
1
|
import { axeCoreCheck } from '../../helpers';
|
|
2
|
+
import DSBreadcrumbCO from '../DSBreadcrumbCO';
|
|
3
3
|
|
|
4
4
|
if (
|
|
5
5
|
(!browser.capabilities['ice:options'].isPhone &&
|
|
@@ -7,16 +7,15 @@ if (
|
|
|
7
7
|
browser.capabilities.browserName === 'chrome') ||
|
|
8
8
|
browser.capabilities.browserName === 'Chrome'
|
|
9
9
|
) {
|
|
10
|
-
|
|
10
|
+
// Tests for the slot system introduced by the compliance remediation in PUI-19129
|
|
11
|
+
describe('PUI-19286 - DSBreadcrumb:: slots with custom theme - Axe-Core', () => {
|
|
11
12
|
before('loading page', async () => {
|
|
12
|
-
const errorOnGo = await
|
|
13
|
+
const errorOnGo = await DSBreadcrumbCO.slotsURL.go();
|
|
13
14
|
if (errorOnGo) throw errorOnGo;
|
|
14
15
|
});
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
await
|
|
18
|
-
const dialog = await DSDialog.getDialog();
|
|
19
|
-
await dialog.waitForDisplayed();
|
|
16
|
+
|
|
17
|
+
it('01: should have no accessibility violations', async () => {
|
|
18
|
+
await (await DSBreadcrumbCO.getContainerSlot()).waitForDisplayed();
|
|
20
19
|
const result = await axeCoreCheck();
|
|
21
20
|
expect(result.length).toBe(0);
|
|
22
21
|
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import DSBreadcrumbCO from '../DSBreadcrumbCO';
|
|
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
|
+
// Tests for the slot system introduced by the compliance remediation in PUI-19129
|
|
10
|
+
describe('PUI-19284 - DSBreadcrumb:: slot wiring - Func', () => {
|
|
11
|
+
before('loading page', async () => {
|
|
12
|
+
const errorOnGo = await DSBreadcrumbCO.slotsURL.go();
|
|
13
|
+
if (errorOnGo) throw errorOnGo;
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('01: should have custom aria-* for each slot', async () => {
|
|
17
|
+
await (await DSBreadcrumbCO.getContainerSlot()).waitForDisplayed();
|
|
18
|
+
await expect(await DSBreadcrumbCO.getContainerSlot()).toHaveAttribute('aria-label', 'container aria');
|
|
19
|
+
await expect(await DSBreadcrumbCO.getListSlot()).toHaveAttribute('aria-label', 'list aria');
|
|
20
|
+
await expect(await DSBreadcrumbCO.getCrumbWrapperSlot()).toHaveAttribute('aria-label', 'crumb-wrapper aria');
|
|
21
|
+
await expect(await DSBreadcrumbCO.getLinkSlot()).toHaveAttribute('aria-label', 'link aria');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('02: should have custom data-testid for each slot', async () => {
|
|
25
|
+
await expect(await DSBreadcrumbCO.getContainerSlot()).toHaveAttribute('data-testid', 'container data');
|
|
26
|
+
await expect(await DSBreadcrumbCO.getListSlot()).toHaveAttribute('data-testid', 'list data');
|
|
27
|
+
await expect(await DSBreadcrumbCO.getCrumbWrapperSlot()).toHaveAttribute('data-testid', 'crumb-wrapper data');
|
|
28
|
+
await expect(await DSBreadcrumbCO.getLinkSlot()).toHaveAttribute('data-testid', 'link data');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('03: should have custom lang for each slot', async () => {
|
|
32
|
+
await expect(await DSBreadcrumbCO.getContainerSlot()).toHaveAttribute('lang', 'pt');
|
|
33
|
+
await expect(await DSBreadcrumbCO.getListSlot()).toHaveAttribute('lang', 'es');
|
|
34
|
+
await expect(await DSBreadcrumbCO.getCrumbWrapperSlot()).toHaveAttribute('lang', 'de');
|
|
35
|
+
await expect(await DSBreadcrumbCO.getLinkSlot()).toHaveAttribute('lang', 'fr');
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import DSBreadcrumbCO from '../DSBreadcrumbCO';
|
|
2
|
+
|
|
3
|
+
if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
|
|
4
|
+
// Tests for the slot system introduced by the compliance remediation in PUI-19129
|
|
5
|
+
describe('PUI-19285 - DSBreadcrumb:: slots with custom theme - Visual', () => {
|
|
6
|
+
before('loading page', async () => {
|
|
7
|
+
const errorOnGo = await DSBreadcrumbCO.slotsURL.go();
|
|
8
|
+
if (errorOnGo) throw errorOnGo;
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('01: should display breadcrumb with customized slots', async () => {
|
|
12
|
+
await (await DSBreadcrumbCO.getContainerSlot()).waitForDisplayed();
|
|
13
|
+
const snapshot = await browser.percyCheckScreenshot();
|
|
14
|
+
await expect(snapshot).toEqual(0);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
}
|
package/ds-chat/DSChatCO.js
CHANGED
|
@@ -13,6 +13,10 @@ export default class DSChatCO extends PageObject {
|
|
|
13
13
|
|
|
14
14
|
static loadMoreURL = new Urlbuilder(PATH_E2E_CHAT, 'container-load-more-test');
|
|
15
15
|
|
|
16
|
+
static loadMoreKeepFocusURL = new Urlbuilder(PATH_E2E_CHAT, 'container-load-more-keep-focus-test');
|
|
17
|
+
|
|
18
|
+
static visibleElementsURL = new Urlbuilder(PATH_E2E_CHAT, 'container-visible-elements-test');
|
|
19
|
+
|
|
16
20
|
static loadingURL = new Urlbuilder(PATH_E2E_CHAT, 'loading-container-test');
|
|
17
21
|
|
|
18
22
|
static loadingErrorURL = new Urlbuilder(PATH_E2E_CHAT, 'loading-error-test');
|
|
@@ -58,6 +62,22 @@ export default class DSChatCO extends PageObject {
|
|
|
58
62
|
return $('[data-testid="scroll-chat-button"]').click();
|
|
59
63
|
}
|
|
60
64
|
|
|
65
|
+
static async clickGetMessagesInView() {
|
|
66
|
+
return $('[data-testid="scroll-chat-button"]').click();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static async getMessagesInViewText() {
|
|
70
|
+
return $('[data-testid="get-messages-in-view"]').getText();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static async getOnScrollEndsText() {
|
|
74
|
+
return $('[data-testid="on-scroll-ends"]').getText();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static async getGetMoreTimesText() {
|
|
78
|
+
return $('[data-testid="get-more-times"]').getText();
|
|
79
|
+
}
|
|
80
|
+
|
|
61
81
|
static async getSentTimes() {
|
|
62
82
|
return $('[data-testid="sent"]').getText();
|
|
63
83
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Key } from 'webdriverio';
|
|
2
|
+
import DSChatCO from '../../DSChatCO';
|
|
3
|
+
|
|
4
|
+
// Tests for the migration of ChatContainer virtualization to ds-fast-list introduced in PUI-19237
|
|
5
|
+
// (getMessagesInView is backed by actionRef.getVisibleItems() and must not return a stale value)
|
|
6
|
+
if (
|
|
7
|
+
(!browser.capabilities['ice:options'].isPhone &&
|
|
8
|
+
!browser.capabilities['ice:options'].isTablet &&
|
|
9
|
+
browser.capabilities.browserName === 'chrome') ||
|
|
10
|
+
browser.capabilities.browserName === 'Chrome'
|
|
11
|
+
) {
|
|
12
|
+
describe('PUI-19297 -ChatContainer:: getMessagesInView returns the current visible messages - Func', () => {
|
|
13
|
+
before('loading page', async () => {
|
|
14
|
+
const errorOnGo = await DSChatCO.visibleElementsURL.go();
|
|
15
|
+
if (errorOnGo) throw errorOnGo;
|
|
16
|
+
});
|
|
17
|
+
it('01: should return the messages at the end of the thread, matching onScrollEnds', async () => {
|
|
18
|
+
await browser.waitUntil(async () => (await DSChatCO.getOnScrollEndsText()).split(' - ').pop() === '999', {
|
|
19
|
+
timeoutMsg: 'expected onScrollEnds to report the final message after initial scrolling',
|
|
20
|
+
});
|
|
21
|
+
const onScrollEnds = await DSChatCO.getOnScrollEndsText();
|
|
22
|
+
await expect(await DSChatCO.getMessagesInViewText()).toEqual('-');
|
|
23
|
+
await DSChatCO.clickGetMessagesInView();
|
|
24
|
+
const inView = await DSChatCO.getMessagesInViewText();
|
|
25
|
+
await expect(inView).toEqual(onScrollEnds);
|
|
26
|
+
});
|
|
27
|
+
it('02: should return the new visible messages after scrolling to the top, not the stale ones', async () => {
|
|
28
|
+
const previousInView = await DSChatCO.getMessagesInViewText();
|
|
29
|
+
const threadContainer = await DSChatCO.getThreadContainer();
|
|
30
|
+
await browser.execute((el) => el.focus(), threadContainer);
|
|
31
|
+
await browser.keys(Key.Home);
|
|
32
|
+
await browser.waitUntil(async () => (await DSChatCO.getOnScrollEndsText()).split(' - ')[0] === '0', {
|
|
33
|
+
timeoutMsg: 'expected onScrollEnds to report the first message after pressing Home',
|
|
34
|
+
});
|
|
35
|
+
await DSChatCO.clickGetMessagesInView();
|
|
36
|
+
const inView = await DSChatCO.getMessagesInViewText();
|
|
37
|
+
await expect(inView).not.toEqual(previousInView);
|
|
38
|
+
await expect(inView).toEqual(await DSChatCO.getOnScrollEndsText());
|
|
39
|
+
await expect(inView.split(' - ')[0]).toEqual('0');
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import DSChatCO from '../../DSChatCO';
|
|
2
|
+
|
|
3
|
+
// Tests for the focus rework introduced with the ds-fast-list migration in PUI-19237
|
|
4
|
+
// (a focused message keeps the focus after older messages are loaded)
|
|
5
|
+
if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
|
|
6
|
+
describe('PUI-19298 -ChatContainer:: focused message keeps focus after older messages load - Func', () => {
|
|
7
|
+
before('loading page', async () => {
|
|
8
|
+
const errorOnGo = await DSChatCO.loadMoreKeepFocusURL.go();
|
|
9
|
+
if (errorOnGo) throw errorOnGo;
|
|
10
|
+
});
|
|
11
|
+
it('01: should have the message 5 focused', async () => {
|
|
12
|
+
const message = await DSChatCO.getElementListItemByDataIndex('5');
|
|
13
|
+
await browser.execute((el) => el.focus(), message);
|
|
14
|
+
await expect(message).toBeFocused();
|
|
15
|
+
await expect(message).toHaveText(expect.stringContaining('Message text INIT Message text 5'));
|
|
16
|
+
});
|
|
17
|
+
it('02: should keep the focus on the same message after older messages are loaded', async () => {
|
|
18
|
+
await browser.keys('l');
|
|
19
|
+
await browser.waitUntil(async () => (await DSChatCO.getGetMoreTimesText()).includes('1 Times'), {
|
|
20
|
+
timeoutMsg: 'expected the older messages to be loaded',
|
|
21
|
+
});
|
|
22
|
+
// the 10 older messages are prepended, so message 5 moves from index 5 to index 15
|
|
23
|
+
const message = await DSChatCO.getElementListItemByDataIndex('15');
|
|
24
|
+
await expect(message).toHaveText(expect.stringContaining('Message text INIT Message text 5'));
|
|
25
|
+
await expect(message).toBeFocused();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -14,7 +14,7 @@ export default class DSControlledRadioCO extends PageObject {
|
|
|
14
14
|
|
|
15
15
|
static applyAriaDisabled = new Urlbuilder(PATH_E2E_RADIO, 'apply-aria-disabled-test');
|
|
16
16
|
|
|
17
|
-
static wrapLabel = new Urlbuilder(PATH_E2E_RADIO, 'wrap-label');
|
|
17
|
+
static wrapLabel = new Urlbuilder(PATH_E2E_RADIO, 'wrap-label-text-test');
|
|
18
18
|
|
|
19
19
|
static themeFontURL = new Urlbuilder(PATH_E2E_RADIO, 'theme-font-family-test');
|
|
20
20
|
|
package/ds-dialog/DSDialogCO.js
CHANGED
|
@@ -4,7 +4,7 @@ import { PATH_E2E_DIALOG } from '../paths';
|
|
|
4
4
|
import { PageObject, Urlbuilder } from '../helpers';
|
|
5
5
|
|
|
6
6
|
export default class DSDialog extends PageObject {
|
|
7
|
-
static basicURL = new Urlbuilder(PATH_E2E_DIALOG, 'basic');
|
|
7
|
+
static basicURL = new Urlbuilder(PATH_E2E_DIALOG, 'basic-test');
|
|
8
8
|
|
|
9
9
|
static centeredURL = new Urlbuilder(PATH_E2E_DIALOG, 'centered-test');
|
|
10
10
|
|
|
@@ -8,21 +8,26 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
|
|
|
8
8
|
const errorOnGo = await DSComboboxMultiCO.hundredAndOneOptions.go();
|
|
9
9
|
if (errorOnGo) throw errorOnGo;
|
|
10
10
|
});
|
|
11
|
+
// Scroll target must be the fast-list, not getComboListbox(). The latter resolves to the
|
|
12
|
+
// virtualized inner list, which is 3137px tall and starts above the viewport, so coordinates
|
|
13
|
+
// derived from its rect land outside the menu. The fast-list is the element that actually
|
|
14
|
+
// scrolls (overflow-y: auto, 300px tall). One scrollbar-track click pages by ~300px, and the
|
|
15
|
+
// menu opens pre-scrolled to the middle, so three clicks reach either target.
|
|
16
|
+
const scrollBarTarget = '[data-testid="ds-combobox-fast-list"]';
|
|
17
|
+
|
|
11
18
|
it('01: Scroll up by clicking the scrollbar', async () => {
|
|
12
19
|
await DSComboboxMultiCO.openMenuListMouse();
|
|
13
20
|
const listItem34 = await DSComboboxMultiCO.getOptionByLabel('label-34');
|
|
14
21
|
await expect(listItem34).not.toBeDisplayedInViewport();
|
|
15
|
-
|
|
16
|
-
await clickScrollBar(comboboxListBox, 'up', 5);
|
|
22
|
+
await clickScrollBar(scrollBarTarget, 'up', 3);
|
|
17
23
|
await expect(listItem34).toBeDisplayedInViewport();
|
|
18
24
|
});
|
|
19
25
|
it('02: Scroll down by clicking the scrollbar', async () => {
|
|
20
26
|
await DSComboboxMultiCO.openMenuListMouse();
|
|
21
|
-
const
|
|
22
|
-
await expect(
|
|
23
|
-
|
|
24
|
-
await
|
|
25
|
-
await expect(listItem75).toBeDisplayedInViewport();
|
|
27
|
+
const listItem85 = await DSComboboxMultiCO.getOptionByLabel('label-85');
|
|
28
|
+
await expect(listItem85).not.toBeDisplayedInViewport();
|
|
29
|
+
await clickScrollBar(scrollBarTarget, 'down', 3);
|
|
30
|
+
await expect(listItem85).toBeDisplayedInViewport();
|
|
26
31
|
});
|
|
27
32
|
});
|
|
28
33
|
}
|
|
@@ -7,7 +7,7 @@ export default class DSFormLayoutBlockItemCO extends PageObject {
|
|
|
7
7
|
|
|
8
8
|
static basicTestURL = new Urlbuilder(PATH_E2E_FORM_LAYOUT_BLOCK_ITEM, 'basic-test');
|
|
9
9
|
|
|
10
|
-
static withHighlight = new Urlbuilder(PATH_E2E_FORM_LAYOUT_BLOCK_ITEM, 'with-highlight');
|
|
10
|
+
static withHighlight = new Urlbuilder(PATH_E2E_FORM_LAYOUT_BLOCK_ITEM, 'with-highlight-e-2-e');
|
|
11
11
|
|
|
12
12
|
static withCustomHighlight = new Urlbuilder(PATH_E2E_FORM_LAYOUT_BLOCK_ITEM, 'custom-highlight-test');
|
|
13
13
|
|
|
@@ -3,7 +3,7 @@ import { PATH_E2E_GLOBAL_HEADER, PATH_E2E_GLOBAL_HEADER_PUI18647 } from '../path
|
|
|
3
3
|
import { PageObject, Urlbuilder, getElementByIndex, type } from '../helpers';
|
|
4
4
|
|
|
5
5
|
export default class GlobalHeader extends PageObject {
|
|
6
|
-
static basicURL = new Urlbuilder(PATH_E2E_GLOBAL_HEADER, 'basic');
|
|
6
|
+
static basicURL = new Urlbuilder(PATH_E2E_GLOBAL_HEADER, 'basic-test');
|
|
7
7
|
|
|
8
8
|
static oneTab = new Urlbuilder(PATH_E2E_GLOBAL_HEADER, 'one-tab');
|
|
9
9
|
|
package/ds-grid/DSGridCO.js
CHANGED
|
@@ -35,7 +35,7 @@ export default class DSGridCO extends PageObject {
|
|
|
35
35
|
|
|
36
36
|
static stickyHeaderFooter = new Urlbuilder(PATH_E2E_GRID, 'sticky-header-and-footer-test');
|
|
37
37
|
|
|
38
|
-
static tableReadOnlyURL = new Urlbuilder(PATH_E2E_GRID, 'table-read-only');
|
|
38
|
+
static tableReadOnlyURL = new Urlbuilder(PATH_E2E_GRID, 'table-read-only-test');
|
|
39
39
|
|
|
40
40
|
static tableTest = new Urlbuilder(PATH_E2E_GRID, 'table-test');
|
|
41
41
|
|
package/ds-image/DSImageCO.js
CHANGED
|
@@ -3,13 +3,13 @@ import { PATH_E2E_IMAGE } from '../paths';
|
|
|
3
3
|
import { PageObject, Urlbuilder } from '../helpers';
|
|
4
4
|
|
|
5
5
|
export default class DSImage extends PageObject {
|
|
6
|
-
static basic = new Urlbuilder(PATH_E2E_IMAGE, 'basic');
|
|
6
|
+
static basic = new Urlbuilder(PATH_E2E_IMAGE, 'basic-test');
|
|
7
7
|
|
|
8
|
-
static sizes = new Urlbuilder(PATH_E2E_IMAGE, 'sizes');
|
|
8
|
+
static sizes = new Urlbuilder(PATH_E2E_IMAGE, 'sizes-test');
|
|
9
9
|
|
|
10
|
-
static dimensions = new Urlbuilder(PATH_E2E_IMAGE, 'dimensions');
|
|
10
|
+
static dimensions = new Urlbuilder(PATH_E2E_IMAGE, 'dimensions-test');
|
|
11
11
|
|
|
12
|
-
static insideInteractive = new Urlbuilder(PATH_E2E_IMAGE, 'inside-interactive-element');
|
|
12
|
+
static insideInteractive = new Urlbuilder(PATH_E2E_IMAGE, 'inside-interactive-element-test');
|
|
13
13
|
|
|
14
14
|
static withTooltip = new Urlbuilder(PATH_E2E_IMAGE, 'with-tooltip');
|
|
15
15
|
|
|
@@ -3,7 +3,7 @@ import { PageObject, Urlbuilder } from '../helpers';
|
|
|
3
3
|
|
|
4
4
|
export default class DSIndeterminateProgressIndicatorCO extends PageObject {
|
|
5
5
|
// Desktop
|
|
6
|
-
static basicURL = new Urlbuilder(PATH_E2E_INDETERMINATE_PROGRESS_INDICATOR, 'basic');
|
|
6
|
+
static basicURL = new Urlbuilder(PATH_E2E_INDETERMINATE_PROGRESS_INDICATOR, 'basic-test');
|
|
7
7
|
|
|
8
8
|
static async getComponentWrapper() {
|
|
9
9
|
return $('[data-testid="ds-indeterminate-progress-indicator-wrapper"]');
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { PATH_E2E_LEFT_NAVIGATION_TREE } from '../paths';
|
|
2
|
+
import { PageObject, Urlbuilder } from '../helpers';
|
|
3
|
+
|
|
4
|
+
export default class LeftNavTreeCO extends PageObject {
|
|
5
|
+
static basicTreeURL = new Urlbuilder(PATH_E2E_LEFT_NAVIGATION_TREE, 'basic-tree-test');
|
|
6
|
+
|
|
7
|
+
static async getTree() {
|
|
8
|
+
return $('[data-testid="ds-leftnavigationtree-tree"]');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static async getItemById(dsId) {
|
|
12
|
+
return $(`[role="treeitem"][data-dsid="${dsId}"]`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static async getFooterCollapseButton() {
|
|
16
|
+
return $('[data-testid="ds-leftnavigationtree-footer-menu-collapse"]');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Snapshot of every rendered treeitem, in DOM order, read in a single browser round trip
|
|
20
|
+
static async getTreeItems() {
|
|
21
|
+
return browser.execute(() =>
|
|
22
|
+
[...document.querySelectorAll('[role="treeitem"]')].map((el) => ({
|
|
23
|
+
dsId: el.dataset.dsid,
|
|
24
|
+
type: el.dataset.type,
|
|
25
|
+
level: el.getAttribute('aria-level'),
|
|
26
|
+
expanded: el.getAttribute('aria-expanded'),
|
|
27
|
+
tabIndex: el.getAttribute('tabindex'),
|
|
28
|
+
current: el.getAttribute('aria-current'),
|
|
29
|
+
selected: el.getAttribute('aria-selected'),
|
|
30
|
+
testId: el.dataset.testid,
|
|
31
|
+
})),
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static async getActiveDsId() {
|
|
36
|
+
return browser.execute(() => document.activeElement?.dataset?.dsid ?? null);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static async getActiveTestId() {
|
|
40
|
+
return browser.execute(() => document.activeElement?.dataset?.testid ?? null);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static async getGroupCount() {
|
|
44
|
+
return browser.execute(() => document.querySelectorAll('[role="group"]').length);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import LeftNavTreeCO from '../LeftNavigationTreeCO';
|
|
2
|
+
|
|
3
|
+
// DOM-attribute contract: identical in every browser, so it runs on Chrome only
|
|
4
|
+
if (
|
|
5
|
+
(!browser.capabilities['ice:options'].isPhone &&
|
|
6
|
+
!browser.capabilities['ice:options'].isTablet &&
|
|
7
|
+
browser.capabilities.browserName === 'chrome') ||
|
|
8
|
+
browser.capabilities.browserName === 'Chrome'
|
|
9
|
+
) {
|
|
10
|
+
// Tests for the Tree View POC introduced in PUI-19047 (new package ds-left-navigation-tree)
|
|
11
|
+
describe('PUI-19281 - DSLeftNavigationTree:: tree semantics and testids - Func', () => {
|
|
12
|
+
before('loading page', async () => {
|
|
13
|
+
const errorOnGo = await LeftNavTreeCO.basicTreeURL.go();
|
|
14
|
+
if (errorOnGo) throw errorOnGo;
|
|
15
|
+
});
|
|
16
|
+
it('01: should render a named tree with a single tab stop and collapsed parents', async () => {
|
|
17
|
+
const tree = await LeftNavTreeCO.getTree();
|
|
18
|
+
await expect(tree).toBeDisplayed();
|
|
19
|
+
await expect(tree).toHaveAttribute('role', 'tree');
|
|
20
|
+
await expect(tree).toHaveAttribute('aria-label', 'Primary');
|
|
21
|
+
|
|
22
|
+
const items = await LeftNavTreeCO.getTreeItems();
|
|
23
|
+
await expect(items.map((item) => item.dsId)).toEqual([
|
|
24
|
+
'e2e-documents',
|
|
25
|
+
'e2e-forms',
|
|
26
|
+
'e2e-conditions',
|
|
27
|
+
'e2e-services',
|
|
28
|
+
]);
|
|
29
|
+
await expect(items.map((item) => item.level)).toEqual(['1', '1', '1', '1']);
|
|
30
|
+
await expect(items.every((item) => item.testId === 'ds-leftnavigationtree-item')).toBe(true);
|
|
31
|
+
// aria-expanded only on parents; leaves never carry it
|
|
32
|
+
await expect(items.map((item) => item.expanded)).toEqual([null, 'false', null, 'false']);
|
|
33
|
+
// the current page is exposed with aria-current, never aria-selected
|
|
34
|
+
await expect(items.every((item) => item.current === null && item.selected === null)).toBe(true);
|
|
35
|
+
// roving tab stop: exactly one treeitem is tabbable
|
|
36
|
+
await expect(items.filter((item) => item.tabIndex === '0').length).toBe(1);
|
|
37
|
+
await expect(await LeftNavTreeCO.getGroupCount()).toBe(0);
|
|
38
|
+
});
|
|
39
|
+
it('02: should expose children in a group with their level once a parent opens', async () => {
|
|
40
|
+
await (await LeftNavTreeCO.getItemById('e2e-forms')).click();
|
|
41
|
+
const forms = await LeftNavTreeCO.getItemById('e2e-forms');
|
|
42
|
+
await expect(forms).toHaveAttribute('aria-expanded', 'true');
|
|
43
|
+
|
|
44
|
+
const items = await LeftNavTreeCO.getTreeItems();
|
|
45
|
+
const children = items.filter((item) => item.dsId.startsWith('e2e-forms-child-'));
|
|
46
|
+
await expect(children.length).toBe(3);
|
|
47
|
+
await expect(children.every((item) => item.level === '2' && item.expanded === null)).toBe(true);
|
|
48
|
+
await expect(await LeftNavTreeCO.getGroupCount()).toBe(1);
|
|
49
|
+
});
|
|
50
|
+
it('03: should mark only the activated page with aria-current', async () => {
|
|
51
|
+
// activating a closed parent made its first child the current page
|
|
52
|
+
let current = (await LeftNavTreeCO.getTreeItems()).filter((item) => item.current !== null);
|
|
53
|
+
await expect(current.map((item) => `${item.dsId}=${item.current}`)).toEqual(['e2e-forms-child-1=page']);
|
|
54
|
+
|
|
55
|
+
await (await LeftNavTreeCO.getItemById('e2e-conditions')).click();
|
|
56
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-conditions')).toHaveAttribute('aria-current', 'page');
|
|
57
|
+
current = (await LeftNavTreeCO.getTreeItems()).filter((item) => item.current !== null);
|
|
58
|
+
await expect(current.map((item) => `${item.dsId}=${item.current}`)).toEqual(['e2e-conditions=page']);
|
|
59
|
+
await expect((await LeftNavTreeCO.getTreeItems()).every((item) => item.selected === null)).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import LeftNavTreeCO from '../LeftNavigationTreeCO';
|
|
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
|
+
// Tests for the Tree View POC introduced in PUI-19047 (new package ds-left-navigation-tree)
|
|
11
|
+
describe('PUI-19283 - DSLeftNavigationTree:: accessibility before and after opening a parent - Axe-Core', () => {
|
|
12
|
+
before('loading page', async () => {
|
|
13
|
+
const errorOnGo = await LeftNavTreeCO.basicTreeURL.go();
|
|
14
|
+
if (errorOnGo) throw errorOnGo;
|
|
15
|
+
});
|
|
16
|
+
it('01: should have no accessibility violations with every parent closed', async () => {
|
|
17
|
+
await (await LeftNavTreeCO.getTree()).waitForDisplayed();
|
|
18
|
+
const result = await axeCoreCheck();
|
|
19
|
+
await expect(result.length).toBe(0);
|
|
20
|
+
});
|
|
21
|
+
it('02: should have no accessibility violations with a parent open', async () => {
|
|
22
|
+
await (await LeftNavTreeCO.getItemById('e2e-forms')).click();
|
|
23
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-forms')).toHaveAttribute('aria-expanded', 'true');
|
|
24
|
+
const result = await axeCoreCheck();
|
|
25
|
+
await expect(result.length).toBe(0);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Key } from 'webdriverio';
|
|
2
|
+
import LeftNavTreeCO from '../LeftNavigationTreeCO';
|
|
3
|
+
|
|
4
|
+
if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
|
|
5
|
+
// Tests for the Tree View POC introduced in PUI-19047 (new package ds-left-navigation-tree)
|
|
6
|
+
describe('PUI-19282 - DSLeftNavigationTree:: keyboard navigation - Func', () => {
|
|
7
|
+
before('loading page', async () => {
|
|
8
|
+
const errorOnGo = await LeftNavTreeCO.basicTreeURL.go();
|
|
9
|
+
if (errorOnGo) throw errorOnGo;
|
|
10
|
+
});
|
|
11
|
+
it('01: should focus the first node on entering the tree [Tab]', async () => {
|
|
12
|
+
await (await LeftNavTreeCO.getTree()).waitForDisplayed();
|
|
13
|
+
await browser.keys(Key.Tab);
|
|
14
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-documents')).toBeFocused();
|
|
15
|
+
});
|
|
16
|
+
it('02: should move between visible nodes without wrapping [ArrowDown][ArrowUp][Home][End]', async () => {
|
|
17
|
+
await browser.keys(Key.ArrowDown);
|
|
18
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-forms')).toBeFocused();
|
|
19
|
+
await browser.keys(Key.End);
|
|
20
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-services')).toBeFocused();
|
|
21
|
+
await browser.keys(Key.ArrowDown);
|
|
22
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-services')).toBeFocused();
|
|
23
|
+
await browser.keys(Key.Home);
|
|
24
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-documents')).toBeFocused();
|
|
25
|
+
await browser.keys(Key.ArrowUp);
|
|
26
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-documents')).toBeFocused();
|
|
27
|
+
// roving tab stop follows the focused node
|
|
28
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-documents')).toHaveAttribute('tabindex', '0');
|
|
29
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-forms')).toHaveAttribute('tabindex', '-1');
|
|
30
|
+
});
|
|
31
|
+
it('03: should jump to the next node starting with the typed character [c][f]', async () => {
|
|
32
|
+
await browser.keys('c');
|
|
33
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-conditions')).toBeFocused();
|
|
34
|
+
await browser.keys('f');
|
|
35
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-forms')).toBeFocused();
|
|
36
|
+
});
|
|
37
|
+
it('04: should open, enter, leave and close a parent [ArrowRight][ArrowLeft]', async () => {
|
|
38
|
+
await browser.keys(Key.ArrowRight);
|
|
39
|
+
const forms = await LeftNavTreeCO.getItemById('e2e-forms');
|
|
40
|
+
await expect(forms).toHaveAttribute('aria-expanded', 'true');
|
|
41
|
+
await expect(forms).toBeFocused();
|
|
42
|
+
await browser.keys(Key.ArrowRight);
|
|
43
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-forms-child-1')).toBeFocused();
|
|
44
|
+
await browser.keys(Key.ArrowLeft);
|
|
45
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-forms')).toBeFocused();
|
|
46
|
+
await browser.keys(Key.ArrowLeft);
|
|
47
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-forms')).toHaveAttribute('aria-expanded', 'false');
|
|
48
|
+
await expect(await LeftNavTreeCO.getGroupCount()).toBe(0);
|
|
49
|
+
});
|
|
50
|
+
it('05: should toggle a parent and select its first page [Enter]', async () => {
|
|
51
|
+
await browser.keys(Key.Enter);
|
|
52
|
+
const forms = await LeftNavTreeCO.getItemById('e2e-forms');
|
|
53
|
+
await expect(forms).toHaveAttribute('aria-expanded', 'true');
|
|
54
|
+
await expect(forms).toBeFocused();
|
|
55
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-forms-child-1')).toHaveAttribute('aria-current', 'page');
|
|
56
|
+
await browser.keys(Key.Enter);
|
|
57
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-forms')).toHaveAttribute('aria-expanded', 'false');
|
|
58
|
+
await expect(await LeftNavTreeCO.getItemById('e2e-forms')).toBeFocused();
|
|
59
|
+
});
|
|
60
|
+
it('06: should leave the tree with a single [Tab]', async () => {
|
|
61
|
+
await browser.keys(Key.Tab);
|
|
62
|
+
await expect(await LeftNavTreeCO.getActiveDsId()).toBe(null);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|