Write scripted browsers

Use New Relic Synthetics' scripted monitors to go beyond ensuring that your website is available, to ensuring that critical business transactions are operating correctly.

Scripted browsers use a JavaScript-like scripting language to drive a Selenium-powered Google Chrome browser. This browser is not emulated, but a real, fully virtualized Google Chrome browser. For example, a scripted browser can visit your website, search for a specific word, wait for the result to load, then click a specific result link.

To view and share scripted browser examples, visit the Synthetics scripts section of New Relic's Explorers Hub.

Scripted browser overview

Scripted monitors are powered by Selenium WebDriverJS. Using a convenient API, you can create scripts to monitor your website with real browser activity. Each time your script runs, Synthetics creates a Selenium-driven Google Chrome browser that navigates your website and follows each step of the script. Synthetics includes an IDE-style script editor which suggests functions, locators, and other elements to simplify scripting.

This document begins with the basic scripting action of visiting a URL, then describes how to locate and interact with page elements. Finally, you can wait for page elements to ensure a specific page element is present before your script attempts to interact with it.

For a list of all available functions, see Scripted browser reference.

After a maximum run time of three minutes, Synthetics manually stops the script.

Visit a URL

All scripts begin by specifying which URL the monitor should navigate to. To specify a URL, call $browser.get("url"):

$browser.get("https://mywebsite.com");

Sequence actions

Because WebDriverJS is asynchronous, scripting actions can sometimes execute out of order. For example, in a script containing three functions, the third function might execute before the second function. To force script actions to execute in order, wrap each action in a then(function(){}) call:

$browser.get("https://my-website.com").then(function(){
    return $browser.findElement($driver.By.linkText("Configuration Panel"));
});

To connect multiple actions in sequence, wrap each action in a then(function(){}) call, and chain the calls together:

$browser.get("https://my-website.com").then(function(){
    return $browser.findElement($driver.By.linkText("Configuration Panel"));
}).then(function(){
    return $browser.findElement($driver.By.partialLinkText("Configuration Pa"));
});

Locate elements

Once you have specified a URL to monitor, you will usually want to locate a particular element on the page. Locating an element verifies its presence on the page, and also allows you to interact with page elements.

You can locate elements by their class, id, link text, name or even XPath. To find these attributes, use your browser's developer tools or view your website's source code. For a list of all locator functions, see Locators: Find page elements.

Locate by CSS class

Locate an element by its HTML class (for example, class="button"). A class is usually specified for CSS styling. When locating an element by class, the monitor will select the first element on the page that has that class:

$browser.findElement($driver.By.className("button"));
Locate by HTML ID

Locate an element by its exact HTML id (for example, id="edit-submit"). This is a very straightforward way to locate page elements, but be careful to specify an id that is not likely to change.

$browser.findElement($driver.By.id("edit-submit"));

For an example of locating an element by its id, see Search a website.

Locate an element by its displayed link text. For example, Your Link Text Here in <a href="http://example.com>your link text here</a>. You can locate by the exact link text ($driver.By.linkText) or by partial match ($driver.By.partialLinkText):

