xpath does not get the web element which has multiple classes - java

I am very new at Java and Selenium so my apologies in advance if my question sounds a bit primary.
I am using Selenium and Java to write tests. But have issue with finding elements. I know some other ways to find this WebElement,
but why this:
WebElement we1 =driverChrome.findElement(By.xpath
("//div[contains(#class,'elfinder-cwd-filename ui-draggable') and #title='project.CPG']"));
can not get this:
<div class="elfinder-cwd-filename ui-draggable" title="project.CPG">project.CPG</div>
and shows this error:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no
such element: Unable to locate element:{"method":"xpath","selector":"
//div[contains(#class,'elfinder-cwd-filename ui-draggable') and #title='project.CPG']"}
this works:
WebElement we1 = driverChrome.findElement(By
.xpath("//div[contains(#class,'elfinder-cwd-filename') and #title='project.CPG']"));
but these ones do not work:
WebElement we1 = driverChrome.findElement(By
.xpath("//div[contains(#class,'ui-draggable') and #title='project.CPG']"));
WebElement we1 = driverChrome.findElement(By.
xpath("//div[#class='elfinder-cwd-filename ui-draggable' and #title='project.CPG']"));
Sounds weird, this:
WebElement we = driverChrome.findElement(By
.xpath("//div[contains(#class,'combine-red')]"));
just worked for this:
<div class="leaflet-marker-icon combine-red-off leaflet-zoom-hide leaflet-
clickable" tabindex="0" style="margin-left: -17px; margin-top: -19px; left:
149px; top: 302px; z-index: 10304; transform: rotate(450deg);"></div>

but why this:
WebElement we1 =driverChrome.findElement(By.xpath
("//div[contains(#class,'elfinder-cwd-filename ui-draggable') and #title='project.CPG']"));
can not get this:
<div class="elfinder-cwd-filename ui-draggable" title="project.CPG">project.CPG</div>
Its because of Selenium's Class selector does not support Compound class names. Its search for exact class name (any part of compound class name), but not compound class name.
This code:
WebElement we1 = driverChrome.findElement(By.
xpath("//div[#class='elfinder-cwd-filename ui-draggable' and #title='project.CPG']"));
possibly can not work if there is some extra spaces or if on page generation classnames was change its place... like:
'elfinder-cwd-filename ui-draggable''
'elfinder-cwd-filename ui-draggable '
or
'ui-draggable elfinder-cwd-filename'
and here...
WebElement we1 = driverChrome.findElement(By
.xpath("//div[contains(#class,'ui-draggable') and #title='project.CPG']"));
possibly you miss dot on the beginning. Try this:
WebElement we1 = driverChrome.findElement(By
.xpath(".//div[contains(#class,'ui-draggable') and #title='project.CPG']"));

When you write contains, try mentioning only one class without any space. IT should solve your issue. Here's how -
WebElement we1 =driverChrome.findElement(By.xpath
("//div[contains(#class,'elfinder-cwd-filename') and #title='project.CPG']"));
If you want to mention both the classes then give that without contains tag. Here's how -
WebElement we1 =driverChrome.findElement(By.xpath
("//div[#class='elfinder-cwd-filename ui-draggable' and #title='project.CPG']"));
Hope this helps.

just try "=" instead of contains:
WebElement we1 =driverChrome.findElement(By.xpath
("//div[#class='elfinder-cwd-filename ui-draggable' and #title='project.CPG']"));
If it still does not work, it is possible that the element is not yet in the DOM when you are trying to find it, then you should try to place an implicit wait in front of your commands:
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

Related

Java Selenium FindBy cannot find div by unique class name

I am using Selenium with Java and I have encountered issue that I am unable to find div by class name, even though it is unique:
<div class="123123-randomclassname"></div>
I am able to find any other element, e.g. input, button, etc. I have issues with div tag only.
I have tried getting this web element using either #FindBy() annotation and findElement() method:
driver.findElement(By.className("123123-randomclassname"))
driver.findElement(By.cssSelector("div[class='123123-randomclassname'"))
#FindBy(className = "123123-randomclassname")
#FindBy(css = "div[class='123123-randomclassname'")
Any of these solutions did not work and I couldn't find element.
Try with following css selector
driver.findElement(By.cssSelector("div[class^='123123-']"))
//# and ]closing bracket was missing in syntax
WebElement DivTag = driver.findElement(By.xpath("div[#class='123123-randomclassname']"));
//OR
#FindBy(xpath = "div[#class='123123-randomclassname']") WebElement DivTag2;

How to find nested elements by class in Selenium

I have a div inside a div inside another div. Most outer div class is "Big Div", inside it there is a div with class "Medium Div" and the most inner div class is "Small Div".
I'm able to see the div's classes when I press the F12 key and hover over the elements, however I can't find them using Selenium.
What am I doing wrong?
WebElement big = browser.findElement(By.cssSelector("//div[contains(#class,'Big')]"));
WebElement medium = big.findElement(By.cssSelector("//div[contains(#class,'Medium')"));
WebElement small = medium.findElement(By.cssSelector("//div[contains(#class,'Small'"));
Note: my classes contain white spaces, Selenium can't find any of the divs and I get the exception: "No Such element".
The syntax you have used that is not for cssSelector that for XPATH and you have missed parenthesis as well.
Try following xpath now.
WebElement big = browser.findElement(By.xpath("//div[contains(#class,'Big')]"));
WebElement medium = big.findElement(By.xpath(".//div[contains(#class,'Medium')]"));
WebElement small = medium.findElement(By.xpath(".//div[contains(#class,'Small')]"));
However you can do it in once like.
WebElement small = browser.findElement(By.xpath("//div[contains(#class,'Big')]//div[contains(#class,'Medium')]//div[contains(#class,'Small')]"));
I would like to add a few lines to the answer of #KunduK
WebElement small = browser.findElement(new ByChained(By.xpath("//div[contains(#class,'Big')]"),By.xpath("//div[contains(#class,'Medium')]"),By.xpath("//div[contains(#class,'Small')]")));
When selenium already gives a few extra implementations, then why not to use it. :-)
You can get more details from the below link:
How Selenium's ByChained class really works?
https://www.linkedin.com/pulse/selenium-classes-stabilize-ui-automation-code-durga-behera/
Brackets are missing in the locator:
WebElement big = browser.findElement(By.cssSelector("div[class*='Big']"));
WebElement medium = big.findElement(By.cssSelector("div[class*='Medium']"));
WebElement small = medium.findElement(By.cssSelector("div[class*='Small')]"));
There is syntactical errors in placing parenthesis and the locator type used.
Try below code,
WebElement big = browser.findElement(By.xpath("//div[contains(#class,'Big')]"));
WebElement medium = big.findElement(By.xpath("//div[contains(#class,'Medium')]"));
WebElement small = medium.findElement(By.xpath("//div[contains(#class,'Small')]"));

