dimsum-e2e-tests 3.70.0-next.53 → 3.70.0-next.55

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 (96) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/ds-accordion/DSAccordionCO.js +4 -0
  3. package/ds-accordion/QA_NOTES.md +105 -0
  4. package/ds-accordion/header-structure/DSAccordion.header-structure.func.spec.js +24 -8
  5. package/ds-accordion/input-inside/DSAccordion.input-inside.func.spec.js +3 -1
  6. package/ds-apppicker/truncation/DSAppPicker.truncation.visual.spec.js +5 -9
  7. package/ds-card-v3/DSCardV3CO.js +1 -1
  8. package/ds-card-v3/accordion/DSCardV3.accordion-aria.keyboard.func.spec.js +49 -0
  9. package/ds-card-v3/accordion/DSCardV3.accordion.axe-core.func.spec.js +2 -2
  10. package/ds-card-v3/action/DSCardV3.action.axe-core.func.spec.js +24 -0
  11. package/ds-card-v3/action/DSCardV3.action.func.spec.js +53 -0
  12. package/ds-card-v3/action/DSCardV3.action.visual.spec.js +28 -0
  13. package/ds-card-v3/drag-n-drop/DSCardV3.DnD.axe-core.func.spec.js +0 -19
  14. package/ds-card-v3/multi-select/DSCardV3.multiselect.axe-core.func.spec.js +47 -0
  15. package/ds-card-v3/multiple-action/DSCardV3.multiple-action.axe-core.func.spec.js +35 -0
  16. package/ds-card-v3/multiple-control/DSCardV3.multi-control.axe-core.func.spec.js +34 -0
  17. package/ds-card-v3/multiple-control/DSCardV3.multi-control.func.spec.js +2 -1
  18. package/ds-card-v3/multiple-control/DSCardV3.multi-control.visual.spec.js +29 -0
  19. package/ds-card-v3/no-action/DSCardV3.no-action.axe-core.func.spec.js +1 -1
  20. package/ds-card-v3/notification-badges/DSCardV3.notification-badges.axe-core.func.spec.js +33 -0
  21. package/ds-card-v3/notification-badges/DSCardV3.notification-badges.visual.spec.js +28 -0
  22. package/ds-card-v3/variant-accented/DSCardV3.variant-accented.axe-core.func.spec.js +45 -0
  23. package/ds-card-v3/variant-accented-disabled/DSCardV3.variant-accented-disabled.axe-core.func.spec.js +35 -0
  24. package/ds-card-v3/variant-accented-disabled/DSCardV3.variant-accented-disabled.visual.spec.js +28 -0
  25. package/ds-card-v3/variant-disabled/DSCardV3.variant-disabled.axe-core.func.spec.js +1 -1
  26. package/ds-card-v3/variant-disabled/DSCardV3.variant-disabled.func.spec.js +61 -0
  27. package/ds-card-v3/variant-disabled/DSCardV3.variant-disabled.visual.spec.js +20 -0
  28. package/ds-card-v3/{disabled/DSCardV3.disabled-non-interactive.func.spec.js → variant-disabled/DSCardV3.variantDisabled-non-interactive.func.spec.js} +1 -1
  29. package/ds-chat/DSChat.visual.spec.js +1 -1
  30. package/ds-chat/DSChatCO.js +12 -12
  31. package/ds-chat/components/CardCO.js +1 -3
  32. package/ds-chat/components/ComposerCO.js +1 -1
  33. package/ds-chat/components/FloatingButtonCO.js +4 -2
  34. package/ds-chat/floatingbutton/DSChat-floating-button.visual.spec.js +1 -1
  35. package/ds-controlled-form/ds-controlled-checkbox/Basic/DSControlledCheckbox.axe-core.basic.func.spec.js +4 -4
  36. package/ds-controlled-form/ds-controlled-checkbox/Basic/DSControlledCheckbox.basic.visual.spec.js +56 -0
  37. package/ds-controlled-form/ds-controlled-checkbox/DSControlledCheckboxCO.js +4 -0
  38. package/ds-controlled-form/ds-controlled-checkbox/Disabled/DSControlledCheckbox.axe-core.disabled.func.spec.js +1 -1
  39. package/ds-controlled-form/ds-controlled-checkbox/Disabled/DSControlledCheckbox.disabled.visual.spec.js +1 -1
  40. package/ds-controlled-form/ds-controlled-checkbox/HasError/DSControlledCheckbox.axe-core.hasError.func.spec.js +4 -4
  41. package/ds-controlled-form/ds-controlled-checkbox/HasError/DSControlledCheckbox.has-error.visual.spec.js +71 -1
  42. package/ds-controlled-form/ds-controlled-checkbox/Mixed/DSControlledCheckbox.axe-core.mixed.func.spec.js +4 -4
  43. package/ds-controlled-form/ds-controlled-checkbox/Mixed/DSControlledCheckbox.mixed.visual.spec.js +1 -1
  44. package/ds-controlled-form/ds-controlled-checkbox/ReadOnly/DSControlledCheckbox.axe-core.read-only.func.spec.js +3 -3
  45. package/ds-controlled-form/ds-controlled-checkbox/ReadOnly/DSControlledCheckbox.read-only.visual.spec.js +1 -1
  46. package/ds-controlled-form/ds-controlled-checkbox/WithTooltip/DSControlledCheckbox.axe-core.with-tooltip.func.spec.js +1 -1
  47. package/ds-controlled-form/ds-controlled-checkbox/WithTooltip/DSControlledCheckbox.with-tooltip.visual.spec.js +1 -3
  48. package/ds-controlled-form/ds-controlled-checkbox/WrapLabel/DSControlledCheckbox.axe-core.wrap-label.func.spec.js +1 -1
  49. package/ds-controlled-form/ds-controlled-checkbox/WrapLabel/DSControlledCheckbox.wrap-label.visual.spec.js +1 -1
  50. package/ds-controlled-form/ds-controlled-checkbox/aria-disabled/DSControlledCheckbox.aria-disabled.visual.spec.js +2 -6
  51. package/ds-controlled-form/ds-controlled-checkbox/aria-disabled/DSControlledCheckbox.axe-core.aria-disabled.func.spec.js +1 -1
  52. package/ds-controlled-form/ds-controlled-checkbox-group/DSControlledCheckboxGroup.axe-core.func.spec.js +4 -4
  53. package/ds-controlled-form/ds-controlled-checkbox-group/DSControlledCheckboxGroup.visual.spec.js +1 -1
  54. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-creatablemultiselect.keyboard.func.spec.js +2 -2
  55. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-creatableselect.keyboard.func.spec.js +2 -2
  56. package/ds-data-table-async/pagination/DSDataTable.pagination.func.spec.js +3 -2
  57. package/ds-data-table-async/resizable/DSDataTable.resizerA11y.func.spec.js +14 -0
  58. package/ds-data-table-async/vissibility/DSDataTable.vissibility.visual.spec.js +2 -0
  59. package/ds-dataviz/DSDataVizCO.js +2 -0
  60. package/ds-dataviz/axecore/DSDataViz.axis.axe-core.func.spec.js +1 -1
  61. package/ds-form-combobox-multi/DSComboboxMultiCO.js +11 -0
  62. package/ds-form-combobox-multi/pills/DSComboboxMulti.pills.func.spec.js +59 -0
  63. package/ds-form-combobox-multi/pills/DSComboboxMulti.pills.visual.spec.js +39 -0
  64. package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.axe-core.func.spec.js +39 -0
  65. package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.func.spec.js +39 -0
  66. package/ds-form-combobox-multi/with-tooltip/DSComboboxMulti.with-tooltip.visual.spec.js +29 -0
  67. package/ds-form-combobox-single/DSComboboxSingleCO.js +2 -0
  68. package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.axe-core.func.spec.js +39 -0
  69. package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.func.spec.js +39 -0
  70. package/ds-form-combobox-single/with-tooltip/DSComboboxSingle.with-tooltip.visual.spec.js +29 -0
  71. package/ds-hooks/DSHook.usetree.func.spec.js +3 -2
  72. package/ds-hooks/useMask/Number/UseNumberMask.axe-core.func.spec.js +48 -0
  73. package/ds-pills-v2/DSPillsV2CO.js +12 -0
  74. package/ds-pills-v2/apply-aria-disabled/DSPills.applyAriaDisabled.func.spec.js +53 -0
  75. package/ds-pills-v2/apply-aria-disabled/DSPills.applyAriaDisabled.visual.spec.js +26 -0
  76. package/ds-pills-v2/disabled/DSPills.disabled.func.spec.js +53 -0
  77. package/ds-pills-v2/disabled/DSPills.disabled.visual.spec.js +33 -0
  78. package/package.json +150 -150
  79. package/paths.js +3 -3
  80. package/ds-accordion-native/DSAccordionNative.axe-core.func.spec.js +0 -135
  81. package/ds-accordion-native/DSAccordionNative.func.spec.js +0 -200
  82. package/ds-accordion-native/DSAccordionNative.visual.spec.js +0 -158
  83. package/ds-accordion-native/DSAccordionNativeCO.js +0 -178
  84. package/ds-accordion-native/QA_NOTES.md +0 -151
  85. package/ds-accordion-native/aria-disabled/DSAccordionNative.aria-disabled.axe-core.func.spec.js +0 -25
  86. package/ds-accordion-native/aria-disabled/DSAccordionNative.aria-disabled.visual.spec.js +0 -28
  87. package/ds-accordion-native/controlled/DSAccordionNative.controlled.func.spec.js +0 -22
  88. package/ds-accordion-native/header-structure/DSAccordionNative.header-structure.func.spec.js +0 -52
  89. package/ds-accordion-native/input-inside/DSAccordionNative.input-inside.func.spec.js +0 -16
  90. package/ds-accordion-native/role/DSAccordionNative.role-heading.func.spec.js +0 -27
  91. package/ds-accordion-native/scrollable-content/DSAccordionNative.scrollable-content.visual.spec.js +0 -49
  92. package/ds-accordion-native/slots/DSAccordionNative.slots.axe-core.func.spec.js +0 -25
  93. package/ds-accordion-native/slots/DSAccordionNative.slots.func.spec.js +0 -73
  94. package/ds-accordion-native/slots/DSAccordionNative.slots.visual.spec.js +0 -21
  95. package/ds-accordion-native/wrapLabel/DSAccordionNative.wrap-label.visual.spec.js +0 -21
  96. package/ds-card-v3/disabled/DSCardV3.disabled.visual.spec.js +0 -16
