I am having a tree element from a jsp page. When clicking this span tag then I get more of the tree.
<span class="tree " onmouseout="onMouseOutTreeNode(this)" onmouseover="onMouseOverTreeNode(this)" onclick="onToggleTree('product_main', this)">
Categories
</span>
Any recommendations how to click with selenium on this span element to expand it more?
I appreciate your answer!
UPDATE
All these tree elements look the same. The only difference is their tag text.
Try this code (Assuming, there is just a single span tag in the webpage, with innerHTML/text as "Categories") :
driver.findElement(By.xpath("//span[#class='tree ' and contains(text(),'Categories')]")).click();
vote up for the answer, what concerns your further issues, if your code is really as posted so the class being with the blank, you need to access it via xpath with the blank as well
driver.findElement(By.xpath("//span[#class='tree ' and contains(text(),'Categories')]")).click();
Related
I'm trying to find an element by the text it contains, then check that that element also has a link to a particular place. I'm using selenium/java.
I'm trying to find elements by text when I can to minimise how many changes I will need to make if the UI is updated (reduce test maintenance costs).
I've tried the following, but the assert fails as the getAttribute ends up being null.
WebElement newsHeadlineTemplate = driver.findElement(By.xpath("//*[contains(text(), 'News Headline')]"));
Assert.assertEquals("Template not clickable", "/news/create/new", newsHeadlineTemplate.getAttribute("href"));
HTML for element I'm trying to find/use:
<div class="columns">
<div class="column is-one-third">
<p>News Headline</p>
</div>
</div>
I'm still fairly new to selenium so any help is very much appreciated.
Your XPath selector is a little bit wrong, you're matching <p> tag and you need to match the <a> tag which is the following-sibling for the <p> tag.
So you need to amend your expression to look like:
//p[text()='News Headline']/following-sibling::a
More information:
XPath Tutorial
XPath Axes
XPath Operators & Functions
i'm tried to select an element from an auto suggestion field but i got always an error saying that the element could not be found even that i'm sure my xpath is correct
here's my code :
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#class=\"ui-menu-item-with-icon ui-menu-item\"][1]")));
driver.findElement(By.xpath("//*[#class=\"ui-menu-item-with-icon ui-menu-item\"][1]")).click();
it should find //*#class=\"ui-menu-item-with-icon ui-menu-item\" which is the first suggestion albert cammus
here's the outerHtml
<li class="ui-menu-item-with-icon ui-menu-item" role="menuitem">
<a class="ui-corner-all" tabindex="-1">
<span class="item-icon"></span>
Albert Camus (SARCELLES)</a>
</li>"
Your XPath is more or less OK apart from using wildcard which may result into longer processing so you can go for li instead of *.
Another option is sticking to the <a> tag containing the text you would like to click using normalize-space() function something like:
//a[normalize-space()="Albert Camus (SARCELLES)"]
Also your popup may reside within an iframe so you might have to switch the webdriver context to the relevant iframe element.
Why don't you try linkText over Xpath ?
linkText is more stable then Xpath, there's no doubt about that.
Code :
wait.until(ExpectedConditions.visibilityOfElementLocated(By.partialLinkText("Albert Camus (SARCELLES)")));
I'm not very sure about spaces in your HTML, that's the reason why I have used partialLinkText
I have looked at the answers to similar questions and it seems like the code that I have should work but I get "Cannot click on element" error when the code invokes click on the web element.
Following is html markup segment
<div class="x-tree-node-item">
<a title="Manage Users" class="sidenavmenu_unselected" id="m-22" onclick="toggleMenu('22', '');" href="#">
<img title="" align="bottom" id="mi-22" alt="" src="ca/images/arrow.png" border="0">Manage Users
</a>
<div style="margin-left: 1em;">
<ul class="submenu-show" id="mp-22" style="height: auto; display: none;">
<li>
...
</li>
</ul>
</div>
Java code to locate the link is:
By xpath=By.xpath("//a[contains(#title,'Manage Users')]/img");
WebElement manageUsers = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(xpath));
manageUsers.click();
It finds the element but I get error:
org.openqa.selenium.ElementNotInteractableException: Cannot click on element
The ids are generated dynamically so we can't find by id and image source is used by multiple links.
Thank you for your help.
* Update *
The problem was solved with help from JeffC and Xwris. JeffC's last comment showed that there are multiple nodes being found. So, I added following code:
List<WebElement> manageUserImages=driver.findElements(xpath);
for (WebElement manageUserImage:manageUserImages) {
if (manageUserImage.isDisplayed()) {
manageUserImage.click();
}
}
Since there is only element displayed at one time with "Manage Users" as title, this finds the correct elements and delivers the desired results.
#JeffC, if you can post an answer with your comment, we can mark that answer as the correct answer.
Thanks again to everyone who helped.
It looks your xpath is wrong.
Personally I would start from the div and the drill down to the actual < a > tag.
In some cases where your web-element sits under a < li > tag, I would go even further up the tree and select a div which is not hidden.
i.e you instruct it to search for under the specific < div >
Who told you you can select only by id? You can use anything! :)
This should work.
//div[#class='x-tree-node-item']//a[#title='Manage Users']
This should work as well. Correct usage of 'contains' is as follows:
//div[#class='x-tree-node-item']//a[text()[contains(.,'Manage Users')]]
Hope this helps!
PS. notice that text contains is case-sensitive and will match partial text.
So if you searched for:
//a[text()[contains(.,'age User')]]
it will still be a successful match!
Update after OP's comments:
You don't actually need xpath helper. You just hit F12 in your browser and then CTRL+f so you open a search field at the bottom. Please see my example on how I locate the title of your question with partial text match ('Image').
Also notice next to xpath where it says 1 of 1 (meaning that our element is unique). Try to do the same for your case. I suspect that you need to go higher up the tree and start from an earlier < div > so you can locate the rest.
Leave off the "/img" part of your locator. You want to click the anchor (a) not the image itself.
By xpath=By.xpath("//a[contains(#title,'Manage Users')]");
WebElement manageUsers = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(xpath));
manageUsers.click();
Alternatively, the locator could be: //a[#id='m-22']
I have in my program a loop that prints a structure like this in each iteration:
<div class="grand-father">
<div class = "father">
<myTag>1</myTag>
<button>show more</button>
</div>
</div>
But after clicking the button the structure changes to:
<div class="grand-father">
<div class = "father">
<myTag>1</myTag>
<myTag>2</myTag>
<myTag>3</myTag>
</div>
</div>
So in my tests with page object model I'm trying to evaluate every myTag element in each "grand-father" element by doing:
List<WebElement> grandFathers = driver.findElements(By.xpath("//div[#class='grand-father']"));
for(WebElement gf : grandFathers){
//**Click the button of this father element to show more**
List<WebElement> myTagElements = gf.findElements(By.xpath(".//div[#class='father']/myTag"));
System.out.println(myTagElements.size());
}
My problem is that the last findElements for the myTag elements doesn't seem to be finding all the elements that weren't there before the "show more" button was pressed :( it's only counting one element even though all elements are already shown :/
Is there any way to tell selenium to "update" the variable according to the new html changes that weren't there when we first fetched the element? (Because I think that the problem might be that one)
Thanks if anyone can help!
It looks like you may have the answer already but for future readers, I would do something like this...
Grab all the DIVs with the class grand-father and loop through them looking for child BUTTONs. Click the BUTTON and then count the myTags.
List<WebElement> gfs = driver.findElements(By.cssSelector("div.grand-father"));
for (WebElement gf : gfs)
{
gf.findElement(By.tagName("button")).click();
System.out.println(gf.findElements(By.tagName("myTag")).size());
}
I solved the issue by refactoring all the code and clicking the "Show More" button when using findElements for the "father" elements, waay before using the findElements method for the myTag elements.
Keep this in mind when dealing with elements that will eventually show up in your DOM: First make all the operations that involve showing and processing data, then use Selenium to evaluate them :)
<div class="col-lg-3 col-sm-4 col-xs-6">
<div class="logo">..................</div> </div>
logo is inner div.
I need to acces col-lg-3 col... div content using xpath.
I did this in java:
WebElement mydiv = driver.findElement(By.className("col-lg-3 ")) ;
but it does not work - because it has spaces in the name.
How do I access this using xpath?
In CSS, you could access it like this:
driver.findElement(By.cssSelector(".col-lg-3 .logo"));
Since you asked, in XPath, it could be:
driver.findElement(By.xpath("//div[contains(#class, 'col-lg-3')]/div[contains(#class, 'logo')]")
As you can see, the CSS selector is much simpler.
To see xpath, I suggest to install Firebug and FirePath; those extensions are Firefox.
Example:
Can you see the image? xpath
Imagine that you don't have id neither name locators or you need to use xpath
Open Firefox.
Click on "Firebug". (#1)
There a panel.
Click on "Click an element in the page to inspect" icon (#2)
Click on "FirePath" tab. (#3)
Select the element that you wish (#4)
It displays the xpath into textbox. (#5)
So, you need to add this line:
driver.findElement(By.xpath("html/body/form/fieldset/p[1]/input"));