Handle Dynamic Webtable in Selenium

What is Web Table?
  • A table is made of rows and columns. When we create a table for a web page, that is called as a web table. In HTML, table is created using <table> tag. 
  • Web table is a HTML structure for creating rows and columns on a Web page.
Basic Structure of Web Table: Below given the basic structure of a webtable which is having 2 rows and 3 columns.
<table>
 <tbody>
  <tr>
     <th>Employee Name</th>
     <th>Designation</th> 
     <th>Salary</th>
   </tr>
  <tr>
     <td>John</td>
     <td>Software Tester</td>
     <td>50000</td>
  </tr>
  <tr>
     <td>Tony</td>
     <td>Sr. Software Tester</td>
     <td>100000</td>
  </tr>
 </tbody>
</table>

Web Table Types?
There are two types of HTML tables published on the web-
  • Static tables: Data is static i.e. Number of rows and columns are fixed.
  • Dynamic tables: Data is dynamic i.e. Number of rows and columns are NOT fixed.
We are going to handle following web table questions in this post.
  • How to get the table headers?
  • Count no of rows and column in a web table
  • Get value from particular column wrt given data
  • Conditional (get all employees > 40 yrs)
  • How to Print last row in a web table?
  • Get particular cell value
  • Get particular cell value using custom method
  • How to get all table data
  • How to get Particular Column
  • How to retrieve More Than One Column
Please refer the below programs to handle above questions:

Base Class: In this class, we are having setup method to launch the browser and some variables 
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class WebTableBaseClass {
 WebDriver driver;
 String xpathString2="//table";

 // test case#2,8
 List<WebElement> c;
 List<WebElement> r;
 
 // test case#3
 String empRole = "Software Engineer";
 int empPosColumn = 2;
 int empNameColumn = 1;

 // test case#4
 int empAge = 40;
 int empAgeColumn = 4;

 // test case#6
 int rowN = 2;
 int colN = 3;

 // test case#7
 public String getColValue(int row, int col) {
  WebElement colValue = driver
    .findElement(By.xpath(""+xpathString+"/tbody/tr[" + row + "]/td[" + col + "]"));
  return colValue.getText();
 }
 // test case#9
 int getcolNo = 2;

 // test case#10
 int noOfColumns = 3;

 // test case#11
 int firstColumnNo = 2;
 int secondColumnNo = 5;

 public void setup() {
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32 (1)\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.seleniumeasy.com/test/table-sort-search-demo.html");
  c = driver.findElements(By.xpath(""+xpathString+"/thead/tr/th"));
  r = driver.findElements(By.xpath(""+xpathString+"/tbody/tr"));
 }
}

TestClass: This is our test class and we have all our test cases in this class. This class extending the above BaseClass.
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;

public class WebtableDemo extends WebTableBaseClass {

 @Test(priority = 1, description = "Get the Table Headers")
 public void getTableHeaders() {
  setup();
  System.out.println("=========Get Table Headers======================");
  List<WebElement> allHeadersOfTable = driver.findElements(By.xpath(""+xpathString+"/thead/tr/th"));
  System.out.println("Headers in table are below:");
  System.out.println("Total headers found: " + allHeadersOfTable.size());
  for (WebElement header : allHeadersOfTable) {
   System.out.println(header.getText());
  }
  System.out.println("================================================");
 }

 @Test(priority = 2, description = "Count total Rows And Coulmns")
 public void countRowsAndCoulmns() {
  setup();
  System.out.println("=========countRowsAndCoulmns===================");
  // Total Columns are
  System.out.println("Total Columns: " + c.size());
  // Total Rows are
  System.out.println("Total Rows: " + r.size());
  System.out.println("================================================");
 }

 @Test(priority = 3, description = "Get the Employee Position whose designation is SW Engg.")
 public void getEmpPosition() {
  setup();
  System.out.println("=======Get All Emp Names of "+empRole+" position=======");
  for (int i = 1; i <= r.size(); i++) {
   WebElement posColumn = driver.findElement(By.xpath(""+xpathString+"/tbody/tr[" + i + "]/td["+empPosColumn+"]"));
   if (posColumn.getText().toLowerCase().equalsIgnoreCase(empRole)) {
    WebElement empNameColumn1 = driver
      .findElement(By.xpath(""+xpathString+"/tbody/tr[" + i + "]/td["+empNameColumn+"]"));
    System.out.println(empNameColumn1.getText());
   }
  }
  System.out.println("===================================================");
 }

