文章目录
- 三. 掌握Selenium常用的API使用
- 1. webdriver API
- 2. 操作测试对象
- 3. 添加等待
- 4. 打印信息
- 5. 浏览器的操作
- 6. 键盘事件
- 7. 鼠标事件
- 8. 定位一组元素
- 9. 多层框架/窗口定位
- 10. 下拉框处理
- 11. 弹窗处理
- 12. 上传文件
- 13. 关闭浏览器
- 14. 切换窗口
- 15. 截图操作
三. 掌握Selenium常用的API使用
一次完整的测试流程:
public static void test01() throws InterruptedException {int flag = 0;ChromeOptions options = new ChromeOptions();//允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver();//打开百度首页webDriver.get("https://www.baidu.com");//找到百度搜索输入框WebElement element = webDriver.findElement(By.xpath("//*[@id=\"kw\"]"));//输入"软件测试(要搜索的内容)"element.sendKeys("软件测试");//找到百度一下按钮//点击webDriver.findElement(By.cssSelector("#su")).click();sleep(3000);//校验//找到搜索结果List<WebElement> elements = webDriver.findElements(By.cssSelector("a em"));for(int i = 0; i < elements.size(); i++) {// 如果返回的结果有软件测试,证明测试通过,否则测试不通过if(elements.get(i).getText().equals("测试")) {flag = 1;System.out.println("测试通过");break;}}if(flag == 0) {System.out.println("测试不通过");}}
1. webdriver API
css
选择语法
public static void main(String[] args) {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("软件测试");}
2. Xpath
定位元素
点击复制后:
public static void main(String[] args) {ChromeOptions options = new ChromeOptions();//允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver();//打开百度首页webDriver.get("https://www.baidu.com");//找到百度搜索输入框WebElement element = webDriver.findElement(By.xpath("//*[@id=\"kw\"]"));//输入"软件测试(要搜索的内容)"element.sendKeys("软件测试");}
关于Xpath的详细语法见:
Xpath教程
面试题:css选择器和Xpath选择器的常见语法有哪些?
css选择器:
- 元素选择器:通过元素名称来选择对应的元素。语法形式为"元素名称",例如"div"表示选择所有的div元素。
- 类选择器:通过元素的class属性值来选择对应的元素。语法形式为".class值",例如".myClass"表示选择class属性值为"myClass"的所有元素。
- ID选择器:通过元素的id属性值来选择对应的元素。语法形式为"#id值",例如"#myElement"表示选择id属性值为"myElement"的元素
- 属性选择器:通过元素的属性和属性值来选择对应的元素。语法形式为"[属性=‘属性值’]“,例如”[href=‘https://example.com’]"表示选择href属性值为"https://example.com"的所有元素。
- 伪类选择器:通过元素的特定状态或位置来选择对应的元素。常见的伪类选择器包括:hover(鼠标悬停)、:first-child(第一个子元素)、:last-child(最后一个子元素)等。
Xpath选择器:
- 绝对路径:/html/head/title(不常用)
- 相对路径:
(1)相对路径+索引://from/span[1]/input
(2)相对路径+属性值 ://input[@class="s_ipt"]
(3)相对路径+通配符:// *[@* = "su"]
(4)相对路径+文本匹配://a[text()="新闻"]
面试题:
(1)定位一个元素有哪几种方式(你是通过什么方式定位元素的?)
答:CSS选择器,Xpath定位元素.
(2)CSS选择器和Xpath选择器哪个更好?
CSS选择器定位元素更高效.
2. 操作测试对象
操作 | 说明 |
---|---|
click | 点击对象 |
send_keys | 在对象上模拟按键输入 |
clear | 清除对象输入的文本内容 |
submit | 提交 |
text | 用于获取元素的文本信息 |
getAttribute | 获取属性 |
此处我们主要讲解clear
以及submit
.
clear
操作:
private static void test02() {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();
// 清空输入框中的数据webDriver.findElement(By.cssSelector("#kw")).clear();}
submit
操作:
webDriver.findElement(By.cssSelector("#su")).submit();
我们可以看到,submit
和click
的效果是一样的,但是submit
存在一定的弊端:
如果点击的元素放在form标签中,此时使用submit实现的效果和click是一样的.如果点击的元素放在非form标签中,此时使用submit会报错!
如下:(此时submit操作的不是from标签下的元素)
一般情况下,我们就使用click.
getAttribute
操作:
private static void test04() {ChromeOptions options = new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);webDriver.get("https://www.baidu.com/");String button_value = webDriver.findElement(By.cssSelector("#su")).getAttribute("value");
// System.out.println(button_value);if(button_value.equals("百度一下")) {System.out.println("测试通过");} else {System.out.println(button_value);System.out.println("测试不通过");}}
3. 添加等待
- sleep强制等待
- 智能等待:隐式等待,显示等待
假设等待三天时间:
强制等待一直等待,等待的时间为三天.
隐式等待,最长等待三天时间,如果在三天之内获取到页面上的元素,此时执行下面的代码,如果等待三天还是没有找到这个元素,就会报错.
强制等待:
智能等待: 隐式等待:
private static void test02() 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")).submit();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);
// 清空输入框中的数据webDriver.findElement(By.cssSelector("#kw")).clear();}
智能等待:显示等待:
private static void test06() {
// #bottom_layer > div > p:nth-child(8) > span// 创建驱动WebDriver webDriver = new ChromeDriver();// 打开百度首页webDriver.get("https://www.baidu.com/");// 判断元素是否可以被点击WebDriverWait wait = new WebDriverWait(webDriver, 1);
// wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#bottom_layer > div > p:nth-child(8)")));wait.until(ExpectedConditions.titleIs("百度一下,你就知道"));}
此处需要注意隐式等待和显示等待的区别:
- 作用范围:隐式等待是全局性的等待设置,适用于整个页面的元素定位操作;显示等待是针对特定元素或条件的等待设置,更具体、可定制性更强。
- 等待时间:隐式等待只需设置一次,并适用于所有元素的定位操作;显示等待可以根据不同情况设定不同的等待时间。
- 等待条件:隐式等待没有明确的等待条件,只要在规定时间内找到元素即可;显示等待可以指定等待元素可见、可点击等特定条件。
- 操作方式:隐式等待是自动等待的,不需要在代码中显式调用;显示等待需要在代码中显式调用等待方法。
4. 打印信息
打印url
&&打印title
private static void test05() {ChromeOptions options = new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);webDriver.get("https://www.baidu.com/");String url = webDriver.getCurrentUrl();String title = webDriver.getTitle();if(url.equals("https://www.baidu.com/") && title.equals("百度一下,你就知道")) {System.out.println("当前页面url:" + url + ",当前页面title:" + title);System.out.println("测试通过");} else {System.out.println("测试不通过");}}
5. 浏览器的操作
操作 | 说明 |
---|---|
browser.maximize_window() | 浏览器的最大化 |
browser.set_window_size(width, high) | 设置浏览器宽、高 |
browser.forward() | 浏览器的前进 |
browser.back() | 浏览器的后退 |
document.documentElement.scrollTop=0 | 将浏览器滚动条滑到最顶端 |
document.documentElement.scrollTop=10000 | 将浏览器滚动条滑到最底端 |
- 浏览器前进,后退,刷新操作
private static void test07() throws InterruptedException {WebDriver webDriver = new ChromeDriver();// 打开百度首页webDriver.get("https://wwww.baidu.com/");// 搜索521webDriver.findElement(By.cssSelector("#kw")).sendKeys("521");// 强制等待3秒webDriver.findElement(By.cssSelector("#su")).click();// 浏览器后退sleep(3000);webDriver.navigate().back();// 强制等待3秒sleep(3000);//浏览器刷新webDriver.navigate().refresh();// 浏览器前进sleep(3000);webDriver.navigate().forward();
3. 浏览器滚动条操作,窗口操作
private static void test07() throws InterruptedException {WebDriver webDriver = new ChromeDriver();// 打开百度首页webDriver.get("https://wwww.baidu.com/");// 搜索521webDriver.findElement(By.cssSelector("#kw")).sendKeys("521");// 强制等待3秒webDriver.findElement(By.cssSelector("#su")).click();//滚动条操作sleep(3000);//网页的滚动条会自动向下滚动至10000像素的位置((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=10000");sleep(3000);//窗口最大化webDriver.manage().window().maximize();sleep(3000);//窗口全屏webDriver.manage().window().fullscreen();sleep(3000);//设置指定窗口大小webDriver.manage().window().setSize(new Dimension(600, 1000));}
6. 键盘事件
操作 | 说明 |
---|---|
send_keys(Keys.TAB) | # TAB |
send_keys(Keys.ENTER) | # 回车 |
send_keys(Keys.SPACE) | #空格键 |
send_keys(Keys.ESCAPE) | #回退键(Esc) |
send_keys(Keys.CONTROL,‘a’) | #全选(Ctrl+A) |
send_keys(Keys.CONTROL,‘c’) | #复制(Ctrl+C) |
send_keys(Keys.CONTROL,‘x’) | #剪贴(Ctrl+X) |
send_keys(Keys.CONTROL,‘v’) | #粘贴(Ctrl+V) |
键盘的全选,剪切,粘贴操作演示:
private static void test08() throws InterruptedException {WebDriver webDriver = new ChromeDriver();// 打开百度首页webDriver.get("https://wwww.baidu.com/");// 搜索521webDriver.findElement(By.cssSelector("#kw")).sendKeys("521");// control+AwebDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "A");sleep(3000);// control+XwebDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "X");sleep(3000);// control+VwebDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "V");sleep(3000);}
7. 鼠标事件
操作 | 说明 |
---|---|
context_click() | 右击 |
double_click() | 双击 |
drag_and_drop() | 拖动 |
move_to_element() | 移动 |
context_click()
演示:
private static void test09() throws InterruptedException {WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com/");webDriver.findElement(By.cssSelector("#kw")).sendKeys("520");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);//contextClick()右击鼠标actions.moveToElement(webElement).contextClick().perform();}
8. 定位一组元素
webdriver
可以很方便的使用findElement
方法来定位某个特定的对象,不过有时候我们却需要定位一组对象,这时候就需要使用findElements
方法。
定位一组对象一般用于以下场景:
- 批量操作对象,比如将页面上所有的
checkbox
都勾上 - 先获取一组对象,再在这组对象中过滤出需要具体定位的一些对象。比如定位出页面上所有的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>
findElements
示例(将页面上所有的checkbox
都勾上):
private static void page01() {WebDriver webDriver = new ChromeDriver();webDriver.get("http://localhost:63342/_20230925testcode/src/main/Page/test01.html?_ijt=hk3glm0bcb2222roak6kf4826i&_ij_reload=RELOAD_ON_SAVE");webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);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 {// 否则什么也不操作;}}}
9. 多层框架/窗口定位
对于一个web应用,经常会出现框架(yrame或窗口(window)的应用,这也就给我们的定位带来了一定的困难。
- 定位一个frame :
switch_to.frame(name_or_id_or_frame_element)
- 定位一个窗口window:
switch_to.window(name_or_id_or_frame_element)
有以下页面:
<html>
<head><meta http-equiv="content-type" content="text/html;charset=utf-8" /><title>frame</title><!-- <link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-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="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>-->
</html>
frame
演示:
private static void page02() {WebDriver webDriver = new ChromeDriver();webDriver.get("http://localhost:63342/_20230925testcode/src/main/Page/test02.html?_ijt=sdck9iv3t1f7l8bv2khvu2k87t&_ij_reload=RELOAD_ON_SAVE");webDriver.switchTo().frame("f1");webDriver.findElement(By.cssSelector("body > div > div > a")).click();}
10. 下拉框处理
有以下界面:
<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>
通过Index
和Value
来选择演示:
private static void page03() {WebDriver webDriver = new ChromeDriver();webDriver.get("http://localhost:63342/_20230925testcode/src/main/Page/test03.html?_ijt=ibu1q228hs9l4q026vbbfjp8r3&_ij_reload=RELOAD_ON_SAVE");WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));Select select = new Select(webElement);//通过下标来选择
// select.selectByIndex(3);//通过value值来选择select.selectByValue("12.51");}
11. 弹窗处理
有以下页面:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<button onclick="Click()">这是一个弹窗</button>
</body>
<script type="text/javascript">function Click() {let name = prompt("请输入姓名:");let parent = document.querySelector("body");let child = document.createElement("div");child.innerHTML = name;parent.appendChild(child)}
</script>
</html>
alert
相关操作:
private static void page04() throws InterruptedException {WebDriver webDriver = new ChromeDriver();webDriver.get("http://localhost:63342/_20230925testcode/src/main/Page/test04.html?_ijt=bv9np3tl8gm9kv04oam7i2sfij&_ij_reload=RELOAD_ON_SAVE");webDriver.findElement(By.cssSelector("button")).click();sleep(3000);// alert弹窗取消webDriver.switchTo().alert().dismiss();sleep(3000);// 点击按钮webDriver.findElement(By.cssSelector("button")).click();// 在alert弹窗中输入"xxxflower"webDriver.switchTo().alert().sendKeys("xxxflower");// alert弹窗确认sleep(3000);webDriver.switchTo().alert().accept();}
12. 上传文件
上传过程一般要打开一个本地窗口,从窗口选择本地文件添加。所以,一般会卡在如何操作本地窗口添加上传文件。
其实,在selenium webdriver
没我们想的那么复杂;只要定位上传按钮,通过send_keys 添加本地文件路径就可以了。绝对路径和相对路径都可以,关键是上传的文件存在.
private static void page05() {WebDriver webDriver = new ChromeDriver();webDriver.get("http://localhost:63342/_20230925testcode/src/main/Page/test05.html?_ijt=16g56va44mth0ok9g9lfkdqj32&_ij_reload=RELOAD_ON_SAVE");webDriver.findElement(By.cssSelector("input")).sendKeys("E:\\壁纸\\haimianbaobao.png");}
13. 关闭浏览器
关闭浏览器有两种方式,分别为
quit();
close();
需要注意的是quit();
和close
之间的区别:
(1)quit关闭了整个浏览器,close关闭了当前的页面.
close的当前页面指的是操作的该页面,也就是百度首页.
(2)quit清空缓存,close不会清空缓存
quit();
和close();
的演示:
private static void test10() 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(2000);webDriver.quit();
// webDriver.close();}
quit();
close();
14. 切换窗口
当我们从百度页面打开新闻页面的时候,此时我们如果想要在新闻页面操作百度一下,那么就得切换窗口.即改变句柄(操作的对象).此时我们就可以使用.getWindowHandles();
获取全部的句柄,遍历存储全部句柄的Set
获取到我们需要的最后一个句柄,然后通过webDriver.switchTo().window(target_handle);
切换窗口.于是我们就可以操作新闻页面的百度一下了.
private static void test11() 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(1000);// 通过getWindowHandles获取所有的窗口句柄// 通过getWindowHandle获取的get打开的页面窗口句柄System.out.println(webDriver.getWindowHandle());Set<String> handles = webDriver.getWindowHandles();String target_handle = "";for(String handle:handles) {target_handle = handle;}webDriver.switchTo().window(target_handle);sleep(3000);//在输入框中搜索新闻联播webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");//点击"百度一下"webDriver.findElement(By.cssSelector("#s_btn_wr")).click();}
15. 截图操作
引入Maven
依赖:
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency>
截图操作演示:
private static void test12() 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);//将截图好的图片存储到E://20231005jietu.png路径下FileUtils.copyFile(file, new File("E://20231005jietu.png"));}