Selenium find and click img with a text inside div - java

I am new to xpaths in selenium and trying to click on Next> image/button in the code below. I have tried following two xpaths but its not working and giving no element not found error.
By.xpath("//div[#class='pzbtn-mid']/img[contains(text(), \"Next >\")]"))
By.xpath("//div[#class='pzbtn-mid']/img[contains(text(), 'Next >')]"))
What am i doing wrong here?
<div class="pzbtn-mid" data-bindprops="innerHTML" data-click="...."> ==$0
<img src="webwb/zblankimage.gif" alt="" class="pzbtn-i">
"Next >"
<img alt="" src="webwb/zblankimage.gif" class="pzbtn-i">

As per the HTML you have shared to click() on the Next> image/button you can use the following xpath :
By.xpath("//div[#class='pzbtn-mid']/img[#class='pzbtn-i' and #src='webwb/zblankimage.gif']"))
Note : The text Next > is not within any of the <img> tags but within the <div> tag. Hence to click on the image/button you have to reach till the <img> tag.

You can also use xpath below,
By.xpath("//div[contains(#class,'pzbtn-mid') and contains(.,'Next >')]//img")
It clicks the first image if the img belongs to next. Othervise you should click the second img like below;
driver.findElementsBy((By.xpath("above xpath")).get(1));

Related

Clicking on Image Link with Selenium webdriver java

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']

Clicking on <li> list item not using Selenium Java

The following list represents page navigation buttons:
<div class="list">
<ul class="pageNav">
<li class="paginate_button ">
1</li>
<li class="paginate_button ">
2</li>
<li class="paginate_button ">
3</li>
</ul>
</div>
To go to the second page for instance, I am using this Selenium Java code:
//after setting up webdriver
List<WebElement> li = driver.findElements(By.className("pageNav"));
System.out.println(li.get(2).getText());
li.get(2).click();
It's printing the text correctly "2", but not clicking or navigating correctly as if I was manually doing it on the actual website. I also tried replacing the link with an actual link like:
Visit our page
But still no luck. What am I doing wrong?
Thank you in advanced!
Try any of these below code.
In your tried code, I have noticed that you were using class locator to click on links element. But your <ul> tag does not contains the link. Inside <ul> tag, <li> tag is present and each <li> tag contains separate <a> tag.
so, here you should go with xpath or cssSelector locator.
Method 1) By using xpath locator
List<WebElement> links = driver.findElements(By.xpath("//ul[#class='pageNav']/li/a"));
System.out.println(links.size());
links.get(1).click(); //indexing start from 0, if you want to click on second link then pass indexing as 1.
Suggestion:- Instead of using absolute xpath, use relative xpath.
Method 2) By using cssSelector locator
List<WebElement> links = driver.findElements(By.cssSelector("ul.pageNav>li>a"));
System.out.println(links.size());
links.get(1).click(); //indexing start from 0, if you want to click on second link then pass indexing as 1.
Try below code
//getting all the anchor tag elements and storing in a list
List<WebElement> links = driver.findElements(By.xpath("//ul[#class='pageNav']//li[starts-with(#class,'paginate_button')]/a"));
System.out.println(links.size());
//performs click on second links
links.get(1).click();
If you're facing any abnormal difficulty which you are not able to handle directly , then you can first try to move to that element using actions class then click it as below:
WebElement we = driver.findElement(By.cssSelector("div.list > ul.pageNav li:nth-child(2));
Actions action = new Actions(driver);
action.moveToElement(we).click().build().perform();

How to change source code of page? using selenium and java

I have source code of page like this:
<header style="position: fixed;">
When I use my script on java, I can't execute click action, because my element locate under the header. And I have an error:
Element is not clickable at point (482, 10.116668701171875). Other element would receive the click...
I need to change source code of page to the next view:
<header style="position: absolute;">
To set the style attribute on the first header tag:
((JavascriptExecutor)driver).executeScript(
"document.getElementsByTagName('header')[0].style='position: absolute;'");
But a better solution would be to scroll the element at the top or bottom:
((JavascriptExecutor)driver).executeScript(
"arguments[0].scrollIntoView(true);", element);

How to access div ids using xpath?[selenium webdriver]

<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"));

How to insert contents into HTML page's iframe using HTMLUnit?

How can i insert some iframes inside a HTML page's iframe.
<HTML>
<div id="data">
<iframe height="160" width="600">
</iframe>
</div>
</HTML>
i could able to find the specific location using xpath
HtmlInlineFrame frame = (HtmlInlineFrame)page.getByXPath("//div[#id='data']/iframe").get(0);
i'm not clear how can i insert another htmlpage (iframe as htmlpage) inside this selected iframe. i have to insert more than one htmlpage (iframes as htmlpages) into this iframe Please suggest some way.
((HtmlInlineFrame)page1.getByXPath("//div[#id='data']/iframe").get(0)).setTextContent(page2.asXml());
this will work, still there is a problem that, there is a parser working in between, that is content set as
page2.asXml();
will set the content. After that when viewing the page as xml all '<' replaced with < and '>' replaced with >
((HtmlInlineFrame)page1.getByXPath("//div[#id='data']/iframe").get(0)).appendChild(page2);
will fix earlier issue still it will add two unwanted lines

Categories