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

A hang at save_screenshot or render_base64 does not, by itself, prove that rendering is broken. First determine which layer is waiting: Capybara may be waiting for an asynchronous condition, the page may still be loading a resource, or Poltergeist may be waiting for PhantomJS to answer a driver command. Capture the exact call, logs, page state, versions, and operating system before changing timeouts or blaming a particular resource.

Identify exactly where the test stops

Record the operation that appears to hang and what happens afterward. Poltergeist supports screenshots through save_screenshot and base64 rendering through render_base64, but the same symptom can arise around other driver calls. Establish whether the process eventually raises an exception, PhantomJS exits or crashes, or the call never returns.

  • Write down the exact method and the immediately preceding test steps.
  • Record how long the call waits and whether the delay is consistent or intermittent.
  • Preserve the full exception and Ruby stack trace, if one appears.
  • Note whether the test runner, PhantomJS process, or entire CI job is what remains active.

That boundary matters: a delay inside a screenshot call can make a page-load or synchronization problem visible, without showing that image rendering itself caused it.

Separate the three likely waiting layers

Capybara is waiting for an asynchronous condition

A test may be waiting for an element, text, or state that client-side JavaScript has not produced yet. Poltergeist’s troubleshooting guidance characterizes flaky tests as synchronization problems and points to Capybara’s asynchronous JavaScript guidance. Wait for the actual condition the test requires rather than treating a longer driver timeout as proof that the page is ready.

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

The evidence available here does not establish a universal Capybara wait duration. Check the installed Capybara version and the condition being awaited before changing a wait setting. If the assertion is waiting on a state that never occurs, increasing a timeout merely delays failure.

The page or one of its resources is still loading

A page can remain incomplete because a request is slow, stalled, or repeatedly attempted. Inspect network traffic and compare it with the visual state: does the page look blank, partly rendered, or complete even though the call has not returned? Poltergeist documents URL whitelisting and blacklisting as ways to address slow external resources. Treat blocking a URL as a targeted diagnostic or deliberate test decision; verify that the resource is not required for the behavior under test.

Poltergeist is waiting for PhantomJS to answer

Poltergeist’s :timeout setting is the number of seconds it waits for a response while communicating with PhantomJS. The README for the version 1.18.1 documentation context gives a default of 30 seconds. This is a driver communication timeout, not a guarantee that page JavaScript has finished or that every network request has completed. Raising it may help if PhantomJS is legitimately slow to answer, but it can also make a stalled process take longer to report.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Enable diagnostics and collect the first evidence

Configure Poltergeist with :debug => true and capture both Ruby-side output and PhantomJS output. Poltergeist notes that some PhantomJS debug output goes to STDOUT for technical reasons, so retaining only a separate error log can miss useful evidence.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Capybara.register_driver :poltergeist_debug do |app|
  Capybara::Poltergeist::Driver.new(app, debug: true)
end

Use the registration pattern appropriate to your installed Capybara and Poltergeist versions; the example enables Poltergeist debugging, but does not set or recommend a timeout. Save the complete output from the failing run, including the stack trace and any PhantomJS messages around the stall.

At the failure boundary, capture a screenshot and inspect network traffic. For example, temporarily add a diagnostic around the point that fails:

Rank #3
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
page.save_screenshot("tmp/poltergeist-failure.png")
traffic = page.driver.network_traffic
traffic.each do |request|
  puts request.url
  request.response_parts.each do |part|
    puts part.status
  end
end

Poltergeist exposes request traffic through page.driver.network_traffic. Exact object details can vary with the installed driver version, so if this snippet does not match your version, inspect the returned objects in a local run and log their available request and response fields. If screenshot capture is the operation that hangs, take the screenshot earlier in the test or use another point in the run where the driver still responds. Poltergeist also documents render_base64 for base64 image output; use it only if that call completes in your environment.

Compare logs with the historical PhantomJS resource-hang report

A PhantomJS issue describes a sporadic page-load hang with PhantomJS 2.1.1 on Debian Jessie. The report associated the problem with a failed resource load and included the message QIODevice::write (QTcpSocket): device not open. Compare your own version, operating system, request trace, and logs with that specific case; it is a useful clue, not evidence that every Poltergeist render hang has the same cause. Read the PhantomJS issue report.

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

Check external resources, sessions, and the test environment

  • External URLs: identify whether a particular third-party request remains incomplete. Poltergeist documents URL whitelisting or blacklisting as possible controls for slow external resources; use them narrowly and confirm the test remains meaningful.
  • Session cleanup: Poltergeist warns that sessions not explicitly quit can contribute to memory exhaustion. Check whether the suite creates sessions without closing them and whether memory use grows across test runs.
  • CI-only differences: the README notes that missing fonts can produce differences in CI. Record the CI image and font availability if output differs between local and CI runs; this observation alone does not establish that fonts caused a hang.
  • Process and memory evidence: capture whether PhantomJS is still running, whether it has exited, and whether system or job memory is under pressure. Avoid changing the environment until the failing run provides evidence for that change.

Use a controlled diagnostic sequence

  1. Reproduce the smallest failing test. Remove unrelated examples and keep the page state and action that trigger the failure.
  2. Mark the boundary. Log immediately before and after the suspect call, such as save_screenshot or render_base64, so you can distinguish a stalled call from earlier waiting.
  3. Enable debug output. Retain Ruby output, PhantomJS STDOUT, the full exception, and stack trace.
  4. Capture page evidence. Save a screenshot if possible and inspect page.driver.network_traffic for requests that do not complete.
  5. Test one hypothesis at a time. If a specific optional external resource appears stalled, compare a run with that URL controlled through the documented allowlist or blocklist mechanism. If an expected UI state is missing, wait for and assert that state rather than increasing the driver timeout.
  6. Repeat in the same environment. Keep the Ruby, Capybara, Poltergeist, PhantomJS, operating system, and CI image fixed while checking whether the change affects reproducibility.

Do not treat a passing run after a change as proof of root cause if several settings or dependencies changed together.

Choose between a local workaround and migration

Poltergeist’s GitHub repository was archived on November 27, 2020 and is read-only. The PhantomJS installer repository says its package is deprecated because PhantomJS development had been suspended. That maintenance posture matters if logs point to a browser-engine or driver defect: a local workaround may be practical for a stable legacy suite, but repeated failures can make a maintained alternative worth evaluating.

The Poltergeist README names Cuprite, a headless Chrome project that claims compatibility. Treat it as a candidate to test, not as a verified drop-in replacement for your suite. The available material does not provide a current compatibility matrix or a migration-effort estimate. Assess the options against your actual Ruby, Capybara, and application JavaScript versions, the reproducibility of the failure, whether it is tied to a particular resource or PhantomJS itself, maintenance needs, and the cost of recurring failures. Poltergeist README and troubleshooting guidance; PhantomJS installer project.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Make a useful bug report

If the failure is reproducible and the cause is not clear, include the information the Poltergeist project requests:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • The smallest failing test and exact reproduction steps.
  • The precise operation at which execution stops and whether it times out, crashes, or never returns.
  • Debug output, including PhantomJS output sent to STDOUT.
  • A full exception and stack trace, plus screenshots where available.
  • Poltergeist and PhantomJS versions, and operating-system name and version.

Also include the relevant request evidence and whether the behavior differs locally and in CI. Avoid presenting the historical Debian Jessie issue as your diagnosis unless your own evidence supports that comparison.

Or skip the browser setup

If your immediate goal is to capture a website image rather than diagnose a legacy test driver, ScreenshotNeo offers a screenshot API and MCP server. A single GET request returns an image or PDF; the example below saves a WebP screenshot.

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

See the ScreenshotNeo API documentation for request options. ScreenshotNeo accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents and other MCP clients. The free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots. These captures do not diagnose or repair a Capybara/Poltergeist test hang. Learn about ScreenshotNeo, or sign up for 1,000 free screenshots a month with no card.

Frequently Asked Questions

Does a hang in render_base64 prove that PhantomJS rendering is broken?

No. The delay could be caused by Capybara synchronization, page or resource loading, or Poltergeist waiting for a PhantomJS command response. The call boundary and logs are needed to distinguish them.

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

Should I increase Poltergeist’s timeout?

Only after establishing that PhantomJS is taking longer to answer a driver command. The setting measures that communication wait; it does not establish that page-side asynchronous work has completed.

Is Cuprite guaranteed to replace Poltergeist without code changes?

No compatibility matrix or migration estimate is established here. The Poltergeist README names Cuprite as a headless Chrome project claiming compatibility, so verify it against your own suite.

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.