What could cause element not clickable while it is the same element? - selenium

An img WebElement click rarely fails claiming the Element is not clickable even though the element that would get the click is the same.
I have a dialog that contains some button (close button with img X inside of it).
When I try to click the close the dialog by clicking on the WebElement for the img, rarely, I'd get WebDriverException as follows:
Caused by: org.openqa.selenium.WebDriverException: unknown error: Element
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfhCB8QKRBsEUJwAAAAn0lEQVQoz72RMQ7CMAwADwbgCSyhqmDpFj6AWqSOfIoH8BkGNsLGhiwG6NKJDvwBBoaExPCAeontu0SWA32F1HKTRawyucjK58PQ21LgvCIZjiU7DwbhzpQjBR0lbxw5LaXtlKCUl8ZKiAoapxkARkzCOU7NKMiMEzktdwxO5n9CxBVrGq18Xzh4bB/2SUWDYf+7qI1cxaRx5Sx1b7/0AYDRNbDgNXvDAAAAAElFTkSuQmCC" class="gwt-Image" style="visibility: visible;"> is not clickable at point (834, 307). Other element would receive the click:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfhCB8QKRBsEUJwAAAAn0lEQVQoz72RMQ7CMAwADwbgCSyhqmDpFj6AWqSOfIoH8BkGNsLGhiwG6NKJDvwBBoaExPCAeontu0SWA32F1HKTRawyucjK58PQ21LgvCIZjiU7DwbhzpQjBR0lbxw5LaXtlKCUl8ZKiAoapxkARkzCOU7NKMiMEzktdwxO5n9CxBVrGq18Xzh4bB/2SUWDYf+7qI1cxaRx5Sx1b7/0AYDRNbDgNXvDAAAAAElFTkSuQmCC" class="gwt-Image" style="visibility: visible;">
As you can see the elements are identical. I started to doubt the Staleness of the element, its enablement, and even the possibility that the element moves.
Below is a code snippet that includes debugging message when I will explain.
private static final By X_BUTTON__SELECTOR
= WlSeleniumUtils.selectTagWithClass("img", "gwt-Image");
public void clickAndReturnIfAny() {
WebElement closeImage = manageWorkspaceDialogWebElem
.findElement(X_BUTTON__SELECTOR);
// print the elements location before clicking
System.out.println(String.format
("Position: %s, Dimensions: %s",
closeImage.getLocation() + "",
closeImage.getSize() + ""));
try {
// print check for staleness and enablement.
System.err.println
("close button: stale? "
+ driverHelper.isStale(closeImage)
+ " displayed? " + closeImage.isDisplayed()
+ " enabled? " + closeImage.isEnabled()
+ " clickable? " + (ExpectedConditions
.elementToBeClickable
(closeImage)
.apply(driverHelper.getDriver())
!= null));
closeImage.click();
}
catch (WebDriverException wde) {
System.err.println
("Faied to click manage-workspaces dialog's "
+ "close button: stale? "
+ driverHelper.isStale(closeImage)
+ " displayed? " + closeImage.isDisplayed()
+ " enabled? " + closeImage.isEnabled()
+ " clickable? " + (ExpectedConditions
.elementToBeClickable
(closeImage)
.apply(driverHelper.getDriver())
!= null));
// print the entire HTML content to check for multiple img tags.
System.err.println
(manageWorkspaceDialogWebElem.getAttribute("innerHTML"));
// fetch the element again and check its location
closeImage = manageWorkspaceDialogWebElem
.findElement(X_BUTTON__SELECTOR);
System.out.println(String.format
("Position: %s, Dimensions: %s",
closeImage.getLocation() + "",
closeImage.getSize() + ""));
throw new RuntimeException
("Failed to close mange-workspaces dialog.", wde);
}
}
Before executing the click:
Position: (826, 299), Dimensions: (16, 16)
close button: stale? false displayed? true enabled? true clickable? true
After executing the click and catching the exception:
Position: (826, 299), Dimensions: (16, 16)
So the element has not moved.
As you can see inner HTML is just one img:
<div class="popupContent">
<table cellspacing="0" cellpadding="0" style="background-color: rgb(255, 255, 255); width: 100%; height: 100%;">
<tbody>
<tr>
<td align="right" style="vertical-align: top;"><button type="button" class="wl-popup-close-button" style="border-style: none; outline-style: none; background-color: rgb(255, 255, 255); padding: 0px;"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfhCB8QKRBsEUJwAAAAn0lEQVQoz72RMQ7CMAwADwbgCSyhqmDpFj6AWqSOfIoH8BkGNsLGhiwG6NKJDvwBBoaExPCAeontu0SWA32F1HKTRawyucjK58PQ21LgvCIZjiU7DwbhzpQjBR0lbxw5LaXtlKCUl8ZKiAoapxkARkzCOU7NKMiMEzktdwxO5n9CxBVrGq18Xzh4bB/2SUWDYf+7qI1cxaRx5Sx1b7/0AYDRNbDgNXvDAAAAAElFTkSuQmCC" class="gwt-Image" style="visibility: visible;"></button></td>
</tr>
</tbody>
</table>
</div>
So any suggestions as to why this is happening would be much appreciated.

Try induce java Scripts executor to click on the element with following xpath.
WebElement element=driver.findElement(By.xpath("//button[#class='wl-popup-close-button']/img[#class='gwt-Image']"));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", element);

It might be the case the <img> itself is not clickable and you need to click the parent <button> instead.
In XPath you can access the any element in the DOM and its parents, children, siblings, etc.
So I would recommend amending your selector to point to the parent button :
//img[#class='gwt-Image']/parent::button
and my expectation is that the click should be successful.
References:
XPath Tutorial
XPath Axes
XPath Operators & Functions

Related

How to move down and move left the scroll bar that exists within the webpage?

I want to move the vertical and horizontal scrollbar that exists within the webpage itself, I couldn't do that with the below method,
When I inspected an element I got the below one,
<div id="DashboardPageContentDiv" class="DashboardPageContentDiv" style="height: 521px; overflow: auto;">
here is the method I created,
public void scrollbardown(RemoteWebDriver remoteWebDriver) throws Exception {
try
{
JavascriptExecutor jse = (JavascriptExecutor)remoteWebDriver;
jse.executeScript("window.scrollBy(0,2500)", "");
}
catch (Exception exc)
{
}
}
This scrollbars exists with in the frame, here is the frame source code:
<iframe allowtransparency="true" id="symbUrlIFrame2" src="/cos/start.swe?SWECmd=GetCachedFrame&SWEC=13&SWEFrame=symbUrlIFrame2&SRN=xaU5eD1S1IOkspAeHu524NMsHC5h5jzSUipwpmEq8bYb " height="800" width="100%" style="height: 607px; position: relative;"></iframe>
Find the nearest element and use scrollintoview function to move there, the below code works,
JavascriptExecutor js = (JavascriptExecutor) remoteDriver;
WebElement
a=remoteDriver.findElement(By.xpath(".//td[#id='titleView!1Subtitle' and
contains(text(),'Time run: ')]"));
js.executeScript("arguments[0].scrollIntoView();",a );

waitForElementToDisappear for all the panels of the page

By panelCollapseSelector = By.cssSelector(".panel-heading+.panel-collapse");
waitForElementToDisappear(panelCollapseSelector);
The above code waits for the 1st panel of the page. I would like to wait for all the panels to collapse. How can I run loop around this.to wait for all the panels of the page.
code before collapse
<div class="panel-collapse collapse in" style="height: auto;">
code after collapse
<div class="panel-collapse collapse" style="height: 0px;">
A simple solution would be to wait for 0 elements matching the non collapsed panels.
One possible CSS selector to get all the non collapsed panels:
".panel-heading:not(.in) + .panel-collapse:not(.in)"
Then to wait with a lambda expression :
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until((WebDriver drv) -> drv.findElements(By.cssSelector(
".panel-heading:not(.in) + .panel-collapse:not(.in)")).size() == 0);
Or using the expected conditions:
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.not(ExpectedConditions.presenceOfAllElementsLocatedBy(
By.cssSelector(".panel-heading:not(.in) + .panel-collapse:not(.in)"))));
You can try this java method for waiting 60 seconds for all panels to get collapse
int timeout=60;
while(driver.findElement(By.cssSelector(".panel-heading+.panel-collapse")).getAttribute("style").contains("height: auto;") && timeout > 0) {
try {
if(timeout>1)
{
timeout--;
System.out.println("====== Waiting for Collapsing Panels ======");
Thread.sleep(1000);
}
}
catch(Exception e) {
}

what will be xpath for image in below mention code

I am trying to finding xpath for image.below is my code.i am getting error unable to locate the element.
driver.findElement(By.xpath("//img[#src='./pics/logo /home.jpg']")).click();
Below mention is my table code. from where i am trying to find xpath for image.
<table cellspacing="0" cellpadding="0" width="600" border="0">
<tbody>
<tr>
<tr>
<td style="vertical-align: top;padding-top:10px;padding-right: 3px;">
<td width="30%" style="vertical-align: top;padding-top:10px;">
<a title="Access to Data (S,g,...)" target="_top" href="./action/updateTabs?tabSet=requestId=1457516682135">
<img border="0" src="./pics/logo/home/EMLogoMini.jpg">
</a>
</td>
I have observed that there is a space in your xpath and the URL is different too..
Use below code:-
driver.findElement(By.xpath("//img[#src='./pics/logo/home/EMLogoMini.jpg']")).click();
Or use cssSelector as below :-
driver.findElement(By.cssSelector("img[src='./pics/logo/home/EMLogoMini.jpg']")).click();
List<WebElement> list=driver.findElements(By.xpath("//img[#src='./pics/logo/home/EMLogoMini.jpg']"));
for(WebElement e : list){
e.click();
}
How to click by different ways:-
If your problem is that the element is scrolled off the screen (and as a result under something like a header bar), you can try scrolling it back into view like this:
private void scrollToElementAndClick(WebElement element) {
int yScrollPosition = element.getLocation().getY();
js.executeScript("window.scroll(0, " + yScrollPosition + ");");
element.click();
}
if you need you could also add in a static offset (if for example you have a page header that is 200px high and always displayed):
public static final int HEADER_OFFSET = 200;
private void scrollToElementAndClick(WebElement element) {
int yScrollPosition = element.getLocation().getY() - HEADER-OFFSET;
js.executeScript("window.scroll(0, " + yScrollPosition + ");");
element.click();
}
If still not work then use JavascriptExecutor
WebElement element= driver.findElement(By."Your Locator"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);
Hope it will help you :)
try to remove spaces and be sure that the URL is same...

How to print the background colour of a menu item while hovering the mouse using selenium webdriver

I am automating a webpage.I have to check the mouse hover functionality works fine or not.
I have to print the background color when mouse is pointed to a particular item.I have written the code but it does not throw the correct out put.
public class Selenium_Demos extends Environment_Setup {
#Test
public void test() throws Exception {
Rapidaction();
}
private void Rapidaction() throws Exception
{
driver2.get("http://www.rapidvaluesolutions.com/");
Actions builder = new Actions(driver2);
// To click on the link 'PRODUCT'
WebElement td_Home = driver2.findElement(By.xpath("//html/body/section[1]/header/nav/ul/li[1]/a"));
String bgColor = td_Home.getCssValue("background-color");
System.out.println("Before hover: " + bgColor);
builder.moveToElement(td_Home).build().perform();
bgColor = td_Home.getCssValue("background-color");
System.out.println("After hover: " + bgColor);
driver2.quit();
}
}
As we point the mouse over the link'Product', the colour of the link - blue should be printed.
From comment moving to post as I want to post some code.
Can you please change below line
WebElement td_Home = driver2.findElement(By.xpath("//html/body/section[1]/header/nav/ul/li[1]/a"));
To
List<WebElement> td_Home = driver2.findElements(By.xpath("//html/body/section[1]/header/nav/ul/li[1]/a"));
And then check what is the length of td_Home i.e. print "td_Home.size()"
if the length is more than 1 then you have to debug if it is giving the size as 1 then check some attribute of the element to make sure you have selected a proper element.
Please try this.
UPDATE:
Now please do
String bgColor = td_Home.get(0).getCssValue("background-color");
I have created simple example for you:copy this html in some location and save as .html
<html>
<body>
<div id="mydiv" style="width:200px;background:white" onmouseover="this.style.background='gray';" onmouseout="this.style.background='white';">
on mouse over color change.
</div>
</body>
</html>
**web driver code:**
driver.get("file:///C:/Users/vkiran/Desktop/color1.html");
WebElement element = driver.findElement(By.xpath("//*[#id='mydiv']"));
Actions builder = new Actions(driver);
Action mouseOver = builder.moveToElement(element).build();
String bgColor = element.getCssValue("background-color");
System.out.println("Before hover: " + bgColor);
mouseOver.perform();
bgColor = element.getCssValue("background-color");
System.out.println("After hover: " + bgColor);
Identify that webelement, then by help of getAttribute() method find the colour
System.out.println("Hexadecimal color : "+driver.findElement(By.xpath("write the proper xpath")).getAttribute("bgcolor"));
This will give hexadecimal notation for colour
Actions actions = new Actions(driver);
WebElement element = driver.findElement(mycopieslink_locator);
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].setAttribute('style', 'background: yellow; border: 3px solid red;');", element);
actions.moveToElement(element);
actions.click().build().perform();

Change TinyMCE input height from textarea height

My form uses inputs and textareas, some of which I've added as TinyMCE elements. The problem is that the inputs are converted into the same size as the textareas. I'd like the inputs to be the same height as non-TinyMCE input fields (I'm using the latest version of TinyMCE - 3.5b2).
For example, TinyMCE adds this table to the inputs and textareas:
<table role="presentation" id="teaser_tbl" class="mceLayout" cellspacing="0" cellpadding="0" style="width: 590px; height: 100px; ">
How can I change this embedded style to reduce the height for inputs to 30px?
I've also posted this on the TinyMCE forums.
<table role="presentation" id="teaser_tbl" class="mceLayout" cellspacing="0" cellpadding="0" style="width: 590px; height: 100px; ">
That is exactly the element you will need to change. Tinymce has the width and height init param, but there are some cases where this setting is not sufficient.
Due to the fact that the editor iframe explicitly gets the same height assigned you will have to adjust the iframe too. You will need to call
var new_val = '30px';
// adjust table element
$('#' + 'my_editorid' + '_tbl').css('height', new_val);
//adjust iframe
$('#' + 'my_editorid' + '_ifr').css('height', new_val);
Idealy, this should be done right on editor initialization. So use:
tinyMCE.init({
...
setup : function(ed) {
ed.onInit.add(function(ed, evt) {
var new_val = '30px';
// adjust table element
$('#' + ed.id + '_tbl').css('height', new_val);
//adjust iframe
$('#' + ed.id + '_ifr').css('height', new_val);
});
}
});
Update: Solution without jQuery:
tinyMCE.init({
...
setup : function(ed) {
ed.onInit.add(function(ed, evt) {
var new_val = '30px';
// adjust table element
var elem = document.getElementById(ed.id + '_tbl');
elem.style.height = new_val;
// adjust iframe element
var iframe = document.getElementById(ed.id + '_ifr');
iframe.style.height = new_val;
});
}
});