Showing posts with label Selenium-2. Show all posts
Showing posts with label Selenium-2. Show all posts

Friday, February 13, 2015

The Undocumented documentation of Page Object Pattern

If you are into automation testing using selenium, you may be knowing about the Page Object Pattern suggested by selenium forum available at url :
https://code.google.com/p/selenium/wiki/PageObjects

The documentation suggests the approach for implementing Page Object Pattern for automation and what are the advantages of it. In here I wont be writing about what the documentation suggests and talks about it. So lets directly jump onto the main subject and learn about what the documentation does not contain. Following are those points:
  • Implementing a Page Object Pattern for a single page application
  • Approach towards defining methods for functionality

Implementing Page Object Pattern for a single page application


With new web application development technologies coming into play on a daily basis web applications has reduced to very few pages and even sometimes to one page url. This becomes a challenge while implementing Page Object Pattern. The question arises is, how to segregate the pages as there are only few pages in the application but there are lot of functionalities to cover in them. If we go ahead with the conventional segregation methodologies we will have very few page classes but with lot of functional methods defined in them. We will fall into the same problem of code management that we were trying to solve using Page Object Pattern.

The solution to this is to enhance the Page Object Pattern guidelines. This includes segregating your page classes based on features, sub-features, functionality etc. and not by page urls. To explain this we have a perfect example of Gmail. Gmail is a single page but there are lot of functionalities available in the said page like navigation, hangouts, inbox, Search, compose and mail folders.
If we go with the conventional method we will be forced to define all the functionalities of compose, hangouts contacts chat, inbox etc in a single class. With the enhanced model we will define separate classes for each of the feature ex. ComposePage, HangoutPage, InboxPage, NavigationPage etc. By using the enhanced model we can fully utilize the advantages of using the Page Object Pattern.

Defining methods for Page functionality


The guideline suggests users to define functionalities as method inside page classes and it ends there. It does not talk much about the segregation,  approach or anything of such sort. Anyways lets cover it here. When planning to define methods for the functionality try to follow following added guidelines:
  • Segregate your functionality into smaller functionally executed methods. Lets take an example of login use case where user enters username, password and click on submit button. While writing a functional method for login you should think of having methods like enter username, enter password and clicking on submit button. This way you will have more control on the code and you can provide more utilities to user who is writing automation tests.
  • Think of functional as well as structural method declarations. Taking the above example. login method that accepts username and password arguments is a functional method whereas enter username, enter password and click on submit button methods are structural methods. As said in the first point structural methods makes code more readable and represents a flow of user actions. It also provide more power into the hands of end user who is using them for writing automation tests.
  • Think of positive and negative scenarios of a functionality while defining methods. I will again take the example of the login functionality. A login can be successful or it can be failure. try to support both kind of scenarios in a single method. This can be achieved in two ways:
    • Allow a Boolean value to be passed as argument to the method that will decide whether the scenario for which the method is being used in positive or negative.
    • Another way is you written a Boolean or some other object as return type representing whether the method execution was success or a failure.
    This way you are covering more ground in the functional methods and giving more power to the user writing automation tests to write different types of tests scenarios with the same given method.

The above suggestion helps in making tests more readable, manageable and in providing more functionality to the user who is automating. The initial time taken to write page class and page methods will be more but there will be very less time spent on writing automation test cases for the said functionality as the methods list will contain methods that supports all kind of related functionality from low level to high level as well as both positive and negative scenarios.

This is a cross post from my company blog here, where I had originally written it.

Monday, February 9, 2015

Selenium Exceptions why it occurs and how to resolve/avoid them

