Selenium WebDriver – How To Query HTML Web Table

Overview:

As an automation engineer , often, we might have to find / interact with some web elements of a HTML Web Table based on certain conditions. There are various approaches to do that.  We will see how to use Java Streams to play with HTML tables.

Sample HTML Table:

I create a Simple HTML page with below table.

sample-table-1

 

Our requirement is to select check boxes based on some conditions like – DOB should match ’01/01/1970′ or Country should be ‘USA’ etc – basically any given condition at run time.

Filter Rows Using Java Streams:

  • First, I launch site as shown here.
WebDriver driver = new ChromeDriver();
driver.get("sample.html");
WebElement table = driver.findElement(By.tagName("table"));
  • Get the column names
List<String> columnNames = table.findElements(By.tagName("th"))   // get table headers
                                        .stream()
                                        .map(WebElement::getText)        // get the text
                                        .map(String::trim)               // trim - no space
                                        .collect(Collectors.toList());   // collect to a list
// columnNames prints [Row Index, Name, DOB, City, Country, Checkbox]
  • Do a mapping of column name and the corresponding index
Map<String, Integer> columnMap = IntStream.range(0, columnNames.size())
                                               .boxed()
                                               .collect(Collectors.toMap(columnNames::get, 
                                                                         Function.identity()));

//columnMap {Row Index=0, Name=1, DOB=2, City=3, Country=4, Checkbox=5}
  • Now we want to select all check boxes when the DOB is 01/01/1960
table.findElements(By.tagName("tr"))  //get all rows
             .stream()
             .skip(1)                 // skip first row as we do not need header
             .map(tr -> tr.findElements(By.tagName("td")))   // get all cells for each rows
             .filter(tds -> tds.get(columnMap.get("DOB")).getText().equals("01/01/1960"))   // find the row which has DOB as 01/01/1960
             .map(tds -> tds.get(columnMap.get("Checkbox")))   // get cell which contains checkbox
             .map(td -> td.findElement(By.tagName("input")))   // get checkbox
             .forEach(WebElement::click);                      // click checkbox
  • Our aim is to choose different filters at run time – so that appropriate check boxes can be selected. So, I create a function which accepts a Predicate – It is basically a filter.
private void filterRows(Predicate<List<WebElement>> compositeCheck){
        
        table.findElements(By.tagName("tr")) 
            .stream()
            .skip(1)        
            .map(tr -> tr.findElements(By.tagName("td"))) 
            .filter(compositeCheck)  // passed as argument
            .map(tds -> tds.get(columnMap.get("Checkbox"))) 
            .map(td -> td.findElement(By.tagName("input")))
            .forEach(WebElement::click);
        
}
  • We might want to include AND, OR conditions as well in our filters.  Lets create below conditions.
Predicate<List<WebElement>> dobCheck = (tds) -> tds.get(columnMap.get("DOB")).getText().equals("01/01/1960");   // check if DOB is '01/01/1960'
Predicate<List<WebElement>> countryCheck = (tds) -> tds.get(columnMap.get("Country")).getText().equals("USA");  // check Country is 'USA'
Predicate<List<WebElement>> cityCheck = (tds) -> tds.get(columnMap.get("City")).getText().equals("Oran");       // check City is 'Oran'
  • To select all the rows for which DOB is 01/01/1960 OR city is Oran – use the below Predicate for the filter.
dobCheck.or(cityCheck)

dobCheck-or-cityCheck

  • To select the rows DOB is 01/01/1960 AND country is USA
dobCheck.and(countryCheck)

dobCheck-and-countryCheck

  • Below check will select all the rows.
dobCheck.or(countryCheck).or(cityCheck)
  • If you have multiple columns and would like to create Predicate at run time, You can create a function which returns a Predicate.
private Predicate<List<WebElement>> getPredicate(String col, String text){
        return (tds) -> tds.get(columnMap.get(col)).getText().equals(text);
}

getPredicate("DOB", "01/01/1960").and(getPredicate("City", "Oran")) 

 

Happy Testing & Subscribe 🙂

 

 

Share This:

Categories: Articles, Framework, Selenium

Leave a Reply

Your email address will not be published. Required fields are marked *