7.1 常见定位对象元素的方法
常见定位对象元素的方法
在使用selenium webdriver进行元素定位时,通常使用findElement或findElements方法结合By类返回的元素句柄来定位元素。其中By类的常用定位方式共八种,现分别介绍如下:
By.id()
id页面元素的id一般是唯一的,使用id定位效率较高,并且定位精确
使用方法如下:
public class SearchButtonById {
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get("http://www.forexample.com");
WebElement searchBox = driver.findElement(By.id("gbqfba"));
searchBox.click();
}
}
常见定位对象元素的方法
By.name()
使用元素的name 和元素的id定位的益处类似
使用方法如下:
public class SearchButtonByName {
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get("http://www.forexample.com");
WebElement searchBox = driver.findElement(By.name("btnK"));
searchBox.click();
}
}
元素没有id或者name,怎么办?建议和相关开发人员沟通增加id或者name,或者使用下列方法:
By.xpath()
这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素。在正式开始使用XPath进行定位前,我们先了解下什么是XPath。XPath是XML Path的简称,由于HTML文档本身就是一个标准的XML页面,所以我们可以使用XPath的语法来定位页面元素。
使用方法如下:
driver.findElement(By.xpath(“//a[contains(@href, ‘logout’)]”));
By.cssSelector()
cssSelector这种元素定位方式跟xpath比较类似,但执行速度较快,而且各种浏览器对它的支持都相当到位,所以功能也是蛮强大的。
使用方法如下:
WebElement password = driver.findElement(By.cssSelector("#J_login_form>dl>dt>input[id=’ J_password’]"));
By.tagName()
该方法可以通过元素的标签名称来查找元素。该方法跟之前两个方法的区别是,这个方法搜索到的元素通常不止一个,所以一般建议结合使用findElements方法来使用。比如我们现在要查找页面上有多少个button,就可以用button这个tagName来进行查找。
使用方法如下:
List<WebElement> buttons = driver.findElements(By.tagName("button"));
By.className()
className属性是利用元素的css样式表所引用的伪类名称来进行元素查找的方法。对于任何HTML页面的元素来说,一般程序员或页面设计师会给元素直接赋予一个样式属性或者利用css文件里的伪类来定义元素样式,使元素在页面上显示时能够更加美观。如果此时我们要通过className属性来查找该button并操作它的话,就可以使用className属性了。
使用方法如下:
WebElement searchBox = driver.findElement(By.className("buttonStyle"));
By.linkText()
这个方法比较直接,即通过超文本链接上的文字信息来定位元素,这种方式一般专门用于定位页面上的超文本链接。
<a href="/intl/en/about.html">About Google</a>
使用方法如下:
WebElement aboutLink = driver.findElement(By.linkText("About Google"));
By.partialLinkText()
这个方法是上一个方法的扩展。当你不能准确知道超链接上的文本信息或者只想通过一些关键字进行匹配时,可以使用这个方法来通过部分链接文字进行匹配。
使用方法如下:
WebElement aboutLink = driver.findElement(By.partialLinkText("About"));
7.2 切换窗口、Frame和其他对象识别方法
在web应用中,常常会遇见点击某个链接会弹出一个新的窗口,或者是相互关联的web应用 ,要去操作新窗口中的元素,就需要主机切换到新窗口进行操作,不然会在之前的窗口找元素,这样会导致找不到元素或者脚本报错,WebDriver 提供了switchTo().window()方法可以实现在不同的窗口之间切换。
主要用到如下方法:
getWindowHandle():获得当前窗口句柄
getWindowHandles():返回的所有窗口的句柄到当前会话
switchTo().window():用于切换到相应的窗口
switchTo().frame()默认的是取表单的ID和name属性。如果没有id和name ,可通过Xpath路径定位。
对表单操作完成之后可以通过driver.switchTo().defaultContent() 跳出表单。
例如:在web应用中,前台网页的设计一般会用到iframe/frame表单嵌套页面的应用。简单的就是一个页面签嵌套多个HEML/JSP文件。selenium webdriver 只能在同一页面识别定位元素,可以理解成只能识别当前所在位置的页面上的元素。对于不同的iframe/frame表单中的元素是无法直接定位的。需要结合switchTo().frame()方法切换到指定的frame/iframe中。
在web应用中,页面有时会弹出Alert弹出框,让用户确认信息,处理这种情况,也需要switchTo弹窗,然后操作。
点击ok
driver.switchTo().alert().accept();
点击Cancel
driver.switchTo().alert().dismiss();
Selenium实现拖拽功能
1. 找到要拖拽的页面元素-源(source)。
2. 找到要释放的页面元素-目标(target), 页面显示的这个元素可能是个坑, 但是在页面代码中他就是一个元素。
3. 借助(new Actions(driver)).DragAnddrop( source, target).perform(), 完成元素拖放操作。
Selenium实现拖拽功能
public static Boolean dragAndDrop(WebDriver driver, By source, By target){
try{
Actions action = new Actions(driver);
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement elementSource = wait.until(ExpectedConditions.presenceOfElementLocated(source));
WebElement elementTarget = wait.until(ExpectedConditions.presenceOfElementLocated(target));
action.dragAndDrop(elementSource, elementTarget).perform();
Sleeper.sleepTight(5);
return true;
}
catch(Exception e)
{
System.out.println(e.getClass().getName() + " " + e.getMessage());
return false;
}
}
Selenium实现上传文件功能
普通上传:普通的附件上传是将本地文件的路径作为一个值放在input 标签中,通过form 表单将这个值提交给服务器。可以通过sendKeys("文件路径")直接上传。
插件上传:一般是指基于Flash、JavaScript 或Ajax 等技术所实现的上传功能。
插件上传,可以使用AutoIt 实现上传 编写脚本 来实现。AutoIt 的安装以及使用需要参考AutoIt 使用手册等相关文档。selenium 通过AutoIt 来操作window窗口的操作实质是通过java代码来调用AutoIt 生成的脚本.exe文件。
通过Java调用的exe 程序并不在Java 的可控范围内。换句话说,exe 执行多长时间,执行是否出错,Java 程序都无法得知。
以下是在AutoIt 编辑器中编辑的操作文件上传窗口的代码:
ControlFocus("打开","","Edit1”);
识别windows窗口
WinWait("[CLASS:#32770]","",10);
窗口等待十秒
ControlSetText("打开", "", "Edit1", "C:UsershappyDesktopFileUpload.html”);
想输入框中输入需要上传的地址
Sleep(2000)
ControlClick("打开", "","Button1");
点击[打开】按钮
以下是java实现的代码。
File file = new File("C:\Users\happy\Desktop\FileUpload.html");
// 用java来实现文件读取功
driver.get(file.getAbsolutePath());
driver.findElement(By.name("uploadFile")).click();
// 点击选择文件按钮
Thread.sleep(3000);
// 设置等待3秒
Runtime exe = Runtime.getRuntime();
// Java 的Runtime 模块的getruntime.exec()方法可以调用exe 程序并执行。
try {
String str = "E://upload.exe";
exe.exec(str);
// 运行指定位置的.exe文件
} catch (IOException e) {
System.out.println("Error to run the exe");
e.printStackTrace();
}
Selenium实现鼠标、键盘功能
get()
driver.get("http://www.baidu.com")
打开一个网页
sendKeys()
driver.findElement(By.id("pwdInput")).sendKeys("password");
模拟键盘输入动作
-clear()
driver.findElement(By.id("pwdInput")).clear();
清除文本输入框中的内容
-click()
driver.findElement(By.id("loginBtn")).click();
鼠标点击事件
-contextClick()
Actions action = new Actions(driver); action.contextClick(driver.findElement(By.id("su"))).perform();
鼠标右键点击指定的元素
-clickAndHold()
Actions action = new Actions(driver); action.clickAndHold(driver.findElement(By.linkText("设置"))).perform();
鼠标悬停
-moveToElement()
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(By.linkText("设置"))).perform();
鼠标移动
-doubleClick()
Actions action = new Actions(driver); action.doubleClick(driver.findElement(By.name("element"))).perform();
鼠标双击
Selenium对浏览器的操作
-driver.manage().window().maximize();
窗口最大化
-driver.forward()/driver.back()
前进/后退
-driver.window_handles
返回当前浏览器的所有窗口
-driver.quit()/driver.close()
关闭浏览器
Selenium实现时间等待
隐性等待
显式等待
implicitlyWait:
识别对象时的超时时间。过了这个时间如果对象还没找到的话就会抛出NoSuchElement 异常
setScriptTimeout:
异步脚本的超时时间。webdriver可以异步执行脚本,这个是设置异步执行脚本脚本 返回结果的超时时间
pageLoadTimeout:
页面加载时的超时时间。因为webdriver会等页面加载完毕在进行后面的操作,所以如果页面在这个超时时间内没有加载完成,那么 webdriver 就会抛出异常。
//页面加载超时时间设置为 5s:
driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS); driver.get("http://www.baidu.com/");
//定位对象时给 10s 的时间, 如果 10s 内还定位不到则抛出异常: driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.findElement(By.id("kw33")).sendKeys("selenium");
//异步脚本的超时时间设置成 3s
driver.manage().timeouts().setScriptTimeout(3, TimeUnit.SECONDS);
sleep 休眠方法:
当执行到 sleep()方法时会固定的休眠所设置的时长(这里以毫秒为单位);然后再继续执行。
driver.get("http://www.baidu.com/");
Thread.sleep(2000);
Selenium处理Windows事件
Selenium 处理安全对话框 (windows security dialog)用安装使用autoit 来代替
public void autoitHandleWin(String title,String userName,String pwd){
AutoItX x=new AutoItX();
if(x.winWaitActive(title,"",20)){
if(x.winExists(title)){
x.sleep(500);
x.ControlSetText(title,"",Edit1,userName);
x.ControlSetText(title,"",Edit1,pwd);
x.ControlClick(title,"",Button);
}
}
}
7.3 如何处理网页出现异常的情况
如何处理网页出现异常的情况?
1.捕获异常,将异常写入log日志
2.截图记录当时网页
3.加入重试机制