Why aren't these table header columns being detected properly?

Today’s question for the font of knowledge:

We have a function used to capture a list object of all the columns in a given table row , which then we later use to perform a cell by cell examination of that particular row for a number of attributes.

One of these attributes is the column count, as seen in the indicated function:

	public List<WebElement> validate_table_columns(WebElement table_row, int expected_column_count, current_row, String column_match_condition = "EQUALS") {

		if (!match_conditions.contains(column_match_condition)) {
			KeywordUtil.markFailedAndStop(column_match_condition + ' is not an acceptable parameter for the column match condition. Please enter EQUALS or MIN.')


		table_columns = table_row.findElements(By.tagName('td'))
		log.logInfo("validate_table_columns -> table_columns.size(): " + table_columns.size())

		header_columns = table_row.findElements(By.tagName('th'))
		log.logInfo("validate_table_columns -> header_columns.size(): " + header_columns.size())

		table_column_count = table_columns.size() + header_columns.size()

		if (column_match_condition == "EQUALS") {
			if (table_column_count != expected_column_count) {
				KeywordUtil.markFailed('The expected column count is ' + expected_column_count + '. The actual column count is ' + table_column_count + '.')
		if (column_match_condition == "MIN") {
			if (table_column_count < expected_column_count) {
				KeywordUtil.markFailed('The expected column count is a minimum of ' + expected_column_count + '. The actual column count is ' + table_column_count + '.')

		//Display column count for first row
		if (current_row == 0) {
			KeywordUtil.logInfo('There are ' + table_column_count + ' columns in row ' + current_row + '. The expected column count is ' + column_match_condition + ': ' + expected_column_count)

		return table_columns

This works for EVERY table in our application (of which there are many tables) - except one.

Here is an image showing this particular table and the HTML encoding for the column header row, which uses the <th> delineator to breakout the individual columns:

By all rights, the code snippet listed above should be detecting and capturing the <th> column elements and counting them; however it is not for some reason. All the other rows in this table count columns correctly, though those use the <td> tagName element.

We’re capturing the header column counts correctly on all our other tables, can anyone spot what might be so unique about this particular instance that is preventing the <th> elements from being counted correctly?

1 Like

Hi there,

Thank you very much for your topic. Please note that it may take a little while before a member of our community or from Katalon team responds to you.



Welcome all of the experts to join and support @kevin.jackey :raised_hands:

This explanation is not concrete enough.

Please show the log you got.

And please describe what you expected to see in the log, and what you actually saw in the log.

Possibly we need to see the code fragment that calls the function validate_table_columns(WebElement table_row, ...). We need to see how it builds a WebElement table_row argument for the <tr> element in the <thead> element.

below is the code segment that creates the table rows list:

public List<WebElement> validate_table_rows(String table_name, String test_object_xpath, int expected_row_count, String row_match_condition = "EQUALS", int object_timeout) {

		int header_count;
		int footer_count;

		//Define table object
		TestObject this_table_object = new TestObject (table_name)
		this_table_object.addProperty('xpath', ConditionType.EQUALS, test_object_xpath)
		//log.logInfo("VTR xpath: " + test_object_xpath)

		if (!match_conditions.contains(row_match_condition)) {
			KeywordUtil.markFailedAndStop(row_match_condition + ' is not an acceptable parameter for the row match condition. Please enter EQUALS or MIN.')

		WebElement table_element = WebUI.findWebElement(this_table_object, object_timeout);

		if(table_element == null) {
			KeywordUtil.markFailed('Unable to identify Table ' + table_name)
			body_rows = 0
		} else {

			List<WebElement> table_rows = table_element.findElements(By.tagName('tr'))
			table_row_count = table_rows.size()

			header_count = validate_table_rows_headers(test_object_xpath)
			body_rows = validate_table_rows_body(test_object_xpath)
			footer_count = validate_table_rows_footers(test_object_xpath)

			if (row_match_condition == "EQUALS") {
				if (table_row_count != expected_row_count) {
					KeywordUtil.markFailed('The expected row count is ' + expected_row_count + '. The actual row count is ' + table_row_count + '.')
			if (row_match_condition == "MIN") {
				if (table_row_count < expected_row_count) {
					KeywordUtil.markFailed('The expected row count is a minimum of ' + expected_row_count + '. The actual row count is ' + table_row_count + '.')

			KeywordUtil.logInfo('There are ' + table_row_count + ' rows. ' + header_count + ' of these rows are headers. ' + footer_count + ' of these rows are footers. The expected row count is ' + row_match_condition + ': ' + expected_row_count)

		return body_rows


which leads to this output for row zero:

The remainder of the rows (with <tr> designators) work just fine:

Please uncomment this line. Or change it to

KeywordUtil.logInfo("table_name: " + table_name + ", test_object_xpath: " + test_object_xpath)

and please show the log again.

We need to see what value you have in the variable test_object_xpath.

I have a doubt that the XPath could be incorrecct.

Will do so; however if I understand things correctly then none of the other rows in the table would be getting detected. Those rows return the column counts correctly, it’s just the header row that’s not detecting things.

Will run with the above and reply here once done. Appreciate everyone’s help on this!


which matches the table property:


You shared the source code of validate_table_rows() function.

You wrote you are unhappy about the following FAILED message.

However, the FAILED message is NOT emitted by the validate_table_rows().

Presumably another function validate_table_rows_headers(String) does emitting the FAILED message. I guess there is a coding mistake in this function.

You haven’t shared the source validate_table_rows_headers(), so I have no more idea.

Apologies for not listing that function:

	public int validate_table_rows_headers(String table_xpath) {

		int header_size;
		String header_xpath = table_xpath + '/thead'
		//KeywordUtil.logInfo("table_header xpath value: " + header_xpath)
		WebDriver driver = DriverFactory.getWebDriver()

		try {
			WebElement header_elements =  driver.findElement(By.xpath(header_xpath))
			List<WebElement> header_rows = header_elements.findElements(By.tagName('tr'))

			header_size = header_rows.size()
			return header_size
		catch(Exception no_such_element) {
			header_size = 0
			return header_size

Re-run with the header xpath logInfo statement uncommented:


You are unhappy about the message “The actual column count is 0”.

You shared the source code of 2 functions: validate_table_rows() and validate_table_rows_headers().

In either of them, I could not find a code fragment that could emit the message “The actual column count is X”.

There must be some other code that you should review.