From 777698210d077fef28548468d70b3713badb7f89 Mon Sep 17 00:00:00 2001 From: Sean Flanigan Date: Fri, 13 Feb 2015 11:41:32 +1000 Subject: [PATCH] Enhance AbstractPage and AjaxCounterBean - Count outstanding timeouts with AjaxCounterBean too - Use new WebDriverWait for each wait, instead of reusing FluentWait - Add AbstractPage.getExecutor() to minimise casting - Add NamedPredicate for better failure messages --- .../java/org/zanata/page/AbstractPage.java | 17 ++++---- .../main/java/org/zanata/page/BasePage.java | 8 ++-- .../main/java/org/zanata/page/CorePage.java | 6 +-- .../ProjectTranslationTab.java | 3 +- .../projectversion/CreateVersionPage.java | 3 +- .../VersionTranslationTab.java | 4 +- .../zanata/page/utility/NamedPredicate.java | 40 +++++++++++++++++++ .../java/org/zanata/util/WebElementUtil.java | 6 +-- .../org/zanata/action/AjaxCounterBean.java | 14 ++++++- 9 files changed, 73 insertions(+), 28 deletions(-) create mode 100644 functional-test/src/main/java/org/zanata/page/utility/NamedPredicate.java diff --git a/functional-test/src/main/java/org/zanata/page/AbstractPage.java b/functional-test/src/main/java/org/zanata/page/AbstractPage.java index 18a042ff0d..d3ffd88093 100644 --- a/functional-test/src/main/java/org/zanata/page/AbstractPage.java +++ b/functional-test/src/main/java/org/zanata/page/AbstractPage.java @@ -46,13 +46,11 @@ @Slf4j public class AbstractPage { private final WebDriver driver; - private final FluentWait ajaxWaitForSec; public AbstractPage(final WebDriver driver) { PageFactory.initElements(new AjaxElementLocatorFactory(driver, 10), this); this.driver = driver; - ajaxWaitForSec = WebElementUtil.waitForAMoment(driver); waitForPageSilence(); } @@ -75,6 +73,10 @@ public WebDriver getDriver() { return driver; } + public JavascriptExecutor getExecutor() { + return (JavascriptExecutor) getDriver(); + } + public String getUrl() { return driver.getCurrentUrl(); } @@ -84,7 +86,7 @@ protected void logWaiting(String msg) { } public FluentWait waitForAMoment() { - return ajaxWaitForSec; + return WebElementUtil.waitForAMoment(driver); } /** @@ -200,16 +202,15 @@ protected int getExpectedBackgroundRequests() { } /** - * Wait for any AJAX calls to return. + * Wait for any AJAX/timeout calls to return. */ public void waitForPageSilence() { - // Wait for AJAX calls to be 0 + // Wait for AJAX/timeout calls to be 0 waitForAMoment().withMessage("page silence").until(new Predicate() { @Override public boolean apply(WebDriver input) { - Long ajaxCalls = (Long) ((JavascriptExecutor) getDriver()) - .executeScript( - "return XMLHttpRequest.active"); + Long ajaxCalls = (Long) getExecutor().executeScript( + "return XMLHttpRequest.active + window.timeoutCounter"); if (ajaxCalls == null) { if (log.isWarnEnabled()) { String url = getDriver().getCurrentUrl(); diff --git a/functional-test/src/main/java/org/zanata/page/BasePage.java b/functional-test/src/main/java/org/zanata/page/BasePage.java index 0cc2833b0a..c13ec85138 100644 --- a/functional-test/src/main/java/org/zanata/page/BasePage.java +++ b/functional-test/src/main/java/org/zanata/page/BasePage.java @@ -232,14 +232,12 @@ public

P goToPage(String navLinkText, Class

pageClass) { * @param locator */ public void clickLinkAfterAnimation(By locator) { - JavascriptExecutor executor = (JavascriptExecutor) getDriver(); - executor.executeScript("arguments[0].click();", getDriver() + getExecutor().executeScript("arguments[0].click();", getDriver() .findElement(locator)); } public void clickLinkAfterAnimation(WebElement element) { - JavascriptExecutor executor = (JavascriptExecutor) getDriver(); - executor.executeScript("arguments[0].click();", element); + getExecutor().executeScript("arguments[0].click();", element); } public HelpPage goToHelp() { @@ -331,7 +329,7 @@ public boolean apply(WebDriver input) { } public String getHtmlSource(WebElement webElement) { - return (String) ((JavascriptExecutor) getDriver()).executeScript( + return (String) getExecutor().executeScript( "return arguments[0].innerHTML;", webElement); } diff --git a/functional-test/src/main/java/org/zanata/page/CorePage.java b/functional-test/src/main/java/org/zanata/page/CorePage.java index a9e0dce373..209903de42 100644 --- a/functional-test/src/main/java/org/zanata/page/CorePage.java +++ b/functional-test/src/main/java/org/zanata/page/CorePage.java @@ -202,7 +202,7 @@ public void defocus() { public void defocus(By elementBy) { log.info("Force unfocus"); WebElement element = getDriver().findElement(elementBy); - ((JavascriptExecutor) getDriver()).executeScript("arguments[0].blur()", element); + getExecutor().executeScript("arguments[0].blur()", element); } /* The system sometimes moves too fast for the Ajax pages, so provide a @@ -217,11 +217,11 @@ public void slightPause() { } public void scrollIntoView(WebElement targetElement) { - ((JavascriptExecutor) getDriver()).executeScript( + getExecutor().executeScript( "arguments[0].scrollIntoView(true);", targetElement); } public void scrollToTop() { - ((JavascriptExecutor) getDriver()).executeScript("scroll(0, 0);"); + getExecutor().executeScript("scroll(0, 0);"); } } diff --git a/functional-test/src/main/java/org/zanata/page/projects/projectsettings/ProjectTranslationTab.java b/functional-test/src/main/java/org/zanata/page/projects/projectsettings/ProjectTranslationTab.java index bf197aa970..b044ca6a6e 100644 --- a/functional-test/src/main/java/org/zanata/page/projects/projectsettings/ProjectTranslationTab.java +++ b/functional-test/src/main/java/org/zanata/page/projects/projectsettings/ProjectTranslationTab.java @@ -65,8 +65,7 @@ public ProjectTranslationTab setValidationLevel(String optionName, waitForElementExists(validationsList), By.id(optionElementID)); - ((JavascriptExecutor) getDriver()) - .executeScript("arguments[0].click();", option); + getExecutor().executeScript("arguments[0].click();", option); slightPause(); return new ProjectTranslationTab(getDriver()); } diff --git a/functional-test/src/main/java/org/zanata/page/projectversion/CreateVersionPage.java b/functional-test/src/main/java/org/zanata/page/projectversion/CreateVersionPage.java index 0c5a880253..b124899fb7 100644 --- a/functional-test/src/main/java/org/zanata/page/projectversion/CreateVersionPage.java +++ b/functional-test/src/main/java/org/zanata/page/projectversion/CreateVersionPage.java @@ -77,8 +77,7 @@ private boolean isCopyFromVersionAvailable() { } private void clickCopyFromCheckbox() { - ((JavascriptExecutor) getDriver()) - .executeScript("arguments[0].click();", + getExecutor().executeScript("arguments[0].click();", waitForWebElement(copyFromPreviousVersionChk) .findElement(By.tagName("span"))); diff --git a/functional-test/src/main/java/org/zanata/page/projectversion/versionsettings/VersionTranslationTab.java b/functional-test/src/main/java/org/zanata/page/projectversion/versionsettings/VersionTranslationTab.java index 1e778aa8bb..2257e627f5 100644 --- a/functional-test/src/main/java/org/zanata/page/projectversion/versionsettings/VersionTranslationTab.java +++ b/functional-test/src/main/java/org/zanata/page/projectversion/versionsettings/VersionTranslationTab.java @@ -22,7 +22,6 @@ import lombok.extern.slf4j.Slf4j; import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.zanata.page.projectversion.VersionBasePage; @@ -62,8 +61,7 @@ public VersionTranslationTab setValidationLevel(String optionName, By.id("settings-translation-validation-form")) .findElement(By.id(optionElementID)); - ((JavascriptExecutor) getDriver()) - .executeScript("arguments[0].click();", option); + getExecutor().executeScript("arguments[0].click();", option); try { Thread.sleep(500); } catch (InterruptedException ie) { diff --git a/functional-test/src/main/java/org/zanata/page/utility/NamedPredicate.java b/functional-test/src/main/java/org/zanata/page/utility/NamedPredicate.java new file mode 100644 index 0000000000..324388723c --- /dev/null +++ b/functional-test/src/main/java/org/zanata/page/utility/NamedPredicate.java @@ -0,0 +1,40 @@ +/* + * Copyright 2014, Red Hat, Inc. and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.zanata.page.utility; + +import com.google.common.base.Predicate; + +/** + * @author Sean Flanigan sflaniga@redhat.com + */ +public abstract class NamedPredicate implements + Predicate { + private final String name; + + public NamedPredicate(String name) { + this.name = name; + } + + @Override + public String toString() { + return "predicate: " + name; + } +} diff --git a/functional-test/src/main/java/org/zanata/util/WebElementUtil.java b/functional-test/src/main/java/org/zanata/util/WebElementUtil.java index fe45c9c23c..7a23425c61 100644 --- a/functional-test/src/main/java/org/zanata/util/WebElementUtil.java +++ b/functional-test/src/main/java/org/zanata/util/WebElementUtil.java @@ -39,6 +39,7 @@ import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.FluentWait; +import org.openqa.selenium.support.ui.WebDriverWait; import org.zanata.page.WebDriverFactory; import static java.util.concurrent.TimeUnit.SECONDS; @@ -145,10 +146,7 @@ public List apply(@Nullable TableRow from) { public static FluentWait waitForSeconds(WebDriver webDriver, int durationInSec) { - return new FluentWait(webDriver) - .withTimeout(durationInSec, SECONDS) - .pollingEvery(1, SECONDS) - .ignoring(NoSuchElementException.class, + return new WebDriverWait(webDriver, durationInSec).ignoring( // TODO is ignoring this safe? StaleElementReferenceException.class); } diff --git a/zanata-war/src/main/java/org/zanata/action/AjaxCounterBean.java b/zanata-war/src/main/java/org/zanata/action/AjaxCounterBean.java index 8cc8df0c4f..cba6cf392d 100644 --- a/zanata-war/src/main/java/org/zanata/action/AjaxCounterBean.java +++ b/zanata-war/src/main/java/org/zanata/action/AjaxCounterBean.java @@ -52,8 +52,20 @@ public class AjaxCounterBean { " };\n" + " this._send.apply(this, arguments);\n" + " }\n" + + " window.timeoutCounter = 0;\n" + + " window.originalSetTimeout = window.setTimeout;\n" + + " window.setTimeout = function(func, delay, params) {\n" + + " window.timeoutCounter++;\n" + + " window.originalSetTimeout(window.timeoutCallback, delay, [func, params]);\n" + + " }\n" + + " window.timeoutCallback = function(funcAndParams) {\n" + + " window.timeoutCounter--;\n" + + " func = funcAndParams[0];\n" + + " params = funcAndParams[1];\n" + + " func(params);\n" + + " }\n" + " }\n" + - "})(XMLHttpRequest)" + + "})(XMLHttpRequest)\n" + "\n"; public String getAjaxCounterScript() { String propName = "zanata.countAjax";