Wednesday 4 September 2013

Take screenshot in WebDriver


File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("C:\\test\\sample.png"));

Monday 5 August 2013

Appium android example program for windows using java - native app

To perform the automation using appium for the native android app just .apk file is enough. No need of developers code at all.

When we write the appium script for automation we need to specify the package name and activity name. We can get package and all activity names from the .apk file itself. For this we need to convert .apk file to java class files. See here to perform that.


I used following environments to accomplish this example program,


  • Windows7
  • Android SDK
  • JDK
  • Eclipse
  • TestNG

Install and start the appium server:


Appium server for windows platform is just a zip folder. It contains all the packages needed for appium such as node, webdriver etc. We no need to install any APIs additionally

  • Download the latest AppiumForWindows.zip from here
  • Unzip the AppiumForWindows.zip
  • Click on the appium.exe present in the unzipped appium folder. It will be opened up as below,


Appium Server For Windows

  • Now click on the 'Launch' button, It will start the server at 127.0.0.1:4723 as below,

Appium server is started

  • Then run the below program once the android emulator is ready.

Appium example program for android


package com.qa.test;

import java.io.File;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class androidExample {
WebDriver driver = null;
         
        @BeforeMethod
         public void setup() {
                File appDir = new File("E://AndroidApps");
File app = new File(appDir, "myApp.apk");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("device","Android");
capabilities.setCapability(CapabilityType.BROWSER_NAME, "");
capabilities.setCapability(CapabilityType.VERSION, "4.2.2");
capabilities.setCapability(CapabilityType.PLATFORM, "WINDOWS");
                // Here we mention the app's package name, to find the package name we  have to convert .apk file into java class files
capabilities.setCapability("app-package","com.myApp.activity");
                //Here we mention the activity name, which is invoked initially as app's first page.
capabilities.setCapability("app-activity","LoginActivity");
//capabilities.setCapability("app-wait-activity","LoginActivity,NewAccountActivity");
capabilities.setCapability("app", app.getAbsolutePath());

driver = new RemoteWebDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(80, TimeUnit.SECONDS);

         }

       @Test
public void loginTest() throws Exception {
driver.findElement(By.xpath("//EditText[@text='Email Address']")).sendKeys("tester@gmail.com");
driver.findElement(By.xpath("//LinearLayout/EditText[2]")).sendKeys("Testerpwd");
driver.findElement(By.xpath("//CheckBox")).click();
driver.findElement(By.xpath("//Button[@text='Login']")).click();

WebDriverWait wait = new WebDriverWait(driver,80);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//Button[@text='Logout']")));
driver.findElement(By.xpath("//Button[@text='Logout']")).click();

        }

       @AfterMethod
        public void tearDown() {
               driver.quit();
        }

}

Running this program will install the app in the emulator if it is not present already. If the app is installed already it will open and perform the automation steps.

If your app is already opened with some other activity(e.g. my profile page) appium will be waiting for the specified activity (com.myApp.activity.LoginActivity) when you run the automation script. In this case automation script will fail, since the app is opened with some other activity.

So it is better to start the appium server with an option full reset. Perform the following steps in appium GUI server,
  • Check the option 'Perform Full Reset'
  • Go to File > Preferences and check the option 'Reset Application State After Each Session'
When you use these options in the GUI server, you might also need to specify the app path, package and Activity name as below,

Start server with full reset

This will uninstall the app once your tests are completed and will install the app into emulator when the test starts initially.

Note:
  • Here I used the uiautomatorviewer to find the element hierarchy and then I constructed the xpath manually. To learn about constructing the xpath, please go here
  • You should set ANDROID_HOME and path for Android SDK in environment variable
  • Emulator adb device should have API level greater than or equal to 17


Wednesday 24 July 2013

How to handle StaleElementReferenceException?


Why StatleElementReferenceException is thrown?


StatleElementReferenceException indicates that a reference to an element is stale, means that element no longer appears on the DOM of the page.

For example let we consider the following code,

                List <WebElement> alllinks = driver.findElements(By.tagName("a"));

for(WebElement link : alllinks) {
link.click(); // It may cause StatleElementReferenceException 
                         driver.navigate().back();
}

Here the reference variable 'alllinks' has the reference of all the WebElements, those has anchor(//a) tag. Coming to below, the 'for' loop clicks on the each WebElement, then navigates to its corresponding page and comes back to the original page. Due to this navigation/refresh DOM references might be changed. But the reference variable 'alllinks' holds the previous references of WebElements. Now the reference of the element becomes 'stale'. In this case the StaleElementReferenceException is thrown.

How to handle StatleElementReferenceException?



You can avoid this StatleElementReferenceException be having following style of code,

             int sizeOfAllLinks = driver.findElements(By.tagName("a")).size();

            for (int index=0; index<sizeOfAllLinks; i++ ) {
                  getElementWithIndex(By.tagName("a"), index).click();
                  driver.navigate().back();
            }


            public WebElement getElementWithIndex(By by, int index) {
                  return webDriver.findElements(by).get(index);
            }

Convert .apk to java files


1. Change the extension of your .apk file to .zip
2. Then unzip the zip file, there you will see a file, named classes.dex. This file only has all the java class files
3. Now you need to convert the classes.dex file into jar file. We can do it by Dex2Jar. Download the it from the here  and unzip it.
4. Copy your classes.dex file into the unzipped Dex2Jar folder
5. Now go to the command line and go to the path of Dex2Jar folder, then run the below command

            dex2jar.bat classes.dex  ---> This will create a jar file in the unzipped folder.
6. Now you need to convert this jar file into java classes. For the you can use java decompiler. Download that from here

Friday 19 July 2013

How to install .apk file in emulator - windows platform

Open the emulator from the command line


Open the command prompt and go into the 'tools' folder of your Android SDK installed and run the below command,

            emulator -avd devicename

For example I have created an emulator already with the name 'test'. so the command would be as below 

            E:\adt-bundle-windows-x86-20130522\sdk\tools>emulator -avd test.

Install the .apk file into the emulator


Open the new command prompt and go into the 'platform-tools' folder of your Android SDK installed and run the below command,

           adb install apkFileNameWithPath

For example, I installe the myApp.apk into the opened emulator by the below command,

           E:\adt-bundle-windows-x86-20130522\sdk\platform-tools>adb install E:\AndroidWorkspace\appiumandroid\src\Resource\myApp.apk


Friday 12 July 2013

WebDriver TestNG example


public class GmailTestCases {

  @BeforeMethod
public void launch() {
driver= new FirefoxDriver();
  driver.get("http://gmail.com");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}

@AfterMethod
public void quit() {
driver.quit();
}


@Test
public void verifyLoginPage() {

String actual_title = driver.getTitle();
String expected_title = "Gmail: Email from Google";
Assert.assertEquals(expected_title, actual_title);
}


@Test
public void verifyLoginWithValidCredentials() throws Exception
{
driver.findElement(By.id("Email")).sendKeys("test@gmail.com");
driver.findElement(By.id("Passwd")).sendKeys("validpassword");
driver.findElement(By.id("signIn")).click();
Thread.sleep(10000);
String expected_username = "Test user";
String actual_username   = driver.findElement(By.id("gbi4t")).getText();
Assert.assertEquals(expected_username, actual_username);
}



@Test
public void verifyLoginWithInValidCredentials() throws InterruptedException {
driver.findElement(By.id("Email")).sendKeys("test@gmail.com");
driver.findElement(By.id("Passwd")).sendKeys("invalidpwd");
driver.findElement(By.id("signIn")).click();
Thread.sleep(10000);
                Assert.assertTrue(driver.getPageSource().contains("The username or password you entered is incorrect"));
}

@Test
public void verifyLinks() throws InterruptedException {

List <WebElement> alllinks = driver.findElements(By.tagName("a"));

for(int i=0;i<alllinks.size();i++) {
System.out.println(alllinks.get(i).getText());
}

for(int i=0;i<alllinks.size();i++){

alllinks = driver.findElements(By.tagName("a"));
alllinks.get(i).click();
Thread.sleep(1000);
driver.navigate().to("http://gmail.com");
Thread.sleep(1000);
}
}

================================================================

XML file

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <!-- Specify the test suite name --> <suite name="Gmail_Login" verbose="1" annotations="JDK"> <!-- Specify the test name --> <test name="gmail_Login_Scenarios" preserve-order="true"> <classes> <class name="packagename.GmailTestCases"> <methods> <include name="verifyLoginPage" /> <include name="verifyLoginWithValidCredentials" /> <include name="verifyLoginWithInValidCredentials" /> <include name="verifyLinks" /> </methods> </class> </classes> </test> </suite>




Mouse hover in WebDriver

'Action' class supports for mouse hover functionality as below,


                   WebElement element = driver.findElement(By.id("menu"));
                   Actions builder = new Actions(driver);
                  builder.moveToElement(element).build().perform();