Tuesday 31 December 2013

Handling Drag & Drop for HTML5 | Robot [Webdriver]

Usual drag & drop doesn't work on pages built with HTML5. Here, I've used Robot for controlling the Mouse Actions to work with HTML5 websites.

Snippet

@Test
public void dragAndDrop() throws AWTException, InterruptedException {

driver.get("http://demo.kaazing.com/forex/");
Actions builder = new Actions(driver);
WebElement sourceElement = driver.findElement(By.xpath("(//li[@name='dragSource'])[13]"));
Action drag = builder.clickAndHold(sourceElement).build();
drag.perform();
    
WebElement targetElement = driver.findElement(By.xpath("//section[@id='section1']/div[2]"));
Point coordinates = targetElement.getLocation();
Robot robot = new Robot(); //Robot for controlling mouse actions
robot.mouseMove(coordinates.getX(),coordinates.getY()+120);
Thread.sleep(5000);
}

Note| Java Robot can also be used for various actions like locating tooltips, etc.,

Friday 27 December 2013

JUnit3 | JUnit 4 | TestNG variations [Selenium Users]

History of Unit Testing Frameworks:
sUnit  |  ~1998, Kent Beck [for Smalltalk]
JUnit  |  ~2000, Kent Beck & Erich Gamma [Latest 3.x: 3.8.2 (March 2006)]
TestNG     |  ~2004 [Latest: 5.8 (March 2008)]
JUnit 4.x |  2006 [Latest: 4.5 (August 2008)]

Handling expected Exceptions


























Test class | Methods























SetUp | Teardown


Wednesday 11 December 2013

Re-run failed tests Automatically | TestNG | Log4J

Here, I've used Maven for Test Execution; Make sure Log4J dependency added in your POM.xml file. You must run your tests on TestNG framework to achieve this.

Please find the optimized test in my GIT with the use case mentioned below| https://github.com/prashanth-sams/re-runFailedTests

1| Assume you have a class file with 10 Methods [@Test]
2| Lets say one got failed due to Network issue
3| The class file, RetryAnalyzer will make the failed test-case to re-run with desired count; But, it display errors for all the test failures during re-run. [Explained in this post]
4| You are ought to add a Listener class, RetryTestListener; it will print the failure only once.
5| If the test got passed in the final count, failure exception won't be thrown in the console.

Note| 
Steps 4 and 5 are missing in this post; Find it in GIT.


Test Class

@BeforeTest
public void setUp()
{
driver = new FirefoxDriver();
baseUrl = "https://www.google.co.in";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}

@Test(retryAnalyzer=RetryAnalyzer.class)
public void test01() throws Exception
{
driver.get(baseUrl + "/");
String save = driver.findElement(By.id("als")).getText();
System.out.println(save);
        // Assert.fail();
Assert.assertEquals(save, "qwerty");
}


RetryAnalyzer.java

Create a Java class, 'RetryAnalyzer' inside the same package and paste the following snippet with minor edits.

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

public class RetryAnalyzer implements IRetryAnalyzer  { 
private int count = 0; 
private int maxCount = 4; // set your count to re-run test
protected Logger log;
private static Logger testbaseLog;

static {
    PropertyConfigurator.configure("test-config/log4j.properties");
    testbaseLog = Logger.getLogger("TestclassName");
}

public RetryAnalyzer()
{
    testbaseLog.trace( " ModeledRetryAnalyzer constructor " + this.getClass().getName() );
    log = Logger.getLogger("TestclassName");
}

@Override 
public boolean retry(ITestResult result) { 
    testbaseLog.trace("running retry logic for  '" 
            + result.getName() 
            + "' on class " + this.getClass().getName() );
        if(count < maxCount) {                     
                count++;                                    
                return true; 
        } 
        return false; 
}
}


POM.xml

<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.37.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>            
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>${basedir}/src/test/java/abilash/yourxmlfile.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>  
</plugins>
</build>


P.S| TestNG will create a xml file, 'testng-failed.xml' after your test failure; It contains all the failed test Methods. It can be used to re-run your Failed tests manually.

Friday 6 December 2013

Appium Native iOS App Testing | WebDriver

Appium is an open source, cross-platform test automation tool for native, hybrid and mobile web apps. Appium tests can be written in your favorite Webdriver-compatible language.


Requirements & installation

1| MAC OS X 10.7 (minimum version required)
2| Xcode updated version (prefer)
3| Node.js
4| Appium.app
5| Eclipse Kepler (prefer)
6| TestNG framework


Pre-Appium setup

iOS .app file is enough to inspect elements. In this example, I have used the project, 'InternationalMountains' from Apple DEV site.

1| Download the project, 'InternationalMountains'
2| Double click and extract it
3| Import it into Xcode by opening the Xcode file
4| Run the project
5| Make sure that the simulator is opened with the application
6| Open Terminal and move to the project folder
7| Run the following command to build the .app file

xcodebuild -sdk iphonesimulator6.1

8| It will build the app and generate the file, 'InternationalMountains.app' under
/InternationalMountains/Build/Products/Release-iphonesimulator/


Appium iOS setup

1| Download & Install Node.js
// npm represents that Node.js Package Manager
$ sudo npm install wd


