Can I put a variable into a string?

I have a set of really strange text fields that I simply cannot find a locator for. I found a workaround in the forum via tabbing to the field from another element, then executing this to enter text to the field:

WebUI.executeJavaScript('document.activeElement.value = "MyValue"', [])

This works a treat. However, I need to have a variable in the value I set to this field (basically, it’s an attribute editor for a product. I change the description here, then go back to the product page and verify that it’s updated to match what I put in). My pet unique variable is just using a timestamp, so I’d love to be able to just have the value be something like “New description timestamp

However, every time I try to put a variable into this expression, I get an error. I don’t come from a technical background, so I don’t know if I’m committing syntax sins or if this is impossible.

This is what I use to get the timestamp:

 Date date = new Date()

def value = date.getTime().toString()

and this is how I get to the field and input text:

WebUI.sendKeys(findTestObject('Attribute/tabMarketCommercial'), Keys.chord(Keys.TAB, Keys.TAB, Keys.TAB, Keys.TAB))
WebUI.executeJavaScript('document.activeElement.value = "This is an automated test description."', [])

Any help would be very much appreciated!

1 Like

Here’s an example of something I’ve tried-- it doesn’t even have to have text, it can literally just be my timestamp variable. Or anything that can change every time it runs.

WebUI.executeJavaScript(('document.activeElement.value'), variableName, [])

Reason:
groovy.lang.MissingMethodException: No signature of method: static com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords.executeJavaScript() is applicable for argument types: (java.lang.String, java.lang.String, java.util.ArrayList) values: [document.activeElement.value, 1575772524017, []]
Possible solutions: executeJavaScript(java.lang.String, java.util.List), executeJavaScript(java.lang.String, java.util.List, com.kms.katalon.core.model.FailureHandling)
	at PM_Edit_AWM_V2.run(PM_Edit_AWM_V2:81)
	at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194)
	at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119)
	at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:337)
	at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:328)
	at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:307)
	at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:299)
	at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:233)
	at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:114)
	at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:105)
	at com.kms.katalon.core.main.TestCaseMain$runTestCase$0.call(Unknown Source)
	at TempTestCase1575772493242.run(TempTestCase1575772493242.groovy:23)


Here’s this, if that helps. It seems to be set up right but I must be missing something :sob:

Probably. The last thing you want is the syntax police breaking down your door :wink:

GStrings to the rescue!

Try to stamp this pattern on your brain:

double-quotes ${variable_name} double-quotes

That’s a GString (groovy-string).

So, now you can…

String timestamp = date.getTime().toString()
String magic = "New description ${timestamp}"
String js = "document.activeElement.value = '${magic}';"
WebUI.executeJavaScript(js, null)

You can, of course, combine all those variable assignments into one line if you prefer, but there’s a lot to be said for readability - especially after time has passed and you forget the details…

1 Like

I’d like to see that stuff up close. Screenshots of the HTML?

OH MY GOD this worked. I could hug you! I have spent literally HOURS trying to first get a locator for this thing, and when I gave up on that, trying to make this js thing work!

1 Like

You’re welcome! image

Sit tight. Your locator is on its way.

Use this css selector:

#ext.sni.longDescription

Here’s the issue…

The page developers have used PERIODS in the id. Periods are special in CSS - they depict CSS CLASSES. So depending how Katalon is passing the selector along, you may need either:

#a\.b\.c

or

#a\\.b\\.c

My advice, call in the syntax police and tell them to quit being silly and use hyphens like any normal person would:

#ext-sni-longDescription
1 Like

That was one of many that I tried and never worked, I’m afraid!

Unfortunately my client is not the developer of this, it’s what they use for their product lifecycle management (PTC Windchill). So beyond emailing PTC to complain I think I’m stuck haha. But your method further up worked like a charm!

Unable to set text 'test' of object 'Object Repository/Attribute/fieldDescription' (Root cause: com.kms.katalon.core.exception.StepFailedException: Unable to set text 'test' of object 'Object Repository/Attribute/fieldDescription'
at com.kms.katalon.core.webui.keyword.internal.WebUIKeywordMain.stepFailed(WebUIKeywordMain.groovy:64)
at com.kms.katalon.core.webui.keyword.internal.WebUIKeywordMain.runKeyword(WebUIKeywordMain.groovy:26)
at com.kms.katalon.core.webui.keyword.builtin.SetTextKeyword.setText(SetTextKeyword.groovy:66)
at com.kms.katalon.core.webui.keyword.builtin.SetTextKeyword.execute(SetTextKeyword.groovy:37)
at com.kms.katalon.core.keyword.internal.KeywordExecutor.executeKeywordForPlatform(KeywordExecutor.groovy:60)
at com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords.setText(WebUiBuiltInKeywords.groovy:950)
at com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords$setText$7.call(Unknown Source)
at PM_Edit_AWM_V2.run(PM_Edit_AWM_V2:63)
at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194)
at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119)
at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:337)
at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:328)
at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:307)
at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:299)
at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:233)
at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:114)
at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:105)
at com.kms.katalon.core.main.TestCaseMain$runTestCase$0.call(Unknown Source)
at TempTestCase1575776781587.run(TempTestCase1575776781587.groovy:23)

