Skip to content

Commit 5f38de1

Browse files
committed
test(ui5-list): add arrow navigation tests for custom items
Add cypress tests for arrow key navigation between internal elements across list items. Tests cover basic navigation, skipping standard items, group boundaries, varying element counts, and boundary conditions.
1 parent 8791fd7 commit 5f38de1

File tree

1 file changed

+180
-3
lines changed

1 file changed

+180
-3
lines changed

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

Lines changed: 180 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,7 +1296,7 @@ describe("List Tests", () => {
12961296
</List>
12971297
);
12981298

1299-
cy.get("[ui5-li-custom]").click();
1299+
cy.get("[ui5-li-custom]").realClick();
13001300
cy.get("[ui5-li-custom]").should("be.focused");
13011301

13021302
// F7 goes to first focusable element
@@ -1329,7 +1329,7 @@ describe("List Tests", () => {
13291329
</div>
13301330
);
13311331

1332-
cy.get("button").click();
1332+
cy.get("button").realClick();
13331333
cy.get("button").should("be.focused");
13341334

13351335
// Tab into list item
@@ -1370,7 +1370,7 @@ describe("List Tests", () => {
13701370
);
13711371

13721372
// Focus first list item
1373-
cy.get("[ui5-li-custom]").first().click();
1373+
cy.get("[ui5-li-custom]").first().realClick();
13741374
cy.get("[ui5-li-custom]").first().should("be.focused");
13751375

13761376
// F7 to enter (should go to first button)
@@ -1394,6 +1394,183 @@ describe("List Tests", () => {
13941394
cy.get("[ui5-button]").eq(4).should("be.focused").and("contain", "Item 2 - Second");
13951395
});
13961396

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+
13971574
it("keyboard handling on TAB when 2 level nested UI5Element is focused", () => {
13981575
cy.mount(
13991576
<div>

0 commit comments

Comments
 (0)