Webdriver 处理display:none

来源:互联网 发布:dcs控制系统与cms 编辑:程序博客网 时间:2024/06/05 12:42

开始的时候,一直定位不到,因为是动的。

后面发现,它在表里。然后去找关于定位表的方法。

最后才发现,是因为display:none的缘故。

然后找方法来实现

Selenium中的waitForCondition使用和编写自己的waitForElementDisplay方法

在我们在页面跳转的时候或者进行了一些操作的时候,我们需要等待某个页面或者元素的出现。对与页面的跳转我们可以用selenium.waitForPageLoad方法,但是对于等待某个元素的出现并没有提供,只提供了一个waitForCondition的方法。

waitForCondition方法会执行传入的js代码,直到条件成立,或者 timout时间到。

[java]view plaincopy

  1. selenium.waitForCondition("var value = selenium.browserbot.findElementOrNull(“id1”); value.style.display == 'none'", "10000");  

waitForCondition方法中也可以有运算符的操作

[java]view plaincopy

  1. selenium.waitForCondition("var value = selenium.browserbot.findElementOrNull(id1); value.style.display == 'none'", || var value = selenium.browserbot.findElementOrNull(id2); value.style.display == 'none' “, "10000");  

 

当然每次我们都去写js代码,这样会很麻烦,而且上面的代码只能判断display属性为none, 我们可以用selenium 自带的 isVisible方法来判断一个Element是否存在。因为isVisible方法判断的跟全面,它还判断了visibilityhiden属性。所以我们可以创建一个更加通用的方法叫做waitForEelementDisplay方法。下面是代码实现:

[java]view plaincopy

  1. package com.safx.selenium;  
  2.   
  3. import java.util.concurrent.ExecutorService;  
  4. import java.util.concurrent.ScheduledThreadPoolExecutor;  
  5. import java.util.concurrent.TimeUnit;  
  6.   
  7. import com.safx.utility.CommonTool;  
  8. import com.thoughtworks.selenium.SeleniumException;  
  9.   
  10. public class DriveSelenium   
  11. {  
  12.     ScheduledThreadPoolExecutor executor = null;  
  13.       
  14.     public boolean waitForElementDisplay(String locator, String time) {  
  15.         SheduleEntity entity = new SheduleEntity(CommonTool.String2Int(time));  
  16.         this.schedule(entity);  
  17.         int tempTime = 1000;  
  18.         while (!entity.isTimeout()) {  
  19.             if (selenium.isVisible(locator)) { // call selenium.isVisable method  
  20.                 this.shutdownAndAwaitTermination(executor);  
  21.                 return true;  
  22.             }  
  23.             Thread.sleep(tempTime);   
  24.         }  
  25.         throw new SeleniumException("ERROR: wait for '" + locator + "' " + time + "s time out!");  
  26.     }  
  27.       
  28.     private void schedule(final SheduleEntity shedule) {  
  29.         executor = new ScheduledThreadPoolExecutor(1);  
  30.         executor.schedule(new Runnable() {  
  31.             @Override  
  32.             public void run() {  
  33.                 shedule.setTimeout(true);  
  34.             }  
  35.         }, shedule.getTempTime(), TimeUnit.SECONDS);  
  36.     }  
  37.   
  38.     private void shutdownAndAwaitTermination(ExecutorService pool) {  
  39.         pool.shutdown(); // Disable new tasks from being submitted  
  40.         try {  
  41.             // Wait a while for existing tasks to terminate  
  42.             if (!pool.awaitTermination(5, TimeUnit.SECONDS)) {  
  43.                 pool.shutdownNow(); // Cancel currently executing tasks  
  44.                 // Wait a while for tasks to respond to being cancelled  
  45.                 if (!pool.awaitTermination(5, TimeUnit.SECONDS))  
  46.                     System.err.println("Pool did not terminate");  
  47.             }  
  48.         } catch (InterruptedException ie) {  
  49.             // (Re-)Cancel if current thread also interrupted  
  50.             pool.shutdownNow();  
  51.             // Preserve interrupt status  
  52.             Thread.currentThread().interrupt();  
  53.         }  
  54.     }  
  55.   
  56.       
  57.     class SheduleEntity{  
  58.   
  59.         private boolean isTimeout = false;  
  60.         private int tempTime;  
  61.           
  62.         public SheduleEntity( int tempTime ) {  
  63.             this.tempTime = tempTime;  
  64.         }  
  65.   
  66.         public void setTimeout(boolean isTimeout) {  
  67.             this.isTimeout = isTimeout;  
  68.         }  
  69.   
  70.         public boolean isTimeout() {  
  71.             return isTimeout;  
  72.         }  
  73.           
  74.         public int getTempTime() {  
  75.             return tempTime;  
  76.         }  
  77.     }  
  1. }  

