Use variable in xpath

Hi there,

Currently I’m struggling with putting a variable into xpath to make the object detection dynamic.

The xpath which identifies the object(a_dashboarditems): //*[normalize-space(text())=‘Projects’]
object.PNG
This works perfectly fine. I can adjust the name and it will also find other items

To make it dynamic, I made a variable on the variable tab called “dashboard”, with the default value: “Projects”
variabletab.PNG

I modified the xpath value at the object in a few ways:
//[normalize-space(text(),${dashboard})]
//
[normalize-space(text())=${dashboard}]

Unfortunately the options above don’t work, the object cannot be find and clicked on anymore.
As an extra step I want to make this variable tab using an excel sheet, but this easy once the step above is working.

Can someone point me into the right direction to make this work? A solution would also be nice.

Thanks!

object.PNG

variabletab.PNG

Seems I cant edit my first post, but there’s a typo in the object.png screenshot: “projectbeheer” should be “projects” in the xpath.

The error message:

Test Cases/Test FAILED because (of) Unable to click on object ‘Object Repository/a_dashboarditems’ (Root cause: com.kms.katalon.core.webui.exception.WebElementNotFoundException: Web element with id: ‘Object Repository/a_dashboarditems’ located by ‘By.xpath: //*[normalize-space(text(),${dashboard})]’ not found)

Test Cases/Test.run:26

I managed to get the first step working, putting a variable in the xpath, by using the script tab:

dashboard = ‘Projects’

TestObject to = findTestObject(‘a_dashboarditems’)

to.findProperty(‘xpath’).setValue(’//*[normalize-space(text())=\’’+dashboard+’\’]’)

But i can’t get it to work in the object’s property screen. I need to get this to work because i want to use a variable from a csvfile later on.
Anyone knows how to use the variable in xpath by using the objectproperty tab?

1 Like

hey, i am looking something like this, can you please explain with more screenshots

Could you try this in the Test Object definition for a_dashboarditems:

//*[normalize-space(text())='${dashboard}']

You need to quote the string value of ${dashboard}.

2 Likes

It seems that backslash before single quotation is not necessary.
PLS try this:

//*[normalize-space(text())='${dashboard}']
2 Likes

Thank you for the help

kazurayam said:

It seems that backslash before single quotation is not necessary. PLS try this://*[normalize-space(text())='${dashboard}']

Thanks, works like a charm!

Hi,

what I’m doing wrong? I tried the whole day, with css and with xpath property, but didn’t get this approach to work with Katalon Studio 5.4.2. As long as I use hard coded values for the active xpath statement of my TestObject (with Basic Selection Method) like:

//td[3]

or even for a accordingly css (Basic) statement like:

*:nth-of-type(3)>td

… everything is fine for a TestCase that accesses such TestObject in a way like:

println WebUI.getText(findTestObject(myTestObjectId))

That means, in both cases I get the 3rd td element in DOM.

But if the TestObject’s xpath property refers to a local variable (say webElmId = 3) like:

//td['${webElmId}']

… there will be found only the first occurence of td in DOM. It’s exactly like if I said “//td[1]”.

And if the TestObject’s css property refers to the same local variable like:

*:nth-of-type('${webElmId}')>td

… of course, nothing will be found.

Am I doing something wrong? Or was there a change in the way Katalon Studio evaluates these TestObject properties?

Thanks a lot and regards!

**# Solution **

Please change your XPath expression as this:

//td[${webElmId}]

and try to see what you get.

# Description

You have this now:

//td['${webElmId}']

Katalon Studio transforms this expression to

//td['3']

This expression is equal to:

//td[position()='3']

The XPath Engine (jaxen built-in Katalon Studio) will evaluate the predicate [position()=‘3’] to false because ‘3’ is not a number. The function position() returns a number value. On the other hand, ‘3’ is a string. In XPath, a comparison of a number and a string makes false.

Then the above expression will result in the same value as

//td

XPath Engine offers 2 interpretation of this expression as follows:

  1. a node-set of elements in the HTML document
  2. the 1st element among a node-set of elements in the HTML document

    Katalon Studio takes the 2nd interpretation. Therefore you get the same value as “//td[1]”.

3 Likes

Hi kazurayam,

once again very conclusively deduced, thank you for your effort! But unfortunately, I had only forgotten to mention that, it doesn’t work for me without quotes either. The result of my command:

println WebUI.getText(findTestObject(myTestObjectId))

… in the case of using xpath is the same as with or without single quotes in the CSS statement:

[FAILED] - Unable to get text of object ‘Object Repository/myTestObject’ (Root cause: com.kms.katalon.core.webui.exception.WebElementNotFoundException: …

It almost seems to me that my variable webElmId is empty? But the TestCase log even says at the beginning:

Variable 'webElmId' is set to 3 as default

BTW, is my expectation actually correct that I should be able to change this local variable to a different integer value during the TestCase runtime in order to use again and again:

println WebUI.getText(findTestObject(myTestObjectId))

… for access to the next TestObject within my WebElement-List of further matching td elements in DOM?

Thank you!

Your Test Case snippet is this:

println WebUI.getText(findTestObject(myTestObjectId))

This is not enough.

The following code would work:

println WebUI.getText(findTestObject(myTestObjectId, ['webElmId' : 3]))

See the API doc of ObjectRepository#findTestObject(String, Map)

2 Likes

Genius, that was my fault! :slight_smile: I somehow assumed without checking that the object properties would have direct access to the (local) variables used in the respective TestCase. Thank you very much for illuminating that! :slight_smile:

HI,

I am trying to use below expression

findTestObject(’//a[text() = ‘${sElement’}’)

here sElement is variable, I tried with and without single quotes but still unable to find object. If I use individual object it’s working fine. I tried similar Xpath with double quotes like below

findTestObject("//a[text() = ${sElement}"), still it’s not working. I want to use dynamic Xpath. Please tell me how can we use dynamic Xpath

answer here : Unable to use dynamic Xpath

@kazurayam - Can you help me on this.
This is the xpath with value directly on it
//li[@id=‘Car’]
Trying to replace the above by
//li[@id=’${loanPurpose}’]

Caused by: com.kms.katalon.core.webui.exception.WebElementNotFoundException: Web element with id: ‘Object Repository/Page/auto’ located by ‘By.xpath: //li[@id=’${loanPurpose}’]’ not found

Getting the above error

How does your test case script looks like? Does it have a line which interpolates the placeholder ${loanPurpose} with a value Car, like:

println WebUI.getText(findTestObject(myTestObjectId, ['loanPurpose' : 'Car']))

Hi,

This is my xpath for table data: //tr[3]/td[3]/div
i need to write dynamic xpath . Could you please advise how i need to declare variable and how shall i code xpath .

I declared variable i =3 and j =3
and gave xpath like //tr[${i}]/td[${j}]/div but it didnt work. pls advise

How does your test case script looks like? Does it have a line which interpolates the placeholder ${i} with a value 3 and ${j} with a value 3, like:

println WebUI.getText(findTestObject(myTestObjectId, ['i' : 3, 'j': 3]))

After adding the above line as placeholder $, can i code in test object as

//tr[${i}/td[${j}]

Pls advise