End-to-end Testing
How-tos & Guides
8 min read

Writing end-to-end tests in Node.js using Selenium

This tutorial demonstrates how to write end-to-end tests in Node.js using Selenium. At the end of this tutorial, you will learn how to set up Selenium WebDriver with Node and have it run tests in the Chrome web browser.

David Adeneye
Published July 22, 2022

The importance of software testing cannot be overstated in software engineering, and it is even more crucial in front-end development. Testing your application with functional and unit tests alone may not guarantee its correctness. In this case, end-to-end (E2E) testing can be very helpful, as it can replicate user behavior in your application to guarantee that it functions correctly. Usually, this process involves writing a script to simulate users navigating through an application, testing certain features and behavior along the way.

In Node.js development, you can use Selenium to automate your E2E tests. This would enable you to test new features and address bug fixes, all while ensuring that the user interface of your application is still functional.

What is Selenium?

Selenium is a suite of tools commonly used in the testing ecosystem for cross-browser testing. It supports all major web browsers, making it one of the most widely used for automating web application testing. Selenium WebDriver is the underlying set of APIs and associated language bindings that allow Selenium (and other WebDriver-compatible tools) to communicate with web browsers in a standard way.

Prerequisites

Here are the prerequisites you’ll need to follow along with this tutorial:

Setting up our test environment

To begin, create a folder for this project:

mkdir e2e-selenium-node

Navigate into the folder and initialize npm in your directory:

cd e2e-selenium-node
npm init

Note: Running this command will present a series of prompts. I’ve opted to add a custom description and license for this project, but the defaults should work fine and you can hit ENTER to answer each prompt.

The command should now generate a package.json file for you in your current directory. This config file will manage your project dependencies and can be customized as we continue testing.

Below is a snapshot of what it will look like initially:

{
  "name": "e2e-selenium-node",
  "version": "1.0.0",
  "description": "end-to-end test in node using selenium",
  "main": "index.js",
  "scripts": {
    "test": "test"
  },
  "author": "Reflect run",
  "license": "ISC"
}

Node.js & Selenium configuration

After setting up the project, the next step is to install the Selenium Webdriver and ChromeDriver packages, as shown below:

selenium-wedriver: Selenium Webdriver is a browser automation library. It can be used to test web applications, or for any tasks that require automating interactions within a web browser.

To install the package, run the following command:

npm install selenium-webdriver

chromedriver: ChromeDriver is a standalone server, or separate executable, that Selenium WebDriver uses to control Chrome.

Run the following command to install the package:

npm install chromedriver

Note: In this tutorial, we use Chrome as the browser to automate. If you would like to use other browsers, you can do so using this guide.

After installing the chromedriver package, navigate to chromedriver.chromium.org/downloads to install the latest ChromeDriver version. Unzip the file, copy the executable to a folder location of your choice, and copy its file path.

For both Windows and macOS users, if you don’t know how to add a file path, follow this guide here.

Create your first tests

To verify that we’ve successfully set up Node.js and Selenium, let’s run a simple test. Create a test file inside your root folder named test_file.js and add the following test:

// import chromedriver so that selenium can by itself open a chrome driver
require("chromedriver");

// import this class from selenium
const { Builder } = require("selenium-webdriver");

(async function openChromeTest() {
  // open chrome browser
  let driver = await new Builder().forBrowser("chrome").build();

  try {
    // go to example website
    await driver.get("https://example.com/");
  } finally {
    // close the chrome browser
    await driver.quit();
  }
})();

The test above automates a pretty straightforward flow using Selenium. Here is an explanation of the test flow:

  1. Open the chrome browser window:

    // open chrome browser
    let driver = await new Builder().forBrowser("chrome").build();
    

    Here, we instantiate a new Chrome web driver to open a Chrome browser using the Builder class that we imported from selenium-webdriver. If you want to use another browser, such as Firefox, pass the browser name as a parameter to the forBrowser(‘firefox’) function.

  2. Go to Reflect website

    For the purpose of this test, when the browser opens, we’ll want it to navigate to a specific website automatically. For instance, let’s set it to navigate to an example website.

    // go to example website
    await driver.get("http://example.com/");
    
  3. Close the Browser

    Once the Reflect website runs successfully, close the browser window.

    // close the chrome browser
    await driver.quit();
    

    You can read more about all the possible classes and available functions in the documentation.

    Now, we should have a script that automatically opens Chrome and navigates to the example website. To run the test, use the command below:

    node test_file.js
    

    Your snapshot should look like this:

Writing Selenium end-to-end tests

In this section, we will model a user story and write an e2e test for it. We’ll write tests to assert that a user can successfully perform some specific actions on Google. As this is a tutorial, we will be using Selenium to test a public website, although you’d normally use it to test your own application.

To write an E2E test for a specific user story, we will simulate actions throughout the test as though we are a user, and ultimately assert that the resulting application state matches our expectations. Our test will perform the following actions: :

Creating your test file

Navigate into the project folder that we created earlier. Add a new test file named e2e_test.js in the root of the project folder, and add the following tests:

// import chromedriver so that selenium can by itself open a chrome driver

require("chromedriver");

// import this classes from selenium
const { Builder, By, Key, until } = require("selenium-webdriver");

var assert = require("assert");

// describe test
describe("Perform Search", function () {
  // it describes expected behaviour when user perfroms search on google
  it("A user performs a Search on Google", async function () {
    // open chrome browser
    let driver = await new Builder().forBrowser("chrome").build();
    try {
      // navigate to to this website
      await driver.get("http://www.google.com/");

      // find a search box element with name ='q'
      await driver.findElement(By.name("q"));

      // type 'reflect run' in the search box then press ENTER Key
      await driver.findElement(By.name("q")).sendKeys("Reflect run", Key.RETURN);

      /* wait for the page to load the search result untill the page
        title is equal to `Reflect run - Google Search */
      await driver.wait(until.titleIs("Reflect run - Google Search"), 1000);

      // Get the pagetitle of the current Page
      let pageTitle = await driver.getTitle();

      // assert that the current pageTitle is equal to 'Reflect run - Google Search'
      assert.strictEqual(pageTitle, "Reflect run - Google Search");
      if (pageTitle) {
        console.log("Page Title:", pageTitle);
      }
    } finally {
      // close the browser
      await driver.quit();
    }
  });
});

Now, we will examine the test above to see if it matches the user story we defined earlier while explaining how we used Selenium to automate this.

  1. Visit a page in your app e.g Google:

    Navigate to Google

    await driver.get("http://www.google.com/");
    
  2. Find and Query a search element on the page:

    To automate typing a search word into the search box, we need to know the DOM element of the search
    input. When you inspect the google source code, you will notice that the name attribute is q. We
    can then use this attribute to get the DOM input element:

    The By class provided by Selenium enables us to locate DOM elements on the page, then we make use of the properties name to get the DOM element with name = ‘q’:

    await driver.findElement(By.name("q"));
    

    You can target the DOM element with other properties aside from name. Read more about possible
    functions and properties in the Selenium documentation.

  3. Interact with the element by clicking enter

    Next, we’ll mimic a user scenario by typing the search query reflect run in the search box, and then pressing the Enter key:

    await driver.findElement(By.name("q")).sendKeys("Reflect run", Key.RETURN);
    

    We will wait for the page to load the search result until the current page title is equal to Reflect run - Google Search. To do this, we’ll make use of the wait function in Selenium. The wait(condition, timeout, message) function waits for a condition to evaluate to a set value. The parameter condition until.titleIs('Reflect run - Google Search') creates a condition that will wait for the current page title to match the given value ('Reflect run - Google Search'). You can learn more about the until class and the titleIs function, as well as other available functions in the documentation.

    Once we have asserted that the current page title is equal to ‘Reflect run - Google Search’, we’ll print the current page title to the console:

    ...
    let pageTitle = await driver.getTitle();
    assert.equal(pageTitle, "Reflect run - Google Search");
    
    if (pageTitle) {
      console.log("Page Title:", pageTitle);
    }
    

We now have a script that implements our user story. Run the test file above using the command below:

npx mocha --no-timeouts 'e2e_test.js'

This command will automatically open Chrome, and swiftly navigate to the specified website google. com. Below is a snapshot of what you should get:

Conclusion

In this tutorial, we learned how to use Selenium to automate end-to-end testing in Node.js development. You should now feel familiar with all of the prerequisites needed to set up Selenium with Node.js and run your tests in Chrome.

Try Reflect: A modern end-to-end testing platform

Reflect is a no-code testing platform that lets you build and run tests across all popular browsers. Using a cloud testing platform like Reflect allows you run automated tests in real browsers without having to stand-up and maintain your own testing infrastructure yourself.

Try it for free.

Get started with Reflect today

Create your first test in 2 minutes, no installation or setup required. Accelerate your testing efforts with fast and maintainable test suites without writing a line of code.

Copyright © 2022 Reflect Software Inc. All Rights Reserved.