com.liferay.faces.bridge.test.integration.issue.FACES_1470PortletTester.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.faces.bridge.test.integration.issue.FACES_1470PortletTester.java

Source

/**
 * Copyright (c) 2000-2018 Liferay, Inc. All rights reserved.
 *
 * 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.liferay.faces.bridge.test.integration.issue;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;

import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;

import com.liferay.faces.bridge.test.integration.BridgeTestUtil;
import com.liferay.faces.test.selenium.browser.BrowserDriver;
import com.liferay.faces.test.selenium.browser.BrowserDriverManagingTesterBase;
import com.liferay.faces.test.selenium.browser.TestUtil;
import com.liferay.faces.test.selenium.browser.WaitingAsserter;
import com.liferay.faces.test.selenium.expectedconditions.WindowOpened;

/**
 * @author  Kyle Stiemann
 */
public class FACES_1470PortletTester extends BrowserDriverManagingTesterBase {

    // Xpaths
    private static final String as7LeakInstanceXpath = "//span[contains(@id,'as7LeakInstances')]//ul/li";

    @After
    public void reset() {

        BrowserDriver browserDriver = getBrowserDriver();
        Set<String> windowIds = browserDriver.getWindowIds();
        int numberOfWindowsToClose = windowIds.size() - 1;

        for (int i = 0; i < numberOfWindowsToClose; i++) {
            browserDriver.closeCurrentWindow();
        }

        windowIds = browserDriver.getWindowIds();
        browserDriver.switchToWindow(windowIds.iterator().next());
        browserDriver.navigateWindowTo(BridgeTestUtil.getIssuePageURL("faces-1470"));

        signOut(browserDriver);
        super.doSetUp();
        browserDriver.setWaitTimeOut(TestUtil.getBrowserDriverWaitTimeOut());
    }

