diff --git a/packages/main/cypress/specs/Icon.cy.tsx b/packages/main/cypress/specs/Icon.cy.tsx
new file mode 100644
index 000000000000..687ed2e00069
--- /dev/null
+++ b/packages/main/cypress/specs/Icon.cy.tsx
@@ -0,0 +1,277 @@
+import Icon from "../../src/Icon.js";
+import Input from "../../src/Input.js";
+import Label from "../../src/Label.js";
+import "@ui5/webcomponents-icons/dist/add-equipment.js";
+import "@ui5/webcomponents-icons/dist/error.js";
+import "@ui5/webcomponents-icons/dist/add.js";
+import "@ui5/webcomponents-icons/dist/add-equipment.js";
+import testAssets from "../../src/bundle.esm.js";
+import { setTheme } from "@ui5/webcomponents-base/dist/config/Theme.js";
+
+describe("Icon general interaction", () => {
+ it("Tests icon rendering", () => {
+ cy.mount(
+ <>
+
+
+ >
+ );
+
+ cy.get("[ui5-icon][name='add-equipment'][mode='Interactive']")
+ .shadow()
+ .find(".ui5-icon-root")
+ .should("exist");
+
+ cy.get("[ui5-icon][show-tooltip]").then(($icon) => {
+ cy.wrap($icon[0])
+ .invoke("prop", "_id")
+ .then((iconId) => {
+ cy.get("[ui5-icon][show-tooltip]")
+ .shadow()
+ .find(`#${iconId}-tooltip`)
+ .should("contain.text", "Save");
+ });
+ });
+ });
+
+ it("Tests events 'click' and 'ui5-click' events", () => {
+ cy.mount(
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+
+ cy.get("[ui5-icon][mode='Interactive']")
+ .as("interactiveIcon")
+ .then($icon => {
+ $icon.get(0).addEventListener("click", cy.stub().as("interactiveClickStub"));
+ $icon.get(0).addEventListener("ui5-click", cy.stub().as("interactiveUI5ClickStub"));
+ });
+
+ cy.get("[ui5-icon]:not([mode='Interactive'])")
+ .as("nonInteractiveIcon")
+ .then($icon => {
+ $icon.get(0).addEventListener("click", cy.stub().as("nonInteractiveClickStub"));
+ $icon.get(0).addEventListener("ui5-click", cy.stub().as("nonInteractiveUI5ClickStub"));
+ });
+
+ cy.get("@interactiveIcon").then($icon => {
+ let clickCount = 0;
+ let ui5ClickCount = 0;
+
+ $icon.get(0).addEventListener("click", () => {
+ clickCount++;
+ const input = document.querySelectorAll("[ui5-input]")[0] as HTMLInputElement;
+ input.value = clickCount.toString();
+ });
+
+ $icon.get(0).addEventListener("ui5-click", () => {
+ ui5ClickCount++;
+ const input = document.querySelectorAll("[ui5-input]")[1] as HTMLInputElement;
+ input.value = ui5ClickCount.toString();
+ });
+ });
+
+ cy.get("@nonInteractiveIcon").then($icon => {
+ let clickCount = 0;
+ let ui5ClickCount = 0;
+
+ $icon.get(0).addEventListener("click", () => {
+ clickCount++;
+ const input = document.querySelectorAll("[ui5-input]")[2] as HTMLInputElement;
+ input.value = clickCount.toString();
+ });
+
+ $icon.get(0).addEventListener("ui5-click", () => {
+ ui5ClickCount++;
+ const input = document.querySelectorAll("[ui5-input]")[3] as HTMLInputElement;
+ input.value = ui5ClickCount.toString();
+ });
+ });
+
+ cy.get("@interactiveIcon").click();
+ cy.get("[ui5-input]").eq(0).should("have.prop", "value", "1");
+ cy.get("[ui5-input]").eq(1).should("have.prop", "value", "0");
+
+ cy.get("@interactiveIcon").realPress("Enter");
+ cy.get("[ui5-input]").eq(0).should("have.prop", "value", "2");
+ cy.get("[ui5-input]").eq(1).should("have.prop", "value", "1");
+
+ cy.get("@interactiveIcon").realPress("Space");
+ cy.get("[ui5-input]").eq(0).should("have.prop", "value", "3");
+ cy.get("[ui5-input]").eq(1).should("have.prop", "value", "2");
+
+ cy.get("@nonInteractiveIcon").click();
+ cy.get("[ui5-input]").eq(2).should("have.prop", "value", "1");
+ cy.get("[ui5-input]").eq(3).should("have.prop", "value", "0");
+
+ cy.get("@interactiveClickStub").should("have.been.calledThrice");
+ cy.get("@interactiveUI5ClickStub").should("have.been.calledTwice");
+
+ cy.get("@nonInteractiveClickStub").should("have.been.calledOnce");
+ cy.get("@nonInteractiveUI5ClickStub").should("not.have.been.called");
+ });
+
+ it("Tests switch to sap_horizon", () => {
+ cy.mount(
+
+ );
+
+ cy.get("[ui5-icon][name='add-equipment']")
+ .shadow()
+ .find("svg")
+ .should("exist")
+ .within(() => {
+ cy.get("g")
+ .should("not.be.empty")
+ .children()
+ .should("exist");
+ });
+
+ let initialContent;
+ cy.get("[ui5-icon][name='add-equipment']")
+ .shadow()
+ .find("svg")
+ .invoke("prop", "innerHTML")
+ .then((content) => {
+ initialContent = content;
+ cy.log("Initial SVG content:", content);
+ expect(content).to.not.equal('');
+ });
+
+ cy.wrap({ setTheme })
+ .invoke("setTheme", "sap_fiori_3");
+
+ cy.get("[ui5-icon][name='add-equipment']")
+ .shadow()
+ .find("svg")
+ .invoke("prop", "innerHTML")
+ .then((newContent) => {
+ cy.log("New SVG content:", newContent);
+ expect(newContent).to.not.equal(initialContent);
+ expect(newContent).to.not.equal('');
+ });
+ });
+
+ it("Tests icon modules' exported values", () => {
+ const expectedExportedValues = "accept|SAP-icons-v4/accept|SAP-icons-v5/accept|tnt/actor|tnt-v2/actor|tnt-v3/actor|business-suite/3d|business-suite-v1/3d|business-suite-v2/3d";
+
+ const exportedIconValues = testAssets.getExportedIconsValues();
+ const actualExportedValues = exportedIconValues.join("|");
+
+ expect(actualExportedValues).to.equal(expectedExportedValues);
+ });
+
+ it("Icon svg aria-label cleaned after name change", () => {
+ cy.mount(
+
+ );
+
+ cy.get("[ui5-icon][name='error']")
+ .shadow()
+ .find(".ui5-icon-root")
+ .should("have.attr", "aria-label", "Error");
+
+ cy.get("[ui5-icon][name='error']")
+ .invoke("attr", "name", "add");
+
+ cy.get("[ui5-icon][name='add']")
+ .shadow()
+ .find(".ui5-icon-root")
+ .should("have.attr", "aria-label", "Add");
+
+ cy.get("[ui5-icon][name='add']")
+ .invoke("attr", "name", "less");
+
+ cy.get("[ui5-icon][name='less']")
+ .shadow()
+ .find(".ui5-icon-root")
+ .should("not.have.attr", "aria-label");
+ });
+
+ it("Tests getIconAccessibleName", () => {
+ const expectedAccNames = ["Add", "Back to Top", "Collapse", "Download"];
+ const iconNames = ["add", "back-to-top", "collapse", "download"];
+
+ cy.then(async () => {
+ const actualAccNames = await Promise.all(
+ iconNames.map(iconName =>
+ testAssets.getIconAccessibleName(iconName)
+ )
+ );
+
+ expect(actualAccNames.join()).to.equal(expectedAccNames.join());
+ });
+ });
+
+ it("Tests mode property", () => {
+ const interactiveMode = "Interactive";
+ const imageMode = "Image";
+ const decorativeMode = "Decorative";
+
+ cy.mount(
+
+ );
+
+ cy.get("[ui5-icon][name='add-equipment']")
+ .should("have.prop", "mode", decorativeMode);
+
+ cy.get("[ui5-icon][name='add-equipment']")
+ .shadow()
+ .find(".ui5-icon-root")
+ .should("have.attr", "role", "presentation")
+ .should("have.attr", "aria-hidden", "true");
+
+ cy.get("[ui5-icon][name='add-equipment']")
+ .invoke("prop", "mode", interactiveMode);
+
+ cy.get("[ui5-icon][name='add-equipment']")
+ .should("have.prop", "mode", interactiveMode);
+
+ cy.get("[ui5-icon][name='add-equipment']")
+ .shadow()
+ .find(".ui5-icon-root")
+ .should("have.attr", "role", "button");
+
+ cy.get("[ui5-icon][name='add-equipment']")
+ .invoke("prop", "mode", imageMode);
+
+ cy.get("[ui5-icon][name='add-equipment']")
+ .should("have.prop", "mode", imageMode);
+
+ cy.get("[ui5-icon][name='add-equipment']")
+ .shadow()
+ .find(".ui5-icon-root")
+ .should("have.attr", "role", "img");
+ });
+});
\ No newline at end of file
diff --git a/packages/main/test/specs/Icon.spec.js b/packages/main/test/specs/Icon.spec.js
deleted file mode 100644
index 3550711156b4..000000000000
--- a/packages/main/test/specs/Icon.spec.js
+++ /dev/null
@@ -1,138 +0,0 @@
-import { assert } from "chai";
-
-describe("Icon general interaction", () => {
- before(async () => {
- await browser.url(`test/pages/Icon.html`);
- });
-
- it("Tests icon rendering", async () => {
- const iconRoot = await browser.$("#interactive-icon").shadow$("ui5-icon-root");
- const iconWithTooltip = await browser.$("#iconWithTooltip");
- const iconTooltip = await iconWithTooltip.shadow$(`#${await iconWithTooltip.getProperty("_id")}-tooltip`);
- const ICON_TOOLTIP_TEXT = "Save";
-
- assert.ok(iconRoot, "Icon is rendered");
- assert.include(await iconTooltip.getHTML(false), ICON_TOOLTIP_TEXT,
- "Built-in tooltip is correct");
- });
-
- it("Tests events 'click' and 'ui5-click' events", async () => {
- // (1) on mouse click (no matter the noConflict mode), the icon fires the native "click" event
- // (2) on SPACE and ENTER
- // - noConflict: false - the icon fires "click" (custom event)
- // - noConflict: true - the icon fires "click" and "ui5-click" (custom events)
-
- // Interactive icon
- const interactiveIcon = await browser.$("#interactive-icon");
- const inpClickRes = await browser.$("#click-event");
- const inpUI5ClickRes = await browser.$("#ui5-click-event");
-
- await interactiveIcon.click();
- assert.strictEqual(await inpClickRes.getAttribute("value"), "1", "The 'click' event is fired.");
- assert.strictEqual(await inpUI5ClickRes.getAttribute("value"), "0", "The 'ui5-click' event is not fired on mouse click.");
-
- await interactiveIcon.keys("Enter");
- assert.strictEqual(await inpClickRes.getAttribute("value"), "2", "Enter fires 'click'");
- assert.strictEqual(await inpUI5ClickRes.getAttribute("value"), "1", "Enter fires 'ui5-click'");
-
- await interactiveIcon.keys("Space");
- assert.strictEqual(await inpClickRes.getAttribute("value"), "3", "Space fires 'click'");
- assert.strictEqual(await inpUI5ClickRes.getAttribute("value"), "2", "Space fires 'ui5-click'");
-
- // Non-interactive icon
- const nonInteractiveIcon = await browser.$("#non-interactive-icon");
- const inpClickRes2 = await browser.$("#click-event-2");
- const inpUI5ClickRes2 = await browser.$("#ui5-click-event-2");
-
- await nonInteractiveIcon.click();
- assert.strictEqual(await inpClickRes2.getAttribute("value"), "1", "The 'click' event is fired.");
- assert.strictEqual(await inpUI5ClickRes2.getAttribute("value"), "0", "The 'ui5-click' event is not fired on mouse click..");
- });
-
- it("Tests switch to sap_horizon", async () => {
- // assert - initial SVG path
- const iconPath = await browser.$("#myIcon").shadow$(".ui5-icon-root path");
- const pathValue = await iconPath.getAttribute("d");
-
- // act - switch theme
- await browser.executeAsync( async (newTheme, done) => {
- const config = window['sap-ui-webcomponents-bundle'].configuration;
- await config.setTheme(newTheme);
- done();
- }, "sap_fiori_3");
-
- // assert - SVG path changed
- const iconPathAfter = await browser.$("#myIcon").shadow$(".ui5-icon-root path");
- const iconPathValueAfter = await iconPathAfter.getAttribute("d");
- assert.notEqual(iconPathValueAfter, pathValue, "Icon's path is changed in sap_fiori_3.");
- });
-
- it("Tests icon modules' exported values", async () => {
- const expectedExportedValues = "accept|SAP-icons-v4/accept|SAP-icons-v5/accept|tnt/actor|tnt-v2/actor|tnt-v3/actor|business-suite/3d|business-suite-v1/3d|business-suite-v2/3d";
- const actualExportedValues = await browser.executeAsync(done => {
- const exportedIconValues = window["sap-ui-webcomponents-bundle"].getExportedIconsValues();
- done(exportedIconValues.join("|"));
- });
- assert.strictEqual(actualExportedValues, expectedExportedValues, "Exported values are correct.");
- });
-
- it("Icon svg aria-label cleaned after name change", async () => {
- // assert - initial SVG aria-label
- let iconEl = await browser.$("#iconError");
- let iconSVG = await browser.$("#iconError").shadow$(".ui5-icon-root");
- assert.equal(await iconSVG.getAttribute("aria-label"), "Error");
-
- // act
- iconEl.setAttribute("name", "sap-icon://add");
-
- // assert - new aria-label is added to SVG element
- iconEl = await browser.$("#iconError");
- iconSVG = await browser.$("#iconError").shadow$(".ui5-icon-root");
- assert.equal(await iconSVG.getAttribute("aria-label"), "Add");
-
- // act
- iconEl.setAttribute("name", "sap-icon://less");
-
- // assert - new aria-label is added to SVG element
- iconEl = await browser.$("#iconError");
- iconSVG = await browser.$("#iconError").shadow$(".ui5-icon-root");
- assert.equal(await iconSVG.getAttribute("aria-label"), null);
- });
-
- it("Tests getIconAccessibleName", async () => {
- const expectedAccNames = ["Add", "Back to Top", "Collapse", "Download"];
- const actualAccNames = await browser.executeAsync(async done => {
- const values = await Promise.all(["add", "back-to-top", "collapse", "download"].map(iconName => {
- return window["sap-ui-webcomponents-bundle"].getIconAccessibleName(iconName);
- }));
- done(values);
- });
-
- assert.strictEqual(actualAccNames.join(), expectedAccNames.join(),
- "getIconAccessibleName returns the correct icon a11y names.");
- });
-
- it("Tests mode property", async () => {
- let icon = await browser.$("#imageIcon");
- let iconSVG = await browser.$("#imageIcon").shadow$(".ui5-icon-root");
- let mode = icon.getProperty("mode");
- const intercativeMode = "Interactive";
- const imageMode = "Image";
- const decorativeMode = "Decorative";
-
- assert.equal(await mode, decorativeMode, "Decorative mode is correctly set by default.");
- assert.equal(await iconSVG.getAttribute("role"), "presentation", "The SVG for the decorative icon has the correct role.");
- assert.equal(await iconSVG.getAttribute("aria-hidden"), "true", "The SVG for the decorative icon includes aria-hidden=true as expected");
-
- await icon.setProperty("mode", intercativeMode)
- mode = await icon.getProperty("mode");
-
- assert.equal(await mode, intercativeMode, "Interactive mode is correctly set.");
- assert.equal(await iconSVG.getAttribute("role"), "button", "The SVG for the interactive icon has the correct role.");
-
- await icon.setProperty("mode", imageMode)
- mode = await icon.getProperty("mode");
-
- assert.equal(await iconSVG.getAttribute("role"), "img", "The SVG for the image icon has the correct role.");
- });
-});