Xpath not working in Katalon but works in Chrome Dev Tools

I have an Xpath that Chrome Dev Tools can locate just fine, but Katalon just looks around like John Travolta in Pulp Fiction. Could someone help me pinpoint what I’m doing wrong, please?

Here’s the xpath:
//img[contains(@src, 'SR-SE.png') and @ref_element = 'Object Repository/Navpoint/QQ5/QQ5Direct_SytemChooser/iFrame']/parent::div/parent::div/parent::li/preceding-sibling::li/descendant::div[text()='None']

I’m just trying to verify it is on the page and is previous to SR-SE.png:
WebUI.waitForElementPresent(findTestObject('Object Repository/Navpoint/QQ5/Reels/Mount_DropDown_None_option-InRelationToSE'), 10)

Here are the logs:

  1. 2019-11-12 15:26:19.021 DEBUG testcase.Reels_Mount_Brackets_Order - 14: waitForElementPresent(findTestObject("Object Repository/Navpoint/QQ5/Reels/Mount_DropDown_None_option-InRelationToSE"), 10)

  2. 2019-11-12 15:26:29.389 INFO c.k.k.c.webui.common.WebUiCommonHelper - Unable to find the element located by 'By.xpath: //img[contains(@src, 'SR-SE.png') and @ref_element = 'Object Repository/Navpoint/QQ5/QQ5Direct_SytemChooser/iFrame']/parent::div/parent::div/parent::li/preceding-sibling::li/descendant::div[text()='None']'. Please recheck the objects properties to make sure the desired element is located.

  3. 2019-11-12 15:26:29.396 WARN k.k.c.w.k.b.WaitForElementPresentKeyword - Object 'Object Repository/Navpoint/QQ5/Reels/Mount_DropDown_None_option-InRelationToSE' is not present after 10 second(s)

Here’s a screen shot of the element and it’s HTML.

This css will select the UL element:

#mountDropdown_listbox

This will select the first child LI element

#mountDropdown_listbox > li

This will select the div element highlighted in your image.

#mountDropdown_listbox > li > div > div

One of the problems with xpath, while it’s a notional standard, implementors don’t draw from a common source (or spend much time verifying it works).

Russ,

Thank you!

The thing Xpath provides me in this case is the ability to key off another element. I want to verify that the “None” is above the “Bracket SE”, for example.
Is there another/better way to do that?

Thanks,
Sarah

Sorry, I didn’t mean to lead you astray. There is no “contains” or text() equivalent in CSS. You can either fix whatever is wrong with your original xpath, or use a combination of CSS and JavaScript. For the former, I’m not you’re guy. For the latter (assuming you need the help) let me know.

Try this approach out:

1.) Try this xpath:

//ul[@id='mountDropdown_listbox']/li[.//div[text()='None'] and ./following-sibling::li[.//div[text()='Bracket SE']]

In plain english:

The list item (the <li> element) within the “Mount Options” dropdown (the <ul> element) which has the text ‘None’ and also has a following sibling list item which has the text ‘Bracket SE’.

2.) Usually, you would use the waitForElement__() family of methods as a way to handle timing, and not as a way to validate the presence/non-presence of something. For “verifying it is on the page”, you should probably use the verifyElement__() family of methods instead:

WebUI.verifyElementPresent(findTestObject('path/to/my/object'), 10)

This will act as a true assertion, and will fail the test if evaluated to false. When you instead use the waitForElementPresent() method as you have, you can see that you’ve just gotten a warning (#3 from your original post) and the test will continue regardless, which I’m assuming is not what you want.

Let me know if this works for you! :smile:

1 Like

no, will not. see recent topics on this matter

1 Like

Links… ?

@Brandon_Hein
one of them:

@Ibus Thanks, I also do not use the WebUI API, so I was not aware of this. The verifyElement__() and waitForElement__() methods have been a point of contention for a while. I even posted on it way back in the day:

@sarah.kladstrup In that case, if you indeed want the test to stop on failure, a simple approach would be to just assert the result of the verifyElementPresent() call, which I believe returns a boolean value:

assert WebUI.verifyElementPresent(findTestObject('path/to/my/object'), 10)

Or to join the rest of us, and implement your own framework :slight_smile:

1 Like

@Brandon_Hein it’s a recent update which changed the behaviours … we still debate on what is the best aproach.

until a decision will be taken, assert is a good workaround (but note that this may change also)

1 Like

@sarah.kladstrup Curious if any of this has helped. Were you able to get something working?

@Brandon_Hein I liked your suggestion of
//ul[@id='mountDropdown_listbox']/li[.//div[text()='None'] and ./following-sibling::li[.//div[text()='Bracket SE']]
but that did not work, unfortunately. I still have some troubleshooting to do here.

I will use the assert functionality, however.

One other thought: Are you working with iframes (does the element you are trying to work with live within an <iframe> element)? This can affect element location a lot of the time.

Yes, but all my objects have their parent iFrame included by Katalon.
To clarify: in every object, I have selected the iFrame using Katalon’s “Have Parent Object?” setting.

I strongly believe this is part of your problem. Historically, the “Have Parent Object” functionality is very hit-or-miss (see this post). Instead, try removing that property from your test object, create a new test object that locates the parent frame, and handle switching to it yourself as a separate test step, like this:

WebUI.switchToFrame(findTestObject('path/to/iframe/object'), 10)
assert WebUI.verifyElementPresent(findTestObject('path/to/my/object'), 10)

Note: If the particular iframe that the element in question lives in is further nested in other iframes, you will of course need multiple switchToFrame() calls to get down to the correct one.

1 Like

@Brandon_Hein While I think that’s a good idea in generally, I don’t have this issue with any of the dozens of other objects in the same module/application. And it’s not the element itself. I have a second object that Katalon uses to interact with it successfully, and again, it has the same parent iFrame included.

Sarah, take a look at this…


  

More here: Groovy(JavaScript(CSS))

Let me know if you want to try it.

Fair enough. At the very least, instead of removing the parent iframe setting altogether as I’ve suggested, you could try creating a test object for the iframe and switching to the frame yourself once, just to see if it works. At least then, you can narrow down what’s actually giving you trouble :slight_smile:

By.xpath: //img[contains(@src, 'SR-SE.png') and @ref_element = 'Object Repository/Navpoint/QQ5/QQ5Direct_SytemChooser/iFrame']/parent::div/parent::div/parent::li/preceding-sibling::li/descendant::div[text()='None']

Somehow this xpath looks strange to me, perhaps a little bit overwhelmed, so I need to test the assumption that it’s correct. Can you confirm (by image preferably) that when you paste this xpath into the Inspection Tool, it successfully highlights your object ? Please do the same with with Brandon’s xpaths.

Because in the xpath I see that it has information of Katalon (namely the part ‘Object Repository’) which the Web Driver will never know, therefore I highly doubt that this is the correct XPath. Exploring @Brandon_Hein’s direction, please post the image of your Test Object.

Another direction, from the image you posted there is a pre-condition (clicking or hovering on the select) to the presence of that element, please confirm that at the time the test fails, you can visually see the element.

Please also share the full script, and the full console log, cause maybe we may see a clue there.

I had the same thought, because that xpath in no way reflects what is in the screenshot of the HTML for the target element. I based my suggestion for an xpath on the HTML screenshot, hence why it looks so different than the one in the OP.

1 Like