Monday, October 3, 2011

Data providers for selenium

  There are different methods to provide data to selenium tests.

One of these is using the properties file. User can store the data in properties file and use its content for the selenium test

Here is a properties file with some content. Name it as datasuite.properties
     
      Directory = C:/prodFiles/
      NumberOfFiles = 25
      Extension = javaworld


and the corresponding java code to manipulate it


        InputStream is = this.getClass().getResourceAsStream("/conf/datasuite.properties");  
        Properties prop = new Properties();  
        prop.load(is); 
        String directory = prop.getProperty("Directory");  
        String numberOfFiles = prop.getProperty("NumberOfFiles");  
        String  fileExtension = prop.getProperty("Extension");  
        is.close(); 
        
        System.out.println(directory+" "+numberOfFiles+" "+fileExtension);

Below is the folder structure

src/main/java(Source Folder)
>com(Package)
  >DataDrivenTest.java
src/main/resource(Source Folder)
>conf(Package)
 >datasuite.properties

Friday, September 30, 2011

Wait For Elements using webdriver

One of the main issues facing automation scripts is using the proper wait for element functions so not to break 
the test and avoid using sleep statements. The WebDriver provides the class WebDriverWait to handle this scenario. The WebDriverWait constuctor can be passed with the required time to wait for each element. It uses the wait() function to handle individual elements which needs to be checked. The wait() function can either check for a boolean condition or a WebElement is actually present.
 
The below example shows the use of WebDriverWait.
 
import com.google.common.base.Function;
import com.google.common.base.Predicate;


Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) { 
  return new Function<WebDriver, WebElement>() { 
    public WebElement apply(WebDriver driver) { 
      return driver.findElement(locator); 
    }
  };
}

Predicate<WebDriver> presenceOfElementLocated1() { 
  return new Predicate<WebDriver>() { 
            public boolean apply(WebDriver d) {
                return d.getTitle().toLowerCase().endsWith("demosd");
    }
  };
}

@Test
public void ajxTest() throws InterruptedException{
selenium.open("http://60.240.240.221/web1");
WebDriverWait wait = new WebDriverWait(driver, /*seconds=*/10);
wait.until(presenceOfElementLocated1());
// selenium.click("//input[@type='button']");
  WebElement clickElement = wait.until(presenceOfElementLocated(By.id("anc_5")));
  clickElement.click();
WebElement element = wait.until(presenceOfElementLocated(By.id("anc_4")));
element.click();
Thread.sleep(4000);
}

Note the useage of Predicate and Function above. User needs to import guava.jar
The Predicate interface will return a boolean condition and Function interface converts WebDriver to WebElement.

Monday, August 22, 2011

Start a maven project for selenium

Create a new Maven project using eclipse. The "artifactId" given for the project will be the name of the project.
Now a a new project is created. It will be having the following two directory structures.

All classes for the project will be under src/main/java  and all unit tests will be under  src/test/java.

For a selenium project there will be no need for both these folder. So we can omit src/test/java and add all tests to src/main/java. The pom file should be updated with the entry  <testSourceDirectory>${basedir}/src/main/java</testSourceDirectory> to point that all tests are in folder structure src/main/java. If only configured like this,  the surefire plugin will execute the tests.

User should specify the class which needs to be executed. It can be specified using "test" option of surefire plugin.
So if all testng tests are written in the file BaseFile.java. Then use this command from cmd mvn test -Dtest=BaseFile.java to run the test. Else the class which needs to be executed can be specified in a suite file and the "suiteXmlFiles" option of surefire  be used.

eg :
      <suiteXmlFiles>
             <suiteXmlFile>sample.xml</suiteXmlFile>
       </suiteXmlFiles>

Use "reportsDirectory"   option of surefire plugin to create a custom folder to store the emailable report.

eg:
     <reportsDirectory>${directory}</reportsDirectory>

Where 'directory' is the argument passed from cmd.

Saturday, August 20, 2011

Run tests using Maven

By default mvn test, tries to execute the unit tests in the folder src/test/java. In order to override that behavior the parameter "testSourceDirectory" can be provided.  If "testSourceDirectory" is specified as src/main/java, then the classes under that directory can be executed using mvn test command.

