Skip to content

Commit ed06865

Browse files
fix(ui5-user-menu-item): fix lint error, add selection line CSS and tests
- Fix ESLint func-names/space-before-function-paren in MenuItemTemplate - Update UserMenuItem CSS: 3.25rem height for two-line selection display, 0.5rem padding, 0.25rem gap, proper font styling with SAP theme vars - Fix CSS selector from [show-selection-text] to [show-selection] - Add 17 Cypress tests for showSelection, single-select behavior, UserMenuItemGroup, CSS styling, and nested submenu items
1 parent b8df9f7 commit ed06865

3 files changed

Lines changed: 352 additions & 28 deletions

File tree

packages/fiori/cypress/specs/UserMenu.cy.tsx

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,3 +988,328 @@ describe("Footer configuration", () => {
988988
cy.get("@signOutClicked").should("have.been.calledOnce");
989989
});
990990
});
991+
992+
describe("UserMenuItem", () => {
993+
describe("showSelection property", () => {
994+
it("renders two-line layout when showSelection is true and sub-item is checked", () => {
995+
cy.mount(
996+
<>
997+
<Button id="openUserMenuBtn">Open User Menu</Button>
998+
<UserMenu open={true} opener="openUserMenuBtn">
999+
<UserMenuItem text="Theme" showSelection={true}>
1000+
<UserMenuItemGroup checkMode="Single">
1001+
<UserMenuItem text="Light" checked={true}></UserMenuItem>
1002+
<UserMenuItem text="Dark"></UserMenuItem>
1003+
</UserMenuItemGroup>
1004+
</UserMenuItem>
1005+
</UserMenu>
1006+
</>
1007+
);
1008+
1009+
cy.get("[ui5-user-menu]").find("[ui5-user-menu-item][text='Theme']").as("themeItem");
1010+
cy.get("@themeItem")
1011+
.shadow()
1012+
.find(".ui5-user-menu-item-text-wrapper")
1013+
.should("exist");
1014+
cy.get("@themeItem")
1015+
.shadow()
1016+
.find(".ui5-user-menu-item-selection-text")
1017+
.should("exist")
1018+
.and("contain.text", "Light");
1019+
});
1020+
1021+
it("does not render selection text when showSelection is false", () => {
1022+
cy.mount(
1023+
<>
1024+
<Button id="openUserMenuBtn">Open User Menu</Button>
1025+
<UserMenu open={true} opener="openUserMenuBtn">
1026+
<UserMenuItem text="Settings">
1027+
<UserMenuItemGroup checkMode="Single">
1028+
<UserMenuItem text="Option A" checked={true}></UserMenuItem>
1029+
</UserMenuItemGroup>
1030+
</UserMenuItem>
1031+
</UserMenu>
1032+
</>
1033+
);
1034+
1035+
cy.get("[ui5-user-menu]").find("[ui5-user-menu-item][text='Settings']").as("settingsItem");
1036+
cy.get("@settingsItem")
1037+
.shadow()
1038+
.find(".ui5-user-menu-item-text-wrapper")
1039+
.should("not.exist");
1040+
cy.get("@settingsItem")
1041+
.shadow()
1042+
.find(".ui5-user-menu-item-selection-text")
1043+
.should("not.exist");
1044+
});
1045+
1046+
it("does not render selection text when no sub-item is checked", () => {
1047+
cy.mount(
1048+
<>
1049+
<Button id="openUserMenuBtn">Open User Menu</Button>
1050+
<UserMenu open={true} opener="openUserMenuBtn">
1051+
<UserMenuItem text="Theme" showSelection={true}>
1052+
<UserMenuItemGroup checkMode="Single">
1053+
<UserMenuItem text="Light"></UserMenuItem>
1054+
<UserMenuItem text="Dark"></UserMenuItem>
1055+
</UserMenuItemGroup>
1056+
</UserMenuItem>
1057+
</UserMenu>
1058+
</>
1059+
);
1060+
1061+
cy.get("[ui5-user-menu]").find("[ui5-user-menu-item][text='Theme']").as("themeItem");
1062+
cy.get("@themeItem")
1063+
.shadow()
1064+
.find(".ui5-user-menu-item-text-wrapper")
1065+
.should("exist");
1066+
cy.get("@themeItem")
1067+
.shadow()
1068+
.find(".ui5-user-menu-item-selection-text")
1069+
.should("not.exist");
1070+
});
1071+
1072+
it("updates selection text when a different sub-item is checked", () => {
1073+
cy.mount(
1074+
<>
1075+
<Button id="openUserMenuBtn">Open User Menu</Button>
1076+
<UserMenu open={true} opener="openUserMenuBtn">
1077+
<UserMenuItem text="Theme" showSelection={true}>
1078+
<UserMenuItemGroup checkMode="Single">
1079+
<UserMenuItem text="Light" checked={true}></UserMenuItem>
1080+
<UserMenuItem text="Dark"></UserMenuItem>
1081+
<UserMenuItem text="High Contrast"></UserMenuItem>
1082+
</UserMenuItemGroup>
1083+
</UserMenuItem>
1084+
</UserMenu>
1085+
</>
1086+
);
1087+
1088+
cy.get("[ui5-user-menu]").find("[ui5-user-menu-item][text='Theme']").as("themeItem");
1089+
cy.get("@themeItem")
1090+
.shadow()
1091+
.find(".ui5-user-menu-item-selection-text")
1092+
.should("contain.text", "Light");
1093+
1094+
cy.get("@themeItem").click();
1095+
1096+
cy.get("[ui5-user-menu-item][text='Dark']").click();
1097+
1098+
cy.get("@themeItem")
1099+
.shadow()
1100+
.find(".ui5-user-menu-item-selection-text")
1101+
.should("contain.text", "Dark");
1102+
});
1103+
});
1104+
1105+
describe("Single-select behavior", () => {
1106+
it("prevents unchecking the only checked item in single-select mode", () => {
1107+
cy.mount(
1108+
<>
1109+
<Button id="openUserMenuBtn">Open User Menu</Button>
1110+
<UserMenu open={true} opener="openUserMenuBtn">
1111+
<UserMenuItem text="Theme" showSelection={true}>
1112+
<UserMenuItemGroup checkMode="Single">
1113+
<UserMenuItem text="Light" checked={true}></UserMenuItem>
1114+
<UserMenuItem text="Dark"></UserMenuItem>
1115+
</UserMenuItemGroup>
1116+
</UserMenuItem>
1117+
</UserMenu>
1118+
</>
1119+
);
1120+
1121+
cy.get("[ui5-user-menu]").find("[ui5-user-menu-item][text='Theme']").as("themeItem");
1122+
cy.get("@themeItem").click();
1123+
1124+
cy.get("[ui5-user-menu-item][text='Light']").click();
1125+
1126+
cy.get("[ui5-user-menu-item][text='Light']")
1127+
.should("have.attr", "checked");
1128+
});
1129+
});
1130+
1131+
describe("UserMenuItemGroup", () => {
1132+
it("renders items within a group with Single check mode", () => {
1133+
cy.mount(
1134+
<>
1135+
<Button id="openUserMenuBtn">Open User Menu</Button>
1136+
<UserMenu open={true} opener="openUserMenuBtn">
1137+
<UserMenuItemGroup checkMode="Single">
1138+
<UserMenuItem text="Option 1" checked={true}></UserMenuItem>
1139+
<UserMenuItem text="Option 2"></UserMenuItem>
1140+
</UserMenuItemGroup>
1141+
</UserMenu>
1142+
</>
1143+
);
1144+
1145+
cy.get("[ui5-user-menu]").find("[ui5-user-menu-item-group]").should("exist");
1146+
cy.get("[ui5-user-menu-item-group]").should("have.attr", "check-mode", "Single");
1147+
cy.get("[ui5-user-menu-item]").should("have.length", 2);
1148+
});
1149+
1150+
it("renders items within a group with Multiple check mode", () => {
1151+
cy.mount(
1152+
<>
1153+
<Button id="openUserMenuBtn">Open User Menu</Button>
1154+
<UserMenu open={true} opener="openUserMenuBtn">
1155+
<UserMenuItemGroup checkMode="Multiple">
1156+
<UserMenuItem text="Feature A" checked={true}></UserMenuItem>
1157+
<UserMenuItem text="Feature B" checked={true}></UserMenuItem>
1158+
<UserMenuItem text="Feature C"></UserMenuItem>
1159+
</UserMenuItemGroup>
1160+
</UserMenu>
1161+
</>
1162+
);
1163+
1164+
cy.get("[ui5-user-menu]").find("[ui5-user-menu-item-group]").should("exist");
1165+
cy.get("[ui5-user-menu-item-group]").should("have.attr", "check-mode", "Multiple");
1166+
cy.get("[ui5-user-menu-item]").should("have.length", 3);
1167+
cy.get("[ui5-user-menu-item][text='Feature A']").should("have.attr", "checked");
1168+
cy.get("[ui5-user-menu-item][text='Feature B']").should("have.attr", "checked");
1169+
cy.get("[ui5-user-menu-item][text='Feature C']").should("not.have.attr", "checked");
1170+
});
1171+
1172+
it("fires ui5-check event when item is checked in a group", () => {
1173+
cy.mount(
1174+
<>
1175+
<Button id="openUserMenuBtn">Open User Menu</Button>
1176+
<UserMenu open={true} opener="openUserMenuBtn">
1177+
<UserMenuItemGroup checkMode="Single">
1178+
<UserMenuItem text="Item 1"></UserMenuItem>
1179+
<UserMenuItem text="Item 2"></UserMenuItem>
1180+
</UserMenuItemGroup>
1181+
</UserMenu>
1182+
</>
1183+
);
1184+
1185+
cy.get("[ui5-user-menu]").as("userMenu");
1186+
cy.get("@userMenu")
1187+
.then($userMenu => {
1188+
$userMenu.get(0).addEventListener("ui5-check", cy.stub().as("checked"));
1189+
});
1190+
1191+
cy.get("[ui5-user-menu-item]").first().click();
1192+
1193+
cy.get("@checked").should("have.been.calledOnce");
1194+
});
1195+
});
1196+
1197+
describe("CSS styling", () => {
1198+
it("has show-selection attribute when showSelection is true", () => {
1199+
cy.mount(
1200+
<>
1201+
<Button id="openUserMenuBtn">Open User Menu</Button>
1202+
<UserMenu open={true} opener="openUserMenuBtn">
1203+
<UserMenuItem text="Theme" showSelection={true}>
1204+
<UserMenuItemGroup checkMode="Single">
1205+
<UserMenuItem text="Light" checked={true}></UserMenuItem>
1206+
<UserMenuItem text="Dark"></UserMenuItem>
1207+
</UserMenuItemGroup>
1208+
</UserMenuItem>
1209+
</UserMenu>
1210+
</>
1211+
);
1212+
1213+
cy.get("[ui5-user-menu-item][text='Theme']")
1214+
.should("have.attr", "show-selection");
1215+
});
1216+
1217+
it("does not have show-selection attribute when showSelection is false", () => {
1218+
cy.mount(
1219+
<>
1220+
<Button id="openUserMenuBtn">Open User Menu</Button>
1221+
<UserMenu open={true} opener="openUserMenuBtn">
1222+
<UserMenuItem text="Settings"></UserMenuItem>
1223+
</UserMenu>
1224+
</>
1225+
);
1226+
1227+
cy.get("[ui5-user-menu-item][text='Settings']")
1228+
.should("not.have.attr", "show-selection");
1229+
});
1230+
1231+
it("selection text has correct styling", () => {
1232+
cy.mount(
1233+
<>
1234+
<Button id="openUserMenuBtn">Open User Menu</Button>
1235+
<UserMenu open={true} opener="openUserMenuBtn">
1236+
<UserMenuItem text="Theme" showSelection={true}>
1237+
<UserMenuItemGroup checkMode="Single">
1238+
<UserMenuItem text="Light" checked={true}></UserMenuItem>
1239+
</UserMenuItemGroup>
1240+
</UserMenuItem>
1241+
</UserMenu>
1242+
</>
1243+
);
1244+
1245+
cy.get("[ui5-user-menu-item][text='Theme']")
1246+
.shadow()
1247+
.find(".ui5-user-menu-item-selection-text")
1248+
.should("have.css", "font-weight", "400")
1249+
.and("have.css", "white-space", "nowrap")
1250+
.and("have.css", "overflow", "hidden")
1251+
.and("have.css", "text-overflow", "ellipsis");
1252+
});
1253+
1254+
it("text wrapper has column layout with gap", () => {
1255+
cy.mount(
1256+
<>
1257+
<Button id="openUserMenuBtn">Open User Menu</Button>
1258+
<UserMenu open={true} opener="openUserMenuBtn">
1259+
<UserMenuItem text="Theme" showSelection={true}>
1260+
<UserMenuItemGroup checkMode="Single">
1261+
<UserMenuItem text="Light" checked={true}></UserMenuItem>
1262+
</UserMenuItemGroup>
1263+
</UserMenuItem>
1264+
</UserMenu>
1265+
</>
1266+
);
1267+
1268+
cy.get("[ui5-user-menu-item][text='Theme']")
1269+
.shadow()
1270+
.find(".ui5-user-menu-item-text-wrapper")
1271+
.should("have.css", "flex-direction", "column")
1272+
.and("have.css", "gap", "4px");
1273+
});
1274+
});
1275+
1276+
describe("Nested submenu items", () => {
1277+
it("renders nested UserMenuItem hierarchy", () => {
1278+
cy.mount(
1279+
<>
1280+
<Button id="openUserMenuBtn">Open User Menu</Button>
1281+
<UserMenu open={true} opener="openUserMenuBtn">
1282+
<UserMenuItem text="Legal Information">
1283+
<UserMenuItem text="Privacy Policy"></UserMenuItem>
1284+
<UserMenuItem text="Terms of Use"></UserMenuItem>
1285+
</UserMenuItem>
1286+
</UserMenu>
1287+
</>
1288+
);
1289+
1290+
cy.get("[ui5-user-menu]").find("[ui5-user-menu-item][text='Legal Information']").as("parentItem");
1291+
cy.get("@parentItem").find("[ui5-user-menu-item]").should("have.length", 2);
1292+
});
1293+
1294+
it("does not show selection text for non-single-select groups", () => {
1295+
cy.mount(
1296+
<>
1297+
<Button id="openUserMenuBtn">Open User Menu</Button>
1298+
<UserMenu open={true} opener="openUserMenuBtn">
1299+
<UserMenuItem text="Features" showSelection={true}>
1300+
<UserMenuItemGroup checkMode="Multiple">
1301+
<UserMenuItem text="Feature A" checked={true}></UserMenuItem>
1302+
<UserMenuItem text="Feature B" checked={true}></UserMenuItem>
1303+
</UserMenuItemGroup>
1304+
</UserMenuItem>
1305+
</UserMenu>
1306+
</>
1307+
);
1308+
1309+
cy.get("[ui5-user-menu-item][text='Features']")
1310+
.shadow()
1311+
.find(".ui5-user-menu-item-selection-text")
1312+
.should("not.exist");
1313+
});
1314+
});
1315+
});

0 commit comments

Comments
 (0)