Part 6. Helpers

Helper Methods

Due to the way we structure our framework, we can create static methods that we can use as helpers on methods involving different object types, such as clicking on a WebElement, explicitly waiting for a WebDriver, or waiting for a WebElement to be displayed or clickable etc.

WebElement Helpers

We will begin each method name with ‘we’ (for WebElement).

weWaitForSeconds() method

  1. Open up the ‘WebElementHelpers’ class in the ‘utils.helpers’ package and add the following method for making the WebDriver wait for a specified number of seconds…
    public WebDriverWait weWaitForSeconds() {
        WebDriverWait wait = new WebDriverWait(browser(), sec);
        return wait;
    }
  2. Make sure the import for ‘WebDriverWait’ and the static import for browser() method have been added above the class…
    import org.openqa.selenium.support.ui.WebDriverWait;
    import static utils.selenium.Driver.browser;
  3. Add an integer variable set to a value of 10 for ‘sec’, and make it private to the class it is in, just above the weWaitForSeconds() method…
    private int sec = 10;

weElementIsDisplayed() method

  1. Add the following method in the ‘WebElementHelpers’ class to check that a given WebElement is displayed, after waiting the specified amount of time from the weWaitForSeconds() method …
    public boolean weElementIsDisplayed(WebElement element) {
        weWaitForSeconds().until(ExpectedConditions.visibilityOf(element));
        return element.isDisplayed();
    }
  2. Also make sure the import for ‘ExpectedConditions’ is added above the class, as well as an import for ‘WebElement’…
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.WebElement;

weElementToBeClickable() method

  1. Add the following method in the ‘WebElementHelpers’ class to check that a given WebElement is clickable, after waiting the specified amount of time from the weWaitForSeconds() method…
    public boolean weElementToBeClickable(WebElement element) {
        weWaitForSeconds().until(ExpectedConditions.elementToBeClickable(element));
        return element.isEnabled();
    }

weHighlightElement() method

  1. Add the following method in the ‘WebElementHelpers’ class to highlight a given WebElement using JavaScript…
    public void weHighlightElement(WebElement element) {
        JavascriptExecutor js = (JavascriptExecutor) browser();
        js.executeScript(weHighlightedColour, element);
    }
  2. Also make sure that an import for JavascriptExecutor has been added above the class…
    import org.openqa.selenium.JavascriptExecutor;
  3. You will notice that an error is thrown due to not knowing what ‘weHighlightedColour’ is, so let’s add that in the ‘Settings’ class of the ‘utils.selenium’ package (of course you can also customise this to change the colour and size of the border etc.)…
    public String weHighlightedColour = "arguments[0].style.border='5px solid blue'";
  4. Finally, go back to the ‘WebElementHelpers’ class and add a static import for ‘weHighlightedColour’ in the ‘Settings’ class
    import static utils.selenium.Settings.weHighlightedColour;

weClick() method

  1. Add the following method in the ‘WebElementHelpers’ class to wait for a given WebElement to be clickable, highlight the clickable WebElement, and then click the WebElement…
    public void weClick(WebElement element) {
        weElementToBeClickable(element);
        weHighlightElement(element);
        element.click();
    }

weSendKeys() method

  1. Add the following method in the ‘WebElementHelpers’ class to wait for a given text field WebElement to be displayed, clear the text field if necessary (if ‘clearFirst’ is true), and then input a given String into the text field…
    public void weSendKeys(WebElement element, String text, boolean clearFirst) {
        weElementIsDisplayed(element);
        if (clearFirst) weClick(element);
        element.sendKeys(text);
    }

weElementIsInvisible() method

  1. Add the following static method in the ‘WebElementHelpers’ class to wait for a given WebElement to not be visible anymore…
    public static boolean weElementIsInvisible(WebElement element) {
        weWaitForSeconds().until(ExpectedConditions.invisibilityOf(element));
        return !element.isDisplayed();
    }

weGetAttribute() Static Method

  1. Add the following static method in the ‘WebElementHelpers’ class to find a specified attribute of a given element…
    public static String weGetAttribute(WebElement element, String attribute) {
        return element.getAttribute(attribute);
    }

WebDriver Helpers

We will begin each method name with ‘wd’ (for WebDriver).

