aboutsummaryrefslogtreecommitdiffstats
path: root/uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabSheetScrollOnTabCloseTest.java
blob: 59f07bc4fb7f133cc72509365acbe5b8bbadcfba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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.
 *
 * @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;
            }
        };
    }
}