@@ -12,7 +12,7 @@ describe('PUI-7100 - DSControlledCheckbox - Visual Test - mixed', () => {
12
12
  await checkbox1.click();
13
13
  await checkbox1.click();
14
14
  await mouseOver(checkbox2);
15
- const snapshot = await browser.checkSnapshot(DSControlledCheckboxCO.snapshotPath('checkbox-mixed'));
15
+ const snapshot = await browser.percyCheckScreenshot();
16
16
  await expect(snapshot).toEqual(0);
17
17
  });
18
18
  });
@@ -17,18 +17,18 @@ if (
17
17
  const checkbox = await DSControlledCheckboxCO.getCheckboxByIndex(0);
18
18
  await checkbox.waitForExist();
19
19
  const result = await axeCoreCheck();
20
- expect(result.length).toBe(0);
20
+ await expect(result).toHaveLength(0);
21
21
  });
22
22
  it('02: Evaluate checkbox accessibility with axe-core (focused)', async () => {
23
23
  await browser.keys(Key.Tab);
24
24
  const result = await axeCoreCheck();
25
- expect(result.length).toBe(0);
25
+ await expect(result).toHaveLength(0);
26
26
  });
27
27
  it('03: Evaluate checkbox accessibility with axe-core (hovered)', async () => {
28
28
  const checkbox = await DSControlledCheckboxCO.getCheckboxByIndex(0);
29
29
  await mouseOver(checkbox);
30
30
  const result = await axeCoreCheck();
31
- expect(result.length).toBe(0);
31
+ await expect(result).toHaveLength(0);
32
32
  });
