Overview
Contributions to HtmlUnit are always welcome! Whether you are fixing bugs, improving JavaScript emulation, updating documentation, or adding test cases, your efforts help maintain a robust browser simulation engine.
HtmlUnit development is a volunteer effort. Following the guidelines on this page helps maintainers review, reproduce, and merge your contributions efficiently.
Reporting General Bugs
Issues in HtmlUnit typically stem from one of four sources: bugs in third-party dependencies, unsupported browser functionality, errors in application code, or genuine bugs in HtmlUnit. We track issues using the GitHub issue tracker at https://github.com/HtmlUnit/htmlunit/issues.
Before submitting a bug report:
- Test against the latest version: Verify if the issue persists in the latest release or latest snapshot build.
- Check existing issues: Search open and recently closed issues to avoid submitting duplicates. If a matching issue exists, add your details or test cases to the discussion thread.
- Verify dependencies: Ensure all required JAR files specified in the dependencies list are present in your classpath.
How to Submit Effective Bug Reports
To fix a bug, maintainers must be able to reproduce it quickly. To help us help you:
- Provide a minimal reproducible example: Reduce your HTML and Java code to the absolute minimum necessary to trigger the failure. Trimming extraneous code speeds up investigation significantly.
- Supply an automated JUnit test: Writing a failing test case allows maintainers to execute and verify the issue immediately.
Reporting and Debugging JavaScript Bugs
HtmlUnit provides extensive JavaScript emulation, including test suites for popular frameworks like jQuery, Dojo, Prototype, GWT, YUI, and Sarissa. However, real-world web applications may expose unsupported properties or edge-case behavior.
Testing pages containing JavaScript can produce errors for several reasons. Some web browsers accept non-standard shortcuts or DOM extensions that HtmlUnit does not yet emulate. When inline JavaScript code is executed, HtmlUnit wraps it in a synthetic function, which can make error line numbers and stack traces harder to decipher.
To assist with debugging, setting the logger org.htmlunit.javascript to the DEBUG log level
causes HtmlUnit to log the generated wrapper functions alongside the original inline code.
To help identify missing property definitions, HtmlUnit emits WARN level log entries when expected objects are undefined.
Before submitting JavaScript issues, please read Debugging JavaScript Bugs.
When reporting JavaScript issues, simply stating that "jQuery does not work" or "Website X fails" is not actionable. Please isolate the issue down to the specific JavaScript method, property, or event handler that is failing.
Steps for Isolating JavaScript Errors
Follow these recommended steps to pin down the root cause:
-
Match target BrowserVersion: Ensure
WebClientis instantiated with the sameBrowserVersionas the real browser you are testing against. -
Enable Debug Logging: Set the logger
org.htmlunit.javascripttoDEBUGlevel. This will log wrapped inline code, making stack traces easier to trace back to source files. -
Use an Intercepting Proxy: Tools like Charles Proxy allow you
to intercept HTTP responses and inject debugging statements (like
alert()) into external JS files. Use Map Local features to substitute remote JavaScript files with modified local files. - Disable Browser Caching: Ensure your comparison browser fetches freshly modified scripts without caching.
Example: Diagnosing undefined errors:
org.htmlunit.corejs.javascript.EcmaError: TypeError: Cannot call method "getAttribute" of undefined
(http://example.com/js/app.js#16)
This indicates that the target variable evaluated to undefined prior to the getAttribute() call.
Inspect the call stack in your proxy or browser developer tools to determine where the object initialization diverged.
Useful Injected JavaScript Debug Techniques
Inspecting Variable Values:
function myFunction(a, b) {
var c = a + b;
alert(c); // Compare output between HtmlUnit and a real browser
return c;
}
Inspecting the Call Stack:
function myFunction(a, b) {
alert(arguments.callee.caller); // Prints the outer caller function
return a + b;
}
Conditional or Flagged Alert Logging:
var debug = false;
function testExecution() {
debug = true; // Enable debug logging specifically for this pass
myFunction(1, 2);
debug = false;
}
function myFunction(a, b) {
if (debug) {
alert("myFunction called with: " + a + ", " + b);
}
return a + b;
}
Submitting Pull Requests
The preferred way to submit code or documentation contributions is by opening a Pull Request against our GitHub repository.
Pull Request Rules and Guidelines
To minimize maintainer overhead and accelerate code review, all pull requests must follow these rules:
-
Coding Conventions: Code must strictly follow our coding conventions.
Run
mvn checkstyle:checkstylebefore submitting. -
Automated Unit Tests: No code changes will be merged without accompanying unit tests.
When applicable, test classes should extend
WebDriverTestCaseto ensure cross-browser compatibility. - Bug Fix Tests: Bug fixes must include a unit test that fails with the old behavior and passes with the fix applied.
- Existing Test Suite Pass: Ensure the full test suite passes locally or via your feature branch.
- License & Copyright: All original source files must carry the Gargoyle Software Inc. copyright notice and be licensed under the project's Apache License 2.0.
-
JavaDoc & Author Tags: All public methods must include clear JavaDoc documentation.
Add your name to the top-level
@authorblock in chronological order when modifying existing classes.
IMPORTANT: Pull requests without accompanying unit tests will be rejected. If you need assistance constructing a WebDriver test case, post a question on your pull request draft or consult the Development Guide.
Additional documentation updates and example improvements are always greatly appreciated.

