What is web table?

A table is made of rows and columns. When we create a table for a web page, that is called a web table. An HTML table is defined with the <table> tag. A web table is an HTML structure for creating rows and columns on a Web page.

Each table row is defined with the <tr> tag. A table header is defined with the <th> tag. By default, table headings are bold and centered. A table data/cell is defined with the <td> tag.

There are two kinds of tables,

  • Non changing tables
  • Dynamic tables (loaded from DB, or shuffled based on requirement)
Select Website Field
Chercher.tech Future Technologies
facebook.com Social Media
selenium-webdriver.com Automation Testing
google.com Search Engine

Custom WebTable in WebdriverIO

WebElement interface provides methods to perform operations on the various webelements, we have a webdriverio layers over webdriver to handle the ajax and angular applications

webdriverIO provides helper classes to work with the web element which are formed HTML tags. Anyways WebdriverIO does not support the tables on the webpage or the &table> elements

We will be using functions from the WebElement to perform operations on Webtable, we will be considering the web table is formed using <table>, <tr>, <td> HTML tags.

WebTable Methods :

To access the details of the web table we may need to implement few methods like:

  • Accept WebTable element
  • Get the number of rows
  • Get the number of columns
  • Get the size of the table
  • Get all the data from a row
  • Get all the data from column
  • Get the total data
  • Verify Presence of Data
  • Get data from Specific cell
  • Click the checkbox based on the value given (your favorite)
Accept WebTable Element :

We need to accept the table element on which we are going to perform the operations. We will be accepting the web table as a parameter for the WebTable() method.

var WebTable = function(webTable) {
    this.methods = function() {

    };
  };
module.exports = new WebTable();

Get number of Rows :

Sometimes users may request the number of rows present in the table, in such cases, we should be able to give details. tr tags are used to form the table rows in HTML, so if we can get the number of tr present in our table element then we got our number of rows.

We have subtracted 1 from the total size because all the rows including the header are also formed using tr HTML tags, so we subtracted 1 to exclude the headers. We are returning the size to the calling method.

// get the number of rows present
this.megetRowCountthods = function(){
	console.log("Fetching number rows")
	return this.webTable.$$("tr").count() -1
}

Get number of Columns :

We can give the count of columns present in the table by counting the number of td HTML tags present in the table, td HTML tags are used to form the cells.

We have used xpath //tr[2]/td to find the number of columns, If we use //tr[1] then we may need to use th HTML tags as tr[1] point to headers and the header will not have the td tags.

// get the number of columns present
public getColumnCount(){
	return this.webTable.all(by.css("th")).count()
	// if you donot have header then above will not work
	// use this if no headre is there
	// return this.webTable.all(by.xpath("//tr[0]/td")).count()
}

Get the size of the table :

Few people may expect our WebTable element to give the details about the total size of the table instead of giving the number of rows, number of columns separately. In this case, we may need to return the Map of Key-Value pairs which contains the count of rows and columns.

Instead of creating a new method implementation we cab use the getRowCount, getColumnCount to get the row count and column count. This method returns a Map of values, Map consists of String as keys and Integer as Value.

// get the number of columns present
this.getColumnCount= function(){
	return this.webTable.all(by.css("th")).count()
	// if you donot have header then above will not work
	// use this if no header is there
	// return this.webTable.all(by.xpath("//tr[0]/td")).count()
}

Get all the data from a Row :

Sometimes users may request the WebTable class to get particular row values, we can get the row values by iterating all the td HTML elements present under that row.

This method gets all the td HTML elements from a specific row and iterates those elements to store the text from it. We would be adding the text into the list, so we can return the list at the end of the method.

We want to exclude the header and xpath index starts from 1, so we are adding +1 to the user passed value. We have thrown the exception when the user passes 0 as a value as all rows start from 1.

// get row data and return it as list
this.rowData = function(rowNumber){
	if(rowNumber == 0){
		throw new Error("Row number starts from 1");
	}
	rowNumber = rowNumber + 1;
	return this.webTable.$$("//tr["+rowNumber+"]/td").getText()
}

Get all the data from a Column :

Similar to a row, the user may need the values from a particular column. To get the values from the column we need to get all the td HTML elements based on the column number passed in the method.

In this case, we will be just iterating only cells, //tr/td avoids the headers so no need to perform any action regarding that, but we still have to throw exception when the user passes 0.

// get the column data and return as list in WebdriverIO
this.columnData = function(columnNumber){
	if(columnNumber == 0){
		throw new Error("Column number starts from 1");
	}
	columnNumber = columnNumber + 1;
	return this.webTable.$$("//tr/td["+columnNumber+"]").getText()
}

Get the total data :

When we design a web table in handling methods in WebdriverIO we must be in a position that we should be able to return all the data present in the table in Map format.

All the rows in an HTML table are formed using tr tags, and all the columns are formed using td tags. If there are 10 columns present under the row in a web table, which means there are 10 td tags are present under the tr tag

To get all the data from the table we have to iterate each and every row present under the web table, once we get the rows we must iterate the td tags present under that particular row

// get all the data from the table
this.describegetAllData = function(){
	return this.webTable.$$("td").getText()
}

Verify the presence of given data :

We also should give an option to the user to check whether a particular data is present in the table or not, we can use xpath to verify whether given data is present or not by using the text() function with the xpath in webdriverio