33
33
  });
34
34
  }
@@ -14,7 +14,7 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
14
14
  await checkbox1.click();
15
15
  await checkbox1.click();
16
16
  await mouseOver(checkbox2);
17
- const snapshot = await browser.eyesCheckSnapshot(DSControlledCheckboxCO.snapshotPath('checkbox-readOnly'));
17
+ const snapshot = await browser.percyCheckScreenshot();
18
18
  await expect(snapshot).toEqual(0);
19
19
  });
20
20
  });
@@ -16,7 +16,7 @@ if (
16
16
  const checkboxLabel = await DSControlledCheckboxCO.getCheckboxLabelByIndex(4);
17
17
  await mouseOver(checkboxLabel);
18
18
  const result = await axeCoreCheck();
19
- expect(result.length).toBe(0);
19
+ await expect(result).toHaveLength(0);
20
20
  });
21
21
  });
22
22
  }
@@ -11,9 +11,7 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
11
11
  await browser.eyesOpen();
12
12
  const checkboxLabel = await DSControlledCheckboxCO.getCheckboxLabelByIndex(4);
13
13
  await mouseOver(checkboxLabel);
14
- const snapshot = await browser.eyesCheckSnapshot(
15
- DSControlledCheckboxCO.snapshotPath('checkbox-tooltip-longword'),
16
- );
14
+ const snapshot = await browser.percyCheckScreenshot();
17
15
  await expect(snapshot).toEqual(0);
18
16
  });
19
17
  });
@@ -16,7 +16,7 @@ if (
16
16
  const checkbox = await DSControlledCheckboxCO.getCheckboxByIndex(0);
17
17
  await checkbox.waitForExist();
18
18
  const result = await axeCoreCheck();
19
- expect(result.length).toBe(0);
19
+ await expect(result).toHaveLength(0);
20
20
  });
21
21
  });
22
22
  }
@@ -10,7 +10,7 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
10
10
  await browser.eyesOpen();
11
11
  const checkbox = await DSControlledCheckboxCO.getCheckboxByIndex(1);
12
12
  await checkbox.waitForExist();
13
- const snapshot = await browser.eyesCheckSnapshot(DSControlledCheckboxCO.snapshotPath('checkbox-wrapped'));
13
+ const snapshot = await browser.percyCheckScreenshot();
14
14
  await expect(snapshot).toEqual(0);
15
15
  });
16
16
  });
@@ -11,18 +11,14 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
11
11
  await browser.eyesOpen();
12
12
  const firstcheckbox = await DSControlledCheckboxCO.getCheckboxByIndex(0);
13
13
  await firstcheckbox.click();
14
- const snapshot = await browser.eyesCheckSnapshot(
15
- DSControlledCheckboxCO.snapshotPath('checkbox-aria-disabled-mouse'),
16
- );
14
+ const snapshot = await browser.percyCheckScreenshot();
17
15
  await expect(snapshot).toEqual(0);
18
16
  });
19
17
  it('02: The second aria-disabled checkbox should be focused - KB nav', async () => {
20
18
  await browser.eyesOpen();
21
19
  await browser.keys(Key.Tab);
22
20
  await browser.keys(Key.Enter);
23
- const snapshot = await browser.eyesCheckSnapshot(
24
- DSControlledCheckboxCO.snapshotPath('checkbox-aria-disabled-kb-nav'),
25
- );
21
+ const snapshot = await browser.percyCheckScreenshot();
26
22
  await expect(snapshot).toEqual(0);
27
23
  });
28
24
  });
@@ -18,7 +18,7 @@ if (
18
18
  const checkbox = await DSControlledCheckboxCO.getCheckboxByIndex(1);
19
19
  await checkbox.click();
20
20
  const result = await axeCoreCheck();
21
- await expect(result.length).toBe(0);
21
+ await expect(result).toHaveLength(0);
22
22
  });
23
23
  });
24
24
  }
@@ -18,24 +18,24 @@ if (
18
18
  const checkbox = await DSControlledCheckboxCO.getCheckboxByIndex(0);
19
19
  await checkbox.waitForExist();
20
20
  const result = await axeCoreCheck();
21
- expect(result.length).toBe(0);
21
+ await expect(result).toHaveLength(0);
22
22
  });
23
23
  it('02: Evaluate checkbox accessibility with axe-core (focused)', async () => {
24
24
  await browser.keys(Key.Tab);
25
25
  const result = await axeCoreCheck();
26
- expect(result.length).toBe(0);
26
+ await expect(result).toHaveLength(0);
27
27
  });
