Tuesday, 28 January 2014

Working with different drivers like HtmlUnitDriver,Internet Explorer Driver,Firefox Driver


The existing drivers are the ChromeDriver, InternetExplorerDriver, FirefoxDriver, OperaDriver and HtmlUnitDriver. including their relative strengths and weaknesses There is also support for mobile testing via the AndroidDriver, OperaMobileDriver and IPhoneDriver
While working with selenium webdriver you have an option to choose from multiple webdrivers, such as HtmlUnitDriver, FirefoxDriver, InternetExplorerDriver, ChromeDriver and OperaDriver. Each one of them is a separate implementation of the WebDriver interface provided by Selenium.
The first major point to note is that there are two groups of driver implementations. One of those that invoke the actual browser installed on your system and the other that emulates the behavior of another browser. FirefoxDriver, InternetExplorerDriver, ChromeDriver and OperaDriver invoke the actual browser installed on the machine; however the HtmlUnitDriver emulates other browsers JS behavior.
This is currently the fastest and most lightweight implementation of WebDriver. As the name suggests, this is based on HtmlUnit.
·         Fastest implementation of WebDriver
·         A pure Java solution and so it is platform independent.
·         Supports Javascript

 HtmlUnit is a java based framework for testing webApps basically a wrapper around ‘HttpClient’ by Jakarta. HtmlUnit provides UI-Less emulation of browsers to test web applications. The HtmlUnit APIs let you do the typical functions performed in an actual web browser, such as click links, fill forms, invoke web pages, submit values etc. HtmlUnit supports java script and complex AJAX libraries. Javascript is disabled in the HtmlUnitDriver by default, however if it can be enabled if required. The mechanism to enable javascript with the HtmlUnitDriver is as follows:

HtmlUnitDriver MyhtmlDriver = new HtmlUnitDriver();
 MyhtmlDriver.setJavascriptEnabled(true);
OR
HtmlUnitDriver MyhtmlDriver = new HtmlUnitDriver(true);

When enabled, the HtmlUnitDriver emulates the java script behavior of Internet Explorer by default. However we can direct the HtmlUnitDriver to emulate the JavaScript behavior of the browser of our choice by invoking the constructor that accepts the browser version. This can be done as follows:
HtmlUnitDriver MyhtmlDriver = new HtmlUnitDriver(BrowserVersion.Firefox_2);
The InternetExplorerDriver is a standalone server which implements WebDriver's wire protocol. This driver has been tested with IE 6, 7, 8 and 9 on appropriate combinations of XP, Vista and Windows 7.

The driver supports running 32-bit and 64-bit versions of the browser. The choice of how to determine which "bit-ness" to use in launching the browser depends on which version of the IEDriverServer.exe is launched. If the 32-bit version of IEDriverServer.exe is launched, the 32-bit version of IE will be launched. Similarly, if the 64-bit version of IEDriverServer.exe is launched, the 64-bit version of IE will be launched.
 The IE driver class ‘InternetExplorerDriver.class’ is located at ‘\org\openqa\selenium\ie\’ directory in the ‘selenium-server-standalone-2.7.0.jar’. To use the InternetExplorerDriver all you need to do is to have the selenium-server-standalone-2.7.0.jar in your CLASSPATH.  The IE driver runs only on windows and supports both 32-bit and 64-bit operations. Depending on the thread that instantiates the InternetExplorerDriver corresponding version of the IE is launched i.e. if the thread instantiating driver is running in 32-bit then the 32-bit version of the IE will be launched and if the thread instantiating driver is running in 64-bit then the 64-bit version of the IE will be launched.

The Internet Explorer driver uses the native or OS-level events to perform various functions on the browser, such as inputs from keyboard and mouse. This approach has both advantages and limitations both. The advantages are that it bypasses the limitations of the Javascript sandbox but there can be issues like the browser window under test might be out of focus.


‘selenium-server-standalone-X.X.X.jar’ contains all the drivers implementing the WebDriver interface of selenium. Hence the 'FirefoxDriver.class' can be found in the ‘\org\openqa\selenium\firefox directory in the selenium-server-standalone-X.X.X.jar. The driver when instantiated is added as an extension to the firefox profile. You can specify the profile with which you want to load firefox session. If no profile is specified then the driver creates an anonymous profile by default.
A profile can be created for the firefox driver as follows:

FirefoxProfile myProfile = new FirefoxProfile();

Multiple operations can be performed on the newly created profile, such as:

myProfile.addExtension(File);
myProfile.clean();
myProfile.getPort();
myProfile.setPort(int port);
myProfile.enableNativeEvents();
myProfile.setPreference(String key, String value); etc...

