From f816dbcc91ec96865582e15c6984a328dd69be5a Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Mon, 30 Jun 2025 12:59:46 +0300 Subject: [PATCH 1/5] chore(ui5-avatar): migrate wdio tests to cypress --- packages/main/cypress/specs/Avatar.cy.tsx | 186 +++++++++++++++++++++- packages/main/test/specs/Avatar.spec.js | 156 ------------------ 2 files changed, 183 insertions(+), 159 deletions(-) delete mode 100644 packages/main/test/specs/Avatar.spec.js diff --git a/packages/main/cypress/specs/Avatar.cy.tsx b/packages/main/cypress/specs/Avatar.cy.tsx index ce6689467345..69b423778716 100644 --- a/packages/main/cypress/specs/Avatar.cy.tsx +++ b/packages/main/cypress/specs/Avatar.cy.tsx @@ -39,9 +39,9 @@ describe("Accessibility", () => { cy.mount(
- - - + + +
@@ -306,3 +306,183 @@ describe("Fallback Logic", () => { .should("have.class", "ui5-avatar-fallback-icon-hidden"); }); }); + +describe("Avatar", () => { + let sharedInputValue = 0; + let sharedInputValue2 = 0; + + beforeEach(() => { + cy.mount( +
+ + Woman image + + + + Woman image + + + + + + + + + + +
+ ); + + cy.get("#interactive-avatar").then(($avatar) => { + $avatar[0].addEventListener("ui5-click", function() { + const input = document.getElementById("click-event") as HTMLInputElement; + input.value = `${++sharedInputValue}`; + }); + }); + + cy.get("#non-interactive-avatar").then(($avatar) => { + $avatar[0].addEventListener("ui5-click", function() { + const input = document.getElementById("click-event") as HTMLInputElement; + input.value = `${++sharedInputValue}`; + }); + }); + + cy.get("#myInteractiveAvatar").then(($avatar) => { + $avatar[0].addEventListener("ui5-click", function() { + const input = document.getElementById("click-event-2") as HTMLInputElement; + input.value = `${++sharedInputValue2}`; + }); + }); + }); + + it("tests rendering of image", () => { + cy.get("#myAvatar1") + .shadow() + .find('slot:not([name="badge"])') + .should("exist"); + + cy.get("#myAvatar1") + .shadow() + .find("ui5-avatar-icon") + .should("not.exist"); + }); + + it("tests rendering of icon", () => { + cy.get("#myAvatar2") + .shadow() + .find(".ui5-avatar-icon") + .should("exist"); + + cy.get("#myAvatar2") + .shadow() + .find('slot:not([name="badge"])') + .should("not.exist"); + }); + + it("tests rendering of image, when all set", () => { + cy.get("#myAvatar3") + .shadow() + .find('slot:not([name="badge"])') + .should("exist"); + + cy.get("#myAvatar3") + .shadow() + .find(".ui5-avatar-icon") + .should("not.exist"); + + cy.get("#myAvatar3") + .shadow() + .find(".ui5-avatar-initials") + .should("not.exist"); + }); + + it("tests rendering of initials", () => { + cy.get("#myAvatar4") + .shadow() + .find(".ui5-avatar-initials") + .should("exist"); + }); + + it("tests rendering of accented characters", () => { + cy.get("#myAvatar6") + .shadow() + .find(".ui5-avatar-initials") + .should("exist"); + }); + + it("tests rendering of default fallback icon when initials are overflowing", () => { + cy.get("#myAvatar5") + .shadow() + .find(".ui5-avatar-icon") + .should("exist") + .should("have.attr", "name", "employee"); + }); + + it("tests rendering of custom fallback icon when initials are overflowing", () => { + cy.get("#myAvatar7") + .shadow() + .find(".ui5-avatar-icon-fallback") + .should("exist") + .should("have.attr", "name", "alert"); + }); + + it("Tests noConflict 'ui5-click' event for interactive avatars", () => { + cy.get("#interactive-avatar") + .shadow() + .find(".ui5-avatar-root") + .realClick(); + + cy.get("#click-event") + .should("have.value", "1"); + + cy.get("#interactive-avatar") + .shadow() + .find(".ui5-avatar-root") + .realPress("Enter"); + + cy.get("#click-event") + .should("have.value", "2"); + + cy.get("#interactive-avatar") + .shadow() + .find(".ui5-avatar-root") + .realPress("Space"); + + cy.get("#click-event") + .should("have.value", "3"); + }); + + it("Tests noConflict 'ui5-click' event for non interactive avatars", () => { + cy.get("#non-interactive-avatar") + .shadow() + .find(".ui5-avatar-root") + .realClick(); + + cy.get("#click-event") + .should("have.value", "4"); + + cy.get("#non-interactive-avatar") + .shadow() + .find(".ui5-avatar-root") + .realPress("Enter"); + + cy.get("#click-event") + .should("have.value", "4"); + + cy.get("#non-interactive-avatar") + .shadow() + .find(".ui5-avatar-root") + .realPress("Space"); + + cy.get("#click-event") + .should("have.value", "4"); + }); + + it("Tests native 'click' event thrown", () => { + cy.get("#myInteractiveAvatar") + .realClick(); + + cy.get("#click-event-2") + .should("have.value", "1"); + }); +}); \ No newline at end of file diff --git a/packages/main/test/specs/Avatar.spec.js b/packages/main/test/specs/Avatar.spec.js deleted file mode 100644 index 8dc0b0214b3a..000000000000 --- a/packages/main/test/specs/Avatar.spec.js +++ /dev/null @@ -1,156 +0,0 @@ -import { assert } from "chai"; - -describe("Avatar", () => { - before(async () => { - await browser.url(`test/pages/Avatar.html`); - }); - - it("tests rendering of image", async () => { - const avatar = await browser.$("#myAvatar1"); - const image = await avatar.shadow$('slot:not([name="badge"])'); - const icon = await avatar.shadow$("ui5-avatar-icon"); - - // img tag is rendered, ui5-icon - not - assert.ok(await image.isExisting(), "img is rendered"); - assert.notOk(await icon.isExisting(), "icon is not rendered"); - }); - - it("tests rendering of icon", async () => { - const avatar = await browser.$("#myAvatar2"); - const image = await avatar.shadow$('slot:not([name="badge"])'); - const icon = await avatar.shadow$(".ui5-avatar-icon"); - - // ui5-icon tag is rendered, img - not - assert.notOk(await image.isExisting(), "img is not rendered"); - assert.ok(await icon.isExisting(), "icon is rendered"); - }); - - it("tests rendering of image, when all set", async () => { - const avatar = await browser.$("#myAvatar3"); - const image = await avatar.shadow$('slot:not([name="badge"])'); - const icon = await avatar.shadow$(".ui5-avatar-icon"); - const initials = await avatar.shadow$(".ui5-avatar-initials"); - - // ui5-icon tag is rendered, img - not - assert.ok(await image.isExisting(), "img is rendered"); - assert.notOk(await icon.isExisting(), "icon is not rendered"); - assert.notOk(await initials.isExisting(), "initials are not rendered"); - }); - - it("tests rendering of initials", async () => { - const avatar = await browser.$("#myAvatar4"); - const initials = await avatar.shadow$(".ui5-avatar-initials"); - - // initials are rendered - assert.ok(await initials.isExisting(), "initials are rendered"); - }); - - it("tests rendering of accented characters", async () => { - const avatar = await browser.$("#myAvatar6"); - const initials = await avatar.shadow$(".ui5-avatar-initials"); - - // initials are rendered - assert.ok(await initials.isExisting(), "initials are rendered"); - }); - - it("tests rendering of default fallback icon when initials are overflowing ", async () => { - const avatar = await browser.$("#myAvatar5"); - const icon = await avatar.shadow$(".ui5-avatar-icon"); - const iconName = await icon.getAttribute("name"); - - // icon is rendered - assert.ok(await icon.isExisting(), "icon should be rendered, when the initials are overflowing"); - assert.strictEqual(await iconName, "employee", "the default fallback icon is renderen"); - - }); - - it("tests rendering of custom fallback icon when initials are overflowing ", async () => { - const avatar = await browser.$("#myAvatar7"); - const fbIcon = await avatar.shadow$(".ui5-avatar-icon-fallback"); - const fbIconName = await fbIcon.getAttribute("name"); - - // icon is rendered - assert.ok(await fbIcon.isExisting(), "fallback icon should be rendered, when it is set and the initials are overflowing"); - assert.strictEqual(await fbIconName, "alert", "the custom fallback icon is renderen"); - - }); - - it("Tests noConflict 'ui5-click' event for interactive avatars", async () => { - const avatarRoot = await browser.$("#interactive-avatar").shadow$(".ui5-avatar-root"); - const input = await browser.$("#click-event"); - - await avatarRoot.click(); - assert.strictEqual(await input.getAttribute("value"), "1", "Mouse click throws event"); - - await avatarRoot.keys("Enter"); - assert.strictEqual(await input.getAttribute("value"), "2", "Enter throws event"); - - await avatarRoot.keys("Space"); - assert.strictEqual(await input.getAttribute("value"), "3", "Space throws event"); - }); - - it("Tests noConflict 'ui5-click' event for non interactive avatars", async () => { - const avatarRoot = await browser.$("#non-interactive-avatar").shadow$(".ui5-avatar-root");; - const input = await browser.$("#click-event"); - - await avatarRoot.click(); - assert.strictEqual(await input.getAttribute("value"), "4", "Mouse click thrown"); - - await avatarRoot.keys("Enter"); - assert.strictEqual(await input.getAttribute("value"), "4", "Enter does not throw event"); - - await avatarRoot.keys("Space"); - assert.strictEqual(await input.getAttribute("value"), "4", "Space does not throw event"); - }); - - it("Tests native 'click' event thrown", async () => { - await browser.executeAsync(function(done) { - window["sap-ui-webcomponents-bundle"].configuration.setNoConflict(false); - done(); - }); - - const avatar = await browser.$("#myInteractiveAvatar"); - const input = await browser.$("#click-event-2"); - - await avatar.click(); - assert.strictEqual(await input.getAttribute("value"), "1", "Mouse click throws event"); - }); -}); - -describe("ARIA attributes", () => { - before(async () => { - await browser.url(`test/pages/Avatar.html`); - }); - - it ("role set correctly", async () => { - const avatar = await $("#myInteractiveAvatar");; - const avatarRoot = await avatar.shadow$(".ui5-avatar-root"); - const nonInteractiveAvatar = await $("#non-interactive-avatar");; - const nonInteractiveavatarRoot = await nonInteractiveAvatar.shadow$(".ui5-avatar-root"); - - assert.strictEqual(await avatarRoot.getAttribute("role"), "button", "should have role button for interactive avatar"); - - assert.strictEqual(await nonInteractiveavatarRoot.getAttribute("role"), "img", "should have role img for non-interactive avatar"); - }); - - it ("aria-haspopup is correct for interactive avatar", async () => { - const avatar = await $("#myInteractiveAvatar");; - const ariaHasPopup = await avatar.getProperty("_ariaHasPopup"); - - assert.strictEqual(ariaHasPopup, "menu", "should have aria-haspopup set"); - }); - - it ("aria-haspopup is correct for non-interactive avatar", async () => { - const avatar = await $("#non-interactive-avatar");; - const ariaHasPopup = await avatar.getProperty("_ariaHasPopup"); - - assert.notExists(ariaHasPopup, "should not have aria-haspopup set"); - }); - - it ("aria-label is correctly set", async () => { - const avatar = await $("#interactive-avatar"), - avatarRoot = avatar.shadow$(".ui5-avatar-root"); - - assert.equal(await avatarRoot.getAttribute("aria-label"), await avatar.getAttribute("accessible-name"), "aria-label should be set according to accessibleName property"); - }); -}); From be6a471e48a2b27896de523c62c3e2e96c8371c3 Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Mon, 30 Jun 2025 13:55:17 +0300 Subject: [PATCH 2/5] refactor: change the slot we need to find --- packages/main/cypress/specs/Avatar.cy.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/main/cypress/specs/Avatar.cy.tsx b/packages/main/cypress/specs/Avatar.cy.tsx index 69b423778716..051b1e381183 100644 --- a/packages/main/cypress/specs/Avatar.cy.tsx +++ b/packages/main/cypress/specs/Avatar.cy.tsx @@ -358,7 +358,7 @@ describe("Avatar", () => { it("tests rendering of image", () => { cy.get("#myAvatar1") .shadow() - .find('slot:not([name="badge"])') + .find("slot:not([name])") .should("exist"); cy.get("#myAvatar1") @@ -375,14 +375,14 @@ describe("Avatar", () => { cy.get("#myAvatar2") .shadow() - .find('slot:not([name="badge"])') + .find("slot:not([name])") .should("not.exist"); }); it("tests rendering of image, when all set", () => { cy.get("#myAvatar3") .shadow() - .find('slot:not([name="badge"])') + .find("slot:not([name])") .should("exist"); cy.get("#myAvatar3") From f1d373000fc2e6d4cde7c71cfaed693e57fc0a5b Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Mon, 30 Jun 2025 15:11:45 +0300 Subject: [PATCH 3/5] chore: migrate avatarGroup tests --- .../main/cypress/specs/AvatarGroup.cy.tsx | 307 ++++++++++++++++++ packages/main/test/specs/AvatarGroup.spec.js | 203 ------------ 2 files changed, 307 insertions(+), 203 deletions(-) delete mode 100644 packages/main/test/specs/AvatarGroup.spec.js diff --git a/packages/main/cypress/specs/AvatarGroup.cy.tsx b/packages/main/cypress/specs/AvatarGroup.cy.tsx index 0919ff327bdf..392ee1ffac9d 100644 --- a/packages/main/cypress/specs/AvatarGroup.cy.tsx +++ b/packages/main/cypress/specs/AvatarGroup.cy.tsx @@ -122,4 +122,311 @@ describe("Accessibility", () => { cy.get(`#${labelId}`).should("exist"); }); +}); + +describe("avatar-group rendering", () => { + beforeEach(() => { + cy.mount( +
+ + + + + + + + + + + + + + + + +
+ ); + + // Set up event listener for individual avatar group + cy.get("#avatar-group-individual").then(($avatarGroup) => { + $avatarGroup[0].addEventListener("ui5-click", function(event: CustomEvent) { + const eventTargetRef = document.getElementById("event-target") as HTMLInputElement; + const eventOverflowButtonClicked = document.getElementById("event-overflow-button-clicked") as HTMLInputElement; + + eventTargetRef.value = event.detail.targetRef.tagName; + eventOverflowButtonClicked.value = event.detail.overflowButtonClicked.toString(); + }); + }); + + // Set up event listener for group avatar group - SAME handler as individual + cy.get("#avatar-group-group").then(($avatarGroup) => { + $avatarGroup[0].addEventListener("ui5-click", function(event: CustomEvent) { + const eventTargetRef = document.getElementById("event-target") as HTMLInputElement; + const eventOverflowButtonClicked = document.getElementById("event-overflow-button-clicked") as HTMLInputElement; + + // For group type, use tagName + className + eventTargetRef.value = event.detail.targetRef.tagName + "." + event.detail.targetRef.className; + eventOverflowButtonClicked.value = event.detail.overflowButtonClicked.toString(); + }); + }); + + // Set up reset functionality + cy.get("#reset-btn").then(($btn) => { + $btn[0].addEventListener("click", function() { + (document.getElementById("event-target") as HTMLInputElement).value = ""; + (document.getElementById("event-overflow-button-clicked") as HTMLInputElement).value = ""; + }); + }); + }); + + it("tests if web component is correctly rendered", () => { + cy.get("#avatar-group-individual") + .shadow() + .find("div") + .should("exist"); + + cy.get("#avatar-group-group") + .shadow() + .find("div") + .should("exist"); + }); + + it("tests click event when avatar is clicked", () => { + cy.get("#reset-btn").realClick(); + cy.get("#avatar-1").realClick(); + + cy.get("#event-target") + .should("have.value", "UI5-AVATAR"); + + cy.get("#event-overflow-button-clicked") + .should("have.value", "false"); + }); + + it("tests click event when overflow button is clicked", () => { + cy.get("#reset-btn").realClick(); + + cy.get("#avatar-group-individual") + .shadow() + .find("ui5-button") + .realClick(); + + cy.get("#event-target") + .should("have.value", "UI5-BUTTON"); + + cy.get("#event-overflow-button-clicked") + .should("have.value", "true"); + }); + + it("tests click event avatar group with type group is clicked", () => { + cy.get("#reset-btn").realClick(); + + cy.get("#avatar-group-group") + .shadow() + .find(".ui5-avatar-group-items") + .realClick(); + + cy.get("#event-target") + .should("have.value", "DIV.ui5-avatar-group-items"); + + cy.get("#event-overflow-button-clicked") + .should("have.value", "false"); + }); + + it("tests if hiddenItems is correctly displayed in the overflow button", () => { + cy.viewport(200, 1080); + + cy.get("#avatar-group-individual") + .shadow() + .find("ui5-button") + .should("not.have.text", "") + .invoke("text") + .then((buttonText) => { + cy.get("#avatar-group-individual") + .then(($avatarGroup) => { + const avatarGroup = $avatarGroup[0] as AvatarGroup; + const hiddenItemsCount = avatarGroup.hiddenItems.length; + expect(buttonText).to.equal(`+${hiddenItemsCount}`); + }); + }); + }); + + it("tests if click event is firing only once", () => { + let eventCounter = 0; + + cy.mount( +
+ + + + + + + + + + + + + +
+ ); + + cy.get("#avatar-group-individual-events").then(($avatarGroup) => { + $avatarGroup[0].addEventListener("ui5-click", function() { + const eventAvatarsClicked = document.getElementById("event-avatars-clicked") as HTMLInputElement; + eventAvatarsClicked.value = (parseInt(eventAvatarsClicked.value) + 1).toString(); + }); + }); + + cy.get("#avatar-group-group-events").then(($avatarGroup) => { + $avatarGroup[0].addEventListener("ui5-click", function() { + const eventAvatarsClicked = document.getElementById("event-avatars-clicked") as HTMLInputElement; + eventAvatarsClicked.value = (parseInt(eventAvatarsClicked.value) + 1).toString(); + }); + }); + + cy.get("#avatar-1-test-events").realClick(); + cy.get("#event-avatars-clicked").should("have.value", (++eventCounter).toString()); + + cy.get("#avatar-1-test-events").realPress("Enter"); + cy.get("#event-avatars-clicked").should("have.value", (++eventCounter).toString()); + + cy.get("#avatar-1-test-events").realPress("Space"); + cy.get("#event-avatars-clicked").should("have.value", (++eventCounter).toString()); + + cy.get("#avatar-group-individual-events") + .shadow() + .find("ui5-button") + .realClick(); + cy.get("#event-avatars-clicked").should("have.value", (++eventCounter).toString()); + + cy.get("#avatar-group-individual-events") + .shadow() + .find("ui5-button") + .realPress("Enter"); + cy.get("#event-avatars-clicked").should("have.value", (++eventCounter).toString()); + + cy.get("#avatar-group-individual-events") + .shadow() + .find("ui5-button") + .realPress("Space"); + cy.get("#event-avatars-clicked").should("have.value", (++eventCounter).toString()); + + cy.get("#avatar-group-group-events").realClick(); + cy.get("#event-avatars-clicked").should("have.value", (++eventCounter).toString()); + + cy.get("#avatar-group-group-events").realPress("Enter"); + cy.get("#event-avatars-clicked").should("have.value", (++eventCounter).toString()); + + cy.get("#avatar-group-group-events").realPress("Space"); + cy.get("#event-avatars-clicked").should("have.value", (++eventCounter).toString()); + }); +}); + +describe("ARIA attributes", () => { + describe("Type Individual", () => { + beforeEach(() => { + cy.mount( +
+ + + + + + + + + + +
+ ); + }); + + it("role is correct", () => { + cy.get("#avatar-group-individual") + .should("have.prop", "_role", "group"); + }); + + it("aria-haspopup is correct", () => { + cy.get("#avatar-group-individual").then(($avatarGroup) => { + ($avatarGroup[0] as any).accessibilityAttributes = { hasPopup: "menu" }; + }); + + + cy.get("#avatar-group-individual") + .then(($avatarGroup) => { + const avatarGroup = $avatarGroup[0] as AvatarGroup; + + expect(avatarGroup._containerAriaHasPopup).to.be.undefined; + + expect(avatarGroup._overflowButtonAccAttributes).to.exist; + expect(avatarGroup._overflowButtonAccAttributes.hasPopup).to.equal("menu"); + }); + }); + + it("aria-label is correct", () => { + cy.get("#avatar-group-individual") + .then(($avatarGroup) => { + const ariaLabel = ($avatarGroup[0] as AvatarGroup)._ariaLabelText; + expect(ariaLabel).to.include("Individual avatars"); + expect(ariaLabel).to.not.include("Show complete list"); + expect(ariaLabel).to.include("Press ARROW keys"); + }); + + cy.get("#avatar-group-individual") + .then(($avatarGroup) => { + const overflowButtonLabel = ($avatarGroup[0] as AvatarGroup)._overflowButtonAriaLabelText; + expect(overflowButtonLabel).to.include("Activate for complete list"); + }); + }); + }); + + describe("Type Group", () => { + beforeEach(() => { + cy.mount( + + + + + + ); + }); + + it("role is correct", () => { + cy.get("#avatar-group-group") + .should("have.prop", "_role", "button"); + }); + + it("aria-haspopup is correct", () => { + cy.get("#avatar-group-group").then(($avatarGroup) => { + ($avatarGroup[0] as AvatarGroup).accessibilityAttributes = { hasPopup: "menu" }; + }); + + cy.get("#avatar-group-group") + .then(($avatarGroup) => { + const avatarGroup = $avatarGroup[0] as AvatarGroup; + + expect(avatarGroup._containerAriaHasPopup).to.equal("menu"); + + if (avatarGroup._overflowButtonAccAttributes) { + expect(avatarGroup._overflowButtonAccAttributes.hasPopup).to.be.undefined; + } + }); + }); + + it("aria-label is correct", () => { + cy.get("#avatar-group-group") + .then(($avatarGroup) => { + const avatarGroup = $avatarGroup[0] as AvatarGroup; + const ariaLabel = avatarGroup._ariaLabelText; + const overflowButtonLabel = avatarGroup._overflowButtonAriaLabelText; + + expect(ariaLabel).to.include("Conjoined avatars"); + expect(ariaLabel).to.include("Activate for complete list"); + expect(ariaLabel).to.not.include("Press ARROW keys"); + + expect(overflowButtonLabel).to.be.undefined; + }); + }); + }); }); \ No newline at end of file diff --git a/packages/main/test/specs/AvatarGroup.spec.js b/packages/main/test/specs/AvatarGroup.spec.js deleted file mode 100644 index ce8176a92844..000000000000 --- a/packages/main/test/specs/AvatarGroup.spec.js +++ /dev/null @@ -1,203 +0,0 @@ -import { assert } from "chai"; - -async function getResourceBundleTexts(keys) { - return browser.executeAsync((keys, done) => { - const avatarGroup = document.getElementById("avatar-group-group"); - - const texts = keys.reduce((result, key) => { - result[key] = avatarGroup.constructor.i18nBundle.getText(window["sap-ui-webcomponents-bundle"].defaultTexts[key]) - return result; - }, {}); - done(texts); - - }, keys); -} - -describe("avatar-group rendering", () => { - before(async () => { - await browser.url(`test/pages/AvatarGroup.html`); - }); - - it("tests if web component is correctly rendered", async () => { - const avatarGroupIndividual = await browser.$("#avatar-group-individual").shadow$("div"); - const avatarGroupGroup = await browser.$("#avatar-group-group").shadow$("div"); - - assert.ok(avatarGroupIndividual, "AvatarGroup mode 'Individual' rendered"); - assert.ok(avatarGroupGroup, "AvatarGroup mode 'Group' rendered"); - }); - - it("tests click event when avatar is clicked", async () => { - const avatar = await browser.$("#avatar-1"); - - const eventTargetRef = await browser.$("#event-target"); - const eventOverflowButtonClicked = await browser.$("#event-overflow-button-clicked"); - const resetBtn = await browser.$("#reset-btn"); - - - await resetBtn.click(); - await avatar.click(); - - assert.strictEqual(await eventTargetRef.getValue(), await avatar.getProperty("tagName"), "Event should be called with ui5-avatar as targetRef"); - assert.strictEqual(await eventOverflowButtonClicked.getValue(), "false", "Event should be called with overflowButtonClicked equal to false"); - }); - - it("tests click event when overflow button is clicked", async () => { - const overflowButton = await browser.$("#avatar-group-individual").shadow$("ui5-button"); - - const eventTargetRef = await browser.$("#event-target"); - const eventOverflowButtonClicked = await browser.$("#event-overflow-button-clicked"); - const resetBtn = await browser.$("#reset-btn"); - - await resetBtn.click(); - await overflowButton.click(); - - assert.strictEqual(await eventTargetRef.getValue(), await overflowButton.getProperty("tagName"), "Event should be called with ui5-button as targetRef"); - assert.strictEqual(await eventOverflowButtonClicked.getValue(), "true", "Event should be called with overflowButtonClicked equal to true"); - }); - - it("tests click event avatar group with type group is clicked", async () => { - const avatarGroup = await browser.$("#avatar-group-group"); - - const eventTargetRef = await browser.$("#event-target"); - const eventOverflowButtonClicked = await browser.$("#event-overflow-button-clicked"); - const resetBtn = await browser.$("#reset-btn"); - - await resetBtn.click(); - await avatarGroup.click(); - - assert.strictEqual(await eventTargetRef.getValue(), "DIV.ui5-avatar-group-items", "Event should be called with ui5-button as targetRef"); - assert.strictEqual(await eventOverflowButtonClicked.getValue(), "false", "Event should be called with overflowButtonClicked equal to false"); - }); - - it("tests if hiddenItems is correctly displayed in the overflow button", async () => { - await browser.setWindowSize(200, 1080); - - const avatarGroup = await browser.$("#avatar-group-individual"); - const overflowButton = await browser.$("#avatar-group-individual").shadow$("ui5-button"); - - const hiddenItemsCount = (await avatarGroup.getProperty("hiddenItems")).length; - const overflowButtonText = await overflowButton.getText(); - - assert.strictEqual(`+${hiddenItemsCount}`, overflowButtonText, "Overflow button shows the hidden items count correctly"); - }); - - it("tests if click event is firing only once", async () => { - await browser.url(`test/pages/AvatarGroup.html`); - let eventCounter = 0; - - const avatar = await browser.$("#avatar-1-test-events"); - const overflowButton = await browser.$("#avatar-group-individual-events").shadow$("ui5-button"); - const avatarGroupTypeGroup = await browser.$("#avatar-group-group-events"); - const eventAvatarsClicked = await browser.$("#event-avatars-clicked"); - const getEventsCount = async () => parseInt(await eventAvatarsClicked.getValue()); - - await avatar.click() // set focus (important for the keys interaction to take action) - assert.strictEqual(await getEventsCount(), ++eventCounter, "Avatar group 'click' event only fires once per mouse click interaction - Avatar"); - await avatar.keys('Enter'); - assert.strictEqual(await getEventsCount(), ++eventCounter, "Avatar group 'click' event only fires once per keyboard 'Enter' interaction - Avatar"); - await avatar.keys('Space'); - assert.strictEqual(await getEventsCount(), ++eventCounter, "Avatar group 'click' event only fires once per keyboard 'Space' interaction - Avatar"); - - await overflowButton.click() // set focus (important for the keys interaction to take action) - assert.strictEqual(await getEventsCount(), ++eventCounter, "Avatar group 'click' event only fires once per mouse click interaction - Overflow Button"); - await overflowButton.keys('Enter'); - assert.strictEqual(await getEventsCount(), ++eventCounter, "Avatar group 'click' event only fires once per keyboard 'Enter' interaction - Overflow Button"); - await overflowButton.keys('Space'); - assert.strictEqual(await getEventsCount(), ++eventCounter, "Avatar group 'click' event only fires once per keyboard 'Space' interaction - Overflow Button"); - - await avatarGroupTypeGroup.click() // set focus (important for the keys interaction to take action) - assert.strictEqual(await getEventsCount(), ++eventCounter, "Avatar group 'click' event only fires once per mouse click interaction - Avatar Group type Group"); - await avatarGroupTypeGroup.keys('Enter'); - assert.strictEqual(await getEventsCount(), ++eventCounter, "Avatar group 'click' event only fires once per keyboard 'Enter' interaction - Avatar Group type Group"); - await avatarGroupTypeGroup.keys('Space'); - assert.strictEqual(await getEventsCount(), ++eventCounter, "Avatar group 'click' event only fires once per keyboard 'Space' interaction - Avatar Group type Group"); - }); -}); - -describe("ARIA attributes", () => { - before(async () => { - await browser.url(`test/pages/AvatarGroup.html`); - }); - - describe("Type Individual", () => { - - it("role is correct", async () => { - const avatarGroup = await browser.$("#avatar-group-individual"); - const role = await avatarGroup.getProperty("_role"); - - assert.strictEqual(role, "group", "should have role group for individual avatars"); - }); - - it("aria-haspopup is correct", async () => { - const avatarGroup = await browser.$("#avatar-group-individual"); - const ariaHasPopupContainer = await avatarGroup.getProperty("_containerAriaHasPopup"); - const overflowButtonAccAttributes = await avatarGroup.getProperty("_overflowButtonAccAttributes"); - - // container - assert.notExists(ariaHasPopupContainer, "should not have aria-haspopup attribute"); - // overflow button - assert.strictEqual(overflowButtonAccAttributes.hasPopup, "menu", "overflow button should have aria-haspopup for type individual"); - }); - - it("aria-label is correct", async () => { - const avatarGroup = await browser.$("#avatar-group-individual"); - const ariaLabel = await avatarGroup.getProperty("_ariaLabelText"); - const overflowButtonLabel = await avatarGroup.getProperty("_overflowButtonAriaLabelText"); - - const keys = [ - "AVATAR_GROUP_SHOW_COMPLETE_LIST_LABEL", - "AVATAR_GROUP_ARIA_LABEL_INDIVIDUAL", - "AVATAR_GROUP_MOVE", - ]; - const texts = await getResourceBundleTexts(keys); - - // container - assert.include(ariaLabel, texts.AVATAR_GROUP_ARIA_LABEL_INDIVIDUAL, "aria-label type message reference is correct"); - assert.notInclude(ariaLabel, texts.AVATAR_GROUP_SHOW_COMPLETE_LIST_LABEL, "should not have aria-label activate message"); - assert.include(ariaLabel, texts.AVATAR_GROUP_MOVE, "aria-label navigation message reference is correct"); - // overflow button - assert.include(overflowButtonLabel, texts.AVATAR_GROUP_SHOW_COMPLETE_LIST_LABEL, "overflow button should have aria-label for type individual"); - }); - }); - - describe("Type Group", () => { - - it("role is correct", async () => { - const avatarGroup = await browser.$("#avatar-group-group"); - const role = await avatarGroup.getProperty("_role"); - - assert.strictEqual(role, "button", "should have role button for grouped avatars"); - }); - - it("aria-haspopup is correct", async () => { - const avatarGroup = await browser.$("#avatar-group-group"); - const ariaHasPopupContainer = await avatarGroup.getProperty("_containerAriaHasPopup"); - const overflowButtonAccAttributes = await avatarGroup.getProperty("_overflowButtonAccAttributes"); - - // container - assert.strictEqual(ariaHasPopupContainer, "menu", "should have 'menu' set to aria-haspopup attribute"); - // overflow button - assert.notExists(overflowButtonAccAttributes.ariaHaspopup, "overflow button should not have aria-haspopup for type group"); - }); - - it("aria-label is correct", async () => { - const avatarGroup = await browser.$("#avatar-group-group"); - const ariaLabel = await avatarGroup.getProperty("_ariaLabelText"); - const overflowButtonLabel = await avatarGroup.getProperty("_overflowButtonAriaLabelText"); - - const keys = [ - "AVATAR_GROUP_SHOW_COMPLETE_LIST_LABEL", - "AVATAR_GROUP_ARIA_LABEL_GROUP", - "AVATAR_GROUP_MOVE" - ]; - const texts = await getResourceBundleTexts(keys); - - // container - assert.include(ariaLabel, texts.AVATAR_GROUP_ARIA_LABEL_GROUP, "aria-label type message reference is correct"); - assert.include(ariaLabel, texts.AVATAR_GROUP_SHOW_COMPLETE_LIST_LABEL, "should have aria-label activate message"); - assert.notInclude(ariaLabel, texts.AVATAR_GROUP_MOVE, "should not have aria-label navigation message"); - // overflow button - assert.notExists(overflowButtonLabel, "overflow button should not have aria-label activate message"); - }); - }); -}); From 5ffbfcfbc3dab9a78217b31668c73e4056bb29fe Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Mon, 30 Jun 2025 15:33:44 +0300 Subject: [PATCH 4/5] refactor: add prefix for failing tests --- packages/main/cypress/specs/Avatar.cy.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/main/cypress/specs/Avatar.cy.tsx b/packages/main/cypress/specs/Avatar.cy.tsx index 051b1e381183..6bbbbeeca557 100644 --- a/packages/main/cypress/specs/Avatar.cy.tsx +++ b/packages/main/cypress/specs/Avatar.cy.tsx @@ -358,9 +358,9 @@ describe("Avatar", () => { it("tests rendering of image", () => { cy.get("#myAvatar1") .shadow() - .find("slot:not([name])") + .find(".ui5-avatar-root slot:not([name])") .should("exist"); - + cy.get("#myAvatar1") .shadow() .find("ui5-avatar-icon") @@ -382,7 +382,7 @@ describe("Avatar", () => { it("tests rendering of image, when all set", () => { cy.get("#myAvatar3") .shadow() - .find("slot:not([name])") + .find(".ui5-avatar-root slot:not([name])") .should("exist"); cy.get("#myAvatar3") From 52af4ec616aab14cc9853e734ca5da0bce243dd6 Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Mon, 30 Jun 2025 16:34:29 +0300 Subject: [PATCH 5/5] refactor: change the image src --- packages/main/cypress/specs/Avatar.cy.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/main/cypress/specs/Avatar.cy.tsx b/packages/main/cypress/specs/Avatar.cy.tsx index 6bbbbeeca557..58c8160ae20e 100644 --- a/packages/main/cypress/specs/Avatar.cy.tsx +++ b/packages/main/cypress/specs/Avatar.cy.tsx @@ -315,11 +315,11 @@ describe("Avatar", () => { cy.mount(
- Woman image + Woman image - Woman image + Woman image @@ -360,7 +360,7 @@ describe("Avatar", () => { .shadow() .find(".ui5-avatar-root slot:not([name])") .should("exist"); - + cy.get("#myAvatar1") .shadow() .find("ui5-avatar-icon")