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

6

11

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

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)

No exception is thrown if I use a Firefox driver.

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

Or disable JavaScript for HtmlUnit driver

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.

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.

Barbabra answered 5/1, 2012 at 15:29 Comment(2)
Hello I am have same problem. Help ([#23659840) [1]: #23659840Sodden
solution based on setting final field #8745561Accalia
C
8

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.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);
Cyprio answered 5/1, 2012 at 17:15 Comment(1)
Alternately, you could subclass HtmlUnitDriver and override newWebClient(), which is protected.Robinette
S
18

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:

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;
    }
}
Sheffy answered 19/3, 2013 at 22:15 Comment(0)
C
8

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.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);
Cyprio answered 5/1, 2012 at 17:15 Comment(1)
Alternately, you could subclass HtmlUnitDriver and override newWebClient(), which is protected.Robinette
P
1

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

class TestBase extends PHPUnit_Extensions_Selenium2TestCase
{
    public function setUp()
    {
        $this->setHost(<your-host>);
        $this->setPort(<your-port>);
        $this->setDesiredCapabilities(Array("javascriptEnabled"=>"false"));
Poaceous answered 4/8, 2015 at 15:58 Comment(0)
P
1

Based on answer from @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);
        }
    }
Pokelogan answered 28/4, 2017 at 20:16 Comment(0)
A
0

I found the same problem in the .net world.

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

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});
}
Assignor answered 1/3, 2012 at 16:20 Comment(0)
A
0

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

            });
Accalia answered 27/1, 2016 at 12:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.