Selenium Page Object Code Generator

0.00 avg. rating (0% score) - 0 votes
How Selenium Page Object Code Generator helped us bring down the coding time from 4.5 hours to less than 5 minutes for a single page object!!
How it started:
Back in 2012 we used to have separate teams for manual and automation testing. Automation team comprised of 2-3 people, who were working on customized hybrid framework in Selenium whereas the manual testing team was of approx. 25-30 people. This dedicated automation team used to cater to the automation needs for all Info Edge sites like Naukri.com, NaukriGulf.com, 99acres.com, Jeevansathi.com & Shiksha.com. The automation work used to happen then for very limited scope and very late in the release cycle. In 2013 we brought in a paradigm shift and trained the entire testing team in Selenium and embarked on a journey to have a team which was fully equipped in doing testing entirely, which meant both manual and automation testing. As the automation team grew suddenly from 2 to 25 so did the need for bringing in processes like Coding standards, Folder structure, Code management and Frameworks.
We then finalized our framework architecture design – POM (Page Object Model) with TestNG and XSLT for custom report generation and started implementing the same in our team.
Although POM brought with it host of advantages like standardization, maintainability, clarity, scalability and robustness, it needed too much of mundane and repetitive coding effort in creating page objects with locator definitions and common functions for each locator.
Just to understand the gravity of this downside let us do effort estimation for a single form:
Say we have a registration page consisting of 13 textboxes, 5 dropdowns, 2 check boxes, 3 links and 1 button. Then the total number of methods required for creating page object class would be as follows:
WebElement Methods No of methods No of elements on Form Total Methods
Effort

(3min/Method)

Textbox Fill, Click, GetText, Clear 4 13 52
156
DropDown Select, DeSelect, GetSelectedValue, GetSelectedID 4 5 20
60
Checkbox Check, UnCheck, IsChecked 3 2 6
18
Radio button Select, GetSelectedValue 2 0 0
0
Link Click, GetLinkText 2 3 6
18
Button Click 1 1 1
3
WebElement Click, GetElementText 2 0 0
0
Total Methods 85
255 minutes
Thus the total effort required to write code for a single page object for the first time was approximately 255 minutes which is a whopping 4.5 hours !!
Solution: We came up with the idea of creating Automated Code generator for Page Objects. Knowing the standard list of functions associated and needed with each HTML element type we went ahead and created the following code generator. And with this within 2-4 minutes anyone and everyone could generate all the code needed to get him started with any page object class.
So to take an example:
We wanted to generate code for a search form page comprising of keyword, location textbox and experience and salary drop downs & a search button
publicclassQSB_Naukri {
    WebDriver driver;
    GenericFunctions generic;
    finalstaticpublicString Keywords_Txt= “//div[@id=’skill’]//input[1]”;
    finalstaticpublicString Location_Txt= “//div[@id=’location’]//input[1]”;
    finalstaticpublicString Experience_DD= “//div[@id=’exp_dd’]/div/input[1]”;
    finalstaticpublicString Salary_DD= “//div[@id=’salary_dd’]/div/input[1]”;
    finalstaticpublicString Search_Btn= “//button[text()=’Search ‘]”;
}
Step 1 for Code generation:
  1. Write xpaths following defined coding guidelines for each element type (like “_Txt” for text box, “_DD” for dropdown, “_Btn” for button etc)
        final static public String Keywords_Txt = “//div[@id=’skill’]//input[1]”;
        finalstaticpublicString Location_Txt= “//div[@id=’location’]//input[1]”;
        finalstaticpublicString Experience_DD= “//div[@id=’exp_dd’]/div/input[1]”;
        finalstaticpublicString Salary_DD= “//div[@id=’salary_dd’]/div/input[1]”;
        finalstaticpublicString Search_Btn= “//button[text()=’Search ‘]”;
  1. Fetch the variables declared in the class
  2. Traverse through each variable to know its name
  3. Check the type of web object[ by using step1]
  4. Generate Code
//Create object for the class that we want to generate code
QSB_Naukri p1 =new QSB_Naukri ();
// Traverse through each xpath variable
for(Field field : p1.getClass().getDeclaredFields()) {

    String xpathdet = field.getName();

    //check condition to know type of object and generate code
    if(xpathdet.endsWith(“_Txt”)){
        //generate code like this
        BufferedWriter out= = new BufferedWriter(new FileWriter(“Path for the generated code”, true));
out.newLine();
out.write(“public void Fill_”+label_name+“_Txt(String inputdata){“);
out.newLine();
out.newLine();
out.write(“if(inputdata.trim().length()==0)return;”);
out.newLine();
out.write(“try{“);
out.newLine();
out.write(“driver.findElement(By.xpath(“+xpathdet+“)).clear();”);
out.newLine();
out.write(“driver.findElement(By.xpath(“+xpathdet+“)).sendKeys(inputdata);”);
out.newLine();
out.write(“}catch(Exception e){“);
out.newLine();
out.write(“generic.GoToSleep(sleepTime);”);
out.newLine();
out.write(“driver.findElement(By.xpath(“+xpathdet+“)).clear();”);
out.newLine(); out.write(“driver.findElement(By.xpath(“+xpathdet+“)).sendKeys(inputdata);”);
out.newLine();
out.write(“}”);
out.newLine();
out.write(“}”);
out.newLine();
    }
}

Generated Code:
WebDriver driver;
GenericFunctions generic;
public int sleepTime=4000;

public voidFill_Keywords_Txt(String inputdata){
    if(inputdata.trim().length()==0)return;
    try{
        driver.findElement(By.xpath(Keywords_Txt)).clear();
        driver.findElement(By.xpath(Keywords_Txt)).sendKeys(inputdata);
    }catch(Exception e){
        generic.GoToSleep(sleepTime);
        driver.findElement(By.xpath(Keywords_Txt)).clear();
        driver.findElement(By.xpath(Keywords_Txt)).sendKeys(inputdata);
    }
}
public voidClear_Keywords_Txt(){
    try{
        driver.findElement(By.xpath(Keywords_Txt)).clear();
    }catch(Exception e){
        generic.GoToSleep(sleepTime);
        driver.findElement(By.xpath(Keywords_Txt)).clear();
    }
}
publicString GetText_Keywords_Txt(){
    try{
        returndriver.findElement(By.xpath(Keywords_Txt)).getAttribute(“value”);
    }catch(Exception e){
        generic.GoToSleep(sleepTime);
        returndriver.findElement(By.xpath(Keywords_Txt)).getAttribute(“value”);
    }
}


public voidFill_Location_Txt(String inputdata){
    if(inputdata.trim().length()==0)return;
    try{
        driver.findElement(By.xpath(Location_Txt)).clear();
        driver.findElement(By.xpath(Location_Txt)).sendKeys(inputdata);
    }catch(Exception e){
        generic.GoToSleep(sleepTime);
        driver.findElement(By.xpath(Location_Txt)).clear();
        driver.findElement(By.xpath(Location_Txt)).sendKeys(inputdata);
    }
}

public voidClear_Location_Txt(){
    try{
        driver.findElement(By.xpath(Location_Txt)).clear();
    }catch(Exception e){
        generic.GoToSleep(sleepTime);
        driver.findElement(By.xpath(Location_Txt)).clear();
    }
}
public voidClick_Location_Txt(){
    try{
        driver.findElement(By.xpath(Location_Txt)).click();
    }catch(Exception e){
        generic.GoToSleep(sleepTime);
        driver.findElement(By.xpath(Location_Txt)).click();
    }
}
publicString GetText_Location_Txt(){
    try{
        returndriver.findElement(By.xpath(Location_Txt)).getAttribute(“value”);
    }catch(Exception e){
        generic.GoToSleep(sleepTime);
        returndriver.findElement(By.xpath(Location_Txt)).getAttribute(“value”);
    }
}
publicvoidSelect_Experience_DD(String inputdata){
    if(inputdata.trim().length()==0)return;
    generic.Click(Experience_DD);
    generic.GoToSleep(2000);
    generic.Click(“//div[@id=’exp_dd’]//ul//li[text()='”+inputdata+“‘]”);
}
publicvoidDeSelect_Experience_DD(String inputdata){
    if(inputdata.trim().length()==0)return;
    try{
        newSelect (driver.findElement(By.xpath(Experience_DD))).deselectByVisibleText(inputdata);
    }catch(Exception e){
        generic.GoToSleep(sleepTime);
        newSelect (driver.findElement(By.xpath(Experience_DD))).deselectByVisibleText(inputdata);
    }
}

publicvoidSelect_Salary_DD(String inputdata){
    if(inputdata.trim().length()==0)return;
    generic.Click(Salary_DD);
    generic.GoToSleep(2000);
    generic.Click(“//div[@id=’salary_dd’]//ul//li[text()='”+inputdata+“‘]”);
}
publicvoidDeSelect_Salary_DD(String inputdata){
    if(inputdata.trim().length()==0)return;
    try{
        newSelect (driver.findElement(By.xpath(Salary_DD))).deselectByVisibleText(inputdata);
    }catch(Exception e){
        generic.GoToSleep(sleepTime);
        newSelect (driver.findElement(By.xpath(Salary_DD))).deselectByVisibleText(inputdata);
    }
}

publicvoidClick_Search_Btn(){
    try{
        driver.findElement(By.xpath(Search_Btn)).click();
    }catch(Exception e){
        generic.GoToSleep(sleepTime);
        driver.findElement(By.xpath(Search_Btn)).click();
    }
}
Viola, we have reduced the effort from 4.5 hours to 2-4 minutes!! 
We have open sourced this project and same can be available  from SeleniumCodeGenerator

9 thoughts on “Selenium Page Object Code Generator

  1. Hi,
    I tried to use this too and i see all the loctors it created are css based. Is there a way to get this tool create locators using name or Link_Name or ID etc.
    Thanks
    Vams

  2. Hi Vams,

    Here we are using xpath locator(not css), if you want to use other locators like id, name etc., please follow

    1. Use ‘By’ to locate elements as shown below

    By username_Txt =By.id(“username”);
    By password_Txt =By.name(“password”);
    By login_Btn =By.id(“loginbtn”);

    2. Customize the above page object code generator so that it will support ‘By’ instead of xpath

    Hope this will help you!!

    Regards
    Omkar Kesa

  3. Here’s from my own code:
    Window.setTimeout executes just when a browser is idle.
    Therefore contacting the operate recursively (42 occasions) may just take 100ms if there’s no task in the browser and much more if the browser is busy performing something else.

Comments are closed.