UI Test Automation with Node.js, TypeScript, Mocha and Selenium

SeleniumDemoTest 01

In this post, we’ll see how to do UI test automation in node application using TypeScript, Mocha and Selenium. This post is extension of my previous post, where I’ve covered Setting up node application with TypeScript in VS Code  —  using mocha, chai, mochawesome, gulp, travis If you are looking for setting up node project with TypeScript and Mocha, first refer previous post and then continue below for browser based tests with selenium.

Note: The entire VS Code project used in this post is available at GitHub.

Let’s get started!

1. Add selenium-webdriver and chromedriver capabilities in project

npm install selenium-webdriver --save-dev

2. Add Mocha Test

  • before – initializes chrome driver
before(function () {

    // initializing chrome driver 
    driver = new webdriver.Builder() 
    .withCapabilities(webdriver.Capabilities.chrome()) 
    .build();
 
    // maximizing chrome browser 
    driver.manage().window().maximize(); 
});
  • afterEach – takes screenshot if test case fails, collects logs etc
afterEach(function () {

    let testCaseName: string = this.currentTest.title; 
    let testCaseStatus: string = this.currentTest.state; 

    if (testCaseStatus === 'failed') { 
        console.log(`Test: ${testCaseName}, Status: Failed!`);
 
        // capturing screenshot if test fails 
        driver.takeScreenshot().then((data) => { 
            let screenshotPath = `TestResults/Screenshots/${testCaseName}.png`; 
            console.log(`Saving Screenshot as: ${screenshotPath}`); 
            fs.writeFileSync(screenshotPath, data, 'base64'); 
        }); 
    } else if (testCaseStatus === 'passed') { 
        console.log(`Test: ${testCaseName}, Status: Passed!`); 
    } else { 
        console.log(`Test: ${testCaseName}, Status: Unknown!`); 
    } 
});
  • after – closes browser
after(function () {
    driver.quit();
});
  • it – performs test operation and validates result. e.g. open bing.com and search for a text
it('should search for nilay shah at bing.com', function () {
    let Url: string = `http://www.bing.com`;
    return driver.get(Url).then(function () {
    console.log(`Page "${Url}" opened`);
    }).then(() => {
        return driver.getCurrentUrl().then((currentUrl) => {
            currentUrl.should.include(
            `www.bing.com`,
            `Expected url: www.bing.com, Actual url: ${currentUrl}`);
        }).then(() => {
            let searchBox = driver.findElement(webdriver.By.name('q'));
            searchBox.sendKeys('nilay shah');
            return searchBox.getAttribute('value').then((value) => {
                value.should.equal('nilay shah');
            });
        });
    });
});
SeleniumDemoTest 01
SeleniumDemoTest 02

3. Run Tests

  • Run tests with mocha (below command from project root folder) or just hit F5 from VS Code (Assuming already followed steps from previous post)
mocha .\lib\test\SeleniumDemo.test.js
  • Note that, I’ve kept chromedriver in project root folder, and I’ve added PATH as . (current directory) so test will be able to find chromedriver from the PATH.
  • Test will launch single chrome browser instance, perform all tests in sequence and then close browser.
  • Mochawesome Report will look like below when you run all tests (unit tests and ui tests together)
Selenium Mochawesome Report

4. Summary

  • This post covers basic steps for setting up UI test automation using Node.js, TypeScript and Mocha.
  • If you will go through the code at github.com, you will notice that I’ve skipped this test with describe.skip() — this is because repo is configured with Travis CI which builds and runs all tests.  And to get UI tests running in CI requires headless chromedriver.

Please share your thoughts using comments on this post. Also let me know if there are particular things that you would enjoy reading further. Please feel free to connect me @nilaydshah.

Setting up node application with TypeScript in VS Code  —  using mocha, chai, mochawesome, gulp, travis

VSCode DebugAddTest

In this post we are going to learn how to configure a TypeScript + VS Code development environment. Perform unit testing with Mocha and Chai. Configure VS Code to perform build task using gulp and then launch mocha tests. Configure Travis CI to enable continuous integration build/test on your github repo. We are going to use the following tools and technologies:

  • TypeScript
  • VS Code
  • Mocha
  • Chai
  • Mochawesome
  • Gulp
  • Travis CI

Let’s get started!