After creating the your profile you can pass the profile while creating the driver instance as follows:
WebDriver myFireFoxDriver = new FirefoxDriver(myProfile);

This driver is faster than the InternetExplorerDriver and executes the test in real Firefox web browser.

Monday, 27 January 2014

Identifying the elements in webdriver using id,Name,DOM,CSS


Typesof Locators
Locators have changed with Selenium 2 with the WebDriver API. Out of the box WebDriver supports several ways to locate elements on the page using the By abstract class.

ids are the preferred way to locate elements on a page for 2 main reasons:
According to w3c ids are supposed to be unique on an html page. This makes ids a very explicit and reliable way to locate elements on the page.
Also, all browsers also have highly efficient methods to get an object on the page using their ids. This makes id locators the fastest type of locator in Selenium.
Let us now look at how to use id locators using this html code as an example:

<form name="loginForm">
    Login Username: <input id="username" name="login" type="text" />
    Password: <input id="password" name="password" type="password" />
    <input name="login" type="submit" value="Login" />
</form>
In the above code, the username and password text fields are can be set using their ids. The locators for them would be

driver.findElement(By.id(username));

Even though this is a great locator, it is not realistic for all elements on a page to have ids. The developers add ids to key elements on the page to better control the look and feel or provide the dynamic user interaction. However, ids should also be added to elements that are frequently interacted within tests … to make the pages more testable. Automated test script authors should consider adding, or requesting addition of, ids to these key elements on the page.

In some cases, the ids on an element cannot be reliably used in a test. For instance, if you are displaying objects stored in the database, the objects ids could contain the database id in it.

Generally ids are added to elements when they want to be referenced from css or javascript and names are added to form fields. When referencing element from javascript either can be used. From a test automation standpoint, whenever id is not available/ usable, you should try to use the name instead.
Using the same example above, the way you would find the submit button would be:

driver.findElement(By.name("login"));

There is one big difference between the id and name attributes though … name attributes don’t have to be unique in a page. If there are multiple elements with the same name, then the first element in the page is selected. So, in this example, if another button or form named “login” was present of added later, it could cause the test to fail.

This locator identifies links by the text in them. Let us look at an example:

<html>
 <body>
    ...
    <a href="signin.html">Sign In</a> to modify your account details.
    ...
</body>
</html>
To click this hyperlink using the anchor tag’s text, you can use the By.linkText() locator:

driver.findElement(By.linkText("Sign In"));

If there are multiple elements with text “Sign In”, the first one is selected.

Btw, this is called linkText because it is used for hyperlinks. In Selenium if you used the link=textPattern locator, you could use it to locate other elements like div, span, td etc. In WebDriver, this locator works only for links.

Another common case is when we need to find links by a portion of the text it contains. In such cases you can find it by specifying the partial text. For example:

driver.findElement(By.partialLinkText("Sign"));

XPath is a very powerful language to express which element to identify. If you use it correctly, it can produce very reliable and low maintenance locators, but if you use it incorrectly, it can create very brittle test cases.


As you can guess, some of these expressions will not be as reliable as others. Of these //table/tr[2]/td/input is the worst because it would break even with slightest modification to the page structure. It can take some time to learn XPath if you aren’t familiar with it, but it is worth the time if you plan to spend a lot of time writing UI automated tests. In any case do not rely on tools, including selenium IDE, to generate the right xpath expression for you. They can help you get started but they are usually bad at identifying the more reliable XPaths.

There are some special cases you should be aware of when you work with XPath, like when you are trying to interact with SVG. Like in the example here, the html looks something like this:

<div id="svgchart">
  ...
    <svg xmlns="http://www.w3.org/2000/svg">
        <g>
            <path .../>
        </g>
        ...
    </svg>
  ...
</div>
Here, if you use XPath like:

//svg

you will get ERROR org.openqa.selenium.NoSuchElementException: Unable to locate element. This is because the svg element is in a different namespace. You will have to specify your xpath with the namespace uri like this instead:

//*[local-name()='svg' and namespace-uri()='http://www.w3.org/2000/svg']

So, if XPath’s are so versatile, why doesn’t everyone prefer these? It’s because they are often the slowest, especially in older versions of IE! There are some ways you can make XPath’s faster, but they still are a few times slower than ids or names.

css locators can be used to identify a large number of elements on a page.
</table>
In this case the css locator variations possible for the highlighted input field are:


input.required
input[class~='required']
input.required[type='text']
#item2_quantity
input#item2_quantity

The css locator may not be as expressive as XPath, but it generally executes faster.

This is more of a convinience mechanism to identify elements. In the css example above, instead of using

driver.findElements(By.css("input[class~='required']"));

you could use

driver.findElements(By.class("required"));

