2017-08-25 61 views
0

我正在使用Selenium編寫Java中的自動化工具。如果WebDriver是FirefoxDriver,下面的代碼工作正常,但是如果我嘗試用HtmlUnitDriver替換它,當它應該點擊一個範圍時,它會在行上崩潰。我試圖通過CSS選擇器和XPath來定位跨度。使驅動程序等待,直到元素加載爲HtmlUnit無法點擊Selenium中的跨度,Java

wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(".//*[@id='home']/div[3]/div[3]/div[10]/div[3]/div[2]/div[1]/a/span"))); 

也不能解決問題。該代碼是:

WebDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_52); 

//driver.setJavascriptEnabled(true); 

WebDriverWait wait = new WebDriverWait(driver, 10); 

//logs in 
driver.get("https://www.tribalwars.net/"); 
driver.findElement(By.id("user")).clear(); 
driver.findElement(By.id("user")).sendKeys(username); 
driver.findElement(By.cssSelector("div.right.login > div.wrap")).click(); 
driver.findElement(By.id("password")).clear(); 
driver.findElement(By.id("password")).sendKeys(password); 
driver.findElement(By.cssSelector("a.btn-login")).click(); 

//It executes fine up until this point 

driver.findElement(By.cssSelector("span.world_button_active")).click(); 
/* 
This won't work either  
driver.findElement(By.xpath(".//*[@id='home']/div[3]/div[3]/div[10]/div[3]/div[2]/div[1]/a/span")).click(); 
*/ 

的錯誤,我給出:

Exception in thread "main" org.openqa.selenium.NoSuchElementException: Returned node was not a DOM element 
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html 
Build info: version: 'unknown', revision: 'unknown', time: 'unknown' 
System info: host: 'PC', ip: '127.0.1.1', os.name: 'Linux', os.arch: 'amd64', os.version: '4.4.0-53-generic', java.version: '1.8.0_131' 
Driver info: driver.version: HtmlUnitDriver 
    at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElementByCssSelector(HtmlUnitDriver.java:1247) 
    at org.openqa.selenium.By$ByCssSelector.findElement(By.java:430) 
    at org.openqa.selenium.htmlunit.HtmlUnitDriver$5.call(HtmlUnitDriver.java:1965) 
    at org.openqa.selenium.htmlunit.HtmlUnitDriver$5.call(HtmlUnitDriver.java:1) 
    at org.openqa.selenium.htmlunit.HtmlUnitDriver.implicitlyWaitFor(HtmlUnitDriver.java:1601) 
    at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElement(HtmlUnitDriver.java:1961) 
    at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElement(HtmlUnitDriver.java:756) 
    at Bot.Test.build(Test.java:86) 
    at Bot.Test.main(Test.java:42) 
+0

你能發佈span.world_button_active的html代碼嗎? – smit9234

+0

嘗試使用elementToBeClickable(通過定位器)... – Grasshopper

+0

聽起來像您的選擇器不匹配元素。你可以通過打開瀏覽器的JS控制檯並執行document.querySelector(「span.world_button_active」)來確認選擇器是否工作正常。看看是否返回一個元素。 –

回答

0

的根本原因是你的HtmlUnitDriver沒有執行JavaScript。你必須打開它。

但是,由於網站有一些錯誤,驅動程序會崩潰。所以你必須定製HtmlUnitDriver來允許這些錯誤。

您需要做的是繼承HtmlUnitDriver並覆蓋modifyWebClient以關閉一些錯誤引發。

import java.util.logging.Level; 
import java.util.logging.Logger; 

import org.openqa.selenium.htmlunit.HtmlUnitDriver; 

import com.gargoylesoftware.htmlunit.BrowserVersion; 
import com.gargoylesoftware.htmlunit.WebClient; 

public class MyHtmlUnitDriver extends HtmlUnitDriver { 

    public MyHtmlUnitDriver(BrowserVersion version, boolean enableJavascript) { 
     super(version, enableJavascript); 
    } 

    protected WebClient modifyWebClient(WebClient client) { 
     WebClient modifiedClient = super.modifyWebClient(client); 
     Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF); 
     modifiedClient.getOptions().setThrowExceptionOnScriptError(false); 
     modifiedClient.getOptions().setThrowExceptionOnFailingStatusCode(false); 
     modifiedClient.getOptions().setPrintContentOnFailingStatusCode(false); 
     return modifiedClient; 
    } 
} 

下面的代碼顯示了一個例子。

public void test() { 
    // Use a custom HtmlUnitDriver 
    WebDriver hd = new MyHtmlUnitDriver(BrowserVersion.FIREFOX_52, true); 
    WebDriverWait wait = new WebDriverWait(hd, 10); 

    hd.get("https://www.tribalwars.net/"); 
    hd.findElement(By.id("user")).clear(); 
    hd.findElement(By.id("user")).sendKeys(username); 
    hd.findElement(By.cssSelector("div.right.login > div.wrap")).click(); 
    hd.findElement(By.id("password")).clear(); 
    hd.findElement(By.id("password")).sendKeys(password); 
    hd.findElement(By.cssSelector("a.btn-login")).click(); 

    // Add Wait here 
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("span.world_button_active"))); 
    hd.findElement(By.cssSelector("span.world_button_active")).click(); 

P.S.我想你應該用PhantomJS或SlimmerJS來代替。

+0

謝謝,它工作!但是爲什麼我應該使用PhantomJS?根據Selenium的網站HtmlUnit是最快的實現,使用PhantomJS將要求我依賴平臺特定的代碼。 – HelloImRandom

+0

@你好隨機這只是我的看法。 PhantomJS和SlimmerJS使用真正的Web瀏覽器引擎,而HtmlUnit使用Rhino,所以我更喜歡真正的引擎。 – Buaban