There could be more than one data matching, so we have used $$ function to find how many elements present. if one or more elements present this method returns true but this method returns false if the number of elements is 0

// verify presence of the text/data
this.presenceOfData = function(data){
	// verify the data by getting the size of the element matches based on the text/data passed
	return this.webTable.$$("//td[normalize-space(text())='"+data+"']")
	.size().then(function(dataSize){
		if(dataSize > 0){
			return true;
		}
		else{
			return false
		}
	})
}

Get data from Specific Cell :

We should return the data from the specific cell when the user requests it, we can do it from the right xpath.

We have to exclude the Header row for that we would be adding +1 to the row requested by the user.

// get the data from a specific cell
this.getCellData = function(rowNumber, columnNumber) {
	if(rowNumber == 0){
		throw new Error("Row number starts from 1");
	}
	rowNumber = rowNumber+1;
	let cellData = this.webTable.$$("//tr["+rowNumber+"]/td["+columnNumber+"]").getText();
	return cellData;
}

Click the checkbox based on the value given :

Handling dynamic table is not a big deal, the trick is with xpath. For example: If you want to click the checkbox related Chercher.tech

You have to find your target element(Chercher.tech), and you can find the check box now select the check box related to the Chercher.tech.

  • find the Chercher.tech using normalize-space xpath
  • Now navigate to its parent using ..
  • Check whether you have your text and the check box under the same parent if not use the .. again till you have both elements under the same parent, this concept is called as dependent and independent xpath</li>
  • Once you have them under the same parent now narrow down to check box using some of its properties like name id or tag
  • I am using tagname (input) as css selector in webdriverio to find the checkbox, if you have more than one checkbox you got to get your input element using the properties like normal xpath
  • Tada, you got the xpath now use it to find the element and click it.
  • I have not added, more features like verifying he checkbox is already selected or not, please do add features according to your need.

I have created dependent and independent xpath, please do learn it

// click checkbox with webdriverio
this.clickCheckBox = function(data){
	this.webTable.$$("//td[normalize-space(text())='"+data+"']/..//input").click()
}


Complete program for Custom Webelement 'WebTable'

var WebTable = function(webTable) {
    // get the number of rows present
    this.megetRowCountthods = function(){
        console.log("Fetching number rows")
        return this.webTable.$$("tr").count() -1
    }

    // get the number of columns present
    this.getColumnCount= function(){
        return this.webTable.all(by.css("th")).count()
        // if you donot have header then above will not work
        // use this if no header is there
        // return this.webTable.all(by.xpath("//tr[0]/td")).count()
    }

    // get row data and return it as list
    this.rowData = function(rowNumber){
        if(rowNumber == 0){
            throw new Error("Row number starts from 1");
        }
        rowNumber = rowNumber + 1;
        return this.webTable.$$("//tr["+rowNumber+"]/td").getText()
    }

    // get the column data and return as list in webdriverio
    this.columnData = function(columnNumber){
        if(columnNumber == 0){
            throw new Error("Column number starts from 1");
        }
        columnNumber = columnNumber + 1;
        return this.webTable.$$("//tr/td["+columnNumber+"]").getText()
    }
    // get all the data from the table
	this.describegetAllData = function(){
		return this.webTable.$$("td").getText()
    }

    // verify presence of the text/data
    this.presenceOfData = function(data){
        // verify the data by getting the size of the element matches based on the text/data passed
        return this.webTable.$$("//td[normalize-space(text())='"+data+"']")
        .size().then(function(dataSize){
            if(dataSize > 0){
                return true;
            }
            else{
                return false
            }
        })
    }
     // get the data from a specific cell
    this.getCellData = function(rowNumber, columnNumber) {
        if(rowNumber == 0){
            throw new Error("Row number starts from 1");
        }
        rowNumber = rowNumber+1;
        let cellData = this.webTable.$$("//tr["+rowNumber+"]/td["+columnNumber+"]").getText();
        return cellData;
    }
    // click checkbox with webdriverio
    this.clickCheckBox = function(data){
        this.webTable.$$("//td[normalize-space(text())='"+data+"']/..//input").click()
    }
  };
module.exports = new WebTable();

WebdriverIO Interview Questions

Test Custom WebTable :

We have to test our WebdriverIO Custom element before we use it in the framework, lets test it.

We will be using the table present in the top of this page. I hope the test code is pretty simple, please comment if you have trouble in understanding.

describe('webdriverio Typescript Demo', function() {
	it('Dynamic table in WebdriverIO ', function() {
		browser.url('https://chercher.tech/webdriverio/dynamic-webtable');
		browser.pause(1000)

		var webTable = new WebTable($("fixed-header"));
		console.log("No of rows : "+webTable.getRowCount())

		console.log("No of Columns : "+webTable.getColumnCount())

		console.log("No Of rows : " +webTable.getTableSize())

		console.log("Nof Of columns : " +webTable.getTableSize())

		console.log("Data in row : " +webTable.rowData(1))

		console.log("Data in Column : " +webTable.columnData(1))

		console.log("Cell data : " +webTable.getCellData(1, 2))

		console.log("Presence of data : "+webTable.presenceOfData("google"))

		console.log("Total data : " +webTable.getAllData())

		webTable.clickCheckBox("Chercher.tech")
	});
});

Capture Screenshot in webdriverio

0 results
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions