Execute xpath functions from Katalon Studio


#1

Hello,
i was thinking how to execute xpath functions inside Katalon to we can use built-in capabilities of browser like count(), more than 1 objet on page directly in scripts. One way is to use selenium driver and capture outputs, but i find that way not “Katalon enough”

so i write myself custom keyword that allows me to execute xpath functions defined eg. in testObjects (need some time to add direct to passing capability - if requested)

for now, one can call this keyword to get number/string/boolean value form it

package com.swre
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebDriver as WDriver
import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.webui.driver.DriverFactory

class tools {	
    /**
	 * Execute/evaluate xpath
	 * @param String or testObject
	 * @param RESULT_TYPE: [NUMBER_TYPE|STRING_TYPE|BOOLEAN_TYPE]
	 * @return result from xpath
	 */

	@Keyword
	def exexpath(String xpth, String RESULT_TYPE) {
		def resultTypes = ['NUMBER_TYPE': 'numberValue','STRING_TYPE': 'stringValue', 'BOOLEAN_TYPE': 'booleanValue']
		WDriver wd = DriverFactory.getWebDriver()
		try{
			String execCmd = 'return (document.evaluate(\''+xpth+'\', document, null, XPathResult.ANY_TYPE, null)).'+resultTypes[RESULT_TYPE]+';'
			return ((JavascriptExecutor) wd).executeScript(execCmd,[xpth])
		} catch (Exception e){
			println e
			return null
		}
	}
}

example: xpath is mallformed by view remove space after first "

import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

WebUI.openBrowser('https://forum.katalon.com/categories/web-testing')

def xObj = CustomKeywords.'com.swre.tools.exexpath'('count(//div[@class=" category_parent_katalon-studio"])', 'NUMBER_TYPE')
println(xObj)
xObj = CustomKeywords.'com.swre.tools.exexpath'('count(//div[@class=" category_parent_katalon-studio"])>10', 'BOOLEAN_TYPE')
println(xObj)
xObj = CustomKeywords.'com.swre.tools.exexpath'('normalize-space(" The   xpath    executer! ")', 'STRING_TYPE')
println(xObj)
xObj = CustomKeywords.'com.swre.tools.exexpath'('normalize-space(" The   xpath    executer! ")', 'STRING_TYPO')
println(xObj)
WebUI.closeBrowser()


Finding Element's xpath address
Variable not receiving value from javascript
#2

Sweet. Upvoted.


#3

Nice.


#4

here is keyword with possibility to call with Test Object - it takes it and search for xpath property then it uses it

package com.swre

import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebDriver as WDriver
import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webui.driver.DriverFactory
class tools {
	/**
	 * Execute/evaluate xpath
	 * @param String or testObject
	 * @param RESULT_TYPE: [NUMBER_TYPE|STRING_TYPE|BOOLEAN_TYPE]
	 * @return result from xpath
	 */

	@Keyword
	def exexpath(String xpth, String RESULT_TYPE) {
		def resultTypes = ['NUMBER_TYPE': 'numberValue','STRING_TYPE': 'stringValue', 'BOOLEAN_TYPE': 'booleanValue']
		WDriver wd = DriverFactory.getWebDriver()
		try{
			String execCmd = 'return (document.evaluate(\''+xpth+'\', document, null, XPathResult.ANY_TYPE, null)).'+resultTypes[RESULT_TYPE]+';'
			return ((JavascriptExecutor) wd).executeScript(execCmd,[xpth])
		} catch (Exception e){
			println e
			return null
		}
	}

	def exexpath(TestObject to, String RESULT_TYPE) {
		try{
			exexpath(to.findPropertyValue("xpath"), RESULT_TYPE)
		} catch (Exception e){
			println e
			return null
		}
	}
}


#5

Andrej Podhajský said:

here is keyword with possibility to call with Test Object - it takes it and search for xpath property then it uses it

package com.swreimport org.openqa.selenium.JavascriptExecutorimport org.openqa.selenium.WebDriver as WDriverimport com.kms.katalon.core.annotation.Keywordimport com.kms.katalon.core.testobject.TestObjectimport com.kms.katalon.core.webui.driver.DriverFactoryclass tools {	/**	 * Execute/evaluate xpath	 * @param String or testObject	 * @param RESULT_TYPE: [NUMBER_TYPE|STRING_TYPE|BOOLEAN_TYPE]	 * @return result from xpath	 */	@Keyword	def exexpath(String xpth, String RESULT_TYPE) {		def resultTypes = ['NUMBER_TYPE': 'numberValue','STRING_TYPE': 'stringValue', 'BOOLEAN_TYPE': 'booleanValue']		WDriver wd = DriverFactory.getWebDriver()		try{			String execCmd = 'return (document.evaluate(\''+xpth+'\', document, null, XPathResult.ANY_TYPE, null)).'+resultTypes[RESULT_TYPE]+';'			return ((JavascriptExecutor) wd).executeScript(execCmd,[xpth])		} catch (Exception e){			println e			return null		}	}	def exexpath(TestObject to, String RESULT_TYPE) {		try{			exexpath(to.findPropertyValue("xpath"), RESULT_TYPE)		} catch (Exception e){			println e			return null		}	}}

  

Hi Andrej, I am new to Katalon …

Could you please show an sample code … how to ‘execute xpath functions’ using Test Object . In the below fn, should you use the annotation @Keyword.

def exexpath(TestObject to, String RESULT_TYPE)
{

}

Thanks for looking into this.


#6

1. define object:


2. use find onbject in parameter

xObj = CustomKeywords.'com.swre.tools.exexpath'(findTestObject('Object Repository/count_in_category'), 'NUMBER_TYPE')println(xObj)

3. console output:

07-18-2018 11:42:19 PM - [START]  - Start action : Statement - xObj = CustomKeywords.com.swre.tools.exexpath(com.kms.katalon.core.testobject.ObjectRepository.findTestObject(Object Repository/count_in_category), "NUMBER_TYPE")07-18-2018 11:42:19 PM - [INFO]   - Finding Test Object with id 'Object Repository/count_in_category'07-18-2018 11:42:19 PM - [PASSED] - com.swre.tools.exexpath is PASSED07-18-2018 11:42:19 PM - [END]    - End action : Statement - xObj = CustomKeywords.com.swre.tools.exexpath(com.kms.katalon.core.testobject.ObjectRepository.findTestObject(Object Repository/count_in_category), "NUMBER_TYPE")07-18-2018 11:42:19 PM - [START]  - Start action : Statement - println(xObj)3107-18-2018 11:42:19 PM - [END]    - End action : Statement - println(xObj)

image.png


#7

disover katalon said:

***cut***
Could you please show an sample code … how to ‘execute xpath functions’ using Test Object . In the below fn, should you use the annotation @Keyword.

def exexpath(TestObject to, String RESULT_TYPE)
{

}

Thanks for looking into this.

hi disover,
i dont need to, since groovy takes over and finds correct function based on type of parameter
but you are right that when i use @Keyword annotatin i’ll see 2nd function definition


#8

Thanks Andrej for clarifying. :slight_smile:

Just curious to know … Where should I use the below xpath function in Automation and it’s purpose?

xObj = CustomKeywords.'com.swre.tools.exexpath'('normalize-space(" The   xpath    executer! ")', 'STRING_TYPE')println(xObj)

#9

hi disover,
to be honest, i have no idea since what this function do can be easily done in groovy or elswhere. i just grab 1st function that my eye land on and that returns string to use it as example.
feel free to elaborate and improove on above text, or sugest better function to use in examples.


#10

Pls suggest a practical usage of this capability?


#11

for example TC:
in OR i have defined object with xpath that returns no of columns in table (can be done also by use of driver capabilities) then when i need i execute xpath defined in that object and use it as input in for cycle to click on each column to check ordering functionality of table


#12

It’s great, upvoted!

Is is possible to get node’s text value? Tried sthg like:

CustomKeywords.‘com.swre.tools.exexpath’(’//div[7]/div/form/table/tbody/tr[5]/td[4]/text()’, ‘STRING_TYPE’)

but it didn’t work.

Thanks in advance!


#13

hello,
you need to use small trick:

CustomKeywords.‘com.swre.tools.exexpath’(’string(//div[7]/div/form/table/tbody/tr[5]/td[4]/text())’, ‘STRING_TYPE’)

putting xpath in conversion function will execute also text() part of it


#14

Forgot to thank you, so thank you :slight_smile:


#15

You are welcome