Latest Event Updates

Automating a Native android app using Selenium and NativeDriver

Posted on Updated on

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< span=""> android:targetPackage="{app_package_name}"
   android:name="com.google.android.testing.nativedriver.server.ServerInstrumentation" />
  <uses-permission< span=""> android:name="android.permission.INTERNET" />
  <uses-permission< span=""> android:name="android.permission.WAKE_LOCK" />
  <uses-permission< span=""> 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:
package com.test;
import org.junit.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
 
import junit.framework.TestCase;
 
import com.google.android.testing.nativedriver.client.AndroidNativeDriver;
import com.google.android.testing.nativedriver.client.AndroidNativeDriverBuilder;
import com.google.android.testing.nativedriver.client.AndroidNativeElement;
import com.google.android.testing.nativedriver.common.AndroidKeys;
import com.google.android.testing.nativedriver.common.AndroidNativeBy;
 
public class K9NativeTesting {
 
    private AndroidNativeDriver driver; //Defining the driver object of AndroidNativeDriver
 
    @Before
    public void beforeTest() { // Before method that will get the driver object from getDriver()
        driver = getDriver();
    }
 
    @After
    public void afterTest() { //Runs after the test is run and shutdown the driver.
        driver.quit();
    }
 
     // Build/start the Android driver and returns it.
protected AndroidNativeDriver getDriver() {
        return new AndroidNativeDriverBuilder().withDefaultServer().build();
    }
     
      private void startK9Activity() {
            driver.startActivity("com.fsck.k9." +
                "activity.Accounts");
          }
     // starts the activity (application) mentioned. In this case it is com.fsck.k9
    //    also you can see the activity.Accounts this you can from the logs of adb logcat while starting the application
       
      @Test //Test method to configure a new mail account in K9
      public void tesK9(){
          startK9Activity();
          driver.findElement(AndroidNativeBy.text("Next")).click();
          driver.findElement(AndroidNativeBy.id("account_email")).sendKeys("test@test.com");
 
// Here I am using the By.Id("account_email") you can get the Ids of the UI elements from the R.java
// file genrated by the android api while building an application.
 
          WebElement ele=this.findAndClickElementById(driver, "account_password");
          ele.sendKeys("password");
          driver.findElement(AndroidNativeBy.text("Next")).click();
      }
       
      @Test /*Test method to compose a new mail in K9*/
      public void composeMail(){
          WebElement ele;
          startK9Activity();
          driver.getKeyboard().sendKeys(AndroidKeys.MENU);
          driver.findElement(AndroidNativeBy.text("Compose")).click();
          ele=this.findAndClickElementById(driver, "to");
          ele.sendKeys("send@test.com");
          ele=this.findAndClickElementById(driver, "subject");
          ele.sendKeys("Test Message");
          ele=this.findAndClickElementById(driver, "message_content");
          ele.sendKeys("This is a test message");
           
          driver.getKeyboard().sendKeys(AndroidKeys.MENU);
          driver.findElement(AndroidNativeBy.text("Send")).click();
           
      }
       
      public WebElement findAndClickElementById(AndroidNativeDriver tempDriver, String id){
          WebElement ele = tempDriver.findElementById(id);
          ele.click();
          return ele;
      }
 
}
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

Running tests on Google Chrome using Webdriver

Posted on Updated on

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&#8221; 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.

1
2
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

Selenium Grid

Posted on Updated on

Some content on this page was disabled on November 9, 2015 as a result of a DMCA takedown notice from Alex Nordeen. You can learn more about the DMCA here:

https://wordpress.com/support/copyright-and-the-dmca/

Selenium Installation Guide

Posted on Updated on

Environment Setup:

OS: Windows XP

We require following software to be installed on system.

1.)    Eclipse Indigo (3.7) with following plugins Installed:

1.)    EGIT (1.3.0)

2.)    Maven (0.12.0)

3.)    TestNG (6.3.2)

2.)    JDK 1.7