wdHighlight() method

  1. Open up the ‘WebDriverHelpers’ class in the ‘utils.helpers’ package and add the following method for highlighting a given locator using JavaScript…
    public Object wdHighlight(By locator) {
        WebDriver driver = browser();
        WebElement myLocator = driver.findElement(locator);
        JavascriptExecutor js = (JavascriptExecutor) driver;
        return js.executeScript(wdHighlightedColour, myLocator);
    }
  2. You will notice that an error is thrown due to not knowing what ‘wdHighlightedColour’ is, so let’s add that in the ‘Settings’ class of the ‘utils.selenium’ package (of course you can also customise this to change the colour and size of the border etc.)…
    public static String wdHighlightedColour = "arguments[0].style.border='5px solid green";
  3. Next, go back to the ‘WebDriverHelpers’ class and add a static import for ‘wdHighlightedColour’ in the ‘Settings’ class…
    import static utils.selenium.Settings.wdHighlightedColour;
  4. Of course, also check that the imports for ‘WebDriver’, ‘WebElement’, ‘JavaScriptExecutor’ and ‘By’ have been added above the class, as well as a static import again for the browser() method in the ‘Drivers’ class of the ‘utils.selenium’ package…
    import org.openqa.selenium.By;
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import static utils.selenium.Driver.browser;

wdElementIsDisplayed() method

  1. Open up the ‘WebDriverHelpers’ class in the ‘utils.helpers’ package and add the following method for checking that a highlighted locator is displayed…
    public Object wdElementIsDisplayed(By locator) {
        wdHighlight(locator);
        WebDriverWait wait = new WebDriverWait(browser(), sec);
        return wait.until(ExpectedConditions.visibilityOf((WebElement) locator));
    }
  2. Make sure the import for ‘WebDriverWait’ and ‘ExpectedConditions’ have been added above the class…
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
  3. Add an integer variable set to a value of 10 for ‘sec’, and make it private to the class it is in, just above the weWaitForSeconds() method…
    private int sec = 10;

wdElementIsInvisible() method

  1. Add the following method in the ‘WebDriverHelpers’ class to wait for a given locator to not be visible…
    public void wdElementToDisappear(By locator) {
        WebDriverWait wait = new WebDriverWait(browser(), 5);
        wait.until(ExpectedConditions.invisibilityOfElementLocated(locator));
    }

wdFindElement() method

  1. Add the following method in the ‘WebDriverHelpers’ class to find a displayed element by its locator…
    public WebElement wdFindElement(By locator) {
        wdElementIsDisplayed(locator);
        return browser().findElement(locator);
    }

wdClick() method

  1. Add the following method in the ‘WebDriverHelpers’ class to click on an element which has been found by its locator…
    public void wdClick(By locator) {
        wdFindElement(locator).click();
    }

wdSendKeys() method

  1. Add the following method in the ‘WebDriverHelpers’ class to wait for a given text field element (which has been found by its locator) to be displayed, clear the text field if necessary (if ‘clearFirst’ is true), and then input a given String into the text field…
    public void wdSendKeys(By locator, String text, boolean clearFirst) {
        if (clearFirst) wdClick(locator);
        wdFindElement(locator).sendKeys(text);
    }

Refactoring our Test Scenario to use the Helpers

We can now use our extensions (static methods) to replace previous lines of code in our test methods.  Over time, this helps us follow DRY principles (Don’t Repeat Yourself) as well as make our code easier to read 🙂

Adding instances of the Helper classes to our Base page

  1. Open up the BasePage class and add the following  in the class to instantiate our Helper classes and allow all pages that inherit from the base page access to them too…
    protected WebElementHelpers elementHelpers = new WebElementHelpers();
    protected WebDriverHelpers driverHelpers = new WebDriverHelpers();

‘searchFor()’ method

  1. Open up the ‘SearchScenarios.feature’ file, right-click on the ‘When I search for “Reddit”‘ step, and select ‘Go To’ –> ‘Declaration’
  2. Right-click on the ‘.searchFor()’ method call and select ‘Go To’ –> ‘Declaration’ again
  3. Edit the ‘searchFor()’ method so it uses the weSendKeys() method from the ‘WebElementHelpers’ class…
    public SearchResultsPage searchFor(String searchTerm) {
        elementHelpers.weSendKeys(searchField, searchTerm, true);
        return instanceOf(SearchResultsPage.class);
    }

‘assertSearchResultsDisplayed()’ method

  1. Open up the ‘SearchResultsPage’ class and edit the method to use the weElementIsDisplayed() method from the ‘WebElementHelpers’ class…
  2. public void assertSearchResultsDisplayed() {
        Assert.assertTrue(elementHelpers.weElementIsDisplayed(searchResultsContainer));
    }

‘selectFirstListedSearchResult()’ method

  1. Open up the ‘SearchResultsPage’ class again
  2. Edit the ‘selectFirstListedSearchResult()’ method so it uses the weClick() method (which already has an explicit wait in it, up to 10 seconds) from the ‘WebElementHelpers’ class…
    public RedditPage selectFirstListedSearchResult() {
        elementHelpers.weClick(searchResultLinks.get(0));
        return instanceOf(RedditPage.class);
    }

You can run your tests in CLI (command line interface) by entering

mvn test

or

gradle test

respectively.

Congratulations on completing this blog series.