While using selenium for web automation many a time we face numerous kind of exceptions. Many of these exceptions are mainly selenium exceptions. In this blog I will write about few of those selenium exceptions, why they occur and how to resolve/avoid them.

  • StaleElementReferenceException - 
    As the name suggests this exception occurs when the element stale, which means the element reference on which you are trying to take a action upon is no longer available on the page or has changed. 
    To avoid this exception, try to find the element as and when you need to take an action upon it rather than getting the element at some point of code and then reusing it at different places.

  • InvalidCoordinatesException - 
    This exception occurs when invalid co-ordinates are provided for an interaction operation like move, click, drag & drop etc.
    You can avoid this exception by identifying a Webelement on the page for interaction rather than providing a co-ordinates.

  • ElementNotVisibleException - 
    This exception occurs when an element may be available in the dom but not displayed on the page and hence not able to be interacted. This exception may also occurs if the element is unable to scroll onto the browser view.
    You can avoid this exception by verifying that the element is visible and then taking action on the element. There are some methods present in "ExpectedConditions" class that can be used to wait for the element to be visible. These methods are "visibilityOf(Webelement)" and "visibilityOfElementLocated(By)".

  • InvalidSelectorException -
    This exception is thrown when the selector used to find the element is invalid or wrong, this may be a syntax error or a compound class name to be provided to "By.className" method.
    To avoid this exception verify that the selector that you are using are verified on the said page using jQuery or firebug or firepath.

  • NoSuchElementException -
    This is a common exception faced by selenium users and occurs when there is no element found on the current page by selenium based on the user provided selector to method "findElement". There can be multiple reasons for this exception to occur like selector being wrong, element taking time load(in case of ajax), earlier step execution failed etc.
    You can avoid this exception by implementation by waiting for element to be present using "FluentWait" with "ExpectedConditions" class methods "presenceOfElementLocated(By)" and "visibilityOfElementLocated(By)".

  • UnreachableBrowserException -
    This exception mainly occurs due to two reasons first when the browser to which the selenium commands has died mid-test and second when the remote server address to which the RemoteWebDriver trying to contact is invalid.
    There is no proper solution to this error you can only take precautionary measures in this cases and is more or less related to hardware.

Tuesday, October 25, 2011

Selenium Grid with WebDriver

I had earlier covered in my blog on how to execute your RC cases in selenium grid. But with the commencement of Selenium-2/Webdriver, grid setup has been changed. In the following blog I will cover how to set-up your grid and the changes that will be required for easy execution of cases.


Following things are required:
1. Selenium 2.xx version server jar and Java library. The latest one can be downloaded from the link: Selenium-2
2. Java 1.6 and above
3. TestNg jar . You can download it from the link: TestNG
4. Eclipse with TestNG plugin installed(optional)
5. ChromeDriver. Can be downloaded from: ChromeDriver


The Test Code
Following is an example of test-class that have a test case to search google for "testing" and verifying after clicking it on a link.

In the above class I am using the TestNG "Parameter" property to provide different data set to the "BeforeClass" method "beforeClass". The beforeClass method accepts two properties "browser" and a "port".
These values are used for initialization of driver and in-turn for initialization of selenium object. In the above code I am using the "WebDriverBackedSelenium" class for creation of the selenium object, so that its easy for guys who had worked on Selenium-1 to understand the code. If you want the code to be purely WebDriver, you can directly use the "driver" object for defining your test-cases.
The main part in this test case is how the driver object is being created:
DesiredCapabilities capability= new DesiredCapabilities();
capability.setBrowserName(browser);
WebDriver driver= new RemoteWebDriver(new URL("http://localhost:".concat(port).concat("/wd/hub")), capability);
The above code creates an object of DesiredCapability and then set the browser value to it. Now using this "capability" object I am creating the webdriver object using the "RemoteWebDriver" class. This tells the selenium on which browser the test-case needs to run and where the server is located. In this example I am assuming the server to be running locally. In case it is on different system the "localhost" needs to be re-placed with the ip of the said system.

TestNG configuration
For parallel execution you need to use the TestNG configuration. Following is an "testng.xml" file for the above said test class. The said configuration executes the test-cases across different browser.


