Selenium 与 JS 执行

在使用 Selenium 进行自动化是,有不少操作是 Selenium 的 API 无法实现的,比如控制页面滚动条、修改该元素属性等,但是这些我们都可以借助执行 JS 代码来去实现,因为本身 JS 就是运行在浏览器中的。

Selenium 提供了一个 JavascriptExecutor 类调用 executeScript 方法来执行 JS 脚本,JavascriptExecutor 可以通过 driver 来获取,代码如下:

JavascriptExecutor js = (JavascriptExecutor) driver;

JavascriptExecutor 类中还包含一个 executeAsyncScript 方法,该方法是异步方法,它不会阻塞主线程执行。

知识点
  • JS 代码定位和操作元素
  • JS 控制页面滚动条
  • JS 获取当前域名
  • JS 修改页面属性
  • JS 判断页面是否有滚动条

    JS 中操作 DOM 非常方便,可以通过 document 对象的 getElementByxx 方法定位元素并调用 value 给元素进行赋值。

    在 cn.lanqiao.js 包下创建一个测试类 ExecuteJSCommandTest,创建测试方法 testExecuteJS 用来执行 JS 定位元素代码,具体代码如下:

    package cn.lanqiao.js;
    
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.chrome.ChromeDriver;
    
    public class ExecuteJSCommandTest {
    
        @Test
        public void testExecuteJS() throws Exception {
            // 设置 WebDriver 的路径
            System.setProperty("webdriver.chrome.driver", "C:\\Users\\jingnan\\chromedriver.exe");
            WebDriver driver = new ChromeDriver();
    
            driver.get("https://www.lanqiao.cn");
    
            // 将 driver 转换为 JavascriptExecutor 用来执行 js 代码
            JavascriptExecutor js = (JavascriptExecutor) driver;
            String jsCode = "document.getElementsByClassName(\"universal-header-search-input\")[0].value=\"Selenium\"";
            // 执行 js 代码
            js.executeScript(jsCode);
    
            Thread.sleep(1000);
            driver.quit();
        }
    }
    

    上述代码通过 JS 的 getElementsByClassName 方法获得一个元素列表,该列表中的第一个就是云课首页的输入框,接着通过 value 方法给元素输入了 Selenium 字符串,执行上述代码,输出结果如下:

    4-2-1

在页面比较长的时候,我们要操作的目标元素并没有显示在当前页面中,需要滑动滚动条使元素显示在当前窗口中,这种操作也需要借助 JS 来实现。

JS 中共有 3 中控制滚动条的方式,分别是:

  • window.scrollTo(x,y): 滚动到某个绝对位置,即滚动到坐标为 x,y 的位置
  • window.scrollBy(x,y): 当前位置滚动到某个相对位置,从当前位置起向右和向下滚动多少像素。
  • Element.scrollTo(view):滑动滚动条,直到元素显示在当前页面

在 ExecuteJSCommandTest 类中创建测试方法 testScrollTo(),具体代码如下:

package cn.lanqiao.js;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ExecuteJSCommandTest {

    @Test
    public void testScrollTo() throws Exception{
        // 设置 WebDriver 的路径
        System.setProperty("webdriver.chrome.driver", "C:\\Users\\jingnan\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.lanqiao.cn");

        JavascriptExecutor js = (JavascriptExecutor) driver;

        // 让窗口滚动条向下滑动完整的窗口高度,即到滑动到底部
        String jsCode = "window.scrollTo(100, document.body.scrollHeight);";
        js.executeScript(jsCode);

        Thread.sleep(1000);
        driver.quit();
    }
}

上述代码的执行过程如下:

4-2-2

可以看到页面滚动到了底部,这样我们就可以对页面底部的元素进行定位和操作了。

接着我们来测试 scrollBy() 方法,在 ExecuteJSCommandTest 测试类中新增 testScrollBy 测试方法,具体代码如下:

package cn.lanqiao.js;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ExecuteJSCommandTest {

    @Test
    public void testScrollBy() throws Exception{
        // 设置 WebDriver 的路径
        System.setProperty("webdriver.chrome.driver", "C:\\Users\\jingnan\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.lanqiao.cn");

        JavascriptExecutor js = (JavascriptExecutor) driver;

        // 沿着 y 轴 向下滑动 500
        js.executeScript("window.scrollBy(0, 500);");
        Thread.sleep(1000);
        // 沿着 x 轴 向右滑动 500
        js.executeScript("window.scrollBy(500, 0);");

        Thread.sleep(1000);
        driver.quit();
    }
}

执行上述代码,执行过程如下:

4-2-3

可以看到 scrollBy() 方法也可以控制滚动条,需要注意的是这里是滚动到相对位置上。