    @Test
    public void runFACES_1470PortletTest() {

        String container = TestUtil.getContainer();
        Assume.assumeTrue("The FACES-1470 test is only valid on Liferay Portal.", container.startsWith("liferay"));

        // 1. Sign in to the portal.
        BrowserDriver browserDriver = getBrowserDriver();
        browserDriver.navigateWindowTo(BridgeTestUtil.getIssuePageURL("faces-1470"));

        String navigateToView1LinkXpath = "//a[contains(text(), 'Navigate to view1.xhtml')]";
        browserDriver.waitForElementEnabled(navigateToView1LinkXpath);

        // 2. Open the *Navigate to view1.xhtml* link in a new tab.
        String as7LeakInstanceTrackerWindowId = browserDriver.getCurrentWindowId();
        Set<String> windowIds = browserDriver.getWindowIds();
        int numberOfWindows = windowIds.size();
        browserDriver.clickElement(navigateToView1LinkXpath);
        browserDriver.waitFor(new WindowOpened(numberOfWindows));
        windowIds = browserDriver.getWindowIds();

        // 3. Switch back to the first tab (as7LeakTracker.xhtml) and click the *Refresh AS7Leak List* button and
        // confirm that several AS7Leak class instances appear.
        Iterator<String> iterator = windowIds.iterator();
        String viewsWindowId = null;

        while (iterator.hasNext()) {

            String windowId = iterator.next();

            if (!as7LeakInstanceTrackerWindowId.equals(windowId)) {

                viewsWindowId = windowId;

                break;
            }
        }

        if (viewsWindowId == null) {
            throw new IllegalStateException("No new tab opened when *Navigate to view1.xhtml* was clicked.");
        }

        WaitingAsserter waitingAsserter = getWaitingAsserter();
        List<WebElement> as7LeakInstanceElements = new ArrayList<WebElement>();
        testAS7LeakIntancesCreated(browserDriver, waitingAsserter, as7LeakInstanceTrackerWindowId,
                as7LeakInstanceElements);

        // 4. Switch back to the tab with view1.xhtml and click the *Click me to navigate to view2.xhtml via Ajax*
        // button.
        switchToWindow(browserDriver, viewsWindowId);

        String navToView2AjaxButtonXpath = "//input[contains(@value,'Click me to navigate to view2.xhtml via Ajax')]";
        clickButton(browserDriver, navToView2AjaxButtonXpath);

        // 5. Click the *Click me to navigate to view1.xhtml via Ajax* button.
        String navToView1AjaxButtonXpath = "//input[contains(@value,'Click me to navigate to view1.xhtml via Ajax')]";
        clickButton(browserDriver, navToView1AjaxButtonXpath);

        // 6. Switch back to the first tab (as7LeakTracker.xhtml) and click the Refresh AS7Leak List button and confirm
        // that several AS7Leak class instances appear.
        testAS7LeakIntancesCreated(browserDriver, waitingAsserter, as7LeakInstanceTrackerWindowId,
                as7LeakInstanceElements);

        // 7. Switch back to the tab with view1.xhtml and click the *Click me to navigate to view2.xhtml via non-Ajax
        // (full postback)* button.
        switchToWindow(browserDriver, viewsWindowId);

        String navToView2NonAjaxButtonXpath = "//input[contains(@value,'Click me to navigate to view2.xhtml via non-Ajax (full postback)')]";
        clickButton(browserDriver, navToView2NonAjaxButtonXpath);

        // 8. Click the *Click me to navigate to view1.xhtml via non-Ajax (full postback)* button.
        String navToView1NonAjaxButtonXpath = "//input[contains(@value,'Click me to navigate to view1.xhtml via non-Ajax (full postback)')]";
        clickButton(browserDriver, navToView1NonAjaxButtonXpath);

        // 9. Switch back to the first tab (as7LeakTracker.xhtml) and click the *Refresh AS7Leak List* button and
        // confirm that several AS7Leak class instances appear.
        testAS7LeakIntancesCreated(browserDriver, waitingAsserter, as7LeakInstanceTrackerWindowId,
                as7LeakInstanceElements);

        // 10. Switch back to the tab with view1.xhtml and click the *Click me to navigate to view2.xhtml via Ajax*
        // button.
        switchToWindow(browserDriver, viewsWindowId);
        clickButton(browserDriver, navToView2AjaxButtonXpath);

        // 11. Click the *Click me to navigate to view1.xhtml via non-Ajax (full postback)* button.
        clickButton(browserDriver, navToView1NonAjaxButtonXpath);

        // 12. Switch back to the first tab (as7LeakTracker.xhtml) and click the *Refresh AS7Leak List* button and
        // confirm that several AS7Leak class instances appear.
        testAS7LeakIntancesCreated(browserDriver, waitingAsserter, as7LeakInstanceTrackerWindowId,
                as7LeakInstanceElements);

        // 13. Switch back to the tab with view1.xhtml and click the *Click me to navigate to view2.xhtml via non-Ajax
        // (full postback)* button.
        switchToWindow(browserDriver, viewsWindowId);
        clickButton(browserDriver, navToView2NonAjaxButtonXpath);

        // 14. Click the *Click me to navigate to view1.xhtml via Ajax* button.
        clickButton(browserDriver, navToView1AjaxButtonXpath);

        // 15. Switch back to the first tab (as7LeakTracker.xhtml) and click the *Refresh AS7Leak List* button and
        // confirm that several AS7Leak class instances appear.
        testAS7LeakIntancesCreated(browserDriver, waitingAsserter, as7LeakInstanceTrackerWindowId,
                as7LeakInstanceElements);

        // 16. Switch back to the tab with view1.xhtml, navigate to the as7LeakTracker.xhtml portlet page (to avoid
        // loading any AS7Leak instances as an unauthenticated user), and sign out of the portal.
        switchToWindow(browserDriver, viewsWindowId);
        browserDriver.navigateWindowTo(BridgeTestUtil.getIssuePageURL("faces-1470"));
        signOut(browserDriver);
        browserDriver.closeCurrentWindow();

        // 17. Switch back to the first tab (as7LeakTracker.xhtml) and click the *Refresh AS7Leak List* button and
        // confirm that several AS7Leak class instances appear.
        testAS7LeakIntancesCreated(browserDriver, waitingAsserter, as7LeakInstanceTrackerWindowId,
                as7LeakInstanceElements);

        // 18. Click the *Perform Garbage Collection* button and confirm that no AS7Leak class instances appear. Note:
        // since this portlet uses System.gc() to initiate garbage collection, it may be necessary to click the *Perform
        // Garbage Collection* multiple times before the garbage is actually collected. For more details see here:
        // http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#gc().
        ExpectedCondition<Boolean> as7LeakElementsNotPresent = ExpectedConditions
                .not(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(as7LeakInstanceXpath)));

        // Attempt garbage collection 5 times before giving up.
        for (int i = 0; i < 5; i++) {

            clickButton(browserDriver, "//input[contains(@value,'Perform Garbage Collection')]");

            try {

                browserDriver.waitFor(as7LeakElementsNotPresent);

                break;
            } catch (TimeoutException e) {
                // Retry.
            }
        }

        waitingAsserter.assertElementNotPresent(as7LeakInstanceXpath);
    }

    @Before
    public void setUpFACES_1470PortletTester() {
        getBrowserDriver().setWaitTimeOut(
                TestUtil.getBrowserDriverWaitTimeOut(BridgeTestUtil.DOUBLED_DEFAULT_BROWSER_DRIVER_WAIT_TIME_OUT));
    }

    private void clickButton(BrowserDriver browserDriver, String buttonXpath) {

        // Workaround element not visible problem in headless Chrome.
        if (browserDriver.isBrowserHeadless() && "chrome".equals(browserDriver.getBrowserName())) {

            browserDriver.waitForElementEnabled(buttonXpath, false);

            WebElement buttonElement = browserDriver.findElementByXpath(buttonXpath);
            browserDriver.executeScriptInCurrentWindow("arguments[0].click();", buttonElement);
        } else {

            browserDriver.waitForElementEnabled(buttonXpath);
            browserDriver.clickElement(buttonXpath);
        }
    }

    private void signOut(BrowserDriver browserDriver) {

        String container = TestUtil.getContainer();

        if (container.startsWith("liferay")) {
            browserDriver.navigateWindowTo(TestUtil.DEFAULT_BASE_URL + "/c/portal/logout");
        }

        browserDriver.clearBrowserCookies();
    }

    private void switchToWindow(BrowserDriver browserDriver, String windowId) {

        browserDriver.switchToWindow(windowId);
        browserDriver.waitFor(new SwitchedToWindow(windowId));
    }

    private void testAS7LeakIntancesCreated(BrowserDriver browserDriver, WaitingAsserter waitingAsserter,
            String as7LeakInstanceTrackerWindowId, List<WebElement> previousAS7LeakInstanceElements) {

        switchToWindow(browserDriver, as7LeakInstanceTrackerWindowId);

        String refreshAS7LeakListButtonXpath = "//input[contains(@value,'Refresh AS7Leak List')]";
        browserDriver.clickElementAndWaitForRerender(refreshAS7LeakListButtonXpath);

        List<WebElement> as7LeakInstanceElements = browserDriver.findElementsByXpath(as7LeakInstanceXpath);
        int previousNumberOfAS7LeakInstances = previousAS7LeakInstanceElements.size();
        int currentNumberOfAS7LeakInstances = as7LeakInstanceElements.size();
        Assert.assertTrue(
                "The size of the list of AS7Leak instances was expected to grow (or remain the same) after the previous action, but instead it was reduced.\n"
                        + "Previous size was: " + previousNumberOfAS7LeakInstances + ". Current size is: "
                        + currentNumberOfAS7LeakInstances,
                (currentNumberOfAS7LeakInstances > 0)
                        && (currentNumberOfAS7LeakInstances >= previousNumberOfAS7LeakInstances));
        previousAS7LeakInstanceElements.clear();
        previousAS7LeakInstanceElements.addAll(as7LeakInstanceElements);

        // Test that at least one non-garbage collected AS7Leak instance is displayed. Non-garbage collected instances
        // will be rendered as an <li> with <code> tags containing the text "AS7Leak". Garbage collected instances will
        // be displayed as an empty <li>.
        waitingAsserter.assertElementDisplayed(as7LeakInstanceXpath + "/code[contains(text(),'AS7Leak')]");
    }

    private static class SwitchedToWindow implements ExpectedCondition<Boolean> {

        // Private Data Members
        private String expectedWindowId;

        public SwitchedToWindow(String expectedWindowId) {
            this.expectedWindowId = expectedWindowId;
        }

        @Override
        public Boolean apply(WebDriver webDriver) {

            String currrentWindowId = webDriver.getWindowHandle();

            return expectedWindowId.equals(currrentWindowId);
        }
    }
}