webdriver报不可见元素异常方法总结

上一篇 / 下一篇  2012-11-23 10:03:20 / 个人分类:Selenium-Webdriver

最近一直在学Selenium相关东西,学到webdriver这块,出现报不可见元素异常方法异常,后来网上找了好多相关资料都没搞定,也没看明白,最后发现是xpath中写了calss属性有问题。现在把学习到的方法和实际解决的方法总结一下,留个记号。
 

1.      关于存在不可见属性的元素,对元素操作时,出现报如下异常的情况及处理办法:

 

Exception in thread "main" org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with Command duration or timeout: 31 milliseconds

 

首先,得排除是否是定位的xpath路径有问题,如果是用xpath定位,其中用@class属性来定位,也会报这个错误(特别是class中含有复合类的定位)。下面用备份软件删除任务的弹出div区中的确认按钮定位为例:

WebElement cf_button=driver.findElement(By.xpath("//div[@class='ui-dialog-buttonset']"));

用上面的class定位,也是有问题的。用下面的路径也是有问题的,都会报上面提到的异常内容。

Xpath=//div[@class=ui-dialog-buttonpane ui-widget-content ui-helper-clearfix]/div/button

这个xpath中的class属于复合类。

如果用下面的定位,就不会报这个异常:

WebElement cf_button=driver.findElement(By.xpath("//div[4]/div[3]/div[1]/button"));

上面的元素定位,可通过元素对象的方法isDisplayed()检测元素是否可显示的,如果得到不可显示,操作该元素时会报上面提到的异常,检测语句如下:

   if(!(cf_button.isDisplayed())){System.out.println("Element is not displayed!"); };

2种情况:就是元素的样式或父级及以上元素含有不可显示属性,以致在有些浏览器中(FirefoxDriver)不能操作,但在正常的浏览器中它是可见和可用的。那么需要检查元素是否具备如下特性:

  • visibility!= hidden
  • display != none (is also checked against every parent element)
  • opacity != 0 (in rc2 this is no longer checked for clicking an element)
  • height and width are both > 0
  • for an input, the attribute type != hidden

如果有不符上面的特性之一,那么就用js脚本来处理,这个解决方案的原英文附在下面:

Element is not currently visible

I am using Selenium 2.0b3 Java API with FirefoxDriver. When I fill a form, checkboxes are added to the page depending the forms inputs. I 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?

  

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):

  • visibility != hidden
  • display != none (is also checked against every parent element)
  • opacity != 0 (in rc2 this is no longer checked for clicking an element)
  • height and width are both > 0
  • for an input, the attribute type != hidden

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).

3种情况是:估计意思是就是选取元素的时候,可能存在两个相同的,但一次只会用一个,这两个区别就有一个样式的属性是不可见的,这个时候选取元素时要去掉不可见属性,如下例子:

WebElement label = driver.findElement(By.xpath("//

label[text()='User Name:' and not(contains(@style,'display:

none'))]"));

这个源版的这种情况下的解决方案附在下面:

can think of two reasons the element you are attempting to interact

with is invisible. The first reason is that some fields might be

invisible until you fill in other fields. For example, many

registration forms have a submit button which is not visible until the

user has filled in all the required fields. WebDriver is designed to

simulate a human interacting with the web page. Are you filling out

the page exactly the same way a human would? Maybe you filled in all

the fields but your automation is faster than a human. So it tries to

click the submit button before the web page can change it to visible.

You can use things like http://darrellgrainger.blogspot.ca/2012/01/waitforelement.html

to help slow down the automation.

 

The second reason the element might be invisible is you have located

an invisible element rather than the element you thought you wanted.

For example, I worked on a web page which had a radio button for new

user versus sign in. If you clicked new user, the form. for registering

a new user appeared. If you clicked existing user, the form. for

signing in appeared. Both forms existed in the DOM but only one was

visible at a time. Both forms had:

 

 

   <label for="foo29_blah_nix17">User Name:</label>

<input id="foo29_blah_nix17" />

 

 

(the for/id values would be different). So if I used:

 

 

   String username = "darrell";

   WebElement label = driver.findElement(By.xpath("//

label[text()='User Name:']"));

   String inputID = label.getAttribute("for");

   WebElement input = driver.findElement(By.id(inputID));

   input.sendKeys(username);

 

 

it might find the invisible label. In these cases, I need to use an

xpath which finds the visible label element. If the element is

invisible because style='display: none' then I'd use:

 

 

   WebElement label = driver.findElement(By.xpath("//

label[text()='User Name:' and not(contains(@style,'display:

none'))]"));

 

 

You'll have to figure out if you have problem #1 or #2. If you have

problem #2, you will have to figure out the exact solution. My

solution is just one of many possible examples and might not be

exactly your problem.

4种情况:一般是编写脚本流程没有严格按照手工的步骤来进行,导致选取到非流程中的不可显示元素,进行操作,以致报上面提到的异常,这种情况在第3种情况的首段有所描述。


TAG:

 

评分:0

我来说两句

Open Toolbar