3.)    GIT Bash(1.7.0 )

 

Installation Instruction:

JDK:

1.)    Install JDK 1.7 on default location. (Make sure PATH  to JDK bin directory is configured after installation in Environment Variable).

To confirm proper working of JDK installation, open command prompt and type javac –verison. This should display current JDK version.

       Eclipse:

2.)    Extract the .zip file to appropriate location and find the eclipse.exe file. In the same directory find the eclipse.ini file. Open eclipse.ini file with editor and set the –vm option under –product.

To set –vm option find

-product

org.eclipse.epp.package.jee.product

under this paste

                -vm

c:/Program Files/Java/jdk1.7.0_02/bin/javaw.exe (This is path to javaw.exe for us as we installed JDK on default location).

3.)    Open the eclipse. And install the required plugins.

 

Git:

4.)    Start the Git installer.(Download it from here http://git-scm.com/download/win)

5.)    Run the installer and select all default options until “Adjusting your PATH environment” is displayed.

6.)    Select 3rd option. i.e. “Run Git and included Unix tools from the windows command prompt”.

7.)    In line ending configuration select 1st option. i.e. “default option”.

8.)    Click “Next” to start the installation.

9.)    Ones installation is done, to make sure Git installation works fine. Open command prompt and type git –version this should display Git version.

10.) Also execute ls command and it should display list of directories and files under current working directory

11.) Ones ready create .ssh folder under Git working directory and copy and paste id_rsa and id_rsa.pub files inside it for SSH access.

 

Install Plugins in Eclipse:

1.)    Open Eclipse IDE and go to Help > Install New Software.

2.)    A new window will appear. Click on [Add…] button.

3.)    New “Add Repository” box will appear. Enter <Plug-in Name> in name text box. And enter following Plug-in URL in Location and click on [Ok] button.

4.)    Depending on network speed it will grab the list of software available from repository and display.

5.)    Select “Maven Integration for Eclipse” and click on next. (Wait until eclipse collects the information).

6.)    Click on [Next >] in Install Details.

7.)    Accept the Terms and Conditions and click [Next >].

8.)    You may Restart the Eclipse IDE ones the installation is done.

Maven Plug-in URL : http://m2eclipse.sonatype.org/sites/m2e/

TestNG Plug-in URL : http://beust.com/eclipse

EGit Plug-in URL: http://download.eclipse.org/egit/updates

 

 

Browsers required on Local System(Should be installed on default locations).

1.)    Firefox 12

2.)    Internet Explorer 8

3.)    Chrome

 

For Android Emulator tests

1.)    Download and install emulator SDK from  http://developer.android.com/sdk/index.html

2.)    After installation open the SDK.

3.)    Select Android 4.1 API and click on Install.

4.)    After installation open Android AVD manager.

5.)    Click on new and select “target” Android 4.1.

6.)    Under Hardware Increase the Device RAM size to 1024 and Device Heap size to 96.

7.)    Give device a Name and click on Create AVD.

8.)    After creating AVD select AVD and start. It will take a while. Meanwhile we will download Selenium Stand alone server for Android from http://selenium.googlecode.com/files/android-server-2.21.0.apk.

9.)    Ones device is started open command prompt or and move to the directory where AVD is installed

10.) For windows it is by default under user profile,

11.) So move to current user directory and execute following  commands.

                cd “Local Settings\Application Data\Android\android-sdk\platform-tools”

                adb devices (To find out name of the device. For us its emulator-5554)

                adb –s <AVD id(i.e. emulator-5554)> install –r <path to android server.apk file >

12.) ones server is installed start server from Android device.(You will find selenium ICON after successful installation)

13.) ones server is started execute the command adb –s <AVD id(i.e. emulator-5554)> forward tcp:8080 tcp:8080 this command will do port forwarding.

14.) To confirm that we can communicate with Android, open any browser and type http://localhost:8080. You should be able to see 404 page. Click on first link and it should say {status:0}.

 

Selenium Standalone Server:

