Understanding SQL Injection: Types and Prevention

HOME

String username = request.getParameter("username");
String forename = request.getParameter("forename");

String sql = "SELECT * FROM users WHERE username = '" + username + "' AND forename = '" + forename + "'";

Connection conn = DriverManager.getConnection(url, username, forename);
Statement stmt = conn.createStatement();
ResultSet result = stmt.executeQuery(sql);
if (result.next()) {
    // User is authenticated
    String status = result.getString("success");
    System.out.println("Login to the application");
} else {
    // Authentication failed
  System.out.println("Unable to Login");
}

SELECT * FROM users WHERE username = 'admin'  AND forename = 'admin';

SELECT * FROM users WHERE username = 'admin'  -- AND forename = 'admin';

SELECT * FROM users WHERE username = 'admin'

String username = request.getParameter("username");
String forename = request.getParameter("forename");

String sql = "SELECT * FROM users WHERE username = ? AND forename = ?";

Connection conn = DriverManager.getConnection(url, username, forename);
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1, username);
preparedStatement.setString(2, forename);
ResultSet result = preparedStatement.executeQuery();
if (result.next()) {
    // User is authenticated
       String status = result.getString("success");
       System.out.println("Login to the application");
} else {
    // Authentication failed
    System.out.println("Unable to Login");
}

SELECT ProductName, ProductDescription, ProductCost
FROM Products
WHERE ProductId = '100' UNION SELECT Username, Password FROM Users;

Mastering CSV File Handling in Java with OpenCSV

HOME

<dependency>
            <groupId>com.opencsv</groupId>
            <artifactId>opencsv</artifactId>
            <version>5.10</version>
</dependency>

// https://mvnrepository.com/artifact/com.opencsv/opencsv
implementation group: 'com.opencsv', name: 'opencsv', version: '5.10'

  FileReader fileReader = new FileReader(filePath);
CSVReader csvReader = new CSVReader(fileReader);
List<String[]> records = csvReader.readAll();
  for (String[] record : records) {
                for (String field : record) {
                    System.out.print(field + " ");
                }
                System.out.println();
         }

package org.example;

import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;

import java.io.FileReader;
import java.io.IOException;
import java.util.List;

public class CSVReader_Demo {

    public static void main(String[] args) {

        String filePath = "C:\\Users\\Documents\\csv_test.csv";

        try {

            FileReader fileReader = new FileReader(filePath);
            CSVReader csvReader = new CSVReader(fileReader);
            List<String[]> records = csvReader.readAll();
            for (String[] record : records) {
                for (String field : record) {
                    System.out.print(field + " ");
                }
                System.out.println();
            }
        } catch (IOException | CsvException e) {
            System.err.println("Error reading CSV file: " + e.getMessage());
        }
    }
}

CSVReader csvReader = new CSVReaderBuilder(fileReader)
                    .withSkipLines(1)
                    .build();

package org.example;

import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.exceptions.CsvException;

import java.io.FileReader;
import java.io.IOException;
import java.util.List;

public class CSVReader_LineSkip_Demo {

    public static void main(String[] args) {

        String filePath = "C:\\Users\\Documents\\csv_test.csv";

        try {
            FileReader fileReader = new FileReader(filePath);
            CSVReader csvReader = new CSVReaderBuilder(fileReader)
                    .withSkipLines(1)
                    .build();

            List<String[]> records = csvReader.readAll();
            for (String[] record : records) {
                for (String field : record) {
                    System.out.print(field + " ");
                }
                System.out.println();
            }
        } catch (IOException | CsvException e) {
            System.err.println("Error reading CSV file: " + e.getMessage());
        }
    }
}

CSVParser csvParser = new CSVParserBuilder().withSeparator(',').build();
CSVReader csvReader = new CSVReaderBuilder(fileReader).withCSVParser(csvParser).build();
package org.example;

import com.opencsv.CSVParser;
import com.opencsv.CSVParserBuilder;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.exceptions.CsvException;

import java.io.FileReader;
import java.io.IOException;
import java.util.List;

public class CSVReader_Seperator_Demo {

    public static void main(String[] args) {

        String filePath = "C:\\Users\\Documents\\csv_test.csv";

        try {
            FileReader fileReader = new FileReader(filePath);
            CSVParser csvParser = new CSVParserBuilder().withSeparator(',').build();
            CSVReader csvReader = new CSVReaderBuilder(fileReader).withCSVParser(csvParser).build();

            List<String[]> records = csvReader.readAll();
            for (String[] record : records) {
                for (String field : record) {
                    System.out.print(field + " ");
                }
                System.out.println();
            }
        } catch (IOException | CsvException e) {
            System.err.println("Error reading CSV file: " + e.getMessage());
        }
    }
}

Step-by-Step HTML Parsing with Jsoup Examples

HOME

Table of Contents

<!DOCTYPE html>
<html>
<head>
    <title>Login Page</title>
</head>
<body>
    <h1>Welcome to My Website</h1>
    <p>This is a paragraph of text.</p>
    <a href="https://qaautomation.expert">Visit QA Automation Expert</a>
</body>
</html>

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.19.1</version>
</dependency>

// https://mvnrepository.com/artifact/org.jsoup/jsoup
implementation("org.jsoup:jsoup:1.19.1")

package com.example;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.File;
import java.io.IOException;

public class Read_HTMLString {

    public static void main(String[] args) {

        String htmlString = "<html><head><title>HTML Scrapping</title></head>"
                + "<body>This page is demo HTML Page. This page is used for web scrapping.</body></html>";
        Document document = Jsoup.parse(htmlString);
        System.out.println("Title : " + document.title());
        System.out.println("Body: " + document.body().text());
    }

String htmlString = "<html><head><title>HTML Scrapping</title></head>"
                + "<body>This page is demo HTML Page. This page is used for web scrapping.</body></html>";

Document document = Jsoup.parse(htmlString);
System.out.println("Title : " + document.title());
System.out.println("Body: " + document.body().text());

package com.example;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.File;
import java.io.IOException;

public class Read_HTMLFile {

    public static void main(String args[]) {
        Document document = null;
        try {
            document = Jsoup.parse(new File("C:\\Users\\vibha\\OneDrive\\Desktop\\Login.html"), "ISO-8859-1");
        } catch (IOException e) {
            e.printStackTrace();
        }

        String title = document.title();
        String divClass = document.getElementById("login").className();

        System.out.println("Jsoup can also parse HTML file directly");
        System.out.println("Title : " + title);
        System.out.println("Class of div tag : " + divClass);
        System.out.println("Heading: " + document.select("h1").text());
        System.out.println("Paragraph: " + document.select("p").text());
    }
}

document = Jsoup.parse(new File("C:\\Users\\vibha\\OneDrive\\Desktop\\Login.html"), "ISO-8859-1");
String divClass = document.getElementById("login").className();
System.out.println("Heading: " + document.select("h1").text());

package com.example;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;

public class Read_URL {

    public static void main(String[] args) throws IOException {
        String url = "http://qaautomation.expert";
        Document document = Jsoup.connect(url).get();
        System.out.println("Title: " + document.title());

        Elements links = document.select("a[href]"); // Select all <a> tags with href attribute
        for (Element link : links) {
            System.out.println("Link: " + link.attr("href"));
            System.out.println("Text: " + link.text());
        }
    }

}

 Document document = Jsoup.connect(url).get();
System.out.println("Title: " + document.title());
Elements links = document.select("a[href]");

How to install node.js on windows 11

HOME

node -v

npm -v

Advance Selenium Multiple Choice Questions – MCQ2

HOME








WebDriver driver = new ChromeDriver();
driver.get("https://www.example.com");
WebElement element = driver.findElement(By.id("submitButton"));
element.click();

WebDriver driver = new ChromeDriver();
driver.get("https://www.example.com");
List<WebElement> links = driver.findElements(By.tagName("a"));
System.out.println("Number of links: " + links.size());

WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("elementId")));

driver.switchTo().___.accept();

WebElement dropdown = driver.findElement(By.id("dropdown"));
Select select = new Select(dropdown);
select.___("Option 1");

Actions actions = new Actions(driver);
WebElement element = driver.findElement(By.id("elementId"));
actions.contextClick(element).perform();

File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("path/to/screenshot.png"));

driver.switchTo().___("frameNameOrId");

WebElement inputField = driver.findElement(By.id("inputField"));
inputField.sendKeys("test data");
inputField.sendKeys(Keys.TAB);

driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

WebElement table = driver.findElement(By.id("tableId"));
List<WebElement> rows = table.findElements(By.tagName("tr"));
WebElement firstCell = rows.get(0).findElements(By.tagName("td")).get(0);
System.out.println(firstCell.getText());

driver.manage().___();

Cookie cookie = new Cookie("name", "value");
driver.manage().___(cookie);

Select dropdown = new Select(driver.findElement(By.id("dropdownId")));
List<WebElement> options = dropdown.___();


try {
    WebElement element = driver.findElement(By.id("submit"));
    element.click();
} catch (NoSuchElementException e) {
    System.out.println("Element not found.");
}


Multiple Choice Questions for Security Testing on Web Application

HOME

























Run ChainTest Report on Docker

HOME

docker-compose -f docker-compose-h2.yml up

# chaintest configuration
chaintest.project.name= ChaninTest Report with Cucumber and TestNG

# generators:
## chainlp
chaintest.generator.chainlp.enabled=true
chaintest.generator.chainlp.class-name=com.aventstack.chaintest.generator.ChainLPGenerator
chaintest.generator.chainlp.host.url=http://localhost/
chaintest.generator.chainlp.client.request-timeout-s=30
chaintest.generator.chainlp.client.expect-continue=false
chaintest.generator.chainlp.client.max-retries=3
mvn clean test

ChainTest Report with Selenium and JUnit5

HOME

<dependency>
      <groupId>com.aventstack</groupId>
      <artifactId>chaintest-junit5</artifactId>
      <version>${chaintest.version}</version>
</dependency>

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

  <groupId>com.example</groupId>
  <artifactId>ChainTestReport_JUnit5_Demo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

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

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <selenium.version>4.21.0</selenium.version>
    <chaintest.version>1.0.11</chaintest.version>
    <junit.jupiter.engine.version>5.11.0-M2</junit.jupiter.engine.version>
    <junit.jupiter.api.version>5.11.0-M2</junit.jupiter.api.version>
    <junit.jupiter.params.version>5.11.0-M2</junit.jupiter.params.version>
    <maven.compiler.plugin.version>3.13.0</maven.compiler.plugin.version>
    <maven.compiler.source.version>17</maven.compiler.source.version>
    <maven.compiler.target.version>17</maven.compiler.target.version>
    <maven.surefire.plugin.version>3.2.5</maven.surefire.plugin.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
  </properties>

  <dependencies>

    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>${selenium.version}</version>
    </dependency>

    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>${junit.jupiter.engine.version}</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>${junit.jupiter.api.version}</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-params</artifactId>
      <version>${junit.jupiter.params.version}</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>com.aventstack</groupId>
      <artifactId>chaintest-junit5</artifactId>
      <version>${chaintest.version}</version>
    </dependency>

  </dependencies>

  <build>
    <plugins>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${maven.surefire.plugin.version}</version>

        <dependencies>
          <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.jupiter.engine.version}</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>

</project>

package com.example;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;

public class BasePage {
    public WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver,this);
    }

}

package com.example;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

public class LoginPage extends BasePage {

    public LoginPage(WebDriver driver) {
        super(driver);

    }

    @FindBy(name = "username")
    public WebElement userName;

    @FindBy(name = "password")
    public WebElement password;

    @FindBy(xpath = "//*[@type='submit']")
    public WebElement loginBtn;

    @FindBy(xpath = "//*[@id='flash']")
    public WebElement errorMessage;

    public void login(String strUserName, String strPassword) {
        userName.sendKeys(strUserName);
        password.sendKeys(strPassword);
        loginBtn.click();
    }

    public String getErrorMessage() {
        return errorMessage.getText();
    }

}
package com.example;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

public class SecurePage extends BasePage {

    public SecurePage(WebDriver driver) {
        super(driver);

    }

    @FindBy(xpath = "//*[@id='flash']")
    public WebElement securePageTitle;

    public String getSecurePageTitle() {
        return securePageTitle.getText();
    }

}
package com.example;

import com.aventstack.chaintest.plugins.ChainTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.TestWatcher;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import java.time.Duration;

@ExtendWith(ChainTestExecutionCallback.class)
public class BaseTests implements TestWatcher {

    public static WebDriver driver;
    public final static int TIMEOUT = 10;

    @BeforeEach
    public void setup() {
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--remote-allow-origins=*");
        options.addArguments("--no-sandbox");
        options.addArguments("--disable-dev-shm-usage");
        driver = new ChromeDriver(options);

        driver.manage().window().maximize();
        driver.get("https://the-internet.herokuapp.com/login");
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(TIMEOUT));
    }

    @AfterEach
    void tearDown() {
        driver.quit();
    }

}

package com.example;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class LoginPageTests extends BaseTests {

    String actualLoginPageTitle;
    String actualErrorMessage;
    String actualSecurePageTitle;
    
    @Test
    public void verifyPageTitle() {

        actualLoginPageTitle = driver.getTitle();
        
        // Verify Page Title - Fail
        Assertions.assertEquals("The Internet !!",actualLoginPageTitle);

    }

    @Test
    public void invalidCredentials() {

        LoginPage loginPage = new LoginPage(driver);
        loginPage.login("tomsmith", "happy!");
        actualErrorMessage = loginPage.getErrorMessage();

        // Verify Error Message
        Assertions.assertTrue(actualErrorMessage.contains("Your password is invalid!"));

    }

    @Test
    public void validLogin() {

        LoginPage loginPage = new LoginPage(driver);
        loginPage.login("tomsmith", "SuperSecretPassword!");

        SecurePage securePage = new SecurePage(driver);
        actualSecurePageTitle = securePage.getSecurePageTitle();

        // Verify Home Page
        Assertions.assertTrue(actualSecurePageTitle.contains("You logged into a secure area!"));

    }
}

# chaintest configuration
chaintest.project.name= ChaninTest Report with Selenium and JUnit5

# storage
chaintest.storage.service.enabled=false
# [azure-blob, aws-s3]
chaintest.storage.service=azure-blob
# s3 bucket or azure container name
chaintest.storage.service.container-name=

# generators:
## chainlp
chaintest.generator.chainlp.enabled=true
chaintest.generator.chainlp.class-name=com.aventstack.chaintest.generator.ChainLPGenerator
chaintest.generator.chainlp.host.url=http://localhost/
chaintest.generator.chainlp.client.request-timeout-s=30
chaintest.generator.chainlp.client.expect-continue=false
chaintest.generator.chainlp.client.max-retries=3

## simple
chaintest.generator.simple.enabled=true
chaintest.generator.simple.document-title=chaintest
chaintest.generator.simple.class-name=com.aventstack.chaintest.generator.ChainTestSimpleGenerator
chaintest.generator.simple.output-file=target/chaintest/Index.html
chaintest.generator.simple.offline=false
chaintest.generator.simple.dark-theme=true
chaintest.generator.simple.datetime-format=yyyy-MM-dd hh:mm:ss a
chaintest.generator.simple.js=
chaintest.generator.simple.css=

## email
chaintest.generator.email.enabled=true
chaintest.generator.email.class-name=com.aventstack.chaintest.generator.ChainTestEmailGenerator
chaintest.generator.email.output-file=target/chaintest/Email.html
chaintest.generator.email.datetime-format=yyyy-MM-dd hh:mm:ss a

This report contains the high level summary of the test execution.

mvn clean test

How to install Desktop Docker on Windows 11

HOME

The current image has no alternative text. The file name is: image-34.png

wsl --version

wsl --install

docker --version

 docker pull nginx

 docker login -u my-user-name (using real username) 

ChainTest Report with Cucumber and TestNG

HOME

<dependency>
      <groupId>com.aventstack</groupId>
      <artifactId>chaintest-cucumber-jvm</artifactId>
      <version>${chaintest.cucumberjvm.version}</version>
      <scope>provided</scope>
 </dependency>

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

  <groupId>com.example</groupId>
  <artifactId>ChainTestReport_Cucumber_TestNG_Demo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

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

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <cucumber.version>7.18.1</cucumber.version>
    <selenium.version>4.25.0</selenium.version>
    <testng.version>7.10.2</testng.version>
    <chaintest.cucumberjvm.version>1.0.11</chaintest.cucumberjvm.version>
    <apache.common.version>2.4</apache.common.version>
    <maven.compiler.plugin.version>3.13.0</maven.compiler.plugin.version>
    <maven.surefire.plugin.version>3.3.1</maven.surefire.plugin.version>
    <maven.compiler.source.version>17</maven.compiler.source.version>
    <maven.compiler.target.version>17</maven.compiler.target.version>
    <maven.cucumber.reporting.version>5.8.2</maven.cucumber.reporting.version>
  </properties>

  <dependencies>

    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-java</artifactId>
      <version>${cucumber.version}</version>
    </dependency>

    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-testng</artifactId>
      <version>${cucumber.version}</version>
      <scope>test</scope>
    </dependency>

    <!-- Selenium -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>${selenium.version}</version>
    </dependency>

    <!-- TestNG -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>${testng.version}</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>com.aventstack</groupId>
      <artifactId>chaintest-cucumber-jvm</artifactId>
      <version>${chaintest.cucumberjvm.version}</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven.compiler.plugin.version}</version>
        <configuration>
          <source>${maven.compiler.source.version}</source>
          <target>${maven.compiler.target.version}</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${maven.surefire.plugin.version}</version>
        <configuration>
          <testFailureIgnore>true</testFailureIgnore>
          <suiteXmlFiles>
            <suiteXmlFile>testng.xml</suiteXmlFile>
          </suiteXmlFiles>
        </configuration>
      </plugin>

    </plugins>
  </build>
</project>

Feature: Login to HRM Application

  Background:
    Given User is on HRMLogin page "https://opensource-demo.orangehrmlive.com/"

  @ValidCredentials
  Scenario: Login with valid credentials

    When User enters username as "Admin" and password as "admin123"
    Then User should be able to login successfully and new page open

  @InvalidCredentials
  Scenario Outline: Login with invalid credentials

    When User enters username as "<username>" and password as "<password>"
    Then User should be able to see error message "<errorMessage>"

    Examples:
      | username   | password  | errorMessage           |
      | Admin      | admin12$$ | Invalid credentials    |
      | admin$$    | admin123  | Invalid credentials    |
      | abc123     | xyz$$     | Invalid credentials    |

  @MissingUsername
  Scenario: Login with blank username - FailedTest

    When User enters username as " " and password as "admin123"
    Then User should be able to see a message "Required1" below Username

package com.example.actions;

import com.example.locators.LoginPageLocators;
import org.openqa.selenium.support.PageFactory;
import com.example.utils.HelperClass;


public class LoginPageActions {

    LoginPageLocators loginPageLocators = null;

    public LoginPageActions() {

        this.loginPageLocators = new LoginPageLocators();
        PageFactory.initElements(HelperClass.getDriver(), loginPageLocators);
    }

    // Get the error message when username is blank
    public String getMissingUsernameText() {
        return loginPageLocators.missingUsernameErrorMessage.getText();
    }

    // Get the Error Message
    public String getErrorMessage() {
        return loginPageLocators.errorMessage.getText();
    }

    public void login(String strUserName, String strPassword) {

        // Fill user name
        loginPageLocators.userName.sendKeys(strUserName);

        // Fill password
        loginPageLocators.password.sendKeys(strPassword);

        // Click Login button
        loginPageLocators.login.click();

    }
}

package com.example.actions;

import com.example.locators.HomePageLocators;
import org.openqa.selenium.support.PageFactory;
import com.example.utils.HelperClass;

public class HomePageActions {

    HomePageLocators homePageLocators = null;

    public HomePageActions() {

        this.homePageLocators = new HomePageLocators();
        PageFactory.initElements(HelperClass.getDriver(),homePageLocators);
    }

    public String getHomePageText() {
        System.out.println("Heading :" + homePageLocators.homePageUserName.getText());
        return homePageLocators.homePageUserName.getText();
    }

}
package com.example.locators;

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

public class LoginPageLocators {

    @FindBy(name = "username")
    public WebElement userName;

    @FindBy(name = "password")
    public WebElement password;

    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/form/div[1]/div/span")
    public WebElement missingUsernameErrorMessage;

    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/form/div[3]/button")
    public WebElement login;

    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/div/div[1]/div[1]/p")
    public  WebElement errorMessage;

}

package com.example.locators;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

public class HomePageLocators {

    @FindBy(xpath = "//span[@class='oxd-topbar-header-breadcrumb']/h6")

    public  WebElement homePageUserName;

}

package com.example.utils;

