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

HtmlUnit выдает исключение и сбой моего теста, когда я загружаю страницу

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

ReferenceError:" x " не определено. (чистый.на SourceForge.htmlunit.corejs.Яваскрипт.EcmaError)

исключение не возникает, если я использую драйвер Firefox.

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

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

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

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

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

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

6 ответов


на источник 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);

Только Для Java: В последней версии WebClient (который обернут HTMLUnitDriver) client.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;
    }
}

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

Я нашел ту же проблему в мире .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});
}

этот метод заткнет любой регистратор навсегда!

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

            });

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