DataProviders in TestNG

HOME

In the last tutorial, I have explain the Parameters in TestNG which passes different test data to the test case as arguments. Similar to TestNG Parameters, DataProviders are a means to pass data to test scripts in TestNG. In this tutorial, I will explain about the DataProviders in TestNG.

What is DataProvider in TestNG?

The DataProvider in TestNG is another way to pass the parameters in the test function, the other one being TestNG parameters. Using DataProvider in TestNG, we can easily inject multiple values into the same test case. It comes inbuilt in TestNG and is popularly used in data-driven frameworks.

Syntax of DataProvider

@DataProvider (name = "name_of_dataprovider")
public Object[][] dpMethod() {
    return new Object [][] { values}
}
  •  A Data Provider is a method on the class that returns an array of array of objects.  This method is annotated with @DataProvider
  • A @Test method specifies its Data Provider with the dataProvider attribute. This name must correspond to a method on the same class annotated with @DataProvider(name=”…”) with a matching name.
  • TestNG dataprovider returns a 2d list of objects..An array of array of objects (Object[][]) where the first dimension’s size is the number of times the test method will be invoked and the second dimension size contains an array of objects that must be compatible with the parameter types of the test method.
  • DataProviders are not declared on top of the functions like TestNG parameters but have a method of their own, which in regular speaking terms called a dataprovider method. For example, dpMethod here.
  • The dataprovider name calls the dataprovider method, and if there is no name specified by the tester, then the dataprovider method is the default name used in the receiving @Test case.
  • Data providers can run in parallel with the attribute parallel.

Below is the basic example of using DataProvider in TestNG.

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class DataProviderDemo {

	WebDriver driver;

	@DataProvider(name = "testData")
	public Object[][] dataProvFunc() {
		return new Object[][] { { "Selenium" }, { "TestNG" } };
	}

	@BeforeMethod
	public void setUp() {

		System.out.println("Start the test");
		System.setProperty("webdriver.chrome.driver",
				"C:\\Users\\Vibha\\Software\\chromedriver\\chromedriver.exe");
		driver = new ChromeDriver();
		driver.get("https://www.bing.com/");
		driver.manage().window().maximize();

	}

	// Passing the dataProvider to the test method through @Test annotation
	@Test(dataProvider = "testData")
	public void search(String keyWord) {
		WebElement txtBox = driver.findElement(By.id("sb_form_q"));
		txtBox.sendKeys(keyWord);
		System.out.println("Keyword entered is : " + keyWord);
		txtBox.sendKeys(Keys.ENTER);
		System.out.println("Search result is displayed.");
	}

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

		System.out.println("End the test");
	}

}

In the above example, I am passing two search keywords, viz “Selenium” and “TestNG” to the test method using the DataProvider method. You can run the code and check the output. It will be as shown below-

Here, Test is executed with two values, but we have run the test only once.

Inheriting DataProvider in TestNG

It is messy to have supporting methods like DataProvider and test code in one class. It is always preferred to declare the test case in one class and define TestNG parameters like DataProviders in another class. By default, the data provider will be looked for in the current test class or one of its base classes. If you want to put your data provider in a different class, it needs to be a static method or a class with a non-arg constructor, and you specify the class where it can be found in the dataProviderClass attribute.

Let us create separate classes for the DataProvider method and the test method, as shown below:

DataProvider Class

public class DPDemo {

	@DataProvider(name = "testData")
	public Object[][] dataProvFunc() {
		return new Object[][] { 
          { "Selenium" }, { "TestNG" }, { "Automation" } };
	}
}

We can see that all we did was create a DataProvider method in a Class and create a new class for Test Code.

public class DataProviderInheritanceDemo {

	WebDriver driver;

	@BeforeMethod
	public void setUp() {

		System.out.println("Start the test");
		System.setProperty("webdriver.chrome.driver",
				"C:\\Users\\Vibha\\Software\\chromedriver\\chromedriver.exe");
		driver = new ChromeDriver();
		driver.get("https://www.bing.com/");
		driver.manage().window().maximize();

	}

	// Passing the dataProvider to the test method through @Test annotation
	@Test(dataProvider = "testData", dataProviderClass = DPDemo.class)
	public void search(String keyWord) {
		WebElement txtBox = driver.findElement(By.id("sb_form_q"));
		txtBox.sendKeys(keyWord);
		System.out.println("Keyword entered is : " + keyWord);
		txtBox.sendKeys(Keys.ENTER);
		System.out.println("Search result is displayed.");
	}

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

		System.out.println("End the test");
	}

}

As you can see, to handle the inheritance, all we did was add an attribute to the test method (highlighted above), which specifies the class that has the DataProvider method. 

Passing Multiple Parameter Values in TestNG DataProviders

Passing multiple values is pretty similar to passing numerous parameters. The only difference is that we will pass various values to a single parameter so that a string of input(s) is sent in one go.

Let us quickly understand this concept with the help of the code as shown below.

DataProvider Class

public class DPDemo {

	@DataProvider(name = "testData")
	public Object[][] dataProvFunc() {
		return new Object[][] { { "Automation Tester", "2-5 years" }, { "Performance Tester", "3+ years" },
				{ "DevOps", "5+ years" } };
	}
}

Test Code – DataProviderInheritanceDemo

public class DataProviderInheritanceDemo {

	WebDriver driver;

	@BeforeMethod
	public void setUp() {

		System.out.println("Start the test");
		System.setProperty("webdriver.chrome.driver",
				"C:\\Users\\Vibha\\Software\\chromedriver\\chromedriver.exe");
		driver = new ChromeDriver();
		driver.get("https://www.bing.com/");
		driver.manage().window().maximize();

	}

	// Passing the dataProvider to the test method through @Test annotation
	@Test(dataProvider = "testData", dataProviderClass = DPDemo.class)
	public void search(String keyWord1, String keyWord2) {

		WebElement txtBox = driver.findElement(By.id("sb_form_q"));
		txtBox.sendKeys(keyWord1, keyWord2);
		System.out.println("Keyword entered is : " + keyWord1 + " " + keyWord2);
		txtBox.sendKeys(Keys.ENTER);
		System.out.println("Search result is displayed.");
	}

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

		System.out.println("End the test");
	}
}

Run the test script, and you will see both the values for the TestNG parameters being passed in one go, the output for it would be as follows-

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Serenity BDD with Gradle and Cucumber for Web Application

HOME

In the previous tutorial, I have explained about Integration Testing of SpringBoot Application with Serenity BDD and Cucumber in Maven project. This tutorial describes the creation of the Gradle Java Project to test a web application using Cucumber6 and JUnit4.

In this tutorial, I will explain creating a framework for the testing of Web Application in Cucumber BDD.

Pre-Requisite

  1. Java 11 installed
  2. Gradle installed
  3. Eclipse or IntelliJ installed

This framework consists of:

  1. Serenity – 2.6.0
  2. Serenity Cucumber – 2.6.0
  3. Java 11
  4. JUnit – 4.13.2
  5. Gradle – 7.2

Steps to setup Gradle Java Project for Web Application using Serenity , Cucumber6 and JUnit4

  1. Download and Install Java on the system
  2. Download and setup Eclipse IDE on the system
  3. Setup Gradle on System and create a new Gradle Project
  4. Update repositories, plugin and dependencies to the Gradle project
  5. Create a feature file under src/test/resources
  6. Create the Step Definition class or Glue Code for the Test Scenario
  7. Create a Serenity Cucumber Runner class
  8. Create serenity.conf file under src/test/resources
  9. Create serenity.properties file in the root of the project
  10. Run the tests through commandline which generates Serenity Report

Step 1- Download and Install Java

Cucumber and Rest-Assured need Java to be installed on the system to run the tests. Click here to know How to install Java.

Step 2 – Download and setup Eclipse IDE on system

The Eclipse IDE (integrated development environment) provides strong support for Java developers. Click here to know How to install Eclipse.

Step 3 – Setup Gradle

To build a test framework, we need to add several dependencies to the project. This can be achieved by any build Tool. I have used Gradle Build Tool. Click here to know How to install Gradle. Click here to know How to create a Gradle Java project. Below is the structure of Gradle project.

Step 4 – Update repositories, plugin and dependencies to the Gradle project

defaultTasks 'clean', 'test', 'aggregate'

repositories {
    mavenLocal()
    jcenter()
}

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }
    dependencies {
        classpath("net.serenity-bdd:serenity-gradle-plugin:2.4.24")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'net.serenity-bdd.aggregator'

sourceCompatibility = 11
targetCompatibility = 11

dependencies {
   
    testImplementation 'net.serenity-bdd:serenity-core:2.6.0'
    testImplementation 'net.serenity-bdd:serenity-cucumber6:2.6.0'
    testImplementation 'net.serenity-bdd:serenity-screenplay:2.6.0'
    testImplementation 'net.serenity-bdd:serenity-screenplay-webdriver:2.6.0'
    testImplementation 'junit:junit:4.13.1'
}

test {
    testLogging.showStandardStreams = true
    systemProperties System.getProperties()
}

gradle.startParameter.continueOnFailure = true

test.finalizedBy(aggregate)

Step 5 – Create a feature file under src/test/resources

A Feature File is an entry point to the Cucumber tests. This is a file where you will describe your tests in Descriptive language (Like English). A feature file can contain a scenario or can contain many scenarios in a single feature file. Below is an example of Feature file.

Feature: Login to HRM  

   @ValidCredentials
   Scenario: Login with valid credentials
   
    Given User is on Home page
    When User enters username as "Admin"
    And User enters password as "admin123"
    Then User should be able to login successfully

Step 6 – Create the Step Definition class or Glue Code for the Test Scenario

Steps definition file stores the mapping between each step of the test scenario defined in the feature file with a code of function to be executed. So, now when Cucumber executes a step of the scenario mentioned in the feature file, it scans the step definition file and figures out which function is to be called.

Create a StepDefinition class for LoginPage.feature

public class LoginPageDefinitions {
 
    @Steps
    StepLoginPage loginPage;
 
    @Steps
    StepDashboardPage dashPage;
 
    @Steps
    StepForgetPasswordPage forgetpasswordPage;
 
    @Given("User is on Home page")
    public void openApplication() {
        loginPage.open();
        System.out.println("Page is opened");
    }
 
    @When("User enters username as {string}")
    public void enterUsername(String userName) {
        System.out.println("Enter Username");
        loginPage.inputUserName(userName);
    }
 
    @When("User enters password as {string}")
    public void enterPassword(String passWord) {
        loginPage.inputPassword(passWord);
 
        loginPage.clickLogin();
    }
 
    @Then("User should be able to login successfully")
    public void clickOnLoginButton() {
        dashPage.loginVerify();
    }
   
}

Serenity Step Libraries integrate smoothly into Cucumber Step Definition files; all you need to do is to annotate a step library variable with the @Steps annotation.  Methods that represent a business task or action (inputUserName()), and that will appear in the reports as a separate step, are annotated with the @Step annotation. Here, I have created two StepClasses – StepLoginPage and StepDashboardPage

public class StepLoginPage extends PageObject {
 
    @Step("Enter Username")
    public void inputUserName(String userName) {
        $(By.name("txtUsername")).sendKeys((userName));
    }
 
    @Step("Enter Password")
    public void inputPassword(String passWord) {
        $(By.name("txtPassword")).sendKeys((passWord));
    }
 
    @Step("Click Submit Button")
    public void clickLogin() {
        $(By.name("Submit")).click();
    } 
 
}

StepDashboardPage

public class StepDashboardPage extends PageObject {
 
    @Step("Successful login")
    public void loginVerify() {
        String dashboardTitle = $(By.id("welcome")).getText();
        assertThat(dashboardTitle, containsString("Welcome"));
    }
}

Step 7 – Create a Serenity Cucumber Runner class

import org.junit.runner.RunWith;

import io.cucumber.junit.CucumberOptions;
import net.serenitybdd.cucumber.CucumberWithSerenity;

@RunWith(CucumberWithSerenity.class)
@CucumberOptions(plugin = {}, features = "lib/src/test/resources/features", glue = "serenitygradleautomation.definitions")

public class CucumberTestSuite {

}

Step 8 – Create serenity.conf file under src/test/resources

Serenity.conf file is used to specify various features like type of webdriver used, various test environments, run test in headless mode and many more options.

webdriver {
    driver = firefox
}
 
 
environments {
  default {
    webdriver.base.url = "https://opensource-demo.orangehrmlive.com/"
  }
  dev {
    webdriver.base.url = "https://opensource-demo.orangehrmlive.com/dev"
  }
  staging {
    webdriver.base.url = "https://opensource-demo.orangehrmlive.com/staging"
  }
  prod {
    webdriver.base.url = "https://opensource-demo.orangehrmlive.com/prod"
  }
}

Step 9 – Create serenity.properties file in the root of the project

serenity.project.name = Serenity and Cucumber Gradle Demo

Step 10 – Run the tests through commandline which generates Serenity Report

Open commandline and go to the location where gradle.build of the project is present and type the below command.

gradle test

The Serenity report is generated under /lib/target/site/serenity.

Serenity Report

Below is the image of Overall Test Result with steps and screenshots.

That’s it! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Integration of Allure Report with Selenium and TestNG

HOME

In this tutorial, I will explain how to integrate Allure Report (one of the very famous Report) with Selenium and TestNG.

What is Allure Framework?

Allure is an open-source framework designed to create interactive and comprehensive test report by Yandex QA Team.

Below example covers the implementation of Allure Reports in Selenium using TestNG, Java and Maven.

Pre-Requisite

  1. Java 11 installed
  2. Maven installed
  3. Eclipse or IntelliJ installed

This framework consists of:

  1. Selenium – 3.141.59
  2. Java 11
  3. TestNG – 7.4.0
  4. Maven – 3.8.1
  5. Allure Report – 2.14.0
  6. Allure TestNG – 2.14.0

Implementation Steps

  1. Update Properties section in Maven pom.xml
  2. Add Selenium, TestNG and Allure TestNG dependencies in POM.xml
  3. Update Build Section of pom.xml in Allure Report Project.
  4. Create Pages and Test Code for the pages
  5. Create testng.xml for the project
  6. Run the Test and Generate Allure Report

Step 1 – Update Properties section

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <selenium.version>3.141.59</selenium.version>
    <testng.version>7.4.0</testng.version>
    <allure.testng.version>2.14.0</allure.testng.version>
    <maven.compiler.plugin.version>3.5.1</maven.compiler.plugin.version>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <aspectj.version>1.9.6</aspectj.version>
    <maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>
  </properties>

Step 2 – Add Selenium, TestNG and Allure TestNG dependencies in POM.xml

<dependencies>
    
     <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>${selenium.version}</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.testng/testng -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>${testng.version}</version>
      <scope>test</scope>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/io.qameta.allure/allure-testng -->
    <dependency>
        <groupId>io.qameta.allure</groupId>
        <artifactId>allure-testng</artifactId>
        <version>${allure.testng.version}</version>
        <scope>test</scope>
    </dependency>
  </dependencies>

Step 3 – Update Build Section of pom.xml in Allure Report Project

<build>
       
       <plugins>
   <!-- Compiler plug-in -->
  
           <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>${maven.compiler.source}</source> <!--For JAVA 8 use 1.8-->
                    <target>${maven.compiler.target}</target> <!--For JAVA 8 use 1.8-->
                </configuration>
            </plugin>
            
     <!-- Added Surefire Plugin configuration to execute tests -->       
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-surefire-plugin</artifactId>
              <version>${maven.surefire.plugin.version}</version>
              <configuration>
                    <suiteXmlFiles>
                        <suiteXmlFile>TestNG.xml</suiteXmlFile>
                    </suiteXmlFiles>
                 <argLine>
                    -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                 </argLine>
             </configuration>          
             <dependencies>
            
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjweaver</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
      </plugins>
  </build>

Step 4 – Create Pages and Test Code for the pages

Below is the sample project which uses Selenium and TestNG which is used to generate an Allure Report.

We have 2 pages. Below is the code for Login Page which contains all the web elements and methods related to that web elements.

LoginPage.java

public class LoginPage {

	WebDriver driver;

	By userName = By.name("txtUsername");

	By password = By.name("txtPassword");

	By titleText = By.id("logInPanelHeading");

	By login = By.id("btnLogin");

	By errorMessage = By.id("spanMessage");

	public LoginPage(WebDriver driver) {
		this.driver = driver;
	}

	// Set user name in textbox
	public void setUserName(String strUserName) {
		driver.findElement(userName).sendKeys(strUserName);
	}

	// Set password in password textbox
	public void setPassword(String strPassword) {
		driver.findElement(password).sendKeys(strPassword);
	}

	// Click on login button
	public void clickLogin() {
		driver.findElement(login).click();
	}

	@Step("Verify title of Login Page")
	public void verifyPageTitle() {
		String loginPageTitle = driver.findElement(titleText).getText();
		Assert.assertTrue(loginPageTitle.contains("LOGIN Panel"));
	}

    /* Failed Test */
	@Step("Verify error message when invalid credentail is provided")
	public void verifyErrorMessage() {
		String invalidCredentialErrorMessage = driver.findElement(errorMessage).getText();
		Assert.assertTrue(invalidCredentialErrorMessage.contains("Incorrect Credentials"));
	}

	@Step("Enter username and password")
	public void login(String strUserName, String strPasword) {

		// Fill user name
		this.setUserName(strUserName);

		// Fill password
		this.setPassword(strPasword);

		// Click Login button
		this.clickLogin();

	}
}

Dashboard.java

public class DashboardPage {

	WebDriver driver;

	By dashboardPageTitle = By.id("welcome");

	By options = By.cssSelector(
			"#dashboard-quick-launch-panel-menu_holder > table > tbody > tr > td:nth-child(1) > div > a > span");

	public DashboardPage(WebDriver driver) {
		this.driver = driver;

	}

	@Step("Verify title of Dashboard page")
	public void verifyDashboardPageTitle() {
		String DashboardPageTitle = driver.findElement(dashboardPageTitle).getText();
		Assert.assertTrue(DashboardPageTitle.contains("Welcome"));
	}

	@Step("Verify Quick Launch Options on Dashboard page")
	public void verifyQuickLaunchOptions() {
		String QuickLaunchOptions = driver.findElement(options).getText();
		Assert.assertTrue(QuickLaunchOptions.contains("Assign Leave"));
	}

}

Below are the Test clases for Login Page and Dasboard Page. Here, we have BaseTest Class also which contains the common methods needed by other test pages.

BaseTest.java

public class BaseTest {

	public static WebDriver driver;
	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@Step("Start the application")
	@BeforeMethod
	public void setup() {
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");
		driver = new FirefoxDriver();
		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
		driver.get("https://opensource-demo.orangehrmlive.com/");
	}

	@Step("Stop the application")
	@AfterMethod
	public void close() {
		driver.close();
	}
}

LoginTests.java

@Epic("Web Application Regression Testing")
@Feature("Login Page Tests")
@Listeners(TestExecutionListener.class)
public class LoginTests extends BaseTest {

	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@Severity(SeverityLevel.NORMAL)
	@Test(priority = 0, description = "Verify Login Page")
	@Description("Test Description : Verify the title of Login Page")
	@Story("Title of Login Page")
	public void verifyLoginPage() {

		// Create Login Page object
		objLogin = new LoginPage(driver);

		// Verify login page text
		objLogin.verifyPageTitle();
	}

   /* Failed Test */
	@Severity(SeverityLevel.BLOCKER)
	@Test(priority = 1, description = "Login with invalid username and password")
	@Description("Test Description : Login Test with invalid credentials")
	@Story("Unsuccessful Login to Application")
	public void invalidCredentialTest() {

		// Create Login Page object
		objLogin = new LoginPage(driver);
		objLogin.login("test", "test123");

		// Verify login page text
		objLogin.verifyErrorMessage();

	}

}

We can order tests by severity by using @Severity annotation. Click here to know more about other Allure annotations.

DashboardTests.java

@Epic("Web Application Regression Testing")
@Feature("Dashboard Page Tests")
@Listeners(TestExecutionListener.class)
public class DashboardTests extends BaseTest {

	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@Severity(SeverityLevel.BLOCKER)
	@Test(priority = 0, description = "Verify Dashboard Page")
	@Description("Test Description : After successful login to application opens Dashboard page")
	@Story("Successful login of application opens Dashboard Page")

	public void DasboardTest() {

		objLogin = new LoginPage(driver);

		// login to application
		objLogin.login("Admin", "admin123");

		// go the dashboard page
		objDashboardPage = new DashboardPage(driver);

		// Verify dashboard page
		objDashboardPage.verifyQuickLaunchOptions();

	}

}

We can group tests with @Epic@Feature, and @Stories annotations. Click here to know more about other Allure annotations.

TestExecutionListener.class

We can add attachments to our reports by using @Attachment annotation. It can return String, byte [], etc.  I need to add @Listeners({ TestExecutionListener.class }) declaration at the top of the test classes. Click here to know more about other Allure annotations.

public class TestExecutionListener implements ITestListener {

	@Attachment(value = "Screenshot of {0}", type = "image/png")
	public byte[] saveScreenshot(String name, WebDriver driver) {
		return (byte[]) ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
	}

	@Override
	public void onTestFailure(ITestResult result) {
		saveScreenshot(result.getName(), BaseTest.driver);
	}

}

Step 5 – Create testng.xml for the project

TestNG.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name = "Allure Reports">
  <test name = "Login Page Tests">
    <classes>
          <class name = "com.example.TestNGAllureReportDemo.tests.LoginTests"/>
         
          </classes>
          </test> 
    <test name =" Dashboard Tests">   
    <classes> 
          <class name = "com.example.TestNGAllureReportDemo.tests.DashboardTests"/>
          </classes>
    </test>

</suite>

Step 6 – Run the Test and Generate Allure Report

To run the tests, use the below command

mvn clean test

In the below image, we can see that one test is failed and two passed out of three tests.

To create Allure Report, use the below command

allure serve

This will generate the beautiful Allure Test Report as shown below.

Allure Report Dashboard

Overview page hosts several default widgets representing basic characteristics of your project and test environment.

  1. Statistics – overall report statistics.
  2. Launches – if this report represents several test launches, statistics per launch will be shown here.
  3. Behaviors – information on results aggregated according to stories and features.
  4. Executors – information on test executors that were used to run the tests.
  5. History Trend – if tests accumulated some historical data, it’s trend will be calculated and shown on the graph.
  6. Environment – information on test environment.

Categories in Allure Report

Categories tab gives you the way to create custom defects classification to apply for test results. There are two categories of defects – Product Defects (failed tests) and Test Defects (broken tests).

Suites in Allure Report

On the Suites tab a standard structural representation of executed tests, grouped by suites and classes can be found.

Graphs in Allure Report

Graphs allow you to see different statistics collected from the test data: statuses breakdown or severity and duration diagrams.

Timeline in Allure Report

Timeline tab visualizes retrospective of tests execution, allure adaptors collect precise timings of tests, and here on this tab they are arranged accordingly to their sequential or parallel timing structure.

Behaviors of Allure Report

This tab groups test results according to Epic, Feature and Story tags.

Packages in Allure Report

Packages tab represents a tree-like layout of test results, grouped by different packages.

If you click on the i (hihlighted tab), it will show the test exection report in the below format.

Page Object Model without Page Factory in Selenium Webdriver

HOME

What is Page Object Model?

Page Object Model(POM) is an object design pattern in Selenium webdriver which tells how to organize the object repository. In this case, we refer to web elements as Objects. Page Object Model(POM) is not a Test Framework.

In the Page Object Model (POM), each web page is represented as a separate class. For example, consider HRM website. It has many web pages like Login , Dashboard , Assign Leave, Leave List, Timesheets, etc. Under this model, for each web page in the application, there should be a corresponding Page Class. This Page class will identify the WebElements of that web page and also contains Page methods that perform operations on those WebElements.

If a new web element is added or an existing web element is updated, then you can add or update that web element in object repository by navigating to class which has same name as webpage.

The object repository is independent of test cases, so we can use the same object repository for a different purpose with different tools. For example, we can integrate Page Object Model in Selenium with TestNG/JUnit for functional Testing and at the same time with JBehave/Cucumber for acceptance testing.

POM enhances test maintenance, readability and reducing code duplication.

In this tutorial, I’m creating a project using Page Object Model as Design Pattern and TestNG as the Test Automation Framework.

Steps to create a Page Object Model Project

  1. Download and Install Java on system
  2. Download and setup Eclipse IDE on system
  3. Setup Maven
  4. Create a new Maven Project
  5. Add dependencies to pom.xml
  6. Create Page Class for each page – LoginPage.Java and DashboardPage.java
  7. Create tests for each Page – BaseTests, LoginTests and DashboardTests
  8. Create a TestNG.XML
  9. Run the tests from TestNG.xml
  10. TestNG Report Generation

Step 1- Download and Install Java

Click here to know How to install Java. To check if Java is already installed on your machine, use the below command in the command line. This command will show the version of Java installed on your machine.

java -version

Step 2 – Download and setup Eclipse IDE on system

The Eclipse IDE (integrated development environment) provides strong support for Java developer. The Eclipse IDE for Java Developers distribution is designed to support standard Java development. It includes support for the Maven and Gradle build system and support for the Git version control system. Click here to know How to install Eclipse.

Step 3 – Setup Maven

To build a test framework, we need to add a number of dependencies to the project. It is very tedious and cumbersome process to add each dependency manually. So, to overcome this problem, we use a build management tool. Maven is a build management tool which is used to define project structure, dependencies, build, and test management. Click here to know How to install Maven.

To know if Maven is already installed or not on your machine, type this command in the command line. This command will show the version of Maven installed on your machine.

mvn -version

Step 4 – Create a new Maven Project

Click here to know How to create a Maven project

Below is the Maven project structure. Here,

Group Id – com.example
Artifact Id – pageobjectmodel_demo
Version – 0.0.1-SNAPSHOT
Package – com. example.pageobjectmodel_demo

Step 5 – Add dependencies to the pom.xml

I have added Selenium and TestNG dependencies.

<dependencies>
  
   <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>3.141.59</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.testng/testng -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>7.4.0</version>
      <scope>test</scope>
    </dependency>   
    
</dependencies>

Step 6 – Create Page Class for each page – LoginPage.Java and DashboardPage.java

I want to test 2 pages – Login and Dashboard. So, I’m creating 2 seperate class. Each class will contain its web elements and methods of that page.

LoginPage.Java

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class LoginPage {

	WebDriver driver;

	By userName = By.name("txtUsername");

	By password = By.name("txtPassword");

	By titleText = By.id("logInPanelHeading");

	By login = By.id("btnLogin");

	public LoginPage(WebDriver driver) {
		this.driver = driver;
	}

	// Set user name in textbox
	public void setUserName(String strUserName) {
		driver.findElement(userName).sendKeys(strUserName);
	}

	// Set password in password textbox
	public void setPassword(String strPassword) {
		driver.findElement(password).sendKeys(strPassword);
	}

	// Click on login button
	public void clickLogin() {
		driver.findElement(login).click();
	}

	// Get the title of Login Page
	public String getLoginTitle() {
		return driver.findElement(titleText).getText();
	}

	public void login(String strUserName, String strPasword) {

		// Fill user name
		this.setUserName(strUserName);

		// Fill password
		this.setPassword(strPasword);

		// Click Login button
		this.clickLogin();
	}
}

DashboardPage.java

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class DashboardPage {

	WebDriver driver;

	By homePageUserName = By.id("welcome");

	public DashboardPage(WebDriver driver) {
		this.driver = driver;

	}

	// Get the User name from Home Page
	public String getHomePageText() {
		return driver.findElement(homePageUserName).getText();
	}

}

Step 7 – Create tests for each Page – BaseTests, LoginTests and DashboardTests

Here, I have created 3 classes. BaseTest class to contain startUp and tearDown methods. These methods will run once before the after of every class. LoginTests and DashboardTests classes contain the tests related to LoginPage and DashboardPage respectively.

BaseTest

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;

import com.example.pageobjectmodel_demo.pages.DashboardPage;
import com.example.pageobjectmodel_demo.pages.LoginPage;

public class BaseTest {

	public static WebDriver driver;
	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@BeforeClass
	public void setup() {
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");
		driver = new FirefoxDriver();
		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
		driver.get("https://opensource-demo.orangehrmlive.com/");
	}

	@AfterClass
	public void close() {
		driver.close();
	}
}

LoginTests

import org.testng.Assert;
import org.testng.annotations.Test;

import com.example.pageobjectmodel_demo.pages.DashboardPage;
import com.example.pageobjectmodel_demo.pages.LoginPage;

public class LoginTests extends BaseTest {

	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@Test(priority = 0)
	public void loginTest() {

		// Create Login Page object
		objLogin = new LoginPage(driver);

		// Verify login page text
		String loginPageTitle = objLogin.getLoginTitle();
		Assert.assertTrue(loginPageTitle.contains("LOGIN Panel"));
	}

}

DashboardTests

import org.testng.Assert;
import org.testng.annotations.Test;

import com.example.pageobjectmodel_demo.pages.DashboardPage;
import com.example.pageobjectmodel_demo.pages.LoginPage;

public class DashboardTests extends BaseTest {

	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@Test(priority = 0)
	public void DasboardTest() {

		objLogin = new LoginPage(driver);

		// login to application
		objLogin.login("Admin", "admin123");

		// go the dashboard page
		objDashboardPage = new DashboardPage(driver);

		// Verify dashboard page
		Assert.assertTrue(objDashboardPage.getHomePageText().contains("Welcome"));
	}

}

Step 8 – Create a TestNG.XML

Here, I have mentioned 2 test classes. So, when I will run the tests from TestNG.xml, it will run the tests of both the classes. If will mention any one class, then the test of that particular class will be executed.

<?xml version = "1.0"encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name = "PageObjectModel">
  <test name = "PageObjectModel Tests">
    <classes>
          <class name = "com.example.pageobjectmodel_demo.tests.LoginTests"/>
          <class name = "com.example.pageobjectmodel_demo.tests.DashboardTests"/>
     </classes>  
   </test>
</suite>

Step 9 – Run the tests from TestNG.xml

Right click on TestNG.xml and select Run As TestNG Suite.

The execution status looks like as shown below.

Step 10 – TestNG Report Generation

Once the execution is finished, refresh the project. It will create a test-output folder containing various reports generated by TestNG. Below is the screenshot of the report folder.

Image of Index.html report

Image of emailable-report.html

Cheers! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Integration of Selenium with TestNG

HOME

In this tutorial, I’ll create a Framework for the testing of web applications using Selenium Webdriver with TestNG . This framework consists of:-

  1. Selenium
  2. Java 8 or above
  3. TestNG
  4. Maven

Steps to setup Cucumber Test Automation Framework with Selenium and TestNG

  1. Download and Install Java on system
  2. Download and setup Eclipse IDE on system
  3. Setup Maven
  4. Create a new Maven Project
  5. Add Selenium and TestNG dependencies to the project
  6. Create a Test file under src/test/java
  7. Run the tests from TestNG.xml
  8. TestNG Report Generation

Detailed Step Description

Step 1- Download and Install Java

Cucumber and Selenium needs Java to be installed on the system to run the tests. Click here to know How to install Java.

Step 2 – Download and setup Eclipse IDE on system

The Eclipse IDE (integrated development environment) provides strong support for Java developer which is needed to write Java code. Click here to know How to install Eclipse.

Step 3 – Setup Maven

To build a test framework, we need to add a number of dependencies to the project. It is very tedious and cumbersome process to add each dependency manually. So, to overcome this problem, we use a build management tool. Maven is a build management tool which is used to define project structure, dependencies, build, and test management. Click here to know How to install Maven.

Step 4 – Create a new Maven Project

Click here to know How to create a Maven project

Below is the Maven project structure. Here,

Group Id – com.example
Artifact Id – Selenium_TestNGDemo
Version – 0.0.1-SNAPSHOT
Package – com. example. Selenium_TestNGDemo

Step 5 – Add Selenium and TestNG dependencies to the project.

As this is a Maven project, we can add the dependencies in POM.xml as shown below.

 <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>3.141.59</version>
    </dependency>
    
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>7.4.0</version>
      <scope>test</scope>
    </dependency>


<!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-core -->
    <dependency>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest</artifactId>
      <version>2.2</version>
      <scope>test</scope>
    </dependency>

After addition of dependencies in pom.xml, Maven Dependencies folder will be updated automatically with all the JAR file related to the dependencies.

Step 6 – Create a Test file under src/test/java

@BeforeTest – methods under this annotation will be executed prior to the first test case in the TestNG file.

@AfterTest – methods under this annotation will be executed after all test cases in the TestNG file are executed.

@Test – The annotated method is a part of a test case.

Description –  You can describe your test case under the description, stating what it does.

description = "This test validates title of login functionality"

Priority – You can prioritize the order of your test methods by defining a priority. Based on the defined priority, the test shall execute in that order.

priority = 0
public class TestNG_Demo {

	WebDriver driver;

	@BeforeTest
	public void setUp() {
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");

		driver = new FirefoxDriver();
		driver.get("https://opensource-demo.orangehrmlive.com/");

		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
	}

	@Test(description = "This test validates title of login functionality", priority = 0)
	public void verifyLoginPage() {

		String expectedTitle = driver.findElement(By.xpath("//*[@id='logInPanelHeading']")).getText();

		System.out.println("Title :" + expectedTitle);
		assertTrue(expectedTitle.equalsIgnoreCase("LOGIN Panel"));
	}

	@Test(description = "This test validates  successful login to Home page", priority = 1)
	public void verifyHomePage() {

		System.out.println("Username Entered");
		driver.findElement(By.name("txtUsername")).sendKeys("Admin");

		System.out.println("Password Entered");
		driver.findElement(By.name("txtPassword")).sendKeys("admin123");

		driver.findElement(By.id("btnLogin")).submit();

		String newPageText = driver.findElement(By.id("welcome")).getText();
		System.out.println("newPageText :" + newPageText);
		assertThat(newPageText, containsString("Welcome"));
	}

	@AfterTest
	public void teardown() {

		driver.quit();
	}

}

Step 7 – Test Execution through TestNG

Go to Runner class and right click Run As TestNG Test. The tests will run as TestNG tests.

Step 8 – Run the tests from TestNG.xml

Create a TestNG.xml as shown below and run the tests as TestNG.

<?xml version = "1.0"encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name = "Suite1">
  <test name = "TestNG Demo">
    <classes>
          <class name = "com.example.Selenium_TestNGDemo.TestNG_Demo"/>
     </classes>  
   </test>
</suite>

Step 9 – TestNG Report Generation

TestNG generates various type of reports under test-output folder like emailable-report.html, index.html, testng-results.xml.

We are interested in ’emailable-report.html’ report. Open ’emailable-report.html’, as this is a html report open it with browser. Below image shows emailable-report.html.

TestNG also produce “index.html” report and it resides under test-output folder. Below image shows index.html report. This is the latest theme of the report.

The links present at the left side are clickable. I have clicked Times link and you can see the details on the right side.

Integration of Cucumber with Selenium and TestNG

HOME

Cucumber is a BDD Tool and Selenium Webdriver is use for the automation of web application. Imagine we need to build a test framework which can be used by business to understand the test scenarios and as well can test the web application. This can be achieved by integrating Cucumber with Selenium. I’m going to use TestNG as the Test Automation tool for assertions.

In this tutorial, I’ll create a BDD Framework for the testing of web applications using Selenium Webdriver with TestNG . This framework consists of:-

  1. Cucumber Java- 6.10.4
  2. Cucumber TestNG – 6.10.4
  3. Java 11
  4. TestNG – 7.4.0
  5. Maven – 3.8.1
  6. Selenium – 3.141.59

Steps to setup Cucumber Test Automation Framework with Selenium and TestNG

  1. Download and Install Java on system
  2. Download and setup Eclipse IDE on system
  3. Setup Maven
  4. Create a new Maven Project
  5. Create source folder – src/test/resources to create test scenarios in Feature file
  6. Add Selenium, TestNG and Cucumber dependencies to the project
  7. Add Maven Compiler Plugin
  8. Create a feature file under src/test/resources
  9. Create the Step Definition class or Glue Code
  10. Create a TestNG Cucumber Runner class
  11. Run the tests from TestNG Runner
  12. Run the tests from TestNG.xml
  13. Run the tests from Command Line
  14. Cucumber Report Generation
  15. TestNG Report Generation

Step 1- Download and Install Java

Cucumber and Selenium needs Java to be installed on the system to run the tests. Click here to know How to install Java.

Step 2 – Download and setup Eclipse IDE on system

The Eclipse IDE (integrated development environment) provides strong support for Java developer which is needed to write Java code. Click here to know How to install Eclipse.

Step 3 – Setup Maven

To build a test framework, we need to add a number of dependencies to the project. It is very tedious and cumbersome process to add each dependency manually. So, to overcome this problem, we use a build management tool. Maven is a build management tool which is used to define project structure, dependencies, build, and test management. Click here to know How to install Maven.

Step 4 – Create a new Maven Project

Click here to know How to create a Maven project

Below is the Maven project structure. Here,

Group Id – com.example
Artifact Id – Cucumber_TestNGDemo
Version – 0.0.1-SNAPSHOT
Package – com. example. Cucumber_TestNGDemo

Step 5 – Create source folder src/test/resources to create test scenarios in Feature file

When a new Maven Project is created, it has 2 folders – src/main/java and src/test/java as shown in below image. To create test scenarios, we need a new source folder called – src/test/resources. To create this folder, right click on your maven project ->select New ->Java and then Source Folder.

Step 6 – Add Selenium, TestNG and Cucumber dependencies to the project

Add below mentioned Selenium, TestNG, Hamcrest and Cucumber dependencies to the project.

 <dependencies>
  <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-java -->
    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-java</artifactId>
      <version>6.10.4</version>
    </dependency>
 

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>3.141.59</version>
    </dependency>
    
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>7.4.0</version>
      <scope>test</scope>
    </dependency>

<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-testng -->
    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-testng</artifactId>
      <version>6.10.4</version>
    </dependency>

<!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-core -->
    <dependency>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest</artifactId>
      <version>2.2</version>
      <scope>test</scope>
    </dependency>
    
</dependencies>

Step 7 – Add Maven Compiler Plugin

The compiler plugin is used to compile the source code of a Maven project. This plugin has two goals, which are already bound to specific phases of the default lifecycle:

  • compile – compile main source files
  • testCompile – compile test source files
<build>
     <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <version>3.7.0</version>
         <configuration>
           <source>11</source>
           <target>11</target>
            <encoding>UTF-8</encoding>          
         </configuration>
       </plugin>                
       </plugins>
   </build>

Step 8 – Create a feature file (LoginPage.feature) containing all the test scenerios under src/test/resources/features.

Feature file should be saved as an extension of .feature. The test scenarios in Feature file are written in Gherkins language. Add the test scenarios in this feature file. I have added sample test scenarios.

Feature: Login to HRM Application 
 
   @ValidCredentials
   Scenario: Login with valid credentials
     
    Given User is on Home page
    When User enters username as "Admin"
    And User enters password as "admin123"
    Then User should be able to login sucessfully

Step 9 – Create the stepdefinition class corresponding to the feature file to test the scenarios

public class LoginDefinition {

	WebDriver driver;

	@Before
	public void setUp() {
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");

		driver = new FirefoxDriver();

		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
	}

	@Given("User is on Home page")
	public void userOnHomePage() {

		driver.get("https://opensource-demo.orangehrmlive.com/");
	}

	@When("User enters username as {string}")
	public void entersUsername(String userName) throws InterruptedException {

		System.out.println("Username Entered");
		driver.findElement(By.name("txtUsername")).sendKeys(userName);

	}

	@When("User enters password as {string}")
	public void entersPassword(String passWord) throws InterruptedException {

		System.out.println("Password Entered");
		driver.findElement(By.name("txtPassword")).sendKeys(passWord);

		driver.findElement(By.id("btnLogin")).submit();
	}

	@Then("User should be able to login sucessfully")
	public void sucessfullLogin() throws InterruptedException {

		String newPageText = driver.findElement(By.id("welcome")).getText();
		System.out.println("newPageText :" + newPageText);
		assertThat(newPageText, containsString("Welcome"));

	}

	@After
	public void teardown() {

		driver.quit();
	}

}

assertThat() and containsString are imported from package:-

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;

Step 10 – Create a TestNG Cucumber Runner class to execute the test scenarios

We need to create a class called Runner class to run the tests. This class will use the TestNG annotation @RunWith(), which tells TestNG what is the test runner class.

package com.example.Cucumber_TestNGDemo.runner;

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;

@CucumberOptions(tags = "", features = "src/test/resources/features/Login.feature", glue = "com.example.Cucumber_TestNGDemo.definitions")

public class CucumberRunnerTest extends AbstractTestNGCucumberTests {

}

  • AbstractTestNGCucumberTests – Runs each cucumber scenario found in the features as separated test.

Step 11 – Test Execution through TestNG

Go to Runner class and right click Run As TestNG Test. The tests will run as TestNG tests.

This is how the execution console will look like.

Step 12 – Run the tests from TestNG.xml

Create a TestNG.xml as shown below and run the tests as TestNG.

<?xml version = "1.0"encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name = "Suite1">
  <test name = "Test Demo">
    <classes>
          <class name = "com.example.Cucumber_TestNGDemo.runner.CucumberRunnerTest"/>
     </classes>  
   </test>
</suite>

Step 13 – Run the tests from Command Line

Run the below command in command prompt to run t he tests and to get the test execution report.

mvn test

The execution screen looks like something as shown below.

Step 14 – Cucumber Report Generation

Add cucumber.properties under src/test/resources and add the below instruction in the file.

cucumber.publish.enabled=true

Below is the image of the Cucumber Report generated using Cucumber Service.

Step 15 – TestNG Report Generation

TestNG generates various type of reports under test-output folder like emailable-report.html, index.html, testng-results.xml.

We are interested in ’emailable-report.html’ report. Open ’emailable-report.html’, as this is a html report open it with browser. Below image shows emailable-report.html.

TestNG also produce “index.html” report and it resides under test-output folder. Below image shows index.html report.

Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!

How to set style in Excel in Java using Apache POI

HOME

In the previous tutorial, I have explained about How to add Formulas in Excel in Java. In this tutorial, I will explain How to customize the style of cells in Excel in Java using Apache POI.

I’m using Apache POI to write data to the excel file. To download and install Apache POI, refer here.

If you are using maven, then you need to add below dependency in pom.xml.

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.0.0</version>
</dependency>
   
   
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.0.0</version>
</dependency>

To know more about various interfaces and classes for managing Excel, please refer to this tutorial.

In the below example, I have an existing excel with the name of “EmployeeDetails.xlsx”.

Steps to Customize the style in Excel

Step 1 – Create a blank work and then a sheet with name Write_TestData.

XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Write_TestData");

Step 2- XSSFWorkbook and XSSFSheet are imported from the below consecutive packages.

import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;

Step 3 – Write data to the sheet. To know more about this part, refer this link.

Step 4 – Set the auto Size for column 0.

sheet.autoSizeColumn(0);

Step 5 – To create a cell style, we only need a reference to the excel workbook:

	CellStyle style = workbook.createCellStyle();

Step 6 – CellStyle is imported from package mentioned below.

import org.apache.poi.ss.usermodel.CellStyle;

Step 7 – To create font style and add attributes to this font

XSSFFont font = workbook.createFont();

Step 8 – XSSFFont is imported from below package

import org.apache.poi.xssf.usermodel.XSSFFont;

Step 9 – To set the Background Colour of the cell.

style.setFillForegroundColor(IndexedColors.BLUE_GREY.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);

Step 10 – BackgroundColor and FillPattern are imported from the below consecutive packages.

import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.FillPatternType;

Step 11 – Write data to an OutputStream. Use the below code to write output stream.

FileOutputStream out = new FileOutputStream(new File("Styled_EmployeeDetails.xlsx"));
workbook.write(out);

Below is the complete program to show various cell setyles for Row 0 (Header Row).

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;

import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelStyleExample {

	public static void main(String[] args) {

		try {
			// create blank workbook
			XSSFWorkbook workbook = new XSSFWorkbook();

			// Create a blank sheet
			XSSFSheet sheet = workbook.createSheet("Write_TestData");

			ArrayList<Object[]> data = new ArrayList<Object[]>();
			data.add(new String[] { "Name", "Id", "Salary" });
			data.add(new Object[] { "Jim Lawrence", "001A", 10000 });
			data.add(new Object[] { "Jack", "1001B", 40000 });
			data.add(new Object[] { "Tim", "2001C", 20000 });
			data.add(new Object[] { "Gina", "1004S", 30000 });

			// Iterate over data and write to sheet
			int rownum = 0;
			for (Object[] employeeDetails : data) {

				// Create Row
				XSSFRow row = sheet.createRow(rownum++);

				int cellnum = 0;
				for (Object obj : employeeDetails) {

					// Create cell
					XSSFCell cell = row.createCell(cellnum++);

					// Set value to cell
					if (obj instanceof String)
						cell.setCellValue((String) obj);
					else if (obj instanceof Double)
						cell.setCellValue((Double) obj);
					else if (obj instanceof Integer)
						cell.setCellValue((Integer) obj);

					// Set Column width to the maximum for Column 0
					sheet.autoSizeColumn(0);

					if (rownum == 1) {

						CellStyle style = null;

						// Creating a font
						XSSFFont font = workbook.createFont();

						font.setFontHeightInPoints((short) 10);
						font.setFontName("Verdana");
						font.setColor(IndexedColors.BLACK.getIndex());
						font.setBold(true);
						font.setItalic(false);

						// Creating cell Style
						style = workbook.createCellStyle();

						// Setting Foreground Colour
						style.setFillForegroundColor(IndexedColors.BLUE_GREY.getIndex());
						style.setFillPattern(FillPatternType.SOLID_FOREGROUND);

						// Setting Alignment of font
						style.setAlignment(HorizontalAlignment.CENTER);

						// Setting font to style
						style.setFont(font);

						// Setting cell style
						cell.setCellStyle(style);

					}
				}
			}

			// Write the workbook in file system
			FileOutputStream out = new FileOutputStream(new File("Styled_EmployeeDetails.xlsx"));
			workbook.write(out);

			System.out.println("Style of Excel is updated successfully");

			out.close();

			// Close workbook
			workbook.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

How to add Formulas in Excel in Java

HOME

In the previous tutorial, I have explained How to update data in existing excel in Java. In this Java Excel tutorial, I will explain how to create an Excel with formula in a Java program. Excel is very excellent in calculating formulas. The Apache POI library provides excellent support for working with formulas in Excel.

I’m using Apache POI to write data to the excel file. To download and install Apache POI, refer here.

If you are using maven, then you need to add below dependency in pom.xml.

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.0.0</version>
</dependency>
  
  
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.0.0</version>
</dependency>

To know about various Interfaces and Classes in Excel, please refer this link.

Below are the steps which explain how to add Formulas in Excel.

Step 1 – Create a blank workbook.

XSSFWorkbook workbook = new XSSFWorkbook();

Step 2 – Import XSSFWorkbook from package.

import org.apache.poi.xssf.usermodel.XSSFWorkbook;

Step 3 – Create a sheet and pass name of the sheet.

XSSFSheet sheet = workbook.createSheet("Calculate Salary");

Step 4 – Import XSSFSheet from package.

import org.apache.poi.xssf.usermodel.XSSFSheet;

Step 5 – Create a Row. A spreadsheet consists of rows and cells. It has a grid layout. I have created object called Header of XSSFRow.

	XSSFRow header = sheet.createRow(0);

Step 6 – Below syntax create new cells within the row at index 0 and set a string value for the cell.

header.createCell(0).setCellValue("Employee_Name");

Step 7 – Below syntax creates a cell at index 4 and sets formula for cell.

dataRow.createCell(4).setCellFormula("B2+C2+D2");

Step 8 – The following line of code sets formula for the cell at the row #1 and column #5 (remember index is 0-based):

In case the column (Cell) does not exist (but the row does), use the following code.

XSSFRow dataRow = sheet.createRow(1);
dataRow.createCell(5).setCellFormula("SUM(B2:C2)");

In the above line, note that you should make sure that the cell at position (1, 5) does exist, otherwise you get a NullPointerException.

Let us see a program where I have created a cell which contains the formula.

public class FormulaExample {

	public static void main(String[] args) {

		// Create object of XSSFWorkbook class
		XSSFWorkbook workbook = new XSSFWorkbook();

		// Create object of XSSFSheet class
		XSSFSheet sheet = workbook.createSheet("Calculate Salary");

		// Create Header row using XSSFRow class
		XSSFRow header = sheet.createRow(0);
		header.createCell(0).setCellValue("Employee_Name");
		header.createCell(1).setCellValue("Base_Salary");
		header.createCell(2).setCellValue("Variable_Pay");
		header.createCell(3).setCellValue("Other_Benefits");
		header.createCell(4).setCellValue("Total Salary");
		header.createCell(5).setCellValue("Base_Variable Salary");

		XSSFRow dataRow = sheet.createRow(1);
		dataRow.createCell(0).setCellValue("George");
		dataRow.createCell(1).setCellValue(5000);
		dataRow.createCell(2).setCellValue(650);
		dataRow.createCell(3).setCellValue(1200);

		// Set formula
		dataRow.createCell(4).setCellFormula("B2+C2+D2");
		dataRow.createCell(5).setCellFormula("SUM(B2:C2)");

		try {

			// Write the workbook in file system
			FileOutputStream out = new FileOutputStream(new File("Salary_Slip.xlsx"));
			workbook.write(out);
			out.close();
			System.out.println("Excel written successfully.");

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

		}
	}
}

That’s it! Well Done! Cheers!!

Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

isDisplayed, isSelected, isEnabled in Selenium

HOME

This tutorial describes how to check the state of a WebElement.

In this tutorial, we will learn isDisplayed, isEnabled, isSelected method in Selenium, and how to check the state of a WebElement. There are many methods which are used to determine the visibility scope for the web elements – isSelected(), isEnabled() and isDispalyed().

Many a time a test fails when we click on an element or enter text in a field. This is because the element is displayed or exist in DOM, but it does not exist on the web page.

WebDriver facilitates the user with the following methods to check the visibility of the web elements. These web elements can be buttons, drop boxes, checkboxes, radio buttons, labels etc.

  • isDisplayed()
  • isSelected()
  • isEnabled()
  1. Boolean isSelected(): This method determines if an element is selected or not. It returns true if the element is selected and false if it is not. It is widely used on check boxes, radio buttons and options in a select.

2. Boolean isDisplayed(): This method determines if an element is displayed or not. It returns true if the element is displayed and false if it is not. Advantage of this method is that it avoids parsing an elements style attribute.

3. Boolean isEnabled(): This method determines if an element is enabled or not. It returns true if element is enabled (All elements apart from disabled input elements) and false if otherwise.

Steps to follow to understand when an element isEnabled and isDisplayed.

  1. Launch the web browser and open the application under test – https://duckduckgo.com/
  2. Verify the web page title
  3. Verify if the “Search Box” is displayed
  4. Verify that the “Search Box” is enabled
  5. If Search Box is enabled, then search for text – Selenium
  6. Close the browser
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class VerifyConditionsDemo {

	public static void main(String[] args) {

		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");
		
WebDriver driver = new FirefoxDriver();

		// launch the firefox browser and open the application url
		driver.get("https://duckduckgo.com/");

		// maximize the browser window
		driver.manage().window().maximize();

		// declare and initialize the variable to store the expected title of the
		// webpage.
		String expectedTitle = "DuckDuckGo — Privacy, simplified.";

		// fetch the title of the web page and save it into a string variable
		String actualTitle = driver.getTitle();

		// compare the expected title of the page with the actual title of the page and
		// print the result
		if (expectedTitle.equals(actualTitle)) {
			System.out.println("Verification Pass- The correct title is displayed on the web page.");
		} else {
			System.out.println("Verification Failed - An incorrect title is displayed on the web page.");
		}

		// verify that the “Search" Box is displayed
		WebElement searchBox = driver.findElement(By.id("search_form_input_homepage"));
		if (searchBox.isDisplayed()) {
			System.out.println("Search Box is visible. Return: " + searchBox.isDisplayed());
		} else {
			System.out.println("Search Box is not visible. Return: " + searchBox.isDisplayed());
		}

		// verify that the “Search” Box is enabled
		if (searchBox.isEnabled()) {
			System.out.println("Search Box is enabled. Return: " + searchBox.isEnabled());
			searchBox.sendKeys("Selenium");
		} else {
			System.out.println("Search Box is not enabled. Return: " + searchBox.isEnabled());
		}

		System.out.println("Successful Execution of Test.");

		// close the web browser
		driver.close();

	}
}

Output
Verification Pass- The correct title is displayed on the web page.
Search Box is visible. Return: true
Search Box is enabled. Return: true
Successfull Execution of Test.

isSelected

Steps to follow to understand when an element is Selected or not.

  1. Launch the web browser and open the application under test – https://www.seleniumeasy.com/test/basic-radiobutton-demo.html
  2. Verify if first Radio Button (Male) is selected or not
  3. If first radio button is already selected, then select Radio Button 2, else vice versa.
  4. Print the value of selected Radio Button
  5. Print the value of selecting a Radio Button
  6. Close the browser

import java.util.List;
import java.util.concurrent.TimeUnit;

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

public class isSelectedDemo {

	public static void main(String[] args) {
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");

		FirefoxDriver driver = new FirefoxDriver();
		driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
		driver.get("https://www.seleniumeasy.com/test/basic-radiobutton-demo.html");

		List<WebElement> Radio_Options = driver.findElements(By.name("optradio"));

		// Create a boolean variable which will hold the value (True/False)
		boolean radio_value = false;

		// This statement will return True, in case of first Radio button is selected
		radio_value = Radio_Options.get(0).isSelected();

		// Identify if Radio Button 1 is selected or not. If Button 1 is already
		// selected, then select Button 2
		if (radio_value == true) {
			Radio_Options.get(1).click();
			System.out.println("Button Selected is :" + Radio_Options.get(1).getAttribute("value"));
		} else {
			Radio_Options.get(0).click();
			System.out.println("Button Selected is :" + Radio_Options.get(0).getAttribute("value"));
		}

		driver.findElement(By.id("buttoncheck")).click();
		String Button_Selected = driver.findElement(By.xpath("//*[@id='easycont']/div/div[2]/div[1]/div[2]/p[3]"))
				.getText();
		System.out.println("Get Checked Value is :" + Button_Selected);

		// close the web browser
		driver.close();
	}
}

That’s it! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!

How to write data in Excel in Java

HOME

This tutorial describes the steps to write data in Excel file in Java.

I’m using Apache POI to write data to the excel file. To download and install Apache POI, refer here.

In the previous tutorial, I have explained How to read data from Excel in Java.

Dependency:

If you are using maven, then you need to add below dependency in pom.xml.

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.0.0</version>
</dependency>
 
 
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.0.0</version>
</dependency>

Here are few classes which you need to aware of.

  • Workbook : This is high level class for representing excel workbook.
  • Sheet : This is high level class for representing excel sheet.
  • Row : This is high level class for representing excel row. It has methods which are related to row.
  • Cell: This is high level class for representing individual excel cell. It has methods which are related to cell for example : getDataType().

The basic steps for writing data into an excel file using Apache POI API are given below:

Step 1 – Create a blank workbook.

XSSFWorkbook wb = new XSSFWorkbook();

Step 2 – Import XSSFWorkbook from package.

import org.apache.poi.xssf.usermodel.XSSFWorkbook;

Step 3 – Create a sheet and pass name of the sheet.

XSSFSheet sheet = workbook.createSheet("Write_TestData");

Step 4 – Import XSSFSheet from package.

import org.apache.poi.xssf.usermodel.XSSFSheet;

Step 5 – Create a Row. A spreadsheet consists of rows and cells. It has a grid layout.

 XSSFRow row = sheet.createRow(rownum++);

Step 6 – Import XSSFRow from package

import org.apache.poi.xssf.usermodel.XSSFRow;

Step 7 – Create cells in a row. A row is a collection of cells. When you enter data in the sheet, it is always stored in the cell.

 XSSFCell cell = row.createCell(cellnum++);

Step 8 – Import XSSFCell from package.

 XSSFCell cell = row.createCell(cellnum++);

Step 9 – Write data to an OutputStream. Use the below code to write output stream.

FileOutputStream out = new FileOutputStream(new File("EmployeeDetails.xlsx"));
workbook.write(out);

Step 10 – Close the output stream.

out.close();

Below is the entire code for writing the data in an excel in Java.

package com.example.seleniumdemo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ReadWriteExcelFile {

	public static void main(String[] args) throws IOException {

		// create blank workbook
		XSSFWorkbook workbook = new XSSFWorkbook();

		// Create a blank sheet
		XSSFSheet sheet = workbook.createSheet("Write_TestData");

		ArrayList<Object[]> data = new ArrayList<Object[]>();
		data.add(new String[] { "Name", "Id", "Salary" });
		data.add(new Object[] { "Jim", "001A", 10000 });
		data.add(new Object[] { "Jack", "1001B", 40000 });
		data.add(new Object[] { "Tim", "2001C", 20000 });
		data.add(new Object[] { "Gina", "1004S", 30000 });

		// Iterate over data and write to sheet
		int rownum = 0;
		for (Object[] employeeDetails : data) {

			// Create Row
			XSSFRow row = sheet.createRow(rownum++);

			int cellnum = 0;
			for (Object obj : employeeDetails) {

				// Create cell
				XSSFCell cell = row.createCell(cellnum++);

				// Set value to cell
				if (obj instanceof String)
					cell.setCellValue((String) obj);
				else if (obj instanceof Double)
					cell.setCellValue((Double) obj);
				else if (obj instanceof Integer)
					cell.setCellValue((Integer) obj);
			}
		}
		try {

			// Write the workbook in file system
			FileOutputStream out = new FileOutputStream(new File("EmployeeDetails.xlsx"));
			workbook.write(out);
			out.close();
			System.out.println("EmployeeDetails.xlsx has been created successfully");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			workbook.close();
		}
	}

}

That’s it! We have written data in Excel.

Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!