CSS Selectors with changing values


#1

Hi!

I have a CSS selector value that is sometimes appended with -prevClone. Is it possible to set the selector editor so it looks for the presence of sponsored-#### within the first selector field? Screenshot showing the two selectors follows…

Thanks!
Morgan

2019-05-08_11-11-35


#2

Not sure what you mean be that.

This is how to return an element that starts with a given sequence of chars:

[id^=sponsored-] > div > blah blah blah

And ends with, in case you need it…

[id$=something] > div > blah blah blah

and contains

[id*=something] > div > blah blah blah

#3

Sorry, this is my first attempt at using CSS Selectors - you picked up what I was putting down, though. I’ll give it a go! Thanks!!! :sunglasses:


#4

Be careful though, if BOTH those elements are present, the selector will return BOTH elements. Let me know if that’s the case.


#5

It seems to find it, which is awesome! Thanks! Oddly, not on the first time - it rotates through the carousel a few times then finds the item I’m looking for (the id value is different each time it actually does click it so there’s something more going on that I need to dive into). I’ll post about that separately - this seems to be the solve for this particular issue. Thanks!

For future me, I adjusted the Selector Editor on the object to be…

[id*=sponsored-14395] > div > div.actions.product__actions > div.actions__alignmentContainer > button

#6

This selector would match both of the elements. Are you sure it is working right?

Maybe the other one is hidden or something…


#7

Ya know… it worked a few times then I tweaked something and couldn’t get it working again. I get what you are saying, it could be finding the hidden element (I hate carousels). Suggestions?


#8

Use Russ’s (am I spelling this right? To many s-es :slight_smile: ) “ends with” locator. It should select only the first element.


#9

Maybe they hate you? That’s okay, they’re pretty shallow anyway. :confused:

If the selector returns more than one element, what happens next depends on the code using it. Mostly it just wont work (Click for example won’t blindly click 100 elements).

So. Show me your code. And the css if it’s changed.


#10

We are SO close! Changing it to $ like so…

[id$=sponsored-14395] > div > div.actions.product__actions > div.actions__alignmentContainer > button

…seemed to work much better when the item returned has an ID that’s simply sponsored-14395. BUT when the object CSS is returned as…

#sponsored-14395-postCalone > div > div.actions.product__actions > div.actions__alignmentContainer > button

… the object is unable to be located. Other ideas of things to try? Thank you both!


#11

That’s right, because $= means “ends with” and sponsored-14395-postCalone doesn’t end with sponsored-14395.

The question I have now is, do you know in your code when the longer ID appears? Because if you do, you can try this:

[id*=sponsored-14395][id$=postCalone] > ...

#12

True… I believe it’s consistently when the carousel navigation occurs. I’m sure I can set the selector value when the navigation occurs. I’ll play with that a bit and update shortly. Thank you!!!


#13

If you’re using TestObjects Morgan, you’ll probably need to use makeTO.

In this first article, ignore the title, Katalon guys got it wrong when they copied my code to the docs. It doesn’t touch the OR. It should say

Creation of TestObject in Memory at Runtime

And to modify an existing TO …


#14

Just a sidenote on this (sorry to beat a dead horse), I have played around quite a bit with the contains and starts with options (* and ^) but have yet been able to get them working. Are you aware of any bugs with this? The only one I can consistently get to work is ends with ($), everything else results in an error that the object could not be found. Thanks!


#15

If there were bugs in how those css selector work, two things would happen:

  1. The web would break.
  2. The world as we know it would cease to exist.

Not to mention the many (150,000+?) lines of my own code that would break.

Trust me, Morgan, there’s something else wrong.

Refresher:

We have an ID used in the HTML like this:

<div id="this-is-my-id">This is a test div</div>

This css selector will find the element with the exact ID of this-is-my-id

#this-is-my-id

This one will find any/all elements with is-my mentioned in their ID:

[id*='is-my']

This will find all elements with ID starting with this-is

[id^='this-is`]

This will find all elements with ID ending with my-id

[id$='my-id`]

#16

Playing around with this some more… I’ve got a theory on what’s going on. I was using the Object Repository Object - CSS selector and feeding that object into WebUI.verifyElementVisible. My guess is that with the start’s with and contains, it’s first finding the first instance of that object in the dom but then saying “hey ya dummy… that isn’t visible.” and failing. When I use cssSelectors from the WebDriver within the scripts themselves, I’m then able to get them to locate the elements with starts with / ends with / contains without issue.

WebDriver driver = DriverFactory.getWebDriver()

WebElement sponsoredPrd = driver.findElement(By.cssSelector('[id^=sponsored-14395] > div > div.actions.product__actions > div.actions__alignmentContainer > button')) 
WebElement sponsoredPrd = driver.findElement(By.cssSelector('[id*=sponsored-14395] > div > div.actions.product__actions > div.actions__alignmentContainer > button')) 
WebElement sponsoredPrd = driver.findElement(By.cssSelector('[id*=sponsored-14395][id$=postCalone]> div > div.actions.product__actions > div.actions__alignmentContainer > button')) 

In sum, I think it was how I set this up that didn’t jive quite right.

Last thing on this - because it’s entirely new territory for me - using the above method for object identification, what is the suggested way to identify and act upon an element that is only visible? Again, I can find 3 occurrences-ish of the element with this ID in the dom, but only one of those that I actually want and it seems the element sporadically has postCalone or preClone appended. Maybe feed in a check for either of those CSS selectors, loop through them with an if statement? But I’m not sure how to handle the check for whether it’s visible with the WebDriver method. :thinking:

Thanks again for the help!
Morgan


#17

That’s how it works - it’s static. But you can…

Or, do like I do, use JS for everything. :confused:


#18

It certainly sounds as thought you have timing issues. Given enough time, maybe the IDs “settle” and go back to being without the suffixes?

Oh… I’ll defer. @Brandon_Hein seems to be back… I’m sure he’ll be along shortly. :wink:


#19

The usual WebDriver method for checking element presence is:

boolean present = driver.findElements(...).size() > 0;

The usual WebDriver method for checking element visibility, given that the element has already been found, is:

boolean visible = element.isDisplayed();


#20

A-ha! I’ll play around with this. Thank you!