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
|
@@ -129,3 +129,41 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
|
|
|
129
129
|
});
|
|
130
130
|
});
|
|
131
131
|
}
|
|
132
|
+
|
|
133
|
+
// DOM-attribute contract: identical in every browser, so it runs on Chrome only
|
|
134
|
+
if (
|
|
135
|
+
(!browser.capabilities['ice:options'].isPhone &&
|
|
136
|
+
!browser.capabilities['ice:options'].isTablet &&
|
|
137
|
+
browser.capabilities.browserName === 'chrome') ||
|
|
138
|
+
browser.capabilities.browserName === 'Chrome'
|
|
139
|
+
) {
|
|
140
|
+
// Tests for the compliance remediation introduced in PUI-19115 (named slots, new data-testids)
|
|
141
|
+
describe('PUI-19280 - LeftNavigation:: truncated label and open window icon testids - Func', () => {
|
|
142
|
+
before('loading page', async () => {
|
|
143
|
+
const errorOnGo = await LeftNavCO.fullFeatures.go();
|
|
144
|
+
if (errorOnGo) throw errorOnGo;
|
|
145
|
+
});
|
|
146
|
+
it('01: should keep ds-icon-root on open window icons', async () => {
|
|
147
|
+
await (await LeftNavCO.leftNavItem(0)).click();
|
|
148
|
+
await browser.waitUntil(async () => (await LeftNavCO.getOpenWindowIconTestIds()).length > 0, {
|
|
149
|
+
timeoutMsg: 'expected open window icons to be rendered after opening the first item',
|
|
150
|
+
});
|
|
151
|
+
const testIds = await LeftNavCO.getOpenWindowIconTestIds();
|
|
152
|
+
await expect(testIds.every((testId) => testId === 'ds-icon-root')).toBe(true);
|
|
153
|
+
});
|
|
154
|
+
it('02: should show the tooltip testid only while hovering a truncated label', async () => {
|
|
155
|
+
await (await LeftNavCO.leftNavItem(0)).click();
|
|
156
|
+
const truncItem = await LeftNavCO.getTruncatedText(0);
|
|
157
|
+
await truncItem.waitForDisplayed();
|
|
158
|
+
const truncatedTexts = await LeftNavCO.getTruncatedLabelTexts();
|
|
159
|
+
await expect(truncatedTexts[0]).toBe('Exception-1 Truncated Content');
|
|
160
|
+
await expect(await LeftNavCO.getTruncatedLabelTooltip()).not.toBeExisting();
|
|
161
|
+
await mouseOver(truncItem);
|
|
162
|
+
const tooltip = await LeftNavCO.getTruncatedLabelTooltip();
|
|
163
|
+
await tooltip.waitForDisplayed();
|
|
164
|
+
await expect(tooltip).toHaveText('Exception-1 Truncated Content');
|
|
165
|
+
await mouseOver(null, 0, 0);
|
|
166
|
+
await expect(await LeftNavCO.getTruncatedLabelTooltip()).not.toBeExisting();
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
@@ -78,6 +78,26 @@ export default class LeftNavCO extends PageObject {
|
|
|
78
78
|
return $('[data-testid="ds-floating-wrapper-root"]');
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
static async getTruncatedLabelTexts() {
|
|
82
|
+
return browser.execute(() =>
|
|
83
|
+
[...document.querySelectorAll('[data-testid="ds-leftnavigation-truncated-label"]')].map((el) =>
|
|
84
|
+
el.textContent.trim(),
|
|
85
|
+
),
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
static async getTruncatedLabelTooltip() {
|
|
90
|
+
return $('[data-testid="ds-leftnavigation-truncated-label-tooltip"]');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
static async getOpenWindowIconTestIds() {
|
|
94
|
+
return browser.execute(() =>
|
|
95
|
+
[...document.querySelectorAll('[data-dimsum-parent-slot="dsLeftnavigationOpenWindowIcon"]')].map(
|
|
96
|
+
(el) => el.dataset.testid,
|
|
97
|
+
),
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
81
101
|
static async getSubItemBtn() {
|
|
82
102
|
return $('[data-testid="sub-item-button"]');
|
|
83
103
|
}
|
|
@@ -3,15 +3,15 @@ import { PageObject, Urlbuilder } from '../helpers';
|
|
|
3
3
|
|
|
4
4
|
export default class DSMenuButtonCO extends PageObject {
|
|
5
5
|
// Current supported examples: POC
|
|
6
|
-
static activableMenuItem = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'activable-menu-item');
|
|
6
|
+
static activableMenuItem = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'activable-menu-item-test');
|
|
7
7
|
|
|
8
|
-
static multipleSelectMenuItem = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'multiple-select-menu-item');
|
|
8
|
+
static multipleSelectMenuItem = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'multiple-select-menu-item-test');
|
|
9
9
|
|
|
10
10
|
static nextTabstopTest = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'next-tabstop-test');
|
|
11
11
|
|
|
12
|
-
static singleSelectMenuItem = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'single-select-menu-item');
|
|
12
|
+
static singleSelectMenuItem = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'single-select-menu-item-test');
|
|
13
13
|
|
|
14
|
-
static withSubmenuMenuItem = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'with-submenu-menu-item');
|
|
14
|
+
static withSubmenuMenuItem = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'with-submenu-menu-item-test');
|
|
15
15
|
|
|
16
16
|
static withDisabled = new Urlbuilder(PATH_E2E_MENU_BUTTON, 'disabled-items-test');
|
|
17
17
|
|
|
@@ -7,8 +7,6 @@ export default class DSQueryBuilderCO extends PageObject {
|
|
|
7
7
|
|
|
8
8
|
static inModalURL = new Urlbuilder(PATH_E2E_QUERY_BUILDER, 'pui-5837-in-modal');
|
|
9
9
|
|
|
10
|
-
static advancedDependencies = new Urlbuilder(PATH_QUERY_BUILDER, 'advanced-dependencies');
|
|
11
|
-
|
|
12
10
|
static arrayConditionsURL = new Urlbuilder(PATH_QUERY_BUILDER, 'advanced-dependencies-array');
|
|
13
11
|
|
|
14
12
|
static fieldDateRangePicker = new Urlbuilder(PATH_QUERY_BUILDER, 'field-date-range-picker');
|
package/ds-svg/DSSvgCO.js
CHANGED
|
@@ -2,15 +2,15 @@ import { PATH_E2E_SVG } from '../paths';
|
|
|
2
2
|
import { PageObject, Urlbuilder } from '../helpers';
|
|
3
3
|
|
|
4
4
|
export default class DSSvgCO extends PageObject {
|
|
5
|
-
static basic = new Urlbuilder(PATH_E2E_SVG, 'basic');
|
|
5
|
+
static basic = new Urlbuilder(PATH_E2E_SVG, 'basic-test');
|
|
6
6
|
|
|
7
|
-
static sizes = new Urlbuilder(PATH_E2E_SVG, 'sizes');
|
|
7
|
+
static sizes = new Urlbuilder(PATH_E2E_SVG, 'sizes-test');
|
|
8
8
|
|
|
9
|
-
static dimensions = new Urlbuilder(PATH_E2E_SVG, 'dimensions');
|
|
9
|
+
static dimensions = new Urlbuilder(PATH_E2E_SVG, 'dimensions-test');
|
|
10
10
|
|
|
11
|
-
static insideInteractive = new Urlbuilder(PATH_E2E_SVG, 'inside-interactive-element');
|
|
11
|
+
static insideInteractive = new Urlbuilder(PATH_E2E_SVG, 'inside-interactive-element-test');
|
|
12
12
|
|
|
13
|
-
static withTooltip = new Urlbuilder(PATH_E2E_SVG, 'with-tooltip');
|
|
13
|
+
static withTooltip = new Urlbuilder(PATH_E2E_SVG, 'with-tooltip-test');
|
|
14
14
|
|
|
15
15
|
// Selectors
|
|
16
16
|
static async getWrapper() {
|
|
@@ -80,7 +80,9 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
|
|
|
80
80
|
const snapshot = await browser.checkSnapshot(DSTabsCO.snapshotPath('tab-grid-default'));
|
|
81
81
|
await expect(snapshot).toEqual(0);
|
|
82
82
|
});
|
|
83
|
-
|
|
83
|
+
// Percy intermittently never completes this snapshot (any browser, only when run alongside other snapshots), marks
|
|
84
|
+
// the whole build as failed and rejects every later snapshot. Re-enable once Percy support resolves it.
|
|
85
|
+
it.skip('should display tabs with a grid moved one tablist to the right', async () => {
|
|
84
86
|
// const tab1 = await DSTabsCO.getTab(1);
|
|
85
87
|
// await tab1.click();
|
|
86
88
|
const tab2 = await DSTabsCO.getTab(2);
|
|
@@ -153,12 +153,16 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
|
|
|
153
153
|
const bottomLeftBtn = await DSToastCO.openToastPositionBtn('bottom-left');
|
|
154
154
|
const bottomCenterBtn = await DSToastCO.openToastPositionBtn('bottom-center');
|
|
155
155
|
const bottomRightBtn = await DSToastCO.openToastPositionBtn('bottom-right');
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
// Click order matters: all six triggers sit within y 0-88, and the top-* toast containers
|
|
157
|
+
// render over y 13-97 with autoClose disabled. Clicking the top row first covers the bottom
|
|
158
|
+
// row and WebDriver rejects the click as intercepted. Bottom row first keeps every trigger
|
|
159
|
+
// clickable (bottom containers sit at y 983-1067) and yields the same final state.
|
|
159
160
|
await bottomLeftBtn.click();
|
|
160
161
|
await bottomCenterBtn.click();
|
|
161
162
|
await bottomRightBtn.click();
|
|
163
|
+
await topLeftBtn.click();
|
|
164
|
+
await topCenterBtn.click();
|
|
165
|
+
await topRigthBtn.click();
|
|
162
166
|
await browser.pause(2000);
|
|
163
167
|
const topLeftToast = await DSToastCO.getToastByPosition('top-left');
|
|
164
168
|
const topCenterToast = await DSToastCO.getToastByPosition('top-center');
|
package/ds-toast/DSToastCO.js
CHANGED
|
@@ -13,7 +13,7 @@ export default class DSToastCO extends PageObject {
|
|
|
13
13
|
|
|
14
14
|
static longTextURL = new Urlbuilder(PATH_E2E_TOAST, 'long-text-test');
|
|
15
15
|
|
|
16
|
-
static longTextWithLinkURL = new Urlbuilder(PATH_E2E_TOAST, 'long-text-with-link');
|
|
16
|
+
static longTextWithLinkURL = new Urlbuilder(PATH_E2E_TOAST, 'long-text-with-link-test');
|
|
17
17
|
|
|
18
18
|
static multipleToastURL = new Urlbuilder(PATH_E2E_TOAST, 'multiple-toast-test');
|
|
19
19
|
|
|
@@ -17,7 +17,7 @@ export const knobs = {
|
|
|
17
17
|
export default class DSTreeViewCO extends PageObject {
|
|
18
18
|
static basicUrl = new Urlbuilder(PATH_TREEVIEW, 'basic');
|
|
19
19
|
|
|
20
|
-
static compactURL = new Urlbuilder(PATH_TREEVIEW, 'compact');
|
|
20
|
+
static compactURL = new Urlbuilder(PATH_TREEVIEW, 'compact-view');
|
|
21
21
|
|
|
22
22
|
static fluidHeightURL = new Urlbuilder(PATH_TREEVIEW, 'fluid-height');
|
|
23
23
|
|
|
@@ -3,13 +3,13 @@ import { PageObject, Urlbuilder, getElementByIndex } from '../helpers';
|
|
|
3
3
|
|
|
4
4
|
export default class DSTypographyCO extends PageObject {
|
|
5
5
|
// Desktop
|
|
6
|
-
static cardURL = new Urlbuilder(PATH_E2E_TYPOGRAPHY, 'card');
|
|
6
|
+
static cardURL = new Urlbuilder(PATH_E2E_TYPOGRAPHY, 'card-read-more');
|
|
7
7
|
|
|
8
|
-
static formURl = new Urlbuilder(PATH_E2E_TYPOGRAPHY, 'form');
|
|
8
|
+
static formURl = new Urlbuilder(PATH_E2E_TYPOGRAPHY, 'form-test');
|
|
9
9
|
|
|
10
|
-
static dialogURL = new Urlbuilder(PATH_E2E_TYPOGRAPHY, 'dialog');
|
|
10
|
+
static dialogURL = new Urlbuilder(PATH_E2E_TYPOGRAPHY, 'dialog-test');
|
|
11
11
|
|
|
12
|
-
static showcaseURL = new Urlbuilder(PATH_E2E_TYPOGRAPHY, 'show-case');
|
|
12
|
+
static showcaseURL = new Urlbuilder(PATH_E2E_TYPOGRAPHY, 'show-case-test');
|
|
13
13
|
|
|
14
14
|
static truncationURL = new Urlbuilder(PATH_E2E_TYPOGRAPHY, 'truncation-test');
|
|
15
15
|
|
package/helpers.js
CHANGED
|
@@ -402,66 +402,54 @@ export async function getLocationByDataTestId(dataTest, index) {
|
|
|
402
402
|
return result;
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
+
// Inset from the element's top/bottom edge for the scrollbar click. Classic Windows scrollbars
|
|
406
|
+
// render an arrow button (~17px) at each end: clicking it scrolls a single line, while clicking the
|
|
407
|
+
// track scrolls a full page. Clearing the arrow is what makes a click page instead of nudge.
|
|
408
|
+
const SCROLLBAR_ARROW_INSET = 30;
|
|
409
|
+
|
|
405
410
|
/**
|
|
406
|
-
* Simulates clicks on the scrollbar of an element to
|
|
411
|
+
* Simulates clicks on the scrollbar track of an element to page its content.
|
|
407
412
|
*
|
|
408
|
-
* For "down" direction
|
|
409
|
-
*
|
|
410
|
-
* to simulate a more realistic click.
|
|
413
|
+
* For "down" direction it clicks the track near the bottom of the element; for "up", near the top.
|
|
414
|
+
* Both are inset far enough to clear the scrollbar's arrow buttons. A pause is added between
|
|
415
|
+
* pointerDown and pointerUp to simulate a more realistic click.
|
|
411
416
|
*
|
|
412
|
-
* @param {string|object} element - Element or selector for the element
|
|
417
|
+
* @param {string|object} element - Element or selector for the element that scrolls (the one with
|
|
418
|
+
* overflow-y: auto/scroll, not an inner content wrapper).
|
|
413
419
|
* @param {string} direction - Scroll direction: 'up' or 'down' (default: 'down').
|
|
414
420
|
* @param {number} clicks - Number of clicks to simulate (default: 1).
|
|
415
421
|
*/
|
|
416
422
|
export async function clickScrollBar(element, direction = 'down', clicks = 1) {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
if (!elem) {
|
|
420
|
-
throw new Error('Element not found.');
|
|
423
|
+
if (direction !== 'up' && direction !== 'down') {
|
|
424
|
+
throw new Error("Invalid direction: choose 'up' or 'down'");
|
|
421
425
|
}
|
|
422
426
|
|
|
423
|
-
//
|
|
424
|
-
|
|
427
|
+
// Page viewport, not browser.getWindowSize(): the latter reports the outer window, which includes
|
|
428
|
+
// the titlebar and toolbar, so clamping against it can yield a y below the page and make
|
|
429
|
+
// performActions fail with "move target out of bounds".
|
|
430
|
+
const viewport = await browser.execute(() => ({ width: window.innerWidth, height: window.innerHeight }));
|
|
425
431
|
|
|
426
|
-
// Loop to simulate each click.
|
|
427
432
|
for (let i = 0; i < clicks; i++) {
|
|
428
|
-
// Re-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
rect = await browser.execute((el) => {
|
|
434
|
-
const r = el.getBoundingClientRect();
|
|
435
|
-
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
436
|
-
}, elem);
|
|
433
|
+
// Re-resolve on every iteration. Virtualized and portalled scrollers re-render between clicks,
|
|
434
|
+
// and a cached element reference would raise "stale element reference".
|
|
435
|
+
const elem = typeof element === 'string' ? await $(element) : element;
|
|
436
|
+
if (!(await elem.isExisting())) {
|
|
437
|
+
throw new Error(`clickScrollBar: element no longer exists on click ${i + 1} of ${clicks}.`);
|
|
437
438
|
}
|
|
438
439
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
// Para scroll up: click en el área superior.
|
|
453
|
-
yCoord = topLimit + i * 5; // Ajusta el valor (por ejemplo, 5px) según sea necesario.
|
|
454
|
-
} else {
|
|
455
|
-
throw new Error("Invalid direction: choose 'up' or 'down'");
|
|
456
|
-
}
|
|
457
|
-
// Asegurarse de que yCoord esté dentro de los límites del elemento.
|
|
458
|
-
if (direction === 'down') {
|
|
459
|
-
yCoord = Math.min(yCoord, bottomLimit);
|
|
460
|
-
} else {
|
|
461
|
-
yCoord = Math.max(yCoord, topLimit);
|
|
462
|
-
}
|
|
463
|
-
// Clamp yCoord within viewport.
|
|
464
|
-
yCoord = Math.max(0, Math.min(yCoord, viewport.height - 1));
|
|
440
|
+
const rect = await browser.execute((el) => {
|
|
441
|
+
const r = el.getBoundingClientRect();
|
|
442
|
+
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
443
|
+
}, elem);
|
|
444
|
+
|
|
445
|
+
// x: inside the scrollbar band, 5px from the right edge.
|
|
446
|
+
const xCoord = Math.max(0, Math.min(Math.round(rect.x + rect.width - 5), viewport.width - 1));
|
|
447
|
+
|
|
448
|
+
const inset = Math.min(SCROLLBAR_ARROW_INSET, Math.max(1, Math.round(rect.height / 2) - 1));
|
|
449
|
+
const rawY = direction === 'down' ? rect.y + rect.height - inset : rect.y + inset;
|
|
450
|
+
// Keep the point inside the element, then inside the viewport.
|
|
451
|
+
const boundedY = Math.min(Math.max(Math.round(rawY), Math.round(rect.y) + 1), Math.round(rect.y + rect.height) - 1);
|
|
452
|
+
const yCoord = Math.max(0, Math.min(boundedY, viewport.height - 1));
|
|
465
453
|
|
|
466
454
|
// Perform the click action with a pause to simulate a more realistic manual click.
|
|
467
455
|
await browser.performActions([
|