/** * Copyright (c) 2011, SOCIETIES Consortium (WATERFORD INSTITUTE OF TECHNOLOGY (TSSG), HERIOT-WATT UNIVERSITY (HWU), SOLUTA.NET * (SN), GERMAN AEROSPACE CENTRE (Deutsches Zentrum fuer Luft- und Raumfahrt e.V.) (DLR), Zavod za varnostne tehnologije * informacijske družbe in elektronsko poslovanje (SETCCE), INSTITUTE OF COMMUNICATION AND COMPUTER SYSTEMS (ICCS), LAKE * COMMUNICATIONS (LAKE), INTEL PERFORMANCE LEARNING SOLUTIONS LTD (INTEL), PORTUGAL TELECOM INOVAÇÃO, SA (PTIN), IBM Corp., * INSTITUT TELECOM (ITSUD), AMITEC DIACHYTI EFYIA PLIROFORIKI KAI EPIKINONIES ETERIA PERIORISMENIS EFTHINIS (AMITEC), TELECOM * ITALIA S.p.a.(TI), TRIALOG (TRIALOG), Stiftelsen SINTEF (SINTEF), NEC EUROPE LTD (NEC)) * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.societies.integration.api.selenium; import org.openqa.selenium.*; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebElement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; public abstract class AbstractSeleniumComponent { protected final Logger log = LoggerFactory.getLogger(this.getClass()); //NB NOT static! private static final long WAIT_UNTIL_THREAD_SLEEP = 100; public static final long DEFAULT_FIND_TIMEOUT_MILLIS = 10000; public static final long DEFAULT_SENDKEYS_DELAY_MILLIS = 100; private long findTimeoutMillis = DEFAULT_FIND_TIMEOUT_MILLIS; private long sendKeysDelayMillis = DEFAULT_SENDKEYS_DELAY_MILLIS; private WebDriver driver; protected AbstractSeleniumComponent(WebDriver driver) { this.driver = driver; } protected WebDriver getDriver() { return driver; } public long getFindTimeoutMillis() { return findTimeoutMillis; } public void setFindTimeoutMillis(long findTimeoutMillis) { this.findTimeoutMillis = findTimeoutMillis; } public long getSendKeysDelayMillis() { return sendKeysDelayMillis; } public void setSendKeysDelayMillis(long sendKeysDelayMillis) { this.sendKeysDelayMillis = sendKeysDelayMillis; } protected void clickButton(By by) { WebElement button = waitUntilVisible(by); clickButton(button); } protected void clickButton(WebElement button) { button.click(); } protected void setFieldValue(String text, By by) { WebElement element = waitUntilVisible(by); threadSleep(sendKeysDelayMillis); element.clear(); element.sendKeys(text); threadSleep(sendKeysDelayMillis); } protected void moveMouseTo(WebElement element) { RemoteWebElement ele = (RemoteWebElement) element; if (driver instanceof RemoteWebDriver) ((RemoteWebDriver) driver).getMouse().mouseMove(ele.getCoordinates()); // ((ChromeDriver) driver).getMouse().mouseMove(ele.getCoordinates()); // else if (driver instanceof FirefoxDriver) // ((FirefoxDriver) driver).getMouse().mouseMove(ele.getCoordinates()); // else if (driver instanceof InternetExplorerDriver) // ((InternetExplorerDriver) driver).getMouse().mouseMove(ele.getCoordinates()); // else if (driver instanceof RemoteWebDriver) else { log.error("Cannot move mouse for driver of type " + getDriver().getClass().getName()); } } protected WebElement waitUntilEnabled(By by) { // Sleep until the element we want is visible or timeout is over long end = System.currentTimeMillis() + findTimeoutMillis; Exception lastEx = null; while (System.currentTimeMillis() < end) { try { WebElement element = driver.findElement(by); if (element != null && element.isEnabled()) { return element; } } catch (NoSuchElementException ex) { // do nothing lastEx = ex; } threadSleep(); } throw new NoSuchElementException("Element identified by [" + by.toString() + "] not enabled after " + findTimeoutMillis + "ms", lastEx); } protected List<WebElement> verifyElementsVisible(By by) { List<WebElement> elements = driver.findElements(by); for (WebElement element : elements) { if (element == null || !element.isDisplayed()) { throw new NoSuchElementException("Element identified by [" + by.toString() + "] not visible"); } } return elements; } protected WebElement verifyVisible(By by) { WebElement element = driver.findElement(by); if (element != null && element.isDisplayed()) { return element; } throw new NoSuchElementException("Element identified by [" + by.toString() + "] not visible"); } protected WebElement waitUntilVisible(By by) { // Sleep until the element we want is visible or timeout is over long end = System.currentTimeMillis() + findTimeoutMillis; Exception lastEx = null; while (System.currentTimeMillis() < end) { try { WebElement element = driver.findElement(by); if (element != null && element.isDisplayed()) { return element; } } catch (NoSuchElementException ex) { // do nothing lastEx = ex; } catch (StaleElementReferenceException ex) { // occasionally happens when isDisplayed() is called in this fashion, shouldn't be an issue continue; // just try again } threadSleep(); } throw new NoSuchElementException("Element identified by [" + by.toString() + "] not visible after " + findTimeoutMillis + "ms"); } protected void waitUntilNotVisible(By by) { // Sleep until the element we want is visible or timeout is over long end = System.currentTimeMillis() + findTimeoutMillis; while (System.currentTimeMillis() < end) { try { WebElement element = driver.findElement(by); if (element == null || !element.isDisplayed()) { return; } } catch (NoSuchElementException ex) { return; } catch (StaleElementReferenceException ex) { // occasionally happens when isDisplayed() is called in this fashion, shouldn't be an issue continue; // just try again } threadSleep(); } throw new TimeoutException("Element identified by [" + by.toString() + "] still visible after " + findTimeoutMillis + "ms"); } protected WebElement waitUntilFound(By by) { // Sleep until the element we want is visible or timeout is over long end = System.currentTimeMillis() + findTimeoutMillis; Exception lastEx = null; while (System.currentTimeMillis() < end) { try { WebElement element = driver.findElement(by); if (element != null) { return element; } } catch (NoSuchElementException ex) { // do nothing lastEx = ex; } threadSleep(); } throw new NoSuchElementException("Element identified by [" + by.toString() + "] not found after " + findTimeoutMillis + "ms", lastEx); } protected void waitUntilNotFound(By by) { // Sleep until the element we want is visible or timeout is over long end = System.currentTimeMillis() + findTimeoutMillis; while (System.currentTimeMillis() < end) { try { WebElement element = driver.findElement(by); if (element == null) { return; } } catch (NoSuchElementException ex) { return; } threadSleep(); } throw new TimeoutException("Element identified by [" + by.toString() + "] still found after " + findTimeoutMillis + "ms"); } protected List<WebElement> waitUntilElementsFound(By by) { // Sleep until the element we want is visible or timeout is over long end = System.currentTimeMillis() + findTimeoutMillis; Exception lastEx = null; while (System.currentTimeMillis() < end) { try { List<WebElement> element = driver.findElements(by); if (element != null) { return element; } } catch (NoSuchElementException ex) { // do nothing lastEx = ex; } threadSleep(); } throw new NoSuchElementException("Elements identified by [" + by.toString() + "] not found after " + findTimeoutMillis + "ms", lastEx); } protected void waitUntilStale(WebElement element) { // Sleep until the element we want is stale or timeout is over long end = System.currentTimeMillis() + findTimeoutMillis; while (System.currentTimeMillis() < end) { try { element.isDisplayed(); } catch (StaleElementReferenceException ex) { return; } threadSleep(); } throw new StaleElementReferenceException("Element [" + element.toString() + "] not stale after " + findTimeoutMillis + "ms"); } public void openContextMenuOnElement(WebElement element) { RemoteWebElement ele = (RemoteWebElement) element; RemoteWebDriver webDriver = ((RemoteWebDriver) driver); if (driver instanceof RemoteWebDriver) webDriver.getMouse().mouseMove(ele.getCoordinates()); // ((ChromeDriver) driver).getMouse().mouseMove(ele.getCoordinates()); // else if (driver instanceof FirefoxDriver) // ((FirefoxDriver) driver).getMouse().mouseMove(ele.getCoordinates()); // else if (driver instanceof InternetExplorerDriver) // ((InternetExplorerDriver) driver).getMouse().mouseMove(ele.getCoordinates()); // else if (driver instanceof RemoteWebDriver) else { log.error("Cannot move mouse for driver of type " + getDriver().getClass().getName()); } webDriver.getMouse().contextClick(ele.getCoordinates()); } public void pickDropdownValue(String value, String fieldId) { clickButton(By.xpath(String.format("//*[@id='%s']//*[contains(@class, 'ui-selectonemenu-trigger')]", fieldId))); clickButton(By.xpath(String.format("//*[@id='%s_panel']//*[text()='%s']", fieldId, value))); } private void threadSleep() { threadSleep(WAIT_UNTIL_THREAD_SLEEP); } private void threadSleep(long timeout) { // This reduces load on the processor by avoiding repeatedly checking faster than events can reasonably happen try { Thread.sleep(timeout); } catch (InterruptedException e) { log.warn("Error sleeping", e); } } }