I am using Selenium 2 Java API with FirefoxDriver. When I fill a form, checkboxes are added to the page depending the forms inputs.
I'd like to simulate a click on those checkboxes using Selenium. The element are visible and usable in a regular browser but, selenium asserts that the elements are not visible.
"Element is not currently visible and so may not be interacted with"
Can I force selenium to ignore the non-visible state of the elements? How can I force Selenium to interact with the non-visible element?
This question is related to
java
selenium-webdriver
Selenium determines an element is visible or not by the following criteria (use a DOM inspector to determine what css applies to your element, make sure you look at computed style):
Your element is matching one of those criteria. If you do not have the ability to change the styling of the element, here is how you can forcefully do it with javascript (going to assume WebDriver since you said Selenium2 API):
((JavascriptExecutor)driver).executeScript("arguments[0].checked = true;", inputElement);
But that won't fire a javascript event, if you depend on the change event for that input you'll have to fire it too (many ways to do that, easiest to use whatever javascript library is loaded on that page).
The source for the visibility check -
https://github.com/SeleniumHQ/selenium/blob/master/javascript/atoms/dom.js#L577
The WebDriver spec that defines this -
Sometimes this means there are multiple elements on a page that have the same property you're trying to search by and you're "talking to the wrong one".
If your element can't be uniquely identified by :id or :name (or :class), it could be tricky.
Sometimes searching for the element by the :xpath will help and in some cases even that is not practical.
In those cases, you may have to get all the elements that match your criteria and reference the right one by the index. It's dirty, but it works.
I'm using Selenium / Watir from Ruby on Rails app, so in my case the example would be:
browser = Watir::Browser.new(:firefox, :profile => "default")
browser.goto("http://www.google.com/analytics")
# login
browser.divs(:text, "+ New Property").last.click
Hope this helps.
I had a similar issue, but it was related to the element not being visible in the viewport. I took a screenshot and realized the browser window was too narrow and the element couldn't be seen. I did one of these and it worked:
driver.maximize_window()
Or you may use Selenium Action Class to simulate user interaction -- For example
WebDriver = new FirefoxDriver();
WebElement menu = driver.findElement(By.xpath("")); // the triger event element
Actions build = new Actions(driver); // heare you state ActionBuider
build.moveToElement(menu).build().perform(); // Here you perform hover mouse over the needed elemnt to triger the visibility of the hidden
WebElement m2m= driver.findElement(By.xpath(""));//the previous non visible element
m2m.click();
There is also another case when visible element will be recognized as not visible:
In order to check if element you wan't to interact with is CSS transformed, on CHROME do this:
The invisibility can also be due to timing when the element is supposed to slowly appear. Forcing the browser to wait a bit might help in that case.
See, e.g., the question on letting WebDriver wait until an element is present.
I just solve this error by waiting element display property
waitFor() { element.displayed }
I had the same problem with selenium 2 in internet explorer 9, but my fix is really strange. I was not able to click into inputs inside my form -> selenium repeats, their are not visible.
It occured when my form had curved shadows -> http://www.paulund.co.uk/creating-different-css3-box-shadows-effects: in the concrete "Effect no. 2"
I have no idea, why&how this pseudo element solution's stopped selenium tests, but it works for me.
You can't force accessing/changing element to which the user normally doesn't have access, as Selenium is designed to imitate user interaction.
If this error happens, check if:
maximize()
in node.js, maximize_window()
in Python),executeScript()
in node.js, execute_script()
in Python).There are many good answers on this page.
Both are discussed in various details above. The answer I didn't see was ScrollToElement. It sounds like you are processing a list of elements, while processing you are creating more elements, checkboxes. This can cause elements in your list to move off the visible page. Sometimes you can see the element with the naked eye but you just can't click on it. When processing lists you sometimes have to interject scrolling.
Because I run across this I created a PageScroll.java and put my scrolling scripts there. Here are a few of the methods from this class:
public static void scrollToTop(WebDriver driver) {
((JavascriptExecutor) driver)
.executeScript("window.scrollTo(0,0)");
}
public static void scrollToBottom(WebDriver driver) {
((JavascriptExecutor) driver)
.executeScript("window.scrollTo(0, document.body.scrollHeight)");
}
public static void scrollToElementTop(WebDriver driver, WebElement element) {
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollIntoView(true);", element);
}
public static void scrollToElementBottom(WebDriver driver, WebElement element) {
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollIntoView(false);", element);
}
see Scroll Element into View with Selenium for more examples
I get into ElementNotVisibleException exception using selenium for functional tests on a django site with bootstrap glyphicons as links in templates as:
<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger"></span></a>
During my functional tests, the bootstrap style is not loaded, then trying to click on such links will raise ElementNotVisibleException. I manage to make them clickable just adding a space in the tag, like that:
<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger"> </span></a>
I just solve this error while using capybara in ror project by adding:
Capybara.ignore_elements = true
to features/support/env.rb
.
The accepted answer worked for me. Below is some code to find the parent element that's making Selenium think it's not visible.
function getStyles(element){_x000D_
_x000D_
computedStyle = window.getComputedStyle(element);_x000D_
_x000D_
if(computedStyle.opacity === 0_x000D_
|| computedStyle.display === "none"_x000D_
|| computedStyle.visibility === "hidden"_x000D_
|| (computedStyle.height < 0 && computedStyle.height < 0)_x000D_
|| element.type === "hidden") {_x000D_
console.log("Found an element that Selenium will consider to not be visible")_x000D_
console.log(element);_x000D_
console.log("opacity: " + computedStyle.opacity);_x000D_
console.log("display: " + computedStyle.display);_x000D_
console.log("visibility: " + computedStyle.visibility);_x000D_
console.log("height: " + computedStyle.height);_x000D_
console.log("width: " + computedStyle.width);_x000D_
}_x000D_
_x000D_
if(element.parentElement){_x000D_
getStyles(element.parentElement);_x000D_
}_x000D_
}_x000D_
_x000D_
getStyles(document.getElementById('REPLACE WITH THE ID OF THE ELEMENT YOU THINK IS VISIBLE BUT SELENIUM CAN NOT FIND'));
_x000D_
To add my grain of sand here: if an element resides behind a fixed div it will be considered as not visible and you won't be able to click it; this happened to me recently and i solved it executing a script as recommended above, which does:
document.evaluate("<xpath locator for element to be clicked>", document, null, XPathResult.ANY_TYPE, null).iterateNext().click()", locator);
Source: Stackoverflow.com