<suite name="Selenium TestNG Suite" parallel="tests"
    thread-count="5">

    <test name="Selenium TestNG - 1">
        <parameter name="browser" value="firefox" />
        <parameter name="port" value="4444" />
        <classes>
            <class name="com.test.testng.Google" />
        </classes>
    </test>
    <test name="Selenium TestNG - 2">
        <parameter name="browser" value="chrome" />
        <parameter name="port" value="4444" />
        <classes>
            <class name="com.test.testng.Google" />
        </classes>
    </test>

</suite>


In the above configuration, I am configuring TestNG to run "tests" in parallel. Also there are two different tests inside a suite. For each test a different "browser" parameter value has been configured.

Selenium-Grid server
Now start your grid using the following commands. Run each command in a seperate terminal or command prompt by going to the directory containing your selenium-server-standalone-2.x.x.jar. In the following example I am using the 2.7.0 version of selenium.

For Hub:

java -jar selenium-server-standalone-2.7.0.jar -role hub


For a firefox based node:

java -jar selenium-server-standalone-2.7.0.jar -role webdriver -hub http://localhost:4444/grid/register -port 5556 -browser browserName=firefox


For google-chrome based node:

java -Dwebdriver.chrome.driver=/path/to/chromedriver -jar selenium-server-standalone-2.7.0.jar -role webdriver -hub http://localhost:4444/grid/register -port 5555 -browser browserName=chrome

Before running  the above command  you need to provide the chrome-driver path to the property "-Dwebdriver.chrome.driver".

Now run your testng.xml from eclipse by selecting it -> Right click -> Run as -> TestNG suite(this will work only if you have TestNG plugin installed in your eclipse.)
Or you can choose other ways to execute "testng.xml" like from command prompt, using ant or maven.
Once you run the above testng.xml. TestNG will execute the cases from the Google class on grid across different browsers firefox and google-chrome as configured.


You can do configurations for environment like OS (Linux,Windows), browser, browser-version and all and then you can run you cases on particular type of environment by configuring them accordingly. More details can be found at the following URL:
http://code.google.com/p/selenium/wiki/Grid2

Tuesday, October 4, 2011

Running tests on Google Chrome using Webdriver

While automating your web-application using webdriver, many may have faced problems in executing your cases on Google-chrome. Whenever you try to use webdriver object for executing your cases on chrome using the following code:

DesiredCapabilities capability = DesiredCapabilities.chrome();

you most probably get the following error:

The path to the chromedriver executable must be set by the webdriver.chrome.driver system property; for more information, see http://code.google.com/p/selenium/wiki/ChromeDriver. The latest version can be downloaded from http://code.google.com/p/chromium/downloads/list

The solution to this error that has been mentioned in the given URL  "http://code.google.com/p/selenium/wiki/ChromeDriver" is  to set the chromedriver path to the variable "webdriver.chrome.driver". But how exactly to set the path and use it for your test execution is not given there. So I though to just document it here on my blog.

For setting the  "webdriver.chrome.driver" value and for using google-chrome to execute your automated tests, you can use one of the following methods:


Method - 1:
Start the selenium server using the following command:
java -Dwebdriver.chrome.driver=/path/to/chromedriver  -jar selenium-server-standalone-2.7.0.jar

And in your Java code you use the chrome driver in the following way:

DesiredCapabilities capability = DesiredCapabilities.chrome();
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);


The advantage of using this method is that you can execute your test-cases in a remote machine and this is advantageous when you want to run it on grid.


Method - 2:
Set the system property  "webdriver.chrome.driver" using System.setProperty()  in your code and then try to execute your cases on Chrome.

System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
WebDriver driver = new ChromeDriver();

This method works well when your tests are getting execute on a local machine and you are not starting any selenium server.

Following are some important links for Chrome driver:
Webdriver Chromedriver page:
http://code.google.com/p/selenium/wiki/ChromeDriver


ChromeDriver download page for downloading the ChromeDriver server:
http://code.google.com/p/chromium/downloads/list

Friday, September 23, 2011

Automating a Native android app using Selenium and NativeDriver