Caused by: com.kms.katalon.core.webui.exception.WebElementNotFoundException: Web element with id: ‘Object Repository/Attribute/fieldDescription’ located by ‘By.cssSelector: #ext.sni.longDescription’ not found
at com.kms.katalon.core.webui.common.WebUiCommonHelper.findWebElement(WebUiCommonHelper.java:1113)
at com.kms.katalon.core.webui.keyword.internal.WebUIAbstractKeyword.findWebElement(WebUIAbstractKeyword.groovy:27)
at com.kms.katalon.core.webui.keyword.internal.WebUIAbstractKeyword.findWebElement(WebUIAbstractKeyword.groovy:26)
at com.kms.katalon.core.webui.keyword.builtin.SetTextKeyword$_setText_closure1.doCall(SetTextKeyword.groovy:51)
at com.kms.katalon.core.webui.keyword.builtin.SetTextKeyword$_setText_closure1.call(SetTextKeyword.groovy)
at com.kms.katalon.core.webui.keyword.internal.WebUIKeywordMain.runKeyword(WebUIKeywordMain.groovy:20)
at com.kms.katalon.core.webui.keyword.builtin.SetTextKeyword.setText(SetTextKeyword.groovy:66)
at com.kms.katalon.core.webui.keyword.builtin.SetTextKeyword.execute(SetTextKeyword.groovy:37)
at com.kms.katalon.core.keyword.internal.KeywordExecutor.executeKeywordForPlatform(KeywordExecutor.groovy:60)
at com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords.setText(WebUiBuiltInKeywords.groovy:950)
at com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords$setText$7.call(Unknown Source)
at Script1575503424136.run(Script1575503424136.groovy:63)
… 11 more
)

Try the backslashes.

Try makeTO and build the TestObject “live” yourself.

1 Like

Oh I see what you’re saying! That works also! I would have never realized that was needed. I’ve learned a lot from your answers on this post, thank you so, so much. I can go to bed without being racked with irritation, haha!

1 Like

image

image
Any ideas here? This one is totally different but I can’t find a working locator for either of these either! I tried the same thing that I used for this field on the form but it says it can’t find it (e.g. #ext\.sni\.longDescription)

First, a little background…

The # in a CSS selector means “id”. A dot in a CSS selector means “class”.

The following CSS selector…

div#my-id.my-class-name

matches this HTML element:

<div id="my-id" class="my-class-name">stuff<div>

Specifying div in the selector is redundant, since IDs should be unique across the entire document. So this selector is identical and less pedantic:

#my-id.my-class-name

And because IDs should be unique across the entire document specifying the class is also surplus to requirements:

#my-id

Not all elements have IDs. IOW, some elements make it a little harder to make a working selector to find them. In your first screenshot, you highlighted a TD element with an attribute called attrid.

You can search for any attribute using the attribute selector [attribute-name ...]

td[attrid='ext\.sni\.longDescription']

In English, that’s saying…

find all TD elements with an attribute called attrid with a value equal to ext.sni.longDescription.

Because it will “find all…”, you may need to be more specific. For example, if there is an ancestor element (further up the HTML tree, not shown in your screenshot) that can be identified as unique, prefix it to the selector above with a space.

e.g. let’s say there is a div element further up, with id=“jess”

#jess td[attrid='ext\.sni\.longDescription']

find the element with id = “jess”, then find all descendant TD elements with an attribute called attrid with a value equal to ext.sni.longDescription.

Now your second screenshot…

td[attrid='ext\.sni\.productHierarchy']

Again, if there is more than one such TD, you may need to be more specific.

Hope that helps?

1 Like

Thank you! That helped a lot with both of those, but it seems for every one that gets solved, another one pops up and I don’t understand how to write it to accurately target it!

For example this one, I figured input#ext\.sni\.longDescription would work, but Katalon insists it can’t find it.

For context, to make it more difficult, on this one, I need to somehow confirm that it’s not editable, which seems to be a whole other can of worms.

Or same with this one, need to first of all successfully locate it, then verify it’s disabled. But everything I’ve tried fails for so much as locating it.

First, let’s test that selector in JavaScript, in the browser (i.e. not in Katalon).

Put this in the browser console (in DevTools)

document.querySelector("#ext\.sni\.longDescription").value = "jess"

You may need to double the slashes.

1 Like
Uncaught TypeError: Cannot set property 'value' of null
at <anonymous>:1:60

Wow. Bad selector.

What does this do? (screenshot please)

document.querySelectorAll("#ext\.sni\.longDescription").length

image