dimsum-e2e-tests 3.80.0-next.4 → 3.80.0-next.41

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 (137) hide show
  1. package/CHANGELOG.md +168 -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-resize.visual.spec.js +2 -0
  8. package/ds-banner/DSBanner.text-wrapping.visual.spec.js +3 -6
  9. package/ds-banner/DSBanner.visual.spec.js +7 -8
  10. package/ds-banner/DSBannerCO.js +189 -4
  11. package/ds-banner/aria-and-role/DSBanner.aria-and-role.func.spec.js +113 -2
  12. package/ds-banner/ids/DSBanner.ids.func.spec.js +66 -0
  13. package/ds-banner/live-region-lang-dir/DSBanner.live-region-lang-dir.func.spec.js +54 -0
  14. package/ds-banner/slide-animation/DSBanner.slide-animation.func.spec.js +105 -0
  15. package/ds-banner/slots/DSBanner.slots.axe-core.func.spec.js +24 -0
  16. package/ds-banner/slots/DSBanner.slots.func.spec.js +13 -0
  17. package/ds-banner/slots/DSBanner.slots.visual.spec.js +3 -2
  18. package/ds-banner/title-element/DSBanner.title-element.func.spec.js +29 -0
  19. package/ds-chip/DSChip.axe-core.func.spec.js +0 -17
  20. package/ds-chip/DSChip.visual.spec.js +0 -22
  21. package/ds-chip/DSChipCO.js +0 -6
  22. package/ds-fast-list/DSFastListCO.js +37 -0
  23. package/ds-fast-list/basic/DSFastList.basic.axe-core.func.spec.js +28 -0
  24. package/ds-fast-list/basic/DSFastList.basic.visual.spec.js +23 -0
  25. package/ds-fast-list/scroll-to-index/DSFastList.scroll-to-index.func.spec.js +45 -0
  26. package/ds-indeterminate-progress-indicator/DSIndeterminateProgressIndicatorCO.js +4 -0
  27. package/ds-indeterminate-progress-indicator/accessible-name/DSIndeterminateProgressIndicator.accessible-name.func.spec.js +51 -0
  28. package/ds-leftnavigation/LeftNavigation.fullFeatures.axe-core.func.spec.js +37 -0
  29. package/ds-leftnavigation/LeftNavigation.isSkeleton.axe-core.func.spec.js +23 -0
  30. package/ds-leftnavigation/LeftNavigation.keepingItems.axe-core.func.spec.js +34 -0
  31. package/ds-leftnavigation/LeftNavigation.loadingIndicator.axe-core.func.spec.js +41 -0
  32. package/ds-leftnavigation/LeftNavigation.notificationBadge.axe-core.func.spec.js +21 -0
  33. package/ds-leftnavigation/LeftNavigation.searchBar.axe-core.func.spec.js +26 -0
  34. package/ds-leftnavigation/LeftNavigation.showCase.axe-core.func.spec.js +23 -0
  35. package/ds-leftnavigation/LeftNavigation.tooltip.axe-core.func.spec.js +28 -0
  36. package/ds-leftnavigation/LeftNavigation.wrappedText.axe-core.func.spec.js +27 -0
  37. package/ds-menu-button/DSMenuButtonCO.js +18 -0
  38. package/ds-menu-button/activable/DSMenuButton.activableMenuItem.keyboardnav.func.spec.js +10 -8
  39. package/ds-menu-button/submenu/DSMenuButton.subMenuItem.keyboardnav.func.spec.js +33 -10
  40. package/ds-modal-slide/inside-dialog/ModalSlide.insideDialog.func.spec.js +45 -0
  41. package/ds-panel-header/DSPanelHeader.func.spec.js +24 -0
  42. package/ds-panel-header/DSPanelHeaderCO.js +17 -0
  43. package/ds-pills-v2/DSPillsV2CO.js +53 -1
  44. package/ds-pills-v2/pitfalls/DSPills.inputPill.func.spec.js +26 -0
  45. package/ds-pills-v2/pitfalls/DSPills.inputWithFormItemBlockURL.axe-core.func.spec.js +38 -0
  46. package/ds-pills-v2/pitfalls/DSPills.inputWithFormItemBlockURL.func.spec.js +72 -0
  47. package/ds-progress-indicator/DSProgressIndicator.axe-core.func.spec.js +8 -5
  48. package/ds-progress-indicator/DSProgressIndicator.func.spec.js +31 -4
  49. package/ds-progress-indicator/DSProgressIndicator.visual.spec.js +14 -6
  50. package/ds-progress-indicator/DSProgressIndicatorCO.js +87 -9
  51. package/ds-progress-indicator/aria-contract/DSProgressIndicator.aria-contract.func.spec.js +104 -0
  52. package/ds-progress-indicator/slots/DSProgressIndicator.slots.axe-core.func.spec.js +31 -0
  53. package/ds-progress-indicator/slots/DSProgressIndicator.slots.func.spec.js +87 -0
  54. package/ds-progress-indicator/slots/DSProgressIndicator.slots.visual.spec.js +27 -0
  55. package/ds-progress-indicator/variant/DSProgressIndicator.single-bar-variant.func.spec.js +44 -0
  56. package/ds-progress-indicator/variant/DSProgressIndicator.single-bar-variant.visual.spec.js +19 -0
  57. package/ds-ribbon/DSRibbonCO.js +21 -0
  58. package/ds-ribbon/keyboard-accessible-row/DSRibbon.keyboard-accessible-row.visual.spec.js +40 -0
  59. package/ds-ribbon/wrap-columns/DSRibbon.wrap-columns.visual.spec.js +18 -0
  60. package/ds-shuttle-v2/load-more/DSShuttleV2.load-more.keyboard.func.spec.js +46 -17
  61. package/ds-slider-v2/DSSliderV2.axe-core.func.spec.js +21 -0
  62. package/ds-slider-v2/DSSliderV2.visual.spec.js +19 -1
  63. package/ds-slider-v2/DSSliderV2CO.js +6 -1
  64. package/ds-slider-v2/has-error/DSSliderV2.has-error.visual.spec.js +44 -0
  65. package/ds-slider-v2/interaction-states/DSSliderV2.interaction-states.visual.spec.js +53 -0
  66. package/ds-virtuallist/DSVirtualList.visual.spec.js +4 -5
  67. package/ds-virtuallist/DSVirtualListCO.js +28 -9
  68. package/ds-virtuallist/basic/DSVirtualList.basic.axe-core.func.spec.js +28 -0
  69. package/ds-virtuallist/scroll-to-index/DSVirtualList.scroll-to-index.func.spec.js +45 -0
  70. package/package.json +149 -149
  71. package/paths.js +3 -49
  72. package/ds-leftnavigation/LeftNavigation.axe-core.func.spec.js +0 -172
  73. package/ds-mobile/Accordion/DSAccordion.visual.spec.js +0 -33
  74. package/ds-mobile/Accordion/DSAccordionCO.js +0 -37
  75. package/ds-mobile/CategoryBox/CategoryBox.visual.spec.js +0 -18
  76. package/ds-mobile/CategoryBox/CategoryBoxCO.js +0 -17
  77. package/ds-mobile/CollectionBox/CollectionBox.visual.spec.js +0 -16
  78. package/ds-mobile/CollectionBox/CollectionBoxCO.js +0 -15
  79. package/ds-mobile/GlobalHeader/DSGlobalHeader.visual.spec.js +0 -55
  80. package/ds-mobile/GlobalHeader/DSGlobalHeaderCO.js +0 -36
  81. package/ds-mobile/GroupBox/GroupBox.visual.spec.js +0 -15
  82. package/ds-mobile/GroupBox/GroupBoxCO.js +0 -15
  83. package/ds-mobile/InfiniteLoader/InfiniteLoader.func.spec.js +0 -90
  84. package/ds-mobile/InfiniteLoader/InfiniteLoaderCO.js +0 -29
  85. package/ds-mobile/MobileActionToolbar/MobileActionToolbar.visual.spec.js +0 -39
  86. package/ds-mobile/MobileActionToolbar/MobileActionToolbarCO.js +0 -19
  87. package/ds-mobile/MobileBanner/MobileBanner.visual.spec.js +0 -23
  88. package/ds-mobile/MobileBanner/MobileBannerCO.js +0 -23
  89. package/ds-mobile/MobileCard/Card.func.spec.js +0 -38
  90. package/ds-mobile/MobileCard/Card.visual.spec.js +0 -103
  91. package/ds-mobile/MobileCard/MobileCardCO.js +0 -42
  92. package/ds-mobile/MobileContextMenu/MobileContextMenu.func.spec.js +0 -88
  93. package/ds-mobile/MobileContextMenu/MobileContextMenu.visual.spec.js +0 -31
  94. package/ds-mobile/MobileContextMenu/MobileContextMenuCO.js +0 -72
  95. package/ds-mobile/MobileDatePicker/MobileDatePicker.func.spec.js +0 -15
  96. package/ds-mobile/MobileDatePicker/MobileDatePicker.visual.spec.js +0 -15
  97. package/ds-mobile/MobileDatePicker/MobileDatePickerCO.js +0 -35
  98. package/ds-mobile/MobileDropdownMenu/MobileDropdownMenu.func.spec.js +0 -38
  99. package/ds-mobile/MobileDropdownMenu/MobileDropdownMenu.visual.spec.js +0 -16
  100. package/ds-mobile/MobileDropdownMenu/MobileDropdownMenuCO.js +0 -37
  101. package/ds-mobile/MobileEmptyState/MobileEmptyState.visual.spec.js +0 -15
  102. package/ds-mobile/MobileEmptyState/MobileEmptyStateCO.js +0 -14
  103. package/ds-mobile/MobileFilterbar/MobileFilterbar.visual.spec.js +0 -39
  104. package/ds-mobile/MobileFilterbar/MobileFilterbarCO.js +0 -19
  105. package/ds-mobile/MobileFooter/MobileFooter.func.spec.js +0 -26
  106. package/ds-mobile/MobileFooter/MobileFooter.visual.spec.js +0 -51
  107. package/ds-mobile/MobileFooter/MobileFooterCO.js +0 -27
  108. package/ds-mobile/MobileListItem/MobileListItem.visual.spec.js +0 -56
  109. package/ds-mobile/MobileListItem/MobileListItemCO.js +0 -19
  110. package/ds-mobile/MobileLoadingPage/MobileLoadingPage.visual.spec.js +0 -37
  111. package/ds-mobile/MobileLoadingPage/MobileLoadingPageCO.js +0 -23
  112. package/ds-mobile/MobilePageHeader/MobilePageHeader.func.spec.js +0 -22
  113. package/ds-mobile/MobilePageHeader/MobilePageHeader.visual.spec.js +0 -135
  114. package/ds-mobile/MobilePageHeader/MobilePageHeaderCO.js +0 -67
  115. package/ds-mobile/MobileSelectList/MobileSelectList.visual.spec.js +0 -56
  116. package/ds-mobile/MobileSelectList/MobileSelectListCO.js +0 -21
  117. package/ds-mobile/MobileSeparator/MobileSeparator.visual.spec.js +0 -28
  118. package/ds-mobile/MobileSeparator/MobileSeparatorCO.js +0 -17
  119. package/ds-mobile/MobileTimePicker/MobileTimePickerCO.js +0 -41
  120. package/ds-mobile/Modal/MobileModal.visual.spec.js +0 -56
  121. package/ds-mobile/Modal/MobileModalCO.js +0 -28
  122. package/ds-mobile/PageFilter/PageFilter.visual.spec.js +0 -46
  123. package/ds-mobile/PageFilter/PageFilterCO.js +0 -19
  124. package/ds-mobile/PageForm/PageForm.visual.spec.js +0 -14
  125. package/ds-mobile/PageForm/PageFormCO.js +0 -11
  126. package/ds-mobile/PageList/PageList.visual.spec.js +0 -31
  127. package/ds-mobile/PageList/PageListCO.js +0 -19
  128. package/ds-mobile/PageSummary/PageSummary.visual.spec.js +0 -20
  129. package/ds-mobile/PageSummary/PageSummaryCO.js +0 -11
  130. package/ds-mobile/SwipeToRefresh/SwipeToRefresh.func.spec.js +0 -26
  131. package/ds-mobile/SwipeToRefresh/SwipeToRefreshCO.js +0 -20
  132. package/ds-mobile/Tabs/MobileTabs.visual.spec.js +0 -91
  133. package/ds-mobile/Tabs/TabsCO.js +0 -37
  134. package/ds-mobile/Tooltip/MobileTooltip.func.spec.js +0 -17
  135. package/ds-mobile/Tooltip/MobileTooltip.visual.spec.js +0 -16
  136. package/ds-mobile/Tooltip/TooltipCO.js +0 -23
  137. package/ds-mobile/helpers.js +0 -7
@@ -20,6 +20,8 @@ if (
20
20
  const bannerButtonSlot = await DSBannerCO.getButtonRootSlotByIndex();
21
21
  const bannerLayoutSlot = await DSBannerCO.getLayoutSlotByIndex();
22
22
  const bannerActionLinkSlot = await DSBannerCO.getActionLinkSlotByIndex();
23
+ const bannerBodySlot = await DSBannerCO.getBodySlotByIndex();
24
+ await expect(bannerBodySlot).toBeDisplayed();
23
25
  await expect(bannerTitleSlot).toBeDisplayed();
24
26
  await expect(bannerSubtitleSlot).toBeDisplayed();
25
27
  await expect(bannerContainer).toBeDisplayed();
@@ -28,6 +30,9 @@ if (
28
30
  await expect(bannerButtonSlot).toBeDisplayed();
29
31
  await expect(bannerLayoutSlot).toBeDisplayed();
30
32
  await expect(bannerActionLinkSlot).toBeDisplayed();
33
+ // PUI-17935: the close button exposes its parent slot (nested DSButton)
34
+ const bannerCloseButtonSlot = await DSBannerCO.getCloseButtonSlotByIndex();
35
+ await expect(bannerCloseButtonSlot).toBeDisplayed();
31
36
  });
32
37
  it('02: should find custom aria for each SLOT', async () => {
33
38
  const bannerTitleSlot = await DSBannerCO.getTitleSlotByIndex();
@@ -37,6 +42,8 @@ if (
37
42
  const bannerIconsSlots = await DSBannerCO.getIconContainerSlotByIndex();
38
43
  const bannerButtonSlot = await DSBannerCO.getButtonRootSlotByIndex();
39
44
  const bannerActionLinkSlot = await DSBannerCO.getActionLinkSlotByIndex();
45
+ const bannerBodySlot = await DSBannerCO.getBodySlotByIndex();
46
+ await expect(bannerBodySlot).toHaveAttribute('aria-label', 'im body aria');
40
47
  await expect(bannerTitleSlot).toHaveAttribute('aria-label', 'im title aria');
41
48
  await expect(bannerSubtitleSlot).toHaveAttribute('aria-label', 'im subtitle aria');
42
49
  await expect(bannerContainer).toHaveAttribute('aria-label', 'im container aria');
@@ -44,6 +51,8 @@ if (
44
51
  await expect(bannerIconsSlots).toHaveAttribute('aria-label', 'im iconcontainer aria');
45
52
  await expect(bannerButtonSlot).toHaveAttribute('aria-label', 'im closebutton aria');
46
53
  await expect(bannerActionLinkSlot).toHaveAttribute('aria-label', 'im actionlink aria');
54
+ const bannerCloseButtonSlot = await DSBannerCO.getCloseButtonSlotByIndex();
55
+ await expect(bannerCloseButtonSlot).toHaveAttribute('aria-label', 'im closebutton aria');
47
56
  });
48
57
  it('03: should find custom data for each SLOT', async () => {
49
58
  const bannerTitleSlot = await DSBannerCO.getTitleSlotByIndex();
@@ -53,6 +62,8 @@ if (
53
62
  const bannerIconsSlots = await DSBannerCO.getIconContainerSlotByIndex();
54
63
  const bannerButtonSlot = await DSBannerCO.getButtonRootSlotByIndex();
55
64
  const bannerActionLinkSlot = await DSBannerCO.getActionLinkSlotByIndex();
65
+ const bannerBodySlot = await DSBannerCO.getBodySlotByIndex();
66
+ await expect(bannerBodySlot).toHaveAttribute('data-testid', 'im body data');
56
67
  await expect(bannerTitleSlot).toHaveAttribute('data-testid', 'im title data');
57
68
  await expect(bannerSubtitleSlot).toHaveAttribute('data-testid', 'im subtitle data');
58
69
  await expect(bannerContainer).toHaveAttribute('data-testid', 'im container data');
@@ -60,6 +71,8 @@ if (
60
71
  await expect(bannerIconsSlots).toHaveAttribute('data-testid', 'im iconcontainer data');
61
72
  await expect(bannerButtonSlot).toHaveAttribute('data-testid', 'im closebutton data');
62
73
  await expect(bannerActionLinkSlot).toHaveAttribute('data-testid', 'im actionlink data');
74
+ const bannerCloseButtonSlot = await DSBannerCO.getCloseButtonSlotByIndex();
75
+ await expect(bannerCloseButtonSlot).toHaveAttribute('data-testid', 'im closebutton data');
63
76
  });
64
77
  });
65
78
  }
@@ -7,10 +7,11 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
7
7
  if (errorOnGo) throw errorOnGo;
8
8
  });
