@sapudex/web-components 2.33.0 → 2.35.0
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/cypress/specs/FilterMenu.cy.tsx +53 -0
- package/cypress/specs/ListItem.cy.tsx +73 -21
- package/cypress/specs/MastheadMenu.cy.tsx +645 -0
- package/cypress/specs/MastheadMobileMenu.cy.tsx +573 -0
- package/cypress/specs/MastheadShell.cy.tsx +79 -0
- package/cypress/specs/SecondaryNavigationDesktop.cy.tsx +14 -0
- package/cypress/specs/SelectBox.cy.tsx +229 -1
- package/cypress/support/component-imports.instrumented.ts +2 -0
- package/cypress/support/component-imports.src.ts +2 -0
- package/dist/CountrySelector.d.ts +1 -0
- package/dist/CountrySelector.js +3 -0
- package/dist/CountrySelector.js.map +1 -1
- package/dist/FilterMenu.d.ts +1 -0
- package/dist/FilterMenu.js +3 -0
- package/dist/FilterMenu.js.map +1 -1
- package/dist/ListItem.d.ts +3 -0
- package/dist/ListItem.js +10 -1
- package/dist/ListItem.js.map +1 -1
- package/dist/ListItemBase.d.ts +31 -0
- package/dist/ListItemBase.js +28 -0
- package/dist/ListItemBase.js.map +1 -1
- package/dist/MastheadItem.d.ts +12 -1
- package/dist/MastheadItem.js +33 -1
- package/dist/MastheadItem.js.map +1 -1
- package/dist/MastheadMenu.d.ts +5 -1
- package/dist/MastheadMenu.js +16 -6
- package/dist/MastheadMenu.js.map +1 -1
- package/dist/SearchableListBase.d.ts +3 -1
- package/dist/SearchableListBase.js +7 -1
- package/dist/SearchableListBase.js.map +1 -1
- package/dist/SecondaryNavigationItem.d.ts +5 -1
- package/dist/SecondaryNavigationItem.js +35 -5
- package/dist/SecondaryNavigationItem.js.map +1 -1
- package/dist/SelectBase.js +14 -3
- package/dist/SelectBase.js.map +1 -1
- package/dist/SelectBox.d.ts +1 -0
- package/dist/SelectBox.js +3 -0
- package/dist/SelectBox.js.map +1 -1
- package/dist/assets/{InputSuggestions-B_Dl2L6w.js → InputSuggestions-CrSNIz-l.js} +1 -1
- package/dist/assets/{ListItemStandardExpandableTextTemplate-9Z-aZmJx.js → ListItemStandardExpandableTextTemplate-BUgxFxi7.js} +1 -1
- package/dist/assets/{bundle-DbTEs-Za.css → bundle-JYo3bV8v.css} +1 -1
- package/dist/assets/{bundle.esm-BlIxH9k1.js → bundle.esm-BZJm6rNI.js} +633 -219
- package/dist/css/themes/Breadcrumbs.css +1 -1
- package/dist/css/themes/BreadcrumbsPopover.css +1 -1
- package/dist/css/themes/FilterMenu.css +1 -1
- package/dist/css/themes/ListGroupHeader.css +1 -1
- package/dist/css/themes/ListItem.css +1 -1
- package/dist/css/themes/MastheadItem.css +1 -1
- package/dist/css/themes/MastheadMenu.css +1 -1
- package/dist/css/themes/MastheadMobileMenu.css +1 -1
- package/dist/css/themes/RatingIndicator.css +1 -1
- package/dist/css/themes/SearchableList.css +1 -1
- package/dist/css/themes/SecondaryNavigation.css +1 -1
- package/dist/css/themes/SecondaryNavigationItem.css +1 -1
- package/dist/css/themes/SelectBase.css +1 -1
- package/dist/css/themes/Slider.css +1 -1
- package/dist/custom-elements-internal.json +1125 -35
- package/dist/custom-elements.json +1126 -36
- package/dist/generated/templates/ListGroupHeaderTemplate.lit.js +16 -12
- package/dist/generated/templates/ListGroupHeaderTemplate.lit.js.map +1 -1
- package/dist/generated/templates/ListItemTemplate.lit.js +40 -32
- package/dist/generated/templates/ListItemTemplate.lit.js.map +1 -1
- package/dist/generated/templates/MastheadItemTemplate.lit.js +2 -2
- package/dist/generated/templates/MastheadItemTemplate.lit.js.map +1 -1
- package/dist/generated/templates/MastheadMenuTemplate.lit.js +8 -1
- package/dist/generated/templates/MastheadMenuTemplate.lit.js.map +1 -1
- package/dist/generated/templates/MastheadMobileMenuTemplate.lit.js +10 -4
- package/dist/generated/templates/MastheadMobileMenuTemplate.lit.js.map +1 -1
- package/dist/generated/templates/MastheadShellTemplate.lit.js +3 -3
- package/dist/generated/templates/MastheadShellTemplate.lit.js.map +1 -1
- package/dist/generated/templates/SearchableListBaseTemplate.lit.js +4 -4
- package/dist/generated/templates/SearchableListBaseTemplate.lit.js.map +1 -1
- package/dist/generated/templates/SelectBoxTemplate.lit.js +12 -10
- package/dist/generated/templates/SelectBoxTemplate.lit.js.map +1 -1
- package/dist/generated/themes/Breadcrumbs.css.d.ts +1 -1
- package/dist/generated/themes/Breadcrumbs.css.js +1 -1
- package/dist/generated/themes/Breadcrumbs.css.js.map +1 -1
- package/dist/generated/themes/BreadcrumbsPopover.css.d.ts +1 -1
- package/dist/generated/themes/BreadcrumbsPopover.css.js +1 -1
- package/dist/generated/themes/BreadcrumbsPopover.css.js.map +1 -1
- package/dist/generated/themes/FilterMenu.css.d.ts +1 -1
- package/dist/generated/themes/FilterMenu.css.js +1 -1
- package/dist/generated/themes/FilterMenu.css.js.map +1 -1
- package/dist/generated/themes/ListGroupHeader.css.d.ts +1 -1
- package/dist/generated/themes/ListGroupHeader.css.js +1 -1
- package/dist/generated/themes/ListGroupHeader.css.js.map +1 -1
- package/dist/generated/themes/ListItem.css.d.ts +1 -1
- package/dist/generated/themes/ListItem.css.js +1 -1
- package/dist/generated/themes/ListItem.css.js.map +1 -1
- package/dist/generated/themes/MastheadItem.css.d.ts +1 -1
- package/dist/generated/themes/MastheadItem.css.js +1 -1
- package/dist/generated/themes/MastheadItem.css.js.map +1 -1
- package/dist/generated/themes/MastheadMenu.css.d.ts +1 -1
- package/dist/generated/themes/MastheadMenu.css.js +1 -1
- package/dist/generated/themes/MastheadMenu.css.js.map +1 -1
- package/dist/generated/themes/MastheadMobileMenu.css.d.ts +1 -1
- package/dist/generated/themes/MastheadMobileMenu.css.js +1 -1
- package/dist/generated/themes/MastheadMobileMenu.css.js.map +1 -1
- package/dist/generated/themes/RatingIndicator.css.d.ts +1 -1
- package/dist/generated/themes/RatingIndicator.css.js +1 -1
- package/dist/generated/themes/RatingIndicator.css.js.map +1 -1
- package/dist/generated/themes/SearchableList.css.d.ts +1 -1
- package/dist/generated/themes/SearchableList.css.js +1 -1
- package/dist/generated/themes/SearchableList.css.js.map +1 -1
- package/dist/generated/themes/SecondaryNavigation.css.d.ts +1 -1
- package/dist/generated/themes/SecondaryNavigation.css.js +1 -1
- package/dist/generated/themes/SecondaryNavigation.css.js.map +1 -1
- package/dist/generated/themes/SecondaryNavigationItem.css.d.ts +1 -1
- package/dist/generated/themes/SecondaryNavigationItem.css.js +1 -1
- package/dist/generated/themes/SecondaryNavigationItem.css.js.map +1 -1
- package/dist/generated/themes/SelectBase.css.d.ts +1 -1
- package/dist/generated/themes/SelectBase.css.js +1 -1
- package/dist/generated/themes/SelectBase.css.js.map +1 -1
- package/dist/generated/themes/Slider.css.d.ts +1 -1
- package/dist/generated/themes/Slider.css.js +1 -1
- package/dist/generated/themes/Slider.css.js.map +1 -1
- package/dist/types/List.d.ts +2 -0
- package/dist/types/List.js +2 -0
- package/dist/types/List.js.map +1 -1
- package/dist/vscode.html-custom-data.json +292 -12
- package/dist/web-types.json +431 -21
- package/package.json +1 -1
- package/src/CountrySelector.ts +3 -0
- package/src/FilterMenu.ts +3 -0
- package/src/ListGroupHeader.hbs +11 -7
- package/src/ListItem.hbs +28 -2
- package/src/ListItem.ts +12 -1
- package/src/ListItemBase.ts +48 -0
- package/src/MastheadItem.hbs +2 -0
- package/src/MastheadItem.ts +37 -2
- package/src/MastheadMenu.hbs +35 -0
- package/src/MastheadMenu.ts +21 -7
- package/src/MastheadMobileMenu.hbs +40 -9
- package/src/MastheadShell.hbs +3 -0
- package/src/SearchableListBase.hbs +21 -1
- package/src/SearchableListBase.ts +11 -2
- package/src/SecondaryNavigationItem.ts +37 -5
- package/src/SelectBase.ts +15 -3
- package/src/SelectBox.hbs +13 -5
- package/src/SelectBox.ts +3 -0
- package/src/generated/templates/ListGroupHeaderTemplate.lit.ts +16 -12
- package/src/generated/templates/ListItemTemplate.lit.ts +40 -32
- package/src/generated/templates/MastheadItemTemplate.lit.ts +2 -2
- package/src/generated/templates/MastheadMenuTemplate.lit.ts +8 -1
- package/src/generated/templates/MastheadMobileMenuTemplate.lit.ts +10 -4
- package/src/generated/templates/MastheadShellTemplate.lit.ts +3 -3
- package/src/generated/templates/SearchableListBaseTemplate.lit.ts +4 -4
- package/src/generated/templates/SelectBoxTemplate.lit.ts +12 -10
- package/src/generated/themes/Breadcrumbs.css.ts +1 -1
- package/src/generated/themes/BreadcrumbsPopover.css.ts +1 -1
- package/src/generated/themes/FilterMenu.css.ts +1 -1
- package/src/generated/themes/ListGroupHeader.css.ts +1 -1
- package/src/generated/themes/ListItem.css.ts +1 -1
- package/src/generated/themes/MastheadItem.css.ts +1 -1
- package/src/generated/themes/MastheadMenu.css.ts +1 -1
- package/src/generated/themes/MastheadMobileMenu.css.ts +1 -1
- package/src/generated/themes/RatingIndicator.css.ts +1 -1
- package/src/generated/themes/SearchableList.css.ts +1 -1
- package/src/generated/themes/SecondaryNavigation.css.ts +1 -1
- package/src/generated/themes/SecondaryNavigationItem.css.ts +1 -1
- package/src/generated/themes/SelectBase.css.ts +1 -1
- package/src/generated/themes/Slider.css.ts +1 -1
- package/src/themes/Breadcrumbs.css +16 -2
- package/src/themes/BreadcrumbsPopover.css +18 -3
- package/src/themes/FilterMenu.css +4 -9
- package/src/themes/ListGroupHeader.css +11 -0
- package/src/themes/ListItem.css +6 -4
- package/src/themes/MastheadItem.css +41 -9
- package/src/themes/MastheadMenu.css +45 -0
- package/src/themes/MastheadMobileMenu.css +45 -0
- package/src/themes/SearchableList.css +18 -3
- package/src/themes/SecondaryNavigation.css +1 -1
- package/src/themes/SecondaryNavigationItem.css +5 -2
- package/src/themes/SelectBase.css +0 -9
- package/src/types/List.ts +2 -0
|
@@ -0,0 +1,645 @@
|
|
|
1
|
+
import { UDExMastheadMenu } from "../support/component-imports.js";
|
|
2
|
+
|
|
3
|
+
// Fixture: items with 3rd-level sub-items (no url on parent items — sub-category renders as <span>)
|
|
4
|
+
const itemsWithSubItems = [
|
|
5
|
+
{
|
|
6
|
+
subMenuLinkItems: [
|
|
7
|
+
{
|
|
8
|
+
category: "Products",
|
|
9
|
+
url: "https://example.com/products",
|
|
10
|
+
items: [
|
|
11
|
+
{
|
|
12
|
+
title: "Cloud Solutions",
|
|
13
|
+
subItems: [
|
|
14
|
+
{
|
|
15
|
+
title: "SAP S/4HANA Cloud",
|
|
16
|
+
url: "https://example.com/s4hana",
|
|
17
|
+
externalLink: false,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
title: "SAP BTP",
|
|
21
|
+
url: "https://example.com/btp",
|
|
22
|
+
externalLink: false,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
title: "On-Premise Solutions",
|
|
28
|
+
subItems: [
|
|
29
|
+
{
|
|
30
|
+
title: "SAP ERP",
|
|
31
|
+
url: "https://example.com/erp",
|
|
32
|
+
externalLink: false,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
// Fixture: items with 3rd-level sub-items AND url on the parent item — sub-category renders as <udex-masthead-menu-item> link
|
|
43
|
+
const itemsWithLinkedSubCategory = [
|
|
44
|
+
{
|
|
45
|
+
subMenuLinkItems: [
|
|
46
|
+
{
|
|
47
|
+
category: "AI Platform",
|
|
48
|
+
items: [
|
|
49
|
+
{
|
|
50
|
+
title: "Build",
|
|
51
|
+
url: "https://example.com/build",
|
|
52
|
+
externalLink: false,
|
|
53
|
+
subItems: [
|
|
54
|
+
{
|
|
55
|
+
title: "Develop",
|
|
56
|
+
url: "https://example.com/develop",
|
|
57
|
+
externalLink: false,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
title: "Deploy",
|
|
61
|
+
url: "https://example.com/deploy",
|
|
62
|
+
externalLink: false,
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
title: "Run",
|
|
68
|
+
url: "https://example.com/run",
|
|
69
|
+
externalLink: false,
|
|
70
|
+
subItems: [
|
|
71
|
+
{
|
|
72
|
+
title: "Monitor",
|
|
73
|
+
url: "https://example.com/monitor",
|
|
74
|
+
externalLink: false,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
// Fixture: mixed linked and non-linked sub-categories within the same list
|
|
85
|
+
const mixedLinkedSubCategories = [
|
|
86
|
+
{
|
|
87
|
+
subMenuLinkItems: [
|
|
88
|
+
{
|
|
89
|
+
category: "Platform",
|
|
90
|
+
items: [
|
|
91
|
+
{
|
|
92
|
+
title: "Build",
|
|
93
|
+
url: "https://example.com/build",
|
|
94
|
+
externalLink: false,
|
|
95
|
+
subItems: [
|
|
96
|
+
{
|
|
97
|
+
title: "Develop",
|
|
98
|
+
url: "https://example.com/develop",
|
|
99
|
+
externalLink: false,
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
title: "Design",
|
|
105
|
+
// no url — renders as <span>
|
|
106
|
+
subItems: [
|
|
107
|
+
{
|
|
108
|
+
title: "Figma",
|
|
109
|
+
url: "https://example.com/figma",
|
|
110
|
+
externalLink: false,
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
// Fixture: items without sub-items (plain links only)
|
|
121
|
+
const itemsWithoutSubItems = [
|
|
122
|
+
{
|
|
123
|
+
subMenuLinkItems: [
|
|
124
|
+
{
|
|
125
|
+
category: "Services",
|
|
126
|
+
items: [
|
|
127
|
+
{
|
|
128
|
+
title: "Consulting",
|
|
129
|
+
url: "https://example.com/consulting",
|
|
130
|
+
externalLink: false,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
title: "Training",
|
|
134
|
+
url: "https://example.com/training",
|
|
135
|
+
externalLink: false,
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
// Fixture: mixed — one category with sub-items, another without
|
|
144
|
+
const mixedItems = [
|
|
145
|
+
{
|
|
146
|
+
subMenuLinkItems: [
|
|
147
|
+
{
|
|
148
|
+
category: "Solutions",
|
|
149
|
+
items: [
|
|
150
|
+
{
|
|
151
|
+
title: "Cloud Solutions",
|
|
152
|
+
subItems: [
|
|
153
|
+
{
|
|
154
|
+
title: "SAP S/4HANA Cloud",
|
|
155
|
+
url: "https://example.com/s4hana",
|
|
156
|
+
externalLink: false,
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
title: "Direct Link Item",
|
|
162
|
+
url: "https://example.com/direct",
|
|
163
|
+
externalLink: false,
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
describe("UDExMastheadMenu — 3rd-level navigation (sub-items)", () => {
|
|
172
|
+
describe("Rendering sub-categories", () => {
|
|
173
|
+
beforeEach(() => {
|
|
174
|
+
cy.mount(
|
|
175
|
+
<UDExMastheadMenu
|
|
176
|
+
id="menu-sub-items"
|
|
177
|
+
subItems={JSON.stringify(itemsWithSubItems)}
|
|
178
|
+
/>
|
|
179
|
+
);
|
|
180
|
+
cy.get("[udex-masthead-menu]").shadow().as("shadow");
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it("renders a .udex-masthead-menu__sub-category for each item with subItems", () => {
|
|
184
|
+
cy.get("@shadow")
|
|
185
|
+
.find(".udex-masthead-menu__sub-category")
|
|
186
|
+
.should("have.length", 2);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Updated: clarified that this covers the no-url case (item.url absent)
|
|
190
|
+
it("renders sub-category as a <span> when item has no url", () => {
|
|
191
|
+
cy.get("@shadow")
|
|
192
|
+
.find(".udex-masthead-menu__sub-category")
|
|
193
|
+
.first()
|
|
194
|
+
.should("have.prop", "tagName", "SPAN");
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("displays the correct title text in each sub-category", () => {
|
|
198
|
+
cy.get("@shadow")
|
|
199
|
+
.find(".udex-masthead-menu__sub-category")
|
|
200
|
+
.eq(0)
|
|
201
|
+
.should("have.text", "Cloud Solutions");
|
|
202
|
+
cy.get("@shadow")
|
|
203
|
+
.find(".udex-masthead-menu__sub-category")
|
|
204
|
+
.eq(1)
|
|
205
|
+
.should("have.text", "On-Premise Solutions");
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
describe("Rendering sub-list and sub-items", () => {
|
|
210
|
+
beforeEach(() => {
|
|
211
|
+
cy.mount(
|
|
212
|
+
<UDExMastheadMenu
|
|
213
|
+
id="menu-sub-items"
|
|
214
|
+
subItems={JSON.stringify(itemsWithSubItems)}
|
|
215
|
+
/>
|
|
216
|
+
);
|
|
217
|
+
cy.get("[udex-masthead-menu]").shadow().as("shadow");
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it("renders a .udex-masthead-menu__sub-list for each item with subItems", () => {
|
|
221
|
+
cy.get("@shadow")
|
|
222
|
+
.find(".udex-masthead-menu__sub-list")
|
|
223
|
+
.should("have.length", 2);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it("renders udex-masthead-menu-item elements inside each sub-list", () => {
|
|
227
|
+
// First sub-list: "Cloud Solutions" has 2 sub-items
|
|
228
|
+
cy.get("@shadow")
|
|
229
|
+
.find(".udex-masthead-menu__sub-list")
|
|
230
|
+
.eq(0)
|
|
231
|
+
.find("udex-masthead-menu-item")
|
|
232
|
+
.should("have.length", 2);
|
|
233
|
+
|
|
234
|
+
// Second sub-list: "On-Premise Solutions" has 1 sub-item
|
|
235
|
+
cy.get("@shadow")
|
|
236
|
+
.find(".udex-masthead-menu__sub-list")
|
|
237
|
+
.eq(1)
|
|
238
|
+
.find("udex-masthead-menu-item")
|
|
239
|
+
.should("have.length", 1);
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it("renders the correct label for each sub-item menu-item", () => {
|
|
243
|
+
cy.get("@shadow")
|
|
244
|
+
.find(".udex-masthead-menu__sub-list")
|
|
245
|
+
.eq(0)
|
|
246
|
+
.find("udex-masthead-menu-item")
|
|
247
|
+
.eq(0)
|
|
248
|
+
.should("have.attr", "label", "SAP S/4HANA Cloud");
|
|
249
|
+
|
|
250
|
+
cy.get("@shadow")
|
|
251
|
+
.find(".udex-masthead-menu__sub-list")
|
|
252
|
+
.eq(0)
|
|
253
|
+
.find("udex-masthead-menu-item")
|
|
254
|
+
.eq(1)
|
|
255
|
+
.should("have.attr", "label", "SAP BTP");
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it("sets the correct url attribute on sub-item menu-items", () => {
|
|
259
|
+
cy.get("@shadow")
|
|
260
|
+
.find(".udex-masthead-menu__sub-list")
|
|
261
|
+
.eq(0)
|
|
262
|
+
.find("udex-masthead-menu-item")
|
|
263
|
+
.eq(0)
|
|
264
|
+
.should("have.attr", "url", "https://example.com/s4hana");
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
describe("Sub-list accessibility", () => {
|
|
269
|
+
beforeEach(() => {
|
|
270
|
+
cy.mount(
|
|
271
|
+
<UDExMastheadMenu
|
|
272
|
+
id="menu-sub-items"
|
|
273
|
+
subItems={JSON.stringify(itemsWithSubItems)}
|
|
274
|
+
/>
|
|
275
|
+
);
|
|
276
|
+
cy.get("[udex-masthead-menu]").shadow().as("shadow");
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it("sets aria-label on the sub-list matching the sub-category title", () => {
|
|
280
|
+
cy.get("@shadow")
|
|
281
|
+
.find(".udex-masthead-menu__sub-list")
|
|
282
|
+
.eq(0)
|
|
283
|
+
.should("have.attr", "aria-label", "Cloud Solutions");
|
|
284
|
+
|
|
285
|
+
cy.get("@shadow")
|
|
286
|
+
.find(".udex-masthead-menu__sub-list")
|
|
287
|
+
.eq(1)
|
|
288
|
+
.should("have.attr", "aria-label", "On-Premise Solutions");
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
describe("Regression: items without subItems still render normally", () => {
|
|
293
|
+
beforeEach(() => {
|
|
294
|
+
cy.mount(
|
|
295
|
+
<UDExMastheadMenu
|
|
296
|
+
id="menu-no-sub-items"
|
|
297
|
+
subItems={JSON.stringify(itemsWithoutSubItems)}
|
|
298
|
+
/>
|
|
299
|
+
);
|
|
300
|
+
cy.get("[udex-masthead-menu]").shadow().as("shadow");
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("does not render any .udex-masthead-menu__sub-category when no items have subItems", () => {
|
|
304
|
+
cy.get("@shadow")
|
|
305
|
+
.find(".udex-masthead-menu__sub-category")
|
|
306
|
+
.should("not.exist");
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it("does not render any .udex-masthead-menu__sub-list when no items have subItems", () => {
|
|
310
|
+
cy.get("@shadow")
|
|
311
|
+
.find(".udex-masthead-menu__sub-list")
|
|
312
|
+
.should("not.exist");
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it("renders udex-masthead-menu-item elements directly in the main list", () => {
|
|
316
|
+
cy.get("@shadow")
|
|
317
|
+
.find(".udex-masthead-menu__list")
|
|
318
|
+
.find("udex-masthead-menu-item")
|
|
319
|
+
.should("have.length", 2);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
it("renders the correct labels for plain items", () => {
|
|
323
|
+
cy.get("@shadow")
|
|
324
|
+
.find(".udex-masthead-menu__list udex-masthead-menu-item")
|
|
325
|
+
.eq(0)
|
|
326
|
+
.should("have.attr", "label", "Consulting");
|
|
327
|
+
|
|
328
|
+
cy.get("@shadow")
|
|
329
|
+
.find(".udex-masthead-menu__list udex-masthead-menu-item")
|
|
330
|
+
.eq(1)
|
|
331
|
+
.should("have.attr", "label", "Training");
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
describe("Mixed content: items with and without subItems in the same list", () => {
|
|
336
|
+
beforeEach(() => {
|
|
337
|
+
cy.mount(
|
|
338
|
+
<UDExMastheadMenu
|
|
339
|
+
id="menu-mixed"
|
|
340
|
+
subItems={JSON.stringify(mixedItems)}
|
|
341
|
+
/>
|
|
342
|
+
);
|
|
343
|
+
cy.get("[udex-masthead-menu]").shadow().as("shadow");
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
it("renders a sub-category for the item that has subItems", () => {
|
|
347
|
+
cy.get("@shadow")
|
|
348
|
+
.find(".udex-masthead-menu__sub-category")
|
|
349
|
+
.should("have.length", 1)
|
|
350
|
+
.and("have.text", "Cloud Solutions");
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it("renders a sub-list with the sub-item for the grouped item", () => {
|
|
354
|
+
cy.get("@shadow")
|
|
355
|
+
.find(".udex-masthead-menu__sub-list")
|
|
356
|
+
.should("have.length", 1)
|
|
357
|
+
.find("udex-masthead-menu-item")
|
|
358
|
+
.should("have.length", 1)
|
|
359
|
+
.and("have.attr", "label", "SAP S/4HANA Cloud");
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it("also renders the plain item as a direct udex-masthead-menu-item in the main list", () => {
|
|
363
|
+
// The main .udex-masthead-menu__list should contain both the sub-category group
|
|
364
|
+
// and the direct link item. The direct link item sits at the top level of the list.
|
|
365
|
+
cy.get("@shadow")
|
|
366
|
+
.find(".udex-masthead-menu__list > li > udex-masthead-menu-item")
|
|
367
|
+
.should("have.length", 1)
|
|
368
|
+
.and("have.attr", "label", "Direct Link Item");
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
// CSS variable remapping for linked sub-categories is handled by the
|
|
373
|
+
// `udex-masthead-menu-item.udex-masthead-menu__sub-category` CSS rule, which sets
|
|
374
|
+
// --udex-masthead-menu-item-color, --udex-masthead-menu-item-font-size,
|
|
375
|
+
// --udex-masthead-menu-item-line-height, --udex-masthead-menu-item-font-weight,
|
|
376
|
+
// and text-transform from the --udex-masthead-menu-sub-category-* variables.
|
|
377
|
+
describe("Linked sub-category: item with subItems AND url renders as udex-masthead-menu-item", () => {
|
|
378
|
+
beforeEach(() => {
|
|
379
|
+
cy.mount(
|
|
380
|
+
<UDExMastheadMenu
|
|
381
|
+
id="menu-linked-sub"
|
|
382
|
+
subItems={JSON.stringify(itemsWithLinkedSubCategory)}
|
|
383
|
+
/>
|
|
384
|
+
);
|
|
385
|
+
cy.get("[udex-masthead-menu]").shadow().as("shadow");
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
describe("Rendering", () => {
|
|
389
|
+
it("renders a .udex-masthead-menu__sub-category for each item with subItems", () => {
|
|
390
|
+
cy.get("@shadow")
|
|
391
|
+
.find(".udex-masthead-menu__sub-category")
|
|
392
|
+
.should("have.length", 2);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it("applies the udex-masthead-menu__sub-category class on the linked udex-masthead-menu-item", () => {
|
|
396
|
+
cy.get("@shadow")
|
|
397
|
+
.find("udex-masthead-menu-item.udex-masthead-menu__sub-category")
|
|
398
|
+
.should("have.length", 2)
|
|
399
|
+
.each(($el) => {
|
|
400
|
+
cy.wrap($el).should("have.class", "udex-masthead-menu__sub-category");
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
it("renders sub-category as a <udex-masthead-menu-item>, not a <span>", () => {
|
|
405
|
+
cy.get("@shadow")
|
|
406
|
+
.find(".udex-masthead-menu__sub-category")
|
|
407
|
+
.first()
|
|
408
|
+
.should("have.prop", "tagName")
|
|
409
|
+
.then((tagName: string) => {
|
|
410
|
+
expect(tagName.toLowerCase()).to.equal("udex-masthead-menu-item");
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
it("displays the correct label attribute on each linked sub-category", () => {
|
|
415
|
+
cy.get("@shadow")
|
|
416
|
+
.find(".udex-masthead-menu__sub-category")
|
|
417
|
+
.eq(0)
|
|
418
|
+
.should("have.attr", "label", "Build");
|
|
419
|
+
|
|
420
|
+
cy.get("@shadow")
|
|
421
|
+
.find(".udex-masthead-menu__sub-category")
|
|
422
|
+
.eq(1)
|
|
423
|
+
.should("have.attr", "label", "Run");
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
it("sets the correct url attribute on each linked sub-category", () => {
|
|
427
|
+
cy.get("@shadow")
|
|
428
|
+
.find(".udex-masthead-menu__sub-category")
|
|
429
|
+
.eq(0)
|
|
430
|
+
.should("have.attr", "url", "https://example.com/build");
|
|
431
|
+
|
|
432
|
+
cy.get("@shadow")
|
|
433
|
+
.find(".udex-masthead-menu__sub-category")
|
|
434
|
+
.eq(1)
|
|
435
|
+
.should("have.attr", "url", "https://example.com/run");
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
describe("Accessibility", () => {
|
|
440
|
+
it("sets accessible-role='link' on the linked sub-category", () => {
|
|
441
|
+
cy.get("@shadow")
|
|
442
|
+
.find(".udex-masthead-menu__sub-category")
|
|
443
|
+
.each(($el) => {
|
|
444
|
+
cy.wrap($el).should("have.attr", "accessible-role", "link");
|
|
445
|
+
});
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it("still renders the sub-list with aria-label matching the sub-category title", () => {
|
|
449
|
+
cy.get("@shadow")
|
|
450
|
+
.find(".udex-masthead-menu__sub-list")
|
|
451
|
+
.eq(0)
|
|
452
|
+
.should("have.attr", "aria-label", "Build");
|
|
453
|
+
|
|
454
|
+
cy.get("@shadow")
|
|
455
|
+
.find(".udex-masthead-menu__sub-list")
|
|
456
|
+
.eq(1)
|
|
457
|
+
.should("have.attr", "aria-label", "Run");
|
|
458
|
+
});
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
describe("Sub-items under linked sub-category", () => {
|
|
462
|
+
it("renders the correct number of sub-items in each sub-list", () => {
|
|
463
|
+
// "Build" has 2 sub-items: Develop, Deploy
|
|
464
|
+
cy.get("@shadow")
|
|
465
|
+
.find(".udex-masthead-menu__sub-list")
|
|
466
|
+
.eq(0)
|
|
467
|
+
.find("udex-masthead-menu-item")
|
|
468
|
+
.should("have.length", 2);
|
|
469
|
+
|
|
470
|
+
// "Run" has 1 sub-item: Monitor
|
|
471
|
+
cy.get("@shadow")
|
|
472
|
+
.find(".udex-masthead-menu__sub-list")
|
|
473
|
+
.eq(1)
|
|
474
|
+
.find("udex-masthead-menu-item")
|
|
475
|
+
.should("have.length", 1);
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
it("renders the correct labels and urls on sub-items", () => {
|
|
479
|
+
cy.get("@shadow")
|
|
480
|
+
.find(".udex-masthead-menu__sub-list")
|
|
481
|
+
.eq(0)
|
|
482
|
+
.find("udex-masthead-menu-item")
|
|
483
|
+
.eq(0)
|
|
484
|
+
.should("have.attr", "label", "Develop")
|
|
485
|
+
.and("have.attr", "url", "https://example.com/develop");
|
|
486
|
+
|
|
487
|
+
cy.get("@shadow")
|
|
488
|
+
.find(".udex-masthead-menu__sub-list")
|
|
489
|
+
.eq(0)
|
|
490
|
+
.find("udex-masthead-menu-item")
|
|
491
|
+
.eq(1)
|
|
492
|
+
.should("have.attr", "label", "Deploy")
|
|
493
|
+
.and("have.attr", "url", "https://example.com/deploy");
|
|
494
|
+
});
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
// Added: verifies focusInnerElement is used for Home/End/Tab navigation within the menu
|
|
499
|
+
describe("Keyboard navigation (Home/End/Tab focus inner element)", () => {
|
|
500
|
+
beforeEach(() => {
|
|
501
|
+
cy.mount(
|
|
502
|
+
<UDExMastheadMenu
|
|
503
|
+
id="menu-keyboard"
|
|
504
|
+
subItems={JSON.stringify(itemsWithSubItems)}
|
|
505
|
+
/>
|
|
506
|
+
);
|
|
507
|
+
cy.get("[udex-masthead-menu]").shadow().as("shadow");
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it("Home key focuses the inner element of the first menu item", () => {
|
|
511
|
+
// Focus the last link, then press Home — should move focus to the inner element of the first link
|
|
512
|
+
cy.get("@shadow")
|
|
513
|
+
.find("[udex-masthead-menu-item][url]")
|
|
514
|
+
.last()
|
|
515
|
+
.shadow()
|
|
516
|
+
.find(".udex-masthead-menu-item")
|
|
517
|
+
.focus();
|
|
518
|
+
cy.realPress("Home");
|
|
519
|
+
cy.get("@shadow")
|
|
520
|
+
.find("[udex-masthead-menu-item][url]")
|
|
521
|
+
.first()
|
|
522
|
+
.shadow()
|
|
523
|
+
.find(".udex-masthead-menu-item")
|
|
524
|
+
.should("be.focused");
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
it("End key focuses the inner element of the last menu item", () => {
|
|
528
|
+
// Focus the first link, then press End — should move focus to the inner element of the last link
|
|
529
|
+
cy.get("@shadow")
|
|
530
|
+
.find("[udex-masthead-menu-item][url]")
|
|
531
|
+
.first()
|
|
532
|
+
.shadow()
|
|
533
|
+
.find(".udex-masthead-menu-item")
|
|
534
|
+
.focus();
|
|
535
|
+
cy.realPress("End");
|
|
536
|
+
cy.get("@shadow")
|
|
537
|
+
.find("[udex-masthead-menu-item][url]")
|
|
538
|
+
.last()
|
|
539
|
+
.shadow()
|
|
540
|
+
.find(".udex-masthead-menu-item")
|
|
541
|
+
.should("be.focused");
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
it("Shift+Tab focuses the inner element of the previous menu item", () => {
|
|
545
|
+
// Focus the second link, then press Shift+Tab — should focus the inner element of the first link
|
|
546
|
+
cy.get("@shadow")
|
|
547
|
+
.find("[udex-masthead-menu-item][url]")
|
|
548
|
+
.eq(1)
|
|
549
|
+
.shadow()
|
|
550
|
+
.find(".udex-masthead-menu-item")
|
|
551
|
+
.focus();
|
|
552
|
+
cy.realPress(["Shift", "Tab"]);
|
|
553
|
+
cy.get("@shadow")
|
|
554
|
+
.find("[udex-masthead-menu-item][url]")
|
|
555
|
+
.first()
|
|
556
|
+
.shadow()
|
|
557
|
+
.find(".udex-masthead-menu-item")
|
|
558
|
+
.should("be.focused");
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
it("Tab focuses the inner element of the next menu item", () => {
|
|
562
|
+
// Focus the first link, then press Tab — should focus the inner element of the second link
|
|
563
|
+
cy.get("@shadow")
|
|
564
|
+
.find("[udex-masthead-menu-item][url]")
|
|
565
|
+
.first()
|
|
566
|
+
.shadow()
|
|
567
|
+
.find(".udex-masthead-menu-item")
|
|
568
|
+
.focus();
|
|
569
|
+
cy.realPress("Tab");
|
|
570
|
+
cy.get("@shadow")
|
|
571
|
+
.find("[udex-masthead-menu-item][url]")
|
|
572
|
+
.eq(1)
|
|
573
|
+
.shadow()
|
|
574
|
+
.find(".udex-masthead-menu-item")
|
|
575
|
+
.should("be.focused");
|
|
576
|
+
});
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
describe("Mixed linked and non-linked sub-categories in the same list", () => {
|
|
580
|
+
beforeEach(() => {
|
|
581
|
+
cy.mount(
|
|
582
|
+
<UDExMastheadMenu
|
|
583
|
+
id="menu-mixed-linked"
|
|
584
|
+
subItems={JSON.stringify(mixedLinkedSubCategories)}
|
|
585
|
+
/>
|
|
586
|
+
);
|
|
587
|
+
cy.get("[udex-masthead-menu]").shadow().as("shadow");
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
it("renders two .udex-masthead-menu__sub-category elements", () => {
|
|
591
|
+
cy.get("@shadow")
|
|
592
|
+
.find(".udex-masthead-menu__sub-category")
|
|
593
|
+
.should("have.length", 2);
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
it("renders the linked sub-category (Build) as a udex-masthead-menu-item", () => {
|
|
597
|
+
cy.get("@shadow")
|
|
598
|
+
.find(".udex-masthead-menu__sub-category")
|
|
599
|
+
.eq(0)
|
|
600
|
+
.should("have.prop", "tagName")
|
|
601
|
+
.then((tagName: string) => {
|
|
602
|
+
expect(tagName.toLowerCase()).to.equal("udex-masthead-menu-item");
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
cy.get("@shadow")
|
|
606
|
+
.find(".udex-masthead-menu__sub-category")
|
|
607
|
+
.eq(0)
|
|
608
|
+
.should("have.attr", "label", "Build")
|
|
609
|
+
.and("have.attr", "url", "https://example.com/build")
|
|
610
|
+
.and("have.attr", "accessible-role", "link");
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
it("renders the non-linked sub-category (Design) as a <span>", () => {
|
|
614
|
+
cy.get("@shadow")
|
|
615
|
+
.find(".udex-masthead-menu__sub-category")
|
|
616
|
+
.eq(1)
|
|
617
|
+
.should("have.prop", "tagName", "SPAN")
|
|
618
|
+
.and("have.text", "Design");
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
it("renders sub-lists under both sub-categories", () => {
|
|
622
|
+
cy.get("@shadow")
|
|
623
|
+
.find(".udex-masthead-menu__sub-list")
|
|
624
|
+
.should("have.length", 2);
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
it("renders sub-items correctly under the linked sub-category", () => {
|
|
628
|
+
cy.get("@shadow")
|
|
629
|
+
.find(".udex-masthead-menu__sub-list")
|
|
630
|
+
.eq(0)
|
|
631
|
+
.find("udex-masthead-menu-item")
|
|
632
|
+
.should("have.length", 1)
|
|
633
|
+
.and("have.attr", "label", "Develop");
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
it("renders sub-items correctly under the non-linked sub-category", () => {
|
|
637
|
+
cy.get("@shadow")
|
|
638
|
+
.find(".udex-masthead-menu__sub-list")
|
|
639
|
+
.eq(1)
|
|
640
|
+
.find("udex-masthead-menu-item")
|
|
641
|
+
.should("have.length", 1)
|
|
642
|
+
.and("have.attr", "label", "Figma");
|
|
643
|
+
});
|
|
644
|
+
});
|
|
645
|
+
});
|