使用WebDriver时可以忽略JavaScriptexception(HtmlUnit,Ruby绑定)

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

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驱动程序,则不会抛出exception。

 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的替代品 – 工作正常,没有错误。 但我还是想在不改变框架的情况下解决问题。

在查看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 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(); $this->setPort(); $this->setDesiredCapabilities(Array("javascriptEnabled"=>"false")); 

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

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