0% found this document useful (0 votes)
6 views25 pages

Selenium Notes

The document outlines a Java-based automation framework using Selenium and TestNG, focusing on creating HTML reports with screenshots using the ExtentReports library. It includes classes for managing reports, handling WebDriver instances, and implementing the Page Object Model for better test maintainability. Key features include capturing screenshots on test failures, a singleton pattern for report management, and a structured approach to test execution and reporting.

Uploaded by

rahulbadhe630
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views25 pages

Selenium Notes

The document outlines a Java-based automation framework using Selenium and TestNG, focusing on creating HTML reports with screenshots using the ExtentReports library. It includes classes for managing reports, handling WebDriver instances, and implementing the Page Object Model for better test maintainability. Key features include capturing screenshots on test failures, a singleton pattern for report management, and a structured approach to test execution and reporting.

Uploaded by

rahulbadhe630
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 25

Session_4:-

Session_5:



Create HTML Reports with Screenshots

// File: utils/ExtentReportManager.java


package utils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.io.FileUtils; // Utility for


copying files
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import com.aventstack.extentreports.ExtentReports; // Main
ExtentReports reporting class
import com.aventstack.extentreports.ExtentTest; //
Represents a single test in report
import
com.aventstack.extentreports.reporter.ExtentSparkReporter; //
Reporter that generates an HTML report

/**
* ExtentReportManager
* -------------------
* Singleton helper to create and manage a single
ExtentReports instance for the test run,
* create test entries, and capture screenshots for attaching
into the report.
*/
public class ExtentReportManager {

// Single shared ExtentReports instance across the test run


(singleton pattern)
private static ExtentReports extent;

// (Optional) store the last created ExtentTest if you want a


global reference
private static ExtentTest test;

/**
* getReportinstance()
* --------------------
* Returns the single ExtentReports instance. If it hasn't been
created yet,
* create it (lazy initialization). This prevents creating
multiple report files
* when tests call this helper multiple times.
*/
public static ExtentReports getReportinstance() {
if (extent == null) { // Only create once
// Create a timestamp to make report file unique for
each run
String timestamp = new SimpleDateFormat("yyyy-MM-
dd HH-mm-ss").format(new Date());
// Define the path where the HTML report will be stored
String reportPath = "reports/ExtentReport_" +
timestamp + ".html";

// Create a Spark reporter (produces modern HTML


report)
ExtentSparkReporter reporter = new
ExtentSparkReporter(reportPath);
// Optional: configure document title and report name
shown in HTML
reporter.config().setDocumentTitle("Automation Test
Report");

reporter.config().setReportName("TestExecutionReport");

// Create ExtentReports object and attach the Spark


reporter to it
extent = new ExtentReports();
extent.attachReporter(reporter);
// You can also add system info like OS, tester name etc.
if needed:
// extent.setSystemInfo("Environment", "QA");
}
return extent;
}

/**
* createTest
* ----------
* Creates and returns an ExtentTest entry under the global
ExtentReports.
* Tests call this at the start to register themselves in the
report.
*
* @param testName - name that will appear in the report for
the test
* @return ExtentTest instance for logging steps and statuses
in the report
*/
public static ExtentTest createTest(String testName) {
test = getReportinstance().createTest(testName);
return test;
}

/**
* captureScreenshot
* -----------------
* Captures a screenshot using the provided WebDriver and
returns the path
* where the screenshot was saved. Test code can then
attach the path to the report.
*
* Note: This method expects the WebDriver to support
TakesScreenshot (ChromeDriver does).
*
* @param driver - WebDriver instance that will perform the
screenshot
* @param screenshotName - friendly name used to name
the screenshot file
* @return path to the saved screenshot (relative path), or
null on failure
*/
public static String captureScreenshot(WebDriver driver,
String screenshotName) {
try {
// Ask the driver to capture the screen and return a
temporary File reference
File src = ((TakesScreenshot)
driver).getScreenshotAs(OutputType.FILE);

// Where we want to copy the screenshot to


(screenshots folder)
String path = "screenshots/" + screenshotName +
".png";

// Use FileUtils to copy the temp screenshot file to our


desired path
FileUtils.copyFile(src, new File(path));
// Return the path so caller can attach it to the report
return path;
} catch (Exception e) {
// Print stack trace (in real projects log this instead)
e.printStackTrace();
return null; // Indicate failure to capture screenshot
}
}
}

--

// File: Base/BaseTest.java
package Base;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.ITestResult; // Provides test status
in @AfterMethod
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.MediaEntityBuilder; //
Helper to attach media like screenshots into report

import utils.ExtentReportManager;

/**
* BaseTest
* --------
* Base test class that test classes extend. Contains:
* - report setup/teardown (BeforeSuite/AfterSuite)
* - webdriver setup/teardown for each test
(BeforeMethod/AfterMethod)
* - common utilities for attaching screenshots on failures
*
* All test classes should extend this so they inherit WebDriver
and reporting behaviour.
*/
public class BaseTest {

// Protected driver so subclasses (tests & page objects) can


access it
protected WebDriver driver;

// Shared ExtentReports instance. Marked static so it's one


per JVM/test run.
protected static ExtentReports extent;
// Each test method can have its own ExtentTest to log steps
and status
protected ExtentTest test;

/**
* setupReport()
* -------------
* Runs once before the entire test suite. Initializes
ExtentReports (through our manager).
* This ensures we create a single report for the whole test
run.
*/
@BeforeSuite
public void setupReport() {
extent = ExtentReportManager.getReportinstance();
}

/**
* tearDownReport()
* ----------------
* Runs once after the entire test suite. Flushes reports so
generated HTML is written to disk.
*/
@AfterSuite
public void tearDownReprt() {
extent.flush(); // Write everything to the HTML report
}
/**
* setup()
* -------
* Runs before each @Test method. Responsible for
WebDriver initialization and navigating to base URL.
*
* Note: In real projects, prefer WebDriverManager or specify
chromedriver path via system property.
*/
@BeforeMethod
public void setup() {
// Create a new Chrome browser instance for the test
// (Assumes chromedriver executable is available in PATH,
or use WebDriverManager)
driver = new ChromeDriver();

// Maximize the browser window to avoid layout


differences between sizes
driver.manage().window().maximize();

// Navigate to the application login URL - this sets the


initial state for tests
driver.get("https://admin-demo.nopcommerce.com/login");
}

/**
* teardown()
* ----------
* Runs after each @Test method. Responsible for:
* - capturing screenshot & attaching to the report on test
failure
* - quitting the driver to free resources
*
* @param result - ITestResult gives information about test
result (PASS/FAIL/SKIP)
*/
@AfterMethod
public void teardown(ITestResult result) {
// If the test failed, capture screenshot and attach to
Extent report
if (result.getStatus() == ITestResult.FAILURE) {
// Capture screenshot and get the saved path
String screenshotPath =
ExtentReportManager.captureScreenshot(driver,
result.getName() + "_Failure");

// Log failure and attach screenshot to the Extent report


for this test
// Note: test variable should be set in the test method
(see LoginTest for example)
if (test != null && screenshotPath != null) {
test.fail("Test Failed.. check screenshot ",

MediaEntityBuilder.createScreenCaptureFromPath(screenshotPa
th).build());
}
}
// Always quit the browser if it was created to avoid
resource leaks
if (driver != null) {
driver.quit();
}
}

// Other common methods (e.g., getDriver(), wait helpers)


can be added here for reuse by tests/pages
}

--
// File: tests/LoginTest.java
package tests;

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

import Base.BaseTest;
import pages.LoginPage; // Page object for the login
page actions
import utils.ExtentReportManager;
import utils.Log; // Simple logging wrapper (below)

