/Query

A query object designed to make page objects easier to manage

Primary LanguageJavaApache License 2.0Apache-2.0

Query

License Build Status codecov GitHub release Maven Central Javadocs

A query object designed to make page objects easier to manage

How do I get started?

It's nice and simple, add the following entry to your POM:

<dependency>
    <groupId>com.lazerycode.selenium</groupId>
    <artifactId>query</artifactId>
    <version>2.0.0-BETA3</version>
    <scope>test</scope>
</dependency>

Then just create a basic query object in your page object when you want to use it:

Query query = new Query().defaultLocator(By.id("foo"));

Then when you create your driver object you will need let the Query object know about it like this:

query.usingDriver(driver);

Or if you already have a driver object you can just do it all in one go:

Query query = new Query().defaultLocator(By.id("foo")).usingDriver(driver);    

Do you want to have different locators for different browsers? You can add specific locators for different browsers:

query.addSpecificLocator(BrowserType.GOOGLECHROME, By.id("bar")
   .addSpecificLocator("custom_driver", By.id("custom");

Once you have set specific locators the query object will check the desired capabilities of the current instantiated driver and just use the appropriate locator. If it cannot find one it will drop back to the default locator. If no appropriate locators are found it will throw a IllegalStateException.

Setting a driver object for every Query object is a real PITA, isn't there an easier way?

Instead of passing a .usingDriver(driver) command to each driver object you can instead put the following code into your constructor:

initQueryObjects(this, driver);

for this to work you will need the following static import:

import static com.lazerycode.selenium.util.AssignDriver.initQueryObjects;    

Instead of using the constructor you can pass in an instance of your page object class:

SomePageObject somePageObject = new SomePageObject();
initQueryObjects(somePageObject, driver);

This will scan the current class for valid Query objects and then assign the supplied driver object to each Query object. This does need to be an instantiated driver object, passing in a null will result in an error. You can then of course still modify the driver object assigned to a Query object at any point in the future using the .usingDriver(driver) command on individual Query objects.

OK, I have a query object. Now what?

It's designed to return certain element types that you can use in your page objects, the various types are shown below:

WebElement element = query.findWebElement();
List<WebElement> elementList = query.findWebElements();
Select selectElement = query.findSelectElement();
MobileElement mobileElement = query.findMobileElement();
List<MobileElement> mobileElementList = query.findMobileElements();

Ok, that's kind of useful, anything else?

Have you ever got frustrated trying to get locators out of element to use in expected conditions? No longer a problem:

WebDriverWait wait = new WebDriverWait(driver, 15, 100);
wait.until(ExpectedConditions.visibilityOfElementLocated(query.by()));

That's all for now, if you can think of any useful additions just raise an issue.