Selenium WebDriver – Scriptless Page Object Design Pattern – Part 2

Overview:

This article is continuation of Part 1 which you can read here.

In Part 1, We created JSON based page objects. Now lets see how to use them in our automation scripts.

Page Object Parser:

We need some script…..by this time, you might be like, Hold on! Script? Did you not say that Scriptless!!? Well.. Do not get upset! Please continue reading…! It will all make sense.

Yes.. we need some script which is going to be just one time creation which is responsible for parsing the JSON file and interacting with the page accordingly.

  • I would be launching the website using Chrome as it is shown here. More Info on the below DriverFactory is here.
WebDriver driver = DriverFactory.getDriver(DriverType.CHROME);
driver.get("https://form.jotform.com/81665408084158");
  • To parse the JSON file, I would be using Jackson library.
//you need this to use below ObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper;

//To parse JSON and convert to a map
String path = "/path/to/page-objects.json";
Map<String, Object> result = new ObjectMapper().readValue(new File(path), LinkedHashMap.class);

//Iterate all the keys from the map & enter data
result.entrySet()
        .stream()
        .forEach(entry -> {
            //find all the elements for the given name / map key
            List<WebElement> elements = driver.findElements(By.name(entry.getKey()));

            //scroll into view - remove this if you do not need it
            ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", elements.get(0));

            //element is found already, scrolled into view
            //now it is time for entering the value
            ElementsHandler.handle(elements, entry.getValue());
        });

The above script delegates all the data entering part to the below script.

Elements Handler:

The below script is basically handles different types of element inputs.

public class ElementsHandler {

    private static final Map<String, BiConsumer<List<WebElement>, Object>> map = new HashMap<>();

    //entering text box
    //we want only first element
    public static final BiConsumer<List<WebElement>, Object> TEXT_HANDLER = (elements, value) -> {
        elements.get(0).sendKeys(value.toString());
    };

    //radio button selection
    //iterate all the elements - click if the value matches
    public static final BiConsumer<List<WebElement>, Object> RADIO_HANDLER = (elements, value) -> {
        elements.stream()
                .filter(ele -> ele.getAttribute("value").equals(value))
                .forEach(WebElement::click);
    };

    //checkbox selection
    //iterate all the elements - click all the elements if the value is present in the list
    public static final BiConsumer<List<WebElement>, Object> CHECKBOX_HANDLER = (elements, value) -> {
        List<String> list = (List<String>) value;
        elements.stream()
                .filter(ele -> list.contains(ele.getAttribute("value")))
                .forEach(WebElement::click);
    };

    //dropdown selection
    //convert webelement to select
    private static final BiConsumer<List<WebElement>, Object> SELECT_HANDLER = (element, value) -> {
        Select select = new Select(element.get(0));
        select.selectByValue(value.toString());
    };

    //store all the above all elements handlers into a map
    static{
        map.put("input#text", TEXT_HANDLER);
        map.put("input#radio", RADIO_HANDLER);
        map.put("input#checkbox", CHECKBOX_HANDLER);
        map.put("select#select-one", SELECT_HANDLER);
        map.put("textarea#textarea", TEXT_HANDLER);
    }

    //handle element
    public static void handle(List<WebElement> elements, Object value){
        String key = elements.get(0).getTagName() + "#" + elements.get(0).getAttribute("type");
        map.getOrDefault(key, TEXT_HANDLER).accept(elements, value);
    }


}

Now we have everything ready to run the script. [The data was entered by the above script. Once it is done, I manually scrolled up to show the entered data]

 

Now you could keep on feeding the JSON files to the parser which knows how to enter data on the given page.

Questions?

I am sure you might have some questions in the approach.

  • Will this approach work for any type of application?
    • Well…It depends. Every framework will have its own pros and cons. Our traditional page object is difficult to maintain/create for pages which have hundreds of elements. So, in those cases, this approach would work great. Usually I would try combination of all. Would not suggest a single approach for any type of application.
  • Can I use it for my application?
    • Why not? You should be able to copy the scripts and try to use it for your application as well. However, Do remember that it is not a library which handles all types of applications/controls like Date input /slider etc.
  • Will this approach would enter always hard coded data? What about dynamic data? 
    • We can enhance this approach to a next level to enter dynamic data from CSV file/map etc. I have explained in the next article which is here.
  • This approach enters only data. What about other page validation?
    • Again, It can be done by modifying the Javascript we injected in the chrome console to create page object slightly in a different format to include page validation as well. I will leave that to you.

Summary:

We created a JSON based page object model by injecting Javascript on the chrome console. Then by feeding it to the JSON parser, we are able to interact with the application in no time. As I had mentioned, It is NOT a library for any type of applications. I had demoed a simple working example for you to understand and learn some concepts. Please use this and modify it as per your project needs.

Happy Testing & Subscribe 🙂

 

Share This:

3 thoughts on “Selenium WebDriver – Scriptless Page Object Design Pattern – Part 2

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.