在使用 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 字符串,执行上述代码,输出结果如下:
在页面比较长的时候,我们要操作的目标元素并没有显示在当前页面中,需要滑动滚动条使元素显示在当前窗口中,这种操作也需要借助 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();
}
}
上述代码的执行过程如下:
可以看到页面滚动到了底部,这样我们就可以对页面底部的元素进行定位和操作了。
接着我们来测试 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();
}
}
执行上述代码,执行过程如下:
可以看到 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 方法使该元素显示在当前页面上,执行上述方法,执行过程如下:
除了常用的控制滚动条外,我们接着来介绍其他常用的 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 属性来修改该字体的颜色为红色。
执行上述代码,执行过程如下:
可以看到会员按钮中的字体被成功修改为红色。
使用 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 来完成。
版权归原作者 onforget 所有, 如有侵权,请联系我们删除。