selenium 2.0 part 2

1.9  拖拉(Drag andDrop)

1 WebElement element =driver.findElement(By.name("source"));
2 WebElement target = driver.findElement(By.name("target"));
3 (new Actions(driver)).dragAndDrop(element, target).perform();

1.10   导航 (Navigationand History)

打开一个新的页面:

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

通过历史导航返回原页面:

1  driver.navigate().forward();
2  driver.navigate().back();

 

2   高级使用

2.1.1 改变user agent

User Agent的设置是平时使用得比较多的操作:

1 FirefoxProfile profile = new FirefoxProfile();
2 profile.addAdditionalPreference("general.useragent.override","some UA string");
3 WebDriver driver = new FirefoxDriver(profile);

2.1.2 读取Cookies

 1 //增加cookie:
 2 // Now set the cookie. This one's valid for the entire domain
 3 Cookie cookie = new Cookie("key", "value");
 4 driver.manage().addCookie(cookie);
 5 //获取cookie的值:
 6 
 7 // And now output all the available cookies for the current URL
 8 
 9 Set<Cookie> allCookies = driver.manage().getCookies();
10 for (Cookie loadedCookie : allCookies) {
11    System.out.println(String.format("%s -> %s",loadedCookie.getName(), loadedCookie.getValue()));
12 }
13 
14 //根据某个cookie的name获取cookie的值:
15 driver.manage().getCookieNamed("mmsid");
16 //删除cookie:
17 // You can delete cookies in 3 ways
18 // By name
19 driver.manage().deleteCookieNamed("CookieName");
20 // By Cookie
21 driver.manage().deleteCookie(loadedCookie);
22 // Or all of them
23 driver.manage().deleteAllCookies();

2.1.3 Webdriver截图

如果用webdriver截图是:

1 driver = webdriver.Firefox()
2 driver.save_screenshot("C:\error.jpg")

3.3.5 页面等待

因为Load页面需要一段时间,如果页面还没加载完就查找元素,必然是查找不到的。最好的方式,就是设置一个默认等待时间,在查找页面元素的时候如果找不到就等待一段时间再找,直到超时。

Webdriver提供两种方法,一种是显性等待,另一种是隐性等待。

//显性等待:
WebDriver driver =new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebElementmyDynamicElement = (new WebDriverWait(driver, 10))
  .until(newExpectedCondition<WebElement>(){
  @Override
  public WebElementapply(WebDriver d) {
    returnd.findElement(By.id("myDynamicElement"));
  }});

 

//隐性等待:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement =driver.findElement(By.id("myDynamicElement"));

 

3    RemoteWebDriver

当本机上没有浏览器,需要远程调用浏览器进行自动化测试时,需要用到RemoteWebDirver.

3.1   使用RemoteWebDriver

 1 import java.io.File;
 2 import java.net.URL;
 3 import org.openqa.selenium.OutputType;
 4 import org.openqa.selenium.TakesScreenshot;
 5 import org.openqa.selenium.WebDriver;
 6 import org.openqa.selenium.remote.Augmenter;
 7 import org.openqa.selenium.remote.DesiredCapabilities;
 8 import org.openqa.selenium.remote.RemoteWebDriver;
 9 public class Testing {
10     public void myTest()throws Exception {
11         WebDriver driver = newRemoteWebDriver(
12                                new URL("http://localhost:4446/wd/hub"),
13                                DesiredCapabilities.firefox());
14        driver.get("http://www.google.com");
15         // RemoteWebDriverdoes not implement the TakesScreenshot class
16         // if the driver doeshave the Capabilities to take a screenshot
17         // then Augmenter willadd the TakesScreenshot methods to the instance
18         WebDriveraugmentedDriver = new Augmenter().augment(driver);
19         File screenshot =((TakesScreenshot)augmentedDriver).
20                             getScreenshotAs(OutputType.FILE);
21     }
22 }

 

 

3.2   SeleniumServer

在使用RemoteDriver时,必须在远程服务器启动一个SeleniumServer:

java -jar selenium-server-standalone-2.20.0.jar -port 4446

3.3   How to setFirefox profile using RemoteWebDriver