As there are more and more development happening on the android front, automation of the developed applications has also become a necessity. Android within its API supports a testing framework which can be used for testing applications, but writing and developing cases using that API is not easy. We may need a framework that makes it easy to write and develop test cases for our applications.
One of such framework is "NativeDriver". It is built over the Selenium webdriver automation framework.
As you must be knowing that selenium is vastly used open-source functional automation tool. 
In this write-up I will tell you on how to automate an android application using NativeDriver
Following things are required before starting:
  • Android SDK 2.2 or later - download
  • Eclipse version 3.5 or later (Eclipse IDE for Java Developers recommended) - download
  • Android Development Toolkit (ADT) plug-in - Installing ADT
  • Ant - download
  • JDK 1.6 or later - download
Building the NativeDriver libraries:
  • Checkout the NativeDriver code:
  • svn checkout https://nativedriver.googlecode.com/svn/trunk nativedriver --username {Google account e-mail address}
  • Build the NativeDriver code:
  • $ cd nativedriver/android
    $ ant

The libraries are built and stored in the nativedriver/android/build directory:

  • server-standalone.jar - this should be linked to your Android application, and runs on the Android device (or emulator). This is the NativeDriver server, and listens for requests to automate the application, such as “start an activity” or “click a UI element”
  • client-standalone.jar - this should be linked to the test, which is the NativeDriver client. It implements a WebDriver API which communicates with the server.

Adding the NativeDriver jar to your application



  • Import your android application code into the eclipse by using the File -> Import functionality of eclipse.
  • Add the server-standalone.jar to the build-path of your android application by Right clicking on the Android application project -> Configure build path -> Add jars or Add external jars (browse to the server-standalone.jar file, select and add it).
  • To the application AndroidMainfest.xml file, add the following to the element.

 <instrumentation android:targetPackage="{app_package_name}"
   android:name="com.google.android.testing.nativedriver.server.ServerInstrumentation" />
   android:name="android.permission.INTERNET" />
   android:name="android.permission.WAKE_LOCK" />
   android:name="android.permission.DISABLE_KEYGUARD" />
           Here {app_package_name} needs to be replaced with the name of the package as specified in the mainfest element's package attribute.
  • Build the application and install it on the device.
  • Now go to the commandline and start the instrumentation using the following line:
adb shell am instrument {app_package_name}/com.google.android.testing.nativedriver.server.ServerInstrumentation
Here again the {app_package_name} needs to be replaced with the name of the package as specified in the mainfest element's package attribute.
  • Enable port forwarding by using the following command:
adb forward tcp:54129 tcp:54129

Writing your Test Cases
For writing your test cases you just have to create a new Java project and start writing code for it. I will explain this using a code example. The following code is done to automate an opensource K9 mail application on android:


Important Notes:-

  • As there is no recording feature available, we need to write the code manually for automating our scenarios. 
  • For identifying the element id to interact on the UI, you can get the ID's of the elements from the R.java file generated inside your android application code.
  • Also as we are writing our cases in Java code we can use our own test framework and generate html reports for out automation execution.


Note: Most of the material in this blog has been taken from the original site of the NativeDriver. The credit for such material goes to the original author.
Following is the link to it. http://code.google.com/p/nativedriver

Wednesday, August 17, 2011

Native android app automation – Nativedriver vs Robonium

Nowadays android is the latest thing in the market and many of the companies are working on android app development. With development comes the requirement to test an application too. As we all tester know that automation is one of the important part of testing, and is mainly used to reduce the time taken to execute the testcases. This gives time to testers to concentrate more on exploratory testing. Recently I was going through some group, and found out about some open-source frameworks that makes it possible to automate an Android native application. I went through two of such frameworks and will write about what I felt about them. The two frameworks I am going to talk about is Nativedriver and Robonium. 

