now I have more complicated (at least for me) and struggling to find element (which is dynamic one - changes on daily basis). Following is how it looks on page. On top is 'ul'
<ul class="feed-tips" id="Grid"
Below are 50 'li' with same name:
<li class="feed-item vevent tip-list-row"
Below one of those 'li' are
<div class="tip medium-9 small-12 column padding-reset dtstart tip-list-row__tip">
Heading4
So, link to a page & Heading4 (in 'href') are dynamic ones and it will be useless from i.e tomorrow.
Above is 5th 'li' in the list and I tried to find element with css selector but it does not work - here is what I tried:
//Open 5th from the list
driver.findElement(By.cssSelector("#Grid > li:nth-child(5) > div.tip.medium-9.small-12.column.padding-reset.dtstart.tip-list-row__tip > div.tip-match.medium-12.column > div.tip-teams > a")).click();
Thank you in advance.
In case you are trying to find the anchor element with dynamic href, you can use somewhat the xpath as below:
//ul[#id='Grid']/li//div[contains(#class, 'tip-teams')]//a[#href]
I did not understand the total problem, but it will list down all the links with attribute href within that hierarchy. In this case, do not use any sort of indexing. Also, not required to drill down all the levels of hierarchy.
//a[#href] - It will provide you all links with #href without comparing any value.
Related
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
Could someone please assist me in order to find 5th 'li' element since that receiving error when trying to locate it. Following is how looks on page:
<ul class="navigation-primary navigation-primary--right js-navigation-primary">
<li><a data-modal="login-modal" href="javascript:void(0);" data-modal-content-switch="login-options" class="is-button-group-right js-prevent-trigger modal-content-button"><span>Logga in</span></a></li>
<li></li>
<li>Svenska</li>
Actually, I need last one with following attribute
data-menu="language"
Since there are several languages - I suppose that it would solve with if loop:
if (driver.findElement(By.xpath("//*[#id="header"]/div[2]/div/ul[2]/li[5]/a") != null
driver.findElement(By.xpath("//*[#id="header"]/div[2]/div/ul[2]/li[5]/a").click();
else {
system.out.println("element not present");
}
Since that there are several languages and every has last li[5] - thought that lang name could solve it, but did not find solution.
Thank you in advance
I know you accepted an answer but it would be a lot cleaner and clearer if you used a simple CSS selector like
driver.findElement(By.cssSelector("a[data-menu='language']")).click();
or you could be more specific and find the element by language using XPath
driver.findElement(By.xpath("//a[#data-menu='language'][.='Svenska']")).click();
Also, you can't check if an element is null. If it's not there, .findElement() will just throw an exception. If you want to check if an elements exists, use .findElements() and check to see if the collection is empty
List<WebElement> links = driver.findElements(...);
if (links.isEmpty())
{
// element doesn't exist
}
else
{
// element exists
links[0].click(); // or whatever
}
As per the HTML you provided the following xpath/cssSelectorshould work:
driver.findElement(By.xpath("//ul[#class='navigation-primary navigation-primary--right js-navigation-primary']/li[contains(.,'Svenska')]"));
OR
driver.findElement(By.cssSelector("ul.navigation-primary.navigation-primary--right.js-navigation-primary > li.navigation-primary.navigation-primary--right.js-navigation-primary"));
At the risk of redefining your question, I'd be tempted to add some id tags into your html and call driver.findElement(By.id(name)).
The advantage is that if an extra item is added to the start of list then your tests will not break.
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']
1.
(From:https://www.virustotal.com/en/file/7b6b268cbca9d421aabba5f08533d3dcaba50e0f7887b07ef2bd66bf218b35ff/analysis/)
I want to get the text in the picture, in Google Developer Tools I would do that (I basically went into another childnode of the span to find the md5 in DevTools but in Jsoup it seems different and only returns the "md5" text)
document.getElementById("additional-info-content").childNodes[1].children[1].childNodes[1].innerHTML
I cant manage to get it using JSoup dom/selector.
(If it's possible to give both of these examples)
2.
How do I specify a child in CSS in Jsoup?
For example, I right click on the span class field above the blue marked line in the picture, and click "Copy Selector":
#file-details > div:nth-child(2) > div:nth-child(1) > span
It gives me file-details as first div, even thought its not the only file-details in the document, but okay, lets say it should be like that(?):
#additional-info-content > div:file-details > div:nth-child(2) > div:nth-child(1) > span
How do I manage to translate it into a working JSoup CSS script with the child? (If possible then DOM example aswell)
3.
Is there a good insight on how to look and how to find the right path when looking for a specific value/node?
What I do now is basically open Developer Tools, then click on a unique div class name, and I check the properties window inside the DevTools for the child nodes, and keep digging with the child nodes till I find the right path...(Like I copied in the first question)
Is there a better way to look at this?
I mean, using the DevTools console is so simple, just writing
.children[1].childnodes[3].children[1] while looking at the properties and seeing the correct attribute that I need, but I know it's not the right way I guess?
1)
// connect to url and retrieve source code as document
Document doc = Jsoup
.connect(url)
.userAgent("Mozilla/5.0")
.referrer("http://www.google.com")
.get();
String md5= doc
// use CSS selector to grab only enums which contain md5
.select("div#file-details.extra-info > div.enum-container > div.enum:contains(md5)")
// use the first element in the result set
.first()
// use only its text node and ignore the text node of the span
.ownText();
2) There are lots of ways to specify children. You can use CSS selectors or some of the jsoup convenience methods.
If I want to extract the text foo from the following html:
<html>
<body>
<div>
<span><b>foo</b></span>
<span><b>bar</b></span>
</div>
</body>
</html>
Each of these will produce the same result:
doc.select("div > span > b").last().ownText();
doc.select("div > span > b").get(1).ownText();
doc.select("div > span:last-child > b").text();
doc.select("div > span:last-child").text();
doc.select("div > span").last().text();
doc.select("div > span").get(1).text();
doc.select("div > span:last-child > b").first().ownText();
doc.select("span > b").last().text();
Deciding which way to go really depends on the HTML structure of the document you are parsing. See CSS Selectors for more examples.
3) Examine the source code, not the code rendered in the browser. Jsoup does not invoke JavaScript. If the DOM of your page is changed onLoad, then you need to render the page before parsing it. Here is an example of how to do this: https://stackoverflow.com/a/38572859/1176178
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();