Drunda,
I can answer to your question and propose a solution. I will explain in detail taking examples from the following demo project:
https://github.com/kazurayam/KatalonDiscussion6790
# Your problem reproduced
I made a Test Object named ‘Page_sample/dev_node_text1’ with a xpath selector:
id('node')/text()[1]
I made a Test Case named TC2, which is as follows:
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
WebUI.openBrowser('')
WebUI.navigateToUrl('http://demoaut-mimic.kazurayam.com/6790_testbed.html')
def text = WebUI.getText(findTestObject('Page_sample/div_node_text1'))
WebUI.verifyEqual(text, 'Text 1')
WebUI.closeBrowser()
When I run this, it fails. The verifyEqual keyword fails with error a message like this:
Test Cases/TC2 FAILED because (of) Unable to get text of object (Root cause: java.lang.IllegalArgumentException: Object is null)
Test Cases/TC2.run:26
This message tells you that the expression findTestObject_(‘Page_sample/div_node_text1’)_ is evaluated to null. Why null?
# Background knowledge about XPath
The XPath 1.0 specification, 5 Data Model defines 7 types of nodes:
- root nodes
- **element **nodes
-
text nodes
-
attribute nodes
- namespace nodes
- processing instruction nodes
- comment nodes
A single XPath expression may return one of these types of nodes.
Your expression :
id("node")/text()[1]
is valid as XPath. If you apply this expression to the problem HTML document using a full-stack XPath engine such as Jaxen, I am sure, this expression would return “Text 1” as you expect.
However, we are not using Jaxen now. We are using Katalon Studio’s findTestObject. So we need to look at findTestObject(String) method. According to the API document, the findTestObject(String) is designed to return an instance of TestObject. What is a TestObject?
**I think a TestObject is designed to wrap an element node only; it can not wrap either a text node nor an attribute node. **
This implicit constraint is not described anywhere in the Katalon documentation, but I have found it by hands-on experiences.
## Rule of thumb:
**
Xpath selector for a Test Object is required to be a valid xpath expression which returns an ‘element node’ as a meaning of XPath. **If you set selector with an xpath which returns a text node, then findTestObject(String ) would return null. A xpath which returns an attribute node would result in null as well.
# Solution proposed
I made a Test Object named ‘Page_sample/dev_node’ with a selector in xpath:
id('node')
I made a Test Case named TS1, which is as follows:
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObjectimport com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI.openBrowser('')WebUI.navigateToUrl('http://demoaut-mimic.kazurayam.com/6790_testbed.html')def text = WebUI.getText(findTestObject('Page_sample/div_node'))WebUI.verifyEqual(text, 'Text 1Text 2')def leadingPart = text.substring(0, text.indexOf('Text 2'))WebUI.verifyEqual(leadingPart, 'Text 1')WebUI.closeBrowser()
This test case runs successful.
What you can get by WebUI.getText() is ‘Text 1Text 2’. The element between ‘Text 1’ and ‘Text 2’ disappears when WebUI.getText(‘Page_sample/div_node’) is evaluated.
You need to parse the ‘Text 1Text 2’ string for yourself with Groovy’s String object methods.
The variable named leadingPart contains ‘Text 1’. This is what you wanted.
Hope this helps.