Overview and Architecture

Core language support for JavaScript in HtmlUnit is provided by an adapted version of the Mozilla Rhino engine. HtmlUnit builds on top of Rhino to provide all browser-specific host objects such as Window, Document, or Navigator.

HtmlUnitScriptable

All of HtmlUnit's JavaScript host objects subclass HtmlUnitScriptable (or its proxy subclasses) either directly or indirectly. This base class implements Rhino's ScriptableObject and manages the binding between JavaScript host objects and their underlying DomNode instances.

Key features provided by HtmlUnitScriptable include:

  • DOM Node Binding: Connects DOM elements to their corresponding JavaScript objects via getDomNodeOrDie(), getDomNodeOrNull(), and setDomNode().
  • Automatic Scriptable Factory: Dynamically instantiates the appropriate JavaScript host class for a given DOM node via makeScriptableFor(DomNode) by walking up the Java inheritance chain.
  • Preemption Property Lookup: Provides getWithPreemption(String) to allow host objects to resolve dynamic object content or properties before Rhino traverses the standard prototype chain.
  • Scope & Window Resolution: Provides helper methods like getWindow() and getBrowserVersion() to easily resolve top-level scope context from any host object.

Configuring JavaScript Execution

JavaScript execution is enabled by default in WebClient, matching standard web browser behavior.

Handling JavaScript Exceptions

Key Difference from Real Browsers: By default, HtmlUnit halts script execution when an unhandled JavaScript error occurs. This "fail-early" practice is designed specifically for automated testing environments.

You can instruct HtmlUnit to log exceptions without throwing Java exceptions by setting throwExceptionOnScriptError to false:

final WebClient webClient = new WebClient();
webClient.getOptions().setThrowExceptionOnScriptError(false);

Completely Disabling JavaScript Support

To optimize performance or reduce memory consumption, you can permanently disable JavaScript support. The most resource-efficient method uses a specific WebClient constructor:

WebClient webClient = new WebClient(BrowserVersion.FIREFOX, false, null, -1);

Temporarily Disabling JavaScript Support

You can toggle JavaScript execution on or off dynamically using WebClientOptions. Disabling JavaScript this way prevents <script> execution and event handler invocation, though JavaScript host objects remain instantiated in memory.

final WebClient webClient = new WebClient(BrowserVersion.FIREFOX);
webClient.getOptions().setJavaScriptEnabled(false);
// ... perform actions with JS disabled ...
webClient.getOptions().setJavaScriptEnabled(true);