1.)    We use latest version of Selenium Client and Server i.e. (2.24.1) download it from here http://seleniumhq.org/download/.

2.)    To start the selenium Server move to the directory where selenium server file is and execute the command java -jar selenium-server-standalone-2.24.1.jar

3.)    This will start selenium stand alone server on machine.

 

To start Selenium Grid:

1.)    Open command prompt and move to the directory where selenium server resides.

2.)    Start the hub: execute the command java -jar ..\selenium-server-standalone-2.21.0.jar -role hub

3.)    Now let’s connect Firefox. Open another command prompt and execute command java -jar ..\selenium-server-standalone-2.21.0.jar -role webdriver -browser browserName=”firefox”,version=”12″,platform=”WINDOWS”,maxInstances=”5″ -hub http://localhost:4444/grid/register -port 6666

4.)    For IE open another command prompt window and execute the command: java -jar ..\selenium-server-standalone-2.20.0.jar -role webdriver -browser browserName=”internet explorer”,version=”8″,platform=”WINDOWS”,maxInstances=”3″ -hub http://localhost:4444/grid/register -port 7777

5.)    *For chrome open another command prompt and execute the command: java -jar ..\selenium-server-standalone-2.21.0.jar -Dwebdriver.chrome.driver=chromedriver.exe -role webdriver -hub http://localhost:4444/grid/register -port 8899 -browser “platform=WINDOWS,browserName=chrome,version=16.0.912.75,maxInstances=5,chrome_binary=C:\Documents and Settings\%username%\Local Settings\Application Data\Google\Chrome\Application\chrome.exe”

Note: *To start chrome using grid chrome driver is required. Download it form http://chromedriver.googlecode.com/files/chromedriver_win_22_0_1203_0b.zip  and extract chromedriver.exe and other files into the selenium server directory.

 

Eclipse Setup:

1.)    To download Eclipse http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/junor

2.)    Install TestNG, EGIT and Maven plug-in to eclipse.

 

Ones above setup is ready

1.)    go to File > Import to import the project.

2.)    Select Import project from GIT under Git

3.)    Select URI to download the project form URL

4.)    Enter the URL and protocol as SSH.

5.)    Select next and it will give you details of branches. (At this step it may give you warnings as we are accessing private repository.)

6.)    Select appropriate branch to import project from and click next

7.)    Select appropriate destination and click next.

8.)    At “Select a wizard for importing projects” select import existing project and click next.

9.)    In “Import projects” select appropriate project and click finish.

10.) Upon clicking finish project will be downloaded on chosen location and all the dependencies will be downloaded by Maven. (Building workspace may take time for the first time as it download all the dependencies).

 

AdvancedUserInteractions – MouseEvents

Posted on Updated on

Introduction

The Advanced User Interactions API is a new, more comprehensive API for describing actions a user can perform on a web page. This includes actions such as drag and drop or clicking multiple elements while holding down the Control key.

Getting started (short how-to)

In order to generate a sequence of actions, use the Actions generator to build it. First, configure it:

   Actions builder = new Actions(driver);

   builder.keyDown(Keys.CONTROL)
       .click(someElement)
       .click(someOtherElement)
       .keyUp(Keys.CONTROL);

Then get the action:

   Action selectMultiple = builder.build();

And execute it:

   selectMultiple.perform();

The sequence of actions should be short – it’s better to perform a short sequence of actions and verify that the page is in the right state before the rest of the sequence takes place. The next section lists all available actions and how can they be extended.

Keyboard interactions

Until now, keyboard interaction took place through a specific element and WebDriver made sure the element is in the proper state for this interaction. This mainly consisted of scrolling the element into the viewport and focusing on the element.

Since the new Interactions API takes a user-oriented approach, it is more logical to explicitly interact with the element before sending text to it, like a user would. This means clicking on an element or sending a Keys.TAB when focused on an adjacent element.

The new interactions API will (first) support keyboard actions without a provided element. The additional work to focus on an element before sending it keyboard events will be added later on.

