Automating Your Front-End Application Testing With Selenium

Testing your front-end application shouldn’t be that hard

Oyetoke Tobiloba Emmanuel
10 min readApr 24, 2020

Testing is an important phase of software and web development, as it helps in identifying any bugs, errors, and missing requirements easily and quickly. Testing usually consists of a gradual and repetitive process in order to be able to test every part of the system. This usually takes more time, and automating these processes would help you identify bugs faster and ship products faster.

With this, we can say front-end testing is simply the process of testing the function of the application user interface, making sure the front end of the application is reacting as it’s supposed to. This means elements on the screen should work as specified — so colors, fonts, and element sizes should match the design requirements.

Automating your front-end testing with Selenium is one of the most effective ways to test your front-end application. It provides multiple methods for automating common interactions a user would perform through a browser instead of through web applications.

What’s Selenium — And Why Use It?

Selenium is a popular automation tool for automating browsers. Selenium can also be used as a testing framework to automate your test processes on your front-end applications. It makes browsers execute commands according to your scenario and steps.

You can run manual and repetitive tasks very quickly and efficiently using Selenium.

It’s an open-source testing solution, which means it’s free and supported by the open-source community, which provides updates frequently, including bug fixes and resources.

Selenium has a suite of tools that includes: Selenium IDE, Selenium WebDriver, Selenium Grid, and Selenium Standalone Server.

Selenium can be run on Windows, Linux, and macOS platforms, which is a good thing for developers who want to use it across platforms.

One of the good things about Selenium is developers can write tests for Selenium WebDriver in any of the programming languages supported by the Selenium project, including Java, C#, Ruby, Python, and JavaScript (named Bindings). With TestCraft, you can write and run Selenium tests without writing a single piece of code.

Let’s Set Things Up

In this article, we’ll go through a step-by-step guide on how to automate testing a simple Svelte to-do front-end application using Node and Selenium.

We’ll be using a Svelte to-do app I found on GitHub, which was written by Ayooluwa Isaiah. The first thing you need to do is get the Svelte to-do app running on your system. You can find and clone the repo on GitHub by going here.

If you don’t want to spend time setting this up, you can use the hosted version here.

You can set it up by cloning the repo and following the setup steps:

git clone https://github.com/freshman-tech/svelte-todo-app
cd svelte-todo-app
npm install
npm run dev

If the setup goes well, you should be able to navigate to http://localhost:5000 and see this:

You can play around with it to make sure you can add a task and remove a task.

Once that’s done, let’s set up our Selenium and Node testing.

Setting up Selenium for our Node environment

There are two ways to run Selenium testing — you can either run it locally (which will require you to set up a web driver) or remotely (which will require Selenium Grid or third-party service and may require getting API Keys), or you can use a tool like TestCraft to run a test with or without a single bit of code.

In other to work with Selenium, you need to download the right WebDriver supported by the browser you’re using to test. Different browsers require different drivers to allow WebDriver to communicate with and control them. You can see platforms supported by Selenium for more information on where to get browser drivers from.

To get started, we need to start by creating a new npm project and installing the required dependencies to get things working.

mkdir svelte-todo-testing && cd svelte-todo-testing
npm init -y
npm install selenium-webdriver
npm install --save-dev mocha

We installed Mocha as a dev dependency since we’ll be using it as our test runner.

Like I mentioned earlier, there are two ways to set up Selenium testing — either running it locally or remotely. I have written a comprehensive tutorial on how to do just that. You can read it over here.

To make things easier, head over to the Geckodriver (for Firefox) or ChromeDriver driver page, and download the latest driver for your OS. Unzip its content into somewhere easy to navigate to, like the root of your home user directory.

Then the next thing is to add the ChromeDriver or the geckodriver’s location to your system PATH variable, and it should be an absolute path from the root of your home directory to the directory containing the drivers.

To set your PATH in Linux/macOS, you need to add the export command to the terminal profile you’re using.

#Add WebDriver browser drivers to PATH
#export PATH=$PATH:<driver_path>
export PATH=$PATH:/home/toby

Once that's done, you can confirm if it all works well by running the name of the driver in your terminal or console, and you should get something like the following:

Tada! Our ChromeDriver is working, and we can now proceed to write tests.

Writing Our First Test

Once everything has been successfully set up, we need to start writing our tests for the to-do app.

Let's see how to write our first to-do test. In the npm project directory, we created earlier, create a new file called first_test.js. Now ensure you’re running the svelte-todo-app running locally simultaneously, or use the live version here.

const webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
const driver = new webdriver.Builder()
.forBrowser('chrome')
.build();
driver.get('http://localhost:5000').then(function(){
driver.findElement(webdriver.By.className('js-todo-input')).sendKeys('Build App\n').then(function(){
driver.getPageSource().then(source=>{
// console.log(source)
if(source.includes("Build App")){
console.log("Test Passed!")
}else{
console.log("Test Failed!")
}
})
});
});

What we did above:

  • We imported the selenium-webdriver library and the methods we’ll be using
  • We create an instance of the chromedriver web driver using the Builder method from the library we imported
  • Next, we navigated to the web app URL using driver.get()
  • Next, we use driver.findElement() to find the input element on the page using its class name (js-todo-input) and typing in our task Build App
  • Then we get the current page source and check if it contains our task Build App

To run the test:

node first_test.js

If all goes well, we should be able to see Test Passed printed out in our terminal and also something like below:

Tada! We’ve successfully written and run our first test to test if we can add a task to the web application.

Writing Our Selenium Tests

The next thing to do is to test if we can:

  • Mark a test complete
  • Delete a task

In order to mark a task complete in the Svelte app, you need to click on the big, round checkbox.

Below is the DOM structure of a completed task:

frontend testing with selenium

A completed task has a done class in its list parent element.

To test this process, we’d need to:

  • Find the checkbox element using its attribute like className with the findElement method and click on it
  • Now to confirm if the task is completed, we need to get the list element of the task and check if it has the done className in its class attributes
driver.get('http://svelte3-todo.surge.sh/').then(function(){
driver.findElement(webdriver.By.className('js-todo-input')).sendKeys('Build App\n').then(function(){
console.log("Adding A Task: ")
driver.getPageSource().then(source=>{
// console.log(source)
if(source.includes("Build App")){
console.log("Test Passed!")
}else{
console.log("Test Failed!")
}
})
driver.findElement(webdriver.By.className("tick")).click().then(function(){
console.log("Marking Task Complete: ")
driver.findElement(webdriver.By.className("todo-item")).getAttribute("class").then(function(className){
if(className.includes("done")){
console.log("Test Passed!")
}else{
console.log("Test Failed!")
}
})
});

});
});

If you run the above successfully, you should see something like the following in the command line:

To delete a task, you’d need to click on the round, reddish button on the right side of the task. Clicking on that button removes the task from the list of tasks.

To test this process, we’d need to:

  • Find the delete button using the findElement method with the element class attributes and initiate a click event
  • Then we confirm if the task is successfully removed by getting the current page source and seeing if we can find the task

If the above code ran successfully, you should get the same as the following image:

Tada! We’ve successfully written Selenium tests to test:

  • Adding a task
  • Marking a task complete
  • Deleting a task

Using a Test Framework: Mocha and Selenium

Using a test runner or framework helps in designing test use cases and really makes your testing process efficient and fast. One of the most popular test frameworks is Mocha.

Mocha is a feature-rich JavaScript test framework that runs on the Node environment and in the browser. Mocha can run both asynchronous and synchronous code in order. Test cases are created using thedescribe() and it() methods — the former is used to provide a structure by allowing the placement of various test cases into logical groups, while the latter is where the tests are written.

In testing, there will be a need for an assertion library in order to run actual tests and to compare results and the expected outputs. Assertion libraries are used to verify whether the condition given to it is true or false. It’s like a runtime mechanism that can be used to verify assumptions made by the program and to print a diagnostic message if this assumption is false.

Node.js comes with a built-in assertion library known as assert.js and also has a rich alternative assertion library in Chai.

In this article, we’ll be using assert.js for the assertion library, and we’ll write three different test case to:

  • Add a task
  • Mark a task complete
  • Delete a task

Now create the mocha_test.js file, and let’s set up a basic boilerplate for our Selenium and Mocha testing:

var assert = require('assert')
const webdriver = require('selenium-webdriver');
describe('Svelte Todo App Test', function() {
var driver;
before(function() {
driver = new webdriver.Builder()
.forBrowser('chrome')
.build();
});
it('add a task', function() {

})

it('mark a task complete', function() {
})

it('delete a task', function() {
}) after(function() { driver.quit(); });})

Now we have a boilerplate we can work with our test cases.

The first test case to look at is adding a task. We have done this earlier — we can just refactor the same code to be:

it('add a task', function() {
driver.get('http://svelte3-todo.surge.sh/');
driver.findElement(webdriver.By.className('js-todo-input')).sendKeys('Build App\n').then(()=>{
driver.getPageSource().then(source=>{
assert.equal(source.includes("Build App"), true)
})
});

To run this, you’d need to run the below command:

mocha mocha_test.js --timeout 10000

Tada! Running this should print out the following:

For the second test case — marking a task complete — we would need to, first of all, add a task and mark the test complete. Take a look at the code below:

it('mark a task complete', function() {
driver.get('http://svelte3-todo.surge.sh/');
driver.findElement(webdriver.By.className('js-todo-input')).sendKeys('Build App\n');
driver.findElement(webdriver.By.className("tick")).click()
driver.findElement(webdriver.By.className("todo-item")).getAttribute("class").then(function(className){
assert.equal(className.includes("done"), true)
});
});

In the above code, we:

  • Added a task using the same process from adding a task
  • Clicked on the checkbox to mark the task
  • Then confirmed if the task is really completed by checking its className attributes

Running this would print a result as below:

Now we can see our first and second test case is passing.

For the last test case, which is deleting a task, just like the way we implemented marking a task, we’ll add a task first and then remove the task.

Take a look at the code below:

it('delete a task', function() {
driver.get('http://localhost:5000');
driver.findElement(webdriver.By.className('js-todo-input')).sendKeys('Build App\n');
driver.findElement(webdriver.By.className("delete-todo")).click();
driver.getPageSource().then(source=>{
assert.equal(source.includes("Build App"), false)
});

});

With the above code, we were able to:

  • Add a task
  • Find the task we just added and clicked on its remove button
  • Then confirmed the task is no longer in the current page source

Running this would result in:

Tada! We’ve successfully written and run all of our test cases.

With all of these, we can draw an assumption that our application is working as expected, and we can always run this test quickly to be sure rather than testing manually.

Here’s the full code:

Wrapping Up

Thanks for reading up to here. In this article, we’ve seen how to write automated front-end tests for our front-end application using Selenium on the Node environment as well as using a testing framework.

This has also given us an idea of how to set up our front-end test suite and how to automate all of our test cases with little configuration. We’re now able to perform an entire front-end test using group tests and using the assertion library.

--

--