`

Selenium2 WebDriver入门

 
阅读更多

1 简介

资源

jar包:http://code.google.com/p/selenium/downloads/list

官方 UserGuide:http://seleniumhq.org/docs/

2 基本配置

2.1 Firefox

对于不同的浏览器,需要创建不同类型的WebDriver进行测试,默认情况下我们通常可以直接 new XXXDriver() 来创建对应类型的 WebDriver。

如果使用Firefox测试,而Firefox又没有安装在默认目录下,那么直接 new FirefoxDriver()将会出现异常提示找不到浏览器。这时,我们需要在程序开始调用以下代码,用以指定Firefox的位置:

System.setProperty(“webdriver.firefox.bin”, “***\\firefox.exe”)

或者我们使用 FirefoxBinary 实例来指定浏览器的位置:

File firefox = new File(“…\\firefox.exe”);

FirefoxBinary firefoxbin = new FirefoxBinary(firefox);

WebDriver driver = new FirefoxDriver(firefoxbin, null);

值得注意的是,使用以上两种配置启动的Firefox浏览器是“全新”的,也就是说浏览器的设置都是初始的,包括插件集。这会使依赖 Firebug 等插件的开发调试工作无法进行,于是我们需要保留浏览器的配置信息。

这需要使用FirefoxProfile 实例来指定配置文件的位置:

String path = System.getProperty( "user.home" )

+ "\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\";

File prodir = new File( path );

File[] files = prodir.listFiles( new FilenameFilter()

{

@Override

public boolean accept( File dir, String name )

{

return name.endsWith( ".default" );

}

} );

FirefoxProfile profile = new FirefoxProfile( files[0] );

综上而言,我们通常会使用 FirefoxDriver(FirefoxBinarybinary, FirefoxProfile profile) 形式的构造器。

 

2.2 Chrome

与Firefox类似,如果测试程序找不到Chrome的安装位置(非默认位置),那么可以这样指定:

System.setProperty(“webdriver.chrome.driver”, “***\\chrome.exe”)

但是,使用Chrome测试,比较特别的是,需要驱动程序:

http://chromedriver.storage.googleapis.com/index.html

通常,我们使用 ChromeDriver(ChromeDriverServiceservice, ChromeOptions options) 形式的构造器,前一参数可指定驱动程序的位置,后一参数可指定浏览器的位置。

ChromeDriverService 实例的创建如下:

String chromeDriver = "…\\chromedriver.exe";

ChromeDriverService service = new ChromeDriverService.Builder().

usingDriverExecutable( new File(chromeDriver) ).build();

ChromeOptions 实例的创建如下:

String chrome = "…\\chrome.exe";

ChromeOptions options = new ChromeOptions();

options.setBinary( chrome );

 

3 基本使用

3.1 打开浏览器

开始测试前,总是应该创建一个WebDriver接口实现类实例,以打开某种浏览器。

// 创建Firefox driver实例,打开Firefox

WebDriver driver = new FirefoxDriver();

// 创建IE driver实例,打开IE

WebDriver driver = new InternetExplorerDriver();

3.2 打开测试页面

打开浏览器后,应该导航到测试页面进行测试。

driver.get( "http://www.baidu.com" )

另一种可选方式是:

driver.navigate().to( "http://www.baidu.com" );

3.3 查找元素

导航到测试页面后,就应该要查找页面元素进行操作了。

由于Selenium2推崇面向接口编程,所以所有元素都使用WebElement接口代表。

定位元素位置可以在WebDriver实例上进行,也可以在某个WebElement上进行。它们都暴露了findElement()和findElements()方法,前者查找返回一个WebElement对象否则抛出异常;后者查找返回一个WebElement列表,如果没有匹配项列表可能为空。

两种find方法都使用By类实例进行定位。By是一个抽象类,所以实际使用的应是它的派生子类,每种派生子类都代表一种查找策略。通常我们不直接调用其派生子类的构造器创建对象,而是使用By类的静态工厂方法来创建。

下面逐一说明各种定位方式。

3.3.1By ID

通过ID查找。这是最高效也最常用的定位方式。但是,可能存在的陷阱是:网页中ID并非唯一或者ID是自动生成的。使用中应该避免这些情况。

WebElement element = driver.findElement(By.id("coolestWidgetEvah"));

3.3.2By Name

通过name查找。

WebElement cheese = driver.findElement(By.name("cheese"));

3.3.3By XPath

通过XPath查找。WebDriver试图在任何地方使用浏览器原生XPath能力,但是对于原生不支持XPath的浏览器,将提供实现。这可能导致一些非预期的行为,除非你清楚不同XPath引擎间的差异。

Driver

Tag and Attribute Name

Attribute Values

Native XPath Support

HtmlUnit Driver

Lower-cased

As they appear in the HTML

Yes

Internet Explorer Driver

Lower-cased

As they appear in the HTML

No

Firefox Driver

Case insensitive

As they appear in the HTML

Yes

比如如下页面:

<input type="text" name="example" />

<INPUT type="text" name="other" />

查找语句为:

List<WebElement> inputs = driver.findElements(By.xpath("//input"));

匹配结果为:

XPath expression

HtmlUnit Driver

Firefox Driver

Internet Explorer Driver

//input

1 (“example”)

2

2

//INPUT

0

2

0

有时元素不必声明某些有默认值的属性,比如input元素的type属性可以缺省,缺省值为text。但是在WebDriver中使用XPath时,你不能期望能够匹配未声明的默认属性。

3.3.4By Class Name

通过class属性查找。实际使用中相同的class属性一般对应多个元素,所以一般会查找到多个元素,然后取用第一个元素。

List<WebElement> cheeses = driver.findElements(By.className("cheese"));

3.3.5By Link Text

通过超链接文本查找超链接。

WebElement cheese = driver.findElement(By.linkText("cheese"));

3.3.6By Partial Link Text

通过部分超链接文本查找超链接。

WebElement cheese = driver.findElement(By.partialLinkText("cheese"));

3.3.7By Css Selector

通过Css Selector查找。如果浏览器默认原生支持css查询,可参阅w3c css selectors;否则 Sizzle被使用。IE6,7和FF3.0都使用Sizzle作为css查询引擎。

注意并非所有的浏览器都是等效的,有的css在一个中起作用也许在另一个中不会。

WebElement cheese = driver.findElement(By.cssSelector("#food span.dairy.aged"));

3.3.8By TagName

通过元素标签名查找。

WebElement frame = driver.findElement(By.tagName("iframe"));

3.4 界面操作

找到页面元素后,需要操作元素,通常WebElement接口方法就足以操作大多数元素了。

3.4.1通用操作

 

// 点击

element.click();

// 文本框输入

element.sendKeys(“*****”);

// 文本框清空

element.clear();

// 是否选中,单/多选等

element.isSelected();

// 是否可用

element.isEnabled();

3.4.2文件域

file.sendKeys(filePath);

3.4.3下拉列表

对于下拉列表这种较复杂的元素,使用通用的方法来操作将不是那么高效的。我们可以将其封装为Select对象,这将提供更多有用的方法便于操作。

Select select = new Select(driver.findElement(By.tagName("select")));

select.selectByVisibleText(“***”);

select.deselectByVisibleText(“***”);

select.selectByValue(“***”);

select.deselectByValue(“***”);

select.deselectAll();

select.getAllSelectedOptions();

select.getFirstSelectedOption();

3.4.4表单

一旦填写完表单,我们就期望提交它。一个提交的方法是找到“提交”按钮并点击它。

driver.findElement(By.id("submit")).click();

另外,WebDriver为每个元素都提供了一个方便的submit()方法。如果你调用一个处于表单中的元素的submit()方法,WebDriver将沿DOM向上查找直到找到表单然后提交。如果元素不在表单中,则会抛出NoSuchElementException异常。

// 表单提交

element.submit();

3.4.5Actions

// 拖拽元素到目标元素中

new Actions( driver ).dragAndDrop( element, target ).perform();

// hover

new Actions(driver).moveToElement( text ).perform();

3.4.6对话框

我们可以获取到各种弹出对话框的对象,并可以执行accept、dismiss、读取内容或者向prompt中输入内容等操作。

Alert alert = driver.switchTo().alert();

alert.accept();

alert.dismiss();

alert.getText();

alert. sendKeys();

3.4.7Windows和Frames切换

有的Web应用是多框架或多窗口的。

WebDriver支持在命名窗口间切换:

driver.switchTo().window("windowName");

怎样知道窗口的名字呢?查看一下打开它的JS或超链接:

<a href="somewhere.html" target="windowName">Click here to open a new window</a>

另外,也可以使用窗口句柄,这可能需要迭代所有窗口句柄来获取某个窗口的句柄了:

for (String handle : driver.getWindowHandles()) {

driver.switchTo().window(handle);

}

在框架间切换也是类似的:

driver.switchTo().frame("frameName");

3.4.8导航

driver.navigate().forward();

driver.navigate().back();

 

4 非界面操作

4.1 Cookie

driver.manage().addCookie(cookie);

driver.manage().getCookies();

driver.manage().getCookieNamed(“cookieName”);

driver.manage().deleteCookieNamed(“cookieName”);

driver.manage().deleteCookie(cookie);

driver.manage().deleteAllCookies();

4.2 执行JS

可以执行任意JS脚本来查找一个元素,并且只要返回一个DOM元素,它将被自动转换为WebElement对象。

WebElement element = (WebElement) ((JavascriptExecutor)driver).executeScript("return $('.cheese')[0]");

 

4.3 截图

测试过程中,可以把页面截图,保存成为图片。

需要注意,截取的图片存在临时目录,所以需要将其拷贝到指定的目录,否则测试完成可就找不到截图了。

File screenshotFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);

FileUtils.copyFile( screenshotFile, new File("E:\\1.png") );

或远程截图

WebDriver augmentedDriver = new Augmenter().augment(getDriver());

File screenshotFile = ((TakesScreenshot)augmentedDriver).getScreenshotAs(OutputType.FILE);

 

4.4 等待

当页面需要一段时间才能加载完成,那么就需要等待完成后才进行查找和操作。

等待有2种:显性等待和隐性等待。

显性等待使用WebDriverWait类和ExpectedCondition接口完成,编码实现ExpectedCondition接口用以判断某种条件,然后等待这种条件达成或超时。

WebElement myDynamicElement = (new WebDriverWait(driver, 10))

.until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));

ExpectedConditions类提供了许多静态工厂方法,返回常用的ExpectedCondition对象。

隐性等待更为简洁:

driver.manage().timeouts().implicitlyWait( 10, TimeUnit.SECONDS );

但是隐性等待的设置将影响后续全局的查找操作。

4.5 改变User Agent

FirefoxProfile profile = new FirefoxProfile();

profile.addAdditionalPreference("general.useragent.override", "some UA string");

WebDriver driver = new FirefoxDriver(profile);

 

5 附录

5.1 注意

5.1.1关于click()

当调用WebElement.click()时,如果被操作元素是不可用的(disabled),click()方法调用仍会是正常的,不会有异常。

所以,如果会出现被点击的元素是不可用的情况,而点击不可用元素又被认为是非法的,那么应该在click()调用前使用isEnable()方法检查元素可用性。

5.1.2driver.close() vs.driver.quit()

在测试结束后通常需要关闭浏览器,这个操作通常使用close()或quit()方法完成。但是两者是有区别的,其方法说明也体现了这一点。

close()

Close the current window, quitting the browser if it's the last window currently open.

quit()

Quits this driver, closing every associated window.

对于close()而言,如果当前窗口是最后一个打开窗口,那么关闭当前窗口退出浏览器;quit()则关闭每个关联的窗口退出浏览器。

但是,实际使用中close()方法的行为同说明有一些出入。以firefox为例,当当前窗口为最后一个打开窗口时,close()方法不会将最后一个窗口关闭,当然也不会使firefox退出。

5.2 常用API

5.2.1Sleeper

原生休眠类

org.openqa.selenium.browserlaunchers.Sleeper

public static void sleepTightInSeconds(longtimeoutInSeconds)

public static void sleepTight(long timeout)

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics