I generally caution against ‘Helper’ classes and Static Helper classes when I’m consulting. SlowLoadableComponent isLoaded methods can be very ugly but are a good example of where helper classes can help, and in particular fluent helper classes.
Helper Classes
By Helper classes I mean things like:
- PageObjectHelper,
- ApplicationHelper,
- StringHelper
- etc.
e.g.
StringHelper.removeAllNewLines(String)
StringHelper.replaceAllSpacesWith(String)
StringHelper.countAllLettersIgnoringSpaces(String)
- etc.
Because ‘generally’, these ‘Helper’ objects mean “We created a class to dump stuff in because we couldn’t figure out how to model our abstraction layers” and often, people then dump more and more methods into them such that they become an undisorganized and unmaintainable mess.
Just so you know where I’m coming from here.
Good Examples of Helper Classes
WebDriver has a ‘good’ Helper class in the form of the ExpectedConditions class. Every static method on it returns an expected condition which I can then use in a WebDriverWait, and these expected conditions represent very common wait conditions that I use across many projects.
Does SlowLoadableComponent need a Helper Class
When using SlowLoadableComponent
approach for Page Objects, we write a lot of code that looks like this:
@Override
protected void isLoaded() throws Error {
try {
// button must exist
final WebElement button =
driver.findElement(By.id("button00"));
if(!button.isDisplayed() && !button.isEnabled()){
throw new RuntimeException("Button not Ready");
}
}catch(Exception e){
throw new Error(e);
}
}
see “Why is my SlowLoadableComponent Not Waiting” for more information on SlowLoadableComponent.
These isLoaded
methods look fairly ugly and can be hard to maintain.
Helper Methods and Classes
We could take a leaf out of the ExpectedConditions class rule book and create an IsLoaded
‘helper’ Class
I have used 3 main approaches for this:
- A Fluent Class
- A set of Static methods
- Combined Fluent And Static
The example here uses a Fluent class with a static constructor in action where the code achieves the same result as the try
catch
code above.
IsLoaded.forThis(driver).
whenElementIsVisible(
By.id("button00"), "Start Button").
whenElementIsEnabled(
By.id("button00"), "Start Button");
You can see I create an IsLoaded
object via a factory method and then have the try
/catch
/throw error
stuff abstracted away on the IsLoaded
methods.
The methods all return this
making it easy to chain the methods
A ‘good’ Helper?
I think that this ‘Helper’ object is well enough named, and tightly enough scoped that it won’t cause a problem, so it doesn’t trigger my ‘Ugh, helper Class’ response.
Full Source
The full source for this is in my Webdriver Java FAQs project:
Specifically:
If you want to learn how to use Selenium WebDriver with Java then check out our online courses. I have a full course on Page Objects and Abstraction layers.