本篇文章内容是关于 Selenium 自动化测试工具的常见 API 的使用
Selenium版本:4.23.1
编程语言:Java JDK22
编译器:IDEA 2024.2.0.2
浏览器版本:谷歌浏览器128.0.6613.36(正式版本) (64 位)
ChromeDriver:128.0.6613.84
依赖项下载地址:https://mvnrepository.com/
谷歌浏览器驱动下载地址(一定要和浏览器对应的版本匹配):https://googlechromelabs.github.io/chrome-for-testing/#stable
或者版本比较旧的 https://chromedriver.storage.googleapis.com/index.html
接下来所有的 Web 页面操作示例都会以百度的页面演示
findment 定位页面元素操作
private static void test001() {
ChromeOptions options = new ChromeOptions();
//允许所有请求
options.addArguments("--remote-allow-origins=*");
//打开百度页面
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
//定位元素
webDriver.findElement(By.cssSelector(".s_ipt"));
}
“允许所有请求”操作在 Selenium4 后可以不用添加
页面元素定位可以在页面按F12,然后使用元素选择作即可,找到对应的代码进行 CSS 样式的复制
sendKeys 在搜索框中输入信息
private static void test001() {
ChromeOptions options = new ChromeOptions();
//允许所有请求
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
WebElement element = webDriver.findElement(By.cssSelector(".s_ipt"));
element.sendKeys("测试在搜索框中输入数据");
}
click 模拟点击操作
private static void test001() {
ChromeOptions options = new ChromeOptions();
//允许所有请求
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
WebElement element = webDriver.findElement(By.cssSelector(".s_ipt"));
element.sendKeys("测试在搜索框中输入数据");
//找到“百度一下按钮” 模拟确认操作
webDriver.findElement(By.cssSelector("#su")).click();
}
clear 清空搜索框信息
private static void test001() {
ChromeOptions options = new ChromeOptions();
//允许所有请求
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
WebElement element = webDriver.findElement(By.cssSelector(".s_ipt"));
element.sendKeys("测试在搜索框中输入数据");
//找到“百度一下按钮” 模拟确认操作
webDriver.findElement(By.cssSelector("#su")).click();
webDriver.findElement(By.cssSelector("#kw")).clear();
}
等待操作 (sleep,隐式等待,显式等待)
普通的等待
调用sleep() API即可
智能等待
智能等待可以提前结束等待,比如设置了等待 3 秒,如果 3 秒内满足了条件,就会提前结束等待。最长等待结束时间为 3 秒
智能等待分为 隐式等待 和 显示等待
两者的区别是 隐式等待要等待当前页面的所有元素加载出来后才会提前结束等待。显示等待可以设置为页面上某一个元素加载出来后就可以提前结束等待。
隐式等待
private static void test002() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
}
显示等待
private static void test03() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
//元素出来后,等待结束。
WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(3));
//等待该元素加载出来后就可以提前结束等待
wait.until(ExpectedConditions.titleIs("百度一下,你就知道"));
}
自动化操作浏览器(后退,刷新,前进,滑动滚动条,最大化窗口,全屏,设置窗口大小)
private static void test04() throws InterruptedException {
ChromeOptions options = new ChromeOptions();
//允许所有请求
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
//在搜索框搜索
webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件");
webDriver.findElement(By.cssSelector("#su")).click();
//浏览器后退
sleep(3000);
webDriver.navigate().back();
sleep(3000);
//刷新
webDriver.navigate().refresh();
sleep(3000);
//前进
webDriver.navigate().forward();
sleep(3000);
//滚动条操作 ((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=10000");
//最大化窗口
webDriver.manage().window().maximize();
sleep(3000);
//全屏
webDriver.manage().window().fullscreen();
sleep(3000);
//设置窗口大小
webDriver.manage().window().setSize(new Dimension(600,1000));
}
自动化键盘操作(CTRL + A ,CTRL + X ,CTRL + V)
private static void test05() throws InterruptedException {
ChromeOptions options = new ChromeOptions();
//允许所有请求
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
//在搜索框搜索
webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件");
// ctrl A + X + V
sleep(3000);
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"A");
sleep(3000);
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"X");
sleep(3000);
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"V");
}
自动化鼠标操作(单击左键,单击右键)
private static void test06() throws InterruptedException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("跑步");
webDriver.findElement(By.cssSelector("#su")).click();
sleep(3000);
//找到图片按钮
WebElement webElement = webDriver.findElement(By.cssSelector("#s_tab > div > a.s-tab-item.s-tab-item_1CwH-.s-tab-pic_p4Uej.s-tab-pic"));
Actions actions = new Actions(webDriver);
sleep(3000);
//鼠标右击
actions.moveToElement(webElement).contextClick().perform();
sleep(3000);
//鼠标左击
actions.moveToElement(webElement).click().perform();
}
解释一下 perform
在Selenium WebDriver中,perform() 方法用于执行之前通过 Actions 类构建的一系列鼠标或键盘操作。当你构建了一个动作序列之后,必须调用 perform() 方法来实际执行这些操作。这是因为 Selenium 设计 Actions 类时采用了“构建-执行”模式,这样可以让你灵活地构建一系列连续的动作,然后再一次性执行它们。
为什么需要perform()
构建动作序列:Actions 类允许你构建一系列动作,如移动鼠标、点击等,而不立即执行它们。这使得你可以组合多个动作,形成更复杂的操作。
执行动作序列:一旦构建好了动作序列,你必须调用 perform() 方法来实际执行这些动作。如果不调用 perform() ,构建的动作将不会被执行。
模拟浏览器操作(quit 、close)
private static void test07() throws InterruptedException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
sleep(3000);
//webDriver.quit(); // 关闭整个浏览器
//webDriver.close(); //关闭get方法打开的页面
}
quit 和 close 的区别
quit 关闭的是整个浏览器,而close 只是关闭get打开的页面
quit 会清空缓存,close 不会清空
获取新窗口的操作句柄
当打开一个新的窗口或标签页时,WebDriver会保持在原来的窗口。为了能够与新打开的窗口进行交互,需要使用窗口句柄来切换到那个窗口
private static void test08() throws InterruptedException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
sleep(3000);
//通过 getWindowHandles 获取所有的窗口句柄
//通过 getWindowHandle 获取get打开的页面的窗口句柄
Set<String> handles = webDriver.getWindowHandles();
String target_handle = "";
for(String handle:handles)
{
target_handle = handle;
}
webDriver.switchTo().window(target_handle);
//一定要获取到当前页面句柄才能进行下面的操作
//否则会找不到元素,原因是元素默认是在 get 打开的页面找的
webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");
webDriver.findElement(By.cssSelector("#s_btn_wr")).click();
}
模拟截图操作
截图后需要设置图片的存放路径,设计到文件的操作,需要在 POM 文件引入新的依赖项
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
private static void test09() throws InterruptedException, IOException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件测试");
webDriver.findElement(By.cssSelector("#su")).click();
sleep(3000);
//图片保存路径
File file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file,new File("D://test.png"));
}
findElements 定位一组元素
webdriver 可以很方便的使用findElement 方法来定位某个特定的对象,不过有时候我们却需要定位一组对象,这时候就需要使用findElements 方法。
定位一组对象一般用于以下场景:
批量操作对象,比如将页面上所有的checkbox 都勾上先获取一组对象,再在这组对象中过滤出需要具体定位的一些对象。比如定位出页面上所有的checkbox,然后选择最后一个
以下是 html 代码,页面为一组checkbox 元素,方便演示
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>Checkbox</title>
</head>
<body>
<h3>checkbox</h3>
<div class="well">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="c1">checkbox1</label>
<div class="controls">
<input type="checkbox" id="c1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c2">checkbox2</label>
<div class="controls">
<input type="checkbox" id="c2" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c3">checkbox3</label>
<div class="controls">
<input type="checkbox" id="c3" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio</label>
<div class="controls">
<input type="radio" id="r1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio</label>
<div class="controls">
<input type="radio" id="r2" />
</div>
</div>
</form>
</div>
</body>
</html>
页面如下:
private static void page01() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("D:\\code\\java\\seleniumstudy\\src\\page\\page01.html");
List<WebElement> webElements = webDriver.findElements(By.cssSelector("input"));
for(int i = 0;i < webElements.size();i++)
{
//如果每个元素type值等于checkbox进行点击
//getAttribute 获取页面上的元素属性值,里面的type是当前的元素属性
if(webElements.get(i).getAttribute("type").equals("checkbox"))
{
webElements.get(i).click();
}
else{}
}
}
frame 多层级框架定位
多层级框架定位在Selenium WebDriver中非常重要,尤其是在测试使用了嵌套框架的Web页面时。框架(Frames)是一种HTML元素,用于在一个页面中嵌入另一个独立的文档。当页面包含多个嵌套的框架时,就需要使用多层级框架定位来进行测试。
如果不使用多层级框架定位,就会出现无法定位的情况
前端演示页面代码:
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>frame</title>
<!-- <link-->
<!-- href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstra-->
<!--p-combined.min.css" rel="stylesheet" />-->
<script type="text/javascript">$(document).ready(function(){
});
</script>
</head>
<body>
<div class="row-fluid">
<div class="span10 well">
<h3>frame</h3>
<iframe id="f1" src="inner.html" width="800",
height="600"></iframe>
</div>
</div>
</body>
<!--<script-->
<!-- src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.-->
<!--min.js"></script>-->
</html>
inner.html
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>inner</title>
</head>
<body>
<div class="row-fluid">
<div class="span6 well">
<h3>inner</h3>
<iframe id="f2" src="http://www.baidu.com"
width="700"height="500"></iframe>
<a href="javascript:alert('watir-webdriver better than
selenium webdriver;')">click</a>
</div>
</div>
</body>
</html>
前端页面图
现在想定位 click 这个元素,如果不使用多层级框架定位的 API 是无法定位到的。
private static void page02() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("D:\\code\\java\\seleniumstudy\\src\\page\\page02.html");
webDriver.switchTo().frame("f1");
webDriver.findElement(By.cssSelector("body > div > div > a")).click();
}
模拟 下拉框操作
前端页面代码
<html>
<body>
<select id="ShippingMethod"
onchange="updateShipping(options[selectedIndex]);" name="ShippingMethod">
<option value="12.51">UPS Next Day Air ==> $12.51</option>
<option value="11.61">UPS Next Day Air Saver ==> $11.61</option>
<option value="10.69">UPS 3 Day Select ==> $10.69</option>
<option value="9.03">UPS 2nd Day Air ==> $9.03</option>
<option value="8.34">UPS Ground ==> $8.34</option>
<option value="9.25">USPS Priority Mail Insured ==> $9.25</option>
<option value="7.45">USPS Priority Mail ==> $7.45</option>
<option value="3.20" selected="">USPS First Class ==> $3.20</option>
</select>
</body>
</html>
前端页面图
private static void page03() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("D:\\code\\java\\seleniumstudy\\src\\page\\page03.html");
WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));
Select select = new Select(webElement);
//通过下标选中
//select.selectByIndex(3);
//通过值选中
select.selectByValue("12.51");
}
模拟alert 弹窗操作
前端页面图
点击按钮后,出现弹窗,可以输入信息,并显示到页面
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>弹窗输入信息示例</title>
<style>
#message {
margin-top: 20px;
font-weight: bold;
color: blue;
}
</style>
</head>
<body>
<h1>点击按钮输入信息</h1>
<button onclick="showPrompt()">点击我</button>
<p id="message"></p>
<script>
function showPrompt() {
var input = prompt("请输入一些信息:");
if (input !== null) {
document.getElementById('message').innerText = "你输入的是: " + input;
}
}
</script>
</body>
</html>
自动化操作
private static void page04() throws InterruptedException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("D:\\code\\java\\seleniumstudy\\src\\page\\page04.html");
webDriver.findElement(By.cssSelector("body > button")).click();
sleep(3000);
// alert 弹窗取消
webDriver.switchTo().alert().dismiss();
sleep(3000);
//点击按钮
webDriver.findElement(By.cssSelector("body > button")).click();
//在 alert 弹窗中输入 信息
webDriver.switchTo().alert().sendKeys("测试");
//alert 弹窗确认
sleep(3000);
webDriver.switchTo().alert().accept();
}
模拟文件上传操作
前端页面
点击按钮后可选择文件上传
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传示例</title>
</head>
<body>
<h1>点击按钮上传文件</h1>
<input type="file" id="fileInput" onchange="displayFileName()">
<p id="fileName"></p>
<script>
function displayFileName() {
var fileInput = document.getElementById('fileInput');
var fileName = document.getElementById('fileName');
fileName.innerText = "你选择了文件: " + fileInput.files[0].name;
}
</script>
</body>
</html>
private static void page05() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("D:\\code\\java\\seleniumstudy\\src\\page\\page05.html");
webDriver.findElement(By.cssSelector("#fileInput")).sendKeys("C:\\qg1.ini");
}