How can i select this span element? - selenium

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.

Related

How to handle changing of absolute xpath?

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.

Get nth element from page using CSS selector in selenium

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.

selenium elementIdElement functionality

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.

Handling dynamic ids and classes

I am using selenium to test a web application, The ids and classes are always changing dynamically.So that I am not able to give correct identification, is it possible to get ids of the element in run time and is there any other method to handle this situation.
It depends on if ids are completely random or if there is some part of the id which remains the same. If yes, then cssSelector is the obvious choice
driver.findElement(By.cssSelector("div[id*=somePart]");
where id* means id contains. If you cant use this approach you will have to track down your element using xpath or again cssSelectors. XPath example is here and CSS selector could look like this
By.cssSelector("boyd table input");
I would strongly recommend locating elements by XPath -- with the caveat that you make your XPaths robust and not just "copy" the xpath using your browser's developer tools. XPath is very easy to learn. You can use XPaths to walk up and down the DOM, and identify elements by their text, or their attributes.
For example, maybe you need to click a button that has a span that contains the text that appears on the button:
<div class="btn-row random-generated-number-1234897395">
...
<button id="random-generated-number-239487340924257">
<span>Click Here!</span>
</button>
...
</div>
You could then use an xpath like this:
//div[contains(#class, 'btn-row')]//button/span[text()='Click Here!']/..
(The /.. at the end walks back up from the span to the button.)
XPath is powerful and flexible and easy to learn. Use it when the ids and classes aren't reliable.

How to use ExpectedConditions.visibilityOfElementLocated for multiple hits

I have a HTML site containing several context menues.
The xpath is: .//*[#id='TopIcon_Edit']/a/span. (This path will hit several elements)
In my test one of the context menues is visible.
I now want to verify that one context menu is visible, using
ExpectedConditions.visibilityOfElementLocated(By.xpath(".//*[#id='TopIcon_Edit']/a/span")).
Although I can see that the context menu is visible, the test tells me:
"Element does not meet condition visibility of element located by By.xpath: ..."
I assume that the method visibilityOfElementLocated(...) just evaluates the visibility of the first element it finds by the locator, which is not visible, as Selenium rightly sais.
I would appreciate any hints on how to solve this problem.
With kind regards,
Gerhard Schuster
Yes, when you search single element with Selenium and result returns more than one element, the method takes the first element and returns it.
So, you have to specify more precisely the xpath you using, for example: ".//*[#id='TopIcon_Edit']/a[1]/span", or similar, that will point only desired element.
If you can do away with xpath that would help. FindElement(By.cssSelector("#TopIcon_Edit span")).click() or do a list of web elements we = FindElements (By.cssSelector("#TopIcon_Edit span")); then filter your list based on style. Its far easier and provides greater flexibility to use cssSelectors.