2| Run the Appium server using node.js;  There are couple of ways to do so..

#1 Using Node.js
//install Appium
$ npm install -g appium (or) $ sudo npm install appium -g
//start Appium server
$ appium & 


#2 Using the App
Download Appium, install and Run it

3| Now, the Appium server gets started in the default port 4723 and IP Address 0.0.0.0
i.e., [http://0.0.0.0:4723]


Appium inspector

Appium inspector is a record and playback tool just like Selenium IDE for web.

1| Open Appium
2| Change the default IP address to 127.0.0.1 and port 4725




3| Now, enable the check box, 'App path'
4| Click on the 'Choose' button and locate the .app local directory. i.e., InternationalMountains.app



5| Click on the 'Launch' button [Appium server launches now]
6| Now, a blue-colored icon found beside the 'Launch' button is enabled
7| Clicking blue-colored icon open up the Appium inspector with Simulator
8| Now, click the 'Record' button in Appium inspector
9| Every action will be generating a script at bottom of the Appium inspector




Run the script in Eclipse IDE

package packagename;

import java.io.File;
import java.net.URL;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class AppiumTest {
public WebDriver driver = null;

@BeforeMethod
public void setUp() throws Exception {
// set up appium
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME, "iOS");
capabilities.setCapability(CapabilityType.VERSION, "6.1");
capabilities.setCapability(CapabilityType.PLATFORM, "Mac");
capabilities.setCapability("app","/Users/username/Downloads/InternationalMountains/build/Release-iphonesimulator/InternationalMountains.app");
driver = new RemoteWebDriver(new URL("http://127.0.0.1:4725/wd/hub"), capabilities);
}

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

@Test
public void test01() throws InterruptedException {
driver.findElement(By.xpath("//window[1]/tableview[1]/cell[2]")).click();
driver.findElement(By.xpath("//window[1]/navigationBar[1]/button[1]")).click();
driver.findElement(By.xpath("//window[1]/tableview[1]/cell[7]/text[1]")).click();
}
}
  

Note: 
1| Currently, there is no Appium inspector support for Windows

Wednesday 4 December 2013

Selenium & Performance Testing | Firebug

Note:  Text in ORANGE can be edited or mentioned important for this entire blog

NetExport Firebug extension is used to find out the actual response time for each and every request sent.  I have used the Firefox profile to do this.

Configure netExport

1| Download Firebug Firefox add-on
2| Download netExport Firefox add-on. [netExport is a part of Firebug]


NetExport Firebug extension is used for exporting the data collected by Net panel

3| Manual Export option is available to download the data in .HAR format. [Here, we are going to do the same using Selenium Webdriver]


4| The downloaded .har log can be viewed later to check performance of the site. [This can done using harviewer]
5| Drag the .har log from local directory and drop it anywhere inside the page mentioned in step 4. (or)
Copy the .har log contents and paste it into the text box and press the preview button.



Snippet | netExport

ProfilesIni profile = new ProfilesIni();
FirefoxProfile myprofile = profile.getProfile("default"); //Here, default is the Firefox profile
 
// Set default Firefox preferences
myprofile.setPreference("app.update.enabled", false);

String domain = "extensions.firebug.";

// Set default Firebug preferences
myprofile.setPreference(domain + "currentVersion", "2.0");
myprofile.setPreference(domain + "allPagesActivation", "on");
myprofile.setPreference(domain + "defaultPanelName", "net");
myprofile.setPreference(domain + "net.enableSites", true);

// Set default NetExport preferences
myprofile.setPreference(domain + "netexport.alwaysEnableAutoExport", true);
myprofile.setPreference(domain + "netexport.showPreview", false);
myprofile.setPreference(domain + "netexport.defaultLogDir", "C:\\Test\\"); //Set the local directory here

driver = new FirefoxDriver(myprofile);


Load Add-on from Local Directory [acts just like incognito Window]

#1 Custom Profile
ProfilesIni profile = new ProfilesIni();
final String firebugPath = "C:\\firebug-1.12.5.xpi";
FirefoxProfile myprofile = profile.getProfile("sams");   
myprofile.addExtension(new File(firebugPath));
  
String domain = "extensions.firebug.";

// Set default Firebug preferences
myprofile.setPreference(domain + "currentVersion", "2.0");
myprofile.setPreference(domain + "allPagesActivation", "on");
myprofile.setPreference(domain + "defaultPanelName", "console");
myprofile.setPreference(domain + "net.enableSites", true);
  
driver = new FirefoxDriver(myprofile);

#2  New Profile
final String firebugPath = "C:\\firebug-1.12.5.xpi";
FirefoxProfile myprofile = new FirefoxProfile();       
myprofile.addExtension(new File(firebugPath));

String domain = "extensions.firebug.";

// Set default Firebug preferences
myprofile.setPreference(domain + "currentVersion", "2.0");
myprofile.setPreference(domain + "allPagesActivation", "on");
myprofile.setPreference(domain + "defaultPanelName", "net");
myprofile.setPreference(domain + "net.enableSites", true);

driver = new FirefoxDriver(myprofile); 


Note: 
1| consoleExport is another tool similar to netExport;  consoleExport can be saved in .html format and viewed manually through browser.