Можно ли игнорировать исключения JavaScript при работе с WebDriver (привязки HtmlUnit, Ruby)

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

Или отключите JavaScript для драйвера HtmlUnit

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

Я не могу изменить код на тестовой странице и устранить проблему, поэтому мне нужно либо игнорировать ее, либо каким-либо образом использовать Firefox JavaScript Engine вместо стандартного JavaScript-движка HtmlUnit.

Можно ли решить мою проблему без изменения кода тестовой страницы?

Update: Tried Capybara + WebKit как альтернатива Selenium + HtmlUnit - отлично работает, без ошибок. Но все же я хотел бы решить проблему, не меняя рамки.

Ответ 1

После просмотра источника 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

Только для Java: В последней версии WebClient (который обернут HTMLUnitDriver) client.setThrowExceptionOnScriptError(false) метод устарел. В случае подкласса HTMLUnitDriver вам необходимо переопределить метод modWebClient:

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;
    }
}

Ответ 3

Я смог решить его с помощью 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"));

Ответ 4

Я нашел ту же проблему в мире .net.

Я обошел его в С# с помощью метода отражения и расширения:

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

Ответ 5

Этот метод будет всегда закрывать любой регистратор!

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

            });

Ответ 6

Основываясь на ответе от @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);
        }
    }