net.sourceforge.jbizmo.commons.selenium.page.AbstractPageComponent Maven / Gradle / Ivy
/*
* This file is part of JBizMo, a set of tools, libraries and plug-ins
* for modeling and creating Java-based enterprise applications.
* For more information visit:
*
* http://sourceforge.net/projects/jbizmo/
*
* This software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU 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
*/
package net.sourceforge.jbizmo.commons.selenium.page;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sourceforge.jbizmo.commons.selenium.data.PageElementTestData;
import net.sourceforge.jbizmo.commons.selenium.junit.SeleniumTestContext;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
/**
*
* Abstract base class for all page object components
*
*
* Copyright 2017 (C) by Martin Ganserer
*
* @author Martin Ganserer
* @version 1.0.0
*/
public abstract class AbstractPageComponent
{
public static final String ATTR_NAME_VALUE = "value";
public static final String HTML_LIST_ITEM = "li";
public static final String ATTR_NAME_CLASS = "class";
public static final String ATTR_NAME_STYLE = "style";
public static final String ATTR_NAME_SELECTED = "selected";
public static final String NEW_LINE = "!NEW_LINE!";
public static final String ITEM_DELIMITER = ";";
public static final int ROW_OFFSET_X = 5;
public static final int ROW_OFFSET_Y = 5;
public static final int AJAX_POLLING_INTERVAL_MILLISECONDS = 50;
protected WebDriver driver;
protected Logger logger;
protected SeleniumTestContext testContext;
/**
* Constructor
* @param testContext
*/
public AbstractPageComponent(SeleniumTestContext testContext)
{
this.testContext = testContext;
this.driver = testContext.getDriver();
this.logger = Logger.getLogger(this.getClass().getName());
}
/**
* @param logger
*/
public void setLogger(Logger logger)
{
this.logger = logger;
}
/**
* @return the logger
*/
public Logger getLogger()
{
return logger;
}
/**
* @return the Selenium WebDriver
*/
public WebDriver getDriver()
{
return driver;
}
/**
* @return the Selenium test context
*/
public SeleniumTestContext getTestContext()
{
return testContext;
}
/**
* Search for an element by using the given ID
* @param elementId
* @param explicitWaitInSeconds controls the amount of time in seconds until an element should be visible
* @return the web element
* @throws AssertionError if the element either could not be found, or the parameter elementId
is null or empty
*/
public WebElement findWebElement(String elementId, int explicitWaitInSeconds)
{
if(logger.isLoggable(Level.FINER))
logger.finer("Search for element with ID '" + elementId + "'");
if(elementId == null || elementId.isEmpty())
fail("Parameter 'elementId' must not be null or empty!");
waitForPendingAjaxRequests();
if(explicitWaitInSeconds > 0)
{
final WebDriverWait wait = new WebDriverWait(driver, explicitWaitInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(elementId)));
}
WebElement element = null;
try
{
element = driver.findElement(By.id(elementId));
}
catch (final NoSuchElementException e)
{
fail("Could not find element with ID '" + elementId + "'!", e);
}
// We must make sure that the element is within the visible area of the browser!
moveToElement(element);
return element;
}
/**
* Search for an element by using the given ID
* @param elementId
* @return the web element
* @throws AssertionError if the element either could not be found, or the parameter elementId
is null or empty
*/
public WebElement findWebElement(String elementId)
{
return findWebElement(elementId, 0);
}
/**
* Find an element by using a XPath expression
* @param xpathExpression
* @return the web element
* @throws AssertionError if the element either could not be found, or the XPath expression is null or empty
*/
public WebElement findWebElementByXPath(String xpathExpression)
{
if(logger.isLoggable(Level.FINER))
logger.finer("Search for element by XPath '" + xpathExpression + "'");
if(xpathExpression == null || xpathExpression.isEmpty())
fail("Parameter 'xpathExpression' must not be null or empty!");
waitForPendingAjaxRequests();
WebElement element = null;
try
{
element = driver.findElement(By.xpath(xpathExpression));
}
catch (final NoSuchElementException e)
{
fail("Could not find element using XPath '" + xpathExpression + "'!");
}
// We must make sure that the element is within the visible area of the browser!
moveToElement(element);
return element;
}
/**
* Find elements by using a XPath expression
* @param xpathExpression
* @return a list containing all web elements
* @throws AssertionError if the XPath expression is null or empty
*/
public List findWebElementsByXPath(String xpathExpression)
{
if(logger.isLoggable(Level.FINER))
logger.finer("Search for elements by XPath '" + xpathExpression + "'");
if(xpathExpression == null || xpathExpression.isEmpty())
fail("Parameter 'xpathExpression' must not be null or empty!");
waitForPendingAjaxRequests();
return driver.findElements(By.xpath(xpathExpression));
}
/**
* Perform a double-click on the given element
* @param webElement
* @throws AssertionError if the parameter webElement
is null
*/
public void doubleClickElement(WebElement webElement)
{
if(logger.isLoggable(Level.FINER))
logger.finer("Perform double-click on element '" + webElement.getTagName() + "'");
assertNotNull("Parameter 'webElement' must not be null!", webElement);
waitForPendingAjaxRequests();
// Move to element as it is not sure that it is really visible!
moveToElement(webElement);
new Actions(driver).doubleClick(webElement).perform();
}
/**
* Enter data into input field
* @param testData the field's test data object that provides necessary information
*/
public void setInputFieldValue(PageElementTestData testData)
{
assertNotNull("Text for input field '" + testData.getElementId() + "' must not be null!", testData.getNewValue());
if(logger.isLoggable(Level.FINE))
logger.fine("Enter text '" + testData.getNewValue() + "' into input field '" + testData.getElementId() + "'");
final WebElement inputField = findWebElement(testData.getElementId());
inputField.clear();
// The ENTER key must be pressed for all new-line characters!
final String textToEnter = testData.getNewValue().replace(NEW_LINE, Keys.ENTER);
inputField.sendKeys(textToEnter);
}
/**
* Validate input field by using the field's test data object
* @param testData the field's test data object that provides necessary information
* @throws AssertionError if the validation has failed
*/
public void validateInputFieldValue(PageElementTestData testData)
{
assertNotNull("Expected value for field '" + testData.getElementId() + "' must not be null!", testData.getExpectedValue());
if(logger.isLoggable(Level.FINE))
logger.fine("Validate text of input field '" + testData.getElementId() + "'");
final WebElement inputField = findWebElement(testData.getElementId());
final String message = "Validation of input field '" + testData.getElementId() + "' has failed!";
final String expectedText = testData.getExpectedValue().replace(NEW_LINE, "\\n");
String actualText = inputField.getAttribute(ATTR_NAME_VALUE);
if(actualText != null)
actualText = actualText.replace("\n", "\\n");
assertEquals(message, expectedText, actualText);
}
/**
* Wait a specific amount of time in seconds until an element should be visible
* @param webElement
* @param secondsToWait
* @throws AssertionError if the parameter webElement
is null
*/
public void waitUntilVisible(WebElement webElement, int secondsToWait)
{
assertNotNull("Parameter 'webElement' must not be null!", webElement);
final WebDriverWait wait = new WebDriverWait(driver, secondsToWait);
wait.until(ExpectedConditions.visibilityOf(webElement));
}
/**
* @param webElement
* @throws AssertionError if the parameter webElement
is null
*/
public void moveToElement(WebElement webElement)
{
assertNotNull("Parameter 'webElement' must not be null!", webElement);
// Move the mouse to the respective element
new Actions(driver).moveToElement(webElement).perform();
}
/**
* Assert that a condition is true and create a log record if the assertion test has failed
* @param message
* @param condition
* @throws AssertionError if the condition is not true
*/
public void assertTrue(String message, boolean condition)
{
if(!condition)
fail(message);
}
/**
* Assert that an object isn't null and create a log record if the assertion test has failed
* @param message
* @param object
* @throws AssertionError if the object is null
*/
public void assertNotNull(String message, Object object)
{
if(object == null)
fail(message);
}
/**
* Assert that two objects are equal and create a log record if the assertion test has failed
* @param message
* @param expected
* @param actual
* @throws AssertionError if both objects are not equal
*/
public void assertEquals(String message, Object expected, Object actual)
{
if(expected == null && actual == null)
return;
if(logger.isLoggable(Level.FINER))
logger.finer("Compare expected value '" + expected + "' with actual value '" + actual + "'");
if(expected != null && !expected.equals(actual))
fail(message);
if(actual != null && !actual.equals(expected))
fail(message);
}
/**
* Throw an assertion error and log the message
* @param message
* @throws AssertionError in any case
*/
public void fail(String message)
{
fail(message, null);
}
/**
* Throw an assertion error and log the message
* @param message
* @param t
* @throws AssertionError in any case
*/
public void fail(String message, Throwable t)
{
if(t == null)
logger.severe(message);
else
logger.log(Level.SEVERE, message, t);
Assert.fail(message);
}
/**
* Every implementation must define how to wait for pending AJAX requests!
*/
public abstract void waitForPendingAjaxRequests();
/**
* Delay the test after creating a page object in order to make sure that the page has been fully rendered
*/
protected void delayPageLoad()
{
final long pageLoadDelay = testContext.getProperties().getPageLoadDelay();
if(pageLoadDelay > 0)
{
// Wait a short period of time until the page has been fully rendered
try
{
Thread.sleep(pageLoadDelay);
}
catch (final InterruptedException e)
{
// Ignored!
}
}
}
/**
* Scroll the browser window to the location of the given element
* @param element
*/
protected void scrollTo(WebElement element)
{
if(!(driver instanceof JavascriptExecutor))
{
logger.warning("Driver doesn't support execution of JavaScript!");
return;
}
final Point elementLocation = element.getLocation();
if(logger.isLoggable(Level.FINER))
logger.fine("Scroll to position x = " + elementLocation.x + " y = " + elementLocation.y);
final JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollTo(" + elementLocation.x + ", " + elementLocation.y + ");");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy