Liam Hurst

Liam Hurst

1573044660

JavaScript Testing using Selenium WebDriver, Mocha and NodeJS

In case you are looking to write a functional test in JavaScript, the following tutorial provides UI automation engineers with the perfect structural reference material for JavaScript testing with Selenium WebDriver 3, Mocha and NodeJS.

These days, JavaScript is a ubiquitous web language which seems to overcome its ‘notorious’ past and has become a more solid platform not only for client-side, but for server domains too. Mocha.js, or simply Mocha, is a feature-rich JavaScript test framework running on Node.js, which provides the platform and the API for building standalone applications server-side using Google’s V8 JavaScript engine at its base.

*Note: to get started with this JavaScript tutorial, you’ll need to be familiar with the basics of NodeJS and the JavaScript programming language.

Tutorial Overview:

1. Mocha Test Construction

  • Introduction
  • Installation
  • Installing Chai Assertion Module
  • Test suite and Test Case Structure
  • Constructing Tests with Mocha
  • Running Mocha’s Test Suite and Test Cases
  • Managing Syncing of Async Testing Code

2. Using Javascript Selenium 3 API Integrated with MochaJS

  • Selenium Introduction
  • Selenium Installation
  • WebDriver Construction
  • Integrating MochaJS with Selenium WebDriver 3

Versions used:

  • Node version used: 6.10.1 (LTS)
  • Mocha: 2.5.3
  • WebDriverJS: 3.3.0

1. Constructing Tests with Mocha

Introduction to Mocha

As mentioned, Mocha is a JavaScript test framework that runs tests on Node. Mocha comes in the form of a Node package via npm, allowing you to use any library for assertions as a replacement to Node’s standard ‘assert’ function, such as ChaiJS.

Mocha provides an API, which specifies a way to structure the testing code into test suites and test case modules for execution, and later on to produce a test report. Mocha provides two modes for running: either by command line (CLI) or programmatically (Mocha API).

Install Mocha

If Mocha is to be used in CLI, then it should be installed globally as Node.js.

npm install -g mocha 

Install Chai Assertion Module

npm install --save chai 

The –save option is used to install the module in the project’s scope and not globally.

Test Suite and Test Case Structure

In Mocha, a test suite is defined by the ‘describe’ keyword which accepts a callback function. A test suite can contain child / inner test suites, which can contain their own child test suites, etc. A test case is denoted by the ‘it’ function, which accepts a callback function and contains the testing code.

Mocha supports test suite setup and test case setup functions. A test suite setup is denoted by before while a test case setup applies beforeEach. beforeEach is actually a common setup for every case in the suite, and will be executed before each case.

As with the setup, Mocha supports test suite and test case teardown functions. A test suite teardown is denoted by after, while a test case teardown is implemented with afterEach, functions that are executed after a test suite and after each test case respectively.

Create a file that will ‘host’ the test suite, e.g. test_suite.js, and write the following to it;

describe("Inner Suite 1", function(){

    before(function(){

        // do something before test suite execution
        // no matter if there are failed cases

    });

    after(function(){

        // do something after test suite execution is finished
        // no matter if there are failed cases

    });

    beforeEach(function(){

        // do something before test case execution
        // no matter if there are failed cases

    });

    afterEach(function(){

        // do something after test case execution is finished
        // no matter if there are failed cases

    });

    it("Test-1", function(){

        // test Code
        // assertions

    });

    it("Test-2", function(){

        // test Code
        // assertions

    });

    it("Test-3", function(){

        // test Code
        // assertions

    });

});

Running Mocha Test Suite and Test Cases

Mocha supports execution of tests in three ways: Whole Test Suite file, tests filtered by “grep” patterns and tests grep filtering looking in a directory tree (recursive option)

Run whole Test Suite file:

mocha /path/to/test_suite.js 

Run a specific suite or test from a specific suite file.

If a suite is selected then all the child suites and/or tests will be executed.

mocha -g “Test-2” /path/to/test_suite.js 

Run a specific suite or test file by searching recursively in a directory tree.

mocha --recursive -g “Test-2” /directory/ 

For extensive CLI options:

mocha –-help 

Managing Syncing of Async Testing Code

In case async functions are used with Mocha and not handled properly, you may find yourself struggling. If asyncing code (e.g. http requests, files, selenium, etc.) is to be used in a test case, follow these guidelines to overcome unexpected results:

1. done Function

In your test function (it) you need to pass the done function down the callback chain — this ensures it is executed after your last step.

The example below emphasizes the done functionality. In this case three seconds of timeout will occur at the end of the test function.