$browser.findElement($driver.By.linkText(Configuration Panel"));
$browser.findElement($driver.By.partialLinkText("Configuration Pa"));

For an example of locating a link by its link text, see Navigate to a link.

Locate by name

Locate an element by its exact HTML name (for example, name="search-query-field"). This is most commonly used with input fields such as a search box:

$browser.findElement($driver.By.name("search-query-field"));

For an example of locating an element by its name, see Wait for a page element.

Locate by XPath

For more complex page structures, you can use XPath to locate the target element.

$browser.findElement($driver.By.xpath("//input[@placeholder = 'search-query-field']"));

To quickly find the XPath for a particular element, use the Google Chrome developer tools:

  1. In Chrome, navigate to the target website.
  2. Right-click the target element, then select Inspect element.
  3. From the Developer Tools panel that opens automatically, look for the highlighted target element.
  4. Right-click the target element, then select Copy XPath.

Use this XPath in scripts. If your website changes frequently, this method may cause your monitor to fail when your page structure changes.

Interact with elements

Because a scripted monitor drives a real, Selenium-powered Google Chrome browser, scripted monitors can interact with page elements in the same way a user would. For example, the monitor can click a link, enter text in a search box, and so on. For a list of available actions, see ActionSequence: Link multiple actions.

First, locate the page element, then call an interaction function:

Click page elements

To click on a link or other page element, locate the element and call the click() function:

$browser.findElement($driver.By.linkText("Configuration Panel")).click();
$browser.findElement($driver.By.className("config-panel-02")).click();

For an example of clicking a located element, see Search a website.

You can control the mouse in other ways with the doubleClick(), dragAndDrop(), mouseDown, mouseUp, and mouseMove functions.

Enter text

To enter text in a field, locate the field and call the sendKeys() function:

$browser.findElement($driver.By.name("search-query-field")).sendKeys("EXAMPLE USER NAME");
$browser.findElement($driver.By.id("search-q-box")).sendKeys("EXAMPLE USER NAME");

Some fields may have default text in them. Clear these fields before sending text to them:

$browser.findElement($driver.By.name("search-query-field")).clear();
$browser.findElement($driver.By.id("search-q-box")).clear();

For an example of entering text in a field, see Log in to a website.

You can add modifier keys (such as ALT and SHIFT) with the keyDown() and keyUp() functions.

Waiting and timeouts

Large page elements, such as images or complex dynamic content, can take a long time to load. This can cause your script to fail when the monitor attempts to interact with or locate an element that hasn't been loaded yet.

To avoid these issues, you can set wait conditions that will pause the script until the specified page element is present. For a list of conditions, see Conditions: Pause and wait for conditions.

Wait for page title

Instruct the monitor to wait for the page title to match a certain value. This ensures that the browser has at least received some data from the target page. To wait for page title, specify an expected title and a timeout value in milliseconds:

//Call the wait function
$browser.wait(function() {
//Tell the monitor to get the page title, then run a function on that title.
  return $browser.getTitle().then(function(title) {
//Specify the expected page title.
    return title === "Your Page Title Here";
    });
//If the condition is not satisfied within a timeout of 1000 milliseconds (1 second), proceed anyway.
}, 1000);

For an example of waiting for page title, see Wait for a page to load.

Wait for a specific element

Instruct the monitor to wait for a page element to be present. This is useful when an element your script depends on takes a long time to load, or simply to ensure that a page element is present before your script clicks on it.

You can use any of the locate functions with the wait function below. Use your desired function instead of the $driver.By.linkText function used below:

//Tell the monitor to wait up to 7,500 milliseconds (7.5 seconds) for a link whose text is `Your Link Text Here`.
$browser.waitForAndFindElement($driver.By.linkText("Your Link Text Here"), 7500);

For an example of waiting for a specific page element to load, see Wait for a page element.

You can also sequence actions manually. While waiting ensures that a page element is present before the script executes, sequencing actions forces each script element to execute in turn (instead of concurrently).

Unblock analytics services

Synthetics blocks popular analytics services' scripts from running by default. You can allow scripts to run for a specified service(s). This allows the service's scripts to run and collect data like it would for a real user.

//Allow Google Analytics scripts to run
$browser.addHostnameToWhitelist(hostnameArr: ['google-analytics.com']);

//Visit https://my-website.com
$browser.get('https://my-website.com');

Log script results

You can also manually log monitor results to the script log. Use logging to troubleshoot a script: By including a log function along with each key step in your script, you can discover which step of your script is failing.

Log static text

To log a line of static text, call console.log():

//Send `That's one small step for man.` to the console log.
console.log('That\'s one small step for man.');

This results in the output:

// ----------------------------------- Console log
That's one small step for man.
Pass a variable to the log function

In addition to logging static text, you can also pass variables to console.log():

//Declare the variable `WEBSITE_URL`
var assert = require('assert'),
  WEBSITE_URL = 'https://my-website.com/';

console.log('That's one small step for man.');
//Load the website specified in `WEBSITE_URL`
$browser.get(WEBSITE_URL);
//Log our success to the console
console.log('One giant leap for', WEBSITE_URL);

This results in the output:

// ----------------------------------- Console log
That's one small step for man.
One giant leap for https://my-website.com/

Import optional modules

You can also import many popular Node.js modules to enhance your test suite, automate the insertion of test data, and simplify complex functions. For more information, see Importing Node.js modules.

For more help

Recommendations for learning more: