执行js-----Selenium快速入门(十四)

摘要:
WebDriverdriver=newChromeDriver();JavascriptExecutiorjsExecutor=(JavascriptExecutor)驱动程序;方法返回List<方法返回Map&lt,String;对象类型为上述类型。下面是一些简单的例子;

  Selenium能够执行js,这使得Selenium拥有更为强大的能力。既然能执行js,那么js能做的事,Selenium应该大部分也能做。这应该得益于JavascriptExecutor这个接口,而ChromeDriverEdgeDriverEventFiringWebDriverFirefoxDriverInternetExplorerDriverOperaDriverRemoteWebDriverSafariDriver均实现了这个接口。跟使用WebDriver一样,我们可以这样使用该接口: 

 WebDriver driver=new ChromeDriver();
 JavascriptExecutor jsExecutor=(JavascriptExecutor) driver;

  该接口十分简单,只有两个方法:

  1.java.lang.Object executeScript(java.lang.String script, java.lang.Object... args)   同步执行js

  2.java.lang.Object executeAsyncScript(java.lang.String script, java.lang.Object... args)  异步执行js

  对于返回值:

  1.如果js返回的是html元素,那么方法返回WebElement

  2.如果js返回的是小数,方法返回Double

  3.如果js返回的是非小数,方法返回Long

  4.如果js返回的是布尔,方法返回Boolean

  5.如果js返回的是其他,方法返回String

  6.如果js返回的是数组,方法返回List<Object>,可以嵌套,Object的值的类型是根据上面5条而定。

  7.如果js返回的是map,方法返回Map<String, Object>,Object值类型的定义同上。

  8.如果js返回null或没有返回,方法返回null

  对于 arg参数:

  js会用一个“魔法”变量arguments来接收。参数的类型可以是:数字,布尔,字符串,元素(WebElement)以及List<Object>,Object类型为上述类型

  下面通过一些简单的例子,来说明用法

  首先,我们在项目的html文件夹增加一个空白的html文件,jsTest.html

  html的代码如下:这是一个空白的html

<html>
<head>

</head>

<body>

</body>

</html>

  我们的代码:

        System.setProperty("webdriver.chrome.driver", "D:/WorkSpace/SeleniumTest/tools/chromedriver.exe");
        WebDriver driver=new ChromeDriver();
        
        driver.get("file:///D:/WorkSpace/SeleniumTest/html/jsTest.html");
        //调用js,弹出信息
        ((JavascriptExecutor) driver).executeScript("alert('hello,selenium');");

  执行的效果如下:

  执行js-----Selenium快速入门(十四)第1张

  是不是非常简单,我们尝试使用带有参数的调用:

        System.setProperty("webdriver.chrome.driver", "D:/WorkSpace/SeleniumTest/tools/chromedriver.exe");
        WebDriver driver=new ChromeDriver();
        
        driver.get("file:///D:/WorkSpace/SeleniumTest/html/jsTest.html");
        //调用js,"11111","22222"等参数将会被arguments接收,成为一个数组,此处arguments[0]表示调用第一个参数
        ((JavascriptExecutor) driver).executeScript("alert(arguments[0]);","1111111","222222");

  执行的效果:

  执行js-----Selenium快速入门(十四)第2张

   我们再修改一下jsTest.html,增加一个js方法,代码如下:

<html>
<head>
    <script>
        function sayHello()
        {
            alert("hi,Selenium");
        }
    </script>
</head>

<body>

</body>

</html>

  调用的java改成如下:

        System.setProperty("webdriver.chrome.driver", "D:/WorkSpace/SeleniumTest/tools/chromedriver.exe");
        WebDriver driver=new ChromeDriver();
        
        driver.get("file:///D:/WorkSpace/SeleniumTest/html/jsTest.html");
        //调用页面上的方法
        ((JavascriptExecutor) driver).executeScript("sayHello()");

  发现依然可以执行成功,效果如下:

执行js-----Selenium快速入门(十四)第3张

  对于异步执行,使用的方法是类似的。更详细的可参考官网:http://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/JavascriptExecutor.html

  但是对于异步执行,Selenium提供了一个时间限制的方法:

  WebDriver.Timeouts setScriptTimeout(long time, java.util.concurrent.TimeUnit unit)

  该方法是针对 executeAsyncScript 方法的执行,对executeScript无效。官方的文档说: If the timeout is negative, then the script will be allowed to run indefinitely.如果timeout的时间设为负数,表示不限执行时间,但我发现,设置为负数,一样会抛出异常(当然,官方没有说不会抛出异常,但抛出异常后,后面的代码就无法执行,除非自己去捕捉这个异常进行额外的处理)。 

        System.setProperty("webdriver.chrome.driver", "D:/WorkSpace/SeleniumTest/tools/chromedriver.exe");
        WebDriver driver=new ChromeDriver();
        
        driver.get("file:///D:/WorkSpace/SeleniumTest/html/jsTest.html");
       
        //设置超时时间为-1秒
        driver.manage().timeouts().setScriptTimeout(-1, TimeUnit.SECONDS);
        
        JavascriptExecutor js=(JavascriptExecutor) driver;
        //3秒后执行
        js.executeAsyncScript("setTimeout("alert('本信息3秒后弹出!')",3000)");

  3秒后,js依然能弹出框,但之前就已经先抛出异常。也就是说,超时并未停止js的执行,只是抛出异常。

    异常信息为:Exception in thread "main" org.openqa.selenium.ScriptTimeoutException:asynchronous script timeout: result was not received in -1 seconds

  如果将超时时间设置为3或以上,则js能顺利执行,并且不会抛出异常。

  如果是executeScript,则无论setScriptTimeout如何设置,都不会对它有任何影响。

    当然,我们一般不会将超时时间设为负数,否则无任何意义,这里只是想验证一下官方的说法而已,结果说明与官方文档的说法稍有些出入。所以,如果想使设置异步脚本超时的这句代码无效,最好的方法还是将它注释掉,而非将超时时间改成负数。

免责声明:文章转载自《执行js-----Selenium快速入门(十四)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇配置Maven本地仓库freeRTOS V10.0.1移植到STM32F407标准库下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Android PendingIntent的一些经验

近日在开发中刚好涉及到桌面Widget的一些开发工作,而桌面Widget控件的点击事件,通常只能通过RemoteViews.setOnClickPendingIntent(int viewId, PendingIntent pendingIntent)方法来指定响应的行为。 通常实际应用中我们会把桌面Widget作为应用的快捷方式和缩略展示,那么通常我们做...

nodejs下function,new function和this的研究

转:http://www.html5china.com/html5-article-3023-1.html 重点我都高亮了! 由于在使用nodejs之前接触js也比较少,最近一直被js的function和new function所困惑,由于两者都可以呈现出面向对象的样子,不知道两者的差别在哪里,就此问题做了一些研究。在研究的过程中发现this指针是个...

如何退出正在Sleep的线程

    今天有个同事问我Thread的Interrupe方法,这个方法用于终止另一个正在等待(Sleep/Wait/Join)状态的线程,如果那个线程未处于等待状态,则等到下次进入等待状态时再抛出。     这个方法的平时用的机会其实并不大,由于需要线程处于等待状态,很大程度上限制了使用的机会,因此问了下同事实际的使用场景,原来是某些线程进入了长时间的Sl...

[转]SIFT,SURF,ORB,FAST 特征提取算法比较

转载地址:https://blog.csdn.net/vonzhoufz/article/details/46461849 主要的特征检测方法有以下几种,在一般的图像处理库中(如opencv, VLFeat, Boofcv等)都会实现。 FAST ,Machine Learning for High-speed Corner Detection, 200...

macOS + MySql8 问题

最近mac 升级安装mysql后遇到一系列问题,稍作记录。 1、升级8以后,使用sequelpro 连接报错 MySQL said: Authentication plugin 'caching_sha2_password' cannot be loaded: dlopen(/usr/local/mysql/lib/plugin/caching_sha2_...

python之logging 模块(下篇)

四、日志处理流程(第二种日志使用方式) 上面简单配置的方法例子中我们了解到了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分别用以记录不同级别的日志信息),logging.basicConfig()(用默认日志格式(Formatter)...