com.gfk.senbot.framework.data.SenBotReferenceService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of SenBotRunner Show documentation
Show all versions of SenBotRunner Show documentation
The SenBot runner which will actually run all your acceptance tests and report the outcome
package com.gfk.senbot.framework.data;
import static org.junit.Assert.fail;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang.StringUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.By.ById;
import org.openqa.selenium.By.ByXPath;
import org.openqa.selenium.support.PageFactory;
import org.springframework.beans.BeanUtils;
import com.gfk.senbot.framework.context.CucumberManager;
import com.gfk.senbot.framework.context.SenBotContext;
import com.gfk.senbot.framework.context.SpringPropertiesExposer;
/**
* A class to define global variables and reference them by a logical human readable way.
* This will help you instead to write tests like:
*
* Given I am looking at page https://localhost:8080/some_path/to/a/user_page.html?name=valie123456
*
* as like this: (which is easier to read)
*
* Given I am looking at the "user page"
*
*
* This is achieved by linking the url to the "user page" name as follows:
*
* static{
* referenceService.addPageReference("user page", "https://localhost:8080/some_path/to/a/user_page.html?name=valie123456");
* }
*
*
* The same reference mechanism is available for element locators to avoid long xpath in the tests and for {@link GenericUser}'s so that you can say things like
*
* Given I am loged in as a "admin" user
*
*
*
* @author joostschouten
*
*/
public class SenBotReferenceService {
public static final String NAME_SPACE_PREFIX = "NS:";
public static final String SCENARIO_NAME_SPACE_PREFIX = "SNS:";
/**
* Map to store generic reference objects by their respective class and name
*/
private Map> referenceMaps = new HashMap>();
private Map pageReferenceToPageUrlMap = new CaseinsensitiveMap();
/**
* Allows for referencing a page or view instantatable by the {@link PageFactory}
*/
private Map pageRepresentationMap = new CaseinsensitiveMap();
private ThreadLocal nameSpaceThreadLocale = new ThreadLocal() {
@Override
protected String initialValue() {
return "NS" + new Integer(UUID.randomUUID().hashCode()).toString() + "-";
}
};
private final CucumberManager cucumberManager;
/**
* Constructor
*
* @param populatorClassName
*
* @throws ClassNotFoundException
* @throws SecurityException
* @throws NoSuchMethodException
* @throws IllegalArgumentException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IOException
*/
public SenBotReferenceService(String populatorClassName,
CucumberManager cucumberManager) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException,
IllegalAccessException, InvocationTargetException, IOException {
this.cucumberManager = cucumberManager;
if (!StringUtils.isBlank(populatorClassName)) {
Constructor> constructor = Class.forName(populatorClassName).getConstructor();
ReferenceServicePopulator populator = (ReferenceServicePopulator) constructor.newInstance();
populator.populate(this);
}
}
/**
* Map a {@link GenericUser} to a reference name
*
* @param refName
* @param user
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
public void addUser(String refName, GenericUser user) {
addReference(GenericUser.class, refName, user);
}
void addConfigurableReferenceObject(String refName, T object) {
Map objectReferenceMap = getObjectReferenceMap((Class)object.getClass());
}
/**
* Map a {@link String} url to a reference name
*
* @param pageReference
* @param pageUrl
*/
public void addPageReference(String pageReference, String pageUrl) {
pageReferenceToPageUrlMap.put(pageReference, pageUrl);
}
/**
* Map a {@link By} element locator to a reference name
*
* @param locatorReference
* @param locator
*
* @deprecated use {@link SenBotReferenceService#addPageRepresentationReference(String, Class)} in stead to define views. Referencing elements at a global level
* is a bad idea as it becomes congested within no time and the element context is completely lost
*/
public void addLocatorReference(String locatorReference, By locator) {
Map objectReferenceMap = getObjectReferenceMap(By.class);
objectReferenceMap.put(locatorReference, locator);
}
/**
* Find a {@link By} locator by its reference name
*
* @param elementReference
* @return {@link By}
*/
public By getElementLocatorForElementReference(String elementReference) {
Map objectReferenceMap = getObjectReferenceMap(By.class);
By elementLocator = objectReferenceMap.get(elementReference);
if (elementLocator == null) {
fail("No elementLocator is found for element name: '" + elementReference + "'. Available element references are: " + objectReferenceMap.keySet().toString());
}
return elementLocator;
}
/**
* Find a {@link By} locator by its reference name and add something to the xpath before the element gets returned
* The drawback of using this method is, that all locators are converted into By.xpath
*
* @param elementReference The name under which the refference is found
* @param apendix The part of the xpath that shall be added
* @return {@link By}
*/
public By getElementLocatorForElementReference(String elementReference, String apendix) {
Map objectReferenceMap = getObjectReferenceMap(By.class);
By elementLocator = objectReferenceMap.get(elementReference);
if (elementLocator instanceof ById) {
String xpathExpression = elementLocator.toString().replaceAll("By.id: ", "//*[@id='") + "']" + apendix;
elementLocator = By.xpath(xpathExpression);
} else if (elementLocator instanceof ByXPath) {
String xpathExpression = elementLocator.toString().replaceAll("By.xpath: ", "") + apendix;
elementLocator = By.xpath(xpathExpression);
} else {
fail("ElementLocator conversion error");
}
if (elementLocator == null) {
fail("No elementLocator is found for element name: '" + elementReference + "'. Available element references are: " + objectReferenceMap.keySet().toString());
}
return elementLocator;
}
public void addPageRepresentationReference(String name, Class clazz) {
pageRepresentationMap.put(name, clazz);
}
/**
* Find a {@link GenericUser} by its reference name
*
* @param userType
* @return {@link GenericUser}
*/
public GenericUser getUserForUserReference(String userReference) {
GenericUser user = getReference(GenericUser.class, userReference);
if (user == null) {
fail("No user of type '" + userReference + "' is found. Available user references are: " + getObjectReferenceMap(GenericUser.class).keySet().toString());
}
return user;
}
/**
* Find a {@link String} url by its reference name
* @param pageReference
* @return {@link String} representing the url to the page mapped to the passed in page name
*/
public String getUrlForPageReference(String pageReference) {
String url = pageReferenceToPageUrlMap.get(pageReference);
if (url == null) {
fail("No url is found for page name: '" + pageReference + "'. Available page references are: " + pageReferenceToPageUrlMap.keySet().toString());
}
return url;
}
public Class getPageRepresentationReference(String pageRepresentationReference) {
Class ret = pageRepresentationMap.get(pageRepresentationReference);
if (ret == null) {
fail("No Class is found for page/view name: '" + pageRepresentationReference + "'. Available page references are: " + pageRepresentationMap.keySet().toString());
}
return ret;
}
public T getPageRepresentationInstance(Class referenceClassType) {
return SenBotContext.getSenBotContext().getSeleniumManager().getViewRepresentation(referenceClassType);
}
/**
* Extends the name space prefix with the actual name space
* All tests that need to ensure privacy, i.e. no other test shall mess up their data, shall
* use name spacing.
* Data that can be messed up by other tests and there fore needs to be unique shall contain the name space prefix
* that will be replaced at run time.
*
* @param plainString The string that contains the name spacing string
* @return The namespacenized string
* @throws RuntimeExpression In case the name spacing string lives at the wrong location
*/
public String namespaceString(String plainString) throws RuntimeException {
if(plainString.startsWith(NAME_SPACE_PREFIX)) {
return (plainString.replace(NAME_SPACE_PREFIX, nameSpaceThreadLocale.get()));
}
if(plainString.startsWith(SCENARIO_NAME_SPACE_PREFIX)) {
if(cucumberManager.getCurrentScenarioGlobals() == null) {
throw new ScenarioNameSpaceAccessOutsideScenarioScopeException("You cannot fetch a Scneario namespace outside the scope of a scenario");
}
return (plainString.replace(SCENARIO_NAME_SPACE_PREFIX, cucumberManager.getCurrentScenarioGlobals().getNameSpace()));
}
else {
return plainString;
}
}
public void addReference(Class referenceClass, String referenceName, T referenceObject) {
Map refMap = getObjectReferenceMap(referenceClass);
PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(referenceObject.getClass());
for(PropertyDescriptor descriptor : propertyDescriptors) {
//ignore all property types that are not strings for now
if(String.class.equals(descriptor.getPropertyType())) {
String findProp = referenceClass.getSimpleName() + "." + referenceName + "." + descriptor.getName();
String foundValue = SpringPropertiesExposer.getProperty(findProp);
if(foundValue != null) {
try {
org.apache.commons.beanutils.BeanUtils.setProperty(referenceObject, descriptor.getName(), foundValue);
} catch (Exception e) {
throw new RuntimeException("Exception while setting " + descriptor.getName() + " on " + referenceObject, e);
}
}
}
}
refMap.put(referenceName, referenceObject);
}
public Map getObjectReferenceMap(Class referenceClass) {
Map refMap = (Map) referenceMaps.get(referenceClass);
if (refMap == null) {
refMap = new CaseinsensitiveMap();
referenceMaps.put(referenceClass, (Map) refMap);
}
return refMap;
}
public T getReference(Class referenceClass, String referenceName) {
return getObjectReferenceMap(referenceClass).get(referenceName);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy