dimsum-e2e-tests 3.80.0-next.3 → 3.80.0-next.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/DSStorybook/baseline.js +0 -186
  3. package/ds-accordion/DSAccordion.visual.spec.js +0 -14
  4. package/ds-accordion/DSAccordionCO.js +0 -2
  5. package/ds-apppicker/aria-disabled/DSAppPicker.aria-disabled.visual.spec.js +14 -1
  6. package/ds-apppicker/basic/DSAppPicker.basic.visual.spec.js +12 -7
  7. package/ds-banner/DSBanner.text-wrapping.visual.spec.js +3 -6
  8. package/ds-banner/DSBanner.visual.spec.js +7 -8
  9. package/ds-banner/DSBannerCO.js +4 -5
  10. package/ds-banner/slots/DSBanner.slots.func.spec.js +6 -0
  11. package/ds-banner/slots/DSBanner.slots.visual.spec.js +1 -2
  12. package/ds-chip/DSChip.axe-core.func.spec.js +0 -17
  13. package/ds-chip/DSChip.visual.spec.js +0 -22
  14. package/ds-chip/DSChipCO.js +0 -6
  15. package/ds-fast-list/DSFastListCO.js +37 -0
  16. package/ds-fast-list/basic/DSFastList.basic.axe-core.func.spec.js +28 -0
  17. package/ds-fast-list/basic/DSFastList.basic.visual.spec.js +23 -0
  18. package/ds-fast-list/scroll-to-index/DSFastList.scroll-to-index.func.spec.js +45 -0
  19. package/ds-indeterminate-progress-indicator/DSIndeterminateProgressIndicatorCO.js +4 -0
  20. package/ds-indeterminate-progress-indicator/accessible-name/DSIndeterminateProgressIndicator.accessible-name.func.spec.js +51 -0
  21. package/ds-leftnavigation/LeftNavigation.fullFeatures.axe-core.func.spec.js +37 -0
  22. package/ds-leftnavigation/LeftNavigation.isSkeleton.axe-core.func.spec.js +23 -0
  23. package/ds-leftnavigation/LeftNavigation.keepingItems.axe-core.func.spec.js +34 -0
  24. package/ds-leftnavigation/LeftNavigation.loadingIndicator.axe-core.func.spec.js +41 -0
  25. package/ds-leftnavigation/LeftNavigation.notificationBadge.axe-core.func.spec.js +21 -0
  26. package/ds-leftnavigation/LeftNavigation.searchBar.axe-core.func.spec.js +26 -0
  27. package/ds-leftnavigation/LeftNavigation.showCase.axe-core.func.spec.js +23 -0
  28. package/ds-leftnavigation/LeftNavigation.tooltip.axe-core.func.spec.js +28 -0
  29. package/ds-leftnavigation/LeftNavigation.wrappedText.axe-core.func.spec.js +27 -0
  30. package/ds-panel-header/DSPanelHeader.func.spec.js +24 -0
  31. package/ds-panel-header/DSPanelHeaderCO.js +17 -0
  32. package/ds-pills-v2/DSPillsV2CO.js +53 -1
  33. package/ds-pills-v2/pitfalls/DSPills.inputPill.func.spec.js +26 -0
  34. package/ds-pills-v2/pitfalls/DSPills.inputWithFormItemBlockURL.axe-core.func.spec.js +38 -0
  35. package/ds-pills-v2/pitfalls/DSPills.inputWithFormItemBlockURL.func.spec.js +72 -0
  36. package/ds-progress-indicator/DSProgressIndicator.axe-core.func.spec.js +8 -5
  37. package/ds-progress-indicator/DSProgressIndicator.func.spec.js +31 -4
  38. package/ds-progress-indicator/DSProgressIndicator.visual.spec.js +14 -6
  39. package/ds-progress-indicator/DSProgressIndicatorCO.js +87 -9
  40. package/ds-progress-indicator/aria-contract/DSProgressIndicator.aria-contract.func.spec.js +104 -0
  41. package/ds-progress-indicator/slots/DSProgressIndicator.slots.axe-core.func.spec.js +31 -0
  42. package/ds-progress-indicator/slots/DSProgressIndicator.slots.func.spec.js +87 -0
  43. package/ds-progress-indicator/slots/DSProgressIndicator.slots.visual.spec.js +27 -0
  44. package/ds-progress-indicator/variant/DSProgressIndicator.single-bar-variant.func.spec.js +44 -0
  45. package/ds-progress-indicator/variant/DSProgressIndicator.single-bar-variant.visual.spec.js +19 -0
  46. package/ds-slider-v2/DSSliderV2.axe-core.func.spec.js +21 -0
  47. package/ds-slider-v2/DSSliderV2.visual.spec.js +19 -1
  48. package/ds-slider-v2/DSSliderV2CO.js +6 -1
  49. package/ds-slider-v2/has-error/DSSliderV2.has-error.visual.spec.js +44 -0
  50. package/ds-slider-v2/interaction-states/DSSliderV2.interaction-states.visual.spec.js +53 -0
  51. package/ds-virtuallist/DSVirtualList.visual.spec.js +4 -5
  52. package/ds-virtuallist/DSVirtualListCO.js +28 -9
  53. package/ds-virtuallist/basic/DSVirtualList.basic.axe-core.func.spec.js +28 -0
  54. package/ds-virtuallist/scroll-to-index/DSVirtualList.scroll-to-index.func.spec.js +45 -0
  55. package/package.json +149 -149
  56. package/paths.js +3 -49
  57. package/ds-leftnavigation/LeftNavigation.axe-core.func.spec.js +0 -172
  58. package/ds-mobile/Accordion/DSAccordion.visual.spec.js +0 -33
  59. package/ds-mobile/Accordion/DSAccordionCO.js +0 -37
  60. package/ds-mobile/CategoryBox/CategoryBox.visual.spec.js +0 -18
  61. package/ds-mobile/CategoryBox/CategoryBoxCO.js +0 -17
  62. package/ds-mobile/CollectionBox/CollectionBox.visual.spec.js +0 -16
  63. package/ds-mobile/CollectionBox/CollectionBoxCO.js +0 -15
  64. package/ds-mobile/GlobalHeader/DSGlobalHeader.visual.spec.js +0 -55
  65. package/ds-mobile/GlobalHeader/DSGlobalHeaderCO.js +0 -36
  66. package/ds-mobile/GroupBox/GroupBox.visual.spec.js +0 -15
  67. package/ds-mobile/GroupBox/GroupBoxCO.js +0 -15
  68. package/ds-mobile/InfiniteLoader/InfiniteLoader.func.spec.js +0 -90
  69. package/ds-mobile/InfiniteLoader/InfiniteLoaderCO.js +0 -29
  70. package/ds-mobile/MobileActionToolbar/MobileActionToolbar.visual.spec.js +0 -39
  71. package/ds-mobile/MobileActionToolbar/MobileActionToolbarCO.js +0 -19
  72. package/ds-mobile/MobileBanner/MobileBanner.visual.spec.js +0 -23
  73. package/ds-mobile/MobileBanner/MobileBannerCO.js +0 -23
  74. package/ds-mobile/MobileCard/Card.func.spec.js +0 -38
  75. package/ds-mobile/MobileCard/Card.visual.spec.js +0 -103
  76. package/ds-mobile/MobileCard/MobileCardCO.js +0 -42
  77. package/ds-mobile/MobileContextMenu/MobileContextMenu.func.spec.js +0 -88
  78. package/ds-mobile/MobileContextMenu/MobileContextMenu.visual.spec.js +0 -31
  79. package/ds-mobile/MobileContextMenu/MobileContextMenuCO.js +0 -72
  80. package/ds-mobile/MobileDatePicker/MobileDatePicker.func.spec.js +0 -15
  81. package/ds-mobile/MobileDatePicker/MobileDatePicker.visual.spec.js +0 -15
  82. package/ds-mobile/MobileDatePicker/MobileDatePickerCO.js +0 -35
  83. package/ds-mobile/MobileDropdownMenu/MobileDropdownMenu.func.spec.js +0 -38
  84. package/ds-mobile/MobileDropdownMenu/MobileDropdownMenu.visual.spec.js +0 -16
  85. package/ds-mobile/MobileDropdownMenu/MobileDropdownMenuCO.js +0 -37
  86. package/ds-mobile/MobileEmptyState/MobileEmptyState.visual.spec.js +0 -15
  87. package/ds-mobile/MobileEmptyState/MobileEmptyStateCO.js +0 -14
  88. package/ds-mobile/MobileFilterbar/MobileFilterbar.visual.spec.js +0 -39
  89. package/ds-mobile/MobileFilterbar/MobileFilterbarCO.js +0 -19
  90. package/ds-mobile/MobileFooter/MobileFooter.func.spec.js +0 -26
  91. package/ds-mobile/MobileFooter/MobileFooter.visual.spec.js +0 -51
  92. package/ds-mobile/MobileFooter/MobileFooterCO.js +0 -27
  93. package/ds-mobile/MobileListItem/MobileListItem.visual.spec.js +0 -56
  94. package/ds-mobile/MobileListItem/MobileListItemCO.js +0 -19
  95. package/ds-mobile/MobileLoadingPage/MobileLoadingPage.visual.spec.js +0 -37
  96. package/ds-mobile/MobileLoadingPage/MobileLoadingPageCO.js +0 -23
  97. package/ds-mobile/MobilePageHeader/MobilePageHeader.func.spec.js +0 -22
  98. package/ds-mobile/MobilePageHeader/MobilePageHeader.visual.spec.js +0 -135
  99. package/ds-mobile/MobilePageHeader/MobilePageHeaderCO.js +0 -67
  100. package/ds-mobile/MobileSelectList/MobileSelectList.visual.spec.js +0 -56
  101. package/ds-mobile/MobileSelectList/MobileSelectListCO.js +0 -21
  102. package/ds-mobile/MobileSeparator/MobileSeparator.visual.spec.js +0 -28
  103. package/ds-mobile/MobileSeparator/MobileSeparatorCO.js +0 -17
  104. package/ds-mobile/MobileTimePicker/MobileTimePickerCO.js +0 -41
  105. package/ds-mobile/Modal/MobileModal.visual.spec.js +0 -56
  106. package/ds-mobile/Modal/MobileModalCO.js +0 -28
  107. package/ds-mobile/PageFilter/PageFilter.visual.spec.js +0 -46
  108. package/ds-mobile/PageFilter/PageFilterCO.js +0 -19
  109. package/ds-mobile/PageForm/PageForm.visual.spec.js +0 -14
  110. package/ds-mobile/PageForm/PageFormCO.js +0 -11
  111. package/ds-mobile/PageList/PageList.visual.spec.js +0 -31
  112. package/ds-mobile/PageList/PageListCO.js +0 -19
  113. package/ds-mobile/PageSummary/PageSummary.visual.spec.js +0 -20
  114. package/ds-mobile/PageSummary/PageSummaryCO.js +0 -11
  115. package/ds-mobile/SwipeToRefresh/SwipeToRefresh.func.spec.js +0 -26
  116. package/ds-mobile/SwipeToRefresh/SwipeToRefreshCO.js +0 -20
  117. package/ds-mobile/Tabs/MobileTabs.visual.spec.js +0 -91
  118. package/ds-mobile/Tabs/TabsCO.js +0 -37
  119. package/ds-mobile/Tooltip/MobileTooltip.func.spec.js +0 -17
  120. package/ds-mobile/Tooltip/MobileTooltip.visual.spec.js +0 -16
  121. package/ds-mobile/Tooltip/TooltipCO.js +0 -23
  122. package/ds-mobile/helpers.js +0 -7
@@ -78,25 +78,3 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
78
78
  });
79
79
  });
80
80
  }
81
- if (browser.capabilities['ice:options'].isPhone) {
82
- describe('PUI-8636 - Chip, Mobile -visual', () => {
83
- before('loading page', async () => {
84
- const errorOnGo = await DSChipCO.mobileURL.go();
85
- if (errorOnGo) throw errorOnGo;
86
- });
87
- it('should show chips on mobile viewport', async () => {
88
- await browser.eyesOpen();
89
- const snapshot = await browser.eyesCheckSnapshot(DSChipCO.snapshotPath('dschips-mobile'));
90
- await expect(snapshot).toEqual(0);
91
- });
92
- it('should show chips on mobile viewport behind the popover', async () => {
93
- await browser.eyesOpen();
94
- const chip = await DSChipCO.getChipButtonByIndex(2);
95
- await chip.click();
96
- const mobileContextMenu = await DSChipCO.getMobileContextMenu();
97
- await mobileContextMenu.waitForDisplayed();
98
- const snapshot = await browser.eyesCheckSnapshot(DSChipCO.snapshotPath('dschips-mobile-behind-shadow'));
99
- await expect(snapshot).toEqual(0);
100
- });
101
- });
102
- }
@@ -10,8 +10,6 @@ export default class DSChipCO extends PageObject {
10
10
 
11
11
  static slotsURL = new Urlbuilder(PATH_E2E_CHIP, 'slots-test');
12
12
 
13
- static mobileURL = new Urlbuilder(PATH_E2E_CHIP, 'mobile-test');
14
-
15
13
  static shapeURL = new Urlbuilder(PATH_E2E_CHIP, 'shape-test');
16
14
 
17
15
  static applyAriaDisabledURL = new Urlbuilder(PATH_E2E_CHIP, 'apply-aria-disabled-test');
@@ -46,10 +44,6 @@ export default class DSChipCO extends PageObject {
46
44
  return $('[data-testid="ds-tooltip-v3-tooltip-text-wrapper"]');
47
45
  }
48
46
 
49
- static async getMobileContextMenu() {
50
- return $('[data-testid="ds-mobile-context-menu"]');
51
- }
52
-
53
47
  // Slots
54
48
 
55
49
  static async getButtonSlotByIndex(index = 0) {
@@ -0,0 +1,37 @@
1
+ import { PATH_E2E_FAST_LIST } from '../paths';
2
+ import { PageObject, Urlbuilder } from '../helpers';
3
+
4
+ export default class DSFastListCO extends PageObject {
5
+ static basicTest = new Urlbuilder(PATH_E2E_FAST_LIST, 'basic-test');
6
+
7
+ static scrollToIndexTest = new Urlbuilder(PATH_E2E_FAST_LIST, 'scroll-to-index-test');
8
+
9
+ // The container is the scroll element (overflow: auto); the wrapper list carries role="list"
10
+ static async getContainer() {
11
+ return $('[data-testid="ds-fastlist-container"]');
12
+ }
13
+
14
+ static async getWrapperList() {
15
+ return $('[data-testid="ds-fastlist-wrapper-list"]');
16
+ }
17
+
18
+ static async getItems() {
19
+ return $$('[data-testid="ds-fastlist-item"]');
20
+ }
21
+
22
+ // Only items inside the virtualization window exist in the DOM, so this resolves
23
+ // to nothing for indexes outside it — that absence is the assertion we rely on.
24
+ static async getItemByIndex(index) {
25
+ return $(`[data-testid="ds-fastlist-item"][data-index="${index}"]`);
26
+ }
27
+
28
+ // The story renders a single input and a single button, so the component-owned
29
+ // data-testids are unambiguous here.
30
+ static async getJumpInput() {
31
+ return $('[data-testid="ds-inputtext-input"]');
32
+ }
33
+
34
+ static async getJumpButton() {
35
+ return $('[data-testid="ds-button"]');
36
+ }
37
+ }
@@ -0,0 +1,28 @@
1
+ import DSFastListCO from '../DSFastListCO';
2
+ import { axeCoreCheck } from '../../helpers';
3
+
4
+ // Coverage for the ds-fast-list compliance remediation in PUI-19124.
5
+ // DOM-attribute/a11y assertions are identical across engines, so this runs Chrome only.
6
+ // The `|| browserName === 'Chrome'` fallback is mandatory: BrowserStack reports the
7
+ // capitalized name and a lowercase-only guard would register 0 tests (false green).
8
+ if (
9
+ (!browser.capabilities['ice:options'].isPhone &&
10
+ !browser.capabilities['ice:options'].isTablet &&
11
+ browser.capabilities.browserName === 'chrome') ||
12
+ browser.capabilities.browserName === 'Chrome'
13
+ ) {
14
+ describe('PUI-19194 - DSFastList:: virtualized list accessibility - Axe-Core', () => {
15
+ before(async () => {
16
+ const errorOnGo = await DSFastListCO.basicTest.go();
17
+ if (errorOnGo) throw errorOnGo;
18
+ });
19
+
20
+ it('01: should have no accessibility violations on the rendered list', async () => {
21
+ const wrapperList = await DSFastListCO.getWrapperList();
22
+ await wrapperList.waitForDisplayed();
23
+
24
+ const result = await axeCoreCheck();
25
+ expect(result.length).toBe(0);
26
+ });
27
+ });
28
+ }
@@ -0,0 +1,23 @@
1
+ import DSFastListCO from '../DSFastListCO';
2
+
3
+ // Coverage for the ds-fast-list compliance remediation in PUI-19124.
4
+ // Only the unscrolled state is snapshotted on purpose: Percy re-renders the serialized DOM, and an
5
+ // inner container's scroll offset is runtime state that is not part of that serialization, so a
6
+ // scrolled virtualized list is not reliably reproducible in a snapshot. The scrolled state is
7
+ // covered functionally instead — see e2e/ds-fast-list/scroll-to-index.
8
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
9
+ describe('PUI-19193 - DSFastList:: virtualized list window rendering - Visual', () => {
10
+ before(async () => {
11
+ const errorOnGo = await DSFastListCO.basicTest.go();
12
+ if (errorOnGo) throw errorOnGo;
13
+ });
14
+
15
+ it('01: should display the virtualized list with its first window of items', async () => {
16
+ const wrapperList = await DSFastListCO.getWrapperList();
17
+ await wrapperList.waitForDisplayed();
18
+
19
+ const snapshot = await browser.percyCheckScreenshot();
20
+ await expect(snapshot).toEqual(0);
21
+ });
22
+ });
23
+ }
@@ -0,0 +1,45 @@
1
+ import DSFastListCO from '../DSFastListCO';
2
+
3
+ // Coverage for the ds-fast-list compliance remediation in PUI-19124.
4
+ // The in-package Playwright CT already covers this in Chromium; this spec exists to run the same
5
+ // contract across the full browser matrix.
6
+ // The window size is not stable (items are measured after mount, so the overscan window grows),
7
+ // which is why the assertions are "bounded window + index recycled", never an exact item count.
8
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
9
+ describe('PUI-19195 - DSFastList:: scroll to index via actionRef - Func', () => {
10
+ before(async () => {
11
+ const errorOnGo = await DSFastListCO.scrollToIndexTest.go();
12
+ if (errorOnGo) throw errorOnGo;
13
+ });
14
+
15
+ it('01: should render only a window of the 200 items, leaving far items out of the DOM', async () => {
16
+ const firstItem = await DSFastListCO.getItemByIndex(0);
17
+ await expect(firstItem).toBeExisting();
18
+
19
+ const farItem = await DSFastListCO.getItemByIndex(150);
20
+ await expect(farItem).not.toBeExisting();
21
+
22
+ const items = await DSFastListCO.getItems();
23
+ await expect(items.length).toBeLessThan(60);
24
+ });
25
+
26
+ it('02: should mount the requested item and recycle the first one after jumping', async () => {
27
+ const jumpInput = await DSFastListCO.getJumpInput();
28
+ await jumpInput.setValue('150');
29
+ const jumpButton = await DSFastListCO.getJumpButton();
30
+ await jumpButton.click();
31
+
32
+ const farItem = await DSFastListCO.getItemByIndex(150);
33
+ await farItem.waitForExist();
34
+ await expect(farItem).toBeDisplayed();
35
+ await expect(farItem).toHaveText('Test 150');
36
+
37
+ // the window moved instead of growing: index 0 is no longer in the DOM
38
+ const firstItem = await DSFastListCO.getItemByIndex(0);
39
+ await expect(firstItem).not.toBeExisting();
40
+
41
+ const items = await DSFastListCO.getItems();
42
+ await expect(items.length).toBeLessThan(60);
43
+ });
44
+ });
45
+ }
@@ -13,6 +13,10 @@ export default class DSIndeterminateProgressIndicatorCO extends PageObject {
13
13
  return (await this.getComponentWrapper()).$('div');
14
14
  }
15
15
 
16
+ static async getRoots() {
17
+ return $$('[data-testid="ds-indeterminateprogressindicator-root"]');
18
+ }
19
+
16
20
  // Snapshots
17
21
  static snapshotPath(example = 'basic') {
18
22
  return PageObject.getSnapshotPathBuilder('IndeterminateProgressIndicator', example);
@@ -0,0 +1,51 @@
1
+ import DSIndeterminateProgressIndicatorCO from '../DSIndeterminateProgressIndicatorCO';
2
+
3
+ // Tests for the fix introduced in PUI-18880: the root used to carry a `title` duplicating its `aria-label`,
4
+ // which some screen readers announce twice. The accessible name must come from `aria-label` only.
5
+ //
6
+ // Chrome only: pure DOM attribute contract. The `|| 'Chrome'` branch is mandatory, BrowserStack reports the
7
+ // capitalised name and a lowercase-only guard registers zero tests.
8
+ if (
9
+ (!browser.capabilities['ice:options'].isPhone &&
10
+ !browser.capabilities['ice:options'].isTablet &&
11
+ browser.capabilities.browserName === 'chrome') ||
12
+ browser.capabilities.browserName === 'Chrome'
13
+ ) {
14
+ describe('PUI-19251 - DSIndeterminateProgressIndicator:: accessible name without title attribute - Func', () => {
15
+ before('loading page', async () => {
16
+ const errorOnGo = await DSIndeterminateProgressIndicatorCO.basicURL.go();
17
+ if (errorOnGo) throw errorOnGo;
18
+ });
19
+
20
+ it('01: should expose the label via aria-label only, with no title attribute', async () => {
21
+ // Wait for the story's timed state change so the final labels are the ones asserted.
22
+ const dynamicTitle = await DSIndeterminateProgressIndicatorCO.getIndeterminateProgressIndicatorTitle();
23
+ await dynamicTitle.waitForDisplayed();
24
+ await browser.waitUntil(async () => (await dynamicTitle.getText()).includes('Title changed'), {
25
+ timeout: 10000,
26
+ timeoutMsg: 'dynamic title did not change',
27
+ });
28
+
29
+ const roots = await DSIndeterminateProgressIndicatorCO.getRoots();
30
+ await expect(roots).toBeElementsArrayOfSize(9);
31
+
32
+ // One read for all roots: lists every root carrying a title, or whose aria-label is empty or
33
+ // differs from the visible text. An empty list means the contract holds for all of them.
34
+ const offenders = await browser.execute(() => {
35
+ const found = [];
36
+ const nodes = document.querySelectorAll('[data-testid="ds-indeterminateprogressindicator-root"]');
37
+ for (let i = 0; i < nodes.length; i += 1) {
38
+ const ariaLabel = nodes[i].getAttribute('aria-label');
39
+ const title = nodes[i].getAttribute('title');
40
+ const text = nodes[i].innerText.trim();
41
+ if (title !== null || !ariaLabel || ariaLabel !== text) found.push({ ariaLabel, title, text });
42
+ }
43
+ return found;
44
+ });
45
+ await expect(offenders).toEqual([]);
46
+
47
+ const titledNodes = await browser.execute(() => document.querySelectorAll('#storybook-root [title]').length);
48
+ await expect(titledNodes).toBe(0);
49
+ });
50
+ });
51
+ }
@@ -0,0 +1,37 @@
1
+ /* eslint-disable max-len */
2
+ import LeftNavCO from './LeftNavigationCO';
3
+ import { axeCoreCheck } from '../helpers';
4
+
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'Chrome') ||
9
+ browser.capabilities.browserName === 'chrome'
10
+ ) {
11
+ describe('PUI-10670 - LeftNavigation: Axe-Core: Basic full features', () => {
12
+ before('loading page', async () => {
13
+ const errorOnGo = await LeftNavCO.fullFeatures.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ });
16
+ it('01: All collapsed (Section icons)', async () => {
17
+ const result = await axeCoreCheck();
18
+ expect(result.length).toBe(0);
19
+ });
20
+ it('02: Click Notifications and expand sections titles', async () => {
21
+ await (await LeftNavCO.leftComponent(0)).click();
22
+ const result = await axeCoreCheck();
23
+ expect(result.length).toBe(0);
24
+ });
25
+ it('03: Click and expand Notifications to have items with subsections', async () => {
26
+ await (await LeftNavCO.leftNavItem(0)).click();
27
+ const result = await axeCoreCheck();
28
+ expect(result.length).toBe(0);
29
+ });
30
+ it('04: Collapse Notifications and open forms with plain items', async () => {
31
+ await (await LeftNavCO.leftChevron()).click();
32
+ await (await LeftNavCO.leftNavItem(2)).click();
33
+ const result = await axeCoreCheck();
34
+ expect(result.length).toBe(0);
35
+ });
36
+ });
37
+ }
@@ -0,0 +1,23 @@
1
+ /* eslint-disable max-len */
2
+ import LeftNavCO from './LeftNavigationCO';
3
+ import { axeCoreCheck } from '../helpers';
4
+
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'Chrome') ||
9
+ browser.capabilities.browserName === 'chrome'
10
+ ) {
11
+ describe('PUI-11620 - LeftNavigation, isSkeleton prop -AxeCore Test', () => {
12
+ before('loading page', async () => {
13
+ const errorOnGo = await LeftNavCO.isSkeletonURL.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ });
16
+ it('01: should display left navigation with isSkeleton and pass the axe-core scan', async () => {
17
+ const skeleton = await LeftNavCO.getSkeletonByIndex();
18
+ await skeleton.waitForDisplayed();
19
+ const result = await axeCoreCheck();
20
+ expect(result.length).toBe(0);
21
+ });
22
+ });
23
+ }
@@ -0,0 +1,34 @@
1
+ /* eslint-disable max-len */
2
+ import LeftNavCO from './LeftNavigationCO';
3
+ import { axeCoreCheck } from '../helpers';
4
+
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'Chrome') ||
9
+ browser.capabilities.browserName === 'chrome'
10
+ ) {
11
+ describe('PUI-10674 - LeftNavigation: Axe-Core: Keeping items', () => {
12
+ before('loading page', async () => {
13
+ const errorOnGo = await LeftNavCO.keepingItems.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ });
16
+ it('01: should expand notifications and keep the remaining sections', async () => {
17
+ const subItemBtn = await LeftNavCO.getSubItemBtn();
18
+ await subItemBtn.click();
19
+ await (await LeftNavCO.leftComponent(0)).click();
20
+ const itemLabel = await LeftNavCO.itemLabel(0);
21
+ await itemLabel.waitForDisplayed();
22
+ const notificationHeader = await LeftNavCO.leftNavItem(0);
23
+ await notificationHeader.click();
24
+ const result = await axeCoreCheck();
25
+ expect(result.length).toBe(0);
26
+ });
27
+ it('02: should scroll down to display the remaining sections', async () => {
28
+ const menuItemBtn = await LeftNavCO.getMenuItemBtn();
29
+ await menuItemBtn.click();
30
+ const result = await axeCoreCheck();
31
+ expect(result.length).toBe(0);
32
+ });
33
+ });
34
+ }
@@ -0,0 +1,41 @@
1
+ /* eslint-disable max-len */
2
+ import LeftNavCO from './LeftNavigationCO';
3
+ import { axeCoreCheck, mouseOver } from '../helpers';
4
+
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'Chrome') ||
9
+ browser.capabilities.browserName === 'chrome'
10
+ ) {
11
+ describe('PUI-10671 - LeftNavigation, Axe-Core: Loading indicator', () => {
12
+ before('loading page', async () => {
13
+ const errorOnGo = await LeftNavCO.loading.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ });
16
+ it('01: loading indicator in leftnav closed', async () => {
17
+ const loadingIndicator = await LeftNavCO.loadingIndicator();
18
+ await loadingIndicator.waitForDisplayed();
19
+ const result = await axeCoreCheck();
20
+ expect(result.length).toBe(0);
21
+ });
22
+ it('02: loading indicator with tooltip (leftnav closed)', async () => {
23
+ const loadingIndicator = await LeftNavCO.loadingIndicator();
24
+ await mouseOver(loadingIndicator);
25
+ const loadingIndicatorTooltip = await LeftNavCO.loadingIndicatorTooltip();
26
+ await loadingIndicatorTooltip.waitForDisplayed();
27
+ const result = await axeCoreCheck();
28
+ expect(result.length).toBe(0);
29
+ });
30
+ it('03: loading indicator in leftnav opened', async () => {
31
+ const loadingIndicator = await LeftNavCO.loadingIndicator();
32
+ await loadingIndicator.waitForDisplayed();
33
+ const footerBtn = await LeftNavCO.footerBtn();
34
+ const footerLabel = await LeftNavCO.footerLabel();
35
+ await footerBtn.click();
36
+ await footerLabel.waitForDisplayed();
37
+ const result = await axeCoreCheck();
38
+ expect(result.length).toBe(0);
39
+ });
40
+ });
41
+ }
@@ -0,0 +1,21 @@
1
+ /* eslint-disable max-len */
2
+ import LeftNavCO from './LeftNavigationCO';
3
+ import { axeCoreCheck } from '../helpers';
4
+
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'Chrome') ||
9
+ browser.capabilities.browserName === 'chrome'
10
+ ) {
11
+ describe('PUI-10673 - LeftNavigation, Axe-Core: Notification badge', () => {
12
+ before('loading page', async () => {
13
+ const errorOnGo = await LeftNavCO.notificationBadgingURL.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ });
16
+ it('01: should display integrated notification badge combinations', async () => {
17
+ const result = await axeCoreCheck();
18
+ expect(result.length).toBe(0);
19
+ });
20
+ });
21
+ }
@@ -0,0 +1,26 @@
1
+ /* eslint-disable max-len */
2
+ import LeftNavCO from './LeftNavigationCO';
3
+ import { axeCoreCheck } from '../helpers';
4
+
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'Chrome') ||
9
+ browser.capabilities.browserName === 'chrome'
10
+ ) {
11
+ describe('PUI-10677 - LeftNavigation, Axe-Core: Search bar', () => {
12
+ before('loading page', async () => {
13
+ const errorOnGo = await LeftNavCO.fullFeatures.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ });
16
+ it('01: Trigger search button and check axe scan', async () => {
17
+ await (await LeftNavCO.leftComponent(0)).click();
18
+ await (await LeftNavCO.leftNavItem(0)).click();
19
+ const searchButton = await LeftNavCO.getIconButtonByIndex(0);
20
+ await searchButton.waitForDisplayed();
21
+ await searchButton.click();
22
+ const result = await axeCoreCheck();
23
+ expect(result.length).toBe(0);
24
+ });
25
+ });
26
+ }
@@ -0,0 +1,23 @@
1
+ /* eslint-disable max-len */
2
+ import LeftNavCO from './LeftNavigationCO';
3
+ import { axeCoreCheck } from '../helpers';
4
+
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'Chrome') ||
9
+ browser.capabilities.browserName === 'chrome'
10
+ ) {
11
+ describe('PUI-10250 - LeftNavigation, Axe-Core: Showcase, more usecases', () => {
12
+ before('loading page', async () => {
13
+ const errorOnGo = await LeftNavCO.showcaseURL.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ });
16
+ it('01: should display the use case showcase and pass the axe scan', async () => {
17
+ await (await LeftNavCO.leftComponent(0)).click();
18
+ await (await LeftNavCO.leftNavItem(0)).click();
19
+ const result = await axeCoreCheck();
20
+ expect(result.length).toBe(0);
21
+ });
22
+ });
23
+ }
@@ -0,0 +1,28 @@
1
+ /* eslint-disable max-len */
2
+ import LeftNavCO from './LeftNavigationCO';
3
+ import { axeCoreCheck, mouseOver } from '../helpers';
4
+
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'Chrome') ||
9
+ browser.capabilities.browserName === 'chrome'
10
+ ) {
11
+ describe('PUI-10672 - LeftNavigation, Axe-Core: Tooltip -func', () => {
12
+ before('loading page', async () => {
13
+ const errorOnGo = await LeftNavCO.fullFeatures.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ });
16
+ it('01: should display tooltip', async () => {
17
+ const notiItem = await LeftNavCO.leftNavItem(0);
18
+ await notiItem.click();
19
+ await notiItem.click();
20
+ const truncItem = await LeftNavCO.getTruncatedText(0);
21
+ await mouseOver(truncItem);
22
+ const tooltip = await LeftNavCO.getTooltip();
23
+ await tooltip.waitForDisplayed();
24
+ const result = await axeCoreCheck();
25
+ expect(result.length).toBe(0);
26
+ });
27
+ });
28
+ }
@@ -0,0 +1,27 @@
1
+ /* eslint-disable max-len */
2
+ import LeftNavCO from './LeftNavigationCO';
3
+ import { axeCoreCheck } from '../helpers';
4
+
5
+ if (
6
+ (!browser.capabilities['ice:options'].isPhone &&
7
+ !browser.capabilities['ice:options'].isTablet &&
8
+ browser.capabilities.browserName === 'Chrome') ||
9
+ browser.capabilities.browserName === 'chrome'
10
+ ) {
11
+ describe('PUI-10676 - LeftNavigation, Axe-Core: Wrapped text -func', () => {
12
+ before('loading page', async () => {
13
+ const errorOnGo = await LeftNavCO.wrapped.go();
14
+ if (errorOnGo) throw errorOnGo;
15
+ });
16
+ it('01: should display truncated sections', async () => {
17
+ await (await LeftNavCO.leftComponent(0)).click();
18
+ const result = await axeCoreCheck();
19
+ expect(result.length).toBe(0);
20
+ });
21
+ it('01: should display truncated items', async () => {
22
+ await (await LeftNavCO.leftComponent(0)).click();
23
+ const result = await axeCoreCheck();
24
+ expect(result.length).toBe(0);
25
+ });
26
+ });
27
+ }
@@ -0,0 +1,24 @@
1
+ import DSPanelHeaderCO from './DSPanelHeaderCO';
2
+ /* this is the syntax for only enabling test for desktop only
3
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
4
+ describe('PUI-XXXX - PanelHeader:: example test - data-testid exists', () => {
5
+ before('loading page', async () => {
6
+ // your code goes here
7
+ });
8
+ it('01: wrapper should be displayed', async () => {
9
+ // your code goes here
10
+ });
11
+
12
+ });
13
+ }
14
+ */
15
+ describe('PUI-XXXX - PanelHeader:: example test - data-testid exists', () => {
16
+ before('loading page', async () => {
17
+ const errorOnGo = await DSPanelHeaderCO.basic.go();
18
+ if (errorOnGo) throw errorOnGo;
19
+ });
20
+ it('01: wrapper should be displayed', async () => {
21
+ const wrapper = await DSPanelHeaderCO.getWrapper();
22
+ await expect(wrapper).toBeDisplayedInViewport();
23
+ });
24
+ });
@@ -0,0 +1,17 @@
1
+ import { PANEL_HEADER_DATA_TESTID } from '@elliemae/ds-panel-header';
2
+ import { PATH_PANEL_HEADER } from '../../environments/storybook/paths';
3
+ import { PageObject, Urlbuilder } from '../helpers';
4
+
5
+ export default class DSPanelHeader extends PageObject {
6
+ static basic = new Urlbuilder(PATH_PANEL_HEADER, 'basic');
7
+
8
+ // Selectors
9
+ static async getWrapper() {
10
+ return $(`[data-testid="${PANEL_HEADER_DATA_TESTID.ROOT}"]`);
11
+ }
12
+
13
+ // Snapshots
14
+ static snapshotPath(example = 'basic') {
15
+ return PageObject.getSnapshotPathBuilder('DSPanelHeader', example, 'ds-panel-header');
16
+ }
17
+ }
@@ -1,7 +1,21 @@
1
- import { PATH_E2E_PILLS_V2 } from '../paths';
1
+ import { PATH_E2E_PILLS_V2, PATH_E2E_PILLS_V2_PITFALLS } from '../paths';
2
2
  import { PageObject, Urlbuilder, getElementByIndex } from '../helpers';