Mouse interactions

Mouse actions have a context – the current location of the mouse. So when setting a context for several mouse actions (using onElement), the first action will be relative to the location of the element used as context, the next action will be relative to the location of the mouse at the end of the last action, etc.

Current status

The API is (mostly) finalized for the actions and actions generator. It is fully implemented for HtmlUnit and Firefox and in the process of being implemented for Opera and IE.

Outline

A single action

All actions implement the Action interface. This action only has one method: perform(). The idea being that each action gets the required information passed in the Constructor. When invoked, the action then figures out how it should interact with the page (for example, finding out the active element to send the key to or calculating the screen coordinates of an element for a click) and calls the underlying implementation to actually carry out the interaction.

There are currently several actions:

  • ButtonReleaseAction – Releasing a held mouse button.
  • ClickAction – Equivalent to WebElement.click()
  • ClickAndHoldAction – Holding down the left mouse button.
  • ContextClickAction – Clicking the mouse button that (usually) brings up the contextual menu.
  • DoubleClickAction – double-clicking an element.
  • KeyDownAction – Holding down a modifier key.
  • KeyUpAction – Releasing a modifier key.
  • MoveMouseAction – Moving the mouse from its current location to another element.
  • MoveToOffsetAction – Moving the mouse to an offset from an element (The offset could be negative and the element could be the same element that the mouse has just moved to).
  • SendKeysAction – Equivalent to WebElement.sendKey(...)

 

The CompositeAction contains other actions and when its perform method is invoked, it will invoke the perform method of each of the actions it contains. Usually, the actions should not created directly – the ActionChainsGenerator should take care of that.

Generating Action chains

The Actions chain generator implements the Builder pattern to create a CompositeAction containing a group of other actions. This should ease building actions by configuring an Actions chains generator instance and invoking it’s build() method to get the complex action:

   Actions builder = new Actions(driver);

   Action dragAndDrop = builder.clickAndHold(someElement)
       .moveToElement(otherElement)
       .release(otherElement)
       .build();

   dragAndDrop.perform();

A planned extension to the Actions class is adding a method that will append any Action to the current list of actions it holds. This will allow adding extended actions without manually creating the CompositeAction. On extending actions, see below.

Guidelines for extending the Action interface

Thie Action interface only has one action – perform(). In addition to the actual interaction itself, any evaluation of conditions should be performed in this method. It’s possible that the page state has changed between creation of the action and when it was actually performed – so things like element’s visibility and coordinates shouldn’t be found out in the Action constructor.

Implementation details

To achieve separation between the operations each action is performing and the actual implementation of the operations, all actions rely on two interfaces: Mouse and Keyboard. These interfaces are implemented by every driver that supports the advanced user interactions. Note that these interfaces are designated to be used by the actions – not by end users – the information in this section is only useful for developers planning to extend WebDriver.

A word of warning

The keyboard and mouse interface are designed to be used by the various action classes. For this reason, their API is less stable than that of theActions chain generator. Directly using these interfaces may not yield the expected results, as the actions themselves do additional work to make sure the right conditions are met before events are actually generated. Such preliminary work includes focusing on the right element or making sure the element is visible before any mouse interaction.

Keyboard

The Keyboard interface has three methods:

  • void sendKeys(CharSequence... keysToSend) – Similar to the existing sendKeys(...) method.
  • void pressKey(Keys keyToPress) – Sends a key press only, without releasing it. Should only be implemented for modifier keys (Control, Alt and Shift).
  • void releaseKey(Keys keyToRelease) – Releases a modifier key.

 

It is the implementation’s responsibility to store the state of modifier keys between calls. The element which will receive those events is the active element.

Mouse

The Mouse interface includes the following methods (This interface will change soon):

    • void click(WebElement onElement) – Similar to the existing click() method.
    • void doubleClick(WebElement onElement) – Double-clicks an element.
    • void mouseDown(WebElement onElement) – Holds down the left mouse button on an element.

Action selectMultiple = builder.build();

  • void mouseUp(WebElement onElement) – Releases the mouse button on an element.
  • void mouseMove(WebElement toElement) – Move (from the current location) to another element.
  • void mouseMove(WebElement toElement, long xOffset, long yOffset) – Move (from the current location) to new coordinates: (X coordinates of toElement + xOffset, Y coordinates of toElement + yOffset).
  • void contextClick(WebElement onElement) – Performs a context-click (right click) on an element.

 

Native events versus synthetic events

In WebDriver advanced user interactions are provided by either simulating the Javascript events directly (i.e. synthetic events) or by letting the browser generate the Javascript events (i.e. native events). Native events simulate the user interactions better whereas synthetic events are platform independent, which can be important in Linux when alternative window managers are used, see native events on Linux. Native events should be used whenever it is possible.

The following table shows which browsers support which kind of events:

 

Browser Operating system Native events Synthetic events
Firefox Linux supported supported (default)
Firefox Windows supported (default) supported
Internet Explorer Windows supported (default) not supported
Chrome Linux/Windows supported* not supported
Opera Linux/Windows supported (default) not supported
HtmlUnit Linux/Windows supported (default) not supported

 

*ChromeDriver provides two modes of supporting native events called WebKit events and raw events. In the WebKit events the ChromeDrivercalls the WebKit functions which trigger Javascript events, in the raw events mode operating systems events are used.

In the FirefoxDriver, native events can be turned on and off in the FirefoxProfile.

FirefoxProfile profile = new FirefoxProfile();
profile.setEnableNativeEvents(true);
FirefoxDriver driver = new FirefoxDriver(profile);

Examples

These are some examples where native events behave different to synthetic events:

  • With synthetic events it is possible to click on elements which are hidden behind other elements. With native events the browser sends the click event to the top most element at the given location, as it would happen when the user clicks on the specific location.
  • When a user presses the ‘tab’ key the focus jumps from the current element to the next element. This is done by the browser. With synthetic events the browser does not know that the ‘tab’ key is pressed and therefore won’t change the focus. With native events the browser will behave as expected.

Firefox driver – Selenium

Aside Posted on Updated on

package org.openqa.selenium.example;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class GoogleSuggest {
    public static void main(String[] args) throws Exception {
        // The Firefox driver supports javascript 
        WebDriver driver = new FirefoxDriver();
        
        // Go to the Google Suggest home page
        driver.get("http://www.google.com/webhp?complete=1&hl=en");
        
        // Enter the query string "Cheese"
        WebElement query = driver.findElement(By.name("q"));
        query.sendKeys("Cheese");

        // Sleep until the div we want is visible or 5 seconds is over
        long end = System.currentTimeMillis() + 5000;
        while (System.currentTimeMillis() < end) {
            WebElement resultsDiv = driver.findElement(By.className("gssb_e"));

            // If results have been returned, the results are displayed in a drop down.
            if (resultsDiv.isDisplayed()) {
              break;
            }
        }

        // And now list the suggestions
        List<WebElement> allSuggestions = driver.findElements(By.xpath("//td[@class='gssb_a gbqfsf']"));
        
        for (WebElement suggestion : allSuggestions) {
            System.out.println(suggestion.getText());
        }
     }
}

WaitForPageToLoad

Posted on Updated on

package com.projectname;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import java.lang.System;

public class BaseTest {

public final int PAGE_TIMEOUT_TIME = 30000;

public boolean waitForPageToLoad(WebDriver driver) {
long start = System.currentTimeMillis();
try {
Thread.sleep(700);
} catch (InterruptedException e1) {

e1.printStackTrace();
}
while (System.currentTimeMillis() – start < PAGE_TIMEOUT_TIME) {
if (((JavascriptExecutor) driver)
.executeScript(“return document.readyState”).toString()
.equalsIgnoreCase(“complete”)) {
return true;
} else {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

return false;

}

}