Let me define a problem with a simple HTML as target.
1. I have a Web page to test. The target page has a list of web elements. Let me name it as the found elements. Please find a list of elements in the following HTML snippet:
Now I want to perform, in my test case, an iteration over the found elements. However, Katalon Studio does not provide any built-in keyword which returns a list of web elements out of the target Web page.
# Solution proposed
## My custom keyword
Here I have developed a Groovy class as custom keyword for Katalon Studio: com.kazurayam.ksbackyard.FindElementsByXPath. This class implements a method: List<org.openqa.selenium.WebElement> getWebElementsAsList(String xpath). The source code is here. Here I copy&paste it:
Please note that this keyword returns List<org.openqa.selenium.WebElement>. Hence, those who use this custom keyword have to study WebDriver’s API document/ WebElement.
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
WebUI.openBrowser('')
WebUI.navigateToUrl('http://demoaut-mimic.kazurayam.com/6967_testbed.html')
List<Map<String,String>> data = [
["text":"Tokyo CURA Healthcare Center"],
["text":"Hongkong CURA Healthcare Center"],
["text":"Seoul CURA Healthcare Center"],
["text":"New York CURA Healthcare Center"]
]
List<WebElement> webElementsInPage =
CustomKeywords.'com.kazurayam.ksbackyard.FindElementsByXPath.getWebElementsAsList'('//select[@name="facility"]/option')
WebUI.comment("webElementsInPage.size()=${webElementsInPage.size()}")
for (int i = 0; i < data.size(); i++) {
data[i].found = 'no'
for (WebElement el: webElementsInPage) {
WebElement node = el.findElement(By.xpath('.')) // you can further search for any descendant nodes of the WebElement
String t = node.getText().trim()
if (t == data[i].text) {
data[i].found = 'yes'
}
}
}
for (Map m : data) {
WebUI.comment("${m.text} is displayed:${m.found}")
}
WebUI.closeBrowser()
## Result
When I execute my test case, I got the following output in the log:
>>> Tokyo CURA Healthcare Center is displayed: yes
...
>>> Hongkong CURA Healthcare Center is displayed: yes
...
>>> Seoul CURA Healthcare Center is displayed: yes
...
>>> New York CURA Healthcare Center is displayed: no
This is what I wanted to see.
## Extensibility
The custom keyword getWebElementsAsList, which I presented here, returns List<org.openqa.selenium.WebElement> into the scope of test case in the Katalon Studio. This keyword would encourage you to develop your test cases using both of Katalon Studio’s built-in keywords and the native API of the Selenium WebDriver. How can you extend this example? — Well, it is up to you. You can do in the Katalon Studio whatever as far as the WebDriver API supports.
## Demo at GitHub
You can check out a demo project from the following GitHub repository:
Katalon team labeled “Internal method” to it. If the Katalon Documentation page “[WebUI] Element” covered this ‘internal’ method, I would not have spent time for reinventing the wheel.
I have used your custom method,
like this
println(getWebElementsAsList("//input[@type=‘checkbox’]").size())
WebUI.click(getWebElementsAsList("//input[@type=‘checkbox’]").get(2), FailureHandling.STOP_ON_FAILURE)
iam able to print number of elements but second code webui.click is not working ,
Throwing the below error
01-21-2020 03:35:54 PM User selects single test from location list
Elapsed time: 19.851s
Location.selectSingleLocation:160
User selects single test from location list FAILED.
Reason:
groovy.lang.MissingMethodException: No signature of method: static com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords.click() is applicable for argument types: (org.openqa.selenium.support.events.EventFiringWebDriver$EventFiringWebElement, com.kms.katalon.core.model.FailureHandling) values: [[[CChromeDriver: chrome on WINDOWS (9f70dd5a87d2f2222e856d1269e94770)] -> xpath: //input[@type=‘checkbox’]], …]
Possible solutions: click(com.kms.katalon.core.testobject.TestObject, com.kms.katalon.core.model.FailureHandling), click(com.kms.katalon.core.testobject.TestObject), check(com.kms.katalon.core.testobject.TestObject, com.kms.katalon.core.model.FailureHandling), back(), back(com.kms.katalon.core.model.FailureHandling), check(com.kms.katalon.core.testobject.TestObject)
at Location.selectSingleLocation(Location.groovy:160)
at ✽.User selects single test from location list(D:/mywork/KS/Webproject/TestEhswatch/Include/features/Location.feature:45)
getWebElementsAsList() returns a List<org.openqa.selenium.WebElement>.
WebUI.click(xxx) requires argument of type com.kms.katalon.core.test.object.TestObject.
Type mismatching.
Therefore WebUI.click(getWebElementsAsList(...).get(x)) will never work.
If you want to use WebUI.click(...) then you should NOT use getWebElementsAsList(). If you want to use WebUI.click(...) you should stick to findTestObject("...")
If you rather want to use getWebElementsAsList(), then you can no longer use WebUI.xxxx keywords. You need use Selenium API to work on objects of class org.openqa.selenium.WebElement in the Test Case script. Using Selenium API in the KS Test Case is totally valid, would certainly work.
@CompileStatic@com.kms.katalon.core.annotation.Keyword(keywordObject = StringConstants.KW_CATEGORIZE_ELEMENT)static com.kms.katalon.core.testobject.TestObject convertWebElementToTestObject(org.openqa.selenium.WebElement webElement, com.kms.katalon.core.model.FailureHandling flowControl)
Convert a WebElement to a TestObject. It will create a Test Object with no name that wraps around the given WebElement. When the Test Object is used by built-in keywords, it is unwrapped and the given WebElement will be used throws:
StepFailedException Returns:
a TestObject that wraps around the given WebElement Parameters:
webElement - the WebElement retrieved by Selenium or other APIs
flowControl - failureHandling Since:
6.2.0