 @Test(priority = 4, description = "Get the name of the employees Age>40")
 public void getAge() {
  setup();
  System.out.println("=======Get All Emp Names whose age>40===========");
  for (int i = 1; i <= r.size(); i++) {
   WebElement ageColumn = driver.findElement(By.xpath(""+xpathString+"/tbody/tr[" + i + "]/td["+empAgeColumn+"]"));
   if (Integer.parseInt(ageColumn.getText()) >= empAge) {
    WebElement empName = driver.findElement(By.xpath(""+xpathString+"/tbody/tr[" + i + "]/td["+empNameColumn+"]"));
    System.out.println(empName.getText());
   }
  }
  System.out.println("===================================================");
 }

 @Test(priority = 5, description = "Print the Last Row")
 public void printLastRow() {
  setup();
  System.out.println("================Get Last Row of table================");
  List<WebElement> columnOfLastRow = driver.findElements(By.xpath(""+xpathString+"/tbody/tr[last()]/td"));
  for (WebElement e : columnOfLastRow) {
   System.out.print(e.getText() + "   ");
  }
  System.out.println();
  System.out.println("===================================================");
 }

 @Test(priority = 6, description = "Get particular Cell Value")
 public void getCellValue() {
  setup();
  System.out.println("====Retrive cell value by providing row and column number========");
  WebElement colValue = driver
    .findElement(By.xpath(""+xpathString+"/tbody/tr[" + rowN + "]/td[" + colN + "]"));
  System.out.println("Cell Value : " + colValue.getText());
  System.out.println("===================================================");
 }

 @Test(priority = 7, description = "Get Cell Value By CustomMethod")
 public void getCellValueByCustomMethod() {
  setup();
  System.out.println("====Retrive cell value by providing row and column number========");
  System.out.println(getColValue(2, 3));
  System.out.println("===================================================");
 }

 @Test(priority = 8, description = "Get All TableData")
 public void getAllTableData() {
  setup();
  System.out.println("====================Retrive All table data============");
  for (int i = 1; i <= r.size(); i++) {

   for (int j = 1; j <= c.size(); j++) {

    System.out.print(
      driver.findElement(By.xpath(""+xpathString+"/tbody/tr[" + i + "]/td[" + j + "]")).getText()
        + "   ");
   }
   System.out.println();
   System.out.println();
  }
  System.out.println("===================================================");
 }

 @Test(priority = 9, description = "Get Particular Column")
 public void getParticularColumn() {
  setup();
  System.out.println("===========================get particular Column========================");
  for (int i = 1; i <= r.size(); i++) {
   WebElement element = driver
     .findElement(By.xpath(""+xpathString+"/tbody/tr[" + i + "]/td[" + getcolNo + "]"));
   System.out.println(element.getText());
  }
  System.out.println("===================================================");
 }

 @Test(priority = 10, description = "Retrive More Than One Column")
 public void retriveMoreThanOneColumn() {
  setup();
  System.out.println("===========retriveMoreThanOneColumns==========");
  for (int i = 1; i <= r.size(); i++) {

   for (int j = 1; j <= noOfColumns; j++) {

    System.out.print(
      driver.findElement(By.xpath(""+xpathString+"/tbody/tr[" + i + "]/td[" + j + "]")).getText()
        + "   ");
   }
   System.out.println();
  }
  System.out.println("===================================================");
 }
 @AfterMethod
 public void tearDown() {
  driver.close();
 }
}

Output: The output looks like below
=========Get Table Headers======================
Headers in table are below:
Total headers found: 6
Name
Position
Office
Age
Start date
Salary
================================================

=========countRowsAndCoulmns===================
Total Columns: 6
Total Rows: 10
================================================

=======Get All Emp Names of Software Engineer position=======
B. Greer
B. Wagner
===================================================

=======Get All Emp Names whose age>40===========
A. Cox
A. Ramos
B. Greer
B. Williamson
===================================================

================Get Last Row of table================
C. Vance   Pre-Sales Support   New York   21   Mon 12th Dec 11   $106,450/y   
===================================================

====Retrive cell value by providing row and column number========
Cell Value : London
===================================================

====Retrive cell value by providing row and column number========
London
===================================================

====================Retrive All table data============
A. Cox   Junior Technical Author   San Francisco   66   Mon 12th Jan 09   $86,000/y   

