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:
- Node and npm installed on your computer
- A basic knowledge of JavaScript
Setting up our test environment
To begin, create a folder for this project:
|
|
Navigate into the folder and initialize npm
in your directory:
|
|
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:
|
|
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:
|
|
chromedriver: ChromeDriver is a standalone server, or separate executable, that Selenium WebDriver uses to control Chrome.
Run the following command to install the package:
|
|
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:
|
|
The test above automates a pretty straightforward flow using Selenium. Here is an explanation of the test flow:
-
Open the chrome browser window:
1 2
// 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 fromselenium-webdriver
. If you want to use another browser, such as Firefox, pass the browser name as a parameter to theforBrowser(‘firefox’)
function. -
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.
1 2
// go to example website await driver.get("http://example.com/");
-
Close the Browser
Once the Reflect website runs successfully, close the browser window.
1 2
// 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:
1
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: :
- Visit a page on your app, e.g. Google
- Find and Query a search element on the page
- Interact with the search element by clicking enter
- Verify that the application is in the correct state after the interaction.
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:
|
|
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.
-
Visit a page in your app e.g Google:
Navigate to Google
1
await driver.get("http://www.google.com/");
-
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 thename
attribute isq
. 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 propertiesname
to get the DOM element withname = ‘q’
:1
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. -
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:1
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. Thewait(condition, timeout, message)
function waits for a condition to evaluate to a set value. The parameter conditionuntil.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 theuntil
class and thetitleIs
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:
1 2 3 4 5 6 7
... 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:
|
|
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.