Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

You can request an HtmlUnit session with JavaScript enabled through php-webdriver’s DesiredCapabilities::htmlUnitWithJS(), then save the current view with $driver->takeScreenshot(). The PHP package is only a WebDriver client: a running remote endpoint must accept that capability and implement screenshot capture. The PHP methods are documented, but support for screenshots on a particular HtmlUnit endpoint is not guaranteed, so verify it against the exact server and version you deploy. [php-webdriver documentation] [capability source]

What you need before writing the PHP code

  • PHP with Composer available in your project.
  • The php-webdriver/webdriver Composer package.
  • A running Selenium-compatible WebDriver remote end reachable from the PHP process.
  • Confirmation that this endpoint accepts the HtmlUnit browser capability with JavaScript enabled and supports the screenshot command you need.

The package documentation describes compatibility with Selenium Server 2.x, 3.x and 4.x, and support for W3C WebDriver and legacy JsonWireProtocol. That is the project’s documented compatibility range, not a guarantee that every capability combination or remote-end implementation works. Older tutorials may use the former package name facebook/php-webdriver; the project says the rename began with library version 1.8.0. Follow your installed package’s current documentation when updating older code. [php-webdriver README]

Install the PHP client

From your project directory, run:

composer require php-webdriver/webdriver

This installs the PHP client library; it does not install HtmlUnit, start Selenium Server, or create a remote browser endpoint.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Confirm the endpoint separately

The endpoint URL depends on your Selenium Server or driver setup. The examples below use http://localhost:4444 only as an illustrative address. Selenium Server versions can require different endpoint paths, and the cited client documentation does not establish a universally recommended current HtmlUnit endpoint pairing. Check the server’s own instructions for its required URL and verify that it accepts browserName=htmlunit plus the HtmlUnit JavaScript capability before relying on the workflow. [php-webdriver README]

Capture a screenshot with HtmlUnitWithJS

Save this as a PHP file inside the Composer project. It requests the HtmlUnit-with-JavaScript capability, opens a page and writes the screenshot to screenshot.png. It will work only if the remote end accepts the requested session and implements screenshot capture.

<?php

require_once __DIR__ . '/vendor/autoload.php';

use FacebookWebDriverRemoteDesiredCapabilities;
use FacebookWebDriverRemoteRemoteWebDriver;

$serverUrl = 'http://localhost:4444'; // Replace with your endpoint URL.
$driver = RemoteWebDriver::create(
    $serverUrl,
    DesiredCapabilities::htmlUnitWithJS()
);

try {
    $driver->get('https://example.com');
    $driver->takeScreenshot(__DIR__ . '/screenshot.png');
} finally {
    $driver->quit();
}

The capability factory requests browserName=htmlunit and enables HtmlUnit’s JavaScript capability. It configures a session request; it does not provision the browser or server. The documented screenshot method accepts a file path for saving the current view. [DesiredCapabilities source] [php-webdriver screenshot reference]

What happens when you run it

  1. Composer’s autoloader makes the client classes available.
  2. RemoteWebDriver::create() asks the server at your configured URL to start a session using the requested capability.
  3. get() navigates that session to the target URL.
  4. takeScreenshot() asks the remote end for a screenshot and saves the returned image data at the specified path.
  5. The finally block calls quit(), closing the WebDriver session whether capture succeeds or an exception occurs.

Because session creation and screenshot support belong to the remote end, a valid PHP call does not prove the server can perform both operations. Treat the first run as an endpoint compatibility check.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Save screenshot data in memory or capture an element

The client documents screenshot calls that return image data without a path, as well as an element screenshot method. The returned data can be passed into your own storage or response logic; choose a destination and error handling appropriate to your application. [php-webdriver screenshot reference]

Keep the current-view image in memory

$screenshotData = $driver->takeScreenshot();

This gets the screenshot data rather than asking the method to save it to a named file. Check how your installed client version represents the result before writing it to a file or sending it elsewhere.

Capture a specific element

$element = $driver->findElement(
    FacebookWebDriverWebDriverBy::cssSelector('.report-card')
);
$element->takeElementScreenshot(__DIR__ . '/element-screenshot.png');

Use a selector that identifies the intended element on the loaded page. The client reference also documents retrieving element screenshot data without providing a file path. Whether the remote end supports element screenshots remains endpoint-specific.

What “current view” means—and what it does not

The PHP reference names the driver method “Screenshot of current view” and the element method “Screenshot of an element.” Do not assume that the first method always produces a full-page capture. Selenium’s general API describes screenshot data as base64-encoded PNG and gives a best-effort scope preference: entire page, current window, visible portion of the current frame, then the entire display containing the browser. Those general semantics do not establish what a particular HtmlUnit remote end implements or returns. [Selenium WebDriver API]

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If your test depends on a full-page image, exact CSS layout, or a particular browser’s rendering, inspect the actual output from your deployed endpoint and compare it with the browser and page behavior your test is meant to represent.