在上面的代码中,

1.定义一个scheduleEntiy类 用来保存,timout 延时时间 和 isTimeout 是否已经延时

2. 通过ScheduledThreadPoolExecutor 类 当定时器使用,当timeout时间到是,把ScheduleEntiy类中的isTimeout设置为True。

3. 我们定义了一个waitForElementDisplay 方法。在这个方法中做一个每隔一秒的无限循环,循环调用isVisible这个方法。如果改Element出现则返回true,如果不出现直到timeout时间到,则抛个异常出来。

 

源文档 <http://blog.csdn.net/caiqcong/article/details/7613028>

 

上周我测的产品出了新版本,上传文件这块的UI代码改动了一下。

用sendkeys这招竟然过不去,抛出了异常:

org.openqa.selenium.ElementNotVisibleException:Element is not currently visible and so may not be interacted with

就是说这个input还在,就是不可见,所以不能sendKeys了。

办法只有一个,就是用javascript把这个input给弄成可见的!

把这句document.findElementById('123').style.visibility='visible';放在selenium中执行,可是上传文件框还是没出来。我的javascriptcss都比较菜,对于显示、隐藏页面元素就只会这一招。正当无奈之际,发现firebughtml下面,input这一行是灰的。这应该说明它是隐藏的,可是改哪儿才能管用呢?

 

我选中了灰的这一行,右边style里显示出了css样式display:none

百度了一下display都有什么值,有none,inline, block...,我把none改成了block,页面上出现了又大又丑的


 所以:如果你想在做seleniumwebdriver 2.0自动化的时候遇到了界面里有“上传文件”的需求,input type='file'加了样式被“美化”没了,直接sendkey不行的时候,在sendkeys之前,用javascript把它给弄出来:

JavascriptExecutor j= (JavascriptExecutor)driver;

j.executeScript("document.findElementById('123').style.display='block';");

然后再WebElement.sendKeys ("c:\abc.txt");

 

就OK了!这样虽然不太优雅,但也是没有办法中的办法。必竟自动化代码不能卡在这里过不去。文件上传不上去,之后的一系列验证工作都做不了。同理的还有下拉菜单中的二级菜单,有时候一闪就没,也可以把visiblility:hidden改成visible,同时设置好lefttop值,让它显示出来。就能继续了。

 

附上我为了解决这个问题做的网页(为了节省登录产品的时间,我单独做了一个网页来模拟这个问题)

和在firebug里观察到情况。

 


心里暗叫一声“惭愧”,一直嫌javascript和css麻烦,不愿意碰它们,可终归躲不过只能直面困难了。我爸帮我把多年前的javascript权威指南给带新家去了,以后没事得翻一翻。

 

 

源文档 <http://blog.sina.com.cn/s/blog_539a70d30101ajsg.html>

 

1、如果在样式文件或页面文件代码中直接用display:none对元素进行了隐藏,载入页面后,在没有通过js设置样式使元素显示的前提下,使用js代码会无法正确获得该元素的一些属性,比如offSetTop,offSetLeft等,返回的值会为0,通过js设置style.display来使元素显示后才能正确获得这些值。

 

2、使用display:none隐藏的元素不会被百度等搜索网站检索,会影响到网站的SEO,某些情况下可以使用left:-100000px来达到同样效果。

 

3、 如果是通过样式文件或<style>css</style>方式来设置元素的display:none样式,用js设置style.display=""并不能使元素显示,可以使用blockinline等值来代替。通过style="display:none"直接在元素上进行的设置不会有这个问题

 

4、有些情况下可以使用style.visibility来代替style.display,但是要注意的是style.visibility隐藏元素时会保留元素在页面上所占的空间,而style.display隐藏元素且让出所占页面空间。

 

源文档 <http://www.jb51.net/article/15781.htm>

0 0
原创粉丝点击