3
3
 
4
4
  export default class DSPillsV2CO extends PageObject {
5
+ /**
6
+ * Every id in the InputWithFormItemBlockTest story is derived by DSFormLayoutBlockItem from the
7
+ * `inputID` it is given. Derived once here so neither the selectors below nor the spec rebuild
8
+ * the `_feedback_message` / `_error_message` suffixes by hand.
9
+ */
10
+ static IDS = {
11
+ input: 'normal',
12
+ feedback: 'normal_feedback_message',
13
+ error: 'normal_error_message',
14
+ };
15
+
16
+ /** What the input's aria-describedby must equal, in the order the story supplies the messages. */
17
+ static DESCRIBED_BY = `${this.IDS.feedback} ${this.IDS.error}`;
18
+
5
19
  // Desktop
6
20
  static removableURL = new Urlbuilder(PATH_E2E_PILLS_V2, 'removable-pill-test');
7
21
 
@@ -27,6 +41,15 @@ export default class DSPillsV2CO extends PageObject {
27
41
 
28
42
  static multiSelectMB = new Urlbuilder(PATH_E2E_PILLS_V2, 'multi-select-menu-button-test');
29
43
 
44
+ // Pitfalls
45
+ static inputWithFormItemBlockURL = new Urlbuilder(PATH_E2E_PILLS_V2_PITFALLS, 'input-with-form-item-block-test');
46
+
47
+ // Distinct from `inputURL` above: same story name, different path. Both are hand-copies of the
48
+ // Input Pill pitfall story's 12 pills; this one is the Pitfalls-scoped twin used by the attribute
49
+ // spec, `inputURL` is the older copy carrying the axe (PUI-11496) and Percy (PUI-8356) baselines.
50
+ // The E2E copy renders PendingReviewDisclaimer; the canonical component pitfall story additionally renders InputPillLabelRequirementDisclaimer.
51
+ static inputPillPitfallURL = new Urlbuilder(PATH_E2E_PILLS_V2_PITFALLS, 'input-pill-test');
52
+
30
53
  static getUrl(component = 'basic') {
31
54
  return PageObject.getUrl(PATH_E2E_PILLS_V2, component);
32
55
  }
@@ -93,6 +116,35 @@ export default class DSPillsV2CO extends PageObject {
93
116
  return $('[data-testid="dropdown-menu-listbox"]');
94
117
  }
95
118
 
119
+ // --- InputWithFormItemBlockTest: label / error association selectors ---
120
+
121
+ /** The pill's inner <input>, reached by the id the story overrides onto it. */
122
+ static async getAssociatedInput() {
123
+ return $(`#${this.IDS.input}`);
124
+ }
125
+
126
+ /** `$$` on purpose — the count is what proves the override did not duplicate the id. */
127
+ static async getNodesWithInputId() {
128
+ return $$(`[id="${this.IDS.input}"]`);
129
+ }
130
+
131
+ /** The DSFormLayoutBlockItem label, which must point at the input via `for`. */
132
+ static async getAssociatedInputLabel() {
133
+ return $(`label[for="${this.IDS.input}"]`);
134
+ }
135
+
136
+ static async getFeedbackMessage() {
137
+ return $(`#${this.IDS.feedback}`);
138
+ }
139
+
140
+ static async getErrorMessage() {
141
+ return $(`#${this.IDS.error}`);
142
+ }
143
+
144
+ static async getClearIcon() {
145
+ return $('[data-testid="ds-pill-clear-icon"]');
146
+ }
147
+
96
148
  // Snapshots
97
149
  static snapshotPath(example = 'basic') {
98
150
  return PageObject.getSnapshotPathBuilder('Pills', example);