Nativerdriver- Is an opensource framework written over Selenium-2.0 Webdriver implementation. As we all know that selenium is a great functional automation tool for web-applications and gives you a cross-browser and cross-platform supports. The support for testing native application has enhanced the value of selenium. Nativedriver can be used when you are actually working along with the development team and has access to the source code of the andorid application that needs to be tested. 

Robonium – Is also a great tool and is written by extending the Internal Android testing framework. This framwork supports a lot of functions which can be used to auotmate your application test. The main advantage of this framework is that , you can automate any application using this without actully having the source code of the app.

Advantages of Nativedriver: 
  • Built over the selenium webdriver hence can be easliy used by existing selenium users.
  • Test are run as a normal Java unit test. And hence other frameworks can also be used for test-case execution or reporting.
  • Ant or maven can also be used for execution of cases.
  • Fast execution and reporting of testing results
Disadvantages of Nativedriver:
  • Need access to the source code of the application that needs to be tested.
  • Sometime difficult to find element as support for finding elements by index is not available

Advantages of Robonium: 
  • Don't require the source code of the application for testing.
  • Elements are easy to identify and work on.
  • Tests are simple to write.
  • Setup is simple.
Disadvantages of Robonium
  • Can only be executed suing eclipse.
  • Slow execution.
  • Typing a normal text is not supported at this point.

Monday, August 8, 2011

Scrolling on pages using Selenium

Somebody recently asked me on how to scroll a page which is dynamically loaded. Something like the Facebook page where the updates gets loaded as you scroll down the page. As I never had such a requirement , I didn't knew a solution to it. 
While searching I found people suggesting the "selenium.focus" function to be used as a solution, but that does not solve the problem I am talking about.  The "selenium.focus" should be used when the element you are looking for gets loaded when the page gets loaded and not when you scroll through the page.
After lot of searching I was unable to get a proper answer to my problem and finally got an idea for implementing it. Its just a 4 to 5 lines of code that can be used in your code for scrolling on the page.
Following is the code:


The above code uses the JavaScript method "scrollBy" to scroll on the page. The for loop runs for 60 sec  and calls the scrollBy function every second. This makes the selenium to scroll on the page.
If you have a test where you need to scroll on the page and check whether an element is loaded dynamically or not you can put a isElementPresent like function after the "driver.executeScript" to check visibility of your element.
Following is a test method written in webdriver that you can use to test the above function on the Facebook page:


The following code is written for Selenium-1.0 users:

Thursday, July 28, 2011

isElementPresent in Selenium-2.0

While going through Selenium-2.0 I found out that WebDriver does not have a function called isElementPresent(). This was one of the important functions that was used in Selenium-1.0. It was mainly used for waiting for an element to be available to take an action on it. To implement this in WebDriver you just need to write a method as mentioned below. You can then  use this function with any type of "By"(By.id, BY.name, etc.)



The above function will return true in case the element is found on the page, else it will return false. 
In case your want to wait for a element to be present you can implement it in the following way.

Thursday, July 21, 2011

Getting the width and height of an Image using Selenium

People has kept asking me how to capture the width and height of an image/element using selenium. I tried to get an answer to it and the solution is very simple. The solution comes with Selenium itself.

Selenium-1 consists of certain functions for storing element values like getElementHeight, getElementWidth, getElementPositionLeft, getElementPositionRight, getElementPositionTop.

Similarly in Selenium-2(WebDriver) you can use the getSize() function which will return a "Dimension" class object. You can then use the getHeight() and getWidth() functions over it for getting the width and height of the element.


We can use these functions to get the position of the element and also its width and height.
Following is an example for getting the height and width of an image/element on the browser using Selenium-1.


height = selenium.getElementHeight("locaton to the image on the browser.(xpath or id)")
width = selenium.getElementWidth("location to the image on the browser.(xpath or id)")

Following is an example for getting the height and width of an image/element on the browser using Selenium-2(WebDriver).

height = driver.findElement("location to the image on the browser.(xpath or id)").getSize().getHeight();
width = driver.findElement("location to the image on the browser.(xpath or id)").getSize().getWidth()