Test automation of web interfaces is very popular now. It's really convenient - to check application "like user do". To create such tests for web part of our applications engineers mostly used selenium. About this product we want to talk in current article. Of cource, you can find  a lot of material about selenium in internet. In our article we will try to describe it in simple and clear way, that it could be understandable to anyone.

 

 What is  selenium?

If you say that selenium - a library or framework - this definition is not complete. Selenium - it is a set of tools for automation testing of web applications. Many peoples, who writes tests this cool product, dealing with some API. From this they may think that selenium is just a library. For real - API is just a part of an iceberg.

Before talking about the components of selenium, first we want to describe, what versions of product you could meet and use in your tests:

  • Selenium IDE - firefox browser plugin, based on record and play mechanism. User could record his actions on the page(like buttons clicks or input of values) and then 'play' this scenarious automatically. The main disadvantage of this product is that scenarios is very hard to support and modify. Also it has some problems with 'hard' scenarios(for example - interaction with popups). As a plus - this product is very easy to use and do not require any skills in code writing.
  • Selenium RC (or Selenium Server) - more advansed version, which includes server that recieved requests from code and then communicate with briwser. Now this part is obsolete and no longer supported.
  • Selenium WebDriver - the current major version of the product. Its main difference from the Selenium RC is that there is no single server - now it is built into the browser as a plugin.

Two last versions - it is versions with programm API, which is used in code. Now, there are many implementations of selenium libs for many programm languages. In our article we'll talk about Java.

So, what is selenium?

In current version - it is a set of the following components:

  • Browser with preconfigured plugin, which recieves requests and performs actions with web elements.
  • API, used from tests code. This api send requests to plugin.

Next, we would like to talk about API and describe, how to write tests with selenium. Of cource, with examples.

Beginning.

So, in order to start using Selenium WebDriver API - you need to connect it to your project.

There are several ways how to do it:

  • create project with our cool plugin
  • if you use maven - add dependency ,which you could find in maven repository central(this is enough for tests createion) to your pom.xml
  • downolad jar file with selenium and connect it to your project.

Now, let's try to create simple test that will perform the following steps:

  1. go to  http://youtube.com
  2. input 'selenium' in search string  
  3. press 'Find' button
  4. check, that there are at least 2 videos in results

We'll do this in 2 ways : in first we'll interact with WebDriver API directly from tests, in second - we'll use PageObject pattern.

Let's start from the very beggining and try to understand, how to start browser and open some url?

 

Browser start.

Selenium developers thought about automation test engineers life and tried to make the process of browser launching as easy as in possible.

To start browser you need to create an instance of the class, whos implement WebDriver intefrace. API includes a number of predefined implementations for different browsers, for example: FirefoxDriverChromeDriver and so on for many other browsers. There is also  exist one more class - RemoteWebDriver, which is used in cases where you need remote driver start and also when you use Selenium Grid.

When you create an instance, you could pass an instance of DesiredCapabilities class as parameter in constructor. Through this parameter you could configure the profile of your browser for tests(here you could find some features of capabilities). Also, DesiredCapabilities class has several static methods, which returns preconfigured profiles for given browser, for example : DesiredCapabilites.firefox() or DesiredCapabilites.chrome().

Driver object creation for Firefox will looks like:

WebDriver driver = new FirefoxDriver(DesiredCapabilities.firefox());

Afrer it's execution - browser will start.

Also we would like to tell, how to do the opposite action - browser closing. You must remember one common rule : always, in any case(positive test finish, error, exception) close browser after your tests were finished.

For closing browser, driver has quit() method, so your code will be like this:

driver.quit();

Now we know, how to do 2 operations - open and close browser.  Already quite a lot. But let's go further.

Page opening.

What we usually do after opening browser? We insert desired address into search string and press "Go" button. Now, let's try to do this operation with WebDriver API.

The answer is elementary - call get(String url) method of the driver object and pass your address to url parameter.

In our test code will look something like this :

driver.get("http://www.youtube.com");

After this page will be opened.

What next in our test? We need to input 'selenium' in search string element on the page. For this we must do the following actions - find element and enter a value.

Element search.

For selenium - every element on the page is and object of WebElement type. Element - it is any DOM object, easier - every element of page html code.  

In order to find desired element, you need to call findElement(By by) method of driver object and pass By class instance as parameter. Let's stop here and discuss it in more details. By object - it is description of the path to element. In WebDriver Api there are several ways, how you could describe this path:

  • By.cssSelector - by css selector of element. 
  • By.xpath - search by xpath
  • By.id - search by element id
  • By.className - search by class name
  • By.tagName - search by tag name

Each method has it's own class, extended from abstract class By. Objects of these classes could be taken by using static methods of By class. You'll see in futher examples how to use them.

Unfortunately, not all methods are applicable at all times. For example, id is not always exist for element. 

The most commonly used methods are xpath and css. To learn, how to create locators(element path) - we'll describe in future in one of our articles. Now we can advice you to look at this table, and after use our plugin, which could be a good friend and assistant in locators building.

Of cource, you must understand, that time of element search depends on optimality of your locator. Often, the difference is not so visible, but you should always think about it when you create your locator.

In our examples we'll use css. Let's look on element on the page and write code, that will find search string element on the page and then save it as a value of variable. We are lucky and our desired element has id, so our lokator will looks like '#mastergead-search-term'. As a result, our code will be the following:

WebElement searchStringElement = driver.findElement(By.cssSelector("#mastergead-search-term"));

There are several possible cases, when error could be thrown:

  • element not found on the page - NoSuchElementException
  • not valud locator(our plugin could help you not to do such mistakes) - InvalidSelectorException
  • some browsers errors often throw the WebDriverException. They may occured when , for example, in the case of unexpected closing the browser (yes, it happens, unfortunately)

Let's now look at the first error -  NoSuchElementException. This exception has interesting feature - befor it will be thrown, selenium will wait for element for some timeout. This timeout in configurable and named implicid wait - timout, during which selenium will wait for element appearance and after that, if element not found, an exception will be thrown. You could set it through driver object in following way:

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

where you will path count and time type(second,minute, hour and so on) as parameters to  implicitlyWait method.

If this timeout is set to 0 - there is a risk, that NoSuchElementException will become your friend.

Also  we would like to note that  findElement method also applicable for type WebElement objects. This operation is used when you need to find element within the element.

In addition, it is also possible to search for a list of elements by using findElements(By by) method of driver of element. This method will return you a list of html elements founded by your locator. Unlike findElement - this method will not throw you an exception, if no element was found. It will just return you empty list instead of this.

Ok, we found an element. Let's go on and set 'selenium' value to it.