参考原文来源于重定向科技:http://class.itest.info/selenium_java
selenium java(下)
十一、设置元素等待
WebDriver提供了两种类型的等待:显式等待 和 隐式等待。
显式等待
WebDriver提供了显式等待方法,专门针对某个元素进行等待判断。
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.*;
public class TimeOut01 {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new ChromeDriver();
driver.get("https://www.baidu.com");
// 显示等待,针对某个元素等待
WebDriverWait wait = new WebDriverWait(driver, 10, 1);
wait.until(new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver webDriver) {
return webDriver.findElement(By.id("kw"));
}
}).sendKeys("selenium");
driver.findElement(By.id("su")).click();
Thread.sleep(2000);
driver.quit();
}
}
WebDriverWait类是由WebDirver提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常。具体格式如下:
WebDriverWait(driver, 10, 1)
driver: 浏览器驱动。
10(timeOutInSeconds): 最长超时时间, 默认以秒为单位。
1(sleepInMillis): 检测的间隔(步长) 时间, 默认为 0.5s。
隐式等待
WebDriver 提供了几种方法来等待元素。
implicitlyWait()
。识别对象时的超时时间。过了这个时间如果对象还没找到的话就会抛出NoSuchElement异常。setScriptTimeout()
。异步脚本的超时时间。WebDriver可以异步执行脚本,这个是设置异步执行脚本脚本返回结果的超时时间。pageLoadTimeout()
。页面加载时的超时时间。因为WebDriver会等页面加载完毕再进行后面的操作,所以如果页面超过设置时间依然没有加载完成,那么WebDriver就会抛出异常。
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
public class TimeOut02 {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
// 页面加载超时时间设置为 5s
driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);
driver.get("https://www.baidu.com");
// 定位对象时给 10s 的时间,如果 10s 内还定位不到则抛出异常
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.findElement(By.id("kw")).sendKeys("selenium");
// 异步脚本的超时时间设置为 3s
driver.manage().timeouts().setScriptTimeout(3, TimeUnit.SECONDS);
driver.quit();
}
}
十二、定位一组元素
在第(五)节我们已经学习了8种定位方法, 那8种定位方法是针对单个元素定位的, WebDriver还提供了另外8种用于定位一组元素的方法。
import org.openqa.selenium.By;
......
findElements(By.id())
findElements(By.name())
findElements(By.className())
findElements(By.tagName())
findElements(By.linkText())
findElements(By.partialLinkText())
findElements(By.xpath())
findElements(By.cssSelector())
定位一组元素的方法与定位单个元素的方法类似,唯一的区别是在单词 findElement 后面多了一个 s 表示复数。
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.List;
public class ElementsDemo {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new ChromeDriver();
driver.get("https://www.baidu.com/");
WebElement search_text = driver.findElement(By.id("kw"));
search_text.sendKeys("selenium");
search_text.submit();
Thread.sleep(2000);
//匹配第一页搜索结果的标题, 循环打印
List<WebElement> search_result = driver.findElements(By.xpath("//h3"));
//打印元素的个数
System.out.println(search_result.size());
// 循环打印搜索结果的标题
for(WebElement result : search_result){
System.out.println(result.getText());
}
driver.quit();
}
}
打印结果:
12
selenium - 百度翻译
Selenium(WEB自动化工具) - 百度百科
selenium--软件测试培训-免费领取试听课程
selenium安装相关博客
Selenium
selenium在线学习,从入门到精通-慕课网
Selenium - 开源的集成测试工具- Gitee 极速下载
selenium中文网 | selenium安装、selenium使用、selenium...
Python+Selenium详解(超全)
功能自动化测试工具——Selenium篇
selenium吧 - 百度贴吧
selenium基础入门_叶常落的博客-CSDN博客_selenium
十三、多表单切换
在 Web 应用中经常会遇到 frame/iframe 表单嵌套页面的应用, WebDriver 只能在一个页面上对元素识别与 定位, 对于 frame/iframe 表单内嵌页面上的元素无法直接定位。 这时就需要通过 switchTo().frame()
方法将当前定位的主体切换为 frame/iframe 表单的内嵌页面中。
<html>
<body>
...
<iframe id="x-URS-iframe" ...>
<html>
<body>
...
<input name="email" >
126邮箱登录框的结构大概是这样子的,想要操作登录框必须要先切换到iframe表单。
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class MailLogin {
public static void main(String[] args){
WebDriver driver = new ChromeDriver();
driver.get("http://www.126.com");
WebElement xf = driver.findElement(By.xpath("//*[@id='loginDiv']/iframe"));
driver.switchTo().frame(xf);
driver.findElement(By.name("email")).clear();
driver.findElement(By.name("email")).sendKeys("username");
driver.findElement(By.name("password")).clear();
driver.findElement(By.name("password")).sendKeys("password");
driver.findElement(By.id("dologin")).click();
driver.switchTo().defaultContent();
//……
}
}
如果完成了在当前表单上的操作,则可以通过 switchTo().defaultContent()
方法跳出表单。
十四、多窗口切换
在页面操作过程中有时候点击某个链接会弹出新的窗口, 这时就需要主机切换到新打开的窗口上进行操作。WebDriver提供了 switchTo().window()
方法可以实现在不同的窗口之间切换。
以百度首页和百度注册页为例,在两个窗口之间的切换如下图。
实现窗口切换的代码如下:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.Set;
public class MoreWindows {
public static void main(String[] args) throws InterruptedException{
WebDriver driver = new ChromeDriver();
driver.get("https://www.baidu.com");
//获得当前窗口句柄
String search_handle = driver.getWindowHandle();
//打开百度注册窗口
driver.findElement(By.linkText("登录")).click();
Thread.sleep(3000);
driver.findElement(By.linkText("立即注册")).click();
//获得所有窗口句柄
Set<String> handles = driver.getWindowHandles();
//判断是否为注册窗口, 并操作注册窗口上的元素
for(String handle : handles){
if (!handle.equals(search_handle)){
//切换到注册页面
driver.switchTo().window(handle);
System.out.println("now register window!");
Thread.sleep(2000);
driver.findElement(By.name("userName")).clear();
driver.findElement(By.name("userName")).sendKeys("user name");
driver.findElement(By.name("phone")).clear();
driver.findElement(By.name("phone")).sendKeys("phone number");
//......
Thread.sleep(2000);
//关闭当前窗口
driver.close();
}
}
Thread.sleep(2000);
driver.quit();
}
}
在本例中所涉及的新方法如下:
- getWindowHandle(): 获得当前窗口句柄。
- getWindowHandles(): 返回所有窗口的句柄到当前会话。
- switchTo().window(): 用于切换到相应的窗口,与上一节的switchTo().frame()类似,前者用于不同窗口的切换, 后者用于不同表单之间的切换。
ps:句柄(Handle)是一个是用来标识对象或者项目的标识符,可以用来描述窗体、文件等,值得注意的是句柄不能是常量 。
十五、下拉框选择
有时我们会碰到下拉框,WebDriver提供了Select类来处理下拉框。
如招聘网站的下拉框,如下图:
搜索下拉框实现代码如下:
<select name="" id="jobarea" style="">
<option value="">请选择工作地点</option>
<option value="010000">北京</option>
<option value="020000">上海</option>
<option value="030200">广州</option>
<option value="090200">成都</option>
<option value="110300">厦门</option>
<option value="160200">石家庄</option>
<option value="200200">西安</option>
</select>
操作下拉框代码如下:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.Select;
public class SelectDemo {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new ChromeDriver();
driver.get("http://campus.51job.com/ecloud2022/about.3.html");
//<select>标签的下拉框选择
WebElement el = driver.findElement(By.xpath("//select"));
Select sel = new Select(el);
sel.selectByVisibleText("成都"); //或者sel.selectByValue("090200");
Thread.sleep(2000);
driver.quit();
}
}
Select类用于定位select标签。 selectByValue()方法符用于选取标签的value值。
十六、警告框处理
在 WebDriver中处理JavaScript所生成的alert、confirm以及prompt十分简单,具体做法是使用 switchTo().alert()
方法定位到alert/confirm/prompt,然后使用text/accept/dismiss/sendKeys等方法进行操作。
- getText(): 返回 alert/confirm/prompt 中的文字信息。
- accept(): 接受现有警告框。
- dismiss(): 解散现有警告框。
- sendKeys(keysToSend): 发送文本至警告框。
- keysToSend: 将文本发送至警告框。
如下图,百度搜索设置弹出的窗口是不能通过前端工具对其进行定位的,这个时候就可以通过 switchTo().alert()
方法接受这个弹窗。
接受一个警告框的代码如下:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class AlertDemo {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new ChromeDriver();
driver.get("https://www.baidu.com");
driver.findElement(By.xpath("//*[@id=\"s-usersetting-top\"]")).click();
driver.findElement(By.linkText("搜索设置")).click();
Thread.sleep(2000);
//保存设置
driver.findElement(By.className("prefpanelgo")).click();
//接收弹窗
driver.switchTo().alert().accept();
Thread.sleep(2000);
driver.quit();
}
}
十七、文件上传
对于通过input标签实现的上传功能,可以将其看作是一个输入框,即通过sendKeys()指定本地文件路径的方式实现文件上传。
创建upfile.html文件,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>upload_file</title>
<link href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="row-fluid">
<div class="span6 well">
<h3>upload_file</h3>
<input type="file" name="file"/>
</div>
</div>
</body>
<script src="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.js"></script>
</html>
通过浏览器打开upfile.html文件,功能如下图。
接下来通过sendKeys()方法来实现文件上传。
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
public class UpFileDemo {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new ChromeDriver();
File file = new File("./src/main/HTMLFile/upfile.html"); //.为当前项目目录
String filePath = file.getAbsolutePath();
driver.get(filePath);
//定位上传按钮, 添加本地文件
driver.findElement(By.name("file")).sendKeys("E:\\dev\\upload_file.txt");
Thread.sleep(5000);
driver.quit();
}
}
十八、浏览器cookie操作
有时候我们需要验证浏览器中Cookie是否正确, 因为基于真实Cookie的测试是无法通过白盒测试和集成测试进行的。WebDriver提供了操作Cookie的相关方法可以读取、 添加和删除Cookie信息。
WebDriver 操作Cookie的方法:
getCookies()
获得所有 cookie 信息。getCookieNamed(String name)
返回字典的key为“name”的Cookie信息。addCookie(cookie dict)
添加Cookie。“cookie_dict”指字典对象,必须有 name和value值。deleteCookieNamed(String name)
删除Cookie 信息。 “name”是要删除的cookie的名称; “optionsString” 是该Cookie的选项,目前支持的选项包括“路径” , “域” 。deleteAllCookies()
删除所有 cookie 信息。
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.Set;
public class CookieDemo {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://www.baidu.com");
Cookie c1 = new Cookie("name", "key-aaa");
Cookie c2 = new Cookie("value", "value-bbb");
driver.manage().addCookie(c1);
driver.manage().addCookie(c2);
//获得 cookie
Set<Cookie> coo = driver.manage().getCookies();
System.out.println(coo);
//删除所有 cookie
//driver.manage().deleteAllCookies();
driver.quit();
}
}
// 打印结果:[BIDUPSID=9FC1D8C667ECCE511C56050F8E3DF078; expires=星期二, 04 十月 2089 07:45:39 CST; path=/; domain=.baidu.com, name=key-aaa; path=/; domain=www.baidu.com;secure;, BA_HECTOR=a9a42gaha4ak2hckm81gk60770q; expires=星期四, 16 九月 2021 05:31:34 CST; path=/; domain=.baidu.com, PSTM=1631781092; expires=星期二, 04 十月 2089 07:45:39 CST; path=/; domain=.baidu.com, H_PS_PSSID=34649_34439_31254_34549_33848_34525_34585_34092_26350_34627_34419_34474_34691; path=/; domain=.baidu.com, BD_UPN=12314753; expires=星期日, 26 九月 2021 04:31:34 CST; path=/; domain=www.baidu.com, value=value-bbb; path=/; domain=www.baidu.com;secure;, BAIDUID=9FC1D8C667ECCE51A9BFDF46FF70B85E:FG=1; expires=星期五, 16 九月 2022 04:31:32 CST; path=/; domain=.baidu.com, BD_HOME=1; path=/; domain=www.baidu.com]
十九、调用JavaScript代码
虽然WebDriver提供了操作浏览器的前进和后退方法,但对于浏览器滚动条并没有提供相应的操作方法。在这种情况下,就可以借助JavaScript来控制浏览器的滚动条。WebDriver提供了executeScript()方法来执行JavaScript代码。
用于调整浏览器滚动条位置的JavaScript代码如下:
<!-- window.scrollTo(左边距,上边距); -->
window.scrollTo(0,450);
window.scrollTo()方法用于设置浏览器窗口滚动条的水平和垂直位置。方法的第一个参数表示水平的左间距,第二个参数表示垂直的上边距。其代码如下:
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class JSDemo {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new ChromeDriver();
//设置浏览器窗口大小
driver.manage().window().setSize(new Dimension(700, 600));
driver.get("https://www.baidu.com");
//进行百度搜索
driver.findElement(By.id("kw")).sendKeys("webdriver api");
driver.findElement(By.id("su")).click();
Thread.sleep(2000);
//将页面滚动条拖到底部
((JavascriptExecutor)driver).executeScript("window.scrollTo(100,450);");
Thread.sleep(3000);
driver.quit();
}
}
通过浏览器打开百度进行搜索,并且提前通过window().setSize()方法将浏览器窗口设置为固定宽高显示,目的是让窗口出现水平和垂直滚动条。然后通过executeScript()方法执行JavaScripts代码来移动滚动条的位置。
二十、获取窗口截图
自动化用例是由程序去执行,因此有时候打印的错误信息并不十分明确。如果在脚本执行出错的时候能对当前窗口截图保存,那么通过图片就可以非常直观地看出出错的原因。 WebDriver提供了截图函数getScreenshotAs()来截取当前窗口。
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;
public class GetImg {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://www.baidu.com");
File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(srcFile, new File("e:\\screenshot.png"));
} catch (IOException e) {
e.printStackTrace();
}
driver.quit();
}
}
脚本运行完成后打开E盘,就可以找到screenshot.png图片文件了。
其中FileUtils为文件操作工具类,需导入commons-io依赖。
关于selenium的详细使用教程请参考selenium官方文档
上一篇:selenium java教程(上)