dimsum-e2e-tests 3.70.0-next.48 → 3.70.0-next.50

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 (26) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/ds-controlled-form/ds-controlled-radio/aria-disabled/DSControlledRadio.aria-disabled.axe-core.func.spec.js +16 -2
  3. package/ds-controlled-form/ds-controlled-radio/aria-disabled/DSControlledRadio.aria-disabled.func.spec.js +37 -0
  4. package/ds-data-table-async/DSDataTableCO.js +2 -0
  5. package/ds-data-table-async/components/HeaderCO.js +15 -0
  6. package/ds-data-table-async/filter-menu-close/DSDataTable.filter-menu-close.func.spec.js +39 -0
  7. package/ds-data-table-async/header-affordances/DSDataTable.header-affordances.func.spec.js +92 -0
  8. package/ds-data-table-async/resizable/DSDataTable.resize-min-clamp.func.spec.js +72 -0
  9. package/ds-data-table-async/toggle-cell-focus/DSDataTable.toggle-cell-enter-focus.func.spec.js +31 -0
  10. package/ds-form-date-range-picker/DateRangePicker.axe-core.spec.js +5 -0
  11. package/ds-form-date-range-picker/DateRangePicker.functional.spec.js +80 -18
  12. package/ds-form-date-range-picker/DateRangePickerCO.js +6 -0
  13. package/ds-form-date-time-picker/partial-date-open-focus/DateTimePicker.partial-date-open-focus.func.spec.js +45 -0
  14. package/ds-form-toggle/DSToggle.func.spec.js +20 -23
  15. package/ds-form-toggle/DSToggleCO.js +11 -2
  16. package/ds-global-header/GlobalHeader.announcements.func.spec.js +27 -0
  17. package/ds-global-header/GlobalHeader.axe-core.func.spec.js +15 -15
  18. package/ds-global-header/GlobalHeader.func.spec.js +70 -1
  19. package/ds-global-header/GlobalHeaderCO.js +25 -1
  20. package/ds-hooks/useFocusStack/DSHook.useFocusStack.func.spec.js +83 -0
  21. package/ds-shuttle-v2/DSShuttleV2CO.js +4 -0
  22. package/ds-shuttle-v2/breadcrumb-a11y/DSShuttleV2.breadcrumb-a11y.func.spec.js +43 -0
  23. package/ds-shuttle-v2/items/DSShuttleV2.items.func.spec.js +4 -2
  24. package/package.json +149 -150
  25. package/paths.js +0 -3
  26. package/ds-hooks/useFocusStack/DSHook.useFocusStack.skipped.js +0 -57
@@ -36,8 +36,17 @@ export default class DSToggleCO extends PageObject {
36
36
  return $$('[data-testid="ds-controlled-toggle-checkbox"]')[index];
37
37
  }
38
38
 
39
- static async getToggleState(state) {
40
- return $(`//div/div[contains(text(), "${state}")]`);
39
+ // The on/off state is exposed semantically via aria-checked on the role="switch"
40
+ // button. Post PUI-16323 the visible ON/OFF label is aria-hidden and purely
41
+ // presentational, so state must be read from aria-checked, not the label text.
42
+ static async getSwitch(index = 0) {
43
+ return $$('button[role="switch"]')[index];
44
+ }
45
+
46
+ // Presentational ON/OFF label (aria-hidden). Targeted via its stable slot
47
+ // data-testid so we can assert the visible text tracks the state.
48
+ static async getStateLabel(index = 0) {
49
+ return $$('[data-testid="ds-formtoggle-text-wrapper"]')[index];
41
50
  }
42
51
 
43
52
  static async getTooltip() {
@@ -0,0 +1,27 @@
1
+ import GlobalHeader from './GlobalHeaderCO';
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
+ describe('PUI-18771 - GlobalHeader: SearchToggle result announcement -Func', () => {
10
+ before(async () => {
11
+ const errorOnGo = await GlobalHeader.withSearchToggleURL.go();
12
+ if (errorOnGo) throw errorOnGo;
13
+ await GlobalHeader.openAndPopulateSearchToggle();
14
+ });
15
+ it('01: search input should expose the accessible name guiding users to the result navigation', async () => {
16
+ const searchInput = await GlobalHeader.getSearchToggleInput();
17
+ await expect(searchInput).toHaveAttribute(
18
+ 'aria-label',
19
+ 'Search among the content of the page. Press Tab twice to reach the result navigation.',
20
+ );
21
+ });
22
+ it('02: results spinbutton should announce the total result count after typing', async () => {
23
+ const spinButton = await GlobalHeader.getSearchToggleSpinbutton();
24
+ await expect(spinButton).toHaveAttribute('aria-valuetext', '3 total results');
25
+ });
26
+ });
27
+ }
@@ -19,14 +19,14 @@ if (
19
19
  await browser.keys(Key.Tab);
20
20
  await browser.keys(Key.Tab);
21
21
  const result = await axeCoreCheck();
22
- expect(result.length).toBe(0);
22
+ await expect(result).toHaveLength(0);
23
23
  });
24
24
  it('02: should have global header with expanded appPicker and pass axe-core scan', async () => {
25
25
  await browser.keys(Key.Tab);
26
26
  await browser.keys(Key.Enter);
27
27
 
28
28
  const result = await axeCoreCheck();
29
- expect(result.length).toBe(0);
29
+ await expect(result).toHaveLength(0);
30
30
  });
31
31
  it('03: should have global header with expanded menu-list and pass axe-core scan', async () => {
32
32
  await browser.keys(Key.Escape);
@@ -34,7 +34,7 @@ if (
34
34
  await browser.keys(Key.Tab);
35
35
  await browser.keys(Key.Enter);
36
36
  const result = await axeCoreCheck();
37
- expect(result.length).toBe(0);
37
+ await expect(result).toHaveLength(0);
38
38
  });
39
39
  });
40
40
 
@@ -47,12 +47,12 @@ if (
47
47
  const globalHeader = await GlobalHeaderCO.getGlobalHeader();
48
48
  await globalHeader.waitForDisplayed();
49
49
  const result = await axeCoreCheck();
50
- expect(result.length).toBe(0);
50
+ await expect(result).toHaveLength(0);
51
51
  });
52
52
  });
53
53
 
54
54
  // Skipped due to defect PUI-17970
55
- describe.skip('PUI-12447 - GlobalHeader: toggle search -AxeCore', () => {
55
+ describe('PUI-12447 - GlobalHeader: toggle search -AxeCore', () => {
56
56
  before(async () => {
57
57
  const errorOnGo = await GlobalHeaderCO.withSearchToggleURL.go();
58
58
  if (errorOnGo) throw errorOnGo;
@@ -61,19 +61,19 @@ if (
61
61
  const globalHeader = await GlobalHeaderCO.getGlobalHeader();
62
62
  await globalHeader.waitForDisplayed();
63
63
  const result = await axeCoreCheck();
64
- expect(result.length).toBe(0);
64
+ await expect(result).toHaveLength(0);
65
65
  });
66
66
  it('02: should have global header with toggle-search expanded and pass axe-core scan', async () => {
67
67
  const toggleSearch = await GlobalHeaderCO.getGHToolbarItem(0);
68
68
  await toggleSearch.click();
69
69
  await type('Hola');
70
70
  const result = await axeCoreCheck();
71
- expect(result.length).toBe(0);
71
+ await expect(result).toHaveLength(0);
72
72
  });
73
73
  it('03: should have global header with populated toggle-search and pass axe-core scan', async () => {
74
74
  await type('Hola');
75
75
  const result = await axeCoreCheck();
76
- expect(result.length).toBe(0);
76
+ await expect(result).toHaveLength(0);
77
77
  });
78
78
  });
79
79
 
@@ -86,12 +86,12 @@ if (
86
86
  const globalHeader = await GlobalHeaderCO.getGlobalHeader();
87
87
  await globalHeader.waitForDisplayed();
88
88
  const result = await axeCoreCheck();
89
- expect(result.length).toBe(0);
89
+ await expect(result).toHaveLength(0);
90
90
  });
91
91
  });
92
92
 
93
93
  // Skipped due to defect PUI-17970
