Skip to content

Automating your first test with Selenium and Node.js

Matthew Heusser Aug 16, 2021 Automation

If you are a Node.js programmer, then adding Selenium to your project can create executable, viewable tests that are also living documentation of how the code can perform - as easily as adding a code library.

Create an object that is a web browser, send it a command to load a web page, then send it commands to click form elements, then inspect form elements to see if they contain the text or HTML result you'd expect. The main problem is the setup – installing all the components and understanding the syntax, which is what you'll get by reading this article.

Assumptions and Requirements

The reader should be a programmer with a basic knowledge of Node.js. Even if you don't know Node.js, you could follow the instructions, copy/paste the code, and see it run. The next step, actually making the code work on your project (and, possibly, learning to code), will be outside the scope of this article.

Selenium itself requires two parts. The driver is an executable program. It is a .exe in Windows, writable and executable by your user in Linux or Mac. The library will be custom to your programming language, in this case Node.js. The library creates an object that executes the driver. The driver opens the program, then passes messages over the WebDriver Protocol down to the browser. Because the protocol runs over Internet Protocol (IP) we can use the same technology later to run tests in the cloud, or run a series of tests in parallel in the cloud.

Setting up the environment

1) Have Node.js installed. Installing Node.js will also install npm, the official package manager. You will install Selenium for Node with npm. The code below was developed with Node.js version 10.24.0 (here's how to upgrade your version of Node); Selenium requires at least version 10.0. The language does not change that quickly.

2) Download a webdriver for your browser. If you can't decide which one, Chrome is the most popular browser, so consider ChromeDriver. There is also a Firefox driver, a Microsoft Edge driver, an Internet Explorer 11 driver, and, for completeness sake, an Apple Safari driver. The drivers should be on the operating system's PATH environment variable, so they can be called without specifying its location. The WebDriver protocol is backward compatible, so there should be no compatibility issues, but these examples were tested with Selenium 3. If your application has security enabled, you may need to double-click on the driver and approve it to run unsigned on your machine before a program can use it.

3) Create the Node application to test in. If you have an actual Node application, you can create a test folder and create files named <filename>.js. If not, run npm init, then replace your package.json with this one:

{
  "name": "seleniumexample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "mocha"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "chai": "^4.3.4",
    "selenium-webdriver": "^4.0.0-beta.4"
  }
}

4) Install the Selenium Node package. With npm installed and internet available, this is a one-line command:

npm install selenium-webdriver

That is it. When this is complete, Selenium is installed. The code examples below were created with selenium-webdriver version 4.

Note: Our examples use the Mocha and Chai test frameworks, which play well together. That makes Selenium not just a web-browser-driver but an actual test tool. You can use whatever test framework you prefer, of course. Our suggestion is to pick a programming language and a test framework that is the same one you use for production coding and, perhaps, unit testing. That keeps the tests inside the loop of production, instead of something done later by someone else.  If you don't have Mocha and Chai installed, it is a two-line npm command:

npm install mocha
npm install chai

Creating (and running) your first test

First we'll create a test of the WonderProxy website itself, which will open a web page and examine the web page title. To do that, create a test subdirectory (mkdir test), then cd into it and create a file called test_titles.js. Here's a snippet of the code to use. This code uses the test framework Chai and requires the selenium-webdriver library. It contains a single test suite, "WonderProxy website", that tests to make sure the title of the website matches the expected text.

const should = require('chai').should();

const {Builder, By, until} = require('selenium-webdriver');
const {NoSuchElementError} = require('selenium-webdriver/lib/error');

describe('WonderProxy website', function () {
  // Browser based tests tend to exceed the default timeout
  // Set a longer timeout here which will be applied to all the tests:
  this.timeout(10000);

  describe('Home Page', function () {
    describe('Title', function () {
      it('should be "Localization testing with confidence - WonderProxy"', async function () {
        await runWithDriver(async function (driver) {
          await driver.get('https://wonderproxy.com');
          const title = await driver.getTitle();
          title.should.equal("Localization testing with confidence - WonderProxy");
        });
      });
    });
  });
});

In order to work the code needs to have a function called runWithDriver that creates and returns a WebDriver object. The code to do that is below. Notice the call to "chrome." To use a different browser, replace that text with "firefox", "Microsoft Edge", "Internet Explorer", or "safari."

async function runWithDriver(test) {
  let driver = await new Builder().forBrowser('chrome').build();

  try {
    await test(driver);
  } finally {
    await driver.quit();
  }
}

For your convenience, the entire project is available on Github; this file is called test_title.js. The Github project includes all the code, including a function to test the second title.

Once the code is in the right folder, run the test:

npm test

The output should look like this; notice the green checkmarks for success.

Output from npm test
Output from npm test

Now that you have the basic test, make it run against your website, and then we'll make a second test.

Creating (and running) our second test

Any file with a .js extension in the test directory will get executed when npm test runs from the command line. This one is in another file, test_serversup.js. This file opens the WonderProxy Servers page and checks the status of four specific servers: lansing, orlando, perth, and knoxville. Notice this could be used to test software or as a systems maintenance tool. (But also keep in mind that WonderProxy has an API that is probably a better fit for those scenarios!)

describe('Server status is up ', function () {
    const serverNames = ['lansing', 'orlando','perth','knoxville'];
    serverNames.forEach(serverName => {
        it(`should show "up" status for ${serverName}`, async function () {
            await runWithDriver(async function (driver) {
                await driver.get('https://wonderproxy.com/servers/status');
                const statusText = await getServerStatus(driver, serverName);
                statusText.should.include('up');
            });
        });
    });
});

Where to go next

The next thing to do is probably to learn Selenese, the command language of Selenium. The most popular use of Selenium is probably "Go to web page, type into a textbox or two, click submit, check results", so you can get pretty far with FindElement(), SendKeys(), Click(), GetCurrentURL(), GetPageSource(), GetText(), and FindElement(By.linkText(“link_text”)). Mastering a few more commands will make you a more powerful programmer – along with mastering how to find elements in CSS and XPATH. You might also want to make the browser type configurable, either with an environmental variable or from the command line.

Once you can do that, build out test coverage of new features as they are developed along with the page object pattern. Once you have several tests that can cover a reasonable part of the application in ten minutes or so, you may get tired of waiting ten minutes, so take a look at running Selenium under continuous integration.

Matthew Heusser

Among with David Hoppe

The managing director of Excelon Development, Matt Heusser writes and consults on software delivery with a focus on quality.