How can I get the data from rows under columns

I looked at the topics similar to this…but really couln’t find an answer (or maybe i’m blind)

I’m trying to get the data from these two columns - Status and Owner and have the test check the columns displays the value the user filtered. (i.e - return all items where Status = Client, or Owner = x… and then have the test verify all the rows under Status = client… Owner=x)

What’s probably tricky is these tables are not traditional HTML tables and rows…but React front-end ones…which has < divs > and < spans > and different layers.

I know some of yall are truly experts in here… Help?


Here’s the HTML!

We need to be able to get access to the target web app and open it on browser in hand.

Is your target web app publicly accessble on the Internet? If so, please tell its URL to us.

If it is not public, please save the target page into a MIME HTML file, and share the file here.

The following post tells you how to save a web page into a MIME HTML file.

Households - Index.zip (58.5 KB)

Taking the MIME HTML provided as an input, I wrote a Test Case

import org.openqa.selenium.By
import org.openqa.selenium.WebElement

import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

File html = new File("./Households - Index.mhtml")

WebUI.openBrowser(html.toURI().toURL().toExternalForm());
WebUI.verifyElementPresent(makeTO("//div[contains(@role,'table')]"),5)
WebUI.verifyElementPresent(makeTO("//div[contains(@role,'table')]//div[@role='row']"),5)

List<WebElement> rows = WebUI.findWebElements(makeTO("//div[contains(@role,'table')]//div[@role='row']"),5);
assert rows.size() > 1
int numberOfRows = rows.size()
println "numberOfRows=${numberOfRows}"

for (WebElement row in rows) {
	WebElement owner = row.findElement(By.xpath("div[@role='gridcell'][4]"))
	assert owner != null
	//println "owner=${owner.getText()}"
	WebElement status = row.findElement(By.xpath("div[@role='gridcell'][5]"))	
	if (owner.getText().trim() == "Ashraf Tester" && 
		status.getText().trim() == "Client") {
		checkRow(row)
	}
}

WebUI.closeBrowser()

/**
 *  
 */
def checkRow(WebElement row) {
	WebElement name = row.findElement(By.xpath("div[@role='gridcell'][3]"))
	WebUI.comment("Name=${name.getText().trim()}")
	// add more code ...
}

/**
 * @param xpath
 * @return a TestObject
 */
TestObject makeTO(String xpath) {
	TestObject to = new TestObject(xpath)
	to.addProperty("xpath", ConditionType.EQUALS, xpath)
	return to
}

The test case emits output

...
numberOfRows=19
Name=AHMADZAI Household
Name=AT Perspective

You can clone the demo project from

This code used Selenium WebDriver API. It was necessary because Katalon’s WebUI.* keywords only works on a DOM tree under the root element of an HTML Document. Katalon’s WebUI.* keyword does not support traversing a sub-tree under a specific WebElement.

The following part does that sub-tree traversal, which is the core of my solution. WebDriver API allows you to traverse a sub-tree under a specific WebElement (row):

for (WebElement row in rows) {
	WebElement owner = row.findElement(By.xpath("div[@role='gridcell'][4]"))

If you have more questions, please do not hesitate to add questions here.

It just matters to how the locator expressions (XPath or CSS Selector) should be written. It is not really a big issue, though Spy & Recorder would not help you much. You need to be capable to write valid locators manually.

This is great stuff! This helps.
But I think it’s my fault I wasn’t really clear what I wanted to accomplish and probably had you do more than the use case(s) I was trying to cover.

What I didn’t mentioned is the page has a filter functions just above… so i already have the tests doing that to update the view on the page…

so the first view or test case is:

  1. FIltering the “Status” column to return all the “Client” and then the tests needs to verify that ALL the rows under Status = Client (obviously nothing else should be in the view). Basically check all the rows under Status and expected should be “Client”

So if I understand how to write the above… I can write same use case for i.e. - Owner column or whichever i choose to do.
does that make sense?

So that’s like the reason I thought this would require for loop function or something.
What you gave me is awesome… but I guess it’s basically trimming all the rows that has “client” and owner name… and that might not be the actual use case I’m trying to do…

I think you already gave me enough to figure it out… but if you can point me to right direction… I should be able to solve it faster.

You want me to write a sample code that does

It looked easy enough. In order to do this, my test case sample needs to interact with the UI component labeled “Select Columns” on the page.

I opened the MHTML file in browser and clicked the “Select Columns” UI component, but it did not react at all. It seemed that JavaScript (React) in the MHTML is not working. There seemed to be a good reason why it didn’t work. But it is not relevant here.

If your target URL is public to the Internet, I would be able to work on it. But possibly the URL is not public, and you haven’t shared it. Therefore I can not open the page on browser on my side.

So, I am not able to help you any more.

hey Kazurayam…
i already scripted the drop-down and filter selection part…
what i need is just for the test to validate that ALL the rows under column “Status” = Client

let me send another MHTML with the view already on thatHouseholds - Index (2).zip (69.3 KB)

I suppose that the only thing you need to know is how to throw an Exception and let a test case fail when a condition turned to be false.

KeywordUtil would be what you want.