Introduction

I wanted to run a suite of Selenium WebDriver tests on a linux server (RedHat).  The server does not have a  GUI installed - and therefore there is no graphical web browser available for the tests. This means we have find another way to execute our tests.

PhantomJS provides a headless browser environment, which can be used with Selenium. There isn’t (at this time) a pre-built PhantomJS executable for RedHat.

Building from Source

I built my own. I did this on a CentOS distro:

1
uname -rsvo
Linux 2.6.32-504.12.2.el6.x86_64 #1 SMP Wed Mar 11 22:03:14 UTC 2015 GNU/Linux  
1
cat /etc/centos-release
CentOS release 6.6 (Final)

I made sure all the required packages were installed on the OS:

1
2
3
sudo yum -y install gcc gcc-c++ make flex bison gperf ruby \  
  openssl-devel freetype-devel fontconfig-devel libicu-devel sqlite-devel \  
  libpng-devel libjpeg-devel

I also had to install git - since that’s where the sources are:

1
sudo yum -y install git

Then I could build the binary:

1
2
3
4
git clone git://github.com/ariya/phantomjs.git phantomjs  
cd phantomjs  
git checkout 2.0  
./build.sh --jobs 1

I used jobs 1 because my CentOS environment was not especially well-endowed with cores, etc. It takes a while to build. Be patient. That gave me a binary (lib/phantomjs), which looked like this:

1
ldd bin/phantomjs  
linux-vdso.so.1 =>  (0x00007fff9f8f7000)  
libicudata.so.42 => /usr/lib64/libicudata.so.42 (0x000000388b600000)  
libssl.so.10 => /usr/lib64/libssl.so.10 (0x000000388b200000)  
libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x0000003888600000)  
libfontconfig.so.1 => /usr/lib64/libfontconfig.so.1 (0x0000003887e00000)  
libfreetype.so.6 => /usr/lib64/libfreetype.so.6 (0x00007fba25217000)  
libjpeg.so.62 => /usr/lib64/libjpeg.so.62 (0x0000003887600000)  
libpng12.so.0 => /usr/lib64/libpng12.so.0 (0x000000388ce00000)  
libz.so.1 => /lib64/libz.so.1 (0x0000003884600000)  
libicui18n.so.42 => /usr/lib64/libicui18n.so.42 (0x0000003886600000)  
libicuuc.so.42 => /usr/lib64/libicuuc.so.42 (0x0000003885e00000)  
libdl.so.2 => /lib64/libdl.so.2 (0x0000003884200000)  
librt.so.1 => /lib64/librt.so.1 (0x0000003884a00000)  
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003883e00000)  
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003886a00000)  
libm.so.6 => /lib64/libm.so.6 (0x0000003884e00000)  
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003885600000)  
libc.so.6 => /lib64/libc.so.6 (0x0000003883a00000)  
/lib64/ld-linux-x86-64.so.2 (0x0000003883600000)  
libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x0000003889a00000)  
libkrb5.so.3 => /lib64/libkrb5.so.3 (0x0000003889200000)  
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x0000003886e00000)  
libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x0000003889600000)  
libexpat.so.1 => /lib64/libexpat.so.1 (0x000000388aa00000)  
libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x0000003888e00000)  
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x0000003887200000)  
libresolv.so.2 => /lib64/libresolv.so.2 (0x0000003885a00000)  
libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003885200000)  
1
bin/phantomjs --version   
2.0.1-development

I then moved the binary to a RedHat server, where I actually needed to use it. It worked!

A big thank you to this site: http://phantomjs.org/build.html. Impossible without the notes provided there.

Using the Binary

Here is my Selenium script:

1
2
3
4
5
6
7
#!/bin/bash  

stamp=$(date +"%Y%m%d_%H%M")  

java -jar SeleniumForMyProject.jar config.properties \  
  > results/results_${stamp}.txt \  
  2> results/errors_${stamp}.txt  

I have the following in a config file:

# Path to the phantomjs executable  
phantomjs=/opt/selenium/phantomjs  

#  
# Command line args needed by phantomjs. Run the command  
# ./phantomjs --help  
# to see a list of available args.  
#  
# Use this on the linux servers:  
# DEV SSL certs:  
#ssl_certs_path=--ssl-certificates-path=/opt/certs  
# QA SSL certs:  
ssl_certs_path=--ignore-ssl-errors=true  

In my Java program I have the PhantomJS Driver JAR (from Selenium):

1
2
import org.openqa.selenium.phantomjs.PhantomJSDriver;  
import org.openqa.selenium.phantomjs.PhantomJSDriverService;  

And this in the main method:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
WebDriver driver = null;  
if (mode.equalsIgnoreCase("headless")) {  

    String phantomjsPath = props.getProperty("phantomjs");  
    String sslCertsPath = props.getProperty("ssl_certs_path");  

    DesiredCapabilities caps = new DesiredCapabilities();  
    caps.setCapability(PhantomJSDriverService  
            .PHANTOMJS_EXECUTABLE_PATH_PROPERTY, phantomjsPath);  
    caps.setCapability(CapabilityType.TAKES_SCREENSHOT, true);  
    if (sslCertsPath != null) {  
        String[] phantomJsArgs = {sslCertsPath};  
        caps.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS,  
                phantomJsArgs);  
    }  
    driver = new PhantomJSDriver(caps);  

 } else {  
    driver = new FirefoxDriver();  
}