/* * Copyright 2000-2016 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.tests.components.tabsheet; import java.util.List; import java.util.NoSuchElementException; import org.junit.Test; import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedCondition; import com.vaadin.testbench.By; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.TabSheetElement; import com.vaadin.tests.tb3.MultiBrowserTest; /** * Tests removing tabs that have been scrolled out of view. This should cause no * change to the scroll position. * * @since * @author Vaadin Ltd */ public class TabSheetScrollOnTabCloseTest extends MultiBrowserTest { @Test public void testScrollPositionAfterClosing() throws Exception { openTestURL(); TabSheetElement ts = $(TabSheetElement.class).first(); WebElement tabSheetScroller = ts .findElement(By.className("v-tabsheet-scrollerNext")); // scroll to the right for (int i = 0; i < 4; i++) { tabSheetScroller.click(); } // check that tab 4 is the first visible tab checkDisplayedStatus(ts, "tab3", false); checkDisplayedStatus(ts, "tab4", true); // remove tabs from the left, check that tab4 is still the first visible // tab for (int i = 0; i < 4; i++) { $(ButtonElement.class).get(i).click(); checkDisplayedStatus(ts, "tab3" + i, false); checkDisplayedStatus(ts, "tab4", true); checkDisplayedStatus(ts, "tab6", true); } // remove tabs from the right and check scroll position for (int i = 7; i < 10; i++) { $(ButtonElement.class).get(i).click(); checkFirstTab(ts, "tab4"); checkDisplayedStatus(ts, "tab6", true); } } /** * Checks that the visible status of the tab with the given id is equal to * shouldBeVisible. That is, the tab with the given id should be visible if * and only if shouldBeVisible is true. Used for checking that the leftmost * visible tab is the expected one when there should be tabs (hidden because * of scroll position) to the left of tabId. * * If there is no tab with the specified id, the tab is considered not to be * visible. */ private void checkDisplayedStatus(TabSheetElement tabSheet, String tabId, boolean shouldBeVisible) { org.openqa.selenium.By locator = By.cssSelector("#" + tabId); waitUntil(visibilityOfElement(locator, shouldBeVisible)); } /** * Checks that there are no hidden tabs in tabSheet and that the id of the * first tab is tabId. Used for checking that the leftmost visible tab is * the expected one when there are no tabs to the left of the tab with the * given id. When there are tabs to the left of tabId, check instead that * tabId is visible and the previous tab is hidden (see * checkDisplayedStatus). */ private void checkFirstTab(TabSheetElement tabSheet, String tabId) { waitUntil(visibilityOfElement( By.cssSelector(".v-tabsheet-tabitemcell[aria-hidden]"), false)); waitUntil(leftmostTabHasId(tabSheet, tabId)); } /** * An expectation for checking that the visibility status of the specified * element is correct. If the element does not exist in the DOM, it is * considered not to be visible. If several elements match the locator, only * the visibility of the first matching element is considered. * * @param locator * used to find the element * @param expectedVisibility * whether the element should be visible */ private static ExpectedCondition<Boolean> visibilityOfElement( final org.openqa.selenium.By locator, final boolean expectedVisibility) { return new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver driver) { List<WebElement> matchingElements = driver .findElements(locator); if (matchingElements.isEmpty()) { return !expectedVisibility; } else { try { WebElement first = matchingElements.get(0); return first.isDisplayed() == expectedVisibility; } catch (StaleElementReferenceException e) { // The element was initially in DOM but has been // removed. return !expectedVisibility; } } } @Override public String toString() { return "element " + (expectedVisibility ? "" : "not ") + "expected to be visible: " + locator; } }; } /** * An expectation for checking that the leftmost tab has id equal to tabId. * * @param tabSheet * the tab sheet containing the tab * @param tabId * the id of the tab that should be the leftmost tab */ private static ExpectedCondition<Boolean> leftmostTabHasId( final TabSheetElement tabSheet, final String tabId) { return new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver driver) { try { WebElement leftElement = tabSheet.findElement( By.cssSelector(".v-tabsheet-tabitemcell")); String leftId = leftElement.getAttribute("id"); return leftId.equals(tabId); } catch (NoSuchElementException e) { return false; } } @Override public String toString() { return "expected tab index of the leftmost tab in the tab sheet: " + tabId; } }; } }