Sunday, October 19, 2014

PhantomJS and SSL

After re-configuring everything this week to avoid the POODLE SSLv3 apocalypse, all of our Geb tests ended up broken when run via GhostDriver (which uses PhantomJS, the headless WebKit browser). Turns out that by default, PhantomJS (up to and including version 1.9.7) tries to connect to any https resource via SSLv3 only — so it'll fail with any server updated to no longer support SSLv3.

Fortunately, it just takes a command-line flag to allow PhantomJS to try TLS as well: --ssl-protocol=ANY. Alternatively, instead of ANY, you can require PhantomJS to use a specific version of TLS: TLSv1, TLSv1.1, or TLSv1.2 (all these values are case insensitive).

To pass command-line flags to PhantomJS with Geb, you have to set the phantomjs.cli.args (aka PhantomJSDriverService.PHANTOMJS_CLI_ARGS) capability on the PhantomJSDriver driver instance. So I adjusted the GebConfig.groovy file for various projects to look more or less like this (where we also have the ignore-ssl-errors flag set so we can run our tests against internal dev servers with self-signed certificates):

import org.openqa.selenium.Dimension
import org.openqa.selenium.phantomjs.PhantomJSDriver
import org.openqa.selenium.remote.DesiredCapabilities

driver = {
    def d = new PhantomJSDriver(new DesiredCapabilities(
        'phantomjs.cli.args': [
            '--ignore-ssl-errors=true',
            '--ssl-protocol=any',
        ] as String[],
    ))
    d.manage().window().size = new Dimension(1028, 768)
    return d
}