A. Ramos   Chief Executive Officer (CEO)   London   47   Fri 9th Oct 09   $1,200,000/y   

A. Satou   Accountant   Tokyo   33   Fri 28th Nov 08   $162,700/y   

B. Greer   Software Engineer   London   41   Sat 13th Oct 12   $132,000/y   

B. Wagner   Software Engineer   San Francisco   28   Tue 7th Jun 11   $206,850/y   

B. Williamson   Integration Specialist   New York   61   Sun 2nd Dec 12   $372,000/y   

C. Hurst   Javascript Developer   San Francisco   39   Tue 15th Sep 09   $205,500/y   

C. Kelly   Senior Javascript Developer   Edinburgh   22   Thu 29th Mar 12   $433,060/y   

C. Marshall   Regional Director   San Francisco   36   Thu 16th Oct 08   $470,600/y   

C. Vance   Pre-Sales Support   New York   21   Mon 12th Dec 11   $106,450/y   

===================================================

===========================get particular Column========================
Junior Technical Author
Chief Executive Officer (CEO)
Accountant
Software Engineer
Software Engineer
Integration Specialist
Javascript Developer
Senior Javascript Developer
Regional Director
Pre-Sales Support
===================================================

===========retriveMoreThanOneColumns==========
A. Cox   Junior Technical Author   San Francisco   
A. Ramos   Chief Executive Officer (CEO)   London   
A. Satou   Accountant   Tokyo   
B. Greer   Software Engineer   London   
B. Wagner   Software Engineer   San Francisco   
B. Williamson   Integration Specialist   New York   
C. Hurst   Javascript Developer   San Francisco   
C. Kelly   Senior Javascript Developer   Edinburgh   
C. Marshall   Regional Director   San Francisco   
C. Vance   Pre-Sales Support   New York   
===================================================

===============================================
    Default test
    Tests run: 10, Failures: 0, Skips: 0
===============================================

Please find the below YouTube video on Dynamic WebTable:
Part1:

Part2:


How To Run Selenium Tests In Headless Google Chrome

We are going to use ChromeOptions class to run out test case on Chrome Browser in HeadLess mode.
ChromeOptions is a Class to manage options specific to ChromeDriver.

Please refer below Program to run tests in headless mode using Chrome Driver.
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.testng.annotations.Test;

public class HeadlessChrome {
 @Test
 public void headlessTest() throws IOException {
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32 (1)\\chromedriver.exe");
  ChromeOptions chromeOptions= new ChromeOptions();
  chromeOptions.addArguments("headless");
  chromeOptions.addArguments("window-size=1200x600");
  WebDriver driver= new ChromeDriver(chromeOptions);
  driver.get("https://www.google.com/");
  System.out.println("Test Start");
  System.out.println("Google title is: "+driver.getTitle());
  System.out.println("Test End");
  TakesScreenshot takesScreenshot = (TakesScreenshot) driver;
  File source = takesScreenshot.getScreenshotAs(OutputType.FILE);
  FileUtils.copyFile(source, new File("D:\\Workspace_Eclipse\\WebDriverConcept3\\ScreenShot\\Headless.png"));
  driver.close(); 
 }
}

Output:


Test Start
Google title is: Google
Test End
PASSED: headlessTest

===============================================
    Default test
    Tests run: 1, Failures: 0, Skips: 0
===============================================

Please refer below YouTube video for more details:

How to take Full Page ScreenShot and ScreenShot of WebElement

In this post, we are going to learn, how we can capture Full Page ScreenShot and ScreenShot of a WebElement  using Third-party utility “Ashot” API.

We are going to cover the following points:
1. Full page screen shot using Ashot API.
2. ScreenShot of WebElement by Ashot API.
3. ScreenShot of WebElement by croping the image.

What is Ashot API?

Ashot is a third party utility by Yandex supported by Selenium WebDriver to capture the Screenshots. 

How to download and configure Ashot API in your project?
1.Using Maven: get the latest maven Dependency from https://mvnrepository.com/artifact/ru.yandex.qatools.ashot/ashot
and Copy the Dependency code and add to your pom.xml file
Example:
<dependency>
  <groupId>ru.yandex.qatools.ashot</groupId>
  <artifactId>ashot</artifactId>
  <version>1.5.3</version>
</dependency>

