Search code examples
ruby-on-railsphantomjspoltergeist

Can't use PhantomJS render options in Poltergeist


Apologies in advance for the newbish question, but I've spent hours on SO and elsewhere trying to figure this out, to no avail.

I'm using Poltergeist as my Capybara driver in a Ruby on Rails app, to create and save screenshots with PhantomJS, and I noticed a strange discrepancy.

Here is an example of the syntax for creating a screenshot using PhantomJS directly:

page.render('google_home.jpeg', {format: 'jpeg', quality: '100'});

I wanted to use Poltergeist to achieve the same thing -- specifically, to take a screenshot at a low resolution (to produce a thumbnail). So I tried Poltergeist's documented method:

By default, only the viewport will be rendered (the part of the page that is in view). To render the entire page, use save_screenshot('/path/to/file.png', :full => true).

Notice that the arguments are different. In Poltergeist, the method accepts a filename and a hash containing the key full, whereas in PhantomJS the method accepts a filename and a hash containing the keys format and quality. And yet, as I understand it, Poltergeist is simply passing its arguments into PhantomJS' render method anyway, so I don't understand what's going on.

Specifically, I looked into Poltergeist's source code, and traced the save_screenshot method (which is simply an alias of render) to here:

def render(path, options = {})
  check_render_options!(options)
  command 'render', path.to_s, !!options[:full], options[:selector]
end

And this is where I lose the plot. I can successfully use the Poltergeist syntax to accomplish exactly what it says will happen (setting full to true takes a screenshot of the whole page; false just captures the viewport), but I can't figure out why this works when PhantomJS itself doesn't even accept full as an argument.

Worse, I actually need to adjust the quality, but there doesn't seem to be any way to do this in Poltergeist. Is there something obvious I'm missing here?


Solution

  • You can't pass the quality option to through Poltergeist to the underlying PhantomJS script, because no options are passed in as seen in the code (CoffeeScript is transpiled into JavaScript, so the actual code is here). However, the project is open source, so you can easily add this functionality to the save_screenshot function and the underlying PhantomJS script (don't forget to create a pull request).


    When :full is false or unset, then only the viewport is rendered, because the page.clipRect property is used to crop the rendering to the current viewport size.