Skip to content

Commit 2cf21d8

Browse files
Merge branch 'main' into user-settings-appearance-view
2 parents 12cf724 + f672e13 commit 2cf21d8

14 files changed

Lines changed: 851 additions & 51 deletions

packages/main/cypress/specs/List.cy.tsx

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,6 +1286,291 @@ describe("List Tests", () => {
12861286
cy.get("[ui5-li-custom]").first().should("be.focused");
12871287
});
12881288

1289+
it("keyboard handling on F7", () => {
1290+
cy.mount(
1291+
<List>
1292+
<ListItemCustom>
1293+
<Button>First</Button>
1294+
<Button>Second</Button>
1295+
</ListItemCustom>
1296+
</List>
1297+
);
1298+
1299+
cy.get("[ui5-li-custom]").realClick();
1300+
cy.get("[ui5-li-custom]").should("be.focused");
1301+
1302+
// F7 goes to first focusable element
1303+
cy.realPress("F7");
1304+
cy.get("[ui5-button]").first().should("be.focused");
1305+
1306+
// Tab to second button
1307+
cy.realPress("Tab");
1308+
cy.get("[ui5-button]").last().should("be.focused");
1309+
1310+
// F7 returns to list item
1311+
cy.realPress("F7");
1312+
cy.get("[ui5-li-custom]").should("be.focused");
1313+
1314+
// F7 remembers last focused element (second button)
1315+
cy.realPress("F7");
1316+
cy.get("[ui5-button]").last().should("be.focused");
1317+
});
1318+
1319+
it("keyboard handling on F7 after TAB navigation", () => {
1320+
cy.mount(
1321+
<div>
1322+
<button>Before</button>
1323+
<List>
1324+
<ListItemCustom>
1325+
<Button>First</Button>
1326+
<Button>Second</Button>
1327+
</ListItemCustom>
1328+
</List>
1329+
</div>
1330+
);
1331+
1332+
cy.get("button").realClick();
1333+
cy.get("button").should("be.focused");
1334+
1335+
// Tab into list item
1336+
cy.realPress("Tab");
1337+
cy.get("[ui5-li-custom]").should("be.focused");
1338+
1339+
// Tab into internal elements (goes to first button)
1340+
cy.realPress("Tab");
1341+
cy.get("[ui5-button]").first().should("be.focused");
1342+
1343+
// Tab to second button
1344+
cy.realPress("Tab");
1345+
cy.get("[ui5-button]").last().should("be.focused");
1346+
1347+
// F7 should store current element and return to list item
1348+
cy.realPress("F7");
1349+
cy.get("[ui5-li-custom]").should("be.focused");
1350+
1351+
// F7 should remember the second button (not go to first)
1352+
cy.realPress("F7");
1353+
cy.get("[ui5-button]").last().should("be.focused");
1354+
});
1355+
1356+
it("keyboard handling on F7 maintains focus position across list items", () => {
1357+
cy.mount(
1358+
<List>
1359+
<ListItemCustom>
1360+
<Button>Item 1 - First</Button>
1361+
<Button>Item 1 - Second</Button>
1362+
<Button>Item 1 - Third</Button>
1363+
</ListItemCustom>
1364+
<ListItemCustom>
1365+
<Button>Item 2 - First</Button>
1366+
<Button>Item 2 - Second</Button>
1367+
<Button>Item 2 - Third</Button>
1368+
</ListItemCustom>
1369+
</List>
1370+
);
1371+
1372+
// Focus first list item
1373+
cy.get("[ui5-li-custom]").first().realClick();
1374+
cy.get("[ui5-li-custom]").first().should("be.focused");
1375+
1376+
// F7 to enter (should go to first button)
1377+
cy.realPress("F7");
1378+
cy.get("[ui5-button]").eq(0).should("be.focused");
1379+
1380+
// Tab to second button
1381+
cy.realPress("Tab");
1382+
cy.get("[ui5-button]").eq(1).should("be.focused");
1383+
1384+
// F7 to exit back to list item
1385+
cy.realPress("F7");
1386+
cy.get("[ui5-li-custom]").first().should("be.focused");
1387+
1388+
// Navigate to second list item with ArrowDown
1389+
cy.realPress("ArrowDown");
1390+
cy.get("[ui5-li-custom]").last().should("be.focused");
1391+
1392+
// F7 should focus the second button (same index as previous item)
1393+
cy.realPress("F7");
1394+
cy.get("[ui5-button]").eq(4).should("be.focused").and("contain", "Item 2 - Second");
1395+
});
1396+
1397+
it("arrow down navigates to same-index element in next custom item", () => {
1398+
cy.mount(
1399+
<List>
1400+
<ListItemCustom>
1401+
<Button>Item 1 - First</Button>
1402+
<Button>Item 1 - Second</Button>
1403+
</ListItemCustom>
1404+
<ListItemCustom>
1405+
<Button>Item 2 - First</Button>
1406+
<Button>Item 2 - Second</Button>
1407+
</ListItemCustom>
1408+
<ListItemCustom>
1409+
<Button>Item 3 - First</Button>
1410+
<Button>Item 3 - Second</Button>
1411+
</ListItemCustom>
1412+
</List>
1413+
);
1414+
1415+
// Focus first button in first item
1416+
cy.get("[ui5-button]").first().realClick();
1417+
cy.get("[ui5-button]").first().should("be.focused");
1418+
1419+
// Arrow down should move to first button in second item
1420+
cy.realPress("ArrowDown");
1421+
cy.get("[ui5-button]").eq(2).should("be.focused").and("contain", "Item 2 - First");
1422+
1423+
// Arrow down again should move to first button in third item
1424+
cy.realPress("ArrowDown");
1425+
cy.get("[ui5-button]").eq(4).should("be.focused").and("contain", "Item 3 - First");
1426+
});
1427+
1428+
it("arrow up navigates to same-index element in previous custom item", () => {
1429+
cy.mount(
1430+
<List>
1431+
<ListItemCustom>
1432+
<Button>Item 1 - First</Button>
1433+
<Button>Item 1 - Second</Button>
1434+
</ListItemCustom>
1435+
<ListItemCustom>
1436+
<Button>Item 2 - First</Button>
1437+
<Button>Item 2 - Second</Button>
1438+
</ListItemCustom>
1439+
<ListItemCustom>
1440+
<Button>Item 3 - First</Button>
1441+
<Button>Item 3 - Second</Button>
1442+
</ListItemCustom>
1443+
</List>
1444+
);
1445+
1446+
// Focus second button in last item
1447+
cy.get("[ui5-button]").eq(5).realClick();
1448+
cy.get("[ui5-button]").eq(5).should("be.focused");
1449+
1450+
// Arrow up should move to second button in second item
1451+
cy.realPress("ArrowUp");
1452+
cy.get("[ui5-button]").eq(3).should("be.focused").and("contain", "Item 2 - Second");
1453+
1454+
// Arrow up again should move to second button in first item
1455+
cy.realPress("ArrowUp");
1456+
cy.get("[ui5-button]").eq(1).should("be.focused").and("contain", "Item 1 - Second");
1457+
});
1458+
1459+
it("arrow navigation skips standard list items", () => {
1460+
cy.mount(
1461+
<List>
1462+
<ListItemCustom>
1463+
<Button>Custom 1</Button>
1464+
</ListItemCustom>
1465+
<ListItemStandard>Standard Item</ListItemStandard>
1466+
<ListItemStandard>Another Standard</ListItemStandard>
1467+
<ListItemCustom>
1468+
<Button>Custom 2</Button>
1469+
</ListItemCustom>
1470+
</List>
1471+
);
1472+
1473+
// Focus button in first custom item
1474+
cy.get("[ui5-button]").first().realClick();
1475+
cy.get("[ui5-button]").first().should("be.focused");
1476+
1477+
// Arrow down should skip standard items and focus button in second custom item
1478+
cy.realPress("ArrowDown");
1479+
cy.get("[ui5-button]").last().should("be.focused").and("contain", "Custom 2");
1480+
1481+
// Arrow up should skip standard items and return to first custom item
1482+
cy.realPress("ArrowUp");
1483+
cy.get("[ui5-button]").first().should("be.focused").and("contain", "Custom 1");
1484+
});
1485+
1486+
it("arrow navigation works across groups", () => {
1487+
cy.mount(
1488+
<List>
1489+
<ListItemCustom>
1490+
<Button>Before Group</Button>
1491+
</ListItemCustom>
1492+
<ListItemGroup headerText="Group 1">
1493+
<ListItemCustom>
1494+
<Button>In Group 1</Button>
1495+
</ListItemCustom>
1496+
</ListItemGroup>
1497+
<ListItemGroup headerText="Group 2">
1498+
<ListItemCustom>
1499+
<Button>In Group 2</Button>
1500+
</ListItemCustom>
1501+
</ListItemGroup>
1502+
<ListItemCustom>
1503+
<Button>After Group</Button>
1504+
</ListItemCustom>
1505+
</List>
1506+
);
1507+
1508+
// Focus button before groups
1509+
cy.get("[ui5-button]").first().realClick();
1510+
1511+
// Navigate down through groups
1512+
cy.realPress("ArrowDown");
1513+
cy.get("[ui5-button]").eq(1).should("be.focused").and("contain", "In Group 1");
1514+
1515+
cy.realPress("ArrowDown");
1516+
cy.get("[ui5-button]").eq(2).should("be.focused").and("contain", "In Group 2");
1517+
1518+
cy.realPress("ArrowDown");
1519+
cy.get("[ui5-button]").last().should("be.focused").and("contain", "After Group");
1520+
});
1521+
1522+
it("arrow navigation handles items with different element counts", () => {
1523+
cy.mount(
1524+
<List>
1525+
<ListItemCustom>
1526+
<Button>Item 1 - A</Button>
1527+
<Button>Item 1 - B</Button>
1528+
<Button>Item 1 - C</Button>
1529+
<Button>Item 1 - D</Button>
1530+
</ListItemCustom>
1531+
<ListItemCustom>
1532+
<Button>Item 2 - A</Button>
1533+
<Button>Item 2 - B</Button>
1534+
</ListItemCustom>
1535+
</List>
1536+
);
1537+
1538+
// Focus fourth button (index 3) in first item
1539+
cy.get("[ui5-button]").eq(3).realClick();
1540+
cy.get("[ui5-button]").eq(3).should("be.focused");
1541+
1542+
// Arrow down should focus last button in second item (index clamped to 1)
1543+
cy.realPress("ArrowDown");
1544+
cy.get("[ui5-button]").eq(5).should("be.focused").and("contain", "Item 2 - B");
1545+
});
1546+
1547+
it("arrow navigation does nothing at list boundaries", () => {
1548+
cy.mount(
1549+
<List>
1550+
<ListItemCustom>
1551+
<Button>First Item</Button>
1552+
</ListItemCustom>
1553+
<ListItemCustom>
1554+
<Button>Last Item</Button>
1555+
</ListItemCustom>
1556+
</List>
1557+
);
1558+
1559+
// Focus first button
1560+
cy.get("[ui5-button]").first().realClick();
1561+
1562+
// Arrow up should do nothing (at top boundary)
1563+
cy.realPress("ArrowUp");
1564+
cy.get("[ui5-button]").first().should("be.focused");
1565+
1566+
// Focus last button
1567+
cy.get("[ui5-button]").last().realClick();
1568+
1569+
// Arrow down should do nothing (at bottom boundary)
1570+
cy.realPress("ArrowDown");
1571+
cy.get("[ui5-button]").last().should("be.focused");
1572+
});
1573+
12891574
it("keyboard handling on TAB when 2 level nested UI5Element is focused", () => {
12901575
cy.mount(
12911576
<div>

0 commit comments

Comments
 (0)