28
28
  it('03: Evaluate checkbox accessibility with axe-core (hovered)', async () => {
29
29
  const checkbox = await DSControlledCheckboxCO.getCheckboxByIndex(10);
30
30
  await mouseOver(checkbox);
31
31
  const result = await axeCoreCheck();
32
- expect(result.length).toBe(0);
32
+ await expect(result).toHaveLength(0);
33
33
  });
34
34
  it('04: Evaluate checkbox accessibility with axe-core (clicked)', async () => {
35
35
  const checkbox = await DSControlledCheckboxCO.getCheckboxByIndex(10);
36
36
  await checkbox.click();
37
37
  const result = await axeCoreCheck();
38
- expect(result.length).toBe(0);
38
+ await expect(result).toHaveLength(0);
39
39
  });
40
40
  });
41
41
  }
@@ -11,7 +11,7 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
11
11
  await browser.eyesOpen();
12
12
  const checkbox = await DSControlledCheckboxCO.getCheckboxByIndex(1);
13
13
  await checkbox.waitForExist();
14
- const snapshot = await browser.eyesCheckSnapshot(DSControlledCheckboxCO.snapshotPath('checkbox-layout'));
14
+ const snapshot = await browser.percyCheckScreenshot();
15
15
  await expect(snapshot).toEqual(0);
16
16
  });
17
17
  });
@@ -5,7 +5,7 @@ import { FiltersCO } from '../components';
5
5
 
6
6
  if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
7
7
  // Forward keyboard navigation
8
- describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Multi Select, forward keyboard navigation', () => {
8
+ describe('PUI-18203 - DataTable:: Filters V2 - Creatable Multi Select, forward keyboard navigation', () => {
9
9
  before('loading page', async () => {
10
10
  const errorOnGo = await DSDataTableCO.creatableMultiSelectFilterV2.go();
11
11
  if (errorOnGo) throw errorOnGo;
@@ -38,7 +38,7 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
38
38
  });
39
39
 
40
40
  // Backward keyboard navigation
41
- describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Multi Select, backward keyboard navigation', () => {
41
+ describe('PUI-18204 - DataTable:: Filters V2 - Creatable Multi Select, backward keyboard navigation', () => {
42
42
  before('loading page', async () => {
43
43
  const errorOnGo = await DSDataTableCO.creatableMultiSelectFilterV2.go();
44
44
  if (errorOnGo) throw errorOnGo;
@@ -5,7 +5,7 @@ import { FiltersCO } from '../components';
5
5
 
6
6
  if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
7
7
  // Forward keyboard navigation
8
- describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Select, forward keyboard navigation', () => {
8
+ describe('PUI-18201 - DataTable:: Filters V2 - Creatable Select, forward keyboard navigation', () => {
9
9
  before('loading page', async () => {
10
10
  const errorOnGo = await DSDataTableCO.creatableSelectFilterV2.go();
11
11
  if (errorOnGo) throw errorOnGo;
@@ -38,7 +38,7 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
38
38
  });
39
39
 
40
40
  // Backward keyboard navigation
41
- describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Select, backward keyboard navigation', () => {
41
+ describe('PUI-18202 - DataTable:: Filters V2 - Creatable Select, backward keyboard navigation', () => {
42
42
  before('loading page', async () => {
43
43
  const errorOnGo = await DSDataTableCO.creatableSelectFilterV2.go();
44
44
  if (errorOnGo) throw errorOnGo;
@@ -14,8 +14,9 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
14
14
  });
15
15
  it('01: should have the previous page button disabled', async () => {
16
16
  const prevPageBt = await PaginationNavCO.getPrevPageBt();
17
- const disabled = await prevPageBt.getAttribute('aria-disabled');
18
- await expect(disabled).toBe('true');
17
+ // DSButtonV3 renders the native `disabled` attribute and intentionally omits aria-disabled
18
+ // (that is reserved for applyAriaDisabled/readOnly), so assert the native disabled state.
19
+ await expect(prevPageBt).toBeDisabled();
19
20
  });
20
21
  it('02: should expand the dropdown menu of the pages per component when clicking its button', async () => {
21
22
  const elemsPerPage = await PaginationNavCO.getElemsPerPageMenu();
@@ -54,6 +54,13 @@ if (
54
54
  const resizer = await HeaderCO.getResizer(1);
55
55
  await expect(resizer).toBeFocused();
56
56
 
57
+ // Disclosure guard. At rest every handle is tabindex="-1" + aria-hidden="true" (isReachable
58
+ // false), so the ARIA contract test 01 asserts is correct but not yet perceivable — by design,
59
+ // to keep idle resizers out of the AT tree. Once focused the handle must be exposed: a focused
60
+ // element left aria-hidden is a real a11y defect, and toBeFocused() alone would still pass.
61
+ await expect(resizer).toHaveAttribute('tabindex', '0');
62
+ expect(await resizer.getAttribute('aria-hidden')).toBe(null);
63
+
57
64
  const before = Number(await resizer.getAttribute('aria-valuenow'));
58
65
  await browser.keys(Key.ArrowRight);
59
66
  await browser.waitUntil(async () => Number(await resizer.getAttribute('aria-valuenow')) > before, {
@@ -97,6 +104,13 @@ if (
97
104
  const resizer = await HeaderCO.getResizer(1);
98
105
  await expect(resizer).toBeFocused();
99
106
 
107
+ // Disclosure guard. At rest every handle is tabindex="-1" + aria-hidden="true" (isReachable
108
+ // false), so the ARIA contract test 01 asserts is correct but not yet perceivable — by design,
109
+ // to keep idle resizers out of the AT tree. Once focused the handle must be exposed: a focused
110
+ // element left aria-hidden is a real a11y defect, and toBeFocused() alone would still pass.
111
+ await expect(resizer).toHaveAttribute('tabindex', '0');
112
+ expect(await resizer.getAttribute('aria-hidden')).toBe(null);
113
+
100
114
  const before = Number(await resizer.getAttribute('aria-valuenow'));
101
115
  await browser.keys(Key.ArrowRight);
102
116
  await browser.waitUntil(async () => Number(await resizer.getAttribute('aria-valuenow')) > before, {
@@ -74,6 +74,8 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
74
74
  await browser.keys(Key.Return);
75
75
  await browser.keys(Key.ArrowDown);
76
76
  await browser.keys(Key.Return);
77
+ await browser.keys(Key.ArrowDown);
78
+ await browser.keys(Key.Return);
77
79
  await FiltersCO.openFilterPopperByColumnName('name', 0);
78
80
  await browser.keys(Key.ArrowDown);
79
81
  await browser.keys(Key.Return);
@@ -25,6 +25,8 @@ export default class DSDatePickerCO extends PageObject {
25
25
 
26
26
  static timeLinearAxis = new Urlbuilder(PATH_E2E_DATAVIZ_AXIS, 'time-linear-axis-test');
27
27
 
28
+ static timeLinearAxisAxe = new Urlbuilder(PATH_E2E_DATAVIZ_AXIS, 'time-linear-axis-axe-test');
29
+
28
30
  // area
29
31
 
30
32
  static basicArea = new Urlbuilder(PATH_E2E_DATAVIZ_AREA, 'basic-area-test');
@@ -29,7 +29,7 @@ if (
29
29
 
30
30
  describe('PUI-11371 - DSDataViz, TimeLinear axis -AxeCore', () => {
31
31
  before('loading page', async () => {
32
- const errorOnGo = await DSDataVizCO.timeLinearAxis.go();
32
+ const errorOnGo = await DSDataVizCO.timeLinearAxisAxe.go();
33
33
  if (errorOnGo) throw errorOnGo;
34
34
  });
35
35
  it('01: should display a chart with time-linear axis and pass axe-core scan', async () => {
@@ -37,6 +37,8 @@ export default class DSComboboxMultiCO extends PageObject {
37
37
 
38
38
  static inlineTest = new Urlbuilder(PATH_E2E_COMBOBOX_MULTI, 'inline-test');
39
39
 
40
+ static withTooltip = new Urlbuilder(PATH_E2E_COMBOBOX_MULTI, 'with-tooltip-test');
41
+
40
42
  static controlledMenuStateWithSectionsSlotsTest = new Urlbuilder(
41
43
  PATH_E2E_COMBOBOX_MULTI_SLOTS,
42
44
  'controlled-menu-state-with-section-slots-test',
@@ -136,6 +138,15 @@ export default class DSComboboxMultiCO extends PageObject {
136
138
  return $$('[data-testid="ds-pill-close-icon"]')[index];
137
139
  }
138
140
 
141
+ static async getPillsByComboboxIndex(index) {
142
+ const selectedValues = await this.getSelectedValuesByIndex(index);
143
+ return selectedValues.$$('[data-testid="ds-pill-wrapper"]');
144
+ }
145
+
146
+ static async getPillCloseBtnByPillLabel(label) {
147
+ return $(`[data-testid="ds-pill-wrapper"][data-label="${label}"] [data-testid="ds-pill-close-icon"]`);
148
+ }
149
+
139
150
  // OPTIONS
140
151
  static async getOptionByLabel(label) {
141
152
  return $(`//li[@data-testid="combobox-option"]//span[contains(text(), "${label}")]/ancestor::li`);
@@ -0,0 +1,59 @@
1
+ import { Key } from 'webdriverio';
2
+ import DSComboboxMultiCO from '../DSComboboxMultiCO';
3
+
4
+ // Reproduces PUI-17870 on the exact surface it was reported on: the SECOND combobox of the
5
+ // `apply-aria-disabled-test` story, whose container is enabled while its two selected values carry
6
+ // per-item state — "Padme Amidala (pill aria-disabled)" (applyAriaDisabled) and
7
+ // "Han Solo (disabled)" (disabled). Both pills stay type `removable`, so their remove button is
8
+ // rendered, and neither must be removable. Fix originally shipped with PUI-17861.
9
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
10
+ describe('PUI-18843 - ComboboxMulti:: per-item disabled and aria-disabled pills - Func', () => {
11
+ const ARIA_DISABLED_PILL = 'Padme Amidala (pill aria-disabled)';
12
+ const DISABLED_PILL = 'Han Solo (disabled)';
13
+
14
+ before('loading page', async () => {
15
+ const errorOnGo = await DSComboboxMultiCO.applyAriaDisabled.go();
16
+ if (errorOnGo) throw errorOnGo;
17
+ });
18
+
19
+ it('01: should reflect each per-item state on its own remove button', async () => {
20
+ const ariaDisabledCloseBtn = await DSComboboxMultiCO.getPillCloseBtnByPillLabel(ARIA_DISABLED_PILL);
21
+ await ariaDisabledCloseBtn.waitForDisplayed();
22
+ const disabledCloseBtn = await DSComboboxMultiCO.getPillCloseBtnByPillLabel(DISABLED_PILL);
23
+ const pills = await DSComboboxMultiCO.getPillsByComboboxIndex(1);
24
+
25
+ await expect(pills.length).toEqual(2);
26
+ await expect(ariaDisabledCloseBtn).toHaveAttribute('aria-disabled', 'true');
27
+ await expect(ariaDisabledCloseBtn).toBeEnabled();
28
+ await expect(disabledCloseBtn).toBeDisabled();
29
+ });
30
+
31
+ it('02: should not remove the disabled pill when its remove button is clicked', async () => {
32
+ const disabledCloseBtn = await DSComboboxMultiCO.getPillCloseBtnByPillLabel(DISABLED_PILL);
33
+ await disabledCloseBtn.click();
34
+
35
+ const pills = await DSComboboxMultiCO.getPillsByComboboxIndex(1);
36
+ const disabledCloseBtnAfterClick = await DSComboboxMultiCO.getPillCloseBtnByPillLabel(DISABLED_PILL);
37
+
38
+ await expect(pills.length).toEqual(2);
39
+ await expect(disabledCloseBtnAfterClick).toBeExisting();
40
+ });
41
+
42
+ it('03: should not remove the aria-disabled pill when its remove button is clicked', async () => {
43
+ const ariaDisabledCloseBtn = await DSComboboxMultiCO.getPillCloseBtnByPillLabel(ARIA_DISABLED_PILL);
44
+ await ariaDisabledCloseBtn.click();
45
+
46
+ // The guarded remove handler returns before stopping propagation, so the click reaches the
47
+ // combobox and opens its menu — expected, the container itself is not disabled.
48
+ const menuList = await DSComboboxMultiCO.getMenuList();
49
+ await menuList.waitForDisplayed();
50
+ await browser.keys(Key.Escape);
51
+
52
+ const pills = await DSComboboxMultiCO.getPillsByComboboxIndex(1);
53
+ const ariaDisabledCloseBtnAfterClick = await DSComboboxMultiCO.getPillCloseBtnByPillLabel(ARIA_DISABLED_PILL);
54
+
55
+ await expect(pills.length).toEqual(2);
56
+ await expect(ariaDisabledCloseBtnAfterClick).toBeExisting();
57
+ });
58
+ });
59
+ }
@@ -0,0 +1,39 @@
1
+ import DSComboboxMultiCO from '../DSComboboxMultiCO';
2
+ import { mouseOver } from '../../helpers';
3
+
4
+ // Reproduces the visual half of PUI-17870 on the surface it was reported on: the SECOND combobox of
5
+ // the `apply-aria-disabled-test` story, whose container is enabled while its two selected values
6
+ // carry per-item state. Both pills keep their remove button, and neither must paint the hover
7
+ // background nor the brand icon color that an enabled pill does. Fix shipped with PUI-17861.
8
+ // Applitools Eyes is used instead of Percy on purpose: Percy serializes the DOM and re-renders it
9
+ // without a pointer, so a CSS-only `:hover` state would be lost from the snapshot.
10
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
11
+ describe('PUI-18844 - ComboboxMulti:: per-item pill remove button hover - Visual', () => {
12
+ const ARIA_DISABLED_PILL = 'Padme Amidala (pill aria-disabled)';
13
+ const DISABLED_PILL = 'Han Solo (disabled)';
14
+
15
+ before('loading page', async () => {
16
+ const errorOnGo = await DSComboboxMultiCO.applyAriaDisabled.go();
17
+ if (errorOnGo) throw errorOnGo;
18
+ });
19
+
20
+ it('01: should keep the aria-disabled pill remove button dimmed with no hover background', async () => {
21
+ await browser.eyesOpen();
22
+ const closeBtn = await DSComboboxMultiCO.getPillCloseBtnByPillLabel(ARIA_DISABLED_PILL);
23
+ await closeBtn.waitForDisplayed();
24
+ await mouseOver(closeBtn);
25
+ const snapshotName = 'combobox-multi-pill-remove-hover-aria-disabled';
26
+ const snapshot = await browser.eyesCheckSnapshot(DSComboboxMultiCO.snapshotPath(snapshotName));
27
+ await expect(snapshot).toEqual(0);
28
+ });
29
+
30
+ it('02: should keep the disabled pill remove button dimmed with no hover background', async () => {
31
+ await browser.eyesOpen();
32
+ const closeBtn = await DSComboboxMultiCO.getPillCloseBtnByPillLabel(DISABLED_PILL);
33
+ await mouseOver(closeBtn);
34
+ const snapshotName = 'combobox-multi-pill-remove-hover-disabled';
35
+ const snapshot = await browser.eyesCheckSnapshot(DSComboboxMultiCO.snapshotPath(snapshotName));
36
+ await expect(snapshot).toEqual(0);
37
+ });
38
+ });
39
+ }
@@ -0,0 +1,39 @@
1
+ import DSComboboxMultiCO from '../DSComboboxMultiCO';
2
+ import DSTooltipV3CO from '../../ds-tooltip-v3/DSTooltipV3CO';
3
+ import { axeCoreCheck, mouseOver } from '../../helpers';
4
+
5
+ // Remediation for PUI-18660: the accessible path to the truncated values is the DSTooltipV3 wrapping
6
+ // the aria-disabled combobox, so the axe scan must cover the tooltip while it is OPEN (its DOM only
7
+ // exists then) — not just the resting markup.
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-18814 - ComboboxMulti:: aria-disabled truncated values tooltip - Axe-Core', () => {
15
+ before('loading page', async () => {
16
+ const errorOnGo = await DSComboboxMultiCO.withTooltip.go();
17
+ if (errorOnGo) throw errorOnGo;
18
+ });
19
+
20
+ it('01: should have no violations at rest (aria-disabled combobox + describedby wiring)', async () => {
21
+ const combobox = await DSComboboxMultiCO.getComboboxWrapper();
22
+ await combobox.waitForDisplayed();
23
+
24
+ const result = await axeCoreCheck();
25
+ expect(result.length).toBe(0);
26
+ });
27
+
28
+ it('02: should have no violations with the tooltip open over the combobox', async () => {
29
+ const combobox = await DSComboboxMultiCO.getComboboxWrapper();
30
+ await mouseOver(combobox);
31
+
32
+ const tooltip = await DSTooltipV3CO.getTooltip();
33
+ await tooltip.waitForDisplayed();
34
+
35
+ const result = await axeCoreCheck();
36
+ expect(result.length).toBe(0);
37
+ });
38
+ });
39
+ }
@@ -0,0 +1,39 @@
1
+ import { Key } from 'webdriverio';
2
+ import DSComboboxMultiCO from '../DSComboboxMultiCO';
3
+ import DSTooltipV3CO from '../../ds-tooltip-v3/DSTooltipV3CO';
4
+ import { mouseOver } from '../../helpers';
5
+
6
+ // Remediation for PUI-18660: the combobox no longer renders its own truncation tooltip. In an
7
+ // aria-disabled combobox the menu cannot be opened, so the only accessible path to the full,
8
+ // truncated selected values is the consumer-provided DSTooltipV3 wrapping the combobox.
9
+ const FULL_VALUE = 'Luke Skywalker too long this text is super long';
10
+
11
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
12
+ describe('PUI-18813 - ComboboxMulti:: aria-disabled truncated values tooltip - Func', () => {
13
+ before('loading page', async () => {
14
+ const errorOnGo = await DSComboboxMultiCO.withTooltip.go();
15
+ if (errorOnGo) throw errorOnGo;
16
+ });
17
+
18
+ it('01: should not display the tooltip before hover', async () => {
19
+ const tooltip = await DSTooltipV3CO.getTooltip();
20
+ await expect(tooltip).not.toBeDisplayed();
21
+ });
22
+
23
+ it('02: should reveal the full selected values via tooltip on hover', async () => {
24
+ const combobox = await DSComboboxMultiCO.getComboboxWrapper();
25
+ await mouseOver(combobox);
26
+
27
+ const tooltip = await DSTooltipV3CO.getTooltip();
28
+ await expect(tooltip).toBeDisplayed();
29
+ await expect(tooltip).toHaveText(expect.stringContaining(FULL_VALUE));
30
+ });
31
+
32
+ it('03: should hide the tooltip on pressing Escape', async () => {
33
+ await browser.keys(Key.Escape);
34
+
35
+ const tooltip = await DSTooltipV3CO.getTooltip();
36
+ await expect(tooltip).not.toBeDisplayed();
37
+ });
38
+ });
39
+ }
@@ -0,0 +1,29 @@
1
+ import DSComboboxMultiCO from '../DSComboboxMultiCO';
2
+ import DSTooltipV3CO from '../../ds-tooltip-v3/DSTooltipV3CO';
3
+ import { mouseOver } from '../../helpers';
4
+
5
+ // Visual coverage for the PUI-18660 remediation: the DSTooltipV3 opened over an aria-disabled
6
+ // ComboboxMulti must render on top and correctly positioned (not occluded, clipped or misplaced).
7
+ // Occlusion/positioning regressions are invisible to func/axe (toBeDisplayed ignores stacking),
8
+ // so they are captured here with a Percy snapshot of the open tooltip.
9
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
10
+ describe('PUI-18817 - ComboboxMulti:: aria-disabled truncated values tooltip - Visual', () => {
11
+ before('loading page', async () => {
12
+ const errorOnGo = await DSComboboxMultiCO.withTooltip.go();
13
+ if (errorOnGo) throw errorOnGo;
14
+ });
15
+
16
+ it('01: should render the tooltip positioned over the aria-disabled combobox', async () => {
17
+ const combobox = await DSComboboxMultiCO.getComboboxWrapper();
18
+ await mouseOver(combobox);
19
+
20
+ const tooltip = await DSTooltipV3CO.getTooltip();
21
+ await tooltip.waitForDisplayed();
22
+
23
+ const snapshot = await browser.percyCheckScreenshot(
24
+ DSComboboxMultiCO.snapshotPath('combobox-multi-aria-disabled-tooltip'),
25
+ );
26
+ await expect(snapshot).toEqual(0);
27
+ });
28
+ });
29
+ }
@@ -43,6 +43,8 @@ export default class DSComboboxSingleCO extends PageObject {
43
43
 
44
44
  static creatableTest = new Urlbuilder(PATH_E2E_COMBOBOX_SINGLE, 'creatable-test');
45
45
 
46
+ static withTooltip = new Urlbuilder(PATH_E2E_COMBOBOX_SINGLE, 'with-tooltip-test');
47
+
46
48
  // COMBOBOX - INPUT
47
49
  static async getCombobox() {
48
50
  return $('[data-testid="combobox-container"]');
@@ -0,0 +1,39 @@
1
+ import DSComboboxSingleCO from '../DSComboboxSingleCO';
2
+ import DSTooltipV3CO from '../../ds-tooltip-v3/DSTooltipV3CO';
3
+ import { axeCoreCheck, mouseOver } from '../../helpers';
4
+
5
+ // Remediation for PUI-18660: the accessible path to the truncated value is the DSTooltipV3 wrapping
6
+ // the aria-disabled combobox, so the axe scan must cover the tooltip while it is OPEN (its DOM only
7
+ // exists then) — not just the resting markup.
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-18816 - ComboboxSingle:: aria-disabled truncated value tooltip - Axe-Core', () => {
15
+ before('loading page', async () => {
16
+ const errorOnGo = await DSComboboxSingleCO.withTooltip.go();
17
+ if (errorOnGo) throw errorOnGo;
18
+ });
19
+
20
+ it('01: should have no violations at rest (aria-disabled combobox + describedby wiring)', async () => {
21
+ const combobox = await DSComboboxSingleCO.getComboboxWrapper();
22
+ await combobox.waitForDisplayed();
23
+
24
+ const result = await axeCoreCheck();
25
+ expect(result.length).toBe(0);
26
+ });
27
+
28
+ it('02: should have no violations with the tooltip open over the combobox', async () => {
29
+ const combobox = await DSComboboxSingleCO.getComboboxWrapper();
30
+ await mouseOver(combobox);
31
+
32
+ const tooltip = await DSTooltipV3CO.getTooltip();
33
+ await tooltip.waitForDisplayed();
34
+
35
+ const result = await axeCoreCheck();
36
+ expect(result.length).toBe(0);
37
+ });
38
+ });
39
+ }
@@ -0,0 +1,39 @@
1
+ import { Key } from 'webdriverio';
2
+ import DSComboboxSingleCO from '../DSComboboxSingleCO';
3
+ import DSTooltipV3CO from '../../ds-tooltip-v3/DSTooltipV3CO';
4
+ import { mouseOver } from '../../helpers';
5
+
6
+ // Remediation for PUI-18660: the combobox no longer renders its own truncation tooltip. In an
7
+ // aria-disabled combobox the menu cannot be opened, so the only accessible path to the full,
8
+ // truncated selected value is the consumer-provided DSTooltipV3 wrapping the combobox.
9
+ const FULL_VALUE = 'Luke Skywalker too long this text is super long';
10
+
11
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
12
+ describe('PUI-18815 - ComboboxSingle:: aria-disabled truncated value tooltip - Func', () => {
13
+ before('loading page', async () => {
14
+ const errorOnGo = await DSComboboxSingleCO.withTooltip.go();
15
+ if (errorOnGo) throw errorOnGo;
16
+ });
17
+
18
+ it('01: should not display the tooltip before hover', async () => {
19
+ const tooltip = await DSTooltipV3CO.getTooltip();
20
+ await expect(tooltip).not.toBeDisplayed();
21
+ });
22
+
23
+ it('02: should reveal the full selected value via tooltip on hover', async () => {
24
+ const combobox = await DSComboboxSingleCO.getComboboxWrapper();
25
+ await mouseOver(combobox);
26
+
27
+ const tooltip = await DSTooltipV3CO.getTooltip();
28
+ await expect(tooltip).toBeDisplayed();
29
+ await expect(tooltip).toHaveText(expect.stringContaining(FULL_VALUE));
30
+ });
31
+
32
+ it('03: should hide the tooltip on pressing Escape', async () => {
33
+ await browser.keys(Key.Escape);
34
+
35
+ const tooltip = await DSTooltipV3CO.getTooltip();
36
+ await expect(tooltip).not.toBeDisplayed();
37
+ });
38
+ });
39
+ }
@@ -0,0 +1,29 @@
1
+ import DSComboboxSingleCO from '../DSComboboxSingleCO';
2
+ import DSTooltipV3CO from '../../ds-tooltip-v3/DSTooltipV3CO';
3
+ import { mouseOver } from '../../helpers';
4
+
5
+ // Visual coverage for the PUI-18660 remediation: the DSTooltipV3 opened over an aria-disabled
6
+ // ComboboxSingle must render on top and correctly positioned (not occluded, clipped or misplaced).
7
+ // Occlusion/positioning regressions are invisible to func/axe (toBeDisplayed ignores stacking),
8
+ // so they are captured here with a Percy snapshot of the open tooltip.
9
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
10
+ describe('PUI-18818 - ComboboxSingle:: aria-disabled truncated value tooltip - Visual', () => {
11
+ before('loading page', async () => {
12
+ const errorOnGo = await DSComboboxSingleCO.withTooltip.go();
13
+ if (errorOnGo) throw errorOnGo;
14
+ });
15
+
16
+ it('01: should render the tooltip positioned over the aria-disabled combobox', async () => {
17
+ const combobox = await DSComboboxSingleCO.getComboboxWrapper();
18
+ await mouseOver(combobox);
19
+
20
+ const tooltip = await DSTooltipV3CO.getTooltip();
21
+ await tooltip.waitForDisplayed();
22
+
23
+ const snapshot = await browser.percyCheckScreenshot(
24
+ DSComboboxSingleCO.snapshotPath('combobox-single-aria-disabled-tooltip'),
25
+ );
26
+ await expect(snapshot).toEqual(0);
27
+ });
28
+ });
29
+ }
@@ -107,8 +107,9 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
107
107
  const drillFirstItemBtn = await DSHookCO.getDrillThisBtnByIndex(0);
108
108
  await drillFirstItemBtn.click();
109
109
  const drillFirstChildBtn = await DSHookCO.getDrillThisBtnByIndex(0);
110
- const isDisabled = await drillFirstChildBtn.getAttribute('aria-disabled');
111
- await expect(isDisabled).toBe('true');
110
+ // Since PUI-17909 DSButtonV2 renders the native `disabled` attribute and intentionally omits
111
+ // aria-disabled (that is reserved for applyAriaDisabled/readOnly), so assert the native disabled state.
112
+ await expect(drillFirstChildBtn).toBeDisabled();
112
113
  });
113
114
  });
114
115
  }