天天看點

Webdriver定位不到元素的解決辦法

不知道怎麼回事,先前能跑動的case,現在元素始終找不到。

  但是我xpath是能定位得到的,debug了一下,結果發現在

  webelementelement = locator.findelement();就卡住了。

  弄了好久也沒有成功。

  網上找例子:

    1 public boolean doeswebelementexist(webdriver driver, by selector)

    2{

    3

    4         try

    5         {

    6                driver.findelement(selector);

    7                returntrue;

    8        }

    9        catch(nosuchelementexception e)

    10         {

    11                 return false;

    12         }

    13 }

  2.一般有這樣的應用場合,例如我們要驗證在一個網站是否登入成功,那麼可以通過判斷登入之後是否顯示相應元素:

  webelementlinkusername =driver.findelement(by.xpath("//a[contains(text(),"+username+")]"));

  return linkusername.isdisplayed();

  這一方法的前提是:該元素之前已經存在,僅僅需要判斷是否被顯示。

  現在存在另一種場合,頁面元素并不存在,即通過driver.findelement隻能在逾時之後得到nosuchelementexception的異常。

  是以隻好通過如下方法解決:

1 boolean elementexist (bylocator )

2{

3 try

4 {

5 driver.findelement( locator );

6 returntrue;

7}

8 catch(org.openqa.selenium.nosuchelementexception ex)

9{

10     returnfalse;

11 }

12 }

  但這一方法仍然不理想,有這樣兩個問題:

  1、這一方法不屬于任何一個page頁,是以需要額外進行架構上的變更以支援這些功能函數,否則就必須在每一個用到該函數的page類寫一遍。

  2、仍然需要等到逾時才能得知結果,當需要頻繁使用該函數的時候會造成相當的時間浪費。

  3.

  類似于seleniumrc中的istextpresent方法

  用xpath比對所有元素(//*[contains(.,'keyword')]),判斷是否存在包含期望關鍵字的元素。

  使用時可以根據需要調整參數和傳回值。

1 public boolean iscontentappeared(webdriver driver,string content) {

2       booleanstatus = false;

3       try {

4          driver.findelement(by.xpath("//*[contains(.,'" + content +"')]"));

5           system.out.println(content + "is appeard!");

6           status = true;

7       } catch (nosuchelementexception e) {

8           status = false;

9           system.out.println("'" +content + "' doesn't exist!"));

10      }

11      return status;

  4. xpath 多重判斷

  1 while(currentpagelinknumber<maxpage)

  2 {

  3 webelement pagelink;

  4 pagelink = driver.findelement(by.xpath("//a[@class = 'pagelink' and@title ='"+integer.tostring(currentpagelinknumber+1)+"']"));

  5 pagelink.click();

  6 currentpagelinknumber++;

  7 //otheroperation();

  8 }

  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的相對路徑方法查找到該元素。

 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>

<td id="c_1">

<table class="menusub" cellspacing="0" cellpadding="0" border="0" align="center">

<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("密碼重置"));

  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

  select quanzhong_select2 = new select(driver.switchto().frame("right_frame").findelement(by.id("coupon_type_str")));

  quanzhong_select2.selectbyvisibletext("售後0小時");

  4.  xpath描述錯誤

  這個是因為在描述路徑的時候沒有按照xpath的規則來寫 造成找不到元素的情況出現

  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.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."); }

  最後看了乙醇的文章

import java.io.file;

importorg.openqa.selenium.by;

importorg.openqa.selenium.webdriver;

importorg.openqa.selenium.chrome.chromedriver;

importorg.openqa.selenium.support.ui.expectedcondition;

importorg.openqa.selenium.support.ui.webdriverwait;

public classbuttondropdown {

public static voidmain(string[] args) throws interruptedexception {

webdriver dr = newchromedriver();

file file = newfile("src/button_dropdown.html");

string filepath = "file:///" + file.getabsolutepath();

system.out.printf("nowaccesss %s \n", filepath);

dr.get(filepath);

thread.sleep(1000);

//      定位text是watir-webdriver的下拉菜單

//      首先顯示下拉菜單

dr.findelement(by.linktext("info")).click();

(newwebdriverwait(dr, 10)).until(new expectedcondition<boolean>(){

public booleanapply(webdriver d){

returnd.findelement(by.classname("dropdown-menu")).isdisplayed();

}

});

//      通過ul再層級定位

dr.findelement(by.classname("dropdown-menu")).findelement(by.linktext("watir-webdriver")).click();

system.out.println("browser will be close");

dr.quit();

  然後我自己定位的。

public xiaoyuanactivitypage zipaixiuye(){

driver.navigate().refresh();

luntan.click();

webdriverwrapper.waitpageload(driver,3);

(new webdriverwait(driver, 10)).until(newexpectedcondition<boolean>() {

public boolean apply(webdriverdriver){

returndriver.findelement(by.classname("tfb_sub_li")).isdisplayed();

driver.findelement(by.classname("tfb_sub_li")).findelement(by.linktext("自拍秀")).click();

returnpagefactory.initelements(this.getdriver(),

xiaoyuanactivitypage.class);

  總算成功了,成功來得真不容易啊!

  我現在還是不明白我之前的方法為什麼開始可以,後面就不行了。

  但是我現在也不去探究了,我自己的問題已經解決了。

  謝謝分享文章的朋友。

最新内容請見作者的github頁:http://qaseven.github.io/

繼續閱讀