Java tutorial
/* ************************************************************************ qxwebdriver-java http://github.com/qooxdoo/qxwebdriver-java Copyright: 2012-2013 1&1 Internet AG, Germany, http://www.1und1.de License: LGPL: http://www.gnu.org/licenses/lgpl.html EPL: http://www.eclipse.org/org/documents/epl-v10.php See the license.txt file in the project's top-level directory for details. Authors: * Daniel Wagner (danielwagner) ************************************************************************ */ package org.oneandone.qxwebdriver; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import org.oneandone.qxwebdriver.log.LogEntry; import org.oneandone.qxwebdriver.resources.JavaScript; import org.oneandone.qxwebdriver.resources.JavaScriptRunner; import org.oneandone.qxwebdriver.ui.Widget; import org.oneandone.qxwebdriver.ui.WidgetFactory; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.NoSuchElementException; 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 org.openqa.selenium.support.ui.WebDriverWait; /** * A Decorator that wraps a {@link org.openqa.selenium.WebDriver} object, * adding qooxdoo-specific features. * Note that the WebDriver used <strong>must</strong> implement the * {@link org.openqa.selenium.JavascriptExecutor} interface. */ public class QxWebDriver implements WebDriver, JavascriptExecutor { public QxWebDriver(WebDriver webdriver) { driver = webdriver; jsExecutor = (JavascriptExecutor) driver; driver.manage().timeouts().implicitlyWait(4, TimeUnit.SECONDS); widgetFactory = new org.oneandone.qxwebdriver.ui.DefaultWidgetFactory(this); } public QxWebDriver(WebDriver webdriver, WidgetFactory widgetFactory) { driver = webdriver; jsExecutor = (JavascriptExecutor) driver; driver.manage().timeouts().implicitlyWait(4, TimeUnit.SECONDS); } /** * A condition that waits until the qooxdoo application in the browser is * ready (<code>qx.core.Init.getApplication()</code> returns anything truthy). */ public ExpectedCondition<Boolean> qxAppIsReady() { return new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver driver) { Object result = null; String script = JavaScript.INSTANCE.getValue("isApplicationReady"); try { result = jsExecutor.executeScript(script); } catch (org.openqa.selenium.WebDriverException e) { } Boolean isReady = (Boolean) result; return isReady; } @Override public String toString() { return "qooxdoo application is ready."; } }; } public JavascriptExecutor jsExecutor; public JavaScriptRunner jsRunner; private WebDriver driver; private WidgetFactory widgetFactory; /** * Returns the original WebDriver instance */ public WebDriver getWebDriver() { return driver; } /** * Find the first matching {@link Widget} using the given method. * * @param by The locating mechanism * @param timeoutInSeconds time to wait for the widget * @return The first matching element on the current page * @throws NoSuchElementException If no matching widget was found before the timeout elapsed * @see org.oneandone.qxwebdriver.By */ protected Widget findWidget(By by, long timeoutInSeconds) throws NoSuchElementException { WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds); WebElement element; try { element = wait.until(ExpectedConditions.presenceOfElementLocated(by)); } catch (org.openqa.selenium.TimeoutException e) { throw new NoSuchElementException("Unable to find element for locator.", e); } return getWidgetForElement(element); } /** * Find the first matching {@link Widget} using the given method. Retry for up to 5 seconds before * throwing. * * @param by The locating mechanism * @return The first matching element on the current page * @throws NoSuchElementException If no matching widget was found before the timeout elapsed * @see org.oneandone.qxwebdriver.By */ public Widget findWidget(By by) { return findWidget(by, 5); } /** * Find the first matching {@link Widget} using the given method. * * @param by The locating mechanism * @param timeoutInSeconds time to wait for the widget * @return The first matching element on the current page * @throws NoSuchElementException If no matching widget was found before the timeout elapsed * @see org.oneandone.qxwebdriver.By */ public Widget waitForWidget(By by, long timeoutInSeconds) { return findWidget(by, timeoutInSeconds); } /** * Returns an instance of {@link Widget} or one of its subclasses that * represents the qooxdoo widget containing the given element. * @param element A WebElement representing a DOM element that is part of a * qooxdoo widget * @return Widget object */ public Widget getWidgetForElement(WebElement element) { return widgetFactory.getWidgetForElement(element); } /** * Registers a new log appender with the AUT's logging system. Entries can be * accessed using getLogEvents() */ public void registerLogAppender() { jsRunner.runScript("registerLogAppender"); } /** * Retrieves the AUT's qx log entries. registerLogAppender() *must* be called * before this can be used. */ public List<LogEntry> getLogEvents() { List<LogEntry> logEntries = new ArrayList<LogEntry>(); List<String> jsonEntries = (List<String>) jsRunner.runScript("getAllLogEvents"); Iterator<String> itr = jsonEntries.iterator(); while (itr.hasNext()) { String json = itr.next(); LogEntry entry = new LogEntry(json); logEntries.add(entry); } return logEntries; } /** * Registers a global error handler using qx.event.GlobalError.setErrorHandler * Caught exceptions can be retrieved using getCaughtErrors */ public void registerGlobalErrorHandler() { jsRunner.runScript("registerGlobalErrorHandler"); } /** * Retrieves any exceptions caught by qooxdoo's global error handling. * registerGlobalErrorHandler *must* be called before this can be used. */ public List<String> getCaughtErrors() { return (List<String>) jsRunner.runScript("getCaughtErrors"); } /** * Uses qooxdoo's localization support to get the currently active locale's translation for a string */ public String getTranslation(String string) { String js = "return qx.locale.Manager.getInstance().translate('" + string + "', []).toString();"; return (String) jsExecutor.executeScript(js, string); } /** * Uses qooxdoo's localization support to get a specific locale's translation for a string */ public String getTranslation(String string, String locale) { String js = "return qx.locale.Manager.getInstance().translate('" + string + "', [], '" + locale + "').toString();"; return (String) jsExecutor.executeScript(js, string); } @Override public void close() { driver.close(); } @Override public WebElement findElement(By arg0) { return driver.findElement(arg0); } @Override public List<WebElement> findElements(By arg0) { return driver.findElements(arg0); } @Override public void get(String arg0) { driver.get(arg0); waitForQxApplication(); init(); } /** * Wait until qx.core.Init.getApplication() returns something truthy. */ public void waitForQxApplication() { new WebDriverWait(driver, 30, 250).until(qxAppIsReady()); } /** * Initializes the testing environment. */ public void init() { jsRunner = new JavaScriptRunner(jsExecutor); // make sure getWidgetByElement is defined so other scripts can use it jsRunner.defineFunction("getWidgetByElement"); } @Override public String getCurrentUrl() { return driver.getCurrentUrl(); } @Override public String getPageSource() { return driver.getPageSource(); } @Override public String getTitle() { return driver.getTitle(); } @Override public String getWindowHandle() { return driver.getWindowHandle(); } @Override public Set<String> getWindowHandles() { return driver.getWindowHandles(); } @Override public Options manage() { return driver.manage(); } @Override public Navigation navigate() { return driver.navigate(); } @Override public void quit() { driver.quit(); } @Override public TargetLocator switchTo() { return driver.switchTo(); } @Override public Object executeAsyncScript(String arg0, Object... arg1) { return jsExecutor.executeAsyncScript(arg0, arg1); } @Override public Object executeScript(String arg0, Object... arg1) { return jsExecutor.executeScript(arg0, arg1); } }