PhantomJS – Screen capture of auth protected page (& keep sessions)

Recently I need to get a screen capture of pages that are auth protected. I realized PhantomJS has a file instance with which you can read/write cookies. Usually PhantomJS performs one page so that it seems to make it hard to create multiple steps process. Of course there’re examples:

http://code-epicenter.com/how-to-login-amazon-using-phantomjs-working-example/

But opening a new page is a different story. Eventually I figured out using the global PhantomJS state. And the following is result:

/**
 * The purpose of the source code is to get a screen capture of a page
 * of auth protected page by running PhantomJS command line.
 * It performs form authentition if the session is not alive.
 * If cookie file exists, it uses the session. 
 * NOTE: I haven't added any arguments for this action.
 */
var webpage = require('webpage');
var fs = require('fs');
var system = require('system');
var page, loginpage;

// Phantomjs global config
phantom.cookiesEnabled = true;
phantom.javascriptEnabled = true;

// Variables settings
var cookie = 'path/to/cookie.json'; // Cookie file location
var max_login = 3; // Maximum login attempt
var login_attempt = 0; // Login attempt count
var login_url = 'https://test.com/login'; // Login page URL
var logout_url = 'https://test.com/logout'; // Logout page URL
var page_url = 'https://test.com/protected'; // Page to capture

/**
 * Add cookies before opening the page
 */
function addCookieInfo() {
  Array.prototype.forEach.call(JSON.parse(fs.read(cookie)), function(param) {
    phantom.addCookie(param);
  });
}

/**
 * Run login page and try form authentication
 */
function runLogin() {
 if (loginPage === 'object') {
    loginPage.close();
  }
  if (loginAttempt < 2) {
    system.stderr.writeLine('Reached max login attempt count.');
    phantom.exit();
  }
  else {
    loginAttempt++;
    loginPage = webPage.create();
    loginPage.open(loginUrl, function(status) {
      if (status === "success") {
        system.stderr.writeLine('form started');
        loginPage.evaluate(function() {
          document.getElementById("name").value = "username";
          document.getElementById("pass").value = "password";
          document.getElementById("login-form").submit();
        });     
        loginPage.onLoadFinished = function(status) { 
          if (status === 'success') {
            if (!phantom.state) {
              phantom.state = 'no-session';
            }
            if (phantom.state === 'no-session') {
              fs.write(cookie, JSON.stringify(phantom.cookies), "w");
              phantom.state = 'run-state';
              setTimeout(runPage, 500);
            }
          }
        };
      }
    });
  }
}

/**
 * Run page to get screen capture
 */
function runPage() {
  if (page === 'object') {
    page.close();
  } 
  page = webPage.create();
  addCookieInfo();
  page.open(url, function(status) {
    if (status !== 'success') {
      system.stderr.writeLine('Unsuccessful loading of: ' + url + ' (status=' + status + ').');
      system.stderr.writeLine('Content: ' + page.content);
      if (page.content) {
        fs.write(outfile, "error", 'w');
      }
      phantom.exit();
    }
    else {
      if (phantom.state === 'run-state') {
        window.setTimeout(function() {
          if (thumbnailFile) {
            page.render(thumbnailFile);
          }
          if (page.content) {
            fs.write(outfile, page.content, 'w');
          }
          page.render("page_service.png");
          phantom.exit();
        }, timeout);
      }

    }   
  });

  page.onResourceReceived = function(response) {  
    if (response.stage == 'end'){
      return;
    }
    if (response.url == url) {
      if (response.status == 403) {
        phantom.state = 'no-session';
      }
      else {
        phantom.state = 'run-state';
        response.headers.forEach(function(header){
          system.stdout.writeLine('HEADER:' + header.name + '=' + header.value);
        });
        system.stdout.writeLine('STATUS:' + response.status);
        system.stdout.writeLine('STATUSTEXT:' + response.statusText);
        system.stdout.writeLine('CONTENTTYPE:' + response.contentType);
      }
    }
  };
  /**
   * onLoadFinished callback
   * Check the status of login page and set state
   * If state is no-session and page is success, write cookies.
   */
  page.onLoadFinished = function(status) {
    if (status === 'success') {
      if (phantom.state == 'no-session') {
        removeCookieFile();
        setTimeout(runLogin, 500);
      }
    }
  };
}

// Main
phantom.state = 'no-state';
if (!fs.isFile(cookie)) {
  runLogin();
}
else {
  runPage();
}

In order to run code, make the following steps:

  1. Download and save phantomjs
  2. Copy the source code, and save it to a folder
  3. On command line, navigate to the file and run the following:
 $ /path/to/bin/phantomjs /path/to/sessions.js

Leave a comment