2.Manually without using any tool:
Download jar file from below location:

https://mvnrepository.com/artifact/ru.yandex.qatools.ashot/ashot
In Eclipse, right-click on the project -> go to properties -> Build Path -> Libraries -> Add External jars--> Select the jar file-->Apply and Close

1. Full page screen shot using Ashot API.
Step 1: Create an Ashot object. If you want a screenshot of the page bigger then the screen size, call the shootingStrategy() method before calling takeScreenshot() method to set up the policy. Then call a method takeScreenshot() passing the webdriver, for example,
Screenshot Screenshot = new AShot()
.shootingStrategy(ShootingStrategies.viewportPasting(500))
.takeScreenshot(driver);
Here 500 is scrolled out time in milliseconds, so for taking a screenshot, the program will scroll for each 500 msec.
Step 2: Now, get the image from the screenshot and write it to the file. You can provide the file type as jpg, png, etc.
ImageIO.write(Screenshot.getImage(), "png",
new File("D:\\Workspace_Eclipse\\WebDriverConcept3\\ScreenShot\\Ashot.png"));

Complete code given below:
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;
import ru.yandex.qatools.ashot.AShot;
import ru.yandex.qatools.ashot.Screenshot;
import ru.yandex.qatools.ashot.shooting.ShootingStrategies;

public class AshotTest1 {
 WebDriver driver;

 @Test
 public void setup() throws InterruptedException {
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.automationtestinginsider.com/p/selenium-vi.html");

  //Create the object of AShot() class and set image strategy by shootingStrategy method
     //and viewportPasting method and take screenshot using takeScreenshot method
  Screenshot Screenshot = new AShot()
    .shootingStrategy(ShootingStrategies.viewportPasting(500))
    .takeScreenshot(driver);

  //Copy the element screenshot to desired location
  try {
   ImageIO.write(Screenshot.getImage(), "png",
     new File("D:\\Workspace_Eclipse\\WebDriverConcept3\\ScreenShot\\Ashot.png"));
  } catch (IOException e) {
   e.getMessage();
  }
  
  driver.close();
 }
}

Output: You will get full-page screenshot of a page which is bigger than screen size.


2. ScreenShot of WebElement by Ashot API:  Below code given to take the screen shot of a webelement (Login Button) from OrangeHRM application using Ashot API.
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;
import ru.yandex.qatools.ashot.AShot;
import ru.yandex.qatools.ashot.Screenshot;
import ru.yandex.qatools.ashot.coordinates.WebDriverCoordsProvider;

public class AshotTest2 {
 WebDriver driver;

 @Test
 public void setup() throws InterruptedException {
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://opensource-demo.orangehrmlive.com/index.php/auth/validateCredentials");
  WebElement element = driver.findElement(By.id("btnLogin"));

  //Create the object of AShot() class and get the image co-ordinates 
  //by coordsProvider method and take screenshot using takeScreenshot method
  Screenshot screenshot = new AShot()
    .coordsProvider(new WebDriverCoordsProvider())
    .takeScreenshot(driver,element);

  //Copy the element screenshot to desired location
  try {
   ImageIO.write(screenshot.getImage(), "png",
     new File("D:\\Workspace_Eclipse\\WebDriverConcept3\\ScreenShot\\Ashot2.png"));
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

  driver.close();
 }
}

Output: Looks like below

3. ScreenShot of WebElement by croping the image: Below code given to take the screen shot of a webelement (Login Button) from WordPress application using Cropping technique.

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;

public class Test1 {

 WebDriver driver;

 @Test
 public void setup() throws IOException  {
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://s1.demo.opensourcecms.com/wordpress/wp-login.php?");
  WebElement element = driver.findElement(By.id("wp-submit"));

  // Get entire page screenshot
  File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        BufferedImage  fullImg = ImageIO.read(screenshot);
  // Get the location,height,width of element on the page
  Point point = element.getLocation();
      int eleWidth = element.getSize().getWidth();
  int eleHeight = element.getSize().getHeight();
  // Crop the entire page screenshot to get only element screenshot
  try {
   BufferedImage eleScreenshot= fullImg.getSubimage(point.getX(), point.getY(),
        eleWidth, eleHeight);
   ImageIO.write(eleScreenshot, "png", screenshot);
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.getMessage();
  }
  // Copy the element screenshot to desired location
  File screenshotLocation = new File("D:\\Workspace_Eclipse\\WebDriverConcept3\\ScreenShot\\Ashot3.png");
  FileUtils.copyFile(screenshot, screenshotLocation);
  // Close the browser
  driver.close();
 }
}

Output: Looks like below

Please refer below YouTube video for more details:



How to capture Screen Shot for failed test cases

In this post we will capture the screen shots in two ways:
1. By using @AfterMethod annotation method in test class.
2. By using TestNG listener ITestListener.

Let's have a look at the first method:
1. By using @AfterMethod annotation method in test class.

Utility Class:
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;

public class TakeScreenShot {
 
