Custom Keyword: get contents of HTML elements as a list of strings

# Problem to solve

Supposing the target web page has a list of element.

I want to verify the displayed contents against other list of strings list like this:

def expectedContents = [
    "Tokyo CURA Healthcare Center",
    "Hongkong CURA Healthcare Center",
    "Seoul CURA Healthcare Center" ]

However, in the built-in keywords of Katalon Studio, there is none which returns the contents of HTML elements as List.

# My Solution

I have developed a class com.kazurayam.ksbackyard.FindElementsByXPath . This class provides 2 custom keywords.

- List getElementContentsAsList(String xpath4elements)

- List getElementAttributesAsList(String xpath4elements, String attributeName)

A sample Test Case looks like this:

def expectedContents = [        "Tokyo CURA Healthcare Center",
	"Hongkong CURA Healthcare Center",
	"Seoul CURA Healthcare Center" ]List<String> cs = CustomKeywords.'com.kazurayam.ksbackyard.FindElementsByXPath.getElementContentsAsList'('//select[@name="facility"]/option')
for (int i = 0; i < cs.size(); i++) {
    WebUI.verifyEqual(cs[i], expectedContents[i])
}
def expectedValues = [
    "Tokyo",
    "Hongkong",
    "Seoul" ]
List<String> vs = CustomKeywords.'com.kazurayam.ksbackyard.FindElementsByXPath.getAttributeValuesAsList'('//select[@name="facility"]/option', 'value')
for (int i = 0; i < vs.size(); i++) {
    WebUI.verifyEqual(vs[i], expectedValues[i])
}

# My implementation

See the following GitHub repository:

6967_testbed.png

2 Likes

I have found that we do not need a custom keyword. A built-in keyword WebUI.findWebElements(TestObject) is available. You can write this

import org.openqa.selenium.WebElement
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.kms.katalon.core.testobject.ConditionType

...
// grasp <tr> elements
List<WebElement> trElements = WebUI.findWebElements(
	new TestObject().addProperty("xpath", ConditionType.EQUALS, 
							"//div[@id='resultDiv']/table/tbody/tr"), 10)
println "trElements.size()=${trElements.size()}"

See

for working example.

2 Likes

kazurayam, what would you say is the relation between test object and web element in this case?

Is it just a one-to-one translation between Selenium’s web elements and Katalon’s test objects?

I have update my demo project:


TC4:

// grasp <tr> elements : 1st way; using Katalon API with a TestObject constructed beforehand 
List<WebElement> trElements1 = WebUI.findWebElements(
	findTestObject("Page_Sample/div_resultDiv.table.tbody.tr"), 10)
println "trElements1.size()=${trElements1.size()}"

// grasp <tr> elements : 2nd way; using Katalon API with a TestObject constructed on the fly
List<WebElement> trElements2 = WebUI.findWebElements(
	new TestObject().addProperty("xpath", ConditionType.EQUALS,
							"//div[@id='resultDiv']/table/tbody/tr"), 10)
println "trElements2.size()=${trElements2.size()}"

// grasp <tr> elements : 3rd way; using WebDriver's native API
WebDriver driver = DriverFactory.getWebDriver()
List<WebElement> trElements3 = driver.findElements(By.xpath("//div[@id='resultDiv']/table/tbody/tr"))
println "trElements3.size()=${trElements3.size()}"

This code prints the following output:

...
trElements1.size()=3
...
trElements2.size()=3
...
trElements3.size()=3

In the above code, I showed 3 ways of grasping <tr> elements in a HTML. These 3 ways have just the same result.


Mate_Mrse asked about

the relation between test object and web element

I think this question is a bit misdirected. Katalon’s Test Object can be regarded equivalent to the org.openqa.selenium.By class. Both classes are the container of selector expression (XPath or CSS).
They are not equivalent to org.openqa.selenium.WebElement class, which represents a <node> found in the target HTML.

A Test Object enables you to serialize a selector expression (XPath or CSS) into Object Repository. In other words, a Test Object externalizes selector expression out of a test case code by saving them into XML files. Externalized selectors will be easier to manage and reuse, than the case where selectors are left buried in test case scripts. That would be a reason why Test Object is prefered to By object. However I often prefer By object to Test object when I write a short one-off test case snippet because I know I would not reuse the selector at all.

2 Likes