1 profile = new FirefoxProfile();  profile.setPreference("general.useragent.override",testData.getUserAgent()); 
2 capabilities = DesiredCapabilities.firefox();
3 capabilities.setCapability("firefox_profile", profile);
4 driver = new RemoteWebDriver(new URL(“http://localhost:4446/wd/hub”),capabilities);
5 driverWait = new WebDriverWait(driver,TestConstant.WAIT_ELEMENT_TO_LOAD);
6 driver.get("http://www.google.com");

4   封装与重用

WebDriver对页面的操作,需要找到一个WebElement,然后再对其进行操作,比较繁琐:

 // Find the text inputelement by its name

WebElement element = driver.findElement(By.name("q"));

 

// Enter something to search for

element.sendKeys("Cheese!");

我们可以考虑对这些基本的操作进行一个封装,简化操作。比如,封装代码:

    protected void sendKeys(Byby, String value){

       driver.findElement(by).sendKeys(value);

    }

那么,在测试用例可以这样简化调用:

sendKeys(By.name("q"),”Cheese!”);

看,这就简洁多了。

类似的封装还有:

 1 package com.drutt.mm.end2end.actions;
 2 import java.util.List;
 3 import java.util.NoSuchElementException;
 4 import java.util.concurrent.TimeUnit;
 5 import org.openqa.selenium.By;
 6 import org.openqa.selenium.WebElement;
 7 import org.openqa.selenium.remote.RemoteWebDriver;
 8 import org.openqa.selenium.support.ui.WebDriverWait;
 9 import com.drutt.mm.end2end.data.TestConstant;
10 public class WebDriverAction {
11    //protected WebDriverdriver;
12    protected RemoteWebDriverdriver;
13    protected WebDriverWaitdriverWait;
14     protected booleanisWebElementExist(By selector) {
15         try {
16             driver.findElement(selector);
17             return true;
18         } catch(NoSuchElementException e) {
19             return false;
20         }
21     } 
22     protected StringgetWebText(By by) {
23         try {
24         return driver.findElement(by).getText();
25         } catch (NoSuchElementException e) {
26             return "Textnot existed!";
27         }
28     }
29     protected voidclickElementContainingText(By by, String text){
30         List<WebElement>elementList = driver.findElements(by);
31         for(WebElement e:elementList){
32             if(e.getText().contains(text)){
33                 e.click();
34                 break;
35             }
36         }    
37     }
38     protected StringgetLinkUrlContainingText(By by, String text){
39         List<WebElement>subscribeButton = driver.findElements(by);
40         String url = null;
41         for(WebElement e:subscribeButton){
42             if(e.getText().contains(text)){
43                 url =e.getAttribute("href");
44                 break;
45             }
46         }
47         return url;
48     }
49     protected void click(Byby){
50        driver.findElement(by).click();     driver.manage().timeouts().implicitlyWait(TestConstant.WAIT_ELEMENT_TO_LOAD,TimeUnit.SECONDS);
51     }
52     protected StringgetLinkUrl(By by){
53         return driver.findElement(by).getAttribute("href");
54     }
55    
56 
57     protected void sendKeys(Byby, String value){
58 
59        driver.findElement(by).sendKeys(value);
60 
61     }

 

 

5   在selenium2.0中使用selenium1.0的API

Selenium2.0中使用WeDriver API对页面进行操作,它最大的优点是不需要安装一个selenium server就可以运行,但是对页面进行操作不如selenium1.0的Selenium RC API那么方便。Selenium2.0提供了使用Selenium RC API的方法:

 1 // You may use any WebDriver implementation. Firefox is used hereas an example
 2 
 3 WebDriver driver = new FirefoxDriver();
 4 
 5  
 6 
 7 // A "base url", used by selenium to resolve relativeURLs
 8 
 9  String baseUrl ="http://www.google.com";
10 
11  
12 
13 // Create the Selenium implementation
14 
15 Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
16 
17  
18 
19 // Perform actions with selenium
20 
21 selenium.open("http://www.google.com");
22 
23 selenium.type("name=q", "cheese");
24 
25 selenium.click("name=btnG");
26 
27  
28 
29 // Get the underlying WebDriver implementation back. This willrefer to the
30 
31 // same WebDriver instance as the "driver" variableabove.
32 
33 WebDriver driverInstance = ((WebDriverBackedSelenium)selenium).getUnderlyingWebDriver();
34 
35  
36 
37     //Finally, close thebrowser. Call stop on the WebDriverBackedSelenium instance
38 
39     //instead of callingdriver.quit(). Otherwise, the JVM will continue running after
40 
41     //the browser has beenclosed.
42 
43     selenium.stop();

 

 

我分别使用WebDriver API和SeleniumRC API写了一个Login的脚本,很明显,后者的操作更加简单明了。

 1 //WebDriver API写的Login脚本:
 2 
 3     public void login() {
 4 
 5         driver.switchTo().defaultContent();
 6 
 7         driver.switchTo().frame("mainFrame");
 8 
 9  
10 
11         WebElement eUsername= waitFindElement(By.id("username"));
12 
13         eUsername.sendKeys(manager@ericsson.com);
14 
15  
16 
17         WebElement ePassword= waitFindElement(By.id("password"));
18 
19         ePassword.sendKeys(manager);
20 
21  
22 
23         WebElementeLoginButton = waitFindElement(By.id("loginButton"));
24 
25        eLoginButton.click();
26 
27  
28 
29     }
30 
31    
32 
33 //SeleniumRC API写的Login脚本:
34 
35     public void login() {
36 
37         selenium.selectFrame("relative=top");
38 
39         selenium.selectFrame("mainFrame");
40 
41         selenium.type("username","manager@ericsson.com");
42 
43         selenium.type("password","manager");
44 
45         selenium.click("loginButton");
46 
47 }

 

6   在selenium webdriver定位不到元素的五种原因及解决办法

Selenium2.0中使用WeDriver API对页面进行操作,它最大的优点是不需要安装一个selenium server就可以运行,但是对页面进行操作不如selenium1.0的Selenium RC API那么方便。Selenium2.0提供了使用Selenium RC API的方法:

6.1.动态id定位不到元素

for example:        //WebElement  xiexin_element = driver.findElement(By.id("_mail_component_82_82"));         WebElement xiexin_element = driver.findElement(By.xpath("//span[contains(.,'写  信')]"));
        xiexin_element.click();

    上面一段代码注释掉的部分为通过id定位element的,但是此id“_mail_component_82_82”后面的数字会随着你每次登陆而变化,此时就无法通过id准确定位到element。
    所以推荐使用xpath的相对路径方法查找到该元素。

6.2.iframe原因定位不到元素

     由于需要定位的元素在某一个frame里边,所以有时通过单独的id/name/xpath还是定位不到此元素
比如以下一段xml源文件:

<iframe id="left_frame" scrolling="auto" frameborder="0" src="index.php?m=Index&a=Menu" name="left_frame" noresize="noresize" style="height: 100%;visibility: inherit; width:  100%;z-index: 1">

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML  4.01 Transitional//EN"  "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<body class="menuBg">
<div id="menu_node_type_0">
<table width="193" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<tr>
<td id="c_1">
<table class="menuSub" cellspacing="0" cellpadding="0" border="0" align="center">
<tbody>
<tr class="sub_menu">
<td>
<a href="index.php?m=Coupon&a=SearchCouponInfo" target="right_frame">密码重置</a>
</td>
</tr>
原本可以通过
WebElement element =  driver.findElement(By.linkText("密码重置"));
来定位此元素,但是由于该元素在iframe id="left_frame"这个frame里边  所以需要先通过定位frame然后再定位frame里边的某一个元素的方法定位此元素
WebElement element  =driver.switchTo().frame("left_frame").findElement(By.linkText("密码重置"));

6.3.不在同一个frame里边查找元素
大家可能会遇到页面左边一栏属于left_frame,右侧属于right_frame的情况,此时如果当前处在
left_frame,就无法通过id定位到right_frame的元素。此时需要通过以下语句切换到默认的content
driver.switchTo().defaultContent();

例如当前所在的frame为left_frame

       WebElement xiaoshoumingxi_element =  driver.switchTo().frame("left_frame").findElement(By.linkText("销售明细"));
        xiaoshoumingxi_element.click();

需要切换到right_frame      
       driver.switchTo().defaultContent();
       
        Select quanzhong_select2 = new  Select(driver.switchTo().frame("right_frame").findElement(By.id("coupon_type_str")));
        quanzhong_select2.selectByVisibleText("售后0小时");


6.4.  xpath描述错误
这个是因为在描述路径的时候没有按照xpath的规则来写 造成找不到元素的情况出现

6.5.点击速度过快  页面没有加载出来就需要点击页面上的元素
这个需要增加一定等待时间,显示等待时间可以通过WebDriverWait  和util来实现
例如:
       //用WebDriverWait和until实现显示等待  等待欢迎页的图片出现再进行其他操作
       WebDriverWait wait = (new  WebDriverWait(driver,10));
       wait.until(new  ExpectedCondition<Boolean>(){
           public Boolean apply(WebDriver  d){
               boolean loadcomplete =  d.switchTo().frame("right_frame").findElement(By.xpath("//center/div[@class='welco']/img")).isDisplayed();
                return loadcomplete;
           }
        });
也可以自己预估时间通过Thread.sleep(5000);//等待5秒 这个是强制线程休息

6.6.firefox安全性强,不允许跨域调用出现报错
错误描述:uncaught exception:  [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)  [nsIDOMNSHTMLDocument.execCommand]" nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location:

解决办法:
这是因为firefox安全性强,不允许跨域调用。 
Firefox  要取消XMLHttpRequest的跨域限制的话,第一
是从 about:config 里设置  signed.applets.codebase_principal_support = true; (地址栏输入about:config  即可进行firefox设置)
第二就是在open的代码函数前加入类似如下的代码: try {  netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); }  catch (e) { alert("Permission UniversalBrowserRead denied."); } 

 参考:http://www.360doc.com/showWeb/0/0/574752331.aspx

          http://www.360doc.com/showWeb/0/0/574745689.aspx

posted @ 2016-07-11 17:09  linchw3  阅读(162)  评论(0编辑  收藏  举报