Monday, September 21, 2015

Concise Selenium Tests in Java using Selenide

There are many wrappers available on Selenium to simplify writing UI tests using Selenium. Selenide is the new Selenium wrapper which supports all features of that Selenium. It allows automation developers to work with elements using jQuery style of notation. It makes Selenium code more readable, and wraps features like waits otherwise have to be written explicitly. I have tried creating a simple test using Selenide, found it's pretty simple to write tests, tests are more readable, don't have to worry for creating WebDriver object, and closing WebDriver object. I would like try Selenide for more complex tests in coming days. Here is a simple test to validate search results of Google's search page for a simple query.

package com.selenidedemo.one;

import org.testng.annotations.Test;
import static com.codeborne.selenide.Selenide.open;
import org.openqa.selenium.By;
import static com.codeborne.selenide.Selenide.$;
import static com.codeborne.selenide.Selenide.$$;
import static com.codeborne.selenide.Condition.text;

public class SearchTest {
    
 @Test
 public void validateSearchResults() {
  open("http://google.com/");
  $(By.name("q")).val("Mount Everest").pressEnter();
  $$("#ires .g").get(0).shouldHave(text("Mount Everest"));
 }
}

Creating Selenium tests using Selenide library easy. Download and add Selenide jar to your project and start creating the Selenium tests using Selenide functions.

Selenide web site: http://selenide.org/
Documentation: http://selenide.org/documentation.html
Quick Start: http://selenide.org/quick-start.html


Thursday, July 16, 2015

Object Handler in Multi Platform Apps

Presence of same application in multiple mobile platforms (iOS, Android etc) is quite common as application developers want to capture the market of all popular platforms. Automating your app for multiple platforms is challenging when they are native applications. Apps on different platforms differ with element definitions, element hierarchy, page hierarchy, and even workflows. One solution to this problem is, to maintain different automation code bases for different platforms or to automate them in respective automation technologies. If functionality and workflow of the app in different platforms is same, then only changing parameter is object definition. How do we handle this scenario with page object pattern?

Page Object Pattern is popular approach followed by automation developers to definite separate classes for each functional page to definite elements, actions, and validations. In basic page object implementation, a typical page class include element definitions, getting values from controls, setting values to controls, actions (like click, check, select) on controls, and validations (or assertions).


To address multi platform apps with common automation code base, we can reorganize the page object classes in such a way we can create workflow classes with methods to a particular part of functionality and contains calls to methods in one or more page classes. This way it moduralizes the frequently called actions into workflow methods. Using this approach, tests look more readable, and code re-use is improved. When there is a change in functionality, this approach reduces the maintenance of scripts that we don't have to make changes in multiple scripts, changes are needed in workflow methods. 


In this approach, we create separate ObjectMap classes which contains object/element definitions for different platforms. Element definitions can be maintained in the class itself or can be loaded from a properties file. Constructor of ObjectMap class contains parameter to determine the mobile platform. Based on mobile platform, element methods returns the proper element object. Page object contains the action methods, element getter/setter methods for values like reading text from textbox or setting a value to textbox.


Scenario: Let's try this approach with an example. In a ToDo app, one of the tests is to create a task after logging into the system, and verifying whether task is created. This test involves 3 steps, 1. Login to system, 2. Create a task, 3. Check. Creating a task involves entering basic details of a task, assigning resources (resources are added from a different page), and saving the task. Create task method involves accessing methods from Create Task page and methods from Resources page. We can create a workflow method called CreateTask in TaskWorkflow class which calls page methods from create task page and resources page. This way if there is any change in create task workflow in future, we can make change in CreateTask workflow method.





Wednesday, July 8, 2015

Design Patterns - Driver Factory

One of the advantages of Selenium is it's support for multiple browsers. Mobile automation platforms like Appium support for Selenium. This makes Selenium a versatile library not only for multiple browsers, but also for mobile platforms.When a test needs to be performed on both browser and mobile, Selenium wins the title.

There are many approaches to utilize multi-browser support in Selenium. One of them is to centralize the Web Driver object creation based on configuration using Factory Pattern. Basically target browser name is configured in a properties file (Java world) or App.Config (C# world), and a factory method takes care of the web driver object creation based on configured value. 

In this solution, browser name (aka target browser) is stored against a key in a properties file. Test fixture (method with @Before annotation in TestNG/JUnit) calls a utility method to get driver instance. This utility method reads the configured browser name from configuration file, and calls web driver object creation method of Driver Factory class.

Such approaches of centralizing the web driver creation through a configuration parameter helps when tests are integrated with CI solution like Jenkins to run tests in multiple browsers. 






Properties File: This file contains key value pairs. One of the keys is "browser name" with possible values FireFox, or IE, or Chrome.

Driver Map: Driver Map can be a singleton class or a regular utility class with a method to read value of "browser name" key in properties file and calls driver creation method in Driver Factory class. Driver Map being a Singleton is helpful if you want to create the web driver instance once for all tests or when you want your page object classes and other object handling static methods to access the web driver instance. (I will cover passing web driver instance to various classes in another post). The same singleton can be used to maintain both web driver instance of browser, as well as Appium (mobile) driver in case you are using Appium.

Driver Factory: A simple method with a parameter browser type and a switch case to handle Web Driver object creation. This method returns instance of Web Driver which is eventually used in selenium tests.