9
9
  it('should display the banners customized using slots', async () => {
10
- await browser.eyesOpen();
11
10
  const banner = await DSBannerCO.getContainerSlotByIndex();
12
11
  await banner.waitForDisplayed();
13
- const snapshot = await browser.eyesCheckSnapshot(DSBannerCO.snapshotPath('banner-slots-test'));
12
+ // the banners are open on load and slide down for 500 ms
13
+ await DSBannerCO.waitForSlideToEnd();
14
+ const snapshot = await browser.percyCheckScreenshot();
14
15
  await expect(snapshot).toEqual(0);
15
16
  });
16
17
  });
@@ -0,0 +1,29 @@
1
+ import DSBannerCO from '../DSBannerCO';
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 fix introduced in PUI-19231 (the title was an h5 and added a heading to the host page outline)
10
+ describe('PUI-19270 - DSBanner:: title rendered as span, not heading - Func', () => {
11
+ before('loading page', async () => {
12
+ const errorOnGo = await DSBannerCO.infoURL.go();
13
+ if (errorOnGo) throw errorOnGo;
14
+ });
15
+
16
+ it('01: should render the title as a span without heading role and keep its attributes', async () => {
17
+ await DSBannerCO.openBanner();
18
+
19
+ const title = await DSBannerCO.getTitle();
20
+ await expect(title).toBeDisplayed();
21
+ await expect(await title.getTagName()).toBe('span');
22
+ await expect(title).not.toHaveAttribute('role');
23
+ await expect(await DSBannerCO.getHeadingsCountInBanners()).toBe(0);
24
+
25
+ await expect(title).toHaveAttribute('data-dimsum-parent-slot', 'dsBannerTitle');
26
+ await expect(await title.getAttribute('id')).toBeTruthy();
27
+ });
28
+ });
29
+ }
@@ -44,21 +44,4 @@ if (
44
44
  expect(result.length).toBe(0);
45
45
  });
46
46
  });
47
- describe('PUI-10694 - DSChip:: Axe-core, Mobile -Func', () => {
48
- before('loading page', async () => {
49
- const errorOnGo = await DSChipCO.mobileURL.go();
50
- if (errorOnGo) throw errorOnGo;
51
- });
52
- it('01: Chips within mobile context should pass axe-core scan without violations', async () => {
53
- await (await DSChipCO.getChipByIndex(1)).waitForDisplayed();
54
- const result = await axeCoreCheck();
55
- expect(result.length).toBe(0);
56
- });
57
- it('02: Chips below mobile context (usecase) should pass axe-core scan without violations', async () => {
58
- const chip = await DSChipCO.getChipByIndex(1);
59
- await chip.click();
60
- const result = await axeCoreCheck();
61
- expect(result.length).toBe(0);
62
- });
63
- });
64
47
  }
@@ -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
+ }