Join us on :

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. An HTML table is defined with the <table> tag. Web table is a HTML structure for creating rows and columns on a Web page.

ach 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 kind of tables,

  • Non changing tables
  • Dynamic tables (loaded from DB, or shuffled based on requirement)
Select Website Field

Custom WebTable in Selenium

WebElement interface provides methods to perform operations on the various webelements, we have webdriverio layer 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 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 WebTable we may need implement few methods like:

  • Accept WebTable element
  • Get number of rows
  • Get number of columns
  • Get the size of the table
  • Get all the data from a row
  • Get all the date 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 webtable as parameter for the WebTable() method.


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

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

Get number of Rows :

Sometimes user may request for 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 header are also formed using tr HTML tags, so we subtracted 1 to exclude the headers.We are returning the size to 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, tdHTML tags are used to form the cells.

We have used xpath //tr[2]/td for 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 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 out WebTable element to give the details about the total size of the table instead of giving number of rows, number of columns separately. In this case we may need to return the Map of Key Value pairs which contains count of rows and columns.

Instead of creating new method implementation we cab use the getRowCount, getColumnCount to get the row count and column count. This methods returns a Map of values, Map consists 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 user may request the WebTable class to get a particular row values, we can get the row values by iterating the all the td HTML elements present under that row.

This method gets the all the td HTML element from a specific row, and iterates those element to store the text from it. We would be adding the text into 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 throw the throw the exception when user passes 0 as value as all rows starts 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, user may need the values from a particular column. To get the values from 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 cell, //tr/td avoids the headers so no need perform any action regarding that, but we still have to throw exception when 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 a HTML table are formed using tr tags, and all the columns are formed using td tags. If there are 10 columns present under row in a webtable, 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 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 methods returns false if 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 specific cell when user requests, we can do it form 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 the 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 same parent if not use the .. again till you have both elements under same parent, this concept is called as dependent and independent xpath</li>
  • Once you have them under 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 feature 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 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 in the 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")
	});
});


Output :

webtable-custom-webelement-selenium-webdriver

Capture Screenshot in webdriverio

About Author

Article is written by Pavan (a) KarthiQ. Well, I am serving notice period in an MNC, Bangalore. I thought to enrich every person knowledge a little, I always have a feeling, when we teach something, we will learn more than what you know. Knowledge is the only thing that doubles when you spend it.

I have also created the reporter for Protractor Jasmine. Use for your projects without any hesitation

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions