Thursday, February 27, 2014

Identifying and working with element that changes dynamically

There several mechanism supported by Selenium to identify the element/object on the browser and to perform some actions. There are times when identifying an element and working with it is a lot difficult. I am sharing one of the problem I faced during identifying an element that is dynamically change after each page load (each new request).

Problem

Web page loads unordered listing element with children listings that have dynamic IDs on each requests/page loads. If you identify an element and try work with selenium scripts the next time scripts run the ID would change and you'll receive dirty exception of NoSuchElementFound blah blah.

Summary outer HTML

This the HTML of the application I was trying to work with.

  •  
  • ......

    Note:
    ID and other selenium selector are not that help since every attribute is same the attributes that are different are dynamic.Therefore, you can not uniquely identify an element and work confidently with. 

    Inner HTML of the First Listing Element.

    This is the detailed HTML of the first listing element as shown above.

  • "listingItem">
  • g="0" cellpadding="0">
             PKR 850,000                       

    The value that need to be pick was PKR 850,000 (which is also changing but its position does not change)

    Solution

    Firepath CSS selector does the trick and help you evaluate your expression, by itself firepath/firebug can give the exact output as below.

    #listings li:first-child strong > span 
    #listings li:nth-child(2) strong > span 
    ...
    List goes on and on

    If the same action needs to be performed on each element this can be iterate by adding the loop as 

    for(int i = 4; i <11 div="" i="">
    System.out.println(driver.findElement(By.cssSelector("#listings li:nth-child("+i+") strong > span")).getText());
    }

    Configuring Selenium with Eclipse on Windows

    Automation is not just about recording and playback the scripts. Its actual value comes far more after you write robust reusable, repeatable and maintainable scripts. To do that you have to have the tool that support designing scripts for such purpose. Many automation tools come with scripts editor to write dynamic code that is repeatable and reusable.

    Since selenium is an opensource browser automation tool that is easily integrated in the FireFox browser to recording the application common scenarios and playing it back for verification. If you want to go further in test automation you will need a bit of liberty where you can design and develop dynamic scripts that can not be done easily with Selenium IDE.

    Required downloads


    Configuration


    • Run Eclipse (after download, unzip the folder no special installation).
    • Set you desired directory as Eclipse workspace (this where you want to save all your projects).
    • Click on File -> New -> Java Project or JPA Project.
    • Name your project, say 'Test' and click Finish
    • Right-Click on the newly created project and then click - > New -> Package
    • Name the package, say 'com' and click Finish.
    • Again right-click on the project name 'Test' and then Properties - > Java Build Path
    • Select the Library tab, if not already selected.
    • Click Add External JARs button
    • Access the path, where you downloaded it, of Selenium Java Client driver.
    • Select Zip/JARs and click Open button, all JARs would be added.
    • Click again Add External JARs button
    • Access the path, where you downloaded it, of Selenium Server Standalone.
    • Select Zip/JARs and click Open button, all JARs would be added.
    • Go to the Package 'com', right-click on it, New -> Class.
    • Name the class as 'MyTestCase'. Remember to keep it 'public' and check 'public static void main(String[] args)' and 'Inherited abstract methods'. Paste the code snippet in your Eclipse IDE.
    • Run the scripts
    Code Snippet

    package com;

    import java.util.concurrent.TimeUnit;

    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.By;
    import org.openqa.selenium.firefox.*;

    public class MyTestCase {

    /**
    * @param args
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    WebDriver driver = new FirefoxDriver();
    driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
    driver.get("https://www.google.com.pk");
    driver.findElement(By.id("gbqfq")).sendKeys("Software Quality Geeks");
    driver.findElement(By.id("gbqfq")).submit();
    driver.findElement(By.linkText("Software Quality Geeks")).click();
    //driver.quit(); //uncomment this line if you want to quit browser after test run.

    }

    }


    Other things to consider

    Eclipse and Java must be of same bit architecture. For example if you are using 32 bit Eclipse then use 32 bit Java and the same is true to for 64 bit. Otherwise it would be little cumbersome to configure the cross bits eclipse and Java if you're a beginner.