it(‘Test-1’, function(done){

    setTimeout(function(){

        console.log(“timeout!”);

  // mocha will wait for done to be called before exiting function.
        done();     
    }, 3000);

});

2. Return Promise

Returning a promise is another way to ensure Mocha has executed all code lines when async functions are used (‘done’ function is not needed in this case.)

it(‘Test-1’, function(done){

    var promise;
    promise = new Promise(function(resolve, reject){
        setTimeout(function(){

            console.log("Timeout");
            resolve();

        }, 3000);

    });
    // mocha will wait for the promise to be resolved before exiting
    return promise;  
});

2. Javascript Selenium 3 Integration with MochaJS

Selenium Introduction

Selenium is a library that controls a web browser and emulates the user’s behavior. More specifically, Selenium offers specific language library APIs called ‘bindings’ for the user. These ‘bindings’ act as a client in order to perform requests to intermediate components and acting as servers in order to finally control a Browser.

The intermediate components could be the actual webdriver, found natively in each Selenium package, the selenium-standalone-server, as well as vendor native browser controlling drivers — such as Geckodriver for Mozilla, chromedriver for Chrome, etc. Moreover, Selenium webdriver communicates with browser drivers via ‘JsonWired Protocol’ and becomes a W3C Web Standard.

Selenium Installation

Before diving any deeper into Selenium integration with MochaJS, we will take a quick look into Selenium implementation with NodeJS.

In order to use the Selenium API for JavaScript (or Selenium JavaScript bindings), we should install the appropriate module:

npm install selenium-webdriver 

At this point, it should be clarified that Javascript Selenium WebDriver can also be referred to as Webdriverjs (although not in npm). Webdrivejs is different than other libs/modules, such as WebdriverIO, Protractor, etc. selenium-webdriver is the official open-source base JavaScript Selenium library while the others are wrapper libraries/frameworks that are built on top of webdriverjs API, claiming to enhance usability and maintenance.

In NodeJS code, the module is used by:

require(‘selenium-webdriver’) 

WebDriver Construction

In order to be able to use Selenium, we should build the appropriate ‘webdriver’ object which will then control our browser. Below, we can see how we use the “Builder” pattern to construct a webdriver object by chaining several functions.

Builder with Options

var webdriver = require('selenium-webdriver')
var chrome = require('selenium-webdriver/chrome'),
var firefox = require('selenium-webdriver/firefox');

var driver = new webdriver.Builder()
    .forBrowser(‘firefox’)
    .setFirefoxOptions( /* … */)
    .setChromeOptions( /* … */)
    .build();

In the code above, we have managed to build a WebDriver object which aggregates configuration for more than one browser (notice the ‘options’ methods), despite the fact that the forBrowser() method explicitly sets firefox.

The user can set the SELENIUM_BROWSER environmental variable on runtime to set the desired browser. It will override any option set by forBrowser, since we have already configured multiple browser capabilities by set Options.

The browser properties can have several types of information depending on the browser under test. For example, in Mozilla’s properties we can set the desired ‘profile’ configuration as follows:

var profile = new firefox.Profile( /* … path to firefox local profile … */);
var firefoxOptions = new firefox Options().setProfile(profile);

Then, in the above Builder snippet we can add:

‘setFirefoxOptions( firefoxOptions )’ 

Builder with Capabilities

Selenium WebDriver JavaScript API documents several ways that a webdriver could be built. One more possible way is by setting all the required driver configurations in capabilities:

var driver = new webdriver.Builder().
    .withCapabilities( { ‘browserName’ : ‘firefox’ } )
    .build();

Note that if setOptions are set after withCapabilities, the configurations will be overridden (e.g. proxy configurations).

Selenium WebDriver Control Flow and Promise Management

Since JavaScript and NodeJS are based on asynchronous principles, Selenium WebDriver behaves in a similar way. In order to avoid callback pyramids and to assist a test engineer with the scripting experience as well as code readability and maintainability, Selenium WebDriver objects incorporate a promise manager that uses a ‘ControlFlow’. ‘ControlFlow’ is a class responsible for the sequential execution of the asynchronous webdriver commands.

Practically, each command is executed on the driver object and a promise is returned. The next commands do not need to be nested in ‘thens’, unless there is a need to handle a promise resolved value as follows:

driver.get("http://www.google.com");
driver.getTitle().then(function( title ) {

    // google page title should be printed 
    console.log(title)

});

driver.quit();

Pointers for JavaScript Testing with Selenium WebDriver and Mocha

  1. driver is a webdriver object, not a promise object
  2. driver.getTitle() or driver.get(url), or any other Selenium command, returns a promise object!

This means that we can perform the following:

var titlePromise = driver.getTitle();
titlePromise.then(function(title){

    console.log(title);

});
  1. Additionally, since driver is asyncing in its base, the following will not work:
var title = driver.getTitle();
expect (title).equals("Google");

Note: title is a promise object and not an actual resolved value.

MochaJS + Selenium WebDriver

Generally speaking, Selenium WebDriver can be integrated with MochaJS since it is used in any plain NodeJS script. However, since Mocha doesn’t know when an asynchronous function has finished before a done() is called or a promise is returned, we have to be very careful with handling.

Promise Based

Selenium commands are registered automatically, to assure webdriver commands are executed in the correct sequential order a promise should be returned.

The code below shows Mocha’s (before, beforeEach, after, afterEach) or test case body it hooks.

describe( 'Test Suite' , function(){

    before(function(){

        driver.get( my_service );
        driver.findElement(webdriver.By.id(username)).sendKeys(my_username);

        // a promise is returned while ‘click’ action
        // is registered in ‘driver’ object
        return driver.findElement(webdriver.By.id(submit)).click();
    });

    after(function(){

        return driver.quit();

    });

    it( 'Test Case', function(){

        driver.getTitle().then(function(title){
            expect(title).equals(my_title);
        })

The following actions will be executed:

  1. Browser page of “my_service” is loaded
  2. Text Field with id ‘username’ is located
  3. Text Field with id ‘username’ is filled with ‘my_username’
  4. Page title is retrieved and checked for equality against ‘my_title’
  5. WebDriver quits and browser window is closed. Browser process is terminated.

Selenium Webdriver Support for MochaJS

In order to perform JavaScript testing with Selenium WebDriver and Mocha in a simple way, WebDriver facilitates usage with MochaJS by wrapping around MochaJS test functions (before, beforeEach, it, etc.) with a test object. This creates a scope that provides awareness that WebDriver is being used. Therefore, there is no need for promise returns.

First, the corresponding module should be loaded:

var test = require('selenium-webdriver/testing'); 

All the function of Mocha are preceded by ‘test.’ as follows:

test.before()
test.describe()

And so on. Then, the above code is fully re-written as:

test.describe( 'Test Suite' , function(){

    test.before(function(){

        driver.get( my_service );
        driver.findElement(webdriver.By.id(username)).sendKeys(my_username);
        driver.findElement(webdriver.By.id(submit)).click();
    });

    test.after(function(){
        driver.quit();
    });

    test.it( 'Test Case' , function(){

        driver.getTitle().then(function(title){
            expect(title).equals(my_title);
        })

        driver.sleep();
    });

});

Conclusion

In this tutorial we got a chance to experience JavaScript testing with Selenium WebDriver and MochaJS. We should keep in mind the main difference when comparing to other programming language bindings, due to the asynchronous nature of NodeJS, MochaJS and Selenium WebDriver.

As long as we keep returning promises in any function which creates a promise (either a custom test lib function or a MochaJS hook/testcase), Mocha will execute them in the correct order.

Other frameworks such as WebdriverIO, Protractor and CodeseptJS provide wrapper solutions that hide some configurations from the user, and provide some promise-enhanced handling for a better scripting experience that many test automation experts might find helpful.

#javascript #testing #selenium #node

What is GEEK

Buddha Community

JavaScript Testing using Selenium WebDriver, Mocha and NodeJS
Anthony  Dach

Anthony Dach

1625124424

A Look at End-to-end Testing in Nightwatch v2.0

Nightwatch was published at the beginning of 2014 and was created as a complete and integrated framework which would enable engineers to write end-to-end tests quickly and without headaches. While writing it, we were guided by the belief that writing and running automated UI tests should be a straightforward and pleasant task, and should require as little configuration and maintenance as possible.

The task of interacting with browser internals was already handled by the Selenium project and working with the Selenium server via an HTTP based api was a straightforward task. And so Nightwatch was born by bringing together various existing tools and techniques into one easy-to-use integrated solution.

Seven years later, the open-source testing space for Node.js looks quite different. Several new frameworks appeared over the past few years, each of which is bringing their own set of capabilities to the table and their own interpretation over how automated testing should be done.

Meanwhile, the Selenium json-wire protocol has transition into the W3C Webdriver standard which is now implemented by all major browsers. As far as Nightwatch is concerned, the strategy hasn’t changed that much. In fact, I personally am even more confident to say that, as an open-source project, Nightwatch has now entered the next major phase in its development and maturity.

The strategy for Nightwatch still remains that we should build the solution using tried-and-tested existing tools and techniques in the automation space instead of going our separate way. The Selenium project (which also includes Webdriver) has been around for more than a decade and has consistently refined and evolved how browser automation works, both on local development environments but also at scale, on large distributed cloud infrastructures. That’s why working in collaboration with the Selenium ecosystem makes me confident to say that Nightwatch will not only deliver on its promises but will even surpass expectations.

#end-to-end-testing-javascript #automated-testing #software-testing #nodejs #selenium-webdriver #selenium #good-company #javascript

Anthony  Dach

Anthony Dach

1624261887

6 Popular Challenges In Automation Testing using Selenium

Selenium is one of the most popular automated testing frameworks, with a market share of about 26.4% in the software testing tools category. This open-source testing framework enables you to automate user actions on your software application under test.

Using this free testing framework, you can also verify & validate your software products across multiple browsers. Additionally, you can create Selenium test scripts using various programming languages such as C#, Java, Python, etc.

The Selenium automation software consists of a host of software tools to cater to an organization’s different quality engineering needs. These are:

  1. Selenium IDE (Integrated Development Environment)
  2. Selenium RC (Remote Control)
  3. Selenium WebDriver
  4. Selenium Grid

Even though Selenium is among the most preferable web-app testing frameworks, it is not completely flawless. This automation framework has its fair share of challenges that developers face while working with it. Let us discuss some of the most common challenges and how you can tackle each of them.

#selenium #selenium-webdriver #selenium-automation-testing #test-automation #software-testing-tools #deployment-challenges #software-quality-assurance #software-testing

Anthony  Dach

Anthony Dach

1620502920

Automate drop-down menu and checkbox using Selenium 4.0

In the last blog, we saw how we can use locator strategies to find and use different elements for automating our projects. In this blog, we will see how we can automate the drop-down menu and checkbox using selenium 4.0.

What’s the need for automating drop-down menu and checkbox?

  • Nowadays most websites contain drop-down menus and check boxes to perform various interactions with the website.
  • These can be static and can also be dynamic. Which may change according to the input that the user provides.
  • So, it is important to know how to handle these cases

Static drop-down menu

  • These drop-down menus contain the static values inside them. They don’t change with input from the user.

#quality assurance (qa) #testing #automation #automation testing #selenium #selenium webdriver #selenium webdriver locators #ui testing

Anthony  Dach

Anthony Dach

1620488040

How to Perform Localization Testing Using Selenium WebDriver

Localization automation testing is essential for your product to gain good standing globally. Read on to learn how to do localization testing using Selenium WebDriver.

Automation testing is vital to the entire process of delivering a successful web product. The challenge associated with testing a web site or web app grows exponentially if it’s built for a global audience (particularly non-English audience). Automation tests have to be performed to ensure that the product features (including the content) cater to specific locales. That’s why localization testing using Selenium WebDriver has become increasingly relevant when a plethora of software products are being built for the world!

We’re sure you’ve come across scenarios where some content or portion of the website did not render correctly in a specific location. This is a common dilemma that most Selenium test automation engineers often come across, and it is extremely likely that incorrectly formatted strings are a part of the resource files. As a part of localization testing using Selenium WebDriver, we need to verify if the website (or app) looks and functions the same after localization automation testing is applied.

That is precisely what this blog aims to deliver. By the end of this blog, you would be comfortable performing localization testing using Selenium WebDriver as we touch upon the critical aspects of localization, including how to perform localization automation testing.

#tutorial #performance #automation testing #selenium webdriver #localization #selenium automation #selenium automated testing #automation selenium

Anthony  Dach

Anthony Dach

1620462169

How To Get Attribute Value In Selenium WebDriver

While you are automating your test cases with Selenium automation, here is how to start implementing Selenium getAttribute() method to get the best results.

Introduction

Testing a web page can be a gargantuan task, considering all the elements and variables that come together to make a page work. Selenium automation is a great way to overcome these challenges and automate everything you would manually do. For example, Selenium makes it so much easier to take a screenshot using Python instead of doing it manually every time you come across a website issue.

Similarly, there are multiple scenarios while writing automation test cases when we need to verify a specific attribute on the web page. To ease our execution, the method to getAttribute() in Selenium comes to the rescue. In this blog, we will understand what an attribute is and how we can handle web elements’ attributes using the Selenium getAttribute() method.

Let’s get to it, shall we?

#selenium #webdriver #selenium automation testing #selenium automation #selenium - web browser automation #selenium automated testing #get attribute