dimsum-e2e-tests 3.70.0-next.60 → 3.70.0-next.62
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.
- package/CHANGELOG.md +12 -0
- package/ds-apppicker/DSAppPickerCO.js +72 -1
- package/ds-apppicker/aria-pattern/DSAppPicker.aria-pattern.func.spec.js +100 -0
- package/ds-apppicker/reflow/DSAppPicker.reflow.func.spec.js +32 -0
- package/ds-controlled-form/ds-controlled-checkbox/DSControlledCheckboxCO.js +40 -1
- package/ds-controlled-form/ds-controlled-checkbox/slots/DSControlledCheckbox.slots.func.spec.js +78 -0
- package/ds-controlled-form/ds-controlled-radio/DSControlledRadioCO.js +40 -1
- package/ds-controlled-form/ds-controlled-radio/slots/DSControlledRadio.slots.func.spec.js +78 -0
- package/ds-data-table-async/components/HeaderCO.js +8 -16
- package/ds-data-table-async/filters/DSDataTable.filters-creatable.func.spec.js +17 -1
- package/ds-data-table-async/resizable/DSDataTable.resizerA11y.axe-core.func.spec.js +9 -10
- package/ds-data-table-async/resizable/DSDataTable.resizerA11y.func.spec.js +19 -13
- package/ds-form-combobox-multi/DSComboboxMultiCO.js +16 -8
- package/ds-form-combobox-multi/disabled/DSComboboxMulti.disabled.mouse.func.spec.js +0 -2
- package/ds-form-combobox-multi/theme-font/DSComboboxMulti.theme-font.func.spec.js +38 -0
- package/ds-form-combobox-single/DSComboboxSingleCO.js +12 -8
- package/ds-form-combobox-single/disabled/DSComboboxSingle.disabled.mouse.func.spec.js +0 -2
- package/ds-form-combobox-single/theme-font/DSComboboxSingle.theme-font.func.spec.js +34 -0
- package/package.json +149 -149
- package/paths.js +2 -0
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.70.0-next.62 (2026-08-19)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- dimsum:: wire playwright test into the test script for ds-form-checkbox, ds-form-layout-autocomplete and ds-app-picker ([#8316](https://git.elliemae.io/platform-ui/dimsum/issues/8316)) ([c301b8c](https://git.elliemae.io/platform-ui/dimsum/commit/c301b8cb3c488d8a4a0da6d8514844b9eeef0119))
|
|
11
|
+
|
|
12
|
+
## 3.70.0-next.61 (2026-08-18)
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
- ds-data-table:: skip the PUI-18881 filter caret and selection e2e [PUI-18881](https://jira.elliemae.io/browse/PUI-18881) ([#8310](https://git.elliemae.io/platform-ui/dimsum/issues/8310)) ([80b0c0f](https://git.elliemae.io/platform-ui/dimsum/commit/80b0c0f7433a409ac6ef74b08535b678be817bf0)), closes [#8307](https://git.elliemae.io/platform-ui/dimsum/issues/8307)
|
|
17
|
+
|
|
6
18
|
## 3.70.0-next.60 (2026-08-13)
|
|
7
19
|
|
|
8
20
|
### Bug Fixes
|
|
@@ -24,8 +24,14 @@ export default class DSAppPickerCO extends PageObject {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// selectors
|
|
27
|
+
// Anchored on data-testid, NOT on the `#app-picker__button` id this used to select. The trigger's
|
|
28
|
+
// `id` is the per-instance dialog label id the dialog's aria-labelledby resolves to
|
|
29
|
+
// (`ds-app-picker-<uid>-dialog-trigger-btn`), deliberately uid-based so several pickers can
|
|
30
|
+
// coexist — documented under "Multiple pickers on one page" in the AccessibilityBehavior docs,
|
|
31
|
+
// which points automation at either a `data-testid` or an `id` prop passed to DSAppPicker.
|
|
32
|
+
// data-testid is the QA-stability-protected identifier, so it is the correct anchor here.
|
|
27
33
|
static async getOpenAppPicker() {
|
|
28
|
-
return $(
|
|
34
|
+
return $('[data-testid="app-picker__button"]');
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
static getChips = async () => $$('[data-testid="app-picker__chip"]');
|
|
@@ -51,6 +57,71 @@ export default class DSAppPickerCO extends PageObject {
|
|
|
51
57
|
return $('[data-testid="ds-apppicker-root"]');
|
|
52
58
|
}
|
|
53
59
|
|
|
60
|
+
// The floating layer that wraps the panel — carries role="dialog" + aria-labelledby. It sits two
|
|
61
|
+
// levels ABOVE the panel root and is portaled to document.body, so it is not reachable from the
|
|
62
|
+
// root selector.
|
|
63
|
+
static async getFloatingWrapper() {
|
|
64
|
+
return $('[data-testid="ds-apppicker-floating-wrapper"]');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// One per section (apps + customApps) — the ARIA group tying a section title to its chips.
|
|
68
|
+
static getGroups = async () => $$('[data-testid="ds-apppicker-group"]');
|
|
69
|
+
|
|
70
|
+
static getGroupByIndex = async (index) => getElementByIndex(this.getGroups, index);
|
|
71
|
+
|
|
72
|
+
static getTitles = async () => $$('[data-testid="ds-apppicker-title"]');
|
|
73
|
+
|
|
74
|
+
static getTitleByIndex = async (index) => getElementByIndex(this.getTitles, index);
|
|
75
|
+
|
|
76
|
+
// Full-width layout rows holding a section title or the separator — purely presentational.
|
|
77
|
+
static getRows = async () => $$('[data-testid="ds-apppicker-row"]');
|
|
78
|
+
|
|
79
|
+
static async openPanel() {
|
|
80
|
+
const trigger = await this.getOpenAppPicker();
|
|
81
|
+
await trigger.waitForDisplayed();
|
|
82
|
+
await trigger.click();
|
|
83
|
+
await (await this.getAppPickerRoot()).waitForDisplayed();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Reads one value per element in a wdio element array. Element arrays in wdio 9 expose their own
|
|
87
|
+
// promise-returning `map`, so `Promise.all(list.map(fn))` is handed a Promise rather than an
|
|
88
|
+
// iterable and throws. `length` + index access behave like a plain array in every version, so the
|
|
89
|
+
// iteration is built from those instead.
|
|
90
|
+
static async collect(elements, read) {
|
|
91
|
+
return Promise.all(Array.from({ length: elements.length }, (_, index) => read(elements[index])));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Measures every chip in the open panel and buckets them by vertical offset — one bucket per
|
|
95
|
+
// rendered grid row. Row membership is derived, not hardcoded: the 3-column grid reflows with
|
|
96
|
+
// viewport width and font size, so which chips share a row is a runtime fact.
|
|
97
|
+
static async getChipRowsGeometry() {
|
|
98
|
+
const chips = await this.getChips();
|
|
99
|
+
const measured = await DSAppPickerCO.collect(chips, async (chip) => {
|
|
100
|
+
const { y } = await chip.getLocation();
|
|
101
|
+
const { height } = await chip.getSize();
|
|
102
|
+
return { label: await chip.getAttribute('aria-label'), top: Math.round(y), height: Math.round(height) };
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const rowsByTop = measured.reduce((acc, chip) => {
|
|
106
|
+
acc[chip.top] = [...(acc[chip.top] ?? []), chip];
|
|
107
|
+
return acc;
|
|
108
|
+
}, {});
|
|
109
|
+
|
|
110
|
+
return Object.values(rowsByTop).map(DSAppPickerCO.summariseChipRow);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Reduces one measured row to the numbers a height assertion needs, plus a human-readable
|
|
114
|
+
// breakdown so a failure names the offending chips and their pixel heights.
|
|
115
|
+
static summariseChipRow(row) {
|
|
116
|
+
const heights = row.map((chip) => chip.height);
|
|
117
|
+
return {
|
|
118
|
+
chipCount: row.length,
|
|
119
|
+
tallest: Math.max(...heights),
|
|
120
|
+
shortest: Math.min(...heights),
|
|
121
|
+
breakdown: row.map((chip) => `${chip.label} (${chip.height}px)`).join(', '),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
54
125
|
static async getChipLabelByIndex(index) {
|
|
55
126
|
return $$('[data-testid="ds-chip-label"]')[index];
|
|
56
127
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import DSAppPickerCO from '../DSAppPickerCO';
|
|
2
|
+
|
|
3
|
+
// Tests for the fix introduced in PUI-17213 (Roles and Pattern Mismatch): the AppPicker was built
|
|
4
|
+
// as a menu but carried neither the menu nor the dialog ARIA contract. It is now a dialog —
|
|
5
|
+
// aria-haspopup="dialog" + no aria-expanded on the trigger, role="dialog" + aria-labelledby on the
|
|
6
|
+
// floating layer, one role="group" per section labelled by its <h3> title, presentational layout
|
|
7
|
+
// rows, and chips left with their native button semantics instead of role="option".
|
|
8
|
+
//
|
|
9
|
+
// Every id in this component is namespaced by a per-instance uid, so the assertions are relational
|
|
10
|
+
// (the dialog's aria-labelledby resolves to the trigger's id) rather than matching literal strings.
|
|
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
|
+
) {
|
|
17
|
+
describe('PUI-18911 - DSAppPicker:: dialog ARIA pattern roles and relationships - Func', () => {
|
|
18
|
+
before('loading page', async () => {
|
|
19
|
+
const errorOnGo = await DSAppPickerCO.basicURL.go();
|
|
20
|
+
if (errorOnGo) throw errorOnGo;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('01: should expose the closed trigger as a dialog popup button', async () => {
|
|
24
|
+
const trigger = await DSAppPickerCO.getOpenAppPicker();
|
|
25
|
+
await trigger.waitForDisplayed();
|
|
26
|
+
|
|
27
|
+
await expect(trigger).toHaveAttribute('aria-haspopup', 'dialog');
|
|
28
|
+
await expect(trigger).toHaveAttribute('aria-label', 'Application picker');
|
|
29
|
+
// aria-expanded belongs to disclosure patterns; on a dialog popup it produces a conflicting
|
|
30
|
+
// announcement, so it must be absent both closed and open (re-checked in 02).
|
|
31
|
+
await expect(await trigger.getAttribute('aria-expanded')).toBe(null);
|
|
32
|
+
await expect(await trigger.getAttribute('id')).not.toBe(null);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('02: should open a dialog whose accessible name comes from the trigger', async () => {
|
|
36
|
+
const trigger = await DSAppPickerCO.getOpenAppPicker();
|
|
37
|
+
await DSAppPickerCO.openPanel();
|
|
38
|
+
|
|
39
|
+
const dialog = await DSAppPickerCO.getFloatingWrapper();
|
|
40
|
+
await expect(dialog).toHaveAttribute('role', 'dialog');
|
|
41
|
+
// The dialog and the trigger share one accessible name: aria-labelledby points at the trigger.
|
|
42
|
+
await expect(await dialog.getAttribute('aria-labelledby')).toBe(await trigger.getAttribute('id'));
|
|
43
|
+
// The replaced aria-label="popup menu" must not have come back alongside aria-labelledby.
|
|
44
|
+
await expect(await dialog.getAttribute('aria-label')).toBe(null);
|
|
45
|
+
|
|
46
|
+
// The panel root is roleless (the former role="region" is gone), so it carries no name either.
|
|
47
|
+
const root = await DSAppPickerCO.getAppPickerRoot();
|
|
48
|
+
await expect(await root.getAttribute('role')).toBe(null);
|
|
49
|
+
await expect(await root.getAttribute('aria-label')).toBe(null);
|
|
50
|
+
|
|
51
|
+
await expect(await trigger.getAttribute('aria-expanded')).toBe(null);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('03: should group each section and label it with its own h3 heading', async () => {
|
|
55
|
+
const groups = await DSAppPickerCO.getGroups();
|
|
56
|
+
const titles = await DSAppPickerCO.getTitles();
|
|
57
|
+
// The story renders apps + customApps, so both sections are present.
|
|
58
|
+
await expect(groups.length).toBe(2);
|
|
59
|
+
await expect(titles.length).toBe(2);
|
|
60
|
+
|
|
61
|
+
const mainGroup = await DSAppPickerCO.getGroupByIndex(0);
|
|
62
|
+
const mainTitle = await DSAppPickerCO.getTitleByIndex(0);
|
|
63
|
+
await expect(mainGroup).toHaveAttribute('role', 'group');
|
|
64
|
+
await expect(await mainGroup.getAttribute('aria-labelledby')).toBe(await mainTitle.getAttribute('id'));
|
|
65
|
+
|
|
66
|
+
const customGroup = await DSAppPickerCO.getGroupByIndex(1);
|
|
67
|
+
const customTitle = await DSAppPickerCO.getTitleByIndex(1);
|
|
68
|
+
await expect(customGroup).toHaveAttribute('role', 'group');
|
|
69
|
+
await expect(await customGroup.getAttribute('aria-labelledby')).toBe(await customTitle.getAttribute('id'));
|
|
70
|
+
|
|
71
|
+
// The titles stay real headings: role="presentation" would hide them from screen reader
|
|
72
|
+
// heading navigation in browse mode.
|
|
73
|
+
await expect(await mainTitle.getTagName()).toBe('h3');
|
|
74
|
+
await expect(await customTitle.getTagName()).toBe('h3');
|
|
75
|
+
await expect(await mainTitle.getAttribute('role')).toBe(null);
|
|
76
|
+
await expect(await customTitle.getAttribute('role')).toBe(null);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('04: should keep layout rows presentational and chips as buttons', async () => {
|
|
80
|
+
// The full-row wrappers around the titles and the separator are layout only: role="group" was
|
|
81
|
+
// reserved for the real sections (03) and aria-hidden="true" would drop them from the tree
|
|
82
|
+
// instead of conveying them as presentation.
|
|
83
|
+
const rows = await DSAppPickerCO.getRows();
|
|
84
|
+
await expect(rows.length).toBeGreaterThan(0);
|
|
85
|
+
const rowRoles = await DSAppPickerCO.collect(rows, (row) => row.getAttribute('role'));
|
|
86
|
+
const rowAriaHidden = await DSAppPickerCO.collect(rows, (row) => row.getAttribute('aria-hidden'));
|
|
87
|
+
await expect(rowRoles.every((role) => role === null)).toBe(true);
|
|
88
|
+
await expect(rowAriaHidden.every((hidden) => hidden === null)).toBe(true);
|
|
89
|
+
|
|
90
|
+
// Chips keep their native button semantics inside the dialog — role="option" claimed a
|
|
91
|
+
// listbox parent that never existed.
|
|
92
|
+
const chips = await DSAppPickerCO.getChips();
|
|
93
|
+
await expect(chips.length).toBeGreaterThan(0);
|
|
94
|
+
const chipTags = await DSAppPickerCO.collect(chips, (chip) => chip.getTagName());
|
|
95
|
+
const chipRoles = await DSAppPickerCO.collect(chips, (chip) => chip.getAttribute('role'));
|
|
96
|
+
await expect(chipTags.every((tag) => tag === 'button')).toBe(true);
|
|
97
|
+
await expect(chipRoles.every((role) => role === 'button')).toBe(true);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import DSAppPickerCO from '../DSAppPickerCO';
|
|
2
|
+
|
|
3
|
+
// Tests for the fix introduced in PUI-17860 (chips don't keep a consistent height). The chip's own
|
|
4
|
+
// wrapper was not a flex container, so a stretched grid row handed no height down to the chip root:
|
|
5
|
+
// a single-line chip ("Pipeline") stayed short next to a chip whose label wrapped onto two lines.
|
|
6
|
+
//
|
|
7
|
+
// The assertion is relational — every chip in a row matches the tallest chip in that row — so it
|
|
8
|
+
// pins no pixel value and survives any typography or spacing token change. The Reflow story is the
|
|
9
|
+
// right surface: it raises the font size so labels genuinely wrap and rows genuinely stretch.
|
|
10
|
+
if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:options'].isTablet) {
|
|
11
|
+
describe('PUI-18912 - DSAppPicker:: chip height uniform within a grid row - Func', () => {
|
|
12
|
+
before('loading page', async () => {
|
|
13
|
+
const errorOnGo = await DSAppPickerCO.reflowURL.go();
|
|
14
|
+
if (errorOnGo) throw errorOnGo;
|
|
15
|
+
await browser.maximizeWindow();
|
|
16
|
+
await DSAppPickerCO.openPanel();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('01: should render every chip in a row at the height of that row tallest chip', async () => {
|
|
20
|
+
const rows = await DSAppPickerCO.getChipRowsGeometry();
|
|
21
|
+
await expect(rows.length).toBeGreaterThan(0);
|
|
22
|
+
|
|
23
|
+
// At least one row must hold more than one chip, otherwise the story no longer reproduces the
|
|
24
|
+
// uneven-height condition (a one-chip row is trivially uniform) and a pass would mean nothing.
|
|
25
|
+
const multiChipRows = rows.filter((row) => row.chipCount > 1);
|
|
26
|
+
await expect(multiChipRows.length).toBeGreaterThan(0);
|
|
27
|
+
|
|
28
|
+
const unevenRows = rows.filter((row) => row.tallest !== row.shortest);
|
|
29
|
+
await expect(unevenRows.map((row) => row.breakdown)).toEqual([]);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable import/no-relative-packages */
|
|
2
|
-
import { PATH_E2E_CHECKBOX } from '../../paths';
|
|
2
|
+
import { PATH_E2E_CHECKBOX, PATH_E2E_CHECKBOX_SLOTS } from '../../paths';
|
|
3
3
|
import { PageObject, Urlbuilder, getElementByIndex } from '../../helpers';
|
|
4
4
|
|
|
5
5
|
export default class DSControlledCheckboxCO extends PageObject {
|
|
@@ -25,6 +25,8 @@ export default class DSControlledCheckboxCO extends PageObject {
|
|
|
25
25
|
|
|
26
26
|
static themeFontURL = new Urlbuilder(PATH_E2E_CHECKBOX, 'theme-font-family-test');
|
|
27
27
|
|
|
28
|
+
static slotsTest = new Urlbuilder(PATH_E2E_CHECKBOX_SLOTS, 'slots-test');
|
|
29
|
+
|
|
28
30
|
static async getCheckbox() {
|
|
29
31
|
return $('[data-testid="ds-checkbox"]');
|
|
30
32
|
}
|
|
@@ -80,4 +82,41 @@ export default class DSControlledCheckboxCO extends PageObject {
|
|
|
80
82
|
static async getFallbackCheckboxLabel() {
|
|
81
83
|
return $('[data-testid="theme-font-fallback"] [data-testid="ds-checkbox-label-typography"]');
|
|
82
84
|
}
|
|
85
|
+
|
|
86
|
+
// Slots rendered through styled(DSTypography) expose the owner slot on
|
|
87
|
+
// `data-dimsum-parent-slot` (the element's own `data-dimsum-slot` is the typography root),
|
|
88
|
+
// while plain-tag slots expose it on `data-dimsum-slot`.
|
|
89
|
+
static async getSlotsRoot() {
|
|
90
|
+
return $('[data-testid="slots-wrapped"] [data-dimsum-slot="dsCheckboxRoot"]');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
static async getSlotsInputWrapper() {
|
|
94
|
+
return $('[data-testid="slots-wrapped"] [data-dimsum-slot="dsCheckboxInputWrapper"]');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static async getSlotsInput() {
|
|
98
|
+
return $('[data-testid="slots-wrapped"] [data-dimsum-slot="dsCheckboxInput"]');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static async getSlotsLabel() {
|
|
102
|
+
return $('[data-testid="slots-wrapped"] [data-dimsum-slot="dsCheckboxLabel"]');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static async getSlotsLabelTypography() {
|
|
106
|
+
return $('[data-testid="slots-wrapped"] [data-dimsum-parent-slot="dsCheckboxLabelTypography"]');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
static async getSlotsTruncatedLabel() {
|
|
110
|
+
return $('[data-testid="slots-truncated"] [data-dimsum-parent-slot="dsCheckboxTruncatedLabel"]');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// The truncation tooltip renders through a portal, outside the story wrapper, so both tooltip
|
|
114
|
+
// slots are queried document-wide instead of scoped to the instance.
|
|
115
|
+
static async getSlotsTooltipContainer() {
|
|
116
|
+
return $('[data-dimsum-slot="dsCheckboxTooltipContainer"]');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
static async getSlotsTooltipText() {
|
|
120
|
+
return $('[data-dimsum-parent-slot="dsCheckboxTooltipText"]');
|
|
121
|
+
}
|
|
83
122
|
}
|
package/ds-controlled-form/ds-controlled-checkbox/slots/DSControlledCheckbox.slots.func.spec.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import DSControlledCheckboxCO from '../DSControlledCheckboxCO';
|
|
2
|
+
|
|
3
|
+
// Slot surface added when the DSControlledCheckbox label moved to DSTypography under PUI-18774:
|
|
4
|
+
// label-typography, truncated-label, tooltip-container and tooltip-text. The tooltip pair only
|
|
5
|
+
// exists while the label is truncated AND hovered, which is why this lives in E2E rather than in
|
|
6
|
+
// the package's jest slot tests.
|
|
7
|
+
if (
|
|
8
|
+
(!browser.capabilities['ice:options'].isPhone &&
|
|
9
|
+
!browser.capabilities['ice:options'].isTablet &&
|
|
10
|
+
browser.capabilities.browserName === 'chrome') ||
|
|
11
|
+
browser.capabilities.browserName === 'Chrome'
|
|
12
|
+
) {
|
|
13
|
+
describe('PUI-18976 - DSControlledCheckbox:: label typography and tooltip slots - Func', () => {
|
|
14
|
+
before('loading page', async () => {
|
|
15
|
+
const errorOnGo = await DSControlledCheckboxCO.slotsTest.go();
|
|
16
|
+
if (errorOnGo) throw errorOnGo;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('01: should have custom aria-* for each rendered label slot', async () => {
|
|
20
|
+
const root = await DSControlledCheckboxCO.getSlotsRoot();
|
|
21
|
+
const inputWrapper = await DSControlledCheckboxCO.getSlotsInputWrapper();
|
|
22
|
+
const input = await DSControlledCheckboxCO.getSlotsInput();
|
|
23
|
+
const label = await DSControlledCheckboxCO.getSlotsLabel();
|
|
24
|
+
const labelTypography = await DSControlledCheckboxCO.getSlotsLabelTypography();
|
|
25
|
+
const truncatedLabel = await DSControlledCheckboxCO.getSlotsTruncatedLabel();
|
|
26
|
+
await expect(root).toHaveAttribute('aria-label', 'root aria');
|
|
27
|
+
await expect(inputWrapper).toHaveAttribute('aria-label', 'inputwrapper aria');
|
|
28
|
+
await expect(input).toHaveAttribute('aria-label', 'input aria');
|
|
29
|
+
await expect(label).toHaveAttribute('aria-label', 'label aria');
|
|
30
|
+
await expect(labelTypography).toHaveAttribute('aria-label', 'labeltypography aria');
|
|
31
|
+
await expect(truncatedLabel).toHaveAttribute('aria-label', 'truncatedlabel aria');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('02: should have custom data-* for each rendered label slot', async () => {
|
|
35
|
+
const root = await DSControlledCheckboxCO.getSlotsRoot();
|
|
36
|
+
const inputWrapper = await DSControlledCheckboxCO.getSlotsInputWrapper();
|
|
37
|
+
const input = await DSControlledCheckboxCO.getSlotsInput();
|
|
38
|
+
const label = await DSControlledCheckboxCO.getSlotsLabel();
|
|
39
|
+
const labelTypography = await DSControlledCheckboxCO.getSlotsLabelTypography();
|
|
40
|
+
const truncatedLabel = await DSControlledCheckboxCO.getSlotsTruncatedLabel();
|
|
41
|
+
await expect(root).toHaveAttribute('data-testid', 'root data');
|
|
42
|
+
await expect(inputWrapper).toHaveAttribute('data-testid', 'inputwrapper data');
|
|
43
|
+
await expect(input).toHaveAttribute('data-testid', 'input data');
|
|
44
|
+
await expect(label).toHaveAttribute('data-testid', 'label data');
|
|
45
|
+
await expect(labelTypography).toHaveAttribute('data-testid', 'labeltypography data');
|
|
46
|
+
await expect(truncatedLabel).toHaveAttribute('data-testid', 'truncatedlabel data');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('03: should have custom lang for each rendered label slot', async () => {
|
|
50
|
+
const root = await DSControlledCheckboxCO.getSlotsRoot();
|
|
51
|
+
const inputWrapper = await DSControlledCheckboxCO.getSlotsInputWrapper();
|
|
52
|
+
const input = await DSControlledCheckboxCO.getSlotsInput();
|
|
53
|
+
const label = await DSControlledCheckboxCO.getSlotsLabel();
|
|
54
|
+
const labelTypography = await DSControlledCheckboxCO.getSlotsLabelTypography();
|
|
55
|
+
const truncatedLabel = await DSControlledCheckboxCO.getSlotsTruncatedLabel();
|
|
56
|
+
await expect(root).toHaveAttribute('lang', 'ja');
|
|
57
|
+
await expect(inputWrapper).toHaveAttribute('lang', 'it');
|
|
58
|
+
await expect(input).toHaveAttribute('lang', 'de');
|
|
59
|
+
await expect(label).toHaveAttribute('lang', 'fr');
|
|
60
|
+
await expect(labelTypography).toHaveAttribute('lang', 'es');
|
|
61
|
+
await expect(truncatedLabel).toHaveAttribute('lang', 'pt');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('04: should have custom aria-*, data-* and lang for the tooltip slots on hover', async () => {
|
|
65
|
+
const truncatedLabel = await DSControlledCheckboxCO.getSlotsTruncatedLabel();
|
|
66
|
+
await truncatedLabel.moveTo();
|
|
67
|
+
const tooltipContainer = await DSControlledCheckboxCO.getSlotsTooltipContainer();
|
|
68
|
+
await tooltipContainer.waitForDisplayed();
|
|
69
|
+
const tooltipText = await DSControlledCheckboxCO.getSlotsTooltipText();
|
|
70
|
+
await expect(tooltipContainer).toHaveAttribute('aria-label', 'tooltipcontainer aria');
|
|
71
|
+
await expect(tooltipContainer).toHaveAttribute('data-testid', 'tooltipcontainer data');
|
|
72
|
+
await expect(tooltipContainer).toHaveAttribute('lang', 'zh');
|
|
73
|
+
await expect(tooltipText).toHaveAttribute('aria-label', 'tooltiptext aria');
|
|
74
|
+
await expect(tooltipText).toHaveAttribute('data-testid', 'tooltiptext data');
|
|
75
|
+
await expect(tooltipText).toHaveAttribute('lang', 'ru');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PATH_E2E_RADIO } from '../../paths';
|
|
1
|
+
import { PATH_E2E_RADIO, PATH_E2E_RADIO_SLOTS } from '../../paths';
|
|
2
2
|
import { PageObject, Urlbuilder, getElementByIndex } from '../../helpers';
|
|
3
3
|
|
|
4
4
|
export default class DSControlledRadioCO extends PageObject {
|
|
@@ -18,6 +18,8 @@ export default class DSControlledRadioCO extends PageObject {
|
|
|
18
18
|
|
|
19
19
|
static themeFontURL = new Urlbuilder(PATH_E2E_RADIO, 'theme-font-family-test');
|
|
20
20
|
|
|
21
|
+
static slotsTest = new Urlbuilder(PATH_E2E_RADIO_SLOTS, 'slots-test');
|
|
22
|
+
|
|
21
23
|
static async getRadio() {
|
|
22
24
|
return $('[data-testid="ds-radio"]');
|
|
23
25
|
}
|
|
@@ -53,4 +55,41 @@ export default class DSControlledRadioCO extends PageObject {
|
|
|
53
55
|
static async getFallbackRadioLabel() {
|
|
54
56
|
return $('[data-testid="theme-font-fallback"] [data-testid="ds-radio-label-typography"]');
|
|
55
57
|
}
|
|
58
|
+
|
|
59
|
+
// Slots rendered through styled(DSTypography) expose the owner slot on
|
|
60
|
+
// `data-dimsum-parent-slot` (the element's own `data-dimsum-slot` is the typography root),
|
|
61
|
+
// while plain-tag slots expose it on `data-dimsum-slot`.
|
|
62
|
+
static async getSlotsRoot() {
|
|
63
|
+
return $('[data-testid="slots-wrapped"] [data-dimsum-slot="dsRadioRoot"]');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static async getSlotsInputWrapper() {
|
|
67
|
+
return $('[data-testid="slots-wrapped"] [data-dimsum-slot="dsRadioInputWrapper"]');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static async getSlotsInput() {
|
|
71
|
+
return $('[data-testid="slots-wrapped"] [data-dimsum-slot="dsRadioInput"]');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static async getSlotsLabel() {
|
|
75
|
+
return $('[data-testid="slots-wrapped"] [data-dimsum-slot="dsRadioLabel"]');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
static async getSlotsLabelTypography() {
|
|
79
|
+
return $('[data-testid="slots-wrapped"] [data-dimsum-parent-slot="dsRadioLabelTypography"]');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static async getSlotsTruncatedLabel() {
|
|
83
|
+
return $('[data-testid="slots-truncated"] [data-dimsum-parent-slot="dsRadioTruncatedLabel"]');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// The truncation tooltip renders through a portal, outside the story wrapper, so both tooltip
|
|
87
|
+
// slots are queried document-wide instead of scoped to the instance.
|
|
88
|
+
static async getSlotsTooltipContainer() {
|
|
89
|
+
return $('[data-dimsum-slot="dsRadioTooltipContainer"]');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
static async getSlotsTooltipText() {
|
|
93
|
+
return $('[data-dimsum-parent-slot="dsRadioTooltipText"]');
|
|
94
|
+
}
|
|
56
95
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import DSControlledRadioCO from '../DSControlledRadioCO';
|
|
2
|
+
|
|
3
|
+
// Slot surface added when the DSControlledRadio label moved to DSTypography under PUI-18774:
|
|
4
|
+
// label-typography, truncated-label, tooltip-container and tooltip-text. The tooltip pair only
|
|
5
|
+
// exists while the label is truncated AND hovered, which is why this lives in E2E rather than in
|
|
6
|
+
// the package's jest slot tests.
|
|
7
|
+
if (
|
|
8
|
+
(!browser.capabilities['ice:options'].isPhone &&
|
|
9
|
+
!browser.capabilities['ice:options'].isTablet &&
|
|
10
|
+
browser.capabilities.browserName === 'chrome') ||
|
|
11
|
+
browser.capabilities.browserName === 'Chrome'
|
|
12
|
+
) {
|
|
13
|
+
describe('PUI-18975 - DSControlledRadio:: label typography and tooltip slots - Func', () => {
|
|
14
|
+
before('loading page', async () => {
|
|
15
|
+
const errorOnGo = await DSControlledRadioCO.slotsTest.go();
|
|
16
|
+
if (errorOnGo) throw errorOnGo;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('01: should have custom aria-* for each rendered label slot', async () => {
|
|
20
|
+
const root = await DSControlledRadioCO.getSlotsRoot();
|
|
21
|
+
const inputWrapper = await DSControlledRadioCO.getSlotsInputWrapper();
|
|
22
|
+
const input = await DSControlledRadioCO.getSlotsInput();
|
|
23
|
+
const label = await DSControlledRadioCO.getSlotsLabel();
|
|
24
|
+
const labelTypography = await DSControlledRadioCO.getSlotsLabelTypography();
|
|
25
|
+
const truncatedLabel = await DSControlledRadioCO.getSlotsTruncatedLabel();
|
|
26
|
+
await expect(root).toHaveAttribute('aria-label', 'root aria');
|
|
27
|
+
await expect(inputWrapper).toHaveAttribute('aria-label', 'inputwrapper aria');
|
|
28
|
+
await expect(input).toHaveAttribute('aria-label', 'input aria');
|
|
29
|
+
await expect(label).toHaveAttribute('aria-label', 'label aria');
|
|
30
|
+
await expect(labelTypography).toHaveAttribute('aria-label', 'labeltypography aria');
|
|
31
|
+
await expect(truncatedLabel).toHaveAttribute('aria-label', 'truncatedlabel aria');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('02: should have custom data-* for each rendered label slot', async () => {
|
|
35
|
+
const root = await DSControlledRadioCO.getSlotsRoot();
|
|
36
|
+
const inputWrapper = await DSControlledRadioCO.getSlotsInputWrapper();
|
|
37
|
+
const input = await DSControlledRadioCO.getSlotsInput();
|
|
38
|
+
const label = await DSControlledRadioCO.getSlotsLabel();
|
|
39
|
+
const labelTypography = await DSControlledRadioCO.getSlotsLabelTypography();
|
|
40
|
+
const truncatedLabel = await DSControlledRadioCO.getSlotsTruncatedLabel();
|
|
41
|
+
await expect(root).toHaveAttribute('data-testid', 'root data');
|
|
42
|
+
await expect(inputWrapper).toHaveAttribute('data-testid', 'inputwrapper data');
|
|
43
|
+
await expect(input).toHaveAttribute('data-testid', 'input data');
|
|
44
|
+
await expect(label).toHaveAttribute('data-testid', 'label data');
|
|
45
|
+
await expect(labelTypography).toHaveAttribute('data-testid', 'labeltypography data');
|
|
46
|
+
await expect(truncatedLabel).toHaveAttribute('data-testid', 'truncatedlabel data');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('03: should have custom lang for each rendered label slot', async () => {
|
|
50
|
+
const root = await DSControlledRadioCO.getSlotsRoot();
|
|
51
|
+
const inputWrapper = await DSControlledRadioCO.getSlotsInputWrapper();
|
|
52
|
+
const input = await DSControlledRadioCO.getSlotsInput();
|
|
53
|
+
const label = await DSControlledRadioCO.getSlotsLabel();
|
|
54
|
+
const labelTypography = await DSControlledRadioCO.getSlotsLabelTypography();
|
|
55
|
+
const truncatedLabel = await DSControlledRadioCO.getSlotsTruncatedLabel();
|
|
56
|
+
await expect(root).toHaveAttribute('lang', 'ja');
|
|
57
|
+
await expect(inputWrapper).toHaveAttribute('lang', 'it');
|
|
58
|
+
await expect(input).toHaveAttribute('lang', 'de');
|
|
59
|
+
await expect(label).toHaveAttribute('lang', 'fr');
|
|
60
|
+
await expect(labelTypography).toHaveAttribute('lang', 'es');
|
|
61
|
+
await expect(truncatedLabel).toHaveAttribute('lang', 'pt');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('04: should have custom aria-*, data-* and lang for the tooltip slots on hover', async () => {
|
|
65
|
+
const truncatedLabel = await DSControlledRadioCO.getSlotsTruncatedLabel();
|
|
66
|
+
await truncatedLabel.moveTo();
|
|
67
|
+
const tooltipContainer = await DSControlledRadioCO.getSlotsTooltipContainer();
|
|
68
|
+
await tooltipContainer.waitForDisplayed();
|
|
69
|
+
const tooltipText = await DSControlledRadioCO.getSlotsTooltipText();
|
|
70
|
+
await expect(tooltipContainer).toHaveAttribute('aria-label', 'tooltipcontainer aria');
|
|
71
|
+
await expect(tooltipContainer).toHaveAttribute('data-testid', 'tooltipcontainer data');
|
|
72
|
+
await expect(tooltipContainer).toHaveAttribute('lang', 'zh');
|
|
73
|
+
await expect(tooltipText).toHaveAttribute('aria-label', 'tooltiptext aria');
|
|
74
|
+
await expect(tooltipText).toHaveAttribute('data-testid', 'tooltiptext data');
|
|
75
|
+
await expect(tooltipText).toHaveAttribute('lang', 'ru');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
@@ -51,10 +51,11 @@ export default class HeaderCO extends PageObject {
|
|
|
51
51
|
|
|
52
52
|
static getHeadersWrapper = async () => $('[data-testid="ds-datatable-head-wrapper"]');
|
|
53
53
|
|
|
54
|
-
// PUI-17784: resize handle
|
|
55
|
-
// <button role="application" aria-labelledby>
|
|
56
|
-
//
|
|
57
|
-
//
|
|
54
|
+
// PUI-17784 / PUI-18812 / PUI-18885: the resize handle went <input type="range" aria-label="Resize
|
|
55
|
+
// column"> -> <button role="application" aria-labelledby> -> back to a native <input type="range">
|
|
56
|
+
// named with a dynamic aria-label="Resize {column} column". Selecting on data-testid rather than
|
|
57
|
+
// aria-label is what kept this accessor stable across all of it (the original selector matched
|
|
58
|
+
// neither data-testid="column" nor the post-PUI-17784 naming).
|
|
58
59
|
static getResizeHandler = async (index) => $$('[data-testid="ds-datatable-resizer"]')[index];
|
|
59
60
|
|
|
60
61
|
static getResizeHandlers = async () => $$('[data-testid="ds-datatable-resizer"]');
|
|
@@ -83,18 +84,9 @@ export default class HeaderCO extends PageObject {
|
|
|
83
84
|
// as the getResizeHandler selector fix (separate PR); kept distinct so these a11y specs run standalone.
|
|
84
85
|
static getResizer = async (index) => $$('[data-testid="ds-datatable-resizer"]')[index];
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
* it. Use getResizerComputedName for that. (The two can disagree: the name span is display:none,
|
|
90
|
-
* and whether a hidden aria-labelledby target contributes to the computed name is exactly the
|
|
91
|
-
* thing this must not assume.)
|
|
92
|
-
*/
|
|
93
|
-
static getResizerLabelledByText = async (resizer) => {
|
|
94
|
-
const labelledById = await resizer.getAttribute('aria-labelledby');
|
|
95
|
-
if (!labelledById) return null;
|
|
96
|
-
return (await $(`#${labelledById}`)).getProperty('textContent');
|
|
97
|
-
};
|
|
87
|
+
// PUI-18885 removed getResizerLabelledByText: the resizer is named with aria-label directly, so
|
|
88
|
+
// there is no aria-labelledby reference left to resolve. Read the attribute in the spec and use
|
|
89
|
+
// getResizerComputedName below for what the browser actually computes.
|
|
98
90
|
|
|
99
91
|
/**
|
|
100
92
|
* The accessible name the BROWSER computes for the resizer, via the W3C WebDriver
|
|
@@ -122,7 +122,23 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
|
|
|
122
122
|
// Tests for the fix introduced in PUI-15851 (a wrapper-level mousedown preventDefault() in the
|
|
123
123
|
// combobox's `inline` mode suppressed the browser's native caret placement and word selection,
|
|
124
124
|
// and a second click on the focused input blurred it, clearing the value and closing the menu).
|
|
125
|
-
|
|
125
|
+
//
|
|
126
|
+
// PUI-15851 was reopened and moved to 27.2: the fix traded away click-to-close on the combobox
|
|
127
|
+
// control (PUI-18919), a behavior ratified in PUI-15737 / PUI-15753 and encoded as QA acceptance
|
|
128
|
+
// criteria in PUI-15741 / PUI-15748. Until that interaction is redefined, the expectations below
|
|
129
|
+
// are not a stable contract, so this describe is describe.skip'd and PUI-18881 is back to a
|
|
130
|
+
// non-automated state.
|
|
131
|
+
//
|
|
132
|
+
// The rollback is PR #8307 (fix/PUI-18919, open against next as of 27.1). It reverts #8233
|
|
133
|
+
// wholesale: the wrapper-level mousedown preventDefault() is restored for clicks on the input,
|
|
134
|
+
// as is the hidden-span width measurement and the click handler that blurs the input on a second
|
|
135
|
+
// click. So once it merges all three cases below go red, not just case 03 — the caret and
|
|
136
|
+
// word-selection behavior they assert stops existing again. That is why the whole describe is
|
|
137
|
+
// skipped rather than case 03 alone. The cases are kept in tree rather than deleted because 01
|
|
138
|
+
// and 02 are not the disputed part and should be the starting point for the 27.2 coverage; only
|
|
139
|
+
// 03 (a second click keeps the value, focus and open menu) has to be re-written, once 27.2
|
|
140
|
+
// settles what a pointer click on the filter search input should do.
|
|
141
|
+
describe.skip('PUI-18881 - DSDataTable:: filter search input mouse caret and selection - Func', () => {
|
|
126
142
|
beforeEach('loading page', async () => {
|
|
127
143
|
const errorOnGo = await DSDataTableCO.filteredCreatable.go();
|
|
128
144
|
if (errorOnGo) throw errorOnGo;
|
|
@@ -10,22 +10,21 @@ import { axeCoreCheck } from '../../helpers';
|
|
|
10
10
|
// The scan is what guards the bounded aria-value* set: a native range input whose aria-valuenow
|
|
11
11
|
// fell outside aria-valuemin/aria-valuemax would trip aria-valid-attr-value.
|
|
12
12
|
// PUI-18812 removed the resizerA11yMode prop, so there is a single resizer shape to scan.
|
|
13
|
+
//
|
|
14
|
+
// PUI-18885: this describe was temporarily describe.skip'd. Making the handle a form element
|
|
15
|
+
// (PUI-18812) exposed it to axe's form rules, and naming it via aria-labelledby -> a display:none
|
|
16
|
+
// span left no labelText axe could resolve; with aria-describedby also present, that tripped
|
|
17
|
+
// label-title-only ("Form elements should have a visible label", serious / best-practice). The fix
|
|
18
|
+
// names the handle directly with aria-label, so the rule no longer applies and the scan is live
|
|
19
|
+
// again. It was never silenced via extraDisabledRules — that would have hidden the regression this
|
|
20
|
+
// scan exists to catch.
|
|
13
21
|
if (
|
|
14
22
|
(!browser.capabilities['ice:options'].isPhone &&
|
|
15
23
|
!browser.capabilities['ice:options'].isTablet &&
|
|
16
24
|
browser.capabilities.browserName === 'chrome') ||
|
|
17
25
|
browser.capabilities.browserName === 'Chrome'
|
|
18
26
|
) {
|
|
19
|
-
|
|
20
|
-
// handle a native <input type="range">, this scan reports one violation:
|
|
21
|
-
//
|
|
22
|
-
// label-title-only — impact: serious — tags: ['cat.forms', 'best-practice']
|
|
23
|
-
// "Ensure that every form element has a visible label and is not solely labeled using hidden
|
|
24
|
-
// labels, or the title or aria-describedby attributes"
|
|
25
|
-
//
|
|
26
|
-
// Skipped rather than silenced with extraDisabledRules, so the violation stays visible on the
|
|
27
|
-
// ticket instead of being suppressed here. Un-skip once PUI-18885 is resolved.
|
|
28
|
-
describe.skip('PUI-18750 - DSDataTable:: resizer native range input a11y contract - Axe-Core', () => {
|
|
27
|
+
describe('PUI-18750 - DSDataTable:: resizer native range input a11y contract - Axe-Core', () => {
|
|
29
28
|
before(async () => {
|
|
30
29
|
const errorOnGo = await DSDataTableCO.resizerSeparatorMode.go();
|
|
31
30
|
if (errorOnGo) throw errorOnGo;
|
|
@@ -9,6 +9,9 @@ import { HeaderCO } from '../components';
|
|
|
9
9
|
// accessible name "Resize {Header} column", so no stray "50" is ever announced.
|
|
10
10
|
// PUI-18812 also removed the resizerA11yMode prop: there is no longer a separator/slider choice, so
|
|
11
11
|
// the ARIA contract below is the single shape for every resizer.
|
|
12
|
+
// PUI-18885 changed how that name is supplied — aria-label on the handle itself instead of
|
|
13
|
+
// aria-labelledby pointing at a display:none span — because the indirection through a hidden node
|
|
14
|
+
// gave axe no resolvable labelText and tripped label-title-only on the native range input.
|
|
12
15
|
if (
|
|
13
16
|
(!browser.capabilities['ice:options'].isPhone &&
|
|
14
17
|
!browser.capabilities['ice:options'].isTablet &&
|
|
@@ -47,15 +50,16 @@ if (
|
|
|
47
50
|
const valueText = await resizer.getAttribute('aria-valuetext'); // SR text, e.g. "150 pixels"
|
|
48
51
|
expect(/^\d+ pixels$/.test(valueText)).toBe(true); // must read "<width> pixels"
|
|
49
52
|
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
expect(
|
|
53
|
+
// PUI-18885: the name is supplied directly via aria-label. It used to be wired through
|
|
54
|
+
// aria-labelledby -> a display:none span, which left axe unable to resolve a labelText and
|
|
55
|
+
// tripped label-title-only on this form element (see the axe-core sibling spec). aria-labelledby
|
|
56
|
+
// must stay absent: reintroducing it would both shadow this name and bring the violation back.
|
|
57
|
+
// This asserts the attribute VALUE only; whether the browser computes a name from it is asserted
|
|
58
|
+
// in test 02, where the handle is exposed to the accessibility tree. It cannot be asserted here:
|
|
59
|
+
// at rest the handle is aria-hidden, so it has no computed name by design and a computed-name
|
|
60
|
+
// check would fail for the wrong reason.
|
|
61
|
+
expect(await resizer.getAttribute('aria-labelledby')).toBe(null);
|
|
62
|
+
await expect(resizer).toHaveAttribute('aria-label', 'Resize Name column');
|
|
59
63
|
});
|
|
60
64
|
|
|
61
65
|
it('02: should update aria-valuenow when resizing with the keyboard', async () => {
|
|
@@ -74,10 +78,12 @@ if (
|
|
|
74
78
|
expect(await resizer.getAttribute('aria-hidden')).toBe(null);
|
|
75
79
|
|
|
76
80
|
// The accessible name the browser actually computes, now that the handle is in the
|
|
77
|
-
// accessibility tree. This is the assertion that matters:
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
+
// accessibility tree. This is the assertion that matters: test 01 only proves the aria-label
|
|
82
|
+
// attribute is present with the right text, which would still pass if something else (a
|
|
83
|
+
// reintroduced aria-labelledby, a native label association) shadowed it in the accname
|
|
84
|
+
// algorithm. A focused control with no computed name is a WCAG 4.1.2 failure, so it is asserted
|
|
85
|
+
// against the browser's own computation via WebDriver's Get Computed Label, not re-derived from
|
|
86
|
+
// the DOM.
|
|
81
87
|
const computedName = await HeaderCO.getResizerComputedName(resizer);
|
|
82
88
|
expect(computedName).toContain('Resize Name column');
|
|
83
89
|
|
|
@@ -39,6 +39,8 @@ export default class DSComboboxMultiCO extends PageObject {
|
|
|
39
39
|
|
|
40
40
|
static withTooltip = new Urlbuilder(PATH_E2E_COMBOBOX_MULTI, 'with-tooltip-test');
|
|
41
41
|
|
|
42
|
+
static themeFontURL = new Urlbuilder(PATH_E2E_COMBOBOX_MULTI, 'theme-font-family-test');
|
|
43
|
+
|
|
42
44
|
static controlledMenuStateWithSectionsSlotsTest = new Urlbuilder(
|
|
43
45
|
PATH_E2E_COMBOBOX_MULTI_SLOTS,
|
|
44
46
|
'controlled-menu-state-with-section-slots-test',
|
|
@@ -81,14 +83,6 @@ export default class DSComboboxMultiCO extends PageObject {
|
|
|
81
83
|
return $$('[data-testid="combobox-input"]')[index];
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
static async getComboboxHiddenInput() {
|
|
85
|
-
return $('input[aria-hidden="true"]');
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
static async getComboboxHiddenInputByIndex(index) {
|
|
89
|
-
return $$('input[aria-hidden="true"]')[index];
|
|
90
|
-
}
|
|
91
|
-
|
|
92
86
|
static async getSelectedValues() {
|
|
93
87
|
return $('[data-testid="combobox-selected-values"]');
|
|
94
88
|
}
|
|
@@ -302,4 +296,18 @@ export default class DSComboboxMultiCO extends PageObject {
|
|
|
302
296
|
static snapshotPath(example = 'basic') {
|
|
303
297
|
return PageObject.getSnapshotPathBuilder('DSComboboxMulti', example, 'ds-combobox-multi');
|
|
304
298
|
}
|
|
299
|
+
|
|
300
|
+
// The selection wrapper and the selected pills' labels both render through
|
|
301
|
+
// styled(DSTypography), so the owner slot lands on `data-dimsum-parent-slot`.
|
|
302
|
+
static async getThemedSelection() {
|
|
303
|
+
return $('[data-testid="theme-font-sentinel"] [data-dimsum-parent-slot="dsComboboxSelection"]');
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
static async getFallbackSelection() {
|
|
307
|
+
return $('[data-testid="theme-font-fallback"] [data-dimsum-parent-slot="dsComboboxSelection"]');
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
static async getThemedPillLabel() {
|
|
311
|
+
return $('[data-testid="theme-font-sentinel"] [data-dimsum-parent-slot="dsPillLabel"]');
|
|
312
|
+
}
|
|
305
313
|
}
|
|
@@ -11,10 +11,8 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
|
|
|
11
11
|
it('01: combobox multi disabled should not be focused - clicking Input', async () => {
|
|
12
12
|
const combobox = await DSComboboxMultiCO.getCombobox();
|
|
13
13
|
const input = await DSComboboxMultiCO.getComboboxInput();
|
|
14
|
-
const hiddenInput = await DSComboboxMultiCO.getComboboxHiddenInput();
|
|
15
14
|
await combobox.click();
|
|
16
15
|
await expect(input).not.toBeFocused();
|
|
17
|
-
await expect(hiddenInput).not.toBeFocused();
|
|
18
16
|
});
|
|
19
17
|
it('02: listbox should not be displayed when combobox is disabled', async () => {
|
|
20
18
|
await browser.keys(Key.ArrowDown);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import DSComboboxMultiCO from '../DSComboboxMultiCO';
|
|
2
|
+
|
|
3
|
+
// Tests the theme-driven font-family mechanism covered by the combobox theming spike PUI-18214
|
|
4
|
+
// (the selection wrapper and the selected pills' labels render through DSTypography, which reads
|
|
5
|
+
// theme.fonts.default, falling back to proxima-nova). Theme-agnostic: uses a sentinel font,
|
|
6
|
+
// never the dsConsumer POC theme values, so it survives any future theme change.
|
|
7
|
+
// Out of scope on purpose: the native <input> that holds typed text mirrors b2 as raw CSS and
|
|
8
|
+
// declares no font-family, so it does NOT follow theme.fonts.default (measured under the sentinel
|
|
9
|
+
// theme it still computes proxima-nova, i.e. the inherited page font, while the selection text
|
|
10
|
+
// switches). Asserting it here would lock in that gap; it is reported separately instead.
|
|
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
|
+
) {
|
|
17
|
+
describe('PUI-18974 - ComboboxMulti:: theme font-family wiring - Func', () => {
|
|
18
|
+
before('loading page', async () => {
|
|
19
|
+
const errorOnGo = await DSComboboxMultiCO.themeFontURL.go();
|
|
20
|
+
if (errorOnGo) throw errorOnGo;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('01: should read selection and pill font-family from theme with proxima-nova fallback', async () => {
|
|
24
|
+
const themed = await DSComboboxMultiCO.getThemedSelection();
|
|
25
|
+
await themed.waitForDisplayed();
|
|
26
|
+
const themedFont = (await themed.getCSSProperty('font-family')).value.toLowerCase();
|
|
27
|
+
await expect(themedFont).toContain('sentinelfont');
|
|
28
|
+
|
|
29
|
+
const themedPill = await DSComboboxMultiCO.getThemedPillLabel();
|
|
30
|
+
const themedPillFont = (await themedPill.getCSSProperty('font-family')).value.toLowerCase();
|
|
31
|
+
await expect(themedPillFont).toContain('sentinelfont');
|
|
32
|
+
|
|
33
|
+
const fallback = await DSComboboxMultiCO.getFallbackSelection();
|
|
34
|
+
const fallbackFont = (await fallback.getCSSProperty('font-family')).value.toLowerCase();
|
|
35
|
+
await expect(fallbackFont).toContain('proxima-nova');
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -45,6 +45,8 @@ export default class DSComboboxSingleCO extends PageObject {
|
|
|
45
45
|
|
|
46
46
|
static withTooltip = new Urlbuilder(PATH_E2E_COMBOBOX_SINGLE, 'with-tooltip-test');
|
|
47
47
|
|
|
48
|
+
static themeFontURL = new Urlbuilder(PATH_E2E_COMBOBOX_SINGLE, 'theme-font-family-test');
|
|
49
|
+
|
|
48
50
|
// COMBOBOX - INPUT
|
|
49
51
|
static async getCombobox() {
|
|
50
52
|
return $('[data-testid="combobox-container"]');
|
|
@@ -78,14 +80,6 @@ export default class DSComboboxSingleCO extends PageObject {
|
|
|
78
80
|
return $$('[data-testid="combobox-input"]')[index];
|
|
79
81
|
}
|
|
80
82
|
|
|
81
|
-
static async getComboboxHiddenInput() {
|
|
82
|
-
return $('input[aria-hidden="true"]');
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
static async getComboboxHiddenInputByIndex(index) {
|
|
86
|
-
return $$('input[aria-hidden="true"]')[index];
|
|
87
|
-
}
|
|
88
|
-
|
|
89
83
|
static async getSelectedValues() {
|
|
90
84
|
return $('[data-testid="combobox-selected-values"]');
|
|
91
85
|
}
|
|
@@ -283,4 +277,14 @@ export default class DSComboboxSingleCO extends PageObject {
|
|
|
283
277
|
static snapshotPath(example = 'basic') {
|
|
284
278
|
return PageObject.getSnapshotPathBuilder('DSComboboxV3', example, 'ds-combobox');
|
|
285
279
|
}
|
|
280
|
+
|
|
281
|
+
// The selection text renders through styled(DSTypography), so the owner slot lands on
|
|
282
|
+
// `data-dimsum-parent-slot` (the element's own `data-dimsum-slot` is the typography root).
|
|
283
|
+
static async getThemedSelection() {
|
|
284
|
+
return $('[data-testid="theme-font-sentinel"] [data-dimsum-parent-slot="dsComboboxSelection"]');
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
static async getFallbackSelection() {
|
|
288
|
+
return $('[data-testid="theme-font-fallback"] [data-dimsum-parent-slot="dsComboboxSelection"]');
|
|
289
|
+
}
|
|
286
290
|
}
|
|
@@ -11,10 +11,8 @@ if (!browser.capabilities['ice:options'].isPhone && !browser.capabilities['ice:o
|
|
|
11
11
|
it('01: combobox single disabled should not be focused - clicking Input', async () => {
|
|
12
12
|
const combobox = await DSComboboxSingleCO.getComboboxByIndex(0);
|
|
13
13
|
const input = await DSComboboxSingleCO.getComboboxInputByIndex(0);
|
|
14
|
-
const hiddenInput = await DSComboboxSingleCO.getComboboxHiddenInputByIndex(0);
|
|
15
14
|
await combobox.click();
|
|
16
15
|
await expect(input).not.toBeFocused();
|
|
17
|
-
await expect(hiddenInput).not.toBeFocused();
|
|
18
16
|
});
|
|
19
17
|
it('02: listbox should not be displayed when combobox is disabled', async () => {
|
|
20
18
|
await browser.keys(Key.ArrowDown);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import DSComboboxSingleCO from '../DSComboboxSingleCO';
|
|
2
|
+
|
|
3
|
+
// Tests the theme-driven font-family mechanism covered by the combobox theming spike PUI-18214
|
|
4
|
+
// (the selection text renders through DSTypography, which reads theme.fonts.default, falling
|
|
5
|
+
// back to proxima-nova). Theme-agnostic: uses a sentinel font, never the dsConsumer POC theme
|
|
6
|
+
// values, so it survives any future theme change.
|
|
7
|
+
// Out of scope on purpose: the native <input> that holds typed text mirrors b2 as raw CSS and
|
|
8
|
+
// declares no font-family, so it does NOT follow theme.fonts.default (measured under the sentinel
|
|
9
|
+
// theme it still computes proxima-nova, i.e. the inherited page font, while the selection text
|
|
10
|
+
// switches). Asserting it here would lock in that gap; it is reported separately instead.
|
|
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
|
+
) {
|
|
17
|
+
describe('PUI-18973 - ComboboxSingle:: theme font-family wiring - Func', () => {
|
|
18
|
+
before('loading page', async () => {
|
|
19
|
+
const errorOnGo = await DSComboboxSingleCO.themeFontURL.go();
|
|
20
|
+
if (errorOnGo) throw errorOnGo;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('01: should read selection font-family from theme with proxima-nova fallback', async () => {
|
|
24
|
+
const themed = await DSComboboxSingleCO.getThemedSelection();
|
|
25
|
+
await themed.waitForDisplayed();
|
|
26
|
+
const themedFont = (await themed.getCSSProperty('font-family')).value.toLowerCase();
|
|
27
|
+
await expect(themedFont).toContain('sentinelfont');
|
|
28
|
+
|
|
29
|
+
const fallback = await DSComboboxSingleCO.getFallbackSelection();
|
|
30
|
+
const fallbackFont = (await fallback.getCSSProperty('font-family')).value.toLowerCase();
|
|
31
|
+
await expect(fallbackFont).toContain('proxima-nova');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "dimsum-e2e-tests",
|
|
4
|
-
"version": "3.70.0-next.
|
|
4
|
+
"version": "3.70.0-next.62",
|
|
5
5
|
"description": "End-to-end tests for dimsum library",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@elliemae/ds-legacy-button": "1.0.16",
|
|
@@ -38,154 +38,154 @@
|
|
|
38
38
|
"@elliemae/ds-legacy-wysiwygeditor": "1.0.16",
|
|
39
39
|
"@elliemae/ds-legacy-zipcode-search": "1.0.16",
|
|
40
40
|
"@elliemae/ds-legacy-zoom": "1.0.16",
|
|
41
|
-
"@elliemae/ds-accessibility": "3.70.0-next.
|
|
42
|
-
"@elliemae/ds-accordion": "3.70.0-next.
|
|
43
|
-
"@elliemae/ds-
|
|
44
|
-
"@elliemae/ds-
|
|
45
|
-
"@elliemae/ds-
|
|
46
|
-
"@elliemae/ds-
|
|
47
|
-
"@elliemae/ds-
|
|
48
|
-
"@elliemae/ds-
|
|
49
|
-
"@elliemae/ds-
|
|
50
|
-
"@elliemae/ds-
|
|
51
|
-
"@elliemae/ds-card-
|
|
52
|
-
"@elliemae/ds-card-v1-detail": "3.70.0-next.
|
|
53
|
-
"@elliemae/ds-card-v2": "3.70.0-next.
|
|
54
|
-
"@elliemae/ds-card-v2-group": "3.70.0-next.
|
|
55
|
-
"@elliemae/ds-card-
|
|
56
|
-
"@elliemae/ds-card-
|
|
57
|
-
"@elliemae/ds-chat": "3.70.0-next.
|
|
58
|
-
"@elliemae/ds-chat-bubble": "3.70.0-next.
|
|
59
|
-
"@elliemae/ds-
|
|
60
|
-
"@elliemae/ds-chat-
|
|
61
|
-
"@elliemae/ds-chat-
|
|
62
|
-
"@elliemae/ds-chat-container-header": "3.70.0-next.
|
|
63
|
-
"@elliemae/ds-chat-floating-button": "3.70.0-next.
|
|
64
|
-
"@elliemae/ds-chat-
|
|
65
|
-
"@elliemae/ds-chat-sidebar": "3.70.0-next.
|
|
66
|
-
"@elliemae/ds-
|
|
67
|
-
"@elliemae/ds-chat-
|
|
68
|
-
"@elliemae/ds-
|
|
69
|
-
"@elliemae/ds-
|
|
70
|
-
"@elliemae/ds-
|
|
71
|
-
"@elliemae/ds-
|
|
72
|
-
"@elliemae/ds-
|
|
73
|
-
"@elliemae/ds-
|
|
74
|
-
"@elliemae/ds-
|
|
75
|
-
"@elliemae/ds-
|
|
76
|
-
"@elliemae/ds-data-table
|
|
77
|
-
"@elliemae/ds-data-table-
|
|
78
|
-
"@elliemae/ds-data-table-cell
|
|
79
|
-
"@elliemae/ds-data-table-
|
|
80
|
-
"@elliemae/ds-data-table-
|
|
81
|
-
"@elliemae/ds-data-table-
|
|
82
|
-
"@elliemae/ds-data-table-
|
|
83
|
-
"@elliemae/ds-data-table-
|
|
84
|
-
"@elliemae/ds-
|
|
85
|
-
"@elliemae/ds-dataviz
|
|
86
|
-
"@elliemae/ds-
|
|
87
|
-
"@elliemae/ds-decision-graph": "3.70.0-next.
|
|
88
|
-
"@elliemae/ds-dropdownmenu-v2": "3.70.0-next.
|
|
89
|
-
"@elliemae/ds-
|
|
90
|
-
"@elliemae/ds-dropzone": "3.70.0-next.
|
|
91
|
-
"@elliemae/ds-
|
|
92
|
-
"@elliemae/ds-
|
|
93
|
-
"@elliemae/ds-
|
|
94
|
-
"@elliemae/ds-
|
|
95
|
-
"@elliemae/ds-form-
|
|
96
|
-
"@elliemae/ds-
|
|
97
|
-
"@elliemae/ds-form-
|
|
98
|
-
"@elliemae/ds-form-
|
|
99
|
-
"@elliemae/ds-form-
|
|
100
|
-
"@elliemae/ds-form-
|
|
101
|
-
"@elliemae/ds-form-
|
|
102
|
-
"@elliemae/ds-form-layout-
|
|
103
|
-
"@elliemae/ds-form-
|
|
104
|
-
"@elliemae/ds-form-
|
|
105
|
-
"@elliemae/ds-form-
|
|
106
|
-
"@elliemae/ds-form-
|
|
107
|
-
"@elliemae/ds-form-
|
|
108
|
-
"@elliemae/ds-form-
|
|
109
|
-
"@elliemae/ds-form-single-combobox": "3.70.0-next.
|
|
110
|
-
"@elliemae/ds-form-
|
|
111
|
-
"@elliemae/ds-
|
|
112
|
-
"@elliemae/ds-global-header": "3.70.0-next.
|
|
113
|
-
"@elliemae/ds-hooks-
|
|
114
|
-
"@elliemae/ds-hooks-fontsize-
|
|
115
|
-
"@elliemae/ds-hooks-
|
|
116
|
-
"@elliemae/ds-hooks-
|
|
117
|
-
"@elliemae/ds-hooks-
|
|
118
|
-
"@elliemae/ds-
|
|
119
|
-
"@elliemae/ds-
|
|
120
|
-
"@elliemae/ds-hooks-
|
|
121
|
-
"@elliemae/ds-
|
|
122
|
-
"@elliemae/ds-
|
|
123
|
-
"@elliemae/ds-
|
|
124
|
-
"@elliemae/ds-
|
|
125
|
-
"@elliemae/ds-
|
|
126
|
-
"@elliemae/ds-
|
|
127
|
-
"@elliemae/ds-
|
|
128
|
-
"@elliemae/ds-loading-indicator": "3.70.0-next.
|
|
129
|
-
"@elliemae/ds-
|
|
130
|
-
"@elliemae/ds-menu-items-
|
|
131
|
-
"@elliemae/ds-menu-items
|
|
132
|
-
"@elliemae/ds-
|
|
133
|
-
"@elliemae/ds-
|
|
134
|
-
"@elliemae/ds-menu-
|
|
135
|
-
"@elliemae/ds-menu-items-
|
|
136
|
-
"@elliemae/ds-
|
|
137
|
-
"@elliemae/ds-menu-items-
|
|
138
|
-
"@elliemae/ds-menu-
|
|
139
|
-
"@elliemae/ds-menu-items-single": "3.70.0-next.
|
|
140
|
-
"@elliemae/ds-
|
|
141
|
-
"@elliemae/ds-
|
|
142
|
-
"@elliemae/ds-
|
|
143
|
-
"@elliemae/ds-
|
|
144
|
-
"@elliemae/ds-menu-items-
|
|
145
|
-
"@elliemae/ds-
|
|
146
|
-
"@elliemae/ds-
|
|
147
|
-
"@elliemae/ds-
|
|
148
|
-
"@elliemae/ds-page-header-v1": "3.70.0-next.
|
|
149
|
-
"@elliemae/ds-page-header-v2": "3.70.0-next.
|
|
150
|
-
"@elliemae/ds-
|
|
151
|
-
"@elliemae/ds-
|
|
152
|
-
"@elliemae/ds-
|
|
153
|
-
"@elliemae/ds-
|
|
154
|
-
"@elliemae/ds-
|
|
155
|
-
"@elliemae/ds-
|
|
156
|
-
"@elliemae/ds-read-more": "3.70.0-next.
|
|
157
|
-
"@elliemae/ds-
|
|
158
|
-
"@elliemae/ds-
|
|
159
|
-
"@elliemae/ds-
|
|
160
|
-
"@elliemae/ds-
|
|
161
|
-
"@elliemae/ds-
|
|
162
|
-
"@elliemae/ds-scrollable-container": "3.70.0-next.
|
|
163
|
-
"@elliemae/ds-
|
|
164
|
-
"@elliemae/ds-
|
|
165
|
-
"@elliemae/ds-
|
|
166
|
-
"@elliemae/ds-side-panel": "3.70.0-next.
|
|
167
|
-
"@elliemae/ds-
|
|
168
|
-
"@elliemae/ds-
|
|
169
|
-
"@elliemae/ds-
|
|
170
|
-
"@elliemae/ds-
|
|
171
|
-
"@elliemae/ds-
|
|
172
|
-
"@elliemae/ds-
|
|
173
|
-
"@elliemae/ds-tabs": "3.70.0-next.
|
|
174
|
-
"@elliemae/ds-test-utils": "3.70.0-next.
|
|
175
|
-
"@elliemae/ds-
|
|
176
|
-
"@elliemae/ds-
|
|
177
|
-
"@elliemae/ds-
|
|
178
|
-
"@elliemae/ds-
|
|
179
|
-
"@elliemae/ds-
|
|
180
|
-
"@elliemae/ds-
|
|
181
|
-
"@elliemae/ds-tree-model": "3.70.0-next.
|
|
182
|
-
"@elliemae/ds-
|
|
183
|
-
"@elliemae/ds-
|
|
184
|
-
"@elliemae/ds-
|
|
185
|
-
"@elliemae/ds-
|
|
186
|
-
"@elliemae/ds-
|
|
187
|
-
"@elliemae/ds-
|
|
188
|
-
"@elliemae/ds-
|
|
41
|
+
"@elliemae/ds-accessibility": "3.70.0-next.62",
|
|
42
|
+
"@elliemae/ds-accordion": "3.70.0-next.62",
|
|
43
|
+
"@elliemae/ds-banner": "3.70.0-next.62",
|
|
44
|
+
"@elliemae/ds-backdrop": "3.70.0-next.62",
|
|
45
|
+
"@elliemae/ds-basic": "3.70.0-next.62",
|
|
46
|
+
"@elliemae/ds-app-picker": "3.70.0-next.62",
|
|
47
|
+
"@elliemae/ds-card": "3.70.0-next.62",
|
|
48
|
+
"@elliemae/ds-button-v2": "3.70.0-next.62",
|
|
49
|
+
"@elliemae/ds-breadcrumb": "3.70.0-next.62",
|
|
50
|
+
"@elliemae/ds-card-v1": "3.70.0-next.62",
|
|
51
|
+
"@elliemae/ds-card-navigation": "3.70.0-next.62",
|
|
52
|
+
"@elliemae/ds-card-v1-detail": "3.70.0-next.62",
|
|
53
|
+
"@elliemae/ds-card-v2-action-addon": "3.70.0-next.62",
|
|
54
|
+
"@elliemae/ds-card-v2-group": "3.70.0-next.62",
|
|
55
|
+
"@elliemae/ds-card-v2": "3.70.0-next.62",
|
|
56
|
+
"@elliemae/ds-card-v3": "3.70.0-next.62",
|
|
57
|
+
"@elliemae/ds-chat": "3.70.0-next.62",
|
|
58
|
+
"@elliemae/ds-chat-bubble": "3.70.0-next.62",
|
|
59
|
+
"@elliemae/ds-card-v3-poc": "3.70.0-next.62",
|
|
60
|
+
"@elliemae/ds-chat-card": "3.70.0-next.62",
|
|
61
|
+
"@elliemae/ds-chat-container": "3.70.0-next.62",
|
|
62
|
+
"@elliemae/ds-chat-container-header": "3.70.0-next.62",
|
|
63
|
+
"@elliemae/ds-chat-floating-button": "3.70.0-next.62",
|
|
64
|
+
"@elliemae/ds-chat-empty-state": "3.70.0-next.62",
|
|
65
|
+
"@elliemae/ds-chat-sidebar": "3.70.0-next.62",
|
|
66
|
+
"@elliemae/ds-chat-message-delimeter": "3.70.0-next.62",
|
|
67
|
+
"@elliemae/ds-chat-system-message": "3.70.0-next.62",
|
|
68
|
+
"@elliemae/ds-chip": "3.70.0-next.62",
|
|
69
|
+
"@elliemae/ds-chat-tile": "3.70.0-next.62",
|
|
70
|
+
"@elliemae/ds-circular-progress-indicator": "3.70.0-next.62",
|
|
71
|
+
"@elliemae/ds-classnames": "3.70.0-next.62",
|
|
72
|
+
"@elliemae/ds-codeeditor": "3.70.0-next.62",
|
|
73
|
+
"@elliemae/ds-comments": "3.70.0-next.62",
|
|
74
|
+
"@elliemae/ds-controlled-form": "3.70.0-next.62",
|
|
75
|
+
"@elliemae/ds-csv-converter": "3.70.0-next.62",
|
|
76
|
+
"@elliemae/ds-data-table": "3.70.0-next.62",
|
|
77
|
+
"@elliemae/ds-data-table-action-cell": "3.70.0-next.62",
|
|
78
|
+
"@elliemae/ds-data-table-cell": "3.70.0-next.62",
|
|
79
|
+
"@elliemae/ds-data-table-cell-header": "3.70.0-next.62",
|
|
80
|
+
"@elliemae/ds-data-table-drag-and-drop-cell": "3.70.0-next.62",
|
|
81
|
+
"@elliemae/ds-data-table-filters": "3.70.0-next.62",
|
|
82
|
+
"@elliemae/ds-data-table-expand-cell": "3.70.0-next.62",
|
|
83
|
+
"@elliemae/ds-data-table-multi-select-cell": "3.70.0-next.62",
|
|
84
|
+
"@elliemae/ds-data-table-single-select-cell": "3.70.0-next.62",
|
|
85
|
+
"@elliemae/ds-dataviz": "3.70.0-next.62",
|
|
86
|
+
"@elliemae/ds-dataviz-pie": "3.70.0-next.62",
|
|
87
|
+
"@elliemae/ds-decision-graph": "3.70.0-next.62",
|
|
88
|
+
"@elliemae/ds-dropdownmenu-v2": "3.70.0-next.62",
|
|
89
|
+
"@elliemae/ds-date-time-picker": "3.70.0-next.62",
|
|
90
|
+
"@elliemae/ds-dropzone": "3.70.0-next.62",
|
|
91
|
+
"@elliemae/ds-drag-and-drop": "3.70.0-next.62",
|
|
92
|
+
"@elliemae/ds-filter-bar": "3.70.0-next.62",
|
|
93
|
+
"@elliemae/ds-dialog": "3.70.0-next.62",
|
|
94
|
+
"@elliemae/ds-fast-list": "3.70.0-next.62",
|
|
95
|
+
"@elliemae/ds-form-checkbox": "3.70.0-next.62",
|
|
96
|
+
"@elliemae/ds-floating-context": "3.70.0-next.62",
|
|
97
|
+
"@elliemae/ds-form-date-time-picker": "3.70.0-next.62",
|
|
98
|
+
"@elliemae/ds-form-helpers-mask-hooks": "3.70.0-next.62",
|
|
99
|
+
"@elliemae/ds-form-input-textarea": "3.70.0-next.62",
|
|
100
|
+
"@elliemae/ds-form-layout-autocomplete": "3.70.0-next.62",
|
|
101
|
+
"@elliemae/ds-form-date-range-picker": "3.70.0-next.62",
|
|
102
|
+
"@elliemae/ds-form-layout-label": "3.70.0-next.62",
|
|
103
|
+
"@elliemae/ds-form-multi-combobox": "3.70.0-next.62",
|
|
104
|
+
"@elliemae/ds-form-input-text": "3.70.0-next.62",
|
|
105
|
+
"@elliemae/ds-form-native-select": "3.70.0-next.62",
|
|
106
|
+
"@elliemae/ds-form-radio": "3.70.0-next.62",
|
|
107
|
+
"@elliemae/ds-form-select": "3.70.0-next.62",
|
|
108
|
+
"@elliemae/ds-form-layout-blocks": "3.70.0-next.62",
|
|
109
|
+
"@elliemae/ds-form-single-combobox": "3.70.0-next.62",
|
|
110
|
+
"@elliemae/ds-form-toggle": "3.70.0-next.62",
|
|
111
|
+
"@elliemae/ds-form-combobox": "3.70.0-next.62",
|
|
112
|
+
"@elliemae/ds-global-header": "3.70.0-next.62",
|
|
113
|
+
"@elliemae/ds-hooks-focus-stack": "3.70.0-next.62",
|
|
114
|
+
"@elliemae/ds-hooks-fontsize-detector": "3.70.0-next.62",
|
|
115
|
+
"@elliemae/ds-hooks-focus-trap": "3.70.0-next.62",
|
|
116
|
+
"@elliemae/ds-hooks-fontsize-media": "3.70.0-next.62",
|
|
117
|
+
"@elliemae/ds-hooks-headless-tooltip": "3.70.0-next.62",
|
|
118
|
+
"@elliemae/ds-grid": "3.70.0-next.62",
|
|
119
|
+
"@elliemae/ds-hooks-is-showing-ellipsis": "3.70.0-next.62",
|
|
120
|
+
"@elliemae/ds-hooks-on-first-focus-in": "3.70.0-next.62",
|
|
121
|
+
"@elliemae/ds-icon": "3.70.0-next.62",
|
|
122
|
+
"@elliemae/ds-hooks-is-mobile": "3.70.0-next.62",
|
|
123
|
+
"@elliemae/ds-hooks-keyboard-navigation": "3.70.0-next.62",
|
|
124
|
+
"@elliemae/ds-image": "3.70.0-next.62",
|
|
125
|
+
"@elliemae/ds-layout-provider": "3.70.0-next.62",
|
|
126
|
+
"@elliemae/ds-left-navigation": "3.70.0-next.62",
|
|
127
|
+
"@elliemae/ds-icons": "3.70.0-next.62",
|
|
128
|
+
"@elliemae/ds-loading-indicator": "3.70.0-next.62",
|
|
129
|
+
"@elliemae/ds-hooks-on-blur-out": "3.70.0-next.62",
|
|
130
|
+
"@elliemae/ds-menu-items-action": "3.70.0-next.62",
|
|
131
|
+
"@elliemae/ds-menu-items": "3.70.0-next.62",
|
|
132
|
+
"@elliemae/ds-imagelibrarymodal": "3.70.0-next.62",
|
|
133
|
+
"@elliemae/ds-form-layout-input-group": "3.70.0-next.62",
|
|
134
|
+
"@elliemae/ds-menu-button": "3.70.0-next.62",
|
|
135
|
+
"@elliemae/ds-menu-items-commons": "3.70.0-next.62",
|
|
136
|
+
"@elliemae/ds-menu-items-section": "3.70.0-next.62",
|
|
137
|
+
"@elliemae/ds-menu-items-multi": "3.70.0-next.62",
|
|
138
|
+
"@elliemae/ds-menu-items-separator": "3.70.0-next.62",
|
|
139
|
+
"@elliemae/ds-menu-items-single": "3.70.0-next.62",
|
|
140
|
+
"@elliemae/ds-indeterminate-progress-indicator": "3.70.0-next.62",
|
|
141
|
+
"@elliemae/ds-modal-slide": "3.70.0-next.62",
|
|
142
|
+
"@elliemae/ds-menu-items-single-with-submenu": "3.70.0-next.62",
|
|
143
|
+
"@elliemae/ds-menu-tree-item": "3.70.0-next.62",
|
|
144
|
+
"@elliemae/ds-menu-items-submenu": "3.70.0-next.62",
|
|
145
|
+
"@elliemae/ds-mobile": "3.70.0-next.62",
|
|
146
|
+
"@elliemae/ds-notification-badge": "3.70.0-next.62",
|
|
147
|
+
"@elliemae/ds-overlay": "3.70.0-next.62",
|
|
148
|
+
"@elliemae/ds-page-header-v1": "3.70.0-next.62",
|
|
149
|
+
"@elliemae/ds-page-header-v2": "3.70.0-next.62",
|
|
150
|
+
"@elliemae/ds-page-layout": "3.70.0-next.62",
|
|
151
|
+
"@elliemae/ds-page-header": "3.70.0-next.62",
|
|
152
|
+
"@elliemae/ds-portal": "3.70.0-next.62",
|
|
153
|
+
"@elliemae/ds-progress-indicator": "3.70.0-next.62",
|
|
154
|
+
"@elliemae/ds-pagination": "3.70.0-next.62",
|
|
155
|
+
"@elliemae/ds-query-builder": "3.70.0-next.62",
|
|
156
|
+
"@elliemae/ds-read-more": "3.70.0-next.62",
|
|
157
|
+
"@elliemae/ds-pills-v2": "3.70.0-next.62",
|
|
158
|
+
"@elliemae/ds-props-helpers": "3.70.0-next.62",
|
|
159
|
+
"@elliemae/ds-ribbon": "3.70.0-next.62",
|
|
160
|
+
"@elliemae/ds-resizeable-container": "3.70.0-next.62",
|
|
161
|
+
"@elliemae/ds-shared": "3.70.0-next.62",
|
|
162
|
+
"@elliemae/ds-scrollable-container": "3.70.0-next.62",
|
|
163
|
+
"@elliemae/ds-separator": "3.70.0-next.62",
|
|
164
|
+
"@elliemae/ds-side-panel": "3.70.0-next.62",
|
|
165
|
+
"@elliemae/ds-shuttle-v2": "3.70.0-next.62",
|
|
166
|
+
"@elliemae/ds-side-panel-header": "3.70.0-next.62",
|
|
167
|
+
"@elliemae/ds-menu-items-skeleton": "3.70.0-next.62",
|
|
168
|
+
"@elliemae/ds-square-indicator": "3.70.0-next.62",
|
|
169
|
+
"@elliemae/ds-slider-v2": "3.70.0-next.62",
|
|
170
|
+
"@elliemae/ds-skeleton": "3.70.0-next.62",
|
|
171
|
+
"@elliemae/ds-stepper": "3.70.0-next.62",
|
|
172
|
+
"@elliemae/ds-svg": "3.70.0-next.62",
|
|
173
|
+
"@elliemae/ds-tabs": "3.70.0-next.62",
|
|
174
|
+
"@elliemae/ds-test-utils": "3.70.0-next.62",
|
|
175
|
+
"@elliemae/ds-toolbar-v1": "3.70.0-next.62",
|
|
176
|
+
"@elliemae/ds-toast": "3.70.0-next.62",
|
|
177
|
+
"@elliemae/ds-system": "3.70.0-next.62",
|
|
178
|
+
"@elliemae/ds-toolbar-v2": "3.70.0-next.62",
|
|
179
|
+
"@elliemae/ds-tooltip-v3": "3.70.0-next.62",
|
|
180
|
+
"@elliemae/ds-transition": "3.70.0-next.62",
|
|
181
|
+
"@elliemae/ds-tree-model": "3.70.0-next.62",
|
|
182
|
+
"@elliemae/ds-treeview": "3.70.0-next.62",
|
|
183
|
+
"@elliemae/ds-typography": "3.70.0-next.62",
|
|
184
|
+
"@elliemae/ds-typescript-helpers": "3.70.0-next.62",
|
|
185
|
+
"@elliemae/ds-wizard": "3.70.0-next.62",
|
|
186
|
+
"@elliemae/ds-virtual-list": "3.70.0-next.62",
|
|
187
|
+
"@elliemae/ds-zustand-helpers": "3.70.0-next.62",
|
|
188
|
+
"@elliemae/ds-truncated-expandable-text": "3.70.0-next.62"
|
|
189
189
|
},
|
|
190
190
|
"publishConfig": {
|
|
191
191
|
"access": "public"
|
package/paths.js
CHANGED
|
@@ -347,6 +347,7 @@ export const PATH_E2E_SQUARE_INDICATOR = `${PATH_E2E}/SquareIndicator`;
|
|
|
347
347
|
export const PATH_E2E_CONTROLLEDLARGEINPUT = `${PATH_E2E}/ControlledLargeInputText`;
|
|
348
348
|
export const PATH_E2E_CONTROLLEDINPUT = `${PATH_E2E}/ControlledInputText`;
|
|
349
349
|
export const PATH_E2E_CHECKBOX = `${PATH_E2E}/Checkbox`;
|
|
350
|
+
export const PATH_E2E_CHECKBOX_SLOTS = `${PATH_E2E_CHECKBOX}/Slots`;
|
|
350
351
|
export const PATH_E2E_BUTTON_V2 = `${PATH_E2E}/ButtonV2`;
|
|
351
352
|
export const PATH_E2E_BUTTON_V3 = `${PATH_E2E}/ButtonV3`;
|
|
352
353
|
export const PATH_E2E_DDMENU_V2 = `${PATH_E2E}/DropDownMenuV2`;
|
|
@@ -370,6 +371,7 @@ export const PATH_E2E_DATAVIZ_SCROLL = `${PATH_E2E_DATAVIZ}/Scroll`;
|
|
|
370
371
|
export const PATH_E2E_DATAVIZ_SINGLESTACKED = `${PATH_E2E_DATAVIZ}/Single Stacked Bar`;
|
|
371
372
|
export const PATH_E2E_AUTOCOMPLETE = `${PATH_E2E}/Autocomplete`;
|
|
372
373
|
export const PATH_E2E_RADIO = `${PATH_E2E}/Radio`;
|
|
374
|
+
export const PATH_E2E_RADIO_SLOTS = `${PATH_E2E_RADIO}/Slots`;
|
|
373
375
|
export const PATH_E2E_RADIO_GROUP = `${PATH_E2E}/RadioGroup`;
|
|
374
376
|
export const PATH_E2E_SVG = `${PATH_E2E}/Svg`;
|
|
375
377
|
export const PATH_E2E_IMAGE = `${PATH_E2E}/Image`;
|