diff --git a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarClassNamesIT.java b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarClassNamesIT.java index 13097e89672..34f5e9f92b7 100644 --- a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarClassNamesIT.java +++ b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarClassNamesIT.java @@ -22,9 +22,10 @@ import org.junit.Test; import org.openqa.selenium.By; +import com.vaadin.flow.component.menubar.testbench.MenuBarButtonElement; import com.vaadin.flow.component.menubar.testbench.MenuBarElement; +import com.vaadin.flow.component.menubar.testbench.MenuBarItemElement; import com.vaadin.flow.testutil.TestPath; -import com.vaadin.testbench.TestBenchElement; import com.vaadin.tests.AbstractComponentIT; @TestPath("vaadin-menu-bar/menu-bar-class-names") @@ -42,7 +43,7 @@ public void init() { @Test public void toggleMenuItemClassName_classNameIsToggled() { - TestBenchElement menuButton1 = menuBar.getButtons().get(0); + MenuBarButtonElement menuButton1 = menuBar.getButtons().get(0); Assert.assertFalse(menuButton1.hasAttribute("class")); click("toggle-item1-class-name"); menuButton1 = menuBar.getButtons().get(0); @@ -56,7 +57,7 @@ public void toggleMenuItemClassName_classNameIsToggled() { @Test public void setMenuItemClassName_classNameIsSet() { - TestBenchElement menuButton1 = menuBar.getButtons().get(0); + MenuBarButtonElement menuButton1 = menuBar.getButtons().get(0); Assert.assertFalse(menuButton1.hasAttribute("class")); click("toggle-item1-class-name"); menuButton1 = menuBar.getButtons().get(0); @@ -72,7 +73,7 @@ public void setMenuItemClassName_classNameIsSet() { @Test public void toggleMenuItemClassNameWithSetClassName_classNameIsToggled() { - TestBenchElement menuButton1 = menuBar.getButtons().get(0); + MenuBarButtonElement menuButton1 = menuBar.getButtons().get(0); Assert.assertFalse(menuButton1.hasAttribute("class")); click("set-unset-item1-class-name"); menuButton1 = menuBar.getButtons().get(0); @@ -86,7 +87,7 @@ public void toggleMenuItemClassNameWithSetClassName_classNameIsToggled() { @Test public void toggleMultipleItemClassName_classNamesAreToggled() { - TestBenchElement menuButton1 = menuBar.getButtons().get(0); + MenuBarButtonElement menuButton1 = menuBar.getButtons().get(0); Assert.assertFalse(menuButton1.hasAttribute("class")); click("add-remove-multiple-classes"); menuButton1 = menuBar.getButtons().get(0); @@ -178,7 +179,7 @@ public void menuItemWithClassNameInOverflow_changeClassName_classNameIsChanged() menuBar.getOverflowButton().click(); click("change-item2-class-name"); menuBar.getOverflowButton().click(); - TestBenchElement menuItem = menuBar.getSubMenuItems().get(0); + MenuBarItemElement menuItem = menuBar.getSubMenuItems().get(0); Assert.assertEquals( Set.of(MenuBarClassNamesPage.MENU_ITEM_SECOND_CLASS_NAME), menuItem.getClassNames()); @@ -192,7 +193,7 @@ public void menuItemWithClassNameInOverflow_removeClassName_classNameIsRemoved() menuBar.getOverflowButton().click(); click("remove-item2-class-name"); menuBar.getOverflowButton().click(); - TestBenchElement menuItem = menuBar.getSubMenuItems().get(0); + MenuBarItemElement menuItem = menuBar.getSubMenuItems().get(0); Assert.assertEquals(Set.of(), menuItem.getClassNames()); } @@ -205,7 +206,7 @@ public void menuItemWithClassNameInOverflow_menuItemLeavesOverflow_classNameCanB click("reset-width"); waitForResizeObserver(); click("change-item2-class-name"); - TestBenchElement menuItem = menuBar.getButtons().get(1); + MenuBarButtonElement menuItem = menuBar.getButtons().get(1); Assert.assertEquals( Set.of(MenuBarClassNamesPage.MENU_ITEM_SECOND_CLASS_NAME), menuItem.getClassNames()); @@ -246,7 +247,7 @@ private void waitForResizeObserver() { private void verifySubMenuItemClassNames(boolean containsClassNames, String... classNames) { openSubMenu(); - TestBenchElement subMenuItem = menuBar.getSubMenuItems().get(2); + MenuBarItemElement subMenuItem = menuBar.getSubMenuItems().get(2); var subMenuItemClassNames = subMenuItem.getClassNames(); for (String className : classNames) { if (containsClassNames) { diff --git a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarDetachReattachIT.java b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarDetachReattachIT.java index e64834eaf98..24083a22350 100644 --- a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarDetachReattachIT.java +++ b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarDetachReattachIT.java @@ -20,9 +20,9 @@ import org.junit.Test; import org.openqa.selenium.By; +import com.vaadin.flow.component.menubar.testbench.MenuBarButtonElement; import com.vaadin.flow.component.menubar.testbench.MenuBarElement; import com.vaadin.flow.testutil.TestPath; -import com.vaadin.testbench.TestBenchElement; import com.vaadin.tests.AbstractComponentIT; @TestPath("vaadin-menu-bar/detach-reattach") @@ -55,7 +55,7 @@ public void setI18n_i18nIsUpdated() { waitForResizeObserver(); - TestBenchElement overflowButton = menuBar.getOverflowButton(); + MenuBarButtonElement overflowButton = menuBar.getOverflowButton(); Assert.assertEquals("More options", overflowButton.getDomAttribute("aria-label")); @@ -74,7 +74,7 @@ public void setI18n_detach_attach_i18nIsPersisted() { click("set-i18n"); - TestBenchElement overflowButton = menuBar.getOverflowButton(); + MenuBarButtonElement overflowButton = menuBar.getOverflowButton(); Assert.assertEquals("more-options", overflowButton.getDomAttribute("aria-label")); diff --git a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarPageIT.java b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarPageIT.java index 1d7d1d1e1c5..3f3586207c2 100644 --- a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarPageIT.java +++ b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarPageIT.java @@ -23,7 +23,9 @@ import org.junit.Test; import org.openqa.selenium.By; +import com.vaadin.flow.component.menubar.testbench.MenuBarButtonElement; import com.vaadin.flow.component.menubar.testbench.MenuBarElement; +import com.vaadin.flow.component.menubar.testbench.MenuBarItemElement; import com.vaadin.flow.testutil.TestPath; import com.vaadin.testbench.TestBenchElement; import com.vaadin.tests.AbstractComponentIT; @@ -99,9 +101,9 @@ public void openSubSubMenu_clickCheckableItem_checkableStateChanges() { hoverOn(menuBar.getSubMenuItems().get(1)); waitUntil(driver -> menuBar.getAllSubMenus().size() == 2); - TestBenchElement checkableItem = menuBar + MenuBarItemElement checkableItem = menuBar .getSubMenuItems(menuBar.getAllSubMenus().get(1)).get(1); - Assert.assertTrue(checkableItem.hasAttribute("menu-item-checked")); + Assert.assertTrue(checkableItem.isChecked()); checkableItem.click(); verifyClosed(); @@ -110,16 +112,16 @@ public void openSubSubMenu_clickCheckableItem_checkableStateChanges() { openSubSubMenu(); checkableItem = menuBar.getSubMenuItems(menuBar.getAllSubMenus().get(1)) .get(1); - Assert.assertFalse(checkableItem.hasAttribute("menu-item-checked")); + Assert.assertFalse(checkableItem.isChecked()); } @Test public void setCheckedExternally_openSubMenu_itemChecked() { click("toggle-checked"); openSubSubMenu(); - TestBenchElement checkableItem = menuBar + MenuBarItemElement checkableItem = menuBar .getSubMenuItems(menuBar.getAllSubMenus().get(1)).get(1); - Assert.assertTrue(checkableItem.hasAttribute("menu-item-checked")); + Assert.assertTrue(checkableItem.isChecked()); } @Test @@ -160,7 +162,7 @@ public void buttonsOverflow_itemsMovedToOverflowSubMenu() { click("set-width"); waitForResizeObserver(); click("add-root-item"); - TestBenchElement overflowButton = menuBar.getOverflowButton(); + MenuBarButtonElement overflowButton = menuBar.getOverflowButton(); Assert.assertNotNull("Expected the overflow button to be rendered", overflowButton); assertButtonContents("item 1"); @@ -200,8 +202,10 @@ public void changeItems_clickRootItemWithClickListener_clickListenerCalledOnce() public void buttonWithClickListenerOverflows_clickListenerWorksInSubMenu() { click("set-width"); waitForResizeObserver(); - menuBar.getOverflowButton().click(); - menuBar.getSubMenuItems().get(0).click(); + var overflowButton = menuBar.getOverflowButton(); + overflowButton.click(); + Assert.assertNotNull(menuBar.getSubMenu()); + menuBar.getSubMenuItems(overflowButton.getSubMenu()).get(0).click(); assertMessage("clicked item 2"); } @@ -243,7 +247,7 @@ public void buttonsReflectDisabledStateOfMenuItems() { @Test public void disableButton_removeDisabledAttribute_click_listenerNotCalled() { click("toggle-disable"); - TestBenchElement button2 = menuBar.getButtons().get(1); + MenuBarButtonElement button2 = menuBar.getButtons().get(1); executeScript("arguments[0].disabled=false;" + "arguments[0].querySelector('vaadin-menu-bar-item').disabled=false;", button2); @@ -417,7 +421,7 @@ private String[] getOverlayMenuItemContents(TestBenchElement overlay) { } private String[] getOverlayMenuItemContents( - List menuItems) { + List menuItems) { return menuItems.stream().map(item -> item.getDomProperty("innerHTML")) .toArray(String[]::new); } diff --git a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarThemeIT.java b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarThemeIT.java index fc3ae6348ee..9b10c46fc72 100644 --- a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarThemeIT.java +++ b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarThemeIT.java @@ -20,9 +20,9 @@ import org.junit.Test; import org.openqa.selenium.By; +import com.vaadin.flow.component.menubar.testbench.MenuBarButtonElement; import com.vaadin.flow.component.menubar.testbench.MenuBarElement; import com.vaadin.flow.testutil.TestPath; -import com.vaadin.testbench.TestBenchElement; import com.vaadin.tests.AbstractComponentIT; @TestPath("vaadin-menu-bar/menu-bar-theme") @@ -50,7 +50,7 @@ public void toggleMenuBarTheme_themeIsToggled() { @Test public void toggleMenuItemTheme_themeIsToggled() { - TestBenchElement menuButton1 = menuBar.getButtons().get(0); + MenuBarButtonElement menuButton1 = menuBar.getButtons().get(0); Assert.assertFalse(menuButton1.hasAttribute("theme")); click("toggle-item-1-theme"); menuButton1 = menuBar.getButtons().get(0); @@ -66,7 +66,7 @@ public void setMenuItemTheme_toggleVisibility_themeIsPreserved() { click("toggle-item-1-theme"); click("toggle-item-1-visibility"); click("toggle-item-1-visibility"); - TestBenchElement menuButton1 = menuBar.getButtons().get(0); + MenuBarButtonElement menuButton1 = menuBar.getButtons().get(0); Assert.assertEquals(menuButton1.getDomAttribute("theme"), MenuBarThemePage.MENU_ITEM_THEME); } @@ -77,7 +77,7 @@ public void setMenuItemTheme_hide_resetTheme_show_themeIsUnset() { click("toggle-item-1-visibility"); click("toggle-item-1-theme"); click("toggle-item-1-visibility"); - TestBenchElement menuButton1 = menuBar.getButtons().get(0); + MenuBarButtonElement menuButton1 = menuBar.getButtons().get(0); Assert.assertFalse(menuButton1.hasAttribute("theme")); } @@ -112,7 +112,7 @@ public void toggleMenuBarTheme_toggleMenuItemTheme_themeIsOverridden() { click("toggle-theme"); click("toggle-item-1-theme"); - TestBenchElement menuButton1 = menuBar.getButtons().get(0); + MenuBarButtonElement menuButton1 = menuBar.getButtons().get(0); Assert.assertEquals(MenuBarThemePage.MENU_ITEM_THEME, menuButton1.getDomAttribute("theme")); } diff --git a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarVisibilityIT.java b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarVisibilityIT.java index 6d86887c96b..b910022ac54 100644 --- a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarVisibilityIT.java +++ b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-flow-integration-tests/src/test/java/com/vaadin/flow/component/menubar/tests/MenuBarVisibilityIT.java @@ -19,6 +19,7 @@ import org.junit.Before; import org.junit.Test; +import com.vaadin.flow.component.menubar.testbench.MenuBarButtonElement; import com.vaadin.flow.component.menubar.testbench.MenuBarElement; import com.vaadin.flow.testutil.TestPath; import com.vaadin.testbench.TestBenchElement; @@ -58,7 +59,7 @@ public void hide_disableMenuItem_show_buttonIsDisabled() { Assert.assertTrue(menuBar.isDisplayed()); // Check that the menu item is disabled. - TestBenchElement button = menuBar.getButtons().get(0); + MenuBarButtonElement button = menuBar.getButtons().get(0); Assert.assertTrue(button.getPropertyBoolean("disabled")); } diff --git a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-testbench/src/main/java/com/vaadin/flow/component/menubar/testbench/MenuBarButtonElement.java b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-testbench/src/main/java/com/vaadin/flow/component/menubar/testbench/MenuBarButtonElement.java new file mode 100644 index 00000000000..85892952a75 --- /dev/null +++ b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-testbench/src/main/java/com/vaadin/flow/component/menubar/testbench/MenuBarButtonElement.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2025 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.flow.component.menubar.testbench; + +import java.util.List; + +import org.openqa.selenium.support.ui.ExpectedConditions; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elementsbase.Element; + +/** + * A TestBench element representing a {@code } element. + */ +@Element("vaadin-menu-bar-button") +public class MenuBarButtonElement extends TestBenchElement { + + /** + * Get the sub menu overlay element linked to this menu button. + * + * @return TestBenchElement for the open sub menu. + */ + public TestBenchElement getSubMenu() { + waitForSubMenu(); + return getPropertyElement("__overlay"); + } + + /** + * Get TestBenchElements representing sub menu items under this button. + * + * @return List of MenuBarItemElement representing sub menu items. + */ + public List getSubMenuItems() { + return getSubMenu().$(MenuBarItemElement.class).all(); + } + + /** + * Check if the button has open sub menu. + * + * @return True if there is sub menu open + */ + public boolean isExpanded() { + return hasAttribute("expanded"); + } + + private void waitForSubMenu() { + waitUntil(ExpectedConditions.attributeToBe(this, "aria-expanded", + "true")); + } + +} diff --git a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-testbench/src/main/java/com/vaadin/flow/component/menubar/testbench/MenuBarElement.java b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-testbench/src/main/java/com/vaadin/flow/component/menubar/testbench/MenuBarElement.java index 3f1b399f0cd..b92010f9766 100644 --- a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-testbench/src/main/java/com/vaadin/flow/component/menubar/testbench/MenuBarElement.java +++ b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-testbench/src/main/java/com/vaadin/flow/component/menubar/testbench/MenuBarElement.java @@ -17,7 +17,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; import org.openqa.selenium.By; @@ -27,8 +26,7 @@ import com.vaadin.testbench.elementsbase.Element; /** - * A TestBench element representing a <vaadin-menu-bar> - * element. + * A TestBench element representing a {@code } element. */ @Element("vaadin-menu-bar") public class MenuBarElement extends TestBenchElement { @@ -42,8 +40,8 @@ public class MenuBarElement extends TestBenchElement { * * @return the button elements in the menu bar */ - public List getButtons() { - return $("vaadin-menu-bar-button").all().stream().filter( + public List getButtons() { + return $(MenuBarButtonElement.class).all().stream().filter( element -> !isOverflowButton(element) && isVisible(element)) .collect(Collectors.toList()); } @@ -54,8 +52,9 @@ public List getButtons() { * * @return the button which opens the sub menu of overflowing items */ - public TestBenchElement getOverflowButton() { - TestBenchElement overflowButton = $("[slot='overflow']").first(); + public MenuBarButtonElement getOverflowButton() { + MenuBarButtonElement overflowButton = $(MenuBarButtonElement.class) + .withAttribute("slot", "overflow").first(); if (overflowButton == null || overflowButton.hasAttribute("hidden")) { return null; } @@ -63,7 +62,7 @@ public TestBenchElement getOverflowButton() { } private boolean isOverflowButton(TestBenchElement element) { - return Objects.equals("overflow", element.getDomAttribute("slot")); + return "overflow".equals(element.getAttribute("slot")); } private boolean isVisible(TestBenchElement element) { @@ -75,9 +74,9 @@ private boolean isVisible(TestBenchElement element) { * Get TestBenchElements representing sub menu items under the first sub * menu. * - * @return List of TestBenchElements representing sub menu items. + * @return List of MenuBarItemElement representing sub menu items. */ - public List getSubMenuItems() { + public List getSubMenuItems() { return getSubMenuItems(getSubMenu()); } @@ -87,21 +86,21 @@ public List getSubMenuItems() { * * @param overlay * The sub menu overlay from which items are being collected. - * @return List of TestBenchElements representing sub menu items. + * @return List of MenuBarItemElement representing sub menu items. */ - public List getSubMenuItems(TestBenchElement overlay) { - return overlay.$("vaadin-menu-bar-item").all(); + public List getSubMenuItems(TestBenchElement overlay) { + return overlay.$(MenuBarItemElement.class).all(); } /** * Get the sub menu overlay element. * - * @return TestBenchElement for the first open sub menu. + * @return TestBenchElement for the first open sub menu in this menu bar */ public TestBenchElement getSubMenu() { - waitForSubMenu(); - return (TestBenchElement) getDriver() - .findElement(By.tagName(OVERLAY_TAG)); + var button = $(MenuBarButtonElement.class).withAttribute("expanded") + .withCondition(this::isVisible).first(); + return button != null ? button.getSubMenu() : null; } /** diff --git a/vaadin-menu-bar-flow-parent/vaadin-menu-bar-testbench/src/main/java/com/vaadin/flow/component/menubar/testbench/MenuBarItemElement.java b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-testbench/src/main/java/com/vaadin/flow/component/menubar/testbench/MenuBarItemElement.java new file mode 100644 index 00000000000..9f6b58db6a2 --- /dev/null +++ b/vaadin-menu-bar-flow-parent/vaadin-menu-bar-testbench/src/main/java/com/vaadin/flow/component/menubar/testbench/MenuBarItemElement.java @@ -0,0 +1,73 @@ +/* + * Copyright 2000-2025 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.flow.component.menubar.testbench; + +import java.util.List; + +import org.openqa.selenium.support.ui.ExpectedConditions; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elementsbase.Element; + +/** + * A TestBench element representing a {@code } element. + */ +@Element("vaadin-menu-bar-item") +public class MenuBarItemElement extends TestBenchElement { + + /** + * Get the sub menu overlay element linked to this menu item. + * + * @return TestBenchElement for the open sub menu. + */ + public TestBenchElement getSubMenu() { + waitForSubMenu(); + return getPropertyElement("__overlay"); + } + + /** + * Get TestBenchElements representing sub menu items under this item. + * + * @return List of MenuBarItemElement representing sub menu items. + */ + public List getSubMenuItems() { + return getSubMenu().$(MenuBarItemElement.class).all(); + } + + /** + * Check if the item has open sub menu. + * + * @return True if there is sub menu open + */ + public boolean isExpanded() { + return hasAttribute("expanded"); + } + + /** + * Check if the item is checked. + * + * @return True if there is checkmark + */ + public boolean isChecked() { + return hasAttribute("menu-item-checked"); + } + + private void waitForSubMenu() { + waitUntil(ExpectedConditions.attributeToBe(this, "aria-expanded", + "true")); + } + +}