Tuesday, August 2, 2011

Javascript and WebDriver

It is possible using webdriver to handle javascript. For this it uses interface JavascriptExecutor.

1. Sample code for getting page title

WebDriver driver = new FirefoxDriver();
JavascriptExecutor js =  (JavascriptExecutor)driver;
js.executeScript("return document.title");


2. Executing a javascript function declared.

Sample Page Code

<script>
function showAlert(){
alert('success');
}
</script>


Sample code

WebDriver driver = new FirefoxDriver();
JavascriptExecutor js =  (JavascriptExecutor)driver;
js.executeScript("showAlert()");
On executing above code, the alert will be shown.

Thursday, July 21, 2011

Execute a suite file using Ant

Ant file for running a suite file

For running a suite file provide the ant script with the task "testng". The "testng" task will only be executed if a task definition for testng is specified.

    <property name="xml" value=""/>


    <taskdef name="testng" classname="com.beust.testng.TestNGAntTask" classpathref="classpath"/>


    <target name="run_tests" depends="compile the code">
       <echo message="running tests" />
       <testng classpathref="classpath of jars and other classes used" haltOnfailure="true">
               <xmlfileset file="${xml}" />
       </testng>
    </target>

A xml suite file can be used to specify the test to be run. The parameters to be passed to the test etc.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
 <suite name="Suite1" verbose="1" >
  <test name="Regression1" preserve-order="true">
  <parameter name="env" value="test"/>
  <parameter name="driver" value="ie"/>
    <classes>
   <class name="mytests.First">
    </class>
    </classes>
    </test>
</suite>

Save the above suite as Sample.xml. It contains the class to be executed, the parameters to be passed to the test etc.

Ant Command
   ant -Dxml = Sample.xml

Yaml as config file

One of the best options to specify a config file for java based selenium project is by using a yaml file. In the yaml file the commonly changing config values or values which are used in all tests can be given. There are number of parsers available. I am using snakeyaml.

Jar File

snakeyaml-1.6.jar

Sample yaml file

base: &base                                  # defines anchor label base
  location_username: 'xpath'
  location_password: 'xpath'
  location_submit: 'xpath'
  page: 'http://xxxxxxxxxxx'

test:
  <<: *base                                 #  merges key : value from base anchor
  username: 'testtest'
  password: '123456'
  page: 'http://xxxxxxxxxxx'

prod:
  <<: *base
  username: 'testprod'
  password: '123456'
  page: 'http://xxxxxxxxxxx'

I have saved the above as sample.yaml in my config folder. The use of  "*" and "&" is the inherit the values defined in "base" to "test" and "prod"

Sample java program

import org.yaml.snakeyaml.Yaml;

public class xxx{
 protected Map<String, Map<String,Object>> fullConf;
 protected Map<String,Object> conf;

             Yaml yaml = new Yaml();
             InputStream input = new FileInputStream(new File(System.getProperty("user.dir") + "/config/sample.yaml"));
                this.fullConf = ((Map<String, Map<String,Object>>) yaml.load(input));
                System.out.println("values of fullConf "+fullConf);
                if (fullConf.containsKey("test")) {
                    this.conf = fullConf.get("test");
                    System.out.println("values of test env "+conf);
                    System.out.println("Username "+conf.get("username"));
                    System.out.println("Passowrd "+conf.get("password"));
                    System.out.println("Page "+conf.get("page"));
                    System.out.println("location_username "+fullConf.get("location_username"));
                    System.out.println("location_password "+fullConf.get("location_password"));
                }

}

This program prints the contents of yaml. The variable "fullConf " contains all data of the yaml file as a "key, Map". The variable "conf " will have data of any specific node.


Project home
   src
      test.com
  one/two/three
      config/config.yaml


         InputStream in = this.getClass().getClassLoader().getResourceAsStream("config/config.yaml");
        System.out.println("Hello1 : "+in);

        in = this.getClass().getResourceAsStream("/config/config.yaml");
        System.out.println("Hello3 : "+in);

http://viralpatel.net/blogs/2009/10/loading-java-properties-files.html