at.tugraz.ist.catroweb.BaseTest.java Source code

Java tutorial

Introduction

Here is the source code for at.tugraz.ist.catroweb.BaseTest.java

Source

/**
  *Catroid: An on-device visual programming system for Android devices
  *Copyright (C) 2010-2013 The Catrobat Team
  *(<http://developer.catrobat.org/credits>)
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU Affero General Public License as
  *published by the Free Software Foundation, either version 3 of the
  *License, or (at your option) any later version.
  *
  *An additional term exception under section 7 of the GNU Affero
  *General Public License, version 3, is available at
  *http://developer.catrobat.org/license_additional_term
  *
  *This program is distributed in the hope that it will be useful,
  *but WITHOUT ANY WARRANTY; without even the implied warranty of
  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *GNU Affero General Public License for more details.
  *
  *You should have received a copy of the GNU Affero General Public License
  *along with this program. If not, see <http://www.gnu.org/licenses/>.
  */

package at.tugraz.ist.catroweb;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.testng.AssertJUnit.assertTrue;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.android.AndroidDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.UnreachableBrowserException;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Reporter;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Parameters;

import at.tugraz.ist.catroweb.common.CommonData;
import at.tugraz.ist.catroweb.common.CommonFunctions;
import at.tugraz.ist.catroweb.common.Config;
import at.tugraz.ist.catroweb.common.ProjectUploader;

public class BaseTest {
    protected ProjectUploader projectUploader;
    protected String webSite;
    protected Map<String, WebDriver> driverSessions;

    @BeforeClass(alwaysRun = true)
    @Parameters({ "webSite", "basedir" })
    protected void constructor(String webSite, String basedir) {
        this.webSite = webSite;
        Config.setSeleniumGridTestdata(basedir);
        projectUploader = new ProjectUploader(webSite);
        this.driverSessions = Collections.synchronizedMap(new HashMap<String, WebDriver>());
    }

    @AfterClass(alwaysRun = true)
    protected void destructor() {
        projectUploader.cleanup();
    }

    @BeforeMethod(alwaysRun = true)
    @Parameters({ "seleniumHost", "seleniumPort", "browser", "webSite" })
    protected void startSession(String seleniumHost, int seleniumPort, String browser, String webSite,
            Method method) {
        if (browser.matches("^firefox$")) {
            startFirefoxSession(seleniumHost, seleniumPort, method.getName(), 0);
        } else if (browser.matches("^chrome$")) {
            startChromeSession(seleniumHost, seleniumPort, method.getName(), 0);
        } else if (browser.matches("^internet explorer$")) {
            startInternetExplorerSession(seleniumHost, seleniumPort, method.getName(), 0);
        } else if (browser.matches("^opera$")) {
            startOperaSession(seleniumHost, seleniumPort, method.getName(), 0);
        } else if (browser.matches("^android$")) {
            startAndroidSession(seleniumHost, seleniumPort, browser, webSite, method.getName());
        }
    }

    protected void startFirefoxSession(String seleniumHost, int seleniumPort, String method, int retry) {
        log("firefox: running " + method + "...");
        FirefoxProfile profile = new FirefoxProfile();

        try {
            DesiredCapabilities capabilities = DesiredCapabilities.firefox();
            capabilities.setCapability("firefox_profile", profile);
            WebDriver driver = new RemoteWebDriver(
                    new URL("http://" + seleniumHost + ":" + seleniumPort + "/wd/hub"), capabilities);
            driverSessions.put(method, driver);
        } catch (UnreachableBrowserException e) {
            if (retry++ < 5) {
                startFirefoxSession(seleniumHost, seleniumPort, method, retry);
            } else {
                log(e.getMessage());
                assertTrue(false);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            log(e.getMessage());
        }
    }

    protected void startInternetExplorerSession(String seleniumHost, int seleniumPort, String method, int retry) {
        log("internet explorer: running " + method + "...");

        try {
            DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
            capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,
                    true);
            WebDriver driver = new RemoteWebDriver(
                    new URL("http://" + seleniumHost + ":" + seleniumPort + "/wd/hub"), capabilities);
            driverSessions.put(method, driver);
        } catch (UnreachableBrowserException e) {
            if (retry++ < 5) {
                startInternetExplorerSession(seleniumHost, seleniumPort, method, retry);
            } else {
                log(e.getMessage());
                assertTrue(false);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            log(e.getMessage());
        }
    }

    protected void startChromeSession(String seleniumHost, int seleniumPort, String method, int retry) {
        log("chrome: running " + method + "...");
        // System.setProperty("webdriver.chrome.bin", "/opt/google/chrome/google-chrome");
        // System.setProperty("webdriver.chrome.driver", "/home/chris/.workspace/catroweb/tests/selenium-grid/chromedriver");

        try {
            DesiredCapabilities capabilities = DesiredCapabilities.chrome();
            WebDriver driver = new RemoteWebDriver(
                    new URL("http://" + seleniumHost + ":" + seleniumPort + "/wd/hub"), capabilities);
            driverSessions.put(method, driver);
        } catch (UnreachableBrowserException e) {
            if (retry++ < 5) {
                startChromeSession(seleniumHost, seleniumPort, method, retry);
            } else {
                log(e.getMessage());
                assertTrue(false);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            log(e.getMessage());
        }
    }

    protected void startOperaSession(String seleniumHost, int seleniumPort, String method, int retry) {
        log("opera: running " + method + "...");

        try {
            DesiredCapabilities capabilities = DesiredCapabilities.opera();
            WebDriver driver = new RemoteWebDriver(
                    new URL("http://" + seleniumHost + ":" + seleniumPort + "/wd/hub"), capabilities);
            driverSessions.put(method, driver);
        } catch (UnreachableBrowserException e) {
            if (retry++ < 5) {
                startOperaSession(seleniumHost, seleniumPort, method, retry);
            } else {
                log(e.getMessage());
                assertTrue(false);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            log(e.getMessage());
        }
    }

    protected void startAndroidSession(String seleniumHost, int seleniumPort, String browser, String webSite,
            String method) {
        log("android: running " + method + "...");

        WebDriver driver = new AndroidDriver();
        driverSessions.put(method, driver);
    }

    @AfterMethod(alwaysRun = true)
    protected void closeSession(Method method) {
        String methodName = method.getName();

        try {
            getDriverObject(methodName).quit();
            driverSessions.remove(methodName);

            log("..." + methodName + " done");
        } catch (NullPointerException e) {
            Reporter.log("..." + methodName + " closeSession got NULL pointer");
        }
    }

    protected WebDriver driver() {
        WebDriver driver = getDriverObject(getCalleeName());

        if (driver == null) {
            for (Map.Entry<String, WebDriver> entry : driverSessions.entrySet()) {
                log(entry.getKey() + ": callee: " + getCalleeName());
            }
        }

        return driver;
    }

    private String getCalleeName() {
        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        for (StackTraceElement item : stack) {
            String entry = item.toString();
            if (entry.matches("at.tugraz.ist.catroweb.*") && !entry.matches("at.tugraz.ist.catroweb.BaseTest.*")) {
                return item.getMethodName();
            }
        }
        return null;
    }

    private WebDriver getDriverObject(String key) {
        if (this.driverSessions.containsKey(key)) {
            return this.driverSessions.get(key);
        }
        return null;
    }

    protected void ajaxWait() {
        Wait<WebDriver> wait = new WebDriverWait(driver(), Config.TIMEOUT_WAIT);
        wait.until(jQueryExists());
        wait.until(jQueryReady());
    }

    public void assertRegExp(String pattern, String string) {
        boolean match = string.matches(pattern);
        if (!match) {
            log("assertRegExp: was [" + string + "] expected [" + pattern + "]");
        }
        assertTrue(match);
    }

    public boolean isTextPresent(String text) {
        return containsElementText(By.tagName("body"), text);
    }

    public String getRecoveryUrl(String message) {
        String[] parts = message.split("<");
        for (String part : parts) {
            if (part.contains("passwordrecovery?c=")) {
                String[] temp = part.split("c=");
                return "passwordrecovery?c=" + temp[1];
            }
        }

        return "passwordrecovery?c=";
    }

    public String getValidationUrl(String message) {
        String[] parts = message.split("<");
        for (String part : parts) {
            if (part.contains("emailvalidation?c=")) {
                String[] temp = part.split("c=");
                return "emailvalidation?c=" + temp[1];
            }
        }

        return "emailvalidation?c=";
    }

    public boolean containsElementText(By selector, String text) {
        // https://code.google.com/p/selenium/issues/detail?id=1438
        waitForElementPresent(selector);
        driver().switchTo().defaultContent(); // TODO workaround
        return (driver().findElement(selector)).getText().contains(text);
    }

    public boolean isElementPresent(By selector) {
        try {
            driver().findElement(selector);
            return true;
        } catch (NoSuchElementException e) {
            return false;
        }
    }

    public boolean isVisible(By selector) {
        return (driver().findElement(selector)).isDisplayed();
    }

    public boolean isEditable(By selector) {
        return (driver().findElement(selector)).isEnabled();
    }

    protected void makeVisible(By selector, String additionalCommands) {
        ((JavascriptExecutor) driver()).executeScript(
                "arguments[0].style.visibility='visible';" + additionalCommands, driver().findElement(selector));
    }

    protected void openLocation() {
        openLocation("");
    }

    protected void openLocation(String location) {
        openLocation(location, true);
    }

    protected void openLocation(String location, Boolean forceDefaultLanguage) {
        if (forceDefaultLanguage == true) {
            if (location.contains("?")) {
                driver().get(this.webSite + Config.TESTS_BASE_PATH.substring(1) + location + "&userLanguage="
                        + Config.SITE_DEFAULT_LANGUAGE);
            } else {
                driver().get(this.webSite + Config.TESTS_BASE_PATH.substring(1) + location + "?userLanguage="
                        + Config.SITE_DEFAULT_LANGUAGE);
            }
        } else {
            driver().get(this.webSite + Config.TESTS_BASE_PATH.substring(1) + location);
        }

        //workaround fo Issue 2714
        //https://code.google.com/p/selenium/issues/detail?id=2714
        driver().manage().window().setSize(new Dimension(1024, 2000));
    }

    protected void openMobileLocation() {
        openMobileLocation("");
    }

    protected void openMobileLocation(String location) {
        openMobileLocation(location, true);
    }

    protected void openMobileLocation(String location, Boolean forceDefaultLanguage) {
        if (forceDefaultLanguage == true) {
            if (location.contains("?")) {
                driver().get(this.webSite + Config.TESTS_BASE_PATH.substring(1) + location + "&userLanguage="
                        + Config.SITE_DEFAULT_LANGUAGE);
            } else {
                driver().get(this.webSite + Config.TESTS_BASE_PATH.substring(1) + location + "?userLanguage="
                        + Config.SITE_DEFAULT_LANGUAGE);
            }
        } else {
            driver().get(this.webSite + Config.TESTS_BASE_PATH.substring(1) + location);
        }

        //workaround fo Issue 2714
        //https://code.google.com/p/selenium/issues/detail?id=2714
        driver().manage().window().setSize(new Dimension(320, 2000));
    }

    protected void openAdminLocation() {
        openAdminLocation("");
    }

    protected void openAdminLocation(String location) {
        driver().get(CommonFunctions.getAdminPath(this.webSite) + location);
    }

    protected void clickAndWaitForPopUp(By selector) {
        String popUpWindow = "";
        Set<String> windowList = driver().getWindowHandles();
        driver().findElement(selector).click();

        Set<String> tmp = driver().getWindowHandles();
        for (String window : tmp) {
            if (!tmp.contains(windowList))
                popUpWindow = window;
        }

        driver().switchTo().window(popUpWindow);
        waitForElementPresent(By.tagName("body"));
    }

    protected void closePopUp() {
        driver().close();
        Set<String> windowList = driver().getWindowHandles();
        for (String window : windowList) {
            driver().switchTo().window(window);
            return;
        }
    }

    protected void clickOkOnNextConfirmationBox() {
        ((JavascriptExecutor) driver()).executeScript("window.confirm = function(msg){return true;};");
    }

    protected void clickCancelOnNextConfirmationBox() {
        ((JavascriptExecutor) driver()).executeScript("window.confirm = function(msg){return false;};");
    }

    protected void assertProjectPresent(String project) {
        String query = "";
        try {
            query = URLEncoder.encode(project, "UTF-8");
        } catch (UnsupportedEncodingException ignore) {
            assertTrue(false);
        }

        openLocation("search/?q=" + query + "&p=1");
        ajaxWait();

        try {
            while (driver().findElement(By.id("moreResults")).isDisplayed()) {
                driver().findElement(By.id("moreResults")).click();
                ajaxWait();
            }
        } catch (NoSuchElementException ignore) {
        }

        assertTrue(isElementPresent(By.xpath("//a[@title=\"" + project + "\"]")));
    }

    protected void assertProjectNotPresent(String project) {
        String query = "";
        try {
            query = URLEncoder.encode(project, "UTF-8");
        } catch (UnsupportedEncodingException ignore) {
            assertTrue(false);
        }

        openLocation("search/?q=" + query + "&p=1");
        ajaxWait();

        try {
            while (driver().findElement(By.id("moreResults")).isDisplayed()) {
                driver().findElement(By.id("moreResults")).click();
                ajaxWait();
            }
        } catch (NoSuchElementException ignore) {
        }

        assertTrue(isElementPresent(By.xpath("//a[@title=\"" + project + "\"]")) == false);
    }

    public void waitForElementPresent(By selector) {
        try {
            Wait<WebDriver> wait = new WebDriverWait(driver(), Config.TIMEOUT_WAIT);
            wait.until(elementPresent(selector));
        } catch (WebDriverException ignore) {
        }
    }

    public void clickLastVisibleProject() {
        try {
            while (driver().findElement(By.id("newestShowMore")).isDisplayed()) {
                driver().findElement(By.id("newestShowMore")).click();
                ajaxWait();
            }
        } catch (NoSuchElementException ignore) {
        }

        WebElement lastLink = null;
        List<WebElement> allLinks = driver().findElement(By.id("newestProjects")).findElements(By.tagName("a"));
        for (WebElement link : allLinks) {
            if (link.isDisplayed()) {
                lastLink = link;
            }
        }
        lastLink.click();
    }

    public void login() {
        login(driver().getCurrentUrl());
    }

    public void login(String location) {
        if (!location.contains(this.webSite + Config.TESTS_BASE_PATH)) {
            location = this.webSite + Config.TESTS_BASE_PATH + location;
        }

        driver().get(this.webSite + Config.TESTS_BASE_PATH + "api/checkToken/.json?username="
                + CommonData.getLoginUserDefault() + "&token=" + Config.DEFAULT_UPLOAD_TOKEN);
        driver().get(location.replace("//", "/"));
        ajaxWait();
    }

    public void logout() {
        logout(driver().getCurrentUrl());
    }

    public void logout(String location) {
        if (!location.contains(this.webSite + Config.TESTS_BASE_PATH)) {
            location = this.webSite + Config.TESTS_BASE_PATH + location;
        }

        driver().get(this.webSite + Config.TESTS_BASE_PATH + "login/logoutRequest.json");
        driver().get(location.replace("//", "/"));
        ajaxWait();
    }

    public void blur(By selector) {
        ((JavascriptExecutor) driver()).executeScript("return arguments[0].blur();",
                driver().findElement(selector));
    }

    protected void log(int message) {
        Reporter.log(String.valueOf(message), Config.REPORTER_LOG_TO_STD_OUT);
    }

    protected void log(String message) {
        Reporter.log(message, Config.REPORTER_LOG_TO_STD_OUT);
    }

    protected void captureScreen(String imageName) {
        WebDriver driver = new Augmenter().augment(driver());
        String imageExtension = ".png";
        String imagePath = Config.SELENIUM_GRID_TARGET + imageName + imageExtension;
        try {
            File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
            FileUtils.copyFile(scrFile, new File(Config.FILESYSTEM_BASE_PATH + imagePath));
            Reporter.log("<a href=\"../" + imageName + imageExtension + "\">Screenshot (" + imageName + ")</a>");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            Reporter.log("captureScreen got NULL pointer");
        } catch (NoSuchElementException e) {
        }
    }

    private ExpectedCondition<WebElement> elementPresent(final By selector) {
        return new ExpectedCondition<WebElement>() {
            public WebElement apply(WebDriver driver) {
                return driver.findElement(selector);
            }
        };
    }

    private ExpectedCondition<Boolean> jQueryExists() {
        return new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver driver) {
                return ((Boolean) ((JavascriptExecutor) driver)
                        .executeScript("return (typeof window.jQuery == 'function')"));
            }
        };
    }

    private ExpectedCondition<Boolean> jQueryReady() {
        return new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver driver) {
                return ((Boolean) ((JavascriptExecutor) driver)
                        .executeScript("return (window.jQuery.active == 0)"));
            }
        };
    }
}