dimsum-e2e-tests 3.60.0-next.42 → 3.60.0-next.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/ds-apppicker/basic/DSAppPicker.basic.func.spec.js +2 -2
  3. package/ds-data-table-async/DSDataTableCO.js +2 -0
  4. package/ds-data-table-async/components/FiltersCO.js +2 -0
  5. package/ds-data-table-async/filters/DSDataTable.custom-filtered-columns-focus.func.spec.js +61 -0
  6. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-creatable.func.spec.js +38 -19
  7. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-creatablemultiselect.keyboard.func.spec.js +72 -0
  8. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-creatableselect.keyboard.func.spec.js +72 -0
  9. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-currencyrange.keyboard.func.spec.js +82 -0
  10. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-daterange.keyboard.func.spec.js +193 -0
  11. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-dateswitcher.keyboard.func.spec.js +376 -0
  12. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-freetextsearch.keyboard.func.spec.js +72 -0
  13. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-multiselect.keyboard.func.spec.js +72 -0
  14. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-numberrange.keyboard.func.spec.js +84 -0
  15. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-singledate.keyboard.func.spec.js +160 -0
  16. package/ds-data-table-async/filtersV2/DSDataTable.filtersV2-singleselect.keyboard.func.spec.js +72 -0
  17. package/ds-global-header/GlobalHeaderCO.js +1 -1
  18. package/ds-menu-button/activable/DSMenuButton.axe-core.activable.func.spec.js +2 -1
  19. package/ds-menu-button/basic/DSMenuButton.axe-core.basic.func.spec.js +2 -1
  20. package/ds-menu-button/disabled/DSMenuButton.axe-core.disabled.func.spec.js +2 -1
  21. package/ds-menu-button/group/DSMenuButton.axe-core.groupMenuItem.func.spec.js +2 -1
  22. package/ds-menu-button/leftdecorations/DSMenuButton.axe-core.leftDecor.func.spec.js +2 -1
  23. package/ds-menu-button/multiselect/DSMenuButton.axe-core.multiselect.func.spec.js +6 -3
  24. package/ds-menu-button/singleSelect/DSMenuButton.axe-core.singleSelect.func.spec.js +8 -3
  25. package/ds-menu-button/skeleton/DSMenuButton.axe-core.skeletonMenuItem.func.spec.js +2 -1
  26. package/ds-menu-button/submenu/DSMenuButton.axe-core.subMenu.func.spec.js +2 -1
  27. package/ds-tabs/with-carousel/DSTabs.with-carousel.func.spec.js +21 -9
  28. package/package.json +151 -151
package/CHANGELOG.md CHANGED
@@ -3,6 +3,18 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 3.60.0-next.44 (2026-03-26)
7
+
8
+ ### Features
9
+
10
+ - ds-data-table:: add keyboard nav tests for all Filters V2 types [PUI-18206](https://jira.elliemae.io/browse/PUI-18206) ([#7950](https://git.elliemae.io/platform-ui/dimsum/issues/7950)) ([e54baa1](https://git.elliemae.io/platform-ui/dimsum/commit/e54baa104db1f46a832977b7eecc6332822c855f))
11
+
12
+ ## 3.60.0-next.43 (2026-03-20)
13
+
14
+ ### Features
15
+
16
+ - ds-read-more:: aria expanded and fixes for safari [PUI-17191](https://jira.elliemae.io/browse/PUI-17191) ([#7947](https://git.elliemae.io/platform-ui/dimsum/issues/7947)) ([f07f003](https://git.elliemae.io/platform-ui/dimsum/commit/f07f003994489f3747b07311a0be004927913e42))
17
+
6
18
  ## 3.60.0-next.42 (2026-03-19)
7
19
 
8
20
  ### Bug Fixes
@@ -34,8 +34,8 @@ if (
34
34
  const appPicker = await DSAppPickerCO.getAppPickerRoot();
35
35
  await expect(appPicker).toBeDisplayedInViewport();
36
36
  });
37
- it('05: should focus the sixth element when clicking it', async () => {
38
- const appPickerChip = await DSAppPickerCO.getChipByIndex(5);
37
+ it('05: should focus the seventh element when clicking it', async () => {
38
+ const appPickerChip = await DSAppPickerCO.getChipByIndex(6);
39
39
  await appPickerChip.click();
40
40
  await expect(appPickerChip).toBeFocused();
41
41
  });
@@ -85,6 +85,8 @@ export default class DataTableCO extends PageObject {
85
85
  'filtered-creatable-using-disable-focus-on-first-option-on-type-test',
86
86
  );
87
87
 
88
+ static customFilteredColumns = new Urlbuilder(PATH_E2E_DATATABLE_FILTERS, 'custom-filtered-columns');
89
+
88
90
  static filterEmpty = new Urlbuilder(PATH_E2E_DATATABLE_FILTERS, 'filter-empty-test');
89
91
 
90
92
  static filteredColumnWithComboboxFilterTest = new Urlbuilder(
@@ -153,6 +153,8 @@ export default class FiltersCO extends PageObject {
153
153
 
154
154
  static getFilterMenuContent = async () => $('[data-testid="data-table-filter-menu-content"]');
155
155
 
156
+ static getCustomTextFilterInput = async () => (await this.getFilterMenuContent()).$('input');
157
+
156
158
  // Calendar navigation buttons (shared across Single Date, Date Range, Date Switcher)
157
159
 
158
160
  static getCalendarPrevYearButton = async () => $('[data-testid="ds-controlled-date-time-picker-calendar-prev-year"]');
@@ -0,0 +1,61 @@
1
+ /* eslint-disable max-statements */
2
+ /* eslint-env mocha */
3
+ import { Key } from 'webdriverio';
4
+ import DSDataTableCO from '../DSDataTableCO';
5
+ import { FiltersCO, HeaderCO } from '../components';
6
+
7
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
8
+ describe('PUI-18226 - DataTable:: Custom Filtered Columns dialog focus - Func', () => {
9
+ beforeEach('loading page', async () => {
10
+ const errorOnGo = await DSDataTableCO.customFilteredColumns.go();
11
+ if (errorOnGo) throw errorOnGo;
12
+ await DSDataTableCO.waitForDataTable();
13
+ });
14
+
15
+ afterEach('close filter', async () => {
16
+ await browser.refresh();
17
+ });
18
+
19
+ it('01: should move focus to the input inside the dialog when the filter is opened', async () => {
20
+ // PUI-17321: verify that opening the Custom Filtered Columns dialog moves focus to its first focusable element
21
+ await FiltersCO.openFilterPopperByColumnName('Name');
22
+ const filterMenuContent = await FiltersCO.getFilterMenuContent();
23
+ await filterMenuContent.waitForDisplayed();
24
+ const customInput = await FiltersCO.getCustomTextFilterInput();
25
+ await expect(customInput).toBeFocused();
26
+ });
27
+
28
+ it('02: should keep focus inside the dialog when pressing Tab', async () => {
29
+ await FiltersCO.openFilterPopperByColumnName('Name');
30
+ const filterMenuContent = await FiltersCO.getFilterMenuContent();
31
+ await filterMenuContent.waitForDisplayed();
32
+ await browser.keys(Key.Tab);
33
+ const isInsideDialog = await filterMenuContent.isExisting();
34
+ await expect(isInsideDialog).toBe(true);
35
+ // Focus should remain within the filter dialog, not escape to elements behind
36
+ const customInput = await FiltersCO.getCustomTextFilterInput();
37
+ await expect(customInput).toBeFocused();
38
+ });
39
+
40
+ it('03: should keep focus inside the dialog when pressing Shift+Tab', async () => {
41
+ await FiltersCO.openFilterPopperByColumnName('Name');
42
+ const filterMenuContent = await FiltersCO.getFilterMenuContent();
43
+ await filterMenuContent.waitForDisplayed();
44
+ const customInput = await FiltersCO.getCustomTextFilterInput();
45
+ await expect(customInput).toBeFocused();
46
+ await browser.keys([Key.Shift, Key.Tab]);
47
+ // Focus should wrap within the dialog, not escape
48
+ await expect(customInput).toBeFocused();
49
+ });
50
+
51
+ it('04: should return focus to the filter button when closing the dialog with Escape', async () => {
52
+ await FiltersCO.openFilterPopperByColumnName('Name');
53
+ const filterMenuContent = await FiltersCO.getFilterMenuContent();
54
+ await filterMenuContent.waitForDisplayed();
55
+ await expect(filterMenuContent).toBeDisplayed();
56
+ await browser.keys(Key.Escape);
57
+ const filterBtn = await HeaderCO.getFilterBtnByIndex(0);
58
+ await expect(filterBtn).toBeFocused();
59
+ });
60
+ });
61
+ }
@@ -1,13 +1,13 @@
1
- /* eslint-disable wdio/no-pause */
1
+ /* eslint-env mocha */
2
+ import { Key } from 'webdriverio';
2
3
  import DSDataTableCO from '../DSDataTableCO';
3
- import { FilterBarCO, FiltersCO } from '../components';
4
+ import { FilterBarCO, FiltersCO, RowCO } from '../components';
5
+ import { type } from '../../helpers';
4
6
 
5
7
  if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
6
8
  // ── Creatable Select V2 ──
7
- // SKIPPED: PUI-18111 - Enter on a newly created option applies the filter bypassing the Apply button flow.
8
- // Tab from the auto-focused created option loses focus and clears the option. Pending component fix.
9
9
 
10
- describe.skip('PUI-18109 - DataTable:: Filters V2 - Creatable Select - Func', () => {
10
+ describe('PUI-18109 - DataTable:: Filters V2 - Creatable Select - Func', () => {
11
11
  before(async () => {
12
12
  const errorOnGo = await DSDataTableCO.creatableSelectFilterV2.go();
13
13
  if (errorOnGo) throw errorOnGo;
@@ -18,20 +18,30 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
18
18
  await FiltersCO.openFilterPopperByColumnName('Name');
19
19
  const footer = await FiltersCO.getFilterFooter();
20
20
  await expect(footer).toBeDisplayed();
21
+ const applyBtn = await FiltersCO.getFilterApplyButton();
22
+ await expect(applyBtn).toBeDisplayed();
23
+ const resetBtn = await FiltersCO.getFilterResetButton();
24
+ await expect(resetBtn).toBeDisplayed();
21
25
  });
22
26
 
23
- it('02: should type a custom value and apply creatable select filter', async () => {
24
- const input = await FiltersCO.getFilterSingleSelectInput();
25
- await input.setValue('CustomValue');
26
- await browser.keys('Enter');
27
- await browser.pause(500);
27
+ it('02: should type a custom value, select created option and apply filter', async () => {
28
+ await type('CustomValue');
29
+ await browser.keys(Key.ArrowDown);
30
+ await browser.keys(Key.Enter);
28
31
  const applyBtn = await FiltersCO.getFilterApplyButton();
29
32
  await applyBtn.click();
30
33
  const pills = await FilterBarCO.getAllPills();
31
34
  await expect(pills.length).toBeGreaterThan(0);
32
35
  });
33
36
 
34
- it('03: should clear creatable select filter after Reset', async () => {
37
+ it('03: should filter data after applying creatable select', async () => {
38
+ const results = await RowCO.getRows();
39
+ const filteredNames = await DSDataTableCO.getAllColumnResults(results, 1);
40
+ const firstPillText = await (await FilterBarCO.getPillByIndex(1)).getText();
41
+ await expect(filteredNames.every((name) => name === firstPillText)).toBeTruthy();
42
+ });
43
+
44
+ it('04: should clear creatable select filter after Reset', async () => {
35
45
  await FiltersCO.openFilterPopperByColumnName('Name');
36
46
  const resetBtn = await FiltersCO.getFilterResetButton();
37
47
  await resetBtn.click();
@@ -41,9 +51,8 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
41
51
  });
42
52
 
43
53
  // ── Creatable Multi Select V2 ──
44
- // SKIPPED: PUI-XXXXX - Same creatable option defect affects multi select. Pending component fix.
45
54
 
46
- describe.skip('PUI-18110 - DataTable:: Filters V2 - Creatable Multi Select - Func', () => {
55
+ describe('PUI-18110 - DataTable:: Filters V2 - Creatable Multi Select - Func', () => {
47
56
  before(async () => {
48
57
  const errorOnGo = await DSDataTableCO.creatableMultiSelectFilterV2.go();
49
58
  if (errorOnGo) throw errorOnGo;
@@ -54,20 +63,30 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
54
63
  await FiltersCO.openFilterPopperByColumnName('Position');
55
64
  const footer = await FiltersCO.getFilterFooter();
56
65
  await expect(footer).toBeDisplayed();
66
+ const applyBtn = await FiltersCO.getFilterApplyButton();
67
+ await expect(applyBtn).toBeDisplayed();
68
+ const resetBtn = await FiltersCO.getFilterResetButton();
69
+ await expect(resetBtn).toBeDisplayed();
57
70
  });
58
71
 
59
- it('02: should type a custom value and apply creatable multi select filter', async () => {
60
- const input = await FiltersCO.getFilterMultiSelectInput();
61
- await input.setValue('CustomPosition');
62
- await browser.keys('Enter');
63
- await browser.pause(500);
72
+ it('02: should type a custom value, select created option and apply filter', async () => {
73
+ await type('CustomPosition');
74
+ await browser.keys(Key.ArrowDown);
75
+ await browser.keys(Key.Enter);
64
76
  const applyBtn = await FiltersCO.getFilterApplyButton();
65
77
  await applyBtn.click();
66
78
  const pills = await FilterBarCO.getAllPills();
67
79
  await expect(pills.length).toBeGreaterThan(0);
68
80
  });
69
81
 
70
- it('03: should clear creatable multi select filter after Reset', async () => {
82
+ it('03: should filter data after applying creatable multi select', async () => {
83
+ const results = await RowCO.getRows();
84
+ const filteredPositions = await DSDataTableCO.getAllColumnResults(results, 1);
85
+ const firstPillText = await (await FilterBarCO.getPillByIndex(1)).getText();
86
+ await expect(filteredPositions.every((pos) => pos === firstPillText)).toBeTruthy();
87
+ });
88
+
89
+ it('04: should clear creatable multi select filter after Reset', async () => {
71
90
  await FiltersCO.openFilterPopperByColumnName('Position');
72
91
  const resetBtn = await FiltersCO.getFilterResetButton();
73
92
  await resetBtn.click();
@@ -0,0 +1,72 @@
1
+ /* eslint-env mocha */
2
+ import { Key } from 'webdriverio';
3
+ import DSDataTableCO from '../DSDataTableCO';
4
+ import { FiltersCO } from '../components';
5
+
6
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
7
+ // Forward keyboard navigation
8
+ describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Multi Select, forward keyboard navigation', () => {
9
+ before('loading page', async () => {
10
+ const errorOnGo = await DSDataTableCO.creatableMultiSelectFilterV2.go();
11
+ if (errorOnGo) throw errorOnGo;
12
+ await DSDataTableCO.waitForDataTable();
13
+ });
14
+
15
+ it('01: should open the Creatable Multi Select V2 filter and focus input', async () => {
16
+ await FiltersCO.openFilterPopperByColumnName('Position');
17
+ const input = await FiltersCO.getFilterMultiSelectInput();
18
+ await expect(input).toBeFocused();
19
+ });
20
+
21
+ it('02: Tab → Reset button', async () => {
22
+ await browser.keys(Key.Tab);
23
+ const resetBtn = await FiltersCO.getFilterResetButton();
24
+ await expect(resetBtn).toBeFocused();
25
+ });
26
+
27
+ it('03: Tab → Apply button', async () => {
28
+ await browser.keys(Key.Tab);
29
+ const applyBtn = await FiltersCO.getFilterApplyButton();
30
+ await expect(applyBtn).toBeFocused();
31
+ });
32
+
33
+ it('04: Tab → wraps back to input', async () => {
34
+ await browser.keys(Key.Tab);
35
+ const input = await FiltersCO.getFilterMultiSelectInput();
36
+ await expect(input).toBeFocused();
37
+ });
38
+ });
39
+
40
+ // Backward keyboard navigation
41
+ describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Multi Select, backward keyboard navigation', () => {
42
+ before('loading page', async () => {
43
+ const errorOnGo = await DSDataTableCO.creatableMultiSelectFilterV2.go();
44
+ if (errorOnGo) throw errorOnGo;
45
+ await DSDataTableCO.waitForDataTable();
46
+ });
47
+
48
+ it('01: should open the Creatable Multi Select V2 filter and focus input', async () => {
49
+ await FiltersCO.openFilterPopperByColumnName('Position');
50
+ const input = await FiltersCO.getFilterMultiSelectInput();
51
+ await expect(input).toBeFocused();
52
+ });
53
+
54
+ it('02: Shift+Tab → Apply button', async () => {
55
+ await browser.keys([Key.Shift, Key.Tab]);
56
+ const applyBtn = await FiltersCO.getFilterApplyButton();
57
+ await expect(applyBtn).toBeFocused();
58
+ });
59
+
60
+ it('03: Shift+Tab → Reset button', async () => {
61
+ await browser.keys([Key.Shift, Key.Tab]);
62
+ const resetBtn = await FiltersCO.getFilterResetButton();
63
+ await expect(resetBtn).toBeFocused();
64
+ });
65
+
66
+ it('04: Shift+Tab → wraps back to input', async () => {
67
+ await browser.keys([Key.Shift, Key.Tab]);
68
+ const input = await FiltersCO.getFilterMultiSelectInput();
69
+ await expect(input).toBeFocused();
70
+ });
71
+ });
72
+ }
@@ -0,0 +1,72 @@
1
+ /* eslint-env mocha */
2
+ import { Key } from 'webdriverio';
3
+ import DSDataTableCO from '../DSDataTableCO';
4
+ import { FiltersCO } from '../components';
5
+
6
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
7
+ // Forward keyboard navigation
8
+ describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Select, forward keyboard navigation', () => {
9
+ before('loading page', async () => {
10
+ const errorOnGo = await DSDataTableCO.creatableSelectFilterV2.go();
11
+ if (errorOnGo) throw errorOnGo;
12
+ await DSDataTableCO.waitForDataTable();
13
+ });
14
+
15
+ it('01: should open the Creatable Select V2 filter and focus input', async () => {
16
+ await FiltersCO.openFilterPopperByColumnName('Name');
17
+ const input = await FiltersCO.getFilterSingleSelectInput();
18
+ await expect(input).toBeFocused();
19
+ });
20
+
21
+ it('02: Tab → Reset button', async () => {
22
+ await browser.keys(Key.Tab);
23
+ const resetBtn = await FiltersCO.getFilterResetButton();
24
+ await expect(resetBtn).toBeFocused();
25
+ });
26
+
27
+ it('03: Tab → Apply button', async () => {
28
+ await browser.keys(Key.Tab);
29
+ const applyBtn = await FiltersCO.getFilterApplyButton();
30
+ await expect(applyBtn).toBeFocused();
31
+ });
32
+
33
+ it('04: Tab → wraps back to input', async () => {
34
+ await browser.keys(Key.Tab);
35
+ const input = await FiltersCO.getFilterSingleSelectInput();
36
+ await expect(input).toBeFocused();
37
+ });
38
+ });
39
+
40
+ // Backward keyboard navigation
41
+ describe('PUI-XXXXX - DataTable:: Filters V2 - Creatable Select, backward keyboard navigation', () => {
42
+ before('loading page', async () => {
43
+ const errorOnGo = await DSDataTableCO.creatableSelectFilterV2.go();
44
+ if (errorOnGo) throw errorOnGo;
45
+ await DSDataTableCO.waitForDataTable();
46
+ });
47
+
48
+ it('01: should open the Creatable Select V2 filter and focus input', async () => {
49
+ await FiltersCO.openFilterPopperByColumnName('Name');
50
+ const input = await FiltersCO.getFilterSingleSelectInput();
51
+ await expect(input).toBeFocused();
52
+ });
53
+
54
+ it('02: Shift+Tab → Apply button', async () => {
55
+ await browser.keys([Key.Shift, Key.Tab]);
56
+ const applyBtn = await FiltersCO.getFilterApplyButton();
57
+ await expect(applyBtn).toBeFocused();
58
+ });
59
+
60
+ it('03: Shift+Tab → Reset button', async () => {
61
+ await browser.keys([Key.Shift, Key.Tab]);
62
+ const resetBtn = await FiltersCO.getFilterResetButton();
63
+ await expect(resetBtn).toBeFocused();
64
+ });
65
+
66
+ it('04: Shift+Tab → wraps back to input', async () => {
67
+ await browser.keys([Key.Shift, Key.Tab]);
68
+ const input = await FiltersCO.getFilterSingleSelectInput();
69
+ await expect(input).toBeFocused();
70
+ });
71
+ });
72
+ }
@@ -0,0 +1,82 @@
1
+ /* eslint-env mocha */
2
+ import { Key } from 'webdriverio';
3
+ import DSDataTableCO from '../DSDataTableCO';
4
+ import { FiltersCO, FiltersCOextra } from '../components';
5
+
6
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
7
+ // Forward keyboard navigation
8
+ describe('PUI-18199 - DataTable:: Filters V2 - Currency Range, forward keyboard navigation', () => {
9
+ before('loading page', async () => {
10
+ const errorOnGo = await DSDataTableCO.currencyRangeFilterV2.go();
11
+ if (errorOnGo) throw errorOnGo;
12
+ await DSDataTableCO.waitForDataTable();
13
+ });
14
+
15
+ it('01: should open the Currency Range V2 filter and focus min input', async () => {
16
+ await FiltersCO.openFilterPopperByColumnName('Salary');
17
+ const minInput = await FiltersCOextra.filterCurrencyLeftInput();
18
+ await expect(minInput).toBeFocused();
19
+ });
20
+
21
+ it('02: Tab → max input', async () => {
22
+ await browser.keys(Key.Tab);
23
+ const maxInput = await FiltersCOextra.filterCurrencyRightInput();
24
+ await expect(maxInput).toBeFocused();
25
+ });
26
+ it('03: Tab → Reset button', async () => {
27
+ await browser.keys(Key.Tab);
28
+ const resetBtn = await FiltersCO.getFilterResetButton();
29
+ await expect(resetBtn).toBeFocused();
30
+ });
31
+ it('04: Tab → Apply button', async () => {
32
+ await browser.keys(Key.Tab);
33
+ const applyBtn = await FiltersCO.getFilterApplyButton();
34
+ await expect(applyBtn).toBeFocused();
35
+ });
36
+
37
+ it('05: Tab → wraps back to min input', async () => {
38
+ await browser.keys(Key.Tab);
39
+ const minInput = await FiltersCOextra.filterCurrencyLeftInput();
40
+ await expect(minInput).toBeFocused();
41
+ });
42
+ });
43
+
44
+ // Backward keyboard navigation
45
+ describe('PUI-18200 - DataTable:: Filters V2 - Currency Range, backward keyboard navigation', () => {
46
+ before('loading page', async () => {
47
+ const errorOnGo = await DSDataTableCO.currencyRangeFilterV2.go();
48
+ if (errorOnGo) throw errorOnGo;
49
+ await DSDataTableCO.waitForDataTable();
50
+ });
51
+
52
+ it('01: should open the Currency Range V2 filter and focus min input', async () => {
53
+ await FiltersCO.openFilterPopperByColumnName('Salary');
54
+ const minInput = await FiltersCOextra.filterCurrencyLeftInput();
55
+ await expect(minInput).toBeFocused();
56
+ });
57
+
58
+ it('02: Shift+Tab → Apply button', async () => {
59
+ await browser.keys([Key.Shift, Key.Tab]);
60
+ const applyBtn = await FiltersCO.getFilterApplyButton();
61
+ await expect(applyBtn).toBeFocused();
62
+ });
63
+
64
+ it('03: Shift+Tab → Reset button', async () => {
65
+ await browser.keys([Key.Shift, Key.Tab]);
66
+ const resetBtn = await FiltersCO.getFilterResetButton();
67
+ await expect(resetBtn).toBeFocused();
68
+ });
69
+
70
+ it('04: Shift+Tab → max input', async () => {
71
+ await browser.keys([Key.Shift, Key.Tab]);
72
+ const maxInput = await FiltersCOextra.filterCurrencyRightInput();
73
+ await expect(maxInput).toBeFocused();
74
+ });
75
+
76
+ it('05: Shift+Tab → wraps back to min input', async () => {
77
+ await browser.keys([Key.Shift, Key.Tab]);
78
+ const minInput = await FiltersCOextra.filterCurrencyLeftInput();
79
+ await expect(minInput).toBeFocused();
80
+ });
81
+ });
82
+ }
@@ -0,0 +1,193 @@
1
+ /* eslint-env mocha */
2
+ import { Key } from 'webdriverio';
3
+ import DSDataTableCO from '../DSDataTableCO';
4
+ import { FiltersCO } from '../components';
5
+
6
+ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
7
+ // Forward keyboard navigation
8
+ describe('PUI-18197 - DataTable:: Filters V2 - Date Range, forward keyboard navigation', () => {
9
+ before('loading page', async () => {
10
+ const errorOnGo = await DSDataTableCO.dateRangeFilterV2.go();
11
+ if (errorOnGo) throw errorOnGo;
12
+ await DSDataTableCO.waitForDataTable();
13
+ });
14
+
15
+ it('01: should open the Date Range V2 filter and focus start MM input', async () => {
16
+ await FiltersCO.openFilterPopperByColumnName('Date range');
17
+ const startMM = await FiltersCO.filterDateRangePopper.getMonthInput(0);
18
+ await expect(startMM).toBeFocused();
19
+ });
20
+
21
+ it('02: Tab → start DD input', async () => {
22
+ await browser.keys(Key.Tab);
23
+ const startDD = await FiltersCO.filterDateRangePopper.getDayInput(0);
24
+ await expect(startDD).toBeFocused();
25
+ });
26
+
27
+ it('03: Tab → start YYYY input', async () => {
28
+ await browser.keys(Key.Tab);
29
+ const startYYYY = await FiltersCO.filterDateRangePopper.getYearInput(0);
30
+ await expect(startYYYY).toBeFocused();
31
+ });
32
+
33
+ it('04: Tab → end MM input', async () => {
34
+ await browser.keys(Key.Tab);
35
+ const endMM = await FiltersCO.filterDateRangePopper.getMonthInput(1);
36
+ await expect(endMM).toBeFocused();
37
+ });
38
+
39
+ it('05: Tab → end DD input', async () => {
40
+ await browser.keys(Key.Tab);
41
+ const endDD = await FiltersCO.filterDateRangePopper.getDayInput(1);
42
+ await expect(endDD).toBeFocused();
43
+ });
44
+
45
+ it('06: Tab → end YYYY input', async () => {
46
+ await browser.keys(Key.Tab);
47
+ const endYYYY = await FiltersCO.filterDateRangePopper.getYearInput(1);
48
+ await expect(endYYYY).toBeFocused();
49
+ });
50
+
51
+ // PUI-15014: current tab order is PrevMonth → NextMonth → PrevYear → NextYear
52
+ // Once PUI-15014 is fixed, update to: PrevYear → PrevMonth → NextMonth → NextYear
53
+ it('07: Tab → Prev Month button', async () => {
54
+ await browser.keys(Key.Tab);
55
+ const prevMonth = await FiltersCO.getCalendarPrevMonthButton();
56
+ await expect(prevMonth).toBeFocused();
57
+ });
58
+
59
+ it('08: Tab → Next Month button', async () => {
60
+ await browser.keys(Key.Tab);
61
+ const nextMonth = await FiltersCO.getCalendarNextMonthButton();
62
+ await expect(nextMonth).toBeFocused();
63
+ });
64
+
65
+ it('09: Tab → Prev Year button', async () => {
66
+ await browser.keys(Key.Tab);
67
+ const prevYear = await FiltersCO.getCalendarPrevYearButton();
68
+ await expect(prevYear).toBeFocused();
69
+ });
70
+
71
+ it('10: Tab → Next Year button', async () => {
72
+ await browser.keys(Key.Tab);
73
+ const nextYear = await FiltersCO.getCalendarNextYearButton();
74
+ await expect(nextYear).toBeFocused();
75
+ });
76
+
77
+ it('11: Tab → current day in calendar', async () => {
78
+ await browser.keys(Key.Tab);
79
+ const focusedDay = await FiltersCO.getCalendarFocusedDay();
80
+ await expect(focusedDay).toBeFocused();
81
+ });
82
+ it('12: Tab → Reset button', async () => {
83
+ await browser.keys(Key.Tab);
84
+ const resetBtn = await FiltersCO.getFilterResetButton();
85
+ await expect(resetBtn).toBeFocused();
86
+ });
87
+ it('13: Tab → Apply button', async () => {
88
+ await browser.keys(Key.Tab);
89
+ const applyBtn = await FiltersCO.getFilterApplyButton();
90
+ await expect(applyBtn).toBeFocused();
91
+ });
92
+ it('14: Tab → wraps back to start MM input', async () => {
93
+ await browser.keys(Key.Tab);
94
+ const startMM = await FiltersCO.filterDateRangePopper.getMonthInput(0);
95
+ await expect(startMM).toBeFocused();
96
+ });
97
+ });
98
+
99
+ // Backward keyboard navigation
100
+ describe('PUI-18198 - DataTable:: Filters V2 - Date Range, backward keyboard navigation', () => {
101
+ before('loading page', async () => {
102
+ const errorOnGo = await DSDataTableCO.dateRangeFilterV2.go();
103
+ if (errorOnGo) throw errorOnGo;
104
+ await DSDataTableCO.waitForDataTable();
105
+ });
106
+
107
+ it('01: should open the Date Range V2 filter and focus start MM input', async () => {
108
+ await FiltersCO.openFilterPopperByColumnName('Date range');
109
+ const startMM = await FiltersCO.filterDateRangePopper.getMonthInput(0);
110
+ await expect(startMM).toBeFocused();
111
+ });
112
+
113
+ it('02: Shift+Tab → Apply button', async () => {
114
+ await browser.keys([Key.Shift, Key.Tab]);
115
+ const applyBtn = await FiltersCO.getFilterApplyButton();
116
+ await expect(applyBtn).toBeFocused();
117
+ });
118
+
119
+ it('03: Shift+Tab → Reset button', async () => {
120
+ await browser.keys([Key.Shift, Key.Tab]);
121
+ const resetBtn = await FiltersCO.getFilterResetButton();
122
+ await expect(resetBtn).toBeFocused();
123
+ });
124
+
125
+ it('04: Shift+Tab → current day in calendar', async () => {
126
+ await browser.keys([Key.Shift, Key.Tab]);
127
+ const focusedDay = await FiltersCO.getCalendarFocusedDay();
128
+ await expect(focusedDay).toBeFocused();
129
+ });
130
+
131
+ // PUI-15014: current tab order is PrevMonth → NextMonth → PrevYear → NextYear
132
+ // Once PUI-15014 is fixed, update to: NextYear → NextMonth → PrevMonth → PrevYear
133
+ it('05: Shift+Tab → Next Year button', async () => {
134
+ await browser.keys([Key.Shift, Key.Tab]);
135
+ const nextYear = await FiltersCO.getCalendarNextYearButton();
136
+ await expect(nextYear).toBeFocused();
137
+ });
138
+
139
+ it('06: Shift+Tab → Prev Year button', async () => {
140
+ await browser.keys([Key.Shift, Key.Tab]);
141
+ const prevYear = await FiltersCO.getCalendarPrevYearButton();
142
+ await expect(prevYear).toBeFocused();
143
+ });
144
+
145
+ it('07: Shift+Tab → Next Month button', async () => {
146
+ await browser.keys([Key.Shift, Key.Tab]);
147
+ const nextMonth = await FiltersCO.getCalendarNextMonthButton();
148
+ await expect(nextMonth).toBeFocused();
149
+ });
150
+
151
+ it('08: Shift+Tab → Prev Month button', async () => {
152
+ await browser.keys([Key.Shift, Key.Tab]);
153
+ const prevMonth = await FiltersCO.getCalendarPrevMonthButton();
154
+ await expect(prevMonth).toBeFocused();
155
+ });
156
+
157
+ it('09: Shift+Tab → end YYYY input', async () => {
158
+ await browser.keys([Key.Shift, Key.Tab]);
159
+ const endYYYY = await FiltersCO.filterDateRangePopper.getYearInput(1);
160
+ await expect(endYYYY).toBeFocused();
161
+ });
162
+
163
+ it('10: Shift+Tab → end DD input', async () => {
164
+ await browser.keys([Key.Shift, Key.Tab]);
165
+ const endDD = await FiltersCO.filterDateRangePopper.getDayInput(1);
166
+ await expect(endDD).toBeFocused();
167
+ });
168
+
169
+ it('11: Shift+Tab → end MM input', async () => {
170
+ await browser.keys([Key.Shift, Key.Tab]);
171
+ const endMM = await FiltersCO.filterDateRangePopper.getMonthInput(1);
172
+ await expect(endMM).toBeFocused();
173
+ });
174
+
175
+ it('12: Shift+Tab → start YYYY input', async () => {
176
+ await browser.keys([Key.Shift, Key.Tab]);
177
+ const startYYYY = await FiltersCO.filterDateRangePopper.getYearInput(0);
178
+ await expect(startYYYY).toBeFocused();
179
+ });
180
+
181
+ it('13: Shift+Tab → start DD input', async () => {
182
+ await browser.keys([Key.Shift, Key.Tab]);
183
+ const startDD = await FiltersCO.filterDateRangePopper.getDayInput(0);
184
+ await expect(startDD).toBeFocused();
185
+ });
186
+
187
+ it('14: Shift+Tab → wraps back to start MM input', async () => {
188
+ await browser.keys([Key.Shift, Key.Tab]);
189
+ const startMM = await FiltersCO.filterDateRangePopper.getMonthInput(0);
190
+ await expect(startMM).toBeFocused();
191
+ });
192
+ });
193
+ }