/**
* LoginTest
* ---------
* A sample test class that demonstrates:
* - creating an ExtentTest entry
* - interacting with a Page Object (LoginPage)
* - assertions to validate behavior
*
* It extends BaseTest and therefore inherits WebDriver + report
setup/teardown.
*/
public class LoginTest extends BaseTest {

/**
* testValidLogin()
* ----------------
* Example test that:
* 1. Creates a test entry in the Extent report
* 2. Uses a LoginPage page object to perform login steps
* 3. Asserts the page title to demonstrate a failing assertion
(intentional here)
*/
@Test
public void testValidLogin() {
// Log a friendly message externally (console/log file)
showing test start
Log.info("starting login test....");

// Create an ExtentTest entry in the report with a readable


name
// and store it in the BaseTest.test variable (inherited) so
teardown can attach screenshots to it
test = ExtentReportManager.createTest("Login Test");
// Add a step into the report to document the current
action
test.info("Navigating to the url...");

// Create the page object for login and pass the WebDriver
instance
// The page object contains methods to interact with UI
elements
LoginPage loginPage = new LoginPage(driver);

Log.info("Adding credentials");
test.info("adding credentials");

// Use page object's methods to enter username and


password
loginPage.enterUsername("[email protected]");
loginPage.enterPassword("admin");

test.info("clicking on login button");


// Click login button via page object
loginPage.clickLogin();

// Print current title to console for quick debugging


System.out.println("title of the page is " +
driver.getTitle());
test.info("verify page title");
// Assertion to validate page title. In your original code this
intentionally
// fails (to demonstrate screenshot capture). Update
expected title for real tests.
Assert.assertEquals(driver.getTitle(), "Just a
moment...123");

// If assertion passes, mark the test as passed in report


test.pass("login successful");
}
}

--

// File: pages/LoginPage.java
package pages;

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

/**
* LoginPage (Page Object)
* -----------------------
* Encapsulates locators and actions for the login page.
* This keeps test code clean and makes locator changes
localized in one place.
*/
public class LoginPage {
private WebDriver driver;

// Locators defined once (preferable to store By objects


rather than WebElement fields)
private By usernameLocator = By.id("Email");
private By passwordLocator = By.id("Password");
private By loginButtonLocator =
By.cssSelector("button[type='submit']");

// Constructor receives the WebDriver from the test and


stores it for page actions
public LoginPage(WebDriver driver) {
this.driver = driver;
}

// Enter username text into username field


public void enterUsername(String username) {
WebElement user = driver.findElement(usernameLocator);
user.clear();
user.sendKeys(username);
}

// Enter password into password field


public void enterPassword(String password) {
WebElement pass = driver.findElement(passwordLocator);
pass.clear();
pass.sendKeys(password);
}

// Click the login button


public void clickLogin() {
driver.findElement(loginButtonLocator).click();
}
}

--
// File: utils/Log.java
package utils;

/**
* Simple Log helper.
* In real projects use a logging framework like Log4j or SLF4J.
* This is a tiny wrapper to keep test code readable.
*/
public class Log {
public static void info(String message) {
// Simple console output - replace with proper logger in
real projects
System.out.println("[INFO] " + message);
}

public static void error(String message) {


System.err.println("[ERROR] " + message);
}
}

Quick notes / things to remember (use in interview)


 Singleton pattern for reports:
ExtentReportManager.getReportinstance() ensures a single
report object across the run. This avoids multiple files and
keeps all test logs under one HTML.
 Why screenshots on failure: We capture screenshots in
@AfterMethod when ITestResult shows failure. This
ensures you attach evidence of the browser state when a
test fails — extremely valuable for debugging.
 Page Object Model (POM): LoginPage holds locators
and actions; tests interact with methods (enterUsername,
clickLogin) rather than raw locators — better
maintainability.
 ExtentTest usage: Create a test entry at the start
(createTest) and use test.info() / test.pass() / test.fail() to
log steps and statuses. This produces readable HTML
reports.
 WebDriver lifecycle: @BeforeMethod creates a fresh
browser per test (isolated), and @AfterMethod quits it to
release resources.
 Where to improve (real-world):
o Use WebDriverManager to avoid manual
chromedriver handling.
o Use try/catch and proper logging in page methods.
o Parameterize base URL, credentials, and paths via
config.properties.
o Use TestNG @Parameters or @DataProvider for data-
driven tests.
o Add explicit waits (WebDriverWait) instead of relying
on implicit behavior.
7.How to use Page Factory in Selenium
Automation Framework-


 with PageFactory we can do this process
at one time using the @FindBy annotation

PageFactory is a class in selenium library


whenever we create the object of this
page class all the elements we have
declared in the page class then all the
 if you want ot initialised the element 100
times it will not search for 100 times but
only 1st time  then you can use as many
times as you want to
Selenium How to do Data Driven
Testing with Excel

You might also like