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 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 $(`#app-picker__button`);
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
  }
@@ -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 changed from <input type="range" aria-label="Resize column"> to a
55
- // <button role="application" aria-labelledby> with dynamic "Resize {column} column" naming; the old
56
- // selector never matched data-testid="column" (unverified in d2) and stopped matching aria-label after
57
- // that fix.
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
- * Text of the node the resizer's aria-labelledby points at. This is a WIRING check only it
88
- * proves the reference resolves to the intended span, NOT that the browser computes a name from
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
- describe('PUI-18881 - DSDataTable:: filter search input mouse caret and selection - Func', () => {
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
- // SKIPPED reported as PUI-18885, awaiting the dev team's decision. Since PUI-18812 made the
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
- // Name is wired through aria-labelledby -> a hidden span, not aria-label. A native input has no
51
- // textContent of its own, so that wiring is the only possible name source (regression guard).
52
- // This asserts the REFERENCE resolves to the right span; whether the browser actually computes
53
- // a name from it is asserted in test 02, where the handle is exposed to the accessibility tree.
54
- // It cannot be asserted here: at rest the handle is aria-hidden, so it has no computed name by
55
- // design and a computed-name check would fail for the wrong reason.
56
- expect(await resizer.getAttribute('aria-label')).toBe(null);
57
- const labelledByText = await HeaderCO.getResizerLabelledByText(resizer);
58
- expect(labelledByText).toContain('Resize Name column');
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: the name span is display:none, and
78
- // reading its textContent (test 01) passes even if the accname algorithm resolves to nothing.
79
- // A focused control with no computed name is a WCAG 4.1.2 failure, so it is asserted against
80
- // the browser's own computation via WebDriver's Get Computed Label, not re-derived from the DOM.
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.60",
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.60",
42
- "@elliemae/ds-accordion": "3.70.0-next.60",
43
- "@elliemae/ds-backdrop": "3.70.0-next.60",
44
- "@elliemae/ds-app-picker": "3.70.0-next.60",
45
- "@elliemae/ds-banner": "3.70.0-next.60",
46
- "@elliemae/ds-basic": "3.70.0-next.60",
47
- "@elliemae/ds-breadcrumb": "3.70.0-next.60",
48
- "@elliemae/ds-card-navigation": "3.70.0-next.60",
49
- "@elliemae/ds-card": "3.70.0-next.60",
50
- "@elliemae/ds-button-v2": "3.70.0-next.60",
51
- "@elliemae/ds-card-v1": "3.70.0-next.60",
52
- "@elliemae/ds-card-v1-detail": "3.70.0-next.60",
53
- "@elliemae/ds-card-v2": "3.70.0-next.60",
54
- "@elliemae/ds-card-v2-group": "3.70.0-next.60",
55
- "@elliemae/ds-card-v3": "3.70.0-next.60",
56
- "@elliemae/ds-card-v2-action-addon": "3.70.0-next.60",
57
- "@elliemae/ds-chat": "3.70.0-next.60",
58
- "@elliemae/ds-chat-bubble": "3.70.0-next.60",
59
- "@elliemae/ds-chat-card": "3.70.0-next.60",
60
- "@elliemae/ds-chat-container": "3.70.0-next.60",
61
- "@elliemae/ds-chat-empty-state": "3.70.0-next.60",
62
- "@elliemae/ds-chat-container-header": "3.70.0-next.60",
63
- "@elliemae/ds-chat-floating-button": "3.70.0-next.60",
64
- "@elliemae/ds-chat-message-delimeter": "3.70.0-next.60",
65
- "@elliemae/ds-chat-sidebar": "3.70.0-next.60",
66
- "@elliemae/ds-card-v3-poc": "3.70.0-next.60",
67
- "@elliemae/ds-chat-tile": "3.70.0-next.60",
68
- "@elliemae/ds-circular-progress-indicator": "3.70.0-next.60",
69
- "@elliemae/ds-classnames": "3.70.0-next.60",
70
- "@elliemae/ds-codeeditor": "3.70.0-next.60",
71
- "@elliemae/ds-chip": "3.70.0-next.60",
72
- "@elliemae/ds-comments": "3.70.0-next.60",
73
- "@elliemae/ds-controlled-form": "3.70.0-next.60",
74
- "@elliemae/ds-csv-converter": "3.70.0-next.60",
75
- "@elliemae/ds-data-table": "3.70.0-next.60",
76
- "@elliemae/ds-data-table-cell": "3.70.0-next.60",
77
- "@elliemae/ds-data-table-drag-and-drop-cell": "3.70.0-next.60",
78
- "@elliemae/ds-data-table-cell-header": "3.70.0-next.60",
79
- "@elliemae/ds-data-table-action-cell": "3.70.0-next.60",
80
- "@elliemae/ds-data-table-expand-cell": "3.70.0-next.60",
81
- "@elliemae/ds-data-table-multi-select-cell": "3.70.0-next.60",
82
- "@elliemae/ds-data-table-filters": "3.70.0-next.60",
83
- "@elliemae/ds-data-table-single-select-cell": "3.70.0-next.60",
84
- "@elliemae/ds-dataviz": "3.70.0-next.60",
85
- "@elliemae/ds-dataviz-pie": "3.70.0-next.60",
86
- "@elliemae/ds-date-time-picker": "3.70.0-next.60",
87
- "@elliemae/ds-decision-graph": "3.70.0-next.60",
88
- "@elliemae/ds-dropdownmenu-v2": "3.70.0-next.60",
89
- "@elliemae/ds-dialog": "3.70.0-next.60",
90
- "@elliemae/ds-dropzone": "3.70.0-next.60",
91
- "@elliemae/ds-floating-context": "3.70.0-next.60",
92
- "@elliemae/ds-fast-list": "3.70.0-next.60",
93
- "@elliemae/ds-filter-bar": "3.70.0-next.60",
94
- "@elliemae/ds-form-checkbox": "3.70.0-next.60",
95
- "@elliemae/ds-form-date-time-picker": "3.70.0-next.60",
96
- "@elliemae/ds-form-date-range-picker": "3.70.0-next.60",
97
- "@elliemae/ds-form-combobox": "3.70.0-next.60",
98
- "@elliemae/ds-form-input-text": "3.70.0-next.60",
99
- "@elliemae/ds-form-layout-autocomplete": "3.70.0-next.60",
100
- "@elliemae/ds-form-input-textarea": "3.70.0-next.60",
101
- "@elliemae/ds-form-layout-input-group": "3.70.0-next.60",
102
- "@elliemae/ds-form-layout-blocks": "3.70.0-next.60",
103
- "@elliemae/ds-form-helpers-mask-hooks": "3.70.0-next.60",
104
- "@elliemae/ds-form-multi-combobox": "3.70.0-next.60",
105
- "@elliemae/ds-form-radio": "3.70.0-next.60",
106
- "@elliemae/ds-form-layout-label": "3.70.0-next.60",
107
- "@elliemae/ds-form-native-select": "3.70.0-next.60",
108
- "@elliemae/ds-form-toggle": "3.70.0-next.60",
109
- "@elliemae/ds-form-single-combobox": "3.70.0-next.60",
110
- "@elliemae/ds-form-select": "3.70.0-next.60",
111
- "@elliemae/ds-hooks-focus-trap": "3.70.0-next.60",
112
- "@elliemae/ds-global-header": "3.70.0-next.60",
113
- "@elliemae/ds-hooks-fontsize-detector": "3.70.0-next.60",
114
- "@elliemae/ds-hooks-fontsize-media": "3.70.0-next.60",
115
- "@elliemae/ds-hooks-headless-tooltip": "3.70.0-next.60",
116
- "@elliemae/ds-hooks-is-mobile": "3.70.0-next.60",
117
- "@elliemae/ds-hooks-on-first-focus-in": "3.70.0-next.60",
118
- "@elliemae/ds-hooks-is-showing-ellipsis": "3.70.0-next.60",
119
- "@elliemae/ds-grid": "3.70.0-next.60",
120
- "@elliemae/ds-hooks-keyboard-navigation": "3.70.0-next.60",
121
- "@elliemae/ds-hooks-on-blur-out": "3.70.0-next.60",
122
- "@elliemae/ds-icon": "3.70.0-next.60",
123
- "@elliemae/ds-image": "3.70.0-next.60",
124
- "@elliemae/ds-indeterminate-progress-indicator": "3.70.0-next.60",
125
- "@elliemae/ds-imagelibrarymodal": "3.70.0-next.60",
126
- "@elliemae/ds-icons": "3.70.0-next.60",
127
- "@elliemae/ds-menu-button": "3.70.0-next.60",
128
- "@elliemae/ds-loading-indicator": "3.70.0-next.60",
129
- "@elliemae/ds-left-navigation": "3.70.0-next.60",
130
- "@elliemae/ds-menu-items-commons": "3.70.0-next.60",
131
- "@elliemae/ds-menu-items-action": "3.70.0-next.60",
132
- "@elliemae/ds-menu-items": "3.70.0-next.60",
133
- "@elliemae/ds-hooks-focus-stack": "3.70.0-next.60",
134
- "@elliemae/ds-menu-items-multi": "3.70.0-next.60",
135
- "@elliemae/ds-menu-items-separator": "3.70.0-next.60",
136
- "@elliemae/ds-layout-provider": "3.70.0-next.60",
137
- "@elliemae/ds-menu-items-section": "3.70.0-next.60",
138
- "@elliemae/ds-menu-tree-item": "3.70.0-next.60",
139
- "@elliemae/ds-menu-items-single": "3.70.0-next.60",
140
- "@elliemae/ds-menu-items-skeleton": "3.70.0-next.60",
141
- "@elliemae/ds-menu-items-submenu": "3.70.0-next.60",
142
- "@elliemae/ds-mobile": "3.70.0-next.60",
143
- "@elliemae/ds-modal-slide": "3.70.0-next.60",
144
- "@elliemae/ds-menu-items-single-with-submenu": "3.70.0-next.60",
145
- "@elliemae/ds-notification-badge": "3.70.0-next.60",
146
- "@elliemae/ds-overlay": "3.70.0-next.60",
147
- "@elliemae/ds-page-header": "3.70.0-next.60",
148
- "@elliemae/ds-page-header-v1": "3.70.0-next.60",
149
- "@elliemae/ds-page-header-v2": "3.70.0-next.60",
150
- "@elliemae/ds-portal": "3.70.0-next.60",
151
- "@elliemae/ds-pagination": "3.70.0-next.60",
152
- "@elliemae/ds-page-layout": "3.70.0-next.60",
153
- "@elliemae/ds-drag-and-drop": "3.70.0-next.60",
154
- "@elliemae/ds-progress-indicator": "3.70.0-next.60",
155
- "@elliemae/ds-props-helpers": "3.70.0-next.60",
156
- "@elliemae/ds-read-more": "3.70.0-next.60",
157
- "@elliemae/ds-query-builder": "3.70.0-next.60",
158
- "@elliemae/ds-resizeable-container": "3.70.0-next.60",
159
- "@elliemae/ds-separator": "3.70.0-next.60",
160
- "@elliemae/ds-ribbon": "3.70.0-next.60",
161
- "@elliemae/ds-chat-system-message": "3.70.0-next.60",
162
- "@elliemae/ds-scrollable-container": "3.70.0-next.60",
163
- "@elliemae/ds-shared": "3.70.0-next.60",
164
- "@elliemae/ds-shuttle-v2": "3.70.0-next.60",
165
- "@elliemae/ds-side-panel-header": "3.70.0-next.60",
166
- "@elliemae/ds-side-panel": "3.70.0-next.60",
167
- "@elliemae/ds-square-indicator": "3.70.0-next.60",
168
- "@elliemae/ds-slider-v2": "3.70.0-next.60",
169
- "@elliemae/ds-skeleton": "3.70.0-next.60",
170
- "@elliemae/ds-stepper": "3.70.0-next.60",
171
- "@elliemae/ds-svg": "3.70.0-next.60",
172
- "@elliemae/ds-system": "3.70.0-next.60",
173
- "@elliemae/ds-tabs": "3.70.0-next.60",
174
- "@elliemae/ds-test-utils": "3.70.0-next.60",
175
- "@elliemae/ds-toast": "3.70.0-next.60",
176
- "@elliemae/ds-toolbar-v1": "3.70.0-next.60",
177
- "@elliemae/ds-toolbar-v2": "3.70.0-next.60",
178
- "@elliemae/ds-tooltip-v3": "3.70.0-next.60",
179
- "@elliemae/ds-transition": "3.70.0-next.60",
180
- "@elliemae/ds-treeview": "3.70.0-next.60",
181
- "@elliemae/ds-tree-model": "3.70.0-next.60",
182
- "@elliemae/ds-truncated-expandable-text": "3.70.0-next.60",
183
- "@elliemae/ds-typescript-helpers": "3.70.0-next.60",
184
- "@elliemae/ds-virtual-list": "3.70.0-next.60",
185
- "@elliemae/ds-zustand-helpers": "3.70.0-next.60",
186
- "@elliemae/ds-typography": "3.70.0-next.60",
187
- "@elliemae/ds-wizard": "3.70.0-next.60",
188
- "@elliemae/ds-pills-v2": "3.70.0-next.60"
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`;