使用WebDriver时是否可以忽略JavaScript异常(HtmlUnit,Ruby绑定)

时间:2012-01-05 15:29:33

标签: javascript ruby selenium webdriver htmlunit

当我加载页面时,HtmlUnit会抛出异常并导致我的测试崩溃

caps = Selenium::WebDriver::Remote::Capabilities.htmlunit(:javascript_enabled => true)
driver = Selenium::WebDriver.for(:remote, :desired_capabilities => caps)
driver.navigate.то url
  

ReferenceError:未定义“x”。   (net.sourceforge.htmlunit.corejs.javascript.EcmaError)

如果我使用Firefox驱动程序,则不会抛出任何异常。

caps = Selenium::WebDriver::Remote::Capabilities.firefox

或禁用HtmlUnit驱动程序的JavaScript

caps = Selenium::WebDriver::Remote::Capabilities.htmlunit(:javascript_enabled => false)

我无法更改测试页面上的代码并解决问题,因此我需要忽略它或以任何方式使用Firefox JavaScript Engine而不是标准的HtmlUnit JavaScript引擎。

是否可以在不更改测试页代码的情况下解决我的问题?

更新 尝试Capybara + WebKit作为Selenium + HtmlUnit的替代品 - 工作正常,没有错误。但我仍然希望在不改变框架的情况下解决问题。

6 个答案:

答案 0 :(得分:18)

仅适用于Java:WebClient的最新版本(由HTMLUnitDriver包装)中,{@ 1}}方法已弃用。在子类化HTMLUnitDriver的情况下,您需要覆盖modifyWebClient方法:

client.setThrowExceptionOnScriptError(false)

答案 1 :(得分:8)

查看source of the HtmlUnitDriver后,似乎无法自定义要更改的行为。您可以做的最简单的事情是修补和重新编译Selenium服务器(可能是也可能不是选项)。您需要添加以下内容:

--- HtmlUnitDriver.java 2012-01-05 17:45:22.779579136 +0100
+++ HtmlUnitDriver.java 2012-01-05 18:14:51.415106195 +0100
@@ -255,6 +255,7 @@
     WebClient client = newWebClient(version);
     client.setHomePage(WebClient.URL_ABOUT_BLANK.toString());
     client.setThrowExceptionOnFailingStatusCode(false);
+    client.setThrowExceptionOnScriptError(false);
     client.setPrintContentOnFailingStatusCode(false);
     client.setJavaScriptEnabled(enableJavascript);
     client.setRedirectEnabled(true);

答案 2 :(得分:1)

我能够使用HPUnit_Extensions_Selenium2TestCase v1.4.0解决问题,如下所示:

class TestBase extends PHPUnit_Extensions_Selenium2TestCase
{
    public function setUp()
    {
        $this->setHost(<your-host>);
        $this->setPort(<your-port>);
        $this->setDesiredCapabilities(Array("javascriptEnabled"=>"false"));

答案 3 :(得分:0)

我在.net世界中发现了同样的问题。

我通过使用反射和扩展方法在c#中解决了这个问题:

public static void SetThrowOnScriptErrors(this HtmlUnitDriver driver, 
                                          bool throwScriptErrors )
{
    object webClient =  driver.GetType().InvokeMember("_webClient",
                                    BindingFlags.GetField | 
                                    BindingFlags.NonPublic | 
                                    BindingFlags.Instance, null,
                                    driver, new object[0]);

    webClient.GetType().InvokeMember("throwExceptionOnScriptError_",
                                        BindingFlags.SetField | 
                                        BindingFlags.NonPublic | 
                                        BindingFlags.Instance,
                                        null, webClient, 
                                        new object[] {throwScriptErrors});
}

答案 4 :(得分:0)

此方法将永远关闭任何记录器!

static void setFinalStatic(Field field, Object newValue) throws Exception {
        field.setAccessible(true);

        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

        field.set(null, newValue);
    }


setFinalStatic(com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.class.getDeclaredField("LOG"), new org.apache.commons.logging.Log() {

            });

答案 5 :(得分:0)

基于@Vitaly的答案

    import org.openqa.selenium.htmlunit.HtmlUnitDriver;
    import com.gargoylesoftware.htmlunit.WebClient;
    import java.util.logging.Logger;
    import java.util.logging.Level;
    public class MyHtmlUnitDriver extends HtmlUnitDriver {
        protected void modifyWebClient() {
            /* turn off annoying htmlunit warnings */
            Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
            WebClient newWebClient = getWebClient();
            newWebClient.getOptions().setThrowExceptionOnScriptError(false);
            newWebClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
            newWebClient.getOptions().setPrintContentOnFailingStatusCode(false);
            modifyWebClient(newWebClient);
        }
    }