I am currently working with Selenium and have now reached the interesting, yet incredibly difficult, world of CSS selectors.
I'm currently looking at selecting the different options of the Google tool bar. E.g when you search for something, on the results page you get options to search for the same term but under images, news, videos etc
I'm particularly interested in selecting the "Images" link.
I've been working on it for quite a while and the closest i have got is the below selector:
div a.q.qs[href]
This drills down into the right sub classes but there are 16 of them. Despite hours of aimless searching, i'm unable to complete the query with a contains method around the anchor text, which is unique in the targeted sub classes.
I'm aware there is a By LinkText option in Selenium, but i'm not sure if the anchor text is unique across the entire page. Also, i really want to understand CSS selectors in general so even if it was, i want to resolve this particular issue so i can apply it to future problems.
I'm looking for something like the below pseudo CSS selector:
div a.q.qs[href].Anchorcontains("Images")
Can anyone help?
All links have a unique parameter called tbm: its value is isch for images, so I'd go with
a[href*="tbm=isch"]
There are sometimes ways to get what you want with CSS selectors but if you want to find an element by contained text, you will have to use either link text/partial link text if it's a link or XPath for everything else.
The XPath for what you want is
//div[#id='hdtb-msb-vis']//a[.='Images']
You could use //a[.='Images'] but that returns two elements, one of which is not visible.
To break this down
// at any level
div find a DIV
[#id='hdtb-msb-vis'] that contains an ID of 'hdtb-msb-vis'
//a that has a child A at any level
[.='Images'] that contains text (.) equal to 'Images'
If you want to explore by link text, you can write something like
int count = driver.findElements(By.linkText("Images")).size();
and print count. My guess is that it will be 2, one of which is not visible. You can use Selenium to further filter this down to only the visible link, if you wanted.
You are going to have the same issue with BackSlash's CSS selector answer. You can tweak it slightly and solve this problem with the CSS selector locator
#hdtb-msb-vis a[href*='tbm=isch']
Here are some links to CSS references that will help you get started: W3C reference, SauceLabs CSS Selectors tips, and Taming Advanced CSS Selectors.
Related
I'm trying to select an iframe in selenium java but the element doesn't have a Name or Id attribute. How should I get it? (I want to use the switchTo to switch to it)
The website I am trying to get the iframe from is jklm.fun and the xpath of the iframe is
"/html/body/div[2]/div[4]/div[1]/iframe"
(you need to be in a game for the iframe to exist)
Same way you select anything, based on their tree position: regular CSS selector. You query-select body div div div iframe and you're almost certainly going to get it (unless you have lots of three-deep divs with iframes in them, in which case what on earth is going on on that webpage =), but if that still gives you multiple options, narrow the query selector using tactical :nth-child(...) pseudo-classes.
I would not suggest to go with absolute xpath :
/html/body/div[2]/div[4]/div[1]/iframe
rather have a relative xpath.
Having said that, as far as switching is concerned, there are multiple ways:
Using driver.switchTo()
This basically provides 3 overloaded methods: -
with index :-
driver.switchTo().frame(index)
with name or ID:-
driver.switchTo().frame(nameOrId)
with web element
driver.switchTo().frame(frameElement)
so out of these 3, we can easily use 2 of them since id or name isn't available in your case.
Using the index:
driver.switchTo().frame("here pass the index if you know. ")
Using frame web element:
driver.switchTo().frame(driver.findElement(By.xpath("/html/body/div[2]/div[4]/div[1]/iframe")))
this should work for you.
The other way we have is with Explicit waits:
new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("/html/body/div[2]/div[4]/div[1]/iframe")));
This is more convenient, way to switch to iframe in angular or react based Application.
I am not getting any locators except full Xpath and also all the left navigation elements are deep inside tags?
I would suggest you to read any articles or watch any free tutorials e.g. copy selector in chrome
But what you can do right now is to try to modify your long Xpath by adding unique classNames or id or ...
Of course would be great to see your problem, for example a piece of code with DOM elements from where you trying to get your Xpath
I want to send a text to a div element in web.whatsapp. I tried several ways ie using XPath, cssSelector, class name etc. but none is working for me.
This textbox comes when we attach an image in web.whatsapp.
Please step into the div and use the div with the class "selectable-text". As this is a contenteditable div you should be able to click into it and call then sendKeys() onto the element.
if this does not help please let me know then I will look in our code how we are filling such divs exactly.
You need to drill down further until you get to a web element that takes an input.
I'm trying to interact with a button on a page. Linktext and xpath do not work, there are no classes or combinations of selecting elements and looping through them I can find that work.
Here is the screen shot of the code I'm trying to do a .click()
Please help me how do i achieve the same ?
I think you have 2 options as below. I simplified your example HTML code to smoke test these queries:
Select an element based on its content. The drawback is of course that as soon as "Historical Scans" label changes to something else your query will stop working.
//nav[#id='secondaryNav']//ul[contains(#class, "menu")]//a[normalize-space(.)="Historical Scans"]
(working example on xpath tester http://xpather.com/dqZ7UWvz)
Select an element based on the position on the list. The downside is that it will stop working once this element changes its position.
//nav[#id='secondaryNav']//ul[contains(#class, "menu")]/li[3]/a
(http://xpather.com/rgexHKBB)
Based on my experience you should not rely on any other attributes or elements. Ideally, the best option would be to add ids/classes. Please let us know if this solves your problem.
What I am trying to do is to use HtmlUnit to get the href from the parent anchor of a span. Here is what I mean.
<span>Some Unique Text</span>
There is no id or name associated with either the or the tags, so going by this example, how would you find that link in a sea of others like it without ids or names?
Thanks!
use the XPATH //span[contains(.,'Transcript')]/parent::a/#href
(non tested, but XPATH is definitely the way to go)