Starting an Automation Framework: Part I

A Step-by-Step Guide to Using Javascript

Being a QA Engineer is not easy. Each day you’re facing all sorts of challenges and you have to find creative ways to overcome them without giving the impression that you have no idea what you’re doing. As a QA Automation Engineer at Cognizant Softvision, I was recently assigned to a project that was close to having its solution built from scratch and there was virtually nothing started on the QA side. 

After defining a minimal QA process for the manual part, work had to start immediately for implementing the automation processes, also known as the automation framework. That’s easy right? Right?! What could go wrong? Well, being a technical QA, being comfortable with the mainstream programming languages like Java, C#, and Python and also creating frameworks from scratch for a living, you might consider that you’ve pretty much seen everything related to this matter, so I told myself: “Easy job, I’ll just start creating a minimal automation framework that can be easily extended, I’m going to use BDD, because people like to see BDD being used even when it’s not correctly used or it’s almost useless, then I’m going to use PageObjects, because that’s a smart way of separating page’s internals from the actual tests and then everything should be perfect!”. 

But there is a catch here. The front end of the application is built using Javascript and because there is no separate automation code repository, the perfect place for the automation code is, as you’ve probably guessed, the devs repository. 

Now, imagine having a framework built entirely in Java or C#, being stuck in the developers code which is Javascript. It would be hard to find anybody who wants to buy a Java automation framework that’s attached to a Javascript solution. It’s more than nothing but it’s far from perfect.

Just to give you some insight, I’ve heard about Javascript, but I’ve never written one single line of code using this language. But how hard can it be? It has variables, conditions, arrays, objects, methods, functions (wait a second, what’s this?). And that’s not all. After doing some research, I developed this guide to creating an automation framework from scratch, using Javascript and Selenium, step-by-step. It may sound a bit like a cliché, promising you to master Javascript and Selenium in 10 simple steps, but this time is different. You won’t master Javascript and Selenium in 10 steps, but it’s not that bad as it looks. 

Requirements

In order to get started, there are some things that are required:

  • Node.jshttps://nodejs.org/en/download/ – This is an open-source Javascript runtime environment that executes Javascript code outside of a browser. Basically, it does everything under the hood for you to be able to run a program written in Javascript. If you’re familiar with Java, Node.js is similar to Java’s JRE.
  • Javahttps://java.com/en/download/ 
  • An IDE – You’ll want something pretty, easy to use and free, right? – Visual Studio Code is all you need – https://code.visualstudio.com/ 
  • A browser driver – in order to be able to run webdriver on a certain browser, you’ll need a particular driver which is specific for each browser. If you want to use Firefox, go to https://github.com/mozilla/geckodriver/releases. If you prefer Chrome, use https://chromedriver.chromium.org/downloads. In both cases, just get the executable and throw it in a folder (the folder can be anywhere). Then make sure to add that folder to the Environment Variables – System variables – Path. That’s it!
  • The rest of the things we need will be installed on the fly. Don’t worry, there isn’t much left.

As you can see, it’s really easy to get up and ready. Now, that we have everything, we need to start using them. Just having them installed doesn’t get you very far. So, let’s proceed with some real stuff.

  1. Create project folder and package.json

Let’s start by creating the project’s home. Create a folder, open a command line, go to that folder, and write the following command:

“npm init –yes”

Now, let’s explain this. Npm is a software registry and it’s used for sharing and borrowing packages of code. You’ll need those packages for developing your tests (in this case). “How do I get those packages and how can I keep track of what I use in my project?” you might ask. Excellent question! The details of the packages are stored in a file called package.json. “But where is this package.json located? I don’t seem to find it” Well, there is no package.json file yet, we need to create it. And this is exactly what init word is doing. It creates a package.json file that will keep the details about the packages and applications that your project depends on. 

Great. What about the “–yes” part? Well, without this part, you’re going to be prompted with some questions about your project’s description or project’s initial version and all sorts of things that are not really important now. If you really want to study this part, go ahead and do the command without the “–yes” part and see what happens. Otherwise, use it, it will populate these details with the default values.

  1. Install selenium webdriver, BDD support dependencies and assert library

