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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8745061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 04:27:46  来源:igfitidea点击:

Is it possible to ignore JavaScript exceptions when working with WebDriver (HtmlUnit, Ruby bindings)

javascriptrubyseleniumwebdriverhtmlunit

提问by boxx

HtmlUnit throws exception and crash my test when I'm loading the page

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

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

ReferenceError: "x" is not defined. (net.sourceforge.htmlunit.corejs.javascript.EcmaError)

参考错误:“x”未定义。(net.sourceforge.htmlunit.corejs.javascript.EcmaError)

No exception is thrown if I use a Firefox driver.

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

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

Or disable JavaScript for HtmlUnit driver

或为 HtmlUnit 驱动程序禁用 JavaScript

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

I am unable to change the code on the test page and fix the problem, so I need to either ignore it or in any way to use Firefox JavaScript Engine instead of the standard HtmlUnit JavaScript Engine.

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

Is it possible to solve my problem without changing the code of test page?

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

Update:Tried Capybara + WebKit as an alternative to Selenium + HtmlUnit - works fine, without errors. But still I would like to solve the problem without changing the framework.

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

采纳答案by Niklas B.

After looking at the source of the HtmlUnitDriver, it seems like there is no possibility to customize the behaviour you want to change. The easiest thing you could do to solve this is to patch and recompile the Selenium server (which might or might not be an option). You'd need to add this line:

查看 的来源后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);

回答by Vitaliy Grigoruk

For Java Only:In the latest version of WebClient(which is wrapped by HTMLUnitDriver) client.setThrowExceptionOnScriptError(false)method is deprecated. In case of subclassing HTMLUnitDriver, you need to override modifyWebClient method:

仅适用于 Java:在最新版本中WebClient(由 包装HTMLUnitDriverclient.setThrowExceptionOnScriptError(false)方法已弃用。在继承 HTMLUnitDriver 的情况下,您需要覆盖 modifyWebClient 方法:

public class MyHtmlUnitDriver extends HtmlUnitDriver {

...

 @Override
    protected WebClient modifyWebClient(WebClient client) {
        //currently does nothing, but may be changed in future versions
        WebClient modifiedClient = super.modifyWebClient(client);

        modifiedClient.getOptions().setThrowExceptionOnScriptError(false);
        return modifiedClient;
    }
}

回答by tvoutour

I was able to solve it using HPUnit_Extensions_Selenium2TestCasev1.4.0as follows:

我能够使用HPUnit_Extensions_Selenium2TestCasev1.4.0以下方法解决它:

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

回答by jechaviz

Based on answer from @Vitaly

基于@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);
        }
    }

回答by user3093030

This method wil shut up any logger for always!

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

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() {

            });

回答by Dan

I found the same problem in the .net world.

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

I got around it in c# by using reflection and an extension method:

我通过使用反射和扩展方法在 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});
}