在 ExecuteJSCommandTest 测试类中新增 testScrollIntoView 测试方法,使用该方法时要先定位一个元素,然后通过元素调用 scrollIntoView 方法就可以滑动该元素的位置了,具体代码如下:

package cn.lanqiao.js;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ExecuteJSCommandTest {

    @Test
    public void testScrollIntoView() throws Exception{
        // 设置 WebDriver 的路径
        System.setProperty("webdriver.chrome.driver", "C:\\Users\\jingnan\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.lanqiao.cn");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        // 定位到云课首页底部的职场提升元素,然后滑动滚动条
        js.executeScript("document.getElementById(\"components-paths\").scrollIntoView(true)");
        
        Thread.sleep(1000);
        driver.quit();
    }
}

上述方法通过 getElementById 方法定位到了云课首页底部的职场提升元素,然后调用 scrollIntoView 方法使该元素显示在当前页面上,执行上述方法,执行过程如下:

4-2-4

 

除了常用的控制滚动条外,我们接着来介绍其他常用的 JS 操作,比如获取当前应用的域名、修改元素属性以及判断当前页面是否有滚动条等。

使用 JS 获取当前域名

在 ExecuteJSCommandTest 测试类下新增测试方法 testGetDomain,在 JS 中可以通过 document.domain 来获取当前域名,这里我们需要返回当前域名,并使用 String 来接收,然后在控制台进行输出,具体代码如下:

package cn.lanqiao.js;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ExecuteJSCommandTest {

    @Test
    public void testGetDomain() throws Exception{
        // 设置 WebDriver 的路径
        System.setProperty("webdriver.chrome.driver", "C:\\Users\\jingnan\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.lanqiao.cn");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        // 获取域名并返回
        String domain = (String)js.executeScript("return document.domain");
        // 输出域名
        System.out.println(domain);
        
        Thread.sleep(1000);
        driver.quit();
    }
}

执行上述代码,控制台输出内容如下:

www.lanqiao.cn

输出的内容正是我们当前应用的域名。

使用 JS 更改页面属性

使用 JS 代码更改元素属性也非常方便,可以将 hidden 的元素改为 Display,可以去除或者增加元素的属性,也可以更改元素的属性值。

接下来我们可以通过 JS 来修改云课官网会员按钮的字体颜色,在 ExecuteJSCommandTest 测试类中新增测试方法 testChangeColor,具体代码如下:

package cn.lanqiao.js;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ExecuteJSCommandTest {

    @Test
    public void testChangeColor() throws Exception{
        // 设置 WebDriver 的路径
        System.setProperty("webdriver.chrome.driver", "C:\\Users\\jingnan\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.lanqiao.cn");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        // 滑动到右边
        js.executeScript("window.scrollBy(500, 0);");
        // 会改会员按钮中会员字体的颜色为红色
        js.executeScript("document.getElementsByTagName(\"span\")[0].style=\"color:red\"");

        Thread.sleep(1000);
        driver.quit();
    }
}

上述代码中首先将页面滑动到右边,然后通过 Tag 名称定位到多个 span 元素,取出第一个 span 标签也就是会员按钮,通过添加 style 属性来修改该字体的颜色为红色。

执行上述代码,执行过程如下:

4-2-5

可以看到会员按钮中的字体被成功修改为红色。

使用 JS 判断窗口是否有滚动条

判断页面或者窗口是否有滚动条也是常常会用到的操作,当前窗口是否有滚动条也跟窗口大小是有关系的,判断是否有滚动条可以直接通过这句 JS 代码来实现 document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight);

在 ExecuteJSCommandTest 测试类中新增测试方法 testHasScroll,在该测试方法中执行上述 JS 代码,并通过定义 Boolean 类型变量来接收 JS 代码执行的返回值,具体代码如下:

package cn.lanqiao.js;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ExecuteJSCommandTest {

    @Test
    public void testHasScroll() throws Exception{
        // 设置 WebDriver 的路径
        System.setProperty("webdriver.chrome.driver", "C:\\Users\\jingnan\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();

        JavascriptExecutor js = (JavascriptExecutor) driver;
        String jsCode = "return document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight);";
        driver.get("https://www.lanqiao.cn");
        // 执行 js 代码,返回一个布尔值,即是否有滚动条
        Boolean hasScroll = (Boolean) js.executeScript(jsCode);
        // 输出这个布尔值
        System.out.println(hasScroll);
        
        Thread.sleep(1000);
        driver.quit();
    }
}

执行上述代码,控制台输出结果如下:

true

输出为 true,即表示云课官网是有滚动条的。

由于 JS 运行在浏览器,因此对 DOM 元素的操作非常方便,当无法使用 Selenium 解决的操作时我们可以借助 JS 来完成。

  • 17
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值