Trying to find text element in a span

I am coding a selenium webdriver test in Java. I need the test to click on a "Yes" button in chrome that does not have an id or name.
I cannot find the element to click on the button that only has "Yes" as its unique identifier. There is also a "No" button.
I have tried to find the WebElement using xpath, classname and I have tried findElements function. Nothing succeeds.
This is the HTML:
<span class="ui-btn-inner">
<span class="ui-btn-text popup-anchor-text">Yes</span>
</span>
I have tried:
WebElement yesBtn = browser.findElement(By.xpath("//div[#class='ui-btn-text popup-anchor-text']/span"));
WebElement yesBtn = browser.findElement(By.xpath("//span[.='Yes']"));
WebElement yesBtn = browser.findElement(By.xpath("//div[contains(text(), 'Yes')]"));
WebElement yesBtn = browser.findElement(By.xpath("//button[#class='ui-btn-text popup-anchor-text' and span='Yes']"));
WebElement yesBtn = browser.findElement(By.xpath("//div[#class='ui-btn-text popup-anchor-text' and span='Yes']"));
yesBtn.click();
List<WebElement> yesBtn = browser.findElements(By.className("ui-btn ui-shadow ui-btn-corner-all ui-btn-up-a"));
yesBtn.get(0).click();
Error message:
NoSuchElementException; no such element. Unable to locate element.
The correct XPath locator would be:
//span[text()='Yes']
Just in case you can go for normalize-space() function:
//span[normalize-space()='Yes']
If this doesn't help:
Make sure that the span doesn't belong to an iframe, otherwise you will have to switch to the iframe before attempting to locate the element.
driver.switchTo().frame("your-frame");
Make sure to use WebDriverWait class just in case the element is not immediately available so WebDriver would perform several find attempts with polling interval
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//span[text()='Yes']")));
Try out //span[#class='ui-btn-inner']/descendant::span[contains(text(), 'Yes')]. It should help out.

Selenium - unable to locate element by classname

I want to find a p tag with class = "big-number". Here is the code I wrote:
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.className("big-number")));
System.out.println(driver.getTitle());
System.out.println(myDynamicElement);
Here is my output:
[[FirefoxDriver: firefox on MAC (fed46ad4-9ca9-9344-a57a-1d336db3927c)] -> class name: big-number]
I cannot identify the error, it is giving me an output but its makes no sense to me.
Any tips on how I can at least identify my error?
I am certainly sure the element is present, here is the HTML code:
<div id="users-online-container" style="">
<img class="big-number-icon" src="images/usersOnline.png">
<p class="big-number">228</p>
<p class="caption">Users Online</p>
</div>
<div id="users-online-loading"></div>
TimeOutException occurs because driver cannot find element in specific time. Problem in selector i think. If you sure that element always visible, and exists on the page so try next code:
//Select first paragraph in div
driver.FindElement(By.CssSelector("#users-online-container .big-number"));
//if you have several p with same classes you could access any of them using index. e.g.
driver.findElements(By.CssSelector(".big-number"))[index];
Selectors can be #users-online-container .big-number or .big-number. Both will work.
Try below code..
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.className("big-number")));
// It will print the text of the Element:
system.out.println(myDynamicElement.getText());
Also you try to locate the element with the help of XPATH and make sure your locator is uniquely identify the element. Also check that IsDisplayed() and IsEnabled() returns True.
In your code you are printing the WebElement that will print the Hashcode.
In order to get the text of the Element, you'll have to use getText() method.
Hope it will help!

webdriver classname with space using java

This question received great answers in jquery and I was wondering if someone could give an example of this in Java please?
I'm doing driver.findElement(By.className("current time")).click(); The space is the issue, and I see the explanation at the link, but I'm not sure how to handle it in java, and don't have access to change the class name.
Pasting example of what i get in the firefox inspect id: Example with cssSelector below did not work, but i may be missing something.
<span>
<a class="current time" href="http://someurl/" onclick="s_objectID="http://someur/">url</a>
</span>
Instead of class name you can use a css selector. You don't mention the tagname for the class 'current time'. I am assuming it to be input, so your css selector work be,
WebElement element = driver.findElement(By.cssSelector("input[class='current time']"));
element.click();
Edit#1 Based on html provided,
Looking at the html in your comment, it seems you have quite a few options to find the webElement. Here are your options,
WebElement element = driver.findElement(By.cssSelector("a[class='current time']"));
element.click();
or this should work too,
WebElement element = driver.findElement(By.cssSelector("a.current.time"));
element.click();
You can also use linkText since the element is link. From the html you provided, the link text is 'url'
WebElement element = driver.findElement(By.linkText("url"));
element.click();
You can also use By.partialLinkText("partial link text here");
You can also use xpath as:
WebElement element = driver.findElement(By.xpath("//a[#class='current time']"));
element.click();
OR,
WebElement element = driver.findElement(By.xpath("//a[text() = 'url']"));
element.click();
For a less fragile test, another option is to use an XPATH which doesn't depend of the order of classes, like:
WebElement element = driver.findElement(By.xpath("//a[contains(#class, 'current') and contains(#class, 'time')]"));
Whenever you found some space in the class name you need to switch to cssSelector Locator.
Convert a class name to cssSelector if it is having a space as below.
In your case it would be:
WebElement element = driver.findElement(By.cssSelector(".current.time"));
element.click();
PS: add . [dot] in start of class name and replace the space with . [dot] to convert class name to cssSelector.

Categories

Resources