From c68a25e293b5fdfcbfcc857ba5773cd4c58208cb Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Tue, 15 Jul 2025 15:07:59 +0300 Subject: [PATCH 1/3] chore(ui5-shellbar): migrate wdio tests to cypress --- packages/fiori/cypress/specs/ShellBar.cy.tsx | 612 ++++++++++++++++++- packages/fiori/test/specs/ShellBar.spec.js | 259 -------- 2 files changed, 607 insertions(+), 264 deletions(-) delete mode 100644 packages/fiori/test/specs/ShellBar.spec.js diff --git a/packages/fiori/cypress/specs/ShellBar.cy.tsx b/packages/fiori/cypress/specs/ShellBar.cy.tsx index eb762a0cd612..8fb65fd9930d 100644 --- a/packages/fiori/cypress/specs/ShellBar.cy.tsx +++ b/packages/fiori/cypress/specs/ShellBar.cy.tsx @@ -504,9 +504,9 @@ describe("Slots", () => { cy.mount( ); - + cy.get("#shellbar").as("shellbar"); - + // Add search field after a timeout (simulating real-world scenario) cy.get("@shellbar").then(shellbar => { setTimeout(() => { @@ -516,15 +516,15 @@ describe("Slots", () => { shellbar.get(0).appendChild(searchField); }, 100); }); - + // Wait for the search field to be added cy.get("#delayed-search", { timeout: 1000 }).should("exist"); - + // Search should now be visible and collapsed cy.get("#shellbar [slot='searchField']") .should("exist") .should("have.prop", "collapsed", true); - + // click the searchField to expand it cy.get("#shellbar [slot='searchField']") .click() @@ -814,3 +814,605 @@ describe("Branding slot", () => { }); }); + +describe("Component Behavior", () => { + describe("Accessibility", () => { + it("tests accessibilityTexts property", () => { + const PROFILE_BTN_CUSTOM_TOOLTIP = "John Dow"; + const LOGO_CUSTOM_TOOLTIP = "Custom logo title"; + + cy.mount( + + + + + ); + + cy.get("[ui5-shellbar]").then(($shellbar) => { + ($shellbar[0] as any).accessibilityAttributes = { + profile: { + name: PROFILE_BTN_CUSTOM_TOOLTIP, + }, + logo: { + name: LOGO_CUSTOM_TOOLTIP + }, + }; + }); + + cy.get("[ui5-shellbar]").should("have.prop", "_profileText", PROFILE_BTN_CUSTOM_TOOLTIP); + + cy.get("[ui5-shellbar]").should("have.prop", "_logoText", LOGO_CUSTOM_TOOLTIP); + }); + + it("tests acc default roles", () => { + cy.mount( + + + + ); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-logo-area") + .should("have.attr", "role", "link"); + }); + + it("tests acc custom roles", () => { + cy.mount( + + + + ); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-logo-area") + .should("have.attr", "role", "link"); + }); + + it("tests accessibilityAttributes property", () => { + const NOTIFICATIONS_BTN_ARIA_HASPOPUP = "dialog"; + + cy.mount( + + + Product Title + + + + ); + + cy.get("[ui5-shellbar]").then(($shellbar) => { + ($shellbar[0] as any).accessibilityAttributes = { + notifications: { + hasPopup: NOTIFICATIONS_BTN_ARIA_HASPOPUP + }, + }; + }); + + cy.get("[ui5-shellbar]").then(($shellbar) => { + const accAttrs = ($shellbar[0] as any).accInfo; + expect(accAttrs.notifications.accessibilityAttributes.hasPopup).to.equal(NOTIFICATIONS_BTN_ARIA_HASPOPUP); + }); + }); + }); + + describe("ui5-shellbar menu", () => { + it("tests prevents close on content click", () => { + cy.viewport(1920, 1680); + + cy.mount( +
+ + + Menu Item 1 + Menu Item 2 + + +
+ ); + + cy.get("#checkKeepPopoverOpen").check(); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-menu-button") + .click(); + + cy.get("[ui5-li][slot='menuItems']").first().click(); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-menu-popover") + .should("have.prop", "open", true); + }); + + it("tests close on content click", () => { + cy.mount( + <> + + + Application 1 + Application 2 + + + ); + + cy.get("[ui5-shellbar]").should("exist"); + + cy.get("[slot='menuItems']").should("have.length", 2); + + cy.get("[ui5-shellbar]").should(($shellbar) => { + const shellbar = $shellbar[0] as any; + expect(shellbar.menuItems).to.exist; + expect(shellbar.menuItems.length).to.be.greaterThan(0); + }); + + cy.get("#checkKeepPopoverOpen").invoke("prop", "checked", false); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-menu-button") + .should("exist") + .should("be.visible") + .realClick(); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-menu-popover") + .should("have.prop", "open", true); + + cy.get("[ui5-li][slot='menuItems']") + .first() + .should("be.visible") + .realClick(); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-menu-popover") + .should("have.prop", "open", false); + }); + }); + + describe("ui5-shellbar-item", () => { + it("tests the stable-dom-ref attribute", () => { + cy.mount( + + + + + ); + + cy.get("[ui5-shellbar]") + .shadow() + .find(`[data-ui5-stable="schedule"]`) + .should("exist"); + }); + }); + + it("tests 'click' on custom action", () => { + cy.mount( +
+ + + + + +
+ ); + + cy.get("[ui5-shellbar-item]").each(($item) => { + const item = $item[0]; + item.addEventListener("click", () => { + const icon = item.getAttribute("icon"); + const value = icon === "accept" ? "accept" : "warning"; + (document.getElementById("press-input3") as HTMLInputElement).value = value; + }); + }); + + cy.get("[ui5-shellbar]") + .shadow() + .find(`.ui5-shellbar-custom-item[icon="accept"]`) + .click(); + + cy.get("#press-input3").should("have.value", "accept"); + + cy.get("[ui5-shellbar]") + .shadow() + .find(`.ui5-shellbar-custom-item[icon="alert"]`) + .click(); + + cy.get("#press-input3").should("have.value", "warning"); + }); + + describe("Events", () => { + describe("Big screen", () => { + beforeEach(() => { + cy.viewport(1920, 1680); + }); + + it("tests opening of menu", () => { + cy.mount( + + Menu Item 1 + Menu Item 2 + + + ); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-menu-button") + .click(); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-menu-popover") + .should("have.prop", "open", true); + }); + + it("tests notificationsClick event", () => { + cy.mount( +
+ + + + +
+ ); + + cy.get("[ui5-shellbar]").then($shellbar => { + const shellbar = $shellbar[0]; + shellbar.addEventListener("ui5-notifications-click", () => { + (document.getElementById("press-input") as HTMLInputElement).value = "Notifications"; + }); + }); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-bell-button") + .click(); + + cy.get("#press-input").should("have.value", "Notifications"); + }); + + it("tests profileClick event", () => { + cy.mount( +
+ + + + + + + +
+ ); + + cy.get("[ui5-shellbar]").then($shellbar => { + const shellbar = $shellbar[0]; + shellbar.addEventListener("ui5-profile-click", () => { + (document.getElementById("press-input") as HTMLInputElement).value = "Profile"; + }); + }); + + cy.get("[ui5-shellbar]") + .shadow() + .find("[data-profile-btn]") + .click(); + + cy.get("#press-input").should("have.value", "Profile"); + }); + + it("tests productSwitchClick event", () => { + cy.mount( +
+ + + + +
+ ); + + cy.get("[ui5-shellbar]").then($shellbar => { + const shellbar = $shellbar[0]; + shellbar.addEventListener("ui5-product-switch-click", () => { + (document.getElementById("press-input") as HTMLInputElement).value = "Product Switch"; + }); + }); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-button-product-switch") + .click(); + + cy.get("#press-input").should("have.value", "Product Switch"); + }); + + it("tests logoClick event", () => { + cy.mount( +
+ + + + +
+ ); + + cy.get("[ui5-shellbar]").then($shellbar => { + const shellbar = $shellbar[0]; + shellbar.addEventListener("ui5-logo-click", () => { + (document.getElementById("press-input") as HTMLInputElement).value = "Logo"; + }); + }); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-logo") + .click(); + + cy.get("#press-input").should("have.value", "Logo"); + }); + + it("tests search-button-click event", () => { + cy.viewport(870, 1680); + + cy.mount( +
+ + + + + +
+ ); + + cy.get("[ui5-shellbar]").then($shellbar => { + const shellbar = $shellbar[0]; + shellbar.addEventListener("ui5-search-button-click", (e) => { + e.preventDefault(); + (document.getElementById("press-input") as HTMLInputElement).value = "Search clicked"; + }); + }); + + cy.get("[ui5-shellbar]").should("have.prop", "showSearchField", false); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-search-button") + .click(); + + cy.get("[ui5-shellbar]").should("have.prop", "showSearchField", false); + + cy.get("#press-input").should("have.value", "Search clicked"); + }); + + it("tests menuItemClick event", () => { + cy.mount( +
+ + + + Application 1 + Application 2 + + +
+ ); + + cy.get("[ui5-li][slot='menuItems']").each(($item) => { + const item = $item[0]; + item.addEventListener("click", () => { + (document.getElementById("press-input") as HTMLInputElement).value = item.textContent.trim(); + (document.getElementById("press-data") as HTMLInputElement).value = item.getAttribute("data-key") || ""; + }); + }); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-menu-button") + .click(); + + cy.get("[ui5-li][slot='menuItems']").first().click(); + + cy.get("#press-input").should("have.value", "Application 1"); + cy.get("#press-data").should("have.value", "key1"); + + cy.get("#press-input").invoke("prop", "value", ""); + cy.get("#press-data").invoke("prop", "value", ""); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-menu-button") + .click(); + + cy.get("[ui5-li][slot='menuItems']").eq(1).click(); + + cy.get("#press-input").should("have.value", "Application 2"); + cy.get("#press-data").should("have.value", "key2"); + }); + + it("tests if searchfield toggles when altering the showSearchField property", () => { + cy.mount( + + + + + ); + + cy.get("[ui5-shellbar]").should("have.prop", "showSearchField", true); + + cy.get("[ui5-shellbar]").invoke("prop", "showSearchField", false); + + cy.get("[ui5-shellbar]").should("have.prop", "showSearchField", false); + + cy.get("[ui5-shellbar]").invoke("prop", "showSearchField", true); + cy.get("[ui5-shellbar]").should("have.prop", "showSearchField", true); + }); + }); + + describe("Small screen", () => { + beforeEach(() => { + cy.viewport(510, 1680); + }); + + it("tests logoClick event", () => { + cy.mount( +
+ + + + +
+ ); + + const title = "SAPLabsBulgaria"; + + cy.get("[ui5-shellbar]").then($shellbar => { + const shellbar = $shellbar[0]; + shellbar.addEventListener("ui5-logo-click", () => { + (document.getElementById("press-input2") as HTMLInputElement).value = title; + }); + }); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-logo") + .click(); + + cy.get("#press-input2").should("have.value", title); + }); + + it("tests opening of menu", () => { + cy.mount( + + Menu Item 1 + Menu Item 2 + + + ); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-menu-button") + .click(); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-menu-popover") + .should("have.prop", "open", true); + }); + + it("tests profileClick event", () => { + cy.mount( +
+ + + + + + + +
+ ); + + cy.get("[ui5-shellbar]").then($shellbar => { + const shellbar = $shellbar[0]; + shellbar.addEventListener("ui5-profile-click", () => { + (document.getElementById("press-input") as HTMLInputElement).value = "Profile"; + }); + }); + + cy.get("[ui5-shellbar]") + .shadow() + .find("[data-profile-btn]") + .click(); + + cy.get("#press-input").should("have.value", "Profile"); + }); + + it("tests productSwitchClick event", () => { + cy.mount( +
+ + + + +
+ ); + + cy.get("[ui5-shellbar]").then($shellbar => { + const shellbar = $shellbar[0]; + shellbar.addEventListener("ui5-product-switch-click", () => { + (document.getElementById("press-input") as HTMLInputElement).value = "Product Switch"; + }); + }); + + cy.get("[ui5-shellbar]") + .shadow() + .find(".ui5-shellbar-button-product-switch") + .click(); + + cy.get("#press-input").should("have.value", "Product Switch"); + }); + + it("tests preventDefault of click on a button with default behavior prevented", () => { + cy.mount( + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + ); cy.viewport(320, 800); cy.get("#shellbar-with-overflow") - .shadow() - .find(".ui5-shellbar-overflow-button") - .should("be.visible"); + .shadow() + .find(".ui5-shellbar-overflow-button") + .should("be.visible"); cy.get("#shellbar-with-overflow") - .shadow() - .find(".ui5-shellbar-overflow-button ui5-button-badge[slot='badge']") - .should("exist") - .should("have.attr", "design", "AttentionDot"); + .shadow() + .find(".ui5-shellbar-overflow-button ui5-button-badge[slot='badge']") + .should("exist") + .should("have.attr", "design", "AttentionDot"); cy.mount( - - - - - - - - - - + + + + + + + + + + ); cy.viewport(320, 800); cy.get("#shellbar-with-single-overflow") - .shadow() - .find(".ui5-shellbar-overflow-button") - .should("be.visible"); + .shadow() + .find(".ui5-shellbar-overflow-button") + .should("be.visible"); cy.get("#shellbar-with-single-overflow") - .shadow() - .find(".ui5-shellbar-overflow-button ui5-button-badge[slot='badge']") - .should("exist") - .should("have.attr", "text", "42"); + .shadow() + .find(".ui5-shellbar-overflow-button ui5-button-badge[slot='badge']") + .should("exist") + .should("have.attr", "text", "42"); }); }); @@ -1272,17 +1254,16 @@ describe("Component Behavior", () => { cy.viewport(1920, 1680); cy.mount( -
- - - Menu Item 1 - Menu Item 2 - - -
+ + Menu Item 1 + Menu Item 2 + + ); - cy.get("#checkKeepPopoverOpen").check(); + cy.get("[ui5-li][slot='menuItems']").first().then($item => { + $item[0].addEventListener("click", cy.stub().as("menuItemClick")); + }); cy.get("[ui5-shellbar]") .shadow() @@ -1290,6 +1271,8 @@ describe("Component Behavior", () => { .click(); cy.get("[ui5-li][slot='menuItems']").first().click(); + cy.get("@menuItemClick") + .should("have.been.calledOnce"); cy.get("[ui5-shellbar]") .shadow() @@ -1299,19 +1282,16 @@ describe("Component Behavior", () => { it("tests close on content click", () => { cy.mount( - <> - - - Application 1 - Application 2 - - + + Application 1 + Application 2 + ); cy.get("[ui5-shellbar]").should("exist"); @@ -1324,7 +1304,9 @@ describe("Component Behavior", () => { expect(shellbar.menuItems.length).to.be.greaterThan(0); }); - cy.get("#checkKeepPopoverOpen").invoke("prop", "checked", false); + cy.get("[ui5-li][slot='menuItems']").first().then($item => { + $item[0].addEventListener("click", cy.stub().as("menuItemClick")); + }); cy.get("[ui5-shellbar]") .shadow() @@ -1343,6 +1325,9 @@ describe("Component Behavior", () => { .should("be.visible") .realClick(); + cy.get("@menuItemClick") + .should("have.been.calledOnce"); + cy.get("[ui5-shellbar]") .shadow() .find(".ui5-shellbar-menu-popover") @@ -1367,22 +1352,17 @@ describe("Component Behavior", () => { it("tests 'click' on custom action", () => { cy.mount( -
- - - - - -
+ + + + ); cy.get("[ui5-shellbar-item]").each(($item) => { const item = $item[0]; - item.addEventListener("click", () => { - const icon = item.getAttribute("icon"); - const value = icon === "accept" ? "accept" : "warning"; - (document.getElementById("press-input3") as HTMLInputElement).value = value; - }); + const icon = item.getAttribute("icon"); + const stubAlias = icon === "accept" ? "acceptClick" : "alertClick"; + item.addEventListener("click", cy.stub().as(stubAlias)); }); cy.get("[ui5-shellbar]") @@ -1390,14 +1370,16 @@ describe("Component Behavior", () => { .find(`.ui5-shellbar-custom-item[icon="accept"]`) .click(); - cy.get("#press-input3").should("have.value", "accept"); + cy.get("@acceptClick") + .should("have.been.calledOnce"); cy.get("[ui5-shellbar]") .shadow() .find(`.ui5-shellbar-custom-item[icon="alert"]`) .click(); - cy.get("#press-input3").should("have.value", "warning"); + cy.get("@alertClick") + .should("have.been.calledOnce"); }); }); }); \ No newline at end of file