Note: The entire VS Code project used in this post is available at GitHub.

1. Download and install VS Code and some extensions

  • Install VS Code from: https://code.visualstudio.com/
  • Install these VS Code extensions: 1) npm 2) npm intellisense 3) mocha sidebar
  • Create project root folder and open that from VS Code
> code . // This opens VS code from current folder

2. Creating node application

> npm init // This will generate default package.json file
  • Add necessary dependencies in package.json and do npm install
 "dependencies": {
"typescript": "^2.6.1"
},
"devDependencies": {
"@types/chai": "^4.0.5",
"@types/mocha": "^2.2.44",
"chai": "^4.1.2",
"del": "^3.0.0",
"gulp": "^3.9.1",
"gulp-typescript": "^3.2.3",
"mocha": "^4.0.1",
"mochawesome": "^2.3.1"
}

3. Add Typescript source and test files

  • First install typescript globally, so that tsc cli would be available
> npm install -g typescript // This will install typescript globally
> tsc --init // This will generate default tsconfig.json
tsconfig.json {
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"outDir": "./lib"
}
}
  • Now let’s add HelloWorld.ts and HelloWorld.test.ts
  • Notice that, we are not using node basic assertion framework, instead we are using Chai for assertion. You can use either ‘should’ or ‘expect’ module from ‘chai’ for assertion. I used ‘should’ as that just aligns with natural language!
HelloWorld And HelloWorldTest
HelloWorld And HelloWorldTest

HelloWorld.ts 
export class HelloWorld {
public helloWorld() : string {
return 'Hello World'
}
}
export default HelloWorld;
HelloWorld.test.ts 
import { should } from 'chai';
import { HelloWorld } from '../src/HelloWorld';
should();
describe('Hello World test suite', function() {
it('Can say Hello World', function() {
const result = new HelloWorld().helloWorld();
result.should.equals('Hello World', `Should return: Hello World, but returned: ${result}`);
});
});
Calc And CalcTest
Calc And CalcTest
Calc.ts 
export class Calc {
public add(num1: number, num2: number) : number {
return num1 + num2;
}
public subtract(num1: number, num2: number) : number {
return num1 - num2;
}
}

export default Calc;
Calc.test.ts
import { should } from 'chai';
import { Calc } from '../src/Calc';
should();

describe('Calc test suite', function() {
let calc = new Calc();
it('Can add', function() {
let result = calc.add(5,5);
result.should.equals(10, `Should return: 10, but returned: ${result}`);
});
it('Can subtract', function() {
let result = calc.subtract(20,10);
result.should.equals(10, `Should return: 10, but returned: ${result}`);
});
});

4. Build and run base project which includes TypeScript + Mocha + Chai + Mochawesome

  • Build TypeScript project with tsc from project root folder
> tsc // This will compile typescripts based on tsconfig.json
  • Alternatively, you can use VS Code: Ctrl + Shift + B and pick tsc:build
VSCode tsc
VSCode tsc
  • Optionally, install mocha globally so that we can run mocha cli
> npm install -g mocha // This will install mocha globally
  • Run mocha tests with mocha or npm test supply mochawesome as reporter argument.
    • Running tests with mocha
      • mocha lib/test/**/*.js –reporter mochawesome –reporter-options reportDir=TestResults
    • Running tests with npm test, (Make sure your package.json contains above as test script)
      • npm test
    • Running tests with mocha sidebar VS Code extension
      • Add below workspace settings.json to enable discovery of our test path by mocha sidebar
      • “mocha.files.glob”: “lib/test/**/*.js” // Use Ctrl + , to edit settings
      • Now we can see our tests under Mocha in side bar. We can debug / run our tests right from there. We can choose selectively single test or run all tests.
VSCode DebugAddTest
VSCode DebugAddTest
  • Running tests with VS Code launch.json
    • We can configure VS Code tasks.json and launch.json and run the same tests with just F5. Will cover that later in the same post after adding gulp support.
  • Let’s see how Mochawesome test report looks like,
Mochawesome ReportDetails
Mochawesome ReportDetails

5. Add Gulp tasks to clean and build project

  • First install gulp-cli globally
> npm install -g gulp-cli // This will add gulp cli globally
  • Add gulpfile.js and add necessary tasks. For example,  task to clean lib folder and TypeScript compile. We can also add more relevant tasks in gulp such as tslint, copy source to remote, uglify.minify and so on.
gulpfile.js 
"use strict";
var gulp = require('gulp');
var ts = require('gulp-typescript');
var del = require('del');
var tsProject = ts.createProject("tsconfig.json");

// task to clean all files in lib (which is out folder for containing all javascripts)
gulp.task("clean:lib", function() {
return del(['lib/**/*']); }); // task to build(transpile) all typescripts into javascripts in lib folder
gulp.task("tsc", function () {
return tsProject.src()
.pipe(tsProject())
.js.pipe(gulp.dest("lib"));
});

// adding default tasks as clean and build
gulp.task('default', ['clean:lib','tsc'], function () {
});
  • Now let’s run this task from VS Code by Ctrl + Shift + B. This will run both ‘clean:lib’ and ‘tsc’ tasks.
GulpFile And GulpRun
GulpFile And GulpRun
  • Now, let’s see how to enable F5 run for the same in VS Code.

6. Configure tasks.json and launch.json to enable F5 run in VS Code

  • We need two things to run mocha tests from VS Code launch
    1. preLaunchTask
    2. program to launch mocha tests
  • Let’s configure preLaunchTask as gulp default task in tasks.json
tasks.json 
{
"version": "2.0.0",
"tasks": [
{
"label": "gulp",
"type": "gulp",
"task": "default",
"problemMatcher": []
}
]
}
  • Let’s configure mocha (with necessary arguments) as launch program in launch.json
  • We can add multiple configurations as we need. For example, one configuration to launch all mocha tests, whereas another configuration to launch specific tests with mocha grep argument.
launch.json 
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch All Mocha Tests",
"preLaunchTask": "gulp",
"cwd": "${workspaceRoot}",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": [
"-u", "tdd",
"--no-timeouts",
"--colors",
"--reporter", "mochawesome",
"--reporter-options", "reportDir=TestResults",
"${workspaceFolder}/lib/test" //you can specify paths to specific tests here
],
"internalConsoleOptions": "openOnSessionStart"
}
]
  • We are ready to launch. Hit F5.
CalcTest And HelloWorldTest
CalcTest And HelloWorldTest
  • By this time we should have following global and local node dependencies. Below are the commands to list global and local node dependencies.
> npm list -g --depth=0 // This lists global installed node dependencies 
> npm list --depth=0 // This lists local (project-specific) node dependencies
NpmGlobal And Local Dependencies
NpmGlobal And Local Dependencies
  • Now let’s configure CI for our repo. So every time there’s new check-in or PR to master branch, we can trigger build and tests automatically.

7. Configure continuous integration with Travis CI

  • To configure continuous integration for your github.com repository, you need to add Travis CI service from your Repo > Integrations & Services tab.
Github Travis Configuration
Github Travis Configuration
  • Once you add Travis CI as your service, you will need to define what language of application are you building and what are the steps to build the application. So accordingly, Travis will provide the RunTime environment. For our example, it is node application and our build sequence consist of 3 steps: 1) npm install 2) gulp task 3) npm test.
  • To configure these, add .travis.yml file in the project.
.travis.yml 
language: node_js
node_js:
- "4"
before_script:
- npm install -g gulp-cli
script:
- gulp
- npm test
  • Now we are ready to request build. (At every check-in for particular branch Travis will trigger automated build.) We can see the build status at Travis CI Build URL
TravisCI Current Build Pass
TravisCI Current Build Pass
  • From the Travis job logs we can see what’s passed (and what’s failed too)
TravisCI Test Pass ConsoleLog
TravisCI Test Pass ConsoleLog
  • Check your repo build history
TravisCI Build Pass2
TravisCI Build Pass2

8. Summary

  • In this post we have covered multiple topics at breadth level. At each topic there is a lot to cover. After following all above steps, we will be getting following project/files structure in VS Code.
VSCode Project Structure
VSCode Project Structure

As already mentioned, The entire VS Code project used in this post is available at GitHub.

It’s been a long post, but I hope you found it useful. Let me know your feedback and suggestion on this post.

Did this work for you?

Could I have done something better?

Have I missed something?

Any queries regarding topics covered in the post?

Please share your thoughts using comments on this post. Also let me know if there are particular things that you would enjoy reading further. Please feel free to connect me @nilaydshah.