Thursday 15 May 2014

Cucumber BDD framework with Selenium WebDriver


Note|  Text in Blue [#PYTHON] and Orange [#JAVA] can be edited or mentioned important for the entire blog. All the posts are practically done by me.


Cucumber BDD Framework | selenium


1| Add an Eclipse plugin, Cucumber Eclipse feature using the below URL,
http://cucumber.github.com/cucumber-eclipse/update-site
2| Help > install new software... > paste the above url in work with text field and press enter key.
3| After the installation is done, restart Eclipse IDE.



4| Create a Maven project and add the following dependencies in POM.xml file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>BDD</groupId>
  <artifactId>Cucumber</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Cucumber</name>
  <url>http://maven.apache.org</url>

    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

      <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.12.2</version>
                <configuration>                
                    <useFile>false</useFile>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
      
 <dependencies>

   <dependency>
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId>
     <version>4.11</version>
     <scope>test</scope>
   </dependency>    

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>2.41.0</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-core</artifactId>
<version>1.1.2</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.1.2</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.1.2</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-html</artifactId>
<version>0.2.2</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>gherkin</artifactId>
<version>2.11.6</version>
</dependency>

<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>gherkin</artifactId>
<version>2.11.6</version>
</dependency>

<dependency>
            <groupId>com.rubiconproject.oss</groupId>
            <artifactId>jchronic</artifactId>
            <version>0.2.6</version>
            <scope>test</scope>
        </dependency>
                    
  </dependencies>
</project>


5| Now, create a test run class file

package BDD.Cucumber;

import org.junit.runner.RunWith;

import cucumber.api.junit.Cucumber;


@RunWith(Cucumber.class)
@Cucumber.Options(format = {"pretty", "html:target/cucumber","json:target/cucumber.json"})
public class RunTest {

}


6| Now, create a test class file

package BDD.Cucumber;

import static org.junit.Assert.assertEquals;

import java.util.concurrent.TimeUnit;

import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

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

import cucumber.api.Scenario;
import cucumber.api.java.After;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;



public class Googlesearch {

public WebDriver driver = new FirefoxDriver();

@Given("^Google page \"([^\"]*)\"$")
public void i_open_google_page_as(String URL) throws Throwable {
driver.get(URL);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

}


@When("^I enter \"([^\"]*)\" in search box$")
public void i_enter_in_search_box(String arg1) throws Throwable {
driver.findElement(By.name("q")).sendKeys(arg1);
}

@When("^I press enter key$")
public void i_press_enter_key() throws Throwable {
driver.findElement(By.name("q")).submit();

}

@Then("^I should get the results of \"([^\"]*)\"$")
public void i_should_see_results_of(String content) throws Throwable {

Thread.sleep(3000L);
boolean b = driver.getPageSource().contains(content);
Assert.assertTrue(b);
}

@After
public void after(Scenario scenario) {
driver.close();
}

}





7| Create a new source folder, "resources" under src/test/
8| Now, create a package, "BDD.Cucumber"
9| Then create a file with extension .feature
Right click BDD.Cucumber under src/test/resources > New > Other > File
10| Name the file with extension .feature; i.e., test.feature

Feature: test

@foo
Scenario: google search

Given Google page "http://www.google.com"
When I enter "Prashanth Sams" in search box
When I press enter key
Then I should get the results of "Prashanth Sams"


11| Right click on the project > Run As > maven clean
12| Again Right click on the project > Run As > maven install


Note: For more info. download my sample project from Github Link

Wednesday 7 May 2014

Selenium Data-driven Text file | @DataProvider


Note|  Text in Blue [#PYTHON] and Orange [#JAVA] can be edited or mentioned important for the entire blog. All the posts are practically done by me.


This is the continuation of one my previous topics, #link.  In this method, we are using @dataProvider annotation on TestNG to fetch keywords from a Text file and passing the arguments to Test class. This is our (Prashanth Sams + Karthikeyan) implementation to work with Text file via dataprovider.


Text File | @DataProvider

The below example illustrates on how to work with @dataprovider in-order to fetch values from a text file.

1| Create a Test class file similar to the one given below:


package packagename;

import java.util.HashMap;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class Google {
    private WebDriver driver;

    @DataProvider(name="keywords")
    public Object[][] data() throws Exception {
        HashMap<String,String[]> dataSet= new Text2TestData(System.getProperty("user.dir")+"\\config.txt").getData();
        
        String search1Strings[]=dataSet.get("search1");
        String search2Strings[]=dataSet.get("search2");
        int size =search1Strings.length;
   
        // modify 2 upon the no. of rows; Here, I used two rows, 'search1' & 'search2'
        Object[][] creds = new Object[size][2];  
        for(int i=0;i<size;i++)
        {
            creds[i][0]=search1Strings[i];
            creds[i][1]=search2Strings[i];
        }
        return creds;
    }


    @BeforeTest
    public void setUp() throws Exception {
        driver = new ChromeDriver();

    }

    @Test(dataProvider = "keywords", description = "Google_Test")
    public void search(String search1, String search2) throws Exception {
   
        driver.get("http://www.google.co.in");

        // search google via keyword 1
        driver.findElement(By.name("q")).clear();
        driver.findElement(By.name("q")).sendKeys("" + search1);
        driver.findElement(By.name("q")).submit();
        Thread.sleep(4000);

        // search google via keyword 1
        driver.findElement(By.name("q")).clear();
        driver.findElement(By.name("q")).sendKeys("" + search2);
        driver.findElement(By.name("q")).submit();
        Thread.sleep(4000);

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

}



Text2TestData

2| Create another java class file, 'Text2TestData' under the same package.


package packagename;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

public class Text2TestData {

    private String fileLocation;

    public Text2TestData(String fileLocation) {
        this.fileLocation = fileLocation;
    }

    public HashMap<String,String[]> getData(){
        FileInputStream fs;
        HashMap<String,String[]> keyValuePair=new HashMap<String,String[]>();
        try (BufferedReader br = new BufferedReader(new FileReader(fileLocation))){
            String stringLine;
            //Read File Line By Line
            while ((stringLine = br.readLine()) != null)   {
                // Print the content on the console
                String[] keyValue=stringLine.split("=");
                keyValuePair.put(keyValue[0],keyValue[1].split(","));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return keyValuePair;
    }


}



3| Create a text data-source file similar to the contents given below separated with comma (,)

search1=Prashanth Sams,bypasshacker
search2=seleniumworks.com,bypasshacker.blogspot.com

4| Now, place the config.txt file inside your project
5| Save the file and run test :)

Selenium Data-driven Properties file | @DataProvider


This is the continuation of one my previous topics, #link.  In this method, we are using @dataProvider annotation on TestNG to fetch keywords from a Properties file and passing the arguments to Test class. This is my implementation to work with Properties file via dataprovider.


Properties File | @DataProvider

The below example illustrates on how to work with @dataprovider in-order to fetch values from a properties file.

1| Create a Test class file similar to the one given below:


package packagename;

import java.util.HashMap;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class Google {
    private WebDriver driver;

    @DataProvider(name="keywords")
    public Object[][] data() throws Exception {
        HashMap<String,String[]> dataSet= new properties2TestData().getData();
        
        String search1Strings[]=dataSet.get("search1");
        String search2Strings[]=dataSet.get("search2");
        int size =search1Strings.length;
   
        // modify 2 upon the no. of rows; Here, I used two rows, 'search1' & 'search2'
        Object[][] creds = new Object[size][2];  
        for(int i=0;i<size;i++)
        {
            creds[i][0]=search1Strings[i];
            creds[i][1]=search2Strings[i];
        }
        return creds;
    }


    @BeforeTest
    public void setUp() throws Exception {
        driver = new ChromeDriver();

    }

    @Test(dataProvider = "keywords", description = "Google_Test")
    public void search(String search1, String search2) throws Exception {
   
        driver.get("http://www.google.co.in");

        // search google via keyword 1
        driver.findElement(By.name("q")).clear();
        driver.findElement(By.name("q")).sendKeys("" + search1);
        driver.findElement(By.name("q")).submit();
        Thread.sleep(4000);

        // search google via keyword 1
        driver.findElement(By.name("q")).clear();
        driver.findElement(By.name("q")).sendKeys("" + search2);
        driver.findElement(By.name("q")).submit();
        Thread.sleep(4000);

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

}



properties2TestData

2| Create another java class file, 'properties2TestData' under the same package.


package packagename;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.ResourceBundle;

public class properties2TestData {

    public properties2TestData() {
    }

    public HashMap<String,String[]> getData(){
    HashMap<String,String[]> configMap=new HashMap<String,String[]>();
    try{
    ResourceBundle bundle = ResourceBundle.getBundle("config");
        Enumeration<String> keys = bundle.getKeys();
        while(keys.hasMoreElements()){
        String aKey = keys.nextElement();
        String aValue = bundle.getString(aKey);
        configMap.put(aKey, aValue.split(","));
        }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return configMap;
    }

}



3| Create a properties data-source file similar to the contents given below separated with comma (,)

search1=Prashanth Sams,bypasshacker
search2=seleniumworks.com,bypasshacker.blogspot.com

4| Now, place config.properties file inside your project's Source folder[src]
5| Save the file and run test :)