In order to use Selenium-Webdriver, we need to install it first (quite obvious). We’re going to do this by issuing the following command (in the same terminal opened when the package.json was created):

“npm install –save-dev selenium-webdriver”

Basically, this command says: “Please bring me the Selenium-Webdriver, install it and save it as future reference, in the package.json, as development dependency.” Why as development dependency and not as simple dependency? Well, at this point in time, it wouldn’t make any difference if it’s saved as a development dependency or as a simple dependency, so you can use “npm install –save selenium-webdriver” as well. Long story short, dependencies are meant to be used in production whereas the devDependencies are used for development of the application but are not required when the application is up and running. 

In order to get the support for BDD (Behavior Driven Development) we’ll need to install Cucumber. In short, Cucumber supports Behavior Driven Development and it will let you describe your test scenarios for the application, using plain text, in a Given-When-Then manner. Usually, this is used for improving the collaboration between the people involved in the project, therefore this is useful when more people are involved in discussing and determining how the application shows work and what scenarios are essential to be covered. If you, as a tester, are the sole person responsible for how your scenarios are going to look like and there is no one else involved, this is going to add an extra layer to you automation framework and you’re going to use it in a way it wasn’t designed to be used. It’s a collaborative tool and it should be used wisely, otherwise you missed its points. But enough about this, let’s install Cucumber by doing the following:

“npm install –save-dev cucumber”

Looks similar to the one for Selenium-Webdriver, right? Now, if you’re going to the package.json file and open it, you’ll notice that the dependencies are stored under “devDependencies” field. On the same level with your package.json file, you’ll notice a folder called “node_modules”. This is the place where the dependencies are stored. If you take a look, the folder contains the dependencies you’ve installed, Selenium-Webdriver and Cucumber besides other things (don’t worry too much about them).

In the same manner, we’re going to install Chai, which is an assertion library for nodes that gives you the opportunity to write assertions in a more natural way.

“npm install –save-dev chai”

 Now that everything is in place, we should start modeling our automation framework. 

Modeling the framework, step by step

There are multiple ways of starting something from scratch. The first one is the top-to-bottom approach. You can start off by defining some testing scenarios in plain text (remember BDD?), then you go on and start implementing the logic, then you continue with the implementation for those steps until you reach the lowest part of the implementation which is identifying the elements you’re going to interact with. The second one is a bottom-to-top approach. Basically, if you have the bigger picture in mind and you already know the elements you’re going to interact with, you can start off by identifying the elements then go up and implement the methods that are using those elements and finish by defining the tests using the already defined methods. The top-to-bottom approach is a bit easier to follow if you’re a beginner and that’s exactly what we’re going to use here. 

With that in mind, we also need something to automate. And for this purpose, we’re going to simulate a Google search but the way of working can be easily extended for any other scenarios and pages. 

  1. Feature file

Now, on the same level with node_modules folder, create a folder called features. By doing this, we’re going to separate the test internals from the project dependencies. Everything related to the actual tests will be placed in this folder. Now, go to the features folder and open a new file (notepad, notepad++, your choice). Here, we’re going to define our first test scenario using plain text and some keywords. So, the file will look like this:

Feature: Google search

Scenario: Get Google results

     Given I am on the Google landing page

     When I am performing a search by word “Selenium”

     Then Google page displays some results for my search

     When I click on the first result

     Then Selenium page should be opened

Basically, we’ve defined our first test scenario. The keywords are kind of self-explanatory: Feature, Scenario, Given, When, Then. So, the file is about a feature (which can have multiple scenarios), one test scenario which is defined in a Given-When-Then manner. Now, save the file with the .feature extension (eg. searchGoogle.feature). 

In the next part of this series, we’ll learn more about Steps definitions and Page Objects pattern, and we’ll try to bring everything together into a nice and minimum viable automation framework. Stay tuned!

Background Image