A personal repository of random information in compensation for a fatigued biological computer
GDAPComon.java
package testNG;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
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.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.Reporter;
import org.testng.annotations.BeforeSuite;
public class GDAPCommon {
/*
* Constants & functionality used across multiple application pages
*/
/*
* ************ constants *************
*/
public static final int waitLongSeconds = 60;
public static final int waitNormalSeconds = 10;
public static final int waitShortSeconds = 2;
/*
* Used where a job state is needed so we have a single point of update
*/
public enum JOBSTATES {
INDRAFT("In Draft"),
FORREVIEW("For Review"),
REVIEWED("Reviewed"),
FINISHED("Finished");
private String text;
private JOBSTATES(String text){
this.text = text;
}
public String getText() {
return text;
}
}
/*
* Entity selections
*/
public enum ENTITIES {
ACCESSAUTHORITY ("Access Authority"),
ACCESSION ("Accession"),
Agency ("Agency"),
DISPOSALAUTHORITY ("Disposal Authority"),
FUNCTION ("Function"),
ITEMGROUP ("Item group"),
JURISDICTION ("Jurisdiction"),
ORGANISATION ("Organisation"),
SERIES ("Series");
private String text;
private ENTITIES(String text){
this.text = text;
}
public String getText() {
return text;
}
}
/*
* user rights (by role) INCOMPLETE
*/
public enum ROLES {
EDITOR("Editor"),
REVIEWER("Reviewer"),
MANAGER("Manager");
private String text;
private ROLES(String text){
this.text = text;
}
public String getText() {
return text;
}
}
/**
* ************ Date helpers *****************
*/
public static String getDateFormatted(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy");
return sdf.format(date);
}
public static String getTimeHHMMSS(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
return sdf.format(new Date());
}
public static String appendCurrentDateTime(String target) {
return target + "_" + getDateFormatted(new Date()) + "_" + getTimeHHMMSS(new Date());
}
public static String prefixCurrentDateTime(String target) {
return getDateFormatted(new Date()) + "_" + getTimeHHMMSS(new Date()) + " " + target;
}
/*
* ************ TestNG Context *****************
*/
// Doing as @Beforesuite here as I don't know how else to get the TestNG context needed
// for getting XML parameters
private static ITestContext gdapTestNGContext;
@BeforeSuite(alwaysRun = true)
public void startTest(ITestContext context) {
gdapTestNGContext = context;
}
public static String getTestNGXMLParameter(String parameterName) {
GDAPCommon.report("getTestNGXMLParameter: '" + parameterName + "'");
String param = gdapTestNGContext.getCurrentXmlTest().getParameter(parameterName);
if (param == null) {
reportAndFail("XML parameter not found: '" + parameterName + "'");
}
return param;
}
private static int reportStartStackDepth = 0;
public static void report(String message) {
/*
* Log entry short form
* Queries call stack depth to indent current logging message accordingly
*/
int currentStackDepth;
//StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
currentStackDepth = Thread.currentThread().getStackTrace().length;
if (reportStartStackDepth == 0) {
reportStartStackDepth = currentStackDepth;
}
currentStackDepth -= reportStartStackDepth;
Reporter.log(prefixCurrentDateTime(StringUtils.repeat(" ", currentStackDepth*4)) + message + "<br>");
}
public static void reportAndFail(String message) {
/*
* Log entry & force fail test
*/
Assert.fail(prefixCurrentDateTime(message) + message);
}
/*
* ************* Manage browser ************
*/
public WebDriver startGDAP() {
/*
* Start browser & application
*/
report("startGDAP: Starting Browser");
String gdapURL = getTestNGXMLParameter("gdap.url");
WebDriver gdap_Driver = new FirefoxDriver();
gdap_Driver.manage().timeouts().implicitlyWait(GDAPCommon.waitNormalSeconds, TimeUnit.SECONDS);
report("startGDAP: Starting GDAP, URL is " + gdapURL);
gdap_Driver.get(gdapURL);
return gdap_Driver;
}
public static void closeGDAP(WebDriver driver) {
/*
* Close application tab
*/
report("closeGDAP: Closing browser");
driver.close();
}
public static void browserMaximise(WebDriver driver) {
driver.manage().window().maximize();
}
public static void browserMinimise(WebDriver driver) {
driver.manage().window().maximize();
}
public static void browserRestorer(WebDriver driver) {
driver.manage().window().maximize();
}
/* ********* Left behind from when was using PageFactory *********** */
/* ****** WILL DELETE ONCE SURE NO LONGER NEEDED *********
public WebElement ifElementsValidReturnFirstElement(WebDriver driver, List<WebElement> elements) {
if (elements.size() > 0)
return (WebElement) elements.get(0);
return null;
}
public List<WebElement> ifElementsValidReturnElements(WebDriver driver, List<WebElement> elements) {
if (elements.size() > 0)
return elements;
return null;
}
public void assertWebElement(WebDriver driver, WebElement element, String errorMessage) {
System.out.println("assertWebElement: " + errorMessage);
if (!doesWebElementExist(driver, element)) {
report("assertWebElement failed: '" + errorMessage + "'");
Assert.fail("assertWebElement failed: '" + errorMessage + "'");
}
}
*/
/* ******************** Wait for helpers & wrappers *******************/
/* perhaps not needed
public enum WAITFOR {
PRESENT,
NOTPRESENT,
VISIBLE,
NOTVISIBLE;
}
public static void waitForElement(WebDriver driver, By by, WAITFOR waitFor) {
switch (waitFor)
{
case PRESENT:
waitForElementPresentBy(driver, by);
break;
case NOTPRESENT:
waitForElementNotPresentBy(driver, by);
break;
case VISIBLE:
waitForElementVisibleBy(driver, by);
break;
case NOTVISIBLE:
waitForElementNotVisibleBy(driver, by);
break;
}
}
*/
/*
* Simple waits
* Any timeouts in use will cause test to fail
*/
public static void waitForElementPresentBy(WebDriver driver, By by) {
WebDriverWait wait = new WebDriverWait(driver, GDAPCommon.waitLongSeconds);
wait.until(ExpectedConditions.presenceOfElementLocated(by));
}
public static void waitForElementNotPresentBy(WebDriver driver, By by) {
WebDriverWait wait = new WebDriverWait(driver, GDAPCommon.waitLongSeconds);
wait.until(ExpectedConditions.not(ExpectedConditions.presenceOfElementLocated(by)));
}
public static void waitForElementVisibleBy(WebDriver driver, By by) {
WebDriverWait wait = new WebDriverWait(driver, GDAPCommon.waitLongSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(by));
}
public static void waitForElementNotVisibleBy(WebDriver driver, By by) {
WebDriverWait wait = new WebDriverWait(driver, GDAPCommon.waitLongSeconds);
wait.until(ExpectedConditions.invisibilityOfElementLocated(by));
}
public static void waitForElementTextBy(WebDriver driver, By by, String text) {
WebDriverWait wait = new WebDriverWait(driver, GDAPCommon.waitLongSeconds);
wait.until(ExpectedConditions.textToBePresentInElement(by, text));
}
public static void waitForElementNotTextBy(WebDriver driver, By by, String text) {
WebDriverWait wait = new WebDriverWait(driver, GDAPCommon.waitLongSeconds);
wait.until(ExpectedConditions.not(ExpectedConditions.textToBePresentInElement(by, text)));
}
public static void waitForElementDateBy(WebDriver driver, By by, Date date) {
WebDriverWait wait = new WebDriverWait(driver, GDAPCommon.waitLongSeconds);
wait.until(ExpectedConditions.textToBePresentInElement(by, getDateFormatted(date)));
}
public static void waitForElementByEqualsElementBy(WebDriver driver, By by1, By by2) {
WebDriverWait wait = new WebDriverWait(driver, GDAPCommon.waitLongSeconds);
wait.until(elementEqualsElement(by1, by2));
}
private static ExpectedCondition<Boolean> elementEqualsElement(final By by1, final By by2) {
/*
* An expectation that that an element selected 2 different ways is the same
* Example use:
* - is element selected by title same as one selected by row number?
*/
return new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
try {
WebElement element1 = driver.findElement(by1);
WebElement element2 = driver.findElement(by2);
if (element1.equals(element2)) {
return true;
}
return false;
} catch (NoSuchElementException e) {
return null;
}
}
};
}
/* ******************** Query current state of elements *************** */
public static void waitForAjax(WebDriver driver, int timeoutInSeconds) {
/*
* http://hedleyproctor.com/2012/07/effective-selenium-testing/
* Queries target page ajax connection queue depth
*/
System.out.println("Checking active ajax calls by calling jquery.active");
try {
if (driver instanceof JavascriptExecutor) {
JavascriptExecutor jsDriver = (JavascriptExecutor)driver;
for (int i = 0; i< timeoutInSeconds; i++) {
Object numberOfAjaxConnections = jsDriver.executeScript("return jQuery.active");
// return should be a number
if (numberOfAjaxConnections instanceof Long) {
Long n = (Long)numberOfAjaxConnections;
System.out.println("Number of active jquery ajax calls: " + n);
if (n.longValue() == 0L) {
break;
}
}
Thread.sleep(1000);
}
}
else {
System.out.println("Web driver: " + driver + " cannot execute javascript");
report("ERROR: Web driver: " + driver + " cannot execute javascript");
}
}
catch (InterruptedException e) {
System.out.println(e);
}
}
public static boolean isElementPresentBy(WebDriver driver, By by) {
/*
* For conditional test flow
*/
@SuppressWarnings("unused")
WebElement element;
waitForAjax(driver, waitNormalSeconds);
boolean result = false;
try {
element = driver.findElement(by); // just a nothing operation to force selenium to try to find this element
result = true;
} catch (NoSuchElementException e) {
}
return result;
}
public boolean isPresentElementEnabledBy(WebDriver driver, By by) {
waitForAjax(driver, waitNormalSeconds);
return (driver.findElement(by)).isEnabled();
}
public boolean isPresentElementDisabledBy(WebDriver driver, By by) {
waitForAjax(driver, waitNormalSeconds);
return (!driver.findElement(by).isEnabled());
}
public boolean isPresentElementVisibleBy(WebDriver driver, By by) {
waitForAjax(driver, waitNormalSeconds);
return (driver.findElement(by).isDisplayed());
}
public static boolean isPresentElementInvisibleBy(WebDriver driver, By by) {
waitForAjax(driver, waitNormalSeconds);
return (!driver.findElement(by).isDisplayed());
}
public static String getElementTextBy(WebDriver driver, By by) {
// See how this goes may need to be by element type
waitForAjax(driver, waitNormalSeconds);
return driver.findElement(by).getText();
}
public static int getElementsCountBy(WebDriver driver, By by) {
List<WebElement> elements = driver.findElements(by);
return elements.size();
}
/* ******************** Rich text specific **************************** */
/*
* Richtext tinyMCE fields are all in their own IFrame
*
* Note: http://watirmelon.com/tag/javascript/ suggest using JavaScript is better
* for multi browser compatibility BUT relies on tinyMCE on javascript.. so... is
* it robust to rely on that?
*
* Note: Caution: TinyMCE inserts/removes '<br data-mce-bogus="1">' so we make allowances for that
*/
private static final By TINYMCETARGETELEMENTINIFRAMEXPATH = By.xpath("//body/p");
private static final String TINYMCEBOGUSINDICATOR = "<br data-mce-bogus=\"1\">";
private static void switchToIFrameBy(WebDriver driver, By by) {
// Focus on iFrame
WebElement frame = driver.findElement(by);
driver.switchTo().frame(frame);
}
public String tinyMCEFieldGetContent(WebDriver driver, By by) {
/*
* Function to get target field content from within parent IFrame
* Returns Selenium focus back to main DOM afterwards
*
* @by = IFrame container By locator
*
*/
switchToIFrameBy(driver, by);
// Action
isPresentElementInvisibleBy(driver, TINYMCETARGETELEMENTINIFRAMEXPATH); // will this ensure TinyMCE JS completed?
String content = getElementTextBy(driver, TINYMCETARGETELEMENTINIFRAMEXPATH);
// Strip out TinyMCE bogus data bit
content = content.replace("<br data-mce-bogus=\"1\">", "");
// Switch back to main context
driver.switchTo().defaultContent() ;
// Done
return content;
}
public void tinyMCEFieldSetContent(WebDriver driver, By by, String text) {
/*
* Function to set target field content within parent IFrame
* Returns Selenium focus back to main DOM afterwards
*
* @by = IFrame container By locator
*/
switchToIFrameBy(driver, by);
// Action
isPresentElementEnabledBy(driver, TINYMCETARGETELEMENTINIFRAMEXPATH);
clearAndEnterTextBy(driver, TINYMCETARGETELEMENTINIFRAMEXPATH, text);
// Switch back to main context
driver.switchTo().defaultContent();
// Done
}
public static void waitForTinyMCEElementTextBy(WebDriver driver, By by, String text) {
/*
* @by = IFrame container By locator
*/
WebDriverWait wait = new WebDriverWait(driver, GDAPCommon.waitLongSeconds);
wait.until(textToBePresentInTinyMCEElement(by, text));
}
/**
* An expectation for checking if the given text is present in the specified
* TinyMCE Iframe editor content.
*
* Strips '<br data-mce-bogus="1">' from found text
*/
private static ExpectedCondition<Boolean> textToBePresentInTinyMCEElement(
final By locator, final String text) {
return new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
try {
String elementText = driver.findElement(locator).getText();
elementText = elementText.replaceAll(TINYMCEBOGUSINDICATOR, "");
return elementText.contains(text);
} catch (NoSuchElementException e) {
return null;
}
}
};
}
/* ******************** Action utilities **************************** */
// Where actions act on a single element they return the target WebElement
// 20130122 Can probably no longer return WebElement now that PageFactory not used
// but no harm for now
public static WebElement clickHarmlessly(WebDriver driver) {
return clickBy(driver, PageCommon.byArchwayLogo);
}
public static WebElement clickBy(WebDriver driver, By by) {
WebElement element = driver.findElement(by);
element.click();
return element;
}
public static WebElement clearAndEnterTextBy(WebDriver driver, By by, String text) {
WebElement element = driver.findElement(by);
element.clear();
element.sendKeys(text);
return element;
}
}
xx