import java.time.Duration;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class HelperClass {

    private static HelperClass helperClass;

    private static WebDriver driver;
    public final static int TIMEOUT = 5;

    private HelperClass() {

        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");
        driver = new ChromeDriver(options);
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(TIMEOUT));
    }

    public static void openPage(String url) {
        driver.get(url);
    }

    public static WebDriver getDriver() {
        return driver;
    }

    public static void setUpDriver() {

        if (helperClass==null) {
            helperClass = new HelperClass();
        }
    }

    public static void tearDown() {

        if(driver!=null) {
            driver.quit();
        }

        helperClass = null;
    }

}

package com.example.definitions;

import com.example.actions.HomePageActions;
import com.example.actions.LoginPageActions;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.testng.Assert;
import com.example.utils.HelperClass;

public class LoginPageDefinitions {

    LoginPageActions objLogin = new LoginPageActions();
    HomePageActions objHomePage = new HomePageActions();

    @Given("User is on HRMLogin page {string}")
    public void loginTest(String url) {

        HelperClass.openPage(url);

    }

    @When("User enters username as {string} and password as {string}")
    public void goToHomePage(String userName, String passWord) {

        // login to application
        objLogin.login(userName, passWord);

    }

    @Then("User should be able to login successfully and new page open")
    public void verifyLogin() {

        // Verify home page
        Assert.assertTrue(objHomePage.getHomePageText().contains("Dashboard"));

    }

    @Then("User should be able to see error message {string}")
    public void verifyErrorMessage(String expectedErrorMessage) {

        // Verify error message
        Assert.assertEquals(objLogin.getErrorMessage(),expectedErrorMessage);

    }

    @Then("User should be able to see a message {string} below Username")
    public void verifyMissingUsernameMessage(String message) {

        Assert.assertEquals(objLogin.getMissingUsernameText(),message);
    }

}

package com.example.definitions;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;

import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;
import com.example.utils.HelperClass;

public class Hooks {

    @Before
    public static void setUp() {

        HelperClass.setUpDriver();
    }

    @After
    public static void tearDown(Scenario scenario) {

        //validate if scenario has failed
        if(scenario.isFailed()) {
            final byte[] screenshot = ((TakesScreenshot) HelperClass.getDriver()).getScreenshotAs(OutputType.BYTES);
            scenario.attach(screenshot, "image/png", scenario.getName());
        }

        HelperClass.tearDown();
    }
}

package com.example.runner;

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

@CucumberOptions(features = "src/test/resources/features/LoginPage.feature",
        glue = "com.example.definitions",
        plugin = {
                "pretty",
                "com.aventstack.chaintest.plugins.ChainTestCucumberListener:"
        }
)
public class RunnerTests extends AbstractTestNGCucumberTests {
}

@CucumberOptions(plugin = { 
  "com.aventstack.chaintest.plugins.ChainTestCucumberListener:" 
})

# chaintest configuration
chaintest.project.name= ChaninTest Report with Cucumber and TestNG

# generators:
## chainlp
chaintest.generator.chainlp.enabled=true
chaintest.generator.chainlp.class-name=com.aventstack.chaintest.generator.ChainLPGenerator
chaintest.generator.chainlp.host.url=http://localhost/
chaintest.generator.chainlp.client.request-timeout-s=30
chaintest.generator.chainlp.client.expect-continue=false
chaintest.generator.chainlp.client.max-retries=3

## simple
chaintest.generator.simple.enabled=true
chaintest.generator.simple.document-title=chaintest
chaintest.generator.simple.class-name=com.aventstack.chaintest.generator.ChainTestSimpleGenerator
chaintest.generator.simple.output-file=target/chaintest/Index.html
chaintest.generator.simple.offline=false
chaintest.generator.simple.dark-theme=true
chaintest.generator.simple.datetime-format=yyyy-MM-dd hh:mm:ss a
chaintest.generator.simple.js=
chaintest.generator.simple.css=

## email
chaintest.generator.email.enabled=true
chaintest.generator.email.class-name=com.aventstack.chaintest.generator.ChainTestEmailGenerator
chaintest.generator.email.output-file=target/chaintest/Email.html
chaintest.generator.email.datetime-format=yyyy-MM-dd hh:mm:ss a

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
    <test  name="Cucumber with TestNG Test">
        <classes>
            <class name="com.example.runner.RunnerTests"/>
        </classes>
    </test> <!-- Test -->
</suite> <!-- Suite -->

This report contains the high level summary of the test execution.

mvn clean test