DOM stands for Document Object Model. DOM is convention for representing objects in HTML documents.

<form id="loginForm">
    Login Username: <input id="username" name="username" type="text" />
    Password: <input name="password" type="password" />
    <input name="login" type="submit" value="Log in" />
</form>
In this page, the dom expression for the highlighted input field would be:


document.forms[0].elements[0]
document.forms['loginForm'].elements['username']
document.forms['loginForm'].username
document.getElementById('username')

For those who have used Selenium 1 API, you would expect to find a By.dom() equivalent api, but it doesn’t exist. However, you still can get a handle to these elements using dom expressions by using the following code snippet instead:

    driver.findElement(byDom("document.forms[0].elements[0]"));
public By byDom(String domExpression) {
    final Object o = ((JavascriptExecutor) driver).executeScript("return " + domExpression + ";");
    if (o instanceof WebElement) {
        return new By() {
            @Override
            public List<WebElement> findElements(SearchContext searchContext) {
                return new ArrayList<WebElement>() {
                    {
                        add((WebElement) o);
                    }
                };
            }
        };
    }
}
The three key aspects of this code that you should note,

The driver can be casted to JavaScript Executor and other interfaces which will provide additional capabilities.
execute Script() in JavaScript Executor returns an object which can be casted to a WebElement if the JavaScript expression returns a dom element.
You can create your own implementation of By
Some things to note for Selenium 1 users
You will notice that Implicit locators are not supported in WebDriver.
When using name in Selenium 1, you could add other attributes in the expressions to filter the results. For example name=login type=text was valid. You cannot do that any more with the By.name() call.
findElement() and findElements()
As you might have noticed in the examples above, the By locators were used within findElement and findElements methods. The purpose of these methods is to return a WebElement, in case of findElement, and a list of WebElements in the case of findElements.

The WebElement represents an html element on the page. In the next section you will see that it is this WebElement object that you would interact with or read attributes of for validations etc.

When you use these methods on the WebDriver object, the scope within with the elements are located is the entire page.


The WebElement interface also has findElement() and findElements() methods. In this case, it is within the scope of this parent element that child elements are located. This is useful when you want to narrow the scope to find several elements that you would interact with. In most cases, narrowing the scope improves the execution times for locating the elements.

Wednesday, 22 January 2014

Object Identification in Selenium IDE

For most applications, easily use the built in Selenium IDE in Firefox
In Firefox, click on Tools>Selenium IDE.
Make sure the red record button is in the “Now recording..” mode.
Notice how the Selenium IDE automatically recognizes what information (id-tools) to use to identify the Select tool dropdown.
Click on the select command to highlight it, then click the “FIND’” button.
we will understand how Selenium identifies the objects on the Application Under Test.
Every page is HTML. While recording, when we click on some element, IDE selects a particular property of that element that is unique in that page. Hence it is able to perform the operations

To identify the objects such as Links, Buttons, Edit boxes, Drop downs, etc on the application Selenium uses a concept called “Locators”.  There are around 8 different types of locators.  Out of them, I will be explaining only four as they are widely used while automating the test cases using Selenium.


Every Web Page will be having some HTML Source code.  This can be viewed using “View –> Page Source / View source” on the browser. In the following picture we can see “id” attribute of a HTML tag is used as a locator to identify an object.


ü  Login to sample application
ü  Click on Accounts tab
ü  Click on Create Account link
ü  Now Create Account Page gets displayed
ü  Selenium IDE has recorded all these steps
3)  xpath = xpathExpression.  Xpath is used as a Locator to identify an object.  This is an expression which is formed by combining various HTML tags
4)   link=link text (in HTML source we can located this using “href” tag)

Monday, 20 January 2014

Selenium History

Selenium is a portable software testing framework for web Applications. Selenium provides a record/playback tool for authoring tests without learning a test scripting language (Selenium IDE). It also provides a test domain specific language(Selenese)  to write tests in a number of popular programming languages, including Java,c#,Groovy, Perl,PHP,Python and Ruby. The tests can then be run against most modern webbrowsers. Selenium deploys onWindows, Linux, and MAcintosh platforms.
History
Selenium was originally developed by Jason Huggins in 2004, who was later joined by other programmers and testers at Thoughtworks. It is open source software, released under the Apache2.0 Licence, and can be downloaded and used without charge.
The name comes from a joke made by Huggins in an email, mocking a competitor named Mercury saying that you can cure mercury poisoning by taking Selenium supplements. The others that received the email took the name and ran with it.
The latest side project is Selenium Grid, which provides a hub allowing the running of multiple Selenium tests concurrently on any number of local or remote systems, thus minimizing test execution time.
Selenium components


