Submitting a search (or other HTML) form

When I want to monitor an application that includes an HTML form, my first impulse is to write a script that completes the form fields and clicks the Submit button. It may be much simpler, however, to send a request directly to the form’s target.

Consider the following search form for a travel web site:

Say you want to write a script that searches for available flights two weeks from today. You could locate each form field, populate it with the desired value, and click the Search button:

$browser.get('https://travel.newrelic.com/')
  .then(function() {
    $browser.findElement($driver.By.id('flight-origin')).sendKeys('PDX');
  })
  .then(function() {
    $browser.findElement($driver.By.id('flight-destination')).sendKeys('NYC');
  })
  //
  // Repeat for other fields
  //
  .then(function() {
    $browser.findElement($driver.By.id('search-button')).click();
  })

But what actually happens when you click the Search button? Most HTML forms issue a GET or POST to a URL, which parses the parameters and performs the search. Why not skip the form and submit the search request directly to the target? Because New Relic Synthetics provides a fully-functional node.js environment, you can import node packages and implement complex logic; you’re not limited to interacting with a browser:

var assert = require('assert');
var qs = require('querystring');

// Set travel date = today + 14 days
var travelDate = addDays(new Date(), 14);

// Modify search params as desired
var searchParams = {
  origin : 'PDX', 
  destination : 'NYC', 
  flexible : 'true', 
  when : yyyymmdd(travelDate) ,
  passengers : '2'
};

// Convert search params to query string
var queryString = qs.stringify(searchParams);

// Do search
$browser.get('https://travel.newrelic.com/search?' + queryString)
  .then(function() {
    // Wait up to 30 seconds for search results
    return $browser.waitForAndFindElement($driver.By.id('result-count'), 30000);
  });

// Helper functions
function addDays(startDate, numberOfDays) {
  return new Date(
    startDate.getFullYear(),
    startDate.getMonth(),
    startDate.getDate() + numberOfDays,
    startDate.getHours(),
    startDate.getMinutes(),
    startDate.getSeconds());
}

function yyyymmdd(dateIn) {
  var yyyy = dateIn.getFullYear();
  var mm = dateIn.getMonth() + 1; // getMonth() is zero-based
  var dd  = dateIn.getDate();
  return String(10000 * yyyy + 100 * mm + dd); // Leading zeros for mm and dd
}
4 Likes

Great tip there @philweber