Setting Up a TestOps Environment Using Selenium WebDriver and JavaScript.

Setting Up a TestOps Environment Using Selenium WebDriver and JavaScript.


Overview

One day I asked myself a question. All web developers know JavaScript. This is the main language for many developers using frameworks such as ReactJS or AngularJS. What if a web developer decides to setup a test framework around Selenium WebDriver and JavaScript? What tools would be required along the way?

Let’s begin our journey of discovery to find out “what tools do you need if you know JavaScript and want to test a web application using Selenium WebDriver?

WebDriver JavaScript Binding

I found three major implementations of WebDriver protocol for JavaScript.

All of them are designed for Node.js runtime. And I have no idea which of them is the best. Since selenium-webdriver has more stars on GitHub and also listed on Selenium downloads - it is my choice.

So, the first step is to download and install Node.js. Then install JavaScript binding with a command

npm install selenium-webdriver

IDE

It would be nice to have an IDE to edit and debug the code. I am a big fan of Visual Studio Code and recommend it to everyone. The home of VS Code is here: https://code.visualstudio.com/.

Recording

Next question I asked myself: can I record my scripts with Selenium IDE? It turned out that Selenium IDE does not support exporting test cases to JavaScript. Ok, no recording, just coding.

Spy

What tools to use to analyze DOM tree of an application and test xpath expressions for Selenium selectors? Chrome, Firefox, Internet Explorer and Safari - all have developer tools. Let's see what we can get with Firefox.

Here is the DOM tree with nodes and attributes. Looks good.

Now I want to test xpath. Searching on the web says it is not possible.

Quote

Firebug allows to search for elements within the HTML panel via CSS selectors or XPaths. Also the DevTools' Inspector panel allows to search for CSS selectors. It even displays a list with matching IDs or classes. Searching by XPaths is not supported though (see bug 963933).

Ok, I need Firebug. Installing.

What about xpath? Works now via the search field.

It is also possible to generate xpath of an element via popup menu. Copy XPath produces full xpath by enumerating the nodes from the root.

/html/body/form/div[3]/div[2]/div[2]/fieldset/p[1]/input

Copy Minimal XPath is way better for making a selector.

//*[@id="MainContent_LoginUser_UserName"]

Ready to Make a Test

I decided to make a login test on http://libraryinformationsystem.org/.

Using Node.js, selenium-webdriver, Visual Studio Code and Firebug I came up with:

var assert = require('assert');
var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;

var driver = new webdriver.Builder()
.forBrowser('firefox')
.build();

driver.get('http:/libraryinformationsystem.org');

driver.wait(until.elementLocated(By.id("HeadLoginView_HeadLoginStatus")));
driver.findElement(By.id('HeadLoginView_HeadLoginStatus')).click();

driver.wait(until.elementLocated(By.id("MainContent_LoginUser_UserName")));
driver.findElement(By.id('MainContent_LoginUser_UserName')).sendKeys('librarian');
driver.findElement(By.id('MainContent_LoginUser_Password')).sendKeys("librarian");
driver.findElement(By.id('MainContent_LoginUser_LoginButton')).click();
var text = driver.findElement(By.className('loginDisplay')).getText().then(function (value) {
assert.equal(value.trim().substr(0, 7), "welcome");
});

driver.quit();

Since Firefox is my browser of choice I tried to launch the test in it. To make it possible I first had to install geckodriver. But it did not work. At the time of writing this post I had Firefox 53, then upgraded to 54 and got same result during execution:

InvalidArgumentError: Could not convert 'text' to string

Selenium failed to enter text into input boxes. Searching the web revealed I am not alone. The issue is already known for a few months.

Ok, let's use Chrome for execution. Downloaded chromedriver, changed firefox to chrome in my test and yes, it worked. The test executed successfully.

Debugging

Next step. I wanted to find out why my assertion failed and see value in watch window.

assert.equal(value.trim().substr(0, 7), "welcome");

So I set a breakpoint. Looks nice.

What if I want to debug my script step by step? Set breakpoint on the line:

driver.get('http:/libraryinformationsystem.org');

Then launched my script, breakpoint was hit, stepped till the end of script and nothing happened, Chrome was not even started.

Why? Because of Node.js async nature. Let's look at the driver.get definition:

/**
* Schedules a command to navigate to the given URL.
* @param {string} url The fully qualified URL to open.
* @return {!promise.Promise.<void>} A promise that will be resolved
* when the document has finished loading.
*/
get(url: string): promise.Promise<void>;

This function as well as other driver methods returns a promise which represents the eventual result of an asynchronous operation. Welcome to the world of async programming.

Test Cases and Assertions

What if I want to implement Test Cases and write fancy assertions? Then I need Mocha and Chai.

Of course there are a lot of other test frameworks and assertion libraries for Node.js, but they are not so widespread: should.js, expect.js, jasmine, cucumber and many more of others.

Installed Mocha and Chai via npm.

npm install mocha
npm install chai

And now my test looks like this:

var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;

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

var chai = require('chai');
var expect = chai.expect;

test.describe('Library Information System', function() {
test.it('should login a user with name "librarian" and password "librarian"', function() {

var driver = new webdriver.Builder()
.forBrowser('chrome')
.build();

driver.get('http:/libraryinformationsystem.org');

driver.wait(until.elementLocated(By.id("HeadLoginView_HeadLoginStatus")));
driver.findElement(By.id('HeadLoginView_HeadLoginStatus')).click();

driver.wait(until.elementLocated(By.id("MainContent_LoginUser_UserName")));
driver.findElement(By.id('MainContent_LoginUser_UserName')).sendKeys('librarian');
driver.findElement(By.id('MainContent_LoginUser_Password')).sendKeys("librarian");
driver.findElement(By.id('MainContent_LoginUser_LoginButton')).click();
var text = driver.findElement(By.className('loginDisplay')).getText().then(function (value) {
value = "" + value;
expect(value.trim().length).to.greaterThan(6);
expect(value.trim().substr(0, 7)).to.equal("welcome");
});

driver.quit();
});
});

Reporting

Now I want reporting in a visual way. One of major players in this field is Allure.

In order to use it with Mocha one needs to install mocha-allure-reporter:

npm install mocha-allure-reporter

I hope it works. I just do not have time to check.

Remote Execution

What about remote execution of tests using different browsers on different platforms? Check out Selenium Grid, Sauce Labs and BrowserStack.

Conclusions

While making this research I noticed a pattern. Answer to each of my questions above is a new tool developed by a separate group of people. Here is the landscape I discovered (and I believe this is just a top of an iceberg, I did not ask all the questions due to time constraints):

Obviously implementing such a test framework around Selenium and JavaScript requires significant investment of time and a lot of technical skills.

Is There an Alternative?

What if one needs to enter the automated testing space fast, without significant time investments and without a dedicated TestOps team working on a test framework (not tests, but infrastructure)? Is there an alternative?

At Inflectra we develop Rapise. This is a complete automated testing solution for web. mobile and desktop applications. Let me quickly show how Rapise answers the questions I posed above.

WebDriver JavaScript Binding

There is no need in Node.js and selenium-webdriver to run web tests with Rapise. Install Rapise and all is set for creating and executing tests.

IDE

Rapise includes full-featured IDE with JavaScript editor and debugger. Rapise uses Windows Script Host to execute JavaScript. The scripting engine is synchronous and thus better suits for UI testing than Node.js. No async programming involved.

Recording

With Rapise one can record scripts using Internet Explorer, Firefox or Chrome browser. During recording Rapise captures user actions:

It also allows to record assertions:

Here is the script generated from this recording:

function Test()
{
SeS('Log_In').DoClick();
SeS('Username_').DoSetText("librarian");
SeS('Password_').DoSetText("librarian");
SeS('ctl00$MainContent$LoginUser$Logi').DoClick();
Tester.AssertEqual("Verify that: InnerText=librarian",
SeS('librarian').GetInnerText(),
"librarian");
SeS('Log_Out').DoClick();
}

g_load_libraries=["%g_browserLibrary:Firefox HTML%"];

This test can be executed by Rapise natively on local Internet Explorer, Firefox and Chrome. Also Rapise can execute this test (without making any changes) via Selenium WebDriver on Safari, PhantomJS, Opera, browsers in Docker, on nodes in Selenium Grid. Thus Rapise can be used as a tool for making Selenium tests.

Spy

Rapise has a spy which works with any browser. It shows a DOM tree, generates xpath selectors using different strategies and allows testing xpath and css expressions. Rapise shows DOM tree for headless browsers as well (PhantomJS, Chrome, Firefox).

Reporting

Rapise has powerful reports making easy to find out why a test failed.

Rapise can capture screenshots of elements.

Test Cases and Remote Execution

Rapise is fully integrated with SpiraTeam. In SpiraTeam one can define Test Cases, Test Sets, schedule remote execution of automated tests on different hosts and trace Test Case failures to requirements.

Scriptless

If you have non programmers in a team they can use Rapise Visual Language (RVL) to implement test scenarios. Here is how our test looks in RVL:

You are Welcome

I encourage you to try Rapise and make sure it meets your needs. We stand for our products and will assist you along the way. We'd be happy to schedule a live WebEx consultation session to help you get the most out of your Rapise trial.