Selenium IDE is a complete integrated development environment (IDE) for Selenium tests. It is implemented as a Firefox Extension, and allows recording, editing, and debugging tests. It was previously known as Selenium Recorder. Selenium-IDE was originally created by Shinya Kasatani and donated to the Selenium project in 2006.
Scripts may be automatically recorded and edited manually providing autocompletion support and the ability to move commands around quickly.
Scripts are recorded in Selenese, a special test scripting language for Selenium. Selenese provides commands for performing actions in a browser (click a link, select an option), and for retrieving data from the resulting pages.
Features:
·         Easy record and playback
·         Intelligent field selection will use IDs, names, or Xpath as needed
·         Autocomplete for all common Selenium commands
·         Walkthrough tests
·         Debug and set breakpoints
·         Save tests as Selenese, Ruby scripts, or other formats
·         Support for Selenium user-extensions.js file
·         Option to automatically assert the title of every page
·         Easy customization through plugins


As an alternative to writing tests in Selenese, tests can also be written in various programming languages. These tests then communicate with Selenium by calling methods in the Selenium Client API. Selenium currently provides client APIs for Java, C#, Ruby and Python.
With Selenium 2, a new Client API was introduced (with WebDriver as its central component). However, the old API (using class Selenium) is still supported.


Selenium Remote Control (RC) is a server, written in Java. that accepts commands for the browser via HTTP.RC makes it possible to write automated tests for a web application in any programming language, which allows for better integration of Selenium in existing unit test frameworks. To make writing tests easier, Selenium project currently provides client drivers for PHP,Python ,Ruby, Java. The Java driver can also be used with JavaScript.A new instance of selenium RC server is needed to launch html test case - which means that the port should be different for each parallel run.However for Java/PHP test case only one Selenium RC instance needs to be running continuously.
Selenium Remote Control was a refactoring of Driven Selenium or Selenium B designed by Paul Hammant, credited with Jason as co-creator of Selenium. The original version directly launched a process for the browser in question, from the test language of Java, .Net, Python or Ruby. The wire protocol (confusingly called 'Selenese' in its day) was reimplemented in each language port. After the refactor by Dan Fabulich, and Nelson Sproul (with help from Pat Lightbody) there was an intermediate daemon process between the driving test script, and the browser. The benefits included the ability to drive remote browsers, and the reduced need to port every line of code to an increasingly growing set of languages. Selenium Remote Control completely took over from the Driven Selenium code-line in 2006. The browser pattern for 'Driven'/'B' and 'RC' was response/request, which subsequently became known as Comet.
With the release of Selenium 2, Selenium RC has been officially deprecated in favor of Selenium WebDriver.


Selenium WebDriver is the successor to Selenium RC. Selenium WebDriver accepts commands (sent in Selenese, or via a Client API) and sends them to a browser. This is implemented through a browser-specific browser driver, which sends commands to a browser, and retrieves results. Most browser drivers actually launch and access a browser application (such as Firefox or Internet Explorer); there is also a HtmlUnit browser driver, which simulates a browser using HtmlUnit.
Unlike in Selenium 1, where the Selenium RC server was necessary to run tests, Selenium WebDriver does not need a special server to execute tests. Instead, the WebDriver directly starts a browser instance and controls it. However, Selenium Grid can be used with WebDriver to execute tests on remote systems (see below).
As of early 2012, Simon Stewart (inventor of WebDriver), who was then with Google and now with Facebook, and David Burns of Mozilla were negotiating with the W3C to make WebDriver an internet standard. In early 2013, the working draft was released. As such, Selenium-Webdriver (Selenium 2.0) aims to be the reference implementation of the WebDriver standard in various programming languages. Currently Selenium-WebDriver is fully implemented and supported in Python, Ruby, Java, and C#.
In practice, this means that the Selenium 2.0 API has significantly fewer calls than does the Selenium 1.0 API. Where Selenium 1.0 attempted to provide a rich interface for many different browser operations, Selenium 2.0 aims to provide a basic set of building blocks from which developers can create their own Dpmain specific language. One such DSL already exists: the Watir project in the Ruby language has a rich history of good design. Watir-webdriver implements the Watir API as a wrapper for Selenium-Webdriver in Ruby. Watir-webdriver is created entirely automatically, based on the WebDriver specification and the HTML specification.


Selenium Grid is a server that allows tests to use web browser instances running on remote machines. With Selenium Grid, one server acts as the hub. Tests contact the hub to obtain access to browser instances. The hub has a list of servers that provide access to browser instances (WebDriver nodes), and lets tests use these instances. Selenium Grid allows to run tests in parallel on multiple machines, and to manage different browser versions and browser configurations centrally (instead of in each individual test).