What JavaScript-enabled HtmlUnit does—and its fidelity limits

DesiredCapabilities::htmlUnitWithJS() sets the browser name to htmlunit and enables the HtmlUnit-specific JavaScript capability. The client source notes that JavaScript enablement is HtmlUnit-only; attempting to set that option after choosing another browser name can raise an unsupported-operation exception. [DesiredCapabilities source]

HtmlUnit describes JavaScript as simulating a configured browser, with scripts running when a page loads or a handler is triggered. Its documentation lists tested examples for selected libraries and versions, including htmx 1.7.0, 1.8.4, 1.9.x and 2.0.x, and jQuery 1.8.2, 1.11.3 and 1.12.4. These are project-stated examples of tested support, not a universal compatibility measure or proof that a site will behave like it does in Chrome or Firefox. [HtmlUnit JavaScript documentation]

Choose the backend according to what you need to validate:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Capability availability: Will the remote end accept browserName=htmlunit with JavaScript enabled?
  • Screenshot behavior: Does that exact endpoint implement current-view capture, element capture or the scope your test expects?
  • Rendering fidelity: Is HtmlUnit’s simulated browser behavior suitable, or must the test use actual Chrome or Firefox rendering?
  • Version and protocol fit: Does your PHP client work with the deployed server or driver and its endpoint path?
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common failures

Session creation is rejected

Likely cause: The remote end does not recognize browserName=htmlunit, does not accept the JavaScript capability, or expects a different endpoint URL or capability format.

What to do: Confirm the server URL and endpoint path from the server’s documentation, check its supported capabilities, and verify compatibility with the client and protocol version actually deployed. Do not interpret successful Composer installation as proof that a server-side HtmlUnit implementation is available.

Screenshot capture fails after the page loads

Likely cause: The endpoint accepted the session but does not implement the screenshot command for HtmlUnit, or does not support the particular screenshot scope you requested.

What to do: Test the command against the exact remote end and version. If screenshot support is a firm requirement, use a remote end that documents the needed command or choose a browser driver that meets the fidelity requirements.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The output is not a full-page image

Likely cause: The API is documented as current-view capture, and general Selenium scope behavior is best effort rather than an HtmlUnit guarantee.

What to do: Examine the produced image and confirm whether your endpoint supports full-page capture. If the requirement is critical, validate the approach using the concrete driver and version intended for production.

JavaScript behavior differs from a regular browser

Likely cause: HtmlUnit simulates a configured browser; the documented library examples do not guarantee compatibility with every script or site.

What to do: Reduce the issue to the page behavior your test depends on, check HtmlUnit’s current JavaScript documentation, and use an actual browser driver when real-browser behavior is necessary.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The browser session is left running after an error

Likely cause: Cleanup was skipped on an exception path.

What to do: Keep session work inside try and call quit() in finally, as in the example. This ensures your code attempts session cleanup after navigation or capture errors.

Reliability, performance and cost considerations

For a single capture, the main operational dependency is the remote endpoint: it must be reachable, accept the desired session, load the target page and support the screenshot command. The available documentation here does not establish a performance benchmark, a universal HtmlUnit screenshot success rate, or a general cost for running an endpoint. Measure latency and resource use in your own deployment, and account for the server or hosted service you choose.

For repeatable tests, pin and record the client and remote-end versions, keep the endpoint path configurable, and save enough context with a failed image to reproduce the session. A screenshot can confirm what that endpoint rendered; it cannot by itself establish that another browser would render the same way.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup:

ScreenshotNeo accepts one GET request and returns a website screenshot as PNG, JPEG or WebP, or a PDF. Its API and parameter details are in the ScreenshotNeo documentation. For example, this cURL request saves a WebP screenshot of the target URL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each of those steps can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and responses include X-Page-Verdict and X-Billed headers. Its MCP server offers take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. These are ScreenshotNeo plan terms, not a comparison with the cost of operating a Selenium endpoint. See ScreenshotNeo, or sign up for 1,000 free screenshots a month with no card.

Frequently Asked Questions

Does HtmlUnitWithJS guarantee that screenshots will work?

No. It requests a JavaScript-enabled HtmlUnit session; screenshot-command support depends on the specific remote end.

Can I use the same PHP client with Chrome or Firefox?

The package supports WebDriver clients, but browser selection and capability setup differ; use the capabilities and endpoint appropriate to the browser driver.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.