目录
WebDriver 类 常用 API
WebDriver 提供了一系列的 API 来和浏览器进行交互。
WebDriver 类常用方法:
方法 | 描述 |
---|---|
get(String url) | 访问目标 url 地址,打开网页 |
getCurrentUrl() | 获取当前页面 url 地址 |
getTitle() | 获取页面标题 |
getPageSource() | 获取页面源代码 |
close() | 关闭浏览器当前打开的窗口(指焦点窗口),不清空缓存 |
quit() | 关闭浏览器所有的窗口,并清空缓存 |
findElement(by) | 查找单个元素 |
findElements(by) | 查到元素集合,返回一个List |
getWindowHandle() | 获取当前窗口的操控柄 |
getWindowHandles() | 获取所有窗口的操控柄 |
WebElement 类 常用 API
通过 WebElement 实现与网站页面上元素的交互,这些元素包含文本框、文本域、按钮、单选框、div等。
WebElement 类常用方法:
方法 | 描述 |
---|---|
click() | 对元素进行点击 |
clear() | 清空内容(如文本框内容) |
sendKeys(…) | 写入内容与模拟按键操作 |
isDisplayed() | 元素是否可见 |
isEnabled() | 元素是否可用 |
isSelected() | 元素是否已被选择 |
getTagName() | 获取元素标签名 |
getAttribute(attributeName) | 获取元素对应的属性值 |
getText() | 获取元素文本值(元素可见状态下才能获取到) |
submit() | 表单提交 |
元素等待机制
sleep()方法
线程类 Thread 中的 sleep 方法,强制等待。该方法会让线程进行休眠。
Thread.sleep(longmillis);
隐式等待
调用方法:
driver.manage().timeouts().implicitlyWait(long time, TimeUtil unit);
隐式等待是指,当脚本执行到某个元素定位语句时,如果元素可以定位,则继续执行;如果元素定位不到,则它以轮询的方式不断的判断元素是否被定位到。直到超出设置的时长。
隐式等待的特点:
- 隐式等待只能作用于元素的等待。
- 智能等待,网页在指定时间内加载完成,且元素在指定的时间内找到,则不会继续等待,否则在指定时间内未找到元素则抛出NoSuchElementException。
- 作用域是全局的,生命周期与driver保持一致。设置隐式等待后,页面所有的元素都会被绑定这种等待机制,全局有效,直到driver实例被关闭。
- 如果多次设置隐式等待,那么最后一次的设置会覆盖之前的设置。
- 隐式等待适用于页面元素加载时间不确定的情况,因为它可以在元素加载完成之前,使脚本暂停执行。
显式等待
调用方法:
WebDriverWait wait = new WebDriverWait(WebDriver driver, long timeOutInSeconds);
wait.until(ExpectedConditions....);
显式等待与隐式等待区别在于:
- 主要区别在于显式等待不止可以作用于元素定位,还可以等待某些条件(如查找元素是否可点击)。
- 不同于隐式等待的全局设置,显式等待非全局设置,即每次使用都需要给出具体的等待条件(如定位某一个元素)。
- 智能等待,指定条件在指定时间内达成,则不会继续等待,否则抛出TimeOutException。
重写 apply() 方法
apply() 方法是 ExpectedCondition 接口的父接口 Function<F, T> 接口下的方法,主要用于轮询元素工作。
重写该方法可以在轮询逻辑中加入自定义逻辑(如指定查找区域)。
public WebElement getElement(long timeOutInSecond, By by) { WebDriverWait wait = new WebDriverWait(driver, timeOutInSecond); WebElement element = wait.until(new ExpectedCondition<WebElement>() { @NullableDecl @Override public WebElement apply(@NullableDecl WebDriver webDriver) { return webDriver.findElement(by); } }); return element; }
ExpectedConditions类中常用方法
方法 | 描述 |
---|---|
presenceOfElementLocated(By locator) | 判断某个元素是否被加到了dom树里,并不代表该元素一定可见; |
visibilityOfElementLocated(By locator) | 判断某个元素是否可见(代表元素非隐藏,元素的宽和高都不等于0); |
elementToBeClickable(By locator) | 判断某个元素中是否可见并且是enable的且可点击; |
elementToBeSelected(By locator) | 判断某个元素是否被选中了,一般用在下拉列表; |
alertIsPresent() | 判断页面上是否存在alert; |
titleIs(String title) | 判断当前页面的title是否精确等于预期; |
titleContains(String title) | 判断当前页面的title是否包含预期字符串; |
textToBePresentInElement(By locator, String text) | 判断某个元素中的text是否包含了预期的字符串; |
textToBePresentInElementValue(By locator, String text) | 判断某个元素中的value属性是否包含了预期的字符串; |
invisibilityOfElementLocated(By locator) | 判断某个元素中是否不存在于dom树或不可见; |
frameToBeAvailableAndSwitchToIt(By locator) | 判断iframe可用,并且切换到iframe中 |
页面加载超时设置
通过TimeOuts 对象进行全局页面加载超时的设置,该设置必须放置get 方法之前。
driver.manage().timeouts().pageLoadTimeout(long var1, TimeUnit var3);
浏览器操作
控制浏览器操作
Window 类
WebDriver 提供了一个 Window 对象,专门用于对窗口的设置。
获取对象:
Window window = driver.manage().window();
Window 类常用方法:
方法 | 描述 |
---|---|
maximize() | 将浏览器窗口最大化。 |
getPosition() | 获取窗口的位置,返回 Point 对象,包含浏览器左上角的坐标位置。通过point.x 和point.y 来获取到。 |
setPosition(Point) | 指定浏览器窗口左上角的坐标位置,创建一个Point 对象,设置对象的 x 和 y 坐标即可。 |
getSize() | 获取窗口尺寸(宽和高),返回一个 Dimension 对象,通过该对象调用 getHeight() 和 getWidth() 来获取 高度和宽度。 |
setSize(Dimension) | 设置窗口大小,创建一个 Dimension 对象,设置对象的高度和宽度。 |
Navigation 类
WebDriver 提供了 Navigation 对象来对浏览器进行导航操作,如:前进、后退、刷新等。
获取对象:
Navigation navigate = driver.navigate();
Navigation 类常用方法:
方法 | 描述 |
---|---|
to(url) | 跳转到指定url,和 webdriver 使用 get 方法是一样的。 |
refresh() | 刷新当前页面。 |
back() | 浏览器回退操作。 |
forward() | 浏览器前进操作。 |
浏览器窗口的切换
浏览器窗口有“句柄”的概念,在这里将“句柄”理解为“操作杆”即可。
每个窗口都有一个操作杆,当需要操作某个窗口时,首先要“握住”这个窗口的“操作杆”。
WebDriver 类中获取窗口“操作杆”的方法:
// 获取当前窗口的句柄 String handle = driver.getWindowHandle(); // 获取所有窗口的句柄,返回一个集合 Set<String> handles = driver.getWindowHandles();
WebDriver 类中切换窗口的方法:
// 切换到窗口 driver.switchTo().window(String handle); driver.switchTo().window(String windowId); driver.switchTo().window(String title);
多窗口查找,通常可以通过匹配title属性来判断是否为所需窗口。
滚动条操作
浏览器的滚动条操作,需要借助 JavaScript 来控制。
在 JavaScript 中,函数
window.scrollTo(0,0)
用于调整滚动条。
函数的两个参数分别是水平坐标和垂直坐标。
WebDriver 类中用于执行 JavaScript 代码的方法:
//根据坐标滚动滚动条; ((JavascriptExecutor)driver).executeScript("window.scrollTo(0,0)"); //根据元素定位滚动滚动条;(使用JavaScript方法获取元素) ((JavascriptExecutor)driver).executeScript( "document.getElementById('s_btn_wr').scrollIntoView(0);"); //根据元素定位滚动滚动条;(使用Java方法获取元素) ((JavascriptExecutor)driver).executeScript( "arguments[0].scrollIntoView(0)",driver.findElement(By.className("cname")));
弹出框处理(alert、confirm)
操作alert、confirm弹出框,可以通过Alert 对象来进行操作,Alert类包含了确认、取消、输入和获取弹出窗内容。
Alert 类中用于进行弹框处理的方法:
方法 | 描述 |
---|---|
getText() | 获取弹出框内容。 |
accept() | 接受弹窗的提示,相当于点击确认按钮。 |
dismiss() | 取消提示窗。 |
sendKeys() | 给弹窗输入内容。 |
如果弹出框不是 js 原生的 alert 弹窗,则仍旧使用 findElement() 定位元素的相关方法。
网页控件和元素操作
iframe 切换
iframe 指网页嵌套,可以嵌套多层,焦点在外层时,无法查找内层的元素。因此查找不同层元素时,需要切换 iframe 。
TargetLocator 接口中用于切换 iframe 的三个重载方法:
// 方法一:通过 iframe 的索引值 driver.switchTo().frame(index); // 方法二:通过 iframe 的 name 或者 id driver.switchTo().frame(nameOrId); // 方法三:通过 iframe 对应的 webElement(常用) driver.switchTo().frame(frameElement);
文件上传
上传功能通过 input 标签实现,可以将其看作是一个输入框,即通过sendKeys()指定本地文件路径的方式实现文件上传。
定位上传按钮, 添加本地文件:
driver.findElement(By).sendKeys("绝对路径");
sendKeys 参数为文件的绝对路径,并且上传的文件一点要存在,否则会抛异常
带 readonly 属性的元素操作
标签元素如果带有 readonly 属性,表示只读不能进行编辑。
操作该类元素,需要先把 readonly 属性移除,再进行操作。
webdriver 没有用于删除标签属性的 API,需要使用 JavaScript 脚本进行删除操作。
//定位元素(可以使用 JavaScript 也可以使用 Java,以下使用 JavaScript) //通过 JavaScript 移除 readonly 属性,并使用 executeScript() 方法执行 JavaScript 语句: ((JavascriptExecutor)driver).executeScript( "document.getElementById('元素id').removeAttribute('readonly')");
select 下拉框处理
当页面元素为下拉框(select)时,selenium 使用专门的 Select 类对下拉框框进行操作。
其中包含了单选和多选下拉框的各种操作,如获得所有的选项、选择某一项、取消选中某一项、是否是多选下拉框等。
Select 类常用方法:
方法 | 描述 |
---|---|
void deselectAll() | 取消所有选择项,仅对下拉框的多选模式有效,若下拉不支持多选模式,则会抛出异常 UnsupportedOperationException |
void deselectByIndex(int index) | 取消指定index的选择,index从零开始,仅对多选模式有效,否则抛出异常 UnsupportedOperationException |
void deselectByValue(String value) | 取消Select标签中value为指定值的选择,仅对多选模式有效,否则抛出异常 UnsupportedOperationException |
void deselectByVisibleText(String Text) | 取消选项的文字为指定值的项,仅对多选模式有效,单选模式无效,但不会抛出异常 |
List getAllSelectedOptions() | 获得所有选中项,单选多选模式均有效,但没有一个被选中时,返回空列表,不会抛出异常 |
WebElement getFirstSelectedOption() | 获得第一个被选中的项,单选多选模式均有效,当多选模式下,没有一个被选中时,会抛出NoSuchElementException异常 |
List getOptions() | 获得下拉框的所有项,单选多选模式均有效,当下拉框没有任何项时,返回空列表,不会抛出异常 |
boolean isMultiple() | 判断下拉框是否多选模式 |
void selectByIndex(int inde() | 选中指定index的项,单选多选均有效,当index超出范围时,抛出NoSuchElementException异常 |
void selectByValue(String valu() | 选中所有Select标签中value为指定值的所有项,单选多选均有效,当没有适合的项时,抛出NoSuchElementException异常 |
void selectByVisibleText(String text) | 选中所有项的文字为指定值的项,与deselectByValue相反,但单选多选模式均有效,当没有适合的项时,抛出NoSuchElementException异常 |
日期控件操作
页面中出现时间控件选择时,一般分为两种:
- 不要求手动输入
- 要求手动输入
无论使用哪种方式进行时间的赋值,输入时间的格式都必须符合系统的要求。
不要求手动输入
控件没有限制手动填写的,直接使用 sendKeys() 方法进行赋值即可。
driver.findElement(By).sendKeys("符合系统的要求的时间格式");
要求手动输入
控件限制了手动输入,只能通过点击控件时间进行输入的,则使用 JavaScript 进行操作。
(JavaScriptExecutor)driver.executeScript("document.getElementById('元素id').value='符合系统的要求的时间格式';")
模拟鼠标和键盘操作
模拟鼠标
在 WebDriver 中,鼠标的操作通过 Actions 类进行模拟,包括鼠标右击、双击、悬停、拖动等操作。
Actions 类常用方法:
方法 | 描述 |
---|---|
contextClick() | 鼠标右击 |
click() | 鼠标单击(左击) |
clickAndHold(WebElement) | 点击并控制(模拟悬停) |
doubleClick(WebElement) | 鼠标双击 |
dragAndDrop(webElement1,webElement2) | 鼠标拖动 |
moveToElement(WebElement) | 鼠标移动到某个元素上 |
release() | 释放鼠标 |
perform() | 执行所有Actions中存储的行为 |
所有的鼠标操作最终都需要调用 perform() 方法,即只有 perform() 方法被调用,Actions 中存储的鼠标行为才会被执行。
模拟键盘
selenium 提供了 Key 类(枚举),用于模拟键盘上的各种按键。
通过以下方法从键盘输入:
//输入文本 sendKeys("selenium"); //输入单个按键 sendKeys(Keys.ENTER); sendKeys("a"); //输入组合按键(两种方式) sendKeys(Keys.BACK_SPACE, "c"); sendKeys(Keys.chord(Keys.CONTROL,"v"));
截图
补充记录截图操作,截图功能不是 selenium 的功能之一,但是实际工作中会经常使用。
截图需要导入 apache.commons.io 包,依赖如下:
<!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency>
截图示例:
private void printscreen() { // 设置截图保存路径 String filePath = "路径"; // 截取当前屏幕,并保存为图片 File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); // 将截图保存到指定路径 try { FileUtils.copyFile(screenshot, new File(filePath)); } catch (IOException e) { e.printStackTrace(); } }