 public static void screenShot(WebDriver driver, String filename) {
  TakesScreenshot takesScreenshot = (TakesScreenshot) driver;
  File source = takesScreenshot.getScreenshotAs(OutputType.FILE);
  try {
   FileUtils.copyFile(source, new File(System.getProperty("user.dir")+"\\ScreenShot\\"+filename+".png"));
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.getMessage();
  }
 }
}

TestClass:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.utility.TakeScreenShot;

public class ScreenShotTest {
 WebDriver driver;

 @BeforeMethod
 public void setup() {
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.google.com/");
 }
 @Test
 public void testCase1() {
  driver.findElement(By.name("q")).sendKeys("ScreenShot Demo");
  Assert.assertTrue(false);
 }
 @Test
 public void testCase2() {
  Assert.assertTrue(true);
 }
 @AfterMethod
 public void tearDown(ITestResult result) {
  if(result.FAILURE==result.getStatus())
  {
   TakeScreenShot.screenShot(driver, result.getName());
  }
  driver.close();
 }
}

2. By using TestNG listener ITestListener.

BaseClass: We have created baseclass where we kept setup method to launch the browser and application and screenShot method to capture the screenshots
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class BaseClass {
 
 public static WebDriver driver;

 public void setup() {
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.google.com/");
 }
 public void screenShot(String filename) {
  String dateName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
  TakesScreenshot takesScreenshot = (TakesScreenshot) driver;
  File source = takesScreenshot.getScreenshotAs(OutputType.FILE);
  try {
   FileUtils.copyFile(source, new File(System.getProperty("user.dir")+"\\ScreenShot\\"+filename+"_"+dateName+".png"));
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.getMessage();
  }
 }
}

Utility Class: In ListenerClass we have classed screenShot method from base class. This class implements ITestListener
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
import com.base.BaseClass;

public class ListenerClass extends BaseClass implements ITestListener {

 public void onTestStart(ITestResult result) {
  // TODO Auto-generated method stub
 }

 public void onTestSuccess(ITestResult result) {
  // TODO Auto-generated method stub 
 }
 public void onTestFailure(ITestResult result) {
  screenShot(result.getName()); 
 }
 public void onTestSkipped(ITestResult result) {
  // TODO Auto-generated method stub
 }
 public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
  // TODO Auto-generated method stub 
 }
 public void onStart(ITestContext context) {
  // TODO Auto-generated method stub
 }

 public void onFinish(ITestContext context) {
  // TODO Auto-generated method stub
  
 }
}

We have two test classes here:
ScreenShotTest:
import org.openqa.selenium.By;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import com.base.BaseClass;

public class ScreenShotTest extends BaseClass {
 
 @Test
 public void testCase1() {
  setup();
  driver.findElement(By.name("q")).sendKeys("ScreenShot Demo");
  Assert.assertTrue(false);
 }
 @Test
 public void testCase2() {
  setup();
  Assert.assertTrue(false);
 }
 @AfterMethod
 public void tearDown() {
  driver.close();
 }
}

2nd TestClass:
import org.openqa.selenium.By;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import com.base.BaseClass;

public class TestClass extends BaseClass {
 
 @Test
 public void testCase3() {
  setup();
  driver.findElement(By.name("q")).sendKeys("ScreenShot Demo");
  Assert.assertTrue(true);
 }
 @Test
 public void testCase4() {
  setup();
  Assert.assertTrue(false);
 }
 
 @AfterMethod
 public void tearDown() {
  driver.close();
 }
}

TestNG.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<listeners>
<listener class-name="com.utility.ListenerClass"></listener>
</listeners>
  <test name="Test">
    <classes>
      <class name="com.testPackage.ScreenShotTest"/>
      <class name="com.testPackage.TestClass"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

Please refer below YouTube video for more details: