Thanks in advance!
I want to know if there is any way in CSS selector in which we can find nth element in page?
I believe in xpath if there multiple element which satisfies an xpath we can get nth element using below syntax:
//input[2] ' Select 2nd Input
Please note I am not looking for nth-child(n) or nth-of-type(n) which selects child element of parent.
Please note I am not looking for nth-child(n) or nth-of-type(n) which selects child element of parent.
That is how you locate the Nth element in CSS locators. If your looking for the Nth root element, you can use html or body as parent elements. By.CssLocator("body:nth(2)")
That seems like a strange solution though. Can you post more information describing your requirements? There may be a better way of locating the element than using a CSS locator. Of course if you have the ability to modify the source, than this could easily be fixed by design. I recommend using data-* attributes.
Related
Html:
<div class="component-multi-row-slide-title"> Cloth </div>
The xpath
/html/body/div/main/div/div/div[2]/div/div/div/div[1]/div/div***[4]***/div/div[2] the div[4]
keep changing. If new item come into web, developer will change the div number.
I want to click on 'Cloth'. The xpath keep changing when new category is added.
To start with using absolute xpath have certain disadvantages, as when new elements are added the xpath of the previously identified elements will keep on changing. Hence the solution would be to use Relative Xpath.
As per the HTML you have provided, to click on the element with text as Cloth you can use the following Locator Strategy:
XPath A:
//div[#class='component-multi-row-slide-title' and contains(., 'Cloth')]
XPath B:
//div[#class='component-multi-row-slide-title' and normalize-space()='Cloth']
Absolute Xpath: It contains the complete path from the Root Element to the desire element.
Relative Xpath: This is more like starting simply by referencing the element you want and go from the particular location.
You use always the Relative Path for testing of an element. The reason behind that is if you make any architectural change in the website the change won't effect the testing or selecting of the element.
So Use relative xpath which is as follows
WebElement cloth = driver.findElement(By.xpath("//div[normalize-space()='Cloth']"));
cloth.click();
Let me know if this doesn't help
I would recommend to use customized xpath. As given below:
driver.findElement(By.xpath("//div[contains(text(), 'Cloth')]").click
driver.findElement(By.xpath("//div[contains(text(), 'Fashion Acessories')]").click
It will work for sure. Feel free to let me know if something is wrong regarding xpath.
Thanks
You need to use relative xpath in this case.
You can use any xpath from the below options. The first two will find the element by text and the 3rd option by class.
1>>driver.findElement(By.xpath("//div[contains(text(),'Cloth')]")).click();
2>>driver.findElement(By.xpath("//*[contains(text(),'Cloth')]")).click();
3>>driver.findElement(By.xpath("//div[#class='component-multi-row-slide-title']")).click();
Let me know if the same class name exist for other elements also.
Just for you reference: XPath is used to find the location of any element on a webpage using HTML DOM structure.
The disadvantage of the absolute XPath is that if there are any changes made in the path of the element then that XPath gets failed.
So, in that case Relative Xpaths can be used:
//div[contains(text(),'Cloth')] or //*[contains(text(),'Cloth')]
//div[contains(text(),'Fashion Acessories')] or //*[contains(text(),'Fashion
Acessories')]
How to use:
driver.findElement(By.xpath("//div[contains(text(),'Cloth')]"));
You write the following code
driver.findElement(By.xpath("//div[normalize-space()='Cloth']").click
The above code will identify the element directly and also it would not be brittle in nature when developer changes the page elements.
I am trying to locate and element on my web page, but the element i want to locate has no unique Id's or anything of that matter. I have only a dynamically changing class name.
I tried using Absolute Xpath but its too brittle.
<div class="frca889813467244cd88b375adbb9452c2s4" style="left:274.05px;top:141.75px;width:94.5px;height:18.9px;"><div
class="frca889813467244cd88b375adbb9452c2s11">6000.00</div></div>
From above DOM i want to get the value every time i locate the above element (Here its 6000.00 but might change in other tests).
I will suggest going with absolute XPath, I know you mentioned you have a hard time creating absolute XPath. I guess below note can help
Note:- if you copy XPath from Firefox it will mostly give you absolute XPath whereas chrome on another side will give relative
or the other way is to make an XPath using another stable element in the tree
I hope this workout for yours. if you can share a link or inspect element snapshot showing Full DOM I can help you even better. Thanks :-)
The documentation on code.google.com describes the elementIdElement functionality as "Search for an element on the page, starting from the identified element". Does this mean the search is done for every element following that element throughout the rest of the web page or only for dependents of that element?
If it is the former, then how would I construct the "value" entry if the "using" parameter is "css selector" and I want to find a descendant of the current element's sibling? I thought the value would be "+ div .classname", but this doesn't seem to work.
One way you can do it is by emulating Selenium ByChained, by calling one wait after another:
browser
.useXpath()
.url('http://www.google.com')
.waitForElementVisible('.//body', 1000)
.waitForElementVisible(".//div[contains(#class, 'classVar')]")
.click('button')
The correct xpath string for navigating to an element's parent's following sibling for the existence of another element with a given class is
'(//div[#id="currentElementID"]/../following-sibling::*[1]//div[contains(#class,"classToLookFor")])[1]'
In this example, I know the current element's ID so that's what I use, but the '//div[#id="currentElementID"]' can be replaced with whatever you need to navigate to the starting element. Also, this example assumes the element I'm looking for is a div.
In my WebDriver project, I have planned to add Jsoup to get 'parent' and 'siblings' and few other features. I need to find an element through Jsoup and click its parent using WebDriver. That means I need to convert a Joup element object to WebElement object. Please let me know how I can do this, if this is feasible.
If it is not possible to integrate Jsoup and WebDriver in such way, then please discuss on how I can get parents and all using WebDriver.
Also, is it possible to list ALL possible elements present under a particular WebElement?
It's quite interesting we're doing the similar approach, integrating JSoup and Selenium WebDriver. I can understand your issue especially dealing with some dynamic website based on some Javascript framework which has no stable IDs or attributes.
Our solution looks like the following, and hopefully it could be some advice for you:
webDriver.getPageSource() to get the current HTML source
use JSoup to parse this HTML source, and leverage Jsoup selector (which is much more powerful than Selenium) to locate the target element
get parents or siblings of this element
write an iteration function to get element xPath, such as //body/div[2]/form[1]/input[3]
webDriver.findElement(By.xpath(...)) to locate element in selenium context
EDITED
The idea of the iteration function is:
first check the tag of your parent node, if it is body, then iteration ends
if not , then use getSiblings to check the index of the node among all the nodes with same tag, e.g, the 3rd div, then equals to div[3]
iterate to your parent node, and do the same procedures
Once you get the xpath of the child node, and parent node, just replace parent node xpath to be empty string inside the child node xpath, finally you can get the relative xpath.
You can use xpath selectors to select parent and child elements
Related questions
Select parent using xpath
XML xpath, get the parent element till a specific element
Getting child nodes using xpath?
What about running findElements with xpath : .//* on your particular element? Also, look into xpath parent::* and following-sibling::*. For the particular case I understand, there is no need for Jsoup.
I am just starting with Selenium and now in need to select this element:
<span class=" close">Matrices</span>
This line of code returns zero elements, so i guess it's not the right one :-)
ReadOnlyCollection<IWebElement> matrixLink = driver.FindElements(By.PartialLinkText("Matrices"));
But I could not find another one suitable, besides the Xpath, but that looks like this (//*[#id=\"Navigation\"]/div[2]/div[2]/ul/li[7]/span), and that seems a bit fragile to me?
EDIT:
the span has the class 'close'.
It's part of a menu, where there are 19 span's with the class 'close' so it's not a unique selector unfortunately....
This will work:
//*[#id=\"Navigation\"]/descendant::span[text()='Matrices']
Note that if you can, be specific in your XPath queries, mainly to aid readability and improve performance...that is the * in your query will query all elements in the page. I don't know what kind of element the Navigation element is, but you should put it's exact element type in, for instance if it's a div, make it:
//div[#id=\"Navigation\"]/descendant::span[text()='Matrices']
A slight explanation for this XPath is that it will grab the Navigation element, and simply look anywhere inside it to find a span element that has the text of Matrices. Without the descendant bit in the XPath, it would only search for direct children. That means elements that a child of Navigation, nothing else - so if an element is a child of TestDiv which is a child of Navigation, descendant would catch it, without it you won't return any results.
As for why By.PartialLinkText would not work, this would only search for anchor links. It is common, as you have seen, that anchor links have a span element inside them or sometimes it is just a span on it's own.
By.PartialLinkText and similarly By.LinkText would not 'see' this element, since it's not an anchor element.
My favorite problem solver for these cases:
Install Selenium IDE
Click the link you need
In the "target" in Selenium IDE you will see different xpath possibilities
But I would use the approach, that its N-th element with "close" class (//span[7] or something like that)
You can use //span[text()='Matrices']
It will select your element.