Jaspersoft reports server valid login and invalid login automation tutorial using Java-Selenium-Cucumber

Sadakar Pochampalli
JasperSoft BI Suite Tutorials - Sadakar Pochampalli )

Hi ,

This is an introductory article on automating the Jaspersoft reports server user activities. In this tutorial, you would learn how to effectively implement cucumber framework with java selenium for Jaspersoft server.

NOTE : 
1) Assuming, the reader should already have basic knowledge on all the software's or technologies mentioned below.

Software's used: 
1) Eclipse - Version: 2.3.0.v20191210-0610, Build id: I20191210-0610
2) Java 1.8
3) Maven build tool (default comes with Eclipse)
4) Cucumber 1.2.5
5) Cucumber Junit 1.2.5
6) Junit 4.12
7) Log4j 1.2.17
8) Google Chrome Browser : Version 80.0.3987.132 (Official Build) (64-bit)
9) Jaspersoft 7.5 Community Server

Automation flow architecture: 

Click on the image to view in non-scroll mode or to view the whole flow:




Note that you may have to download and point to correct chromedriver.exe driver. This demonstration is used chrome driver 80 versioned driver.

To get a copy of this demo, drop me a message at
LinkedIn


Video tutorial : Execution flow of the project
TBD

Steps: 
1) Creating a new Maven project

       File -> New -> Project -> Maven -> Maven Project
         (Jaspersoft Automation is the project  name)

2) Add log4j library to the project build path.
     
3) Ensure installed JRE points to locally installed jdk as shown in below image. 
    i.e., C:\Program Files\Java\jdk1.8.0_181


4)  The final project folder structure is as follows.

5) pom.xml

This will download and install the required libraries for the project. 

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>SMAPI_UI_POC</groupId>
  <artifactId>SMAPI_UI_POC</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>SMAPI_UI_POC</name>
  <description>SMAPI_UI_POC</description>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>

  <!--  cucumber-java -->
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-java -->
<dependency>
    <groupId>info.cukes</groupId>
    <artifactId>cucumber-java</artifactId>
    <version>1.2.5</version>
</dependency>

  <!--  cucumber-junit -->
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-junit -->

<dependency>
    <groupId>info.cukes</groupId>
    <artifactId>cucumber-junit</artifactId>
    <version>1.2.5</version>
</dependency>
<!--
<dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-junit</artifactId>
        <version>3.0.2</version>
        <scope>test</scope>
    </dependency>
-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</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>
  </dependencies>

  <build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

6) configuration.properties

Read values from properties file 

chrome_driver_path=D:\\chromedriver_80\\chromedriver.exe
jaspersoft_server_url=http://localhost:8080/jasperserver
user_id=jasperadmin
password=jasperadmin

7) 001_LoginJaspersoftServer.feature 

Cucumber feature file with valid and invalid login scenarios using Scenario Outline concept.
This code of language is called as Gherkin 

#Author: sadakar.pochampalli
# https://docs.katalon.com/katalon-studio/docs/cucumber-features-file.html#maintain-features-file
# https://riptutorial.com/cucumber/example/28790/scenario-outline
#https://www.tutorialspoint.com/cucumber/cucumber_scenario_outline.htm
@Login
Feature: Login feature

  As a admin user, I want to login to Jaspersoft Server so that
  I can run the reports, dashboards, create ad-hoc reports and etc.

  @ValidLogin
  Scenario Outline: Login with valid credentials
    Given Chrome browser and Jaspersoft login page
    When I enter User Id as "<UserId>" and Password as "<Password>"
    And I click on Login button
    Then I should be able to login successfully

    Examples:
      | UserId      | Password    |
      | jasperadmin | jasperadmin |
      | joeuser     | joeuser     |

  @InvalidLogin
  Scenario Outline: Login with Invalid credentials
    Given Chrome browser and Jaspersoft login page
    When I enter User Id as "<UserId>" and Password as "<Password>"
    And I click on Login button
    Then I should NOT be able to login successfully

    Examples:
      | UserId  | Password    |
      | baduser | jasperadmin |
      | joeuser | badpassword |
      | baduser | badpassword |

8) log4j.properties

DEBUG, ERROR, INFO logs displayed in file at : D:\\jasper_selenium\\jasper_selenium.logs

# Root logger option
log4j.rootLogger=DEBUG,stdout,dest1,ERROR,INFO

# Direct log messages to a log file
log4j.appender.dest1=org.apache.log4j.RollingFileAppender
log4j.appender.dest1.File=D:\\jasper_selenium\\jasper_selenium.logs
log4j.appender.dest1.MaxFileSize=10MB
log4j.appender.dest1.MaxBackupIndex=10
log4j.appender.dest1.layout=org.apache.log4j.PatternLayout
log4j.appender.dest1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.appender.dest1.Append=false

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

#ERROR
log4j.appender.ERROR=org.apache.log4j.RollingFileAppender
log4j.appender.ERROR.layout=org.apache.log4j.PatternLayout
log4j.appender.ERROR.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
#log4j.appender.ERROR.File=D:\\smapiui_logs\\smapi_ui.logs

#INFO
log4j.appender.INFO=org.apache.log4j.RollingFileAppender
log4j.appender.INFO.layout=org.apache.log4j.PatternLayout
log4j.appender.INFO.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
#log4j.appender.INFO.File=D:\\smapiui_logs\\smapi_ui.logs

9) Hooks.java - This class displays each scenario name with it's status. 

package com.sadakar.cucumber.common;
import com.sadakar.resource.utilities.Log;
import cucumber.api.Scenario;
import cucumber.api.java.After;
import cucumber.api.java.Before;

public class Hooks {
@Before(order=0)
public void before(Scenario scenario) {
    System.out.println("------------------------------");
    Log.info("------------------------------");
    Log.info("Scenario: '" + scenario.getName() );
    Log.info("******************************");
    System.out.println("Starting - " + scenario.getName());
    System.out.println("------------------------------");
}
@After(order=0)
public void after(Scenario scenario) {
    System.out.println("------------------------------");
    Log.info("Scenario: '" + scenario.getName() + "' has status " + scenario.getStatus());
    Log.info("******************************");
    Log.info("------------------------------");
    System.out.println(scenario.getName() + " Status - " + scenario.getStatus());
    System.out.println("------------------------------");
}
}

10) CucumberRunner.java

In this class, give path for the features, glue code, which scenarios to test/run and cucumber plugins such as reports in various formats

package com.sadakar.cucumber.runner;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions
(
features="classpath:features",
tags="@ValidLogin,@InvalidLogin",
glue={"com.sadakar.cucumber.stepdefinitions/","com.sadakar.cucumber.common"},
plugin = { "pretty", "json:target/cucumber-reports/Cucumber.json",
"junit:target/cucumber-reports/Cucumber.xml",
"html:target/cucumber-reports"},
monochrome = true
)
public class CucumberRunner {

}

11) LoginToJaspersoft.java

In this class define the step definitions for the scenarios. This code is called glue code. Wherever required, add the wait, sleep statements based on the logon speed of your jaspersoft server. 

package com.sadakar.cucumber.stepdefinitions;

import com.sadakar.resource.utilities.Log;
import com.sadakar.selenium.common.BasePage;
import com.sadakar.selenium.common.CommonFunctions;
import cucumber.api.java.en.And;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import java.util.concurrent.TimeUnit;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;

public class LoginToJaspersoft extends BasePage{
CommonFunctions cf = new CommonFunctions();
@Given("^Chrome browser and Jaspersoft login page$")
public void chrome_browser_and_Jaspersoft_login_page() throws Throwable {
try {    
cf.initDriver();
cf.maximizeDriver();
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
cf.getJapsersoftURL();
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
}
catch(Exception e) {
Log.error("failed to open the Japsersoft URL or Login page"+e);
Assert.fail("failed to open the Japsersoft URL or Login page"+e);
}
}

@When("^I enter User Id as \"([^\"]*)\" and Password as \"([^\"]*)\"$")
public void i_enter_User_Id_as_and_Password_as(String arg1, String arg2) throws Throwable {
  Log.debug("Enter User Id");
  driver.findElement(By.xpath("//*[@id='j_username']")).sendKeys(arg1+Keys.TAB);
  Log.debug("Enter tab");
  Log.debug("Enter Password");
      driver.findElement(By.xpath("//*[@id='j_password_pseudo']")).sendKeys(arg2+Keys.TAB);
      Log.debug("Enter tab");
}
@And("^I click on Login button$")
public void i_click_on_Login_button() throws Throwable {
Log.debug("Click Login button");
      driver.findElement(By.xpath("//*[@id='submitButton']")).click();  
      Thread.sleep(5000);
}

@Then("^I should be able to login successfully$")
public void i_should_be_able_to_login_successfully() throws Throwable {
if(driver.getCurrentUrl().equalsIgnoreCase(
      "http://localhost:8080/jasperserver/flow.html?_flowId=searchFlow")){
         Log.debug("Login Successfull");
      } else { 
         Log.debug("Login NOT Success full");
         Assert.fail("Login NOT Success full");
      } 
driver.close(); 
driver.quit();
}
@Then("^I should NOT be able to login successfully$")
public void i_should_NOT_be_able_to_login_successfully() throws Throwable {
if(driver.getCurrentUrl().equalsIgnoreCase(
      "http://localhost:8080/jasperserver/login.html?error=1")){
         Log.debug("Invalid Login Successfull");
      } else { 
         Log.debug("Invalid Login NOT Success full");
         Assert.fail("Invalid Login NOT Success full");
      } 
driver.close(); 
driver.quit();
}
}

12) Log.java

package com.sadakar.resource.utilities;
import org.apache.log4j.Logger;
public class Log {

public static Logger log= Logger.getLogger(Log.class.getSimpleName());
//Logger log2 = Logger.getLogger("devpinoyLogger");

/**
* To print Log for the start test case
* @param startTestCaseMessage
*/
public static void startTestCase(String startTestScenario ) {
log.info("********************* " + "S_T_A_R_T" + " *********************");
log.info("********************* " + startTestScenario + " *********************");
}

/**
* This is to print Log for the ending of the test case
* @param endTestCaseMessage
*/
public static void endTestCase(String endTestScenario) {
log.info("********************* " + "-E---N---D-" + " *********************");
log.info("********************* " + endTestScenario + " *********************");
}

public static void info(String infoMessage) {
log.info(infoMessage);
}

public static void warn(String warnMessage) {
log.warn(warnMessage);
}

public static void error(String errorMessage) {
log.error(errorMessage);
}

public static void fatal(String fatalMessage) {
log.fatal(fatalMessage);
}

public static void debug(String debugMessage) {
log.debug(debugMessage);
}

}

13) PropertyManager.java

package com.sadakar.resource.utilities;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertyManager {
private static PropertyManager instance;
    private static final Object lock = new Object();
    private static String propertyFilePath=System.getProperty("user.dir") + "\\configuration.properties";    
    private static String jaspersoft_server_url;
    private static String chrome_driver_path;
    private static String user_id;
    private static String password;
    
    //Create a Singleton instance. We need only one instance of Property Manager.
    public static PropertyManager getInstance () {
        if (instance == null) {
            synchronized (lock) {
                instance = new PropertyManager();
                instance.loadData();
            }
        }
        return instance;
    }
    //Get all configuration data and assign to related fields.
    private void loadData() {
        //Declare a properties object
        Properties prop = new Properties();
        //Read configuration.properties file
        try {
            prop.load(new FileInputStream(propertyFilePath));
            //prop.load(this.getClass().getClassLoader().getResourceAsStream("configuration.properties"));
        } catch (IOException e) {
            System.out.println("Configuration properties file cannot be found");
        }
        //Get properties from configuration.properties
        jaspersoft_server_url = prop.getProperty("jaspersoft_server_url");
        chrome_driver_path=prop.getProperty("chrome_driver_path");
        user_id=prop.getProperty("user_id");
        password=prop.getProperty("password");

    }
    public String getAppMangtURL () {
      return jaspersoft_server_url;
    }
    public String getChormeDriverPath () {
        return chrome_driver_path;
      }
    
    public String getUserId () {
        return user_id;
      }
      public String getPassword () {
          return password;
        }
}

14) Basepage.java

package com.sadakar.selenium.common;
import org.openqa.selenium.WebDriver;

public class BasePage {
public  static WebDriver driver;
public static void main(String args[]){
}

}

15) CommonFunctions.java

package com.sadakar.selenium.common;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import com.sadakar.resource.utilities.Log;
import com.sadakar.resource.utilities.PropertyManager;

import org.openqa.selenium.PageLoadStrategy;
public class CommonFunctions extends BasePage{
String chromeDriverPath=PropertyManager.getInstance().getChormeDriverPath();
String appMangtURL = PropertyManager.getInstance().getAppMangtURL();

public void initDriver() {
Log.debug("finding chrome driver path");
System.setProperty("webdriver.chrome.driver",chromeDriverPath);
Log.debug("Chrome driver path found");
Log.debug("Initiate Chrome driver");
ChromeOptions options = new ChromeOptions();
        //options.addArguments("--headless");
        options.addArguments("--disable-gpu");
        options.setPageLoadStrategy(PageLoadStrategy.NONE);
        options.addArguments("--allow-insecure-localhost");
        options.addArguments("--allow-running-insecure-content");
        options.addArguments("--ignore-certificate-errors");
        options.addArguments("--no-sandbox");
        options.addArguments("--window-size=1280,1000");
        options.setCapability("acceptSslCerts", true);
        options.setCapability("acceptInsecureCerts", true);
        
driver = new ChromeDriver(options);
Log.debug("Chrome driver is being initiated");
}
public void maximizeDriver() {
Log.debug("Maximize Chrome Browser");
driver.manage().window().maximize();
Log.debug("Chrome Browser maximized");
}
public void getJapsersoftURL() {
Log.debug("Authenticating to Jaspersoft Reports Server");
//System.out.println("App magt URL="+appMangtURL);
//driver.get("http://management.myabilitynetwork.lab/");
        driver.get(appMangtURL);
        Log.debug("Enter User ID and Password");
}
public void closeDriver() {
Log.debug("Closing driver: Closing browser");
driver.close();
Log.debug("Driver is closed: Closed browser");
}
public void quitDriver() {
Log.debug("Closing driver session");
driver.quit();
Log.debug("Driver session is closed");
}

}

16) Cucumber reports




17) jasper_selenium.logs

2020-03-13 19:22:57 INFO  Log:30 - ------------------------------
2020-03-13 19:22:57 INFO  Log:30 - Scenario: 'Login with valid credentials
2020-03-13 19:22:57 INFO  Log:30 - ******************************
2020-03-13 19:22:57 DEBUG Log:46 - finding chrome driver path
2020-03-13 19:22:57 DEBUG Log:46 - Chrome driver path found
2020-03-13 19:22:57 DEBUG Log:46 - Initiate Chrome driver
2020-03-13 19:23:07 DEBUG Log:46 - Chrome driver is being initiated
2020-03-13 19:23:07 DEBUG Log:46 - Maximize Chrome Browser
2020-03-13 19:23:07 DEBUG Log:46 - Chrome Browser maximized
2020-03-13 19:23:07 DEBUG Log:46 - Authenticating to Jaspersoft Reports Server
2020-03-13 19:23:07 DEBUG Log:46 - Enter User ID and Password
2020-03-13 19:23:07 DEBUG Log:46 - Enter User Id
2020-03-13 19:23:08 DEBUG Log:46 - Enter tab
2020-03-13 19:23:08 DEBUG Log:46 - Enter Password
2020-03-13 19:23:08 DEBUG Log:46 - Enter tab
2020-03-13 19:23:08 DEBUG Log:46 - Click Login button
2020-03-13 19:23:14 DEBUG Log:46 - Login Successfull
2020-03-13 19:23:15 INFO  Log:30 - Scenario: 'Login with valid credentials' has status passed
2020-03-13 19:23:15 INFO  Log:30 - ******************************
2020-03-13 19:23:15 INFO  Log:30 - ------------------------------
2020-03-13 19:23:15 INFO  Log:30 - ------------------------------
2020-03-13 19:23:15 INFO  Log:30 - Scenario: 'Login with valid credentials
2020-03-13 19:23:15 INFO  Log:30 - ******************************
2020-03-13 19:23:15 DEBUG Log:46 - finding chrome driver path
2020-03-13 19:23:15 DEBUG Log:46 - Chrome driver path found
2020-03-13 19:23:15 DEBUG Log:46 - Initiate Chrome driver
2020-03-13 19:23:24 DEBUG Log:46 - Chrome driver is being initiated
2020-03-13 19:23:24 DEBUG Log:46 - Maximize Chrome Browser
2020-03-13 19:23:24 DEBUG Log:46 - Chrome Browser maximized
2020-03-13 19:23:24 DEBUG Log:46 - Authenticating to Jaspersoft Reports Server
2020-03-13 19:23:24 DEBUG Log:46 - Enter User ID and Password
2020-03-13 19:23:24 DEBUG Log:46 - Enter User Id
2020-03-13 19:23:25 DEBUG Log:46 - Enter tab
2020-03-13 19:23:25 DEBUG Log:46 - Enter Password
2020-03-13 19:23:25 DEBUG Log:46 - Enter tab
2020-03-13 19:23:25 DEBUG Log:46 - Click Login button
2020-03-13 19:23:30 DEBUG Log:46 - Login Successfull
2020-03-13 19:23:31 INFO  Log:30 - Scenario: 'Login with valid credentials' has status passed
2020-03-13 19:23:31 INFO  Log:30 - ******************************
2020-03-13 19:23:31 INFO  Log:30 - ------------------------------
2020-03-13 19:23:31 INFO  Log:30 - ------------------------------
2020-03-13 19:23:31 INFO  Log:30 - Scenario: 'Login with Invalid credentials
2020-03-13 19:23:31 INFO  Log:30 - ******************************
2020-03-13 19:23:31 DEBUG Log:46 - finding chrome driver path
2020-03-13 19:23:31 DEBUG Log:46 - Chrome driver path found
2020-03-13 19:23:31 DEBUG Log:46 - Initiate Chrome driver
2020-03-13 19:23:40 DEBUG Log:46 - Chrome driver is being initiated
2020-03-13 19:23:40 DEBUG Log:46 - Maximize Chrome Browser
2020-03-13 19:23:41 DEBUG Log:46 - Chrome Browser maximized
2020-03-13 19:23:41 DEBUG Log:46 - Authenticating to Jaspersoft Reports Server
2020-03-13 19:23:41 DEBUG Log:46 - Enter User ID and Password
2020-03-13 19:23:41 DEBUG Log:46 - Enter User Id
2020-03-13 19:23:42 DEBUG Log:46 - Enter tab
2020-03-13 19:23:42 DEBUG Log:46 - Enter Password
2020-03-13 19:23:42 DEBUG Log:46 - Enter tab
2020-03-13 19:23:42 DEBUG Log:46 - Click Login button
2020-03-13 19:23:47 DEBUG Log:46 - Invalid Login Successfull
2020-03-13 19:23:48 INFO  Log:30 - Scenario: 'Login with Invalid credentials' has status passed
2020-03-13 19:23:48 INFO  Log:30 - ******************************
2020-03-13 19:23:48 INFO  Log:30 - ------------------------------
2020-03-13 19:23:48 INFO  Log:30 - ------------------------------
2020-03-13 19:23:48 INFO  Log:30 - Scenario: 'Login with Invalid credentials
2020-03-13 19:23:48 INFO  Log:30 - ******************************
2020-03-13 19:23:48 DEBUG Log:46 - finding chrome driver path
2020-03-13 19:23:48 DEBUG Log:46 - Chrome driver path found
2020-03-13 19:23:48 DEBUG Log:46 - Initiate Chrome driver
2020-03-13 19:23:57 DEBUG Log:46 - Chrome driver is being initiated
2020-03-13 19:23:57 DEBUG Log:46 - Maximize Chrome Browser
2020-03-13 19:23:57 DEBUG Log:46 - Chrome Browser maximized
2020-03-13 19:23:57 DEBUG Log:46 - Authenticating to Jaspersoft Reports Server
2020-03-13 19:23:57 DEBUG Log:46 - Enter User ID and Password
2020-03-13 19:23:57 DEBUG Log:46 - Enter User Id
2020-03-13 19:23:58 DEBUG Log:46 - Enter tab
2020-03-13 19:23:58 DEBUG Log:46 - Enter Password
2020-03-13 19:23:58 DEBUG Log:46 - Enter tab
2020-03-13 19:23:58 DEBUG Log:46 - Click Login button
2020-03-13 19:24:03 DEBUG Log:46 - Invalid Login Successfull
2020-03-13 19:24:04 INFO  Log:30 - Scenario: 'Login with Invalid credentials' has status passed
2020-03-13 19:24:04 INFO  Log:30 - ******************************
2020-03-13 19:24:04 INFO  Log:30 - ------------------------------
2020-03-13 19:24:04 INFO  Log:30 - ------------------------------
2020-03-13 19:24:04 INFO  Log:30 - Scenario: 'Login with Invalid credentials
2020-03-13 19:24:04 INFO  Log:30 - ******************************
2020-03-13 19:24:04 DEBUG Log:46 - finding chrome driver path
2020-03-13 19:24:04 DEBUG Log:46 - Chrome driver path found
2020-03-13 19:24:04 DEBUG Log:46 - Initiate Chrome driver
2020-03-13 19:24:14 DEBUG Log:46 - Chrome driver is being initiated
2020-03-13 19:24:14 DEBUG Log:46 - Maximize Chrome Browser
2020-03-13 19:24:14 DEBUG Log:46 - Chrome Browser maximized
2020-03-13 19:24:14 DEBUG Log:46 - Authenticating to Jaspersoft Reports Server
2020-03-13 19:24:14 DEBUG Log:46 - Enter User ID and Password
2020-03-13 19:24:14 DEBUG Log:46 - Enter User Id
2020-03-13 19:24:15 DEBUG Log:46 - Enter tab
2020-03-13 19:24:15 DEBUG Log:46 - Enter Password
2020-03-13 19:24:15 DEBUG Log:46 - Enter tab
2020-03-13 19:24:15 DEBUG Log:46 - Click Login button
2020-03-13 19:24:20 DEBUG Log:46 - Invalid Login Successfull
2020-03-13 19:24:21 INFO  Log:30 - Scenario: 'Login with Invalid credentials' has status passed
2020-03-13 19:24:21 INFO  Log:30 - ******************************
2020-03-13 19:24:21 INFO  Log:30 - ------------------------------
Feedback