1.检查元素的文本
当测试一个网页应用的时候,我们需要验证元素显示的是否正确。Selenium WebDriver
API 提供了多种方法来得到和验证文本。有时候,我们需要先将元素的实时的文本值保存下
来以便测试后面的某些地点使用。
在此秘籍中,我们要使用 WebElement 类中的 getText()方法来获得和验证元素文本。
如何实现:
这里,我们创建了一个测试,先定位元素再将它的文本保存到一个字符串变量中。我们将验
证字符串的内容是否正确。
@Test
public void testElementText()
{
//取得元素
WebElement message = driver.findElement(By.id("message"));
//得到元素文本
String messageText = message.getText();
//验证文本为"Click on me and my color will change"
assertEquals("Click on me and my color will change", messageText);
//获得 area 元素
WebElement area = driver.findElement(By.id("area"));
//验证文本为"Div's Text\nSpan's Text"
assertEquals("Div's Text\nSpan's Text",area.getText());
}
WebElement 中的 getText()方法返回元素的 innerText 属性。所以元素里面如果有子
节点一样也会被返回出来
我们也可以使用 Java String API 方法如 contains(),startsWith(),endsWith()
来迕行部分匹配。方法如下:
assertTrue(messageText.contains("color"));
assertTrue(messageText.startsWith("Click on"));
assertTrue(messageText.endsWith("will change"));
2.检查元素的属性值
开发人员通过配置各种元素属性来控制元素行为或样式。例如,<input>元素可以被设置
为 readonly 属性。
我们需要创建一个测试来验证元素属性是正确的。我们可以使用 WebElement 类的
getAttribute()方法来获得元素的属性。
如何实现:
创建一个测试,定位元素再检查它的属性,方法如下:
@Test
public void testElementAttribute()
{
WebElement message = driver.findElement(By.id("message"));
assertEquals("justify",message.getAttribute("align"));
}
此例子中我们验证了元素的属性 align 的值是否为 justify。
3.检查元素的 CSS 属性值
不同的样式应用在页面的元素上,让网页变得更加丰富和美丽。开发人员使用 CSS 来增加
这些样式。测试人员就需要验证那些样式是否正确的应用到元素上面。这可以通过
WebElement 类中的 getCSSValue()方法实现,方法将返回指定样式属性的值。
如何实现:
让我们创建一个测试,读取元素的 CSS 的 width 属性并验证它的值。
@Test
public void testElementStyle()
{
WebElement message = driver.findElement(By.id("message"));
String width = message.getCssValue("width");
assertEquals("150px",width);
}
4. 针对鼠标和键盘事件使用高级的用户交互 API
Selenium WebDriver 高级用户交互 API 允许我们通过使用 Actions类执行从键盘事件到
简单或复杂的鼠标事件,如拖拽操作,按住一个按键然后执行鼠标操作,创建一个复杂的事
件链就像用户真正的在手动操作一样。
在此秘籍中,我们将使用 Actions 类来创建一个事件链来选择表格中的一行。
如何实现:
我们创建一个测试使用 Ctrl 按键来选择表格的多个行。我们可以先选择第一行,然后按住
ctrl 键,再选择另一行后释放 ctrl 键。这样就可以选择所需要的行。
@Test
public void testRowSelectionUsingControlKey() {
List<WebElement> tableRows = driver.findElements
(By.xpath("//table[@class='iceDatTbl']/tbody/tr"));
//Select second and fourth row from table using Control Key.
//Row Index start at 0
Actions builder = new Actions(driver);
builder.click(tableRows.get(1))
.keyDown(Keys.CONTROL)
.click(tableRows.get(3))
.keyUp(Keys.CONTROL)
.build().perform();
//Verify Selected Row table shows two rows selected
List<WebElement> rows = driver.findElements
(By.xpath("//div[@class='icePnlGrp
exampleBox']/table[@class='iceDatTbl']/tbody/tr"));
assertEquals(2,rows.size());
}
首先创建一个 Actions 的实例,再调用相应的事件方法,然后调用 build()方法,建立
这么一组操作方法链,最后调用 perform()来执行。Actions 不能在隐藏的元素上进行
操作,所以如果要使用,确保元素是可见的。
(想吐槽一下这个例子,仅仅是一个方法,也没有实例看看,况且一般人选表格行不会用
ctrl+点击,貌似返样也选不中啊。)
5.在元素上执行双击操作
在网页应用中,有可能出现要对某一元素进行双击才能触发其相应的事件。比如,在某一个
表格中双击启动一个新的窗口。在高级用户交互中提供了来执行双击操作的 API。
在此秘籍中我们将使用 Actions 类来执行双击操作。
如何实现:
package com.example.tests;
import static org.junit.Assert.*;
import org.junit.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
public class Selenium2 {
WebDriver driver = new FirefoxDriver();
@Test
public void actionsTest() {
driver.get("D:\\demo\\DoubleClickDemo.html");
WebElement message = driver.findElement(By.id("message"));
// 验证初始字体为14px
assertEquals("14px", message.getCssValue("font-size"));
Actions builder = new Actions(driver);
builder.doubleClick(message).build().perform();
// 验证点击后字体变为20px
assertEquals("20px", message.getCssValue("font-size"));
driver.close();
}
}
当鼠标双击的时候触发了字体变化的事件,我们可以使用 doubleClick()来模拟真实的双
击动作,并验证了字体属性说明确实有效了.
6.执行拖拽操作
Selenium WebDriver在 Actions 类中也实现了 Selenium RC 里的 dragandDrop 命令。
我们之前看到了 Actions 类支持高级的用户交互操作,如鼠标和键盘的事件。通过这个类
我们可以建立一系列的动作链。
package com.example.tests;
import static org.junit.Assert.*;
import org.junit.*;
import org.openqa.selenium.*;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.interactions.Actions;
public class Selenium2 {
@Test
public void testDragDrop() {
WebDriver driver = new InternetExplorerDriver();
driver.get("D:\\demo\\DragAndDrop.html");
WebElement source = driver.findElement(By.id("draggable"));
WebElement target = driver.findElement(By.id("droppable"));
Actions builder = new Actions(driver);
builder.dragAndDrop(source, target).perform();
try {
assertEquals("Dropped!", target.getText());
} catch (Error e) {
e.printStackTrace();
}finally{
driver.close();
}
}
}
拖拽一个元素到另一个元素再放下,我们需要先定位这些元素(原元素,目标元素)然后作为参
数传给 dragAndDrop()。
7. 执行 JavaScript 代码
Selenium WebDriver API 提供了执行 JavaScript 代码的能力。当测试需要使用 JavaScript
进行交互的时候,这将会非常的有用。利用这个 API,客户端的 JavaScript 代码可以通过
Selenium WebDriver 来执行。Selenium WebDriver 提供了 JavascriptExecutor 接
口,可以任意执行 JavaScript 代码。
在这个秘籍中,我们将探索如何使用 JavascriptExecutor 来执行 JavaScript 代码。本
书还有一些其它的秘籍也使用了 JavascriptExecutor 来执行一些高级的 Selenium
WebDriver 目前并支持的操作
如何实现:
让我们建立了一个测试调用 JavaScript 代码来返回网页的 title 并统计超链接的数量。
这可以通过调用 driver.getTile()方法。
package com.example.tests;
import static org.junit.Assert.*;
import org.junit.*;
import org.openqa.selenium.*;
import org.openqa.selenium.ie.InternetExplorerDriver;
public class Selenium2 {
@Test
public void testJavaScriptCalls() {
WebDriver driver = new InternetExplorerDriver();
driver.get("http://www.baidu.com");
JavascriptExecutor js = (JavascriptExecutor) driver;
String title = (String) js.executeScript("return document.title");
assertEquals("百度一下,你就知道", title);
long links = (Long) js.executeScript("var links = "
+ "document.getElementsByTagName('A'); "
+ "return links.length");
assertEquals(26, links);
driver.close();
}
}
从 javaScript 代码中返回数据,我们需要使用 return 关键字。基于返回值的类型,我们需要
对 executeScript()方法进行转型。对于带小数点的值,使用 Double 类型,非小数值可以
使用 Long 类型,布尔值可以使用 Boolean 类型,如果返回到是 HTML 节点,可以使用
WebElement 类型,文本值,可以使用 String 类型。如果返回到是对象列表,基于对象类型
的任何值都可以。
8. 使用 Selenium WebDriver 进行截图
Selenium WebDriver 提供了 TakesScreenshot 接口来捕捉网页的截屏。这可以在测试执行
遇到异常或错误的时候将屏幕截取下来,可以知道当时发生了什么。我们也可以在验证元素状态,
显示的值或是某个操作完成后的状态进行截屏。
截屏也可以帮助我们验证布局,字段对齐,图片的对比。
如何实现:
让我们创建一个测试,打开一个页面应用进行截屏并保存 PNG 格式。
package com.example.tests;
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.junit.*;
import org.openqa.selenium.*;
import org.openqa.selenium.ie.InternetExplorerDriver;
public class Selenium2 {
@Test
public void testTakesScreenshot() {
WebDriver driver = new InternetExplorerDriver();
driver.get("http://www.baidu.com");
try {
File srcFile=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile
(srcFile,new File("d:\\screenshot.png"));
} catch (Exception e) {
e.printStackTrace();
}
driver.close();
}
}
TakesScreenshot 接口提供了 getScreenshotAs()方法来捕捉屏幕。上面的例子中,
我们指定了 OutputType.FILE 作为参数传递给 getScreenshoAs()方法,告诉它将截取的
屏幕以文件形式返回。
使 用 org.apache.commons.io.FileUtils 类 中 的 copyFile() 方 法 来 保 存
getScreenshot()返回的文件对象。TakesScreenshot 接口依赖于浏览器中的 API 来
捕捉屏幕。所以在 HtmlUnit Driver 中不支持这样使用。
OutputType 类提供了多种数据类型,在前面的例子中我们使用了文件类型,它也可以保
存为 Base64 编码的字符串,代码如下
String base64 =((TakesScreenshot)driver).getScreenshotAs(OutputType.BASE64);