94
- describe.skip('PUI-18379 - GlobalHeader: with search toggle -AxeCore', () => {
94
+ describe('PUI-18379 - GlobalHeader: with search toggle -AxeCore', () => {
95
95
  before(async () => {
96
96
  const errorOnGo = await GlobalHeaderCO.withSearchToggleURL.go();
97
97
  if (errorOnGo) throw errorOnGo;
@@ -103,7 +103,7 @@ if (
103
103
  await expect(toggleSearch).toHaveAttribute('aria-expanded', 'false');
104
104
  await expect(toggleSearch).toHaveAttribute('aria-controls');
105
105
  const result = await axeCoreCheck();
106
- expect(result.length).toBe(0);
106
+ await expect(result).toHaveLength(0);
107
107
  });
108
108
  it('02: should have global header with search toggle expanded and pass axe-core scan', async () => {
109
109
  const toggleSearch = await GlobalHeaderCO.getGHToolbarItem(0);
@@ -111,17 +111,17 @@ if (
111
111
  await expect(toggleSearch).toHaveAttribute('aria-expanded', 'true');
112
112
  await expect(toggleSearch).toHaveAttribute('aria-controls', /^ds-global-header/);
113
113
  const result = await axeCoreCheck();
114
- expect(result.length).toBe(0);
114
+ await expect(result).toHaveLength(0);
115
115
  });
116
116
  it('03: should have global header with populated search toggle and pass axe-core scan', async () => {
117
117
  await type('Labor');
118
118
  const result = await axeCoreCheck();
119
- expect(result.length).toBe(0);
119
+ await expect(result).toHaveLength(0);
120
120
  });
121
121
  });
122
122
 
123
123
  // Skipped due to defect PUI-17970
124
- describe.skip('PUI-16270 - GlobalHeader: Controled with Iframe -AxeCore', () => {
124
+ describe('PUI-16270 - GlobalHeader: Controled with Iframe -AxeCore', () => {
125
125
  before(async () => {
126
126
  const errorOnGo = await GlobalHeaderCO.iframeURL.go();
127
127
  if (errorOnGo) throw errorOnGo;
@@ -130,7 +130,7 @@ if (
130
130
  const globalHeader = await GlobalHeaderCO.getGlobalHeader();
131
131
  await globalHeader.waitForDisplayed();
132
132
  const result = await axeCoreCheck({ extraDisabledRules: ['landmark-one-main'] });
133
- expect(result.length).toBe(0);
133
+ await expect(result).toHaveLength(0);
134
134
  });
135
135
  });
136
136
  }
@@ -1,7 +1,19 @@
1
1
  import { Key } from 'webdriverio';
2
2
  import GlobalHeader from './GlobalHeaderCO';
3
3
 
4
- if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
4
+ // Asserts the search-toggle spinbutton reflects the expected selected-result state.
5
+ const expectSelectedResult = async (valuenow, valuetext) => {
6
+ const spinButton = await GlobalHeader.getSearchToggleSpinbutton();
7
+ await expect(spinButton).toHaveAttribute('aria-valuenow', valuenow);
8
+ await expect(spinButton).toHaveAttribute('aria-valuetext', valuetext);
9
+ };
10
+
11
+ if (
12
+ (!browser.capabilities['ice:options'].isPhone &&
13
+ !browser.capabilities['ice:options'].isTablet &&
14
+ browser.capabilities.browserName === 'chrome') ||
15
+ browser.capabilities.browserName === 'Chrome'
16
+ ) {
5
17
  describe('PUI-10036 - GlobalHeader: title and aria attributes', () => {
6
18
  before(async () => {
7
19
  const errorOnGo = await GlobalHeader.customAttributes.go();
@@ -80,4 +92,61 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
80
92
  await expect(firstToolbarItem).not.toBeFocused();
81
93
  });
82
94
  });
95
+
96
+ // Tests for the fix in PUI-17974 (SearchToggle arrow navigation could not start with ArrowDown nor cycle)
97
+ describe('PUI-18772 - GlobalHeader: SearchToggle result navigation with ArrowDown -Func', () => {
98
+ before(async () => {
99
+ const errorOnGo = await GlobalHeader.withSearchToggleURL.go();
100
+ if (errorOnGo) throw errorOnGo;
101
+ await GlobalHeader.openAndPopulateSearchToggle();
102
+ });
103
+ it('01: should be idle (no result selected) before navigation starts', async () => {
104
+ await expectSelectedResult('0', '3 total results');
105
+ });
106
+ it('02: should start navigation on last result when pressing ArrowDown from idle', async () => {
107
+ await browser.keys(Key.ArrowDown);
108
+ await expectSelectedResult('3', 'result 3 of 3');
109
+ });
110
+ it('03: should move to the previous result on subsequent ArrowDown', async () => {
111
+ await browser.keys(Key.ArrowDown);
112
+ await expectSelectedResult('2', 'result 2 of 3');
113
+ });
114
+ it('04: should reach the first result on ArrowDown', async () => {
115
+ await browser.keys(Key.ArrowDown);
116
+ await expectSelectedResult('1', 'result 1 of 3');
117
+ });
118
+ it('05: should cycle from the first result back to the last on ArrowDown', async () => {
119
+ await browser.keys(Key.ArrowDown);
120
+ await expectSelectedResult('3', 'result 3 of 3');
121
+ });
122
+ });
123
+
124
+ // Tests for the fix in PUI-17974 (SearchToggle arrow navigation could not start with ArrowDown nor cycle)
125
+ describe('PUI-18773 - GlobalHeader: SearchToggle result navigation with ArrowUp -Func', () => {
126
+ // same setup as above; here the ArrowUp navigation is exercised from idle
127
+ before(async () => {
128
+ const errorOnGo = await GlobalHeader.withSearchToggleURL.go();
129
+ if (errorOnGo) throw errorOnGo;
130
+ await GlobalHeader.openAndPopulateSearchToggle();
131
+ });
132
+ it('01: should be idle (no result selected) before navigation starts', async () => {
133
+ await expectSelectedResult('0', '3 total results');
134
+ });
135
+ it('02: should start navigation on the first result when pressing ArrowUp from idle', async () => {
136
+ await browser.keys(Key.ArrowUp);
137
+ await expectSelectedResult('1', 'result 1 of 3');
138
+ });
139
+ it('03: should move to the next result on subsequent ArrowUp', async () => {
140
+ await browser.keys(Key.ArrowUp);
141
+ await expectSelectedResult('2', 'result 2 of 3');
142
+ });
143
+ it('04: should reach the last result on ArrowUp', async () => {
144
+ await browser.keys(Key.ArrowUp);
145
+ await expectSelectedResult('3', 'result 3 of 3');
146
+ });
147
+ it('05: should cycle from the last result back to the first on ArrowUp', async () => {
148
+ await browser.keys(Key.ArrowUp);
149
+ await expectSelectedResult('1', 'result 1 of 3');
150
+ });
151
+ });
83
152
  }
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable import/no-relative-packages */
2
2
  import { PATH_E2E_GLOBAL_HEADER } from '../paths';
3
- import { PageObject, Urlbuilder } from '../helpers';
3
+ import { PageObject, Urlbuilder, type } from '../helpers';
4
4
 
5
5
  export default class GlobalHeader extends PageObject {
6
6
  static basicURL = new Urlbuilder(PATH_E2E_GLOBAL_HEADER, 'basic');
@@ -84,6 +84,30 @@ export default class GlobalHeader extends PageObject {
84
84
  return $('button*=Skip');
85
85
  }
86
86
 
87
+ static async getSearchToggleInput() {
88
+ return $('[data-testid="ds-globalheader-searchtoggle-textinput"]');
89
+ }
90
+
91
+ static async getSearchToggleSpinbutton() {
92
+ return $('[data-testid="ds-globalheader-searchtoggle-spinbutton-text"]');
93
+ }
94
+
95
+ // Opens the search toggle, runs a query, and focuses the populated results spinbutton
96
+ // so result navigation can be exercised. Waits for results to load before returning.
97
+ static async openAndPopulateSearchToggle(searchText = 'Labor') {
98
+ const toggleSearch = await GlobalHeader.getGHToolbarItem(0);
99
+ await toggleSearch.click();
100
+ const searchInput = await GlobalHeader.getSearchToggleInput();
101
+ await searchInput.click();
102
+ await type(searchText);
103
+ const spinButton = await GlobalHeader.getSearchToggleSpinbutton();
104
+ await browser.waitUntil(async () => (await spinButton.getText()) !== 'n/a', {
105
+ timeout: 3000,
106
+ timeoutMsg: 'search results did not populate after typing',
107
+ });
108
+ await spinButton.click();
109
+ }
110
+
87
111
  // Slots
88
112
 
89
113
  static async getGHBreadcrumbChevronlotByIndex(index = 0) {
@@ -0,0 +1,83 @@
1
+ /* eslint-disable max-len */
2
+ import { Key } from 'webdriverio';
3
+ import useFocusStackCO from './useFocusStackCO';
4
+ import { tabStops } from '../../helpers';
5
+ import DSPillsV2CO from '../../ds-pills-v2/DSPillsV2CO';
6
+ import DSButtonV3CO from '../../ds-button-v3/DSButtonV3CO';
7
+
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-13147: UseFocusStack for focus return -Func', () => {
15
+ before(async () => {
16
+ const errorOnGo = await useFocusStackCO.basicURL.go();
17
+ if (errorOnGo) throw errorOnGo;
18
+ });
19
+
20
+ it('01: should Tab x4 and have D focused', async () => {
21
+ await tabStops(4);
22
+ const typographys = (await useFocusStackCO.getTypographys()).length;
23
+ const pillD = await DSPillsV2CO.getCloseButtonByIndex(3);
24
+ // stack holds the three departed elements [C, B, A] -> 1 (h3) + 3
25
+ await expect(typographys).toEqual(4);
26
+ await expect(pillD).toBeFocused();
27
+ });
28
+
29
+ it('02: PUI-13301 - should click non-focused C, remove it, and keep focus on D (not B)', async () => {
30
+ // D is focused; click C (index 2) to remove it. Focus must return to D, the pre-click element.
31
+ const pillC = await DSPillsV2CO.getCloseButtonByIndex(2);
32
+ await pillC.click();
33
+ // C is gone, so the remaining pills are A, B, D, E, F, G -> D is now at index 2.
34
+ const pillD = await DSPillsV2CO.getCloseButtonByIndex(2);
35
+ const typographys = (await useFocusStackCO.getTypographys()).length;
36
+ // removed C does not linger; the stack reads [B, A] -> 1 (h3) + 2
37
+ await expect(typographys).toEqual(3);
38
+ await expect(pillD).toBeFocused();
39
+ });
40
+
41
+ it('03: should Tab forward to E, remove it, and return focus to D', async () => {
42
+ await tabStops(1);
43
+ const pillE = await DSPillsV2CO.getCloseButtonByIndex(3);
44
+ await expect(pillE).toBeFocused();
45
+ // remove the focused pill with the keyboard
46
+ await browser.keys(Key.Return);
47
+ // E removed, remaining pills are A, B, D, F, G -> D is at index 2
48
+ const pillD = await DSPillsV2CO.getCloseButtonByIndex(2);
49
+ const typographys = (await useFocusStackCO.getTypographys()).length;
50
+ await expect(typographys).toEqual(3);
51
+ await expect(pillD).toBeFocused();
52
+ });
53
+
54
+ it('04: should delete back through the stack until focus falls back to Reset', async () => {
55
+ // remove D (focused) -> B, remove B -> A, remove A -> no survivor left -> fallBackRef (Reset)
56
+ await browser.keys(Key.Return);
57
+ await browser.keys(Key.Return);
58
+ await browser.keys(Key.Return);
59
+ const reset = await DSButtonV3CO.getButtonByIndex(0);
60
+ const typographys = (await useFocusStackCO.getTypographys()).length;
61
+ // stack emptied -> only the h3 remains
62
+ await expect(typographys).toEqual(1);
63
+ await expect(reset).toBeFocused();
64
+ });
65
+
66
+ it('05: should click Reset and restore all removable pills', async () => {
67
+ await browser.keys(Key.Return);
68
+ const closeButtons = await DSPillsV2CO.getCloseButtons();
69
+ const typographys = (await useFocusStackCO.getTypographys()).length;
70
+ await expect(closeButtons).toHaveLength(7);
71
+ await expect(typographys).toEqual(1);
72
+ });
73
+ it('06: should mouse-remove E with an empty stack and fall back focus to Reset', async () => {
74
+ const pillE = await DSPillsV2CO.getCloseButtonByIndex(4);
75
+ await pillE.click();
76
+ const reset = await DSButtonV3CO.getButtonByIndex(0);
77
+ await expect(reset).toBeFocused();
78
+ // E is hidden, so 6 removable pills remain.
79
+ const closeButtons = await DSPillsV2CO.getCloseButtons();
80
+ await expect(closeButtons).toHaveLength(6);
81
+ });
82
+ });
83
+ }
@@ -42,6 +42,8 @@ export default class DSShuttleV2CO extends PageObject {
42
42
 
43
43
  static basicURL = new Urlbuilder(PATH_E2E_SHUTTLE_V2, 'basic-test');
44
44
 
45
+ static breadcrumbAccessibleURL = new Urlbuilder(PATH_E2E_SHUTTLE_V2, 'breadcrumb-accessible-test');
46
+
45
47
  static adHocRenderAfterBulkMove = new Urlbuilder(PATH_E2E_SHUTTLE_V2, 'ad-hoc-render-after-bulk-move');
46
48
 
47
49
  static ariaPropsUrl = new Urlbuilder(PATH_E2E_SHUTTLE_V2, 'aria-props-test');
@@ -192,6 +194,8 @@ export default class DSShuttleV2CO extends PageObject {
192
194
 
193
195
  static getBreadcrumbs = async () => $$(`[data-testid="ds-breadcrumb-link"]`);
194
196
 
197
+ static getActiveBreadcrumb = async () => $(`[data-testid="ds-breadcrumb-link"][aria-current="step"]`);
198
+
195
199
  static getSubtitleByItem = async (item) => item.$$(`p`)[1];
196
200
 
197
201
  static getActionButtonByItemAndIndex = async (item, index = 0) =>
@@ -0,0 +1,43 @@
1
+ import DSShuttleV2CO from '../DSShuttleV2CO';
2
+
3
+ // Tests for the fix introduced in PUI-17395 (ShuttleV2 breadcrumb a11y):
4
+ // every step renders as a focusable <button> and the active/current step exposes
5
+ // aria-current="step". DOM-attribute assertions are browser-agnostic, so this runs Chrome-only.
6
+ if (
7
+ (!browser.capabilities['ice:options'].isPhone &&
8
+ !browser.capabilities['ice:options'].isTablet &&
9
+ browser.capabilities.browserName === 'chrome') ||
10
+ browser.capabilities.browserName === 'Chrome'
11
+ ) {
12
+ describe('PUI-18762 - DSShuttleV2:: breadcrumb active step aria-current -Func', () => {
13
+ before(async () => {
14
+ const errorOnGo = await DSShuttleV2CO.breadcrumbAccessibleURL.go();
15
+ if (errorOnGo) throw errorOnGo;
16
+ });
17
+
18
+ it('01: active step exposes aria-current="step" and every step is a focusable button', async () => {
19
+ // Drill down two levels so the breadcrumb has multiple steps (ancestors + current)
20
+ const rootItem = await DSShuttleV2CO.getItemFromSourceByIndex(1);
21
+ await (await DSShuttleV2CO.getActionButtonByItemAndIndex(rootItem, 0)).click();
22
+ const subItem = await DSShuttleV2CO.getItemFromSourceByIndex(2);
23
+ await (await DSShuttleV2CO.getActionButtonByItemAndIndex(subItem, 0)).click();
24
+
25
+ // Gather elements/values
26
+ const crumbs = await DSShuttleV2CO.getBreadcrumbs();
27
+ const activeCrumb = await DSShuttleV2CO.getActiveBreadcrumb();
28
+ const activeCrumbTag = await activeCrumb.getTagName();
29
+ const firstCrumb = crumbs[0];
30
+ const firstCrumbTag = await firstCrumb.getTagName();
31
+
32
+ // Assertions
33
+ await expect(crumbs.length).toBeGreaterThan(1);
34
+ // The current/active step (last) is announced as the current step
35
+ await expect(activeCrumb).toBeExisting();
36
+ await expect(activeCrumb).toHaveAttribute('aria-current', 'step');
37
+ await expect(activeCrumbTag).toBe('button');
38
+ // Non-active ancestor steps are buttons without aria-current
39
+ await expect(firstCrumbTag).toBe('button');
40
+ await expect(firstCrumb).not.toHaveAttribute('aria-current');
41
+ });
42
+ });
43
+ }
@@ -74,11 +74,13 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
74
74
  it('01: should not move the item when the disabled move action button is clicked', async () => {
75
75
  const testItem = await DSShuttleV2CO.getItemWrapper(1);
76
76
  const testItemMoveBtn = await DSShuttleV2CO.getActionButtonByItemAndIndex(testItem, 1);
77
- const testItemMoveBtnDisabled = await testItemMoveBtn.getAttribute('aria-disabled');
78
77
  const testItemText = await testItem.getText();
79
78
  await testItemMoveBtn.click();
80
79
  await expect(testItemText).toBe('Source 0.1');
81
- await expect(testItemMoveBtnDisabled).toBe('true');
80
+ // PUI-17909: a natively disabled DSButton emits the native `disabled` attribute and
81
+ // intentionally omits aria-disabled (that is reserved for applyAriaDisabled). Assert the
82
+ // native disabled state instead of the now-absent aria-disabled.
83
+ await expect(testItemMoveBtn).toBeDisabled();
82
84
  });
83
85
  it('02: should not display the BAB when a disabled item is clicked', async () => {
84
86
  const testItem = await DSShuttleV2CO.getItemWrapper(1);