Why does nth-child equivalent work for css selector but not xpath? - selenium

I am trying to get the xpath equivalent of this css_selector of this website.
To get 6 elements I add: div:nth-child(1). For xpath it would be //div[1] yet this makes no difference. I am wanting all the 6 numbers under the left result tab
Css:
div:nth-child(1) > proposition-return > div > animate-odds-change > div > div
Returns 6 elements
xpath (quite similar):
//div[#class='propositions-wrapper'][1]//div[contains(#class, 'proposition-return')]//animate-odds-change//div//div
Returns 18
I desire 6.
<div ng-repeat="odd in odds" class="animate-odd ng-binding ng-scope" ng-class="{
'no-animation': oddsShouldChangeWithoutAnimation
}" style="">2.05</div>

Those are totally different selectors:
CSS: div:nth-child(1) > proposition-return > div > animate-odds-change > div > div
Find every div that is the first child of its parent, then get its direct proposition-return child (I assume you wanted to use it like .proposition-return, then its direct div and so on..
XPATH: //div[#class='propositions-wrapper'][1]//div[contains(#class, 'proposition-return')]//animate-odds-change//div//div
Find all div elements with proposition-wrapper as class, then only get the first. After, find all div with proposition-return class that are descendant of the previous element and so on..
[1] is very different to nth-child(1) to begin with, and also // is not the same as >, but / is.
For getting the specific elements that you want, I would use this xpath:
//div[contains(#class, "template-item")]//div[#data-test-match-propositions]/div[1]//div[contains(#class, "animate-odd")]

that site is not available worldwide, but looking at the img you provided helps. as eLRuLL points out, your xpath is not equivalent to the css.
try getting rid of some of the double slashes
//div[#class='propositions-wrapper']//div[contains(#class, 'proposition-return')]/animate-odds-change/div/div[contains(#class, 'animate-odd')]

Related

Choose the correct element from the list of objects with the same className

Quick one, i am trying to avoid using xpath and using css selectors due to performance issues xpath can have so i would like to know the right approach of locating for example "A" in the list
<div class="input-search-suggests" xpath="1">
<div class="input-search-suggests-item">A</div>
<div class="input-search-suggests-item">B</div>
<div class="input-search-suggests-item">C</div>
</div>
Currently i am locating A using xpath / span but it would be indeed sufficient locating all elements and then grabbing A from the list that have same class which is "input-search-suggests-item"
#FindBy(xpath = "//span[contains(text(),'A')]")
CSS_SELECTOR does not have support for direct text what xpath has.
What this means is, for the below xpath
xpath = "//span[contains(text(),'A')]"
based on text A you can not write a css selector.
Instead to locate A using css selector, you can do :
div.input-search-suggests > div.input-search-suggests-item
In Selenium something like this :
#FindBy(cssSelector= "div.input-search-suggests > div.input-search-suggests-item")
Even though it will have 3 matching nodes, but findElement will take the first web element.
Also you may wanna look at nth-child(n)
div.input-search-suggests > nth-child(1)
to make use of index to locate A, B, C
Here is the Reference Link

Unable to find CSS selector by :contains()

Unable to find CSS selector using :contains().
I have followed the instructions from https://www.browserstack.com/guide/css-selectors-in-selenium
at #5 – Inner text
but still, no result is shown, Can someone please help me/Tell me how to find Web element using text, CSS only
Here is Sample Dom
<ul id='id'>
<li class='class'>
<a class='class_class2' href="/Myaccount/summary">"Summary"</a>
<li class='class'>
<a class='class_class2' href="/Myaccount/Profile">"Profile"</a>
</ul>
Here : a:contains('Summary')
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference
https://stackoverflow.com/a/4781167/6793637
Contains: is no longer available
you should use xpath to find elements using innerText
xpath:
//a[contains(text(),"Summary")]
You can get exact match as
//a[text()="Summary"]
The :contains pseudo-class isn't in the CSS Spec and is not supported by either Firefox or Chrome (even outside WebDriver).
You can find a couple of relevant detailed discussion in:
selenium.common.exceptions.InvalidSelectorException with "span:contains('string')"
Finding link using text in CSS Selector is not working
Alternative
To locate the element with text as Summary you can use either of the following css-selectors:
Using first-child:
ul#id li:first-child > a
Using nth-child():
ul#id > li:nth-child(1) > a
tl; dr
References:
CSS selector :contains doesn't work with Selenium 2.0a7
css pseudo-class :contains() no longer allows anchors

Finding tag by xpath by a text that has an inner tag inside

I've recently come across an issue.
I need to find a div tag on a page, that contain specific text. The problem is, that text is divided into two parts by an inner link tag, so that an HTML tree would look like:
**<html>
<...>
<div>
start of div text - part 1
<a/>
end of div text - part 2
</div>
<...>
</html>**
To uniquely identify that div tag I'd need two parts of div text. Naturally, I would come up with something like this XPath:
.//div[contains(text(), 'start of div text') and contains(text(), 'end of div text')]
However, it doesn't work, the second part can not be found.
What would be the best approach to describe this kind of tag uniquely?
try to use below XPath to match required div by two text nodes:
//div[normalize-space(text())="start of div text - part 1" and normalize-space(text()[2])="end of div text - part 2"]
You were almost there. You simply need to replace the text() with . as follows:
//div[contains(., 'start of div text') and contains(., 'end of div text')]
Here is the snapshot of the validation :
This should work:
//div[contains(text(), 'start of div text') and contains(./a/text(), 'end of div text')]
Well if you have HTML DOM tree like this :
<div id="container" class="someclass">
<div>
start of div text - part 1
<a/>
end of div text - part 2
</div>
</div>
for extracting div text, you can write xpath like this :
//div[#id='container']/child::div
P.S : Writing xpath based on text to find the same exact text is not a good way to write Xpath.
If all you want is the div element of those child text elements, then you could isolate a piece of unique content from "part 1" and try the following:
//*[contains(., 'part 1')]/parent::div
This way you wouldn't have to think about the div's attributes.
However, this is usually not best practice. Ideally, you should use the following Xpath in most cases:
//div[#id,('some id') and contains(., 'part 1')]

How to get the text from the <text> tag using selenium

I cant able to get text from the Web Element on below mentioned tags:
<text dy="-.1em" class="c3-gauge-value" transform="" style="opacity: 1; text-anchor: middle; pointer-events: none; font-size: 9px;">95</text>
Need to get the value "95", that value will available inside the donot chart.
I am facing issue :
no such element: Unable to locate element: {"method":"css
selector","selector":"#chart > svg > g:nth-child(2) > g.c3-chart >
g.c3-chart-arcs > g > text"}
Anyone can you provide any solutions.
You can try xPath to locate your element:
//text[#dy = '-.1em' and #class='c3-gauge-value']
Btw it's probably necessary to add wait method to wait until element will be attached to DOM. Also make sure that your element is not in the iframe.
I don't know which language are you using, thats why I cannot provide the concrete example code for your case. But you can search on this site, there are many very good examples.
You can access it's text by,
driver.findElement(By.cssSelector(".c3-gauge-value")).getText();

how to locate element with selenium webdriver for below html

I have an issue clicking on the below HTML:
<div id="P7d2205a39cb24114b60b80b3c14cc45b_1_26iT0C0x0" style="word-wrap:break-word;white-space:pre-wrap;font-weight:500;" class="Ab73b430b430a49ebb0a0e8a49c8d71af3"><a tabindex="1" style="cursor:pointer;" onclick="var rp=$get('ctl00_ContentPlaceHolder1_ReportViewer1_ctl10_ReportControl');if(rp&&rp.control)rp.control.InvokeReportAction('Toggle','26iT0C0x0');return false;" onkeypress="if(event.keyCode == 13 || event.which == 13){var rp=$get('ctl00_ContentPlaceHolder1_ReportViewer1_ctl10_ReportControl');if(rp&&rp.control)rp.control.InvokeReportAction('Toggle','26iT0C0x0');}return false;"><img border="0" src="/Reserved.ReportViewerWebControl.axd?OpType=Resource&Version=10.0.30319.1&Name=Microsoft.ReportingServices.Rendering.HtmlRenderer.RendererResources.TogglePlus.gif" alt="+"></a> 2013</div>
I have used the below script to click anchor inside a div tag. For the above html code it is not fixed only end part of id example "26iT0C0x0" is fixed. The script that I have used is:
WebElement e1=wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[ends-with(#id,'26iT0C0x0')]/a")));
e1.click();
You can use the 'contains' method within an xpath lookup:
driver.findElement(By.xpath("//div[contains(#id,'26iT0C0x0')]")
I would recommend you to consider CSS selector alternative as CSS working faster, than xpath.
So 'contains' in attribute in CSS stands for '*=', for example
if we want to find attribute by 'CSS' ending in this: <htmlTag A="blablaCSS" > we need do the following:
String CSSselector="htmlTag[A*=CSS]";
and you get this element searched.
So considering your example CSS selector be like:
String cssSearched="div[id*=26iT0C0x0] a";
also try to click not on link - a
but on parent div as well:
String cssSearched="div[id*=26iT0C0x0]";
driver.findElement(By.cssSelector(cssSearched));
hope this works for you.
As Mark Rwolands already mentioned: the xpath-Function 'ends-with()' isn't supported in Selenium 2.
Also, if you maybe consider to use chromeDriver in the future, I would recommend clicking the image, not the anchor, see:
https://sites.google.com/a/chromium.org/chromedriver/help/clicking-issues
edit:
Also your IDs are looking generated. I wouldn't count on them for a stable test-environment.