I have been with SwarmOnline for just under 6 months and during that time I had the chance to explore some of the most interesting JavaScript testing frameworks, test runners and assertion libraries. Coming from a payment systems background, where majority of tools used in the industry are set in stone, it is a rewarding experience to try new flexible frameworks, and tools for automated testing, and reporting.
As with any project, testing and quality assurance is an essential aspect of planning, development, and final release. Using emerging web technologies for enterprise development is no different, and you are certainly not limited to the frameworks available to you. The aim of this blog post is to demonstrate the effective use of the WebDriverIO framework, coupled with an assertion library and a test reporter, and have a look at what benefits this tool can bring. Let’s begin!
WebDriverIO
We create bespoke web and mobile applications, and each one needs a well defined approach to quality, one of which is user acceptance testing. This framework, coupled with an assertion library, allows us to code and mimic user interaction with an app, whilst gathering stats, and catching any potential issues an end user may encounter. From a technical perspective, this framework is essentially a JavaScript implementation of accessing Selenium WebDriver calls, and emulating a real user on a range of different browsers. For this example, you’ll need to have configured your environment by installing Node.js and Java JDK, going through the config file using ./node_modules/.bin/wdio config
, and ensuring the Selenium Standalone Server is running in the background using java -jar selenium-server-standalone-2.53.1.jar
. Make sure to get a copy of the browser executable that you’re planning on using, for example ChromeDriver. The helpful chaps over at WebDriverIO provide a really simple quick start guide, which will help you follow our example below. Let’s have a look at a quick example and break it down:
var assert = require('assert'); describe('Homepage', function() { it('should display the correct title', function () { browser.url('https://swarmonline.com'); var title = browser.getTitle(); assert.equal(title, "SwarmOnline | Mobile and Web App Development Experts"); }); });
After installing WebDriverIO using npm install webdriverio
, and setting up your environment, you can run tests using the built-in test runner, by pointing your command line to the following: ./node_modules/.bin/wdio wdio.conf.js
Having a look at what comes back
What you should see next is an instance of your chosen target browser show up and automatically navigate to the SwarmOnline website, then almost instantly close, updating your command line output to something similar as below:
․ 1 passing (9.20s)
The .
is the output of the default test reporter, which simply displays a dot for each test that is executed, passed, and failed. A handy timer will also indicate how long it is taking to run your test suite, broken down into duration per test case – very handy when you need to know how long it’ll take to run a full automated regression suite, for example, but it is also useful in gathering metrics, and seeing where your code needs some refactoring and optimization. Onto fleshing out the test case itself:
With var assert = require('assert');
you are importing the use of the assert function in Node.js, for which you can also utilize an assertion library, like Mocha. The main bit of code, which is our actual test case, is written in the format of Behavioural Driven Development (BDD), where you describe what a certain component is meant to do, and this is made up of JavaScript functions. In our example above, we are testing the Homepage
component, which should display the correct title
and this nesting allows for a very clean way to categorize your test cases and test suites, in addition to seeing exactly where the test run failed.
We then point the target browser to the desired website with browser.url('https://swarmonline.com');
and retrieve the title of the page using var title = browser.getTitle();
which is then checked against our expected value using assert.equal(title, "SwarmOnline | Mobile and Web App Development Experts");
, which should match and the test should pass.
Onto your second test case
Let’s add another, more interesting test case – entering data, and ensuring the website reacts as we expect. We want to ensure that when entering details into the contact form, the user is prompted if the data they’ve entered is invalid, or a field is empty. To achieve this, we have to locate the element which we want to alter, and use setValue()
to enter some data into the text field.
browser.url('https://swarmonline.com/contact'); var inputEmail = '.your-email > .wpcf7-email'; browser.setValue(inputEmail, 'test@test.com');
In the snippet above, we’re pointing our ChromeDriver instance to the Contact page of the website, and defining the CSS class that is tied to the text field. By pointing WebDriverIO directly to the textbox we want to edit, it makes it really easy to then just setValue();
with any desired string. To confirm that the field is indeed being edited during the test, you can use console.log(browser.getValue(inputEmail));
to check the contents of the textbox.
If you run that now, your second test case should pass and the inserted email address should be included in the command line output (note that I switched to the spec
reporter):
test@test.com ------------------------------------------------------------------ [chrome #0a] Session ID: c241cc64-3597-4622-b792-c47d15c3cbf9 [chrome #0a] Spec: /mnt/c/Users/Eugene/Automation/TestProject/webdriverio-test/test/specs/loginTests.js [chrome #0a] Running: chrome [chrome #0a] [chrome #0a] Homepage [chrome #0a] ✓ should display the correct title [chrome #0a] [chrome #0a] Contact [chrome #0a] ✓ should implement and force input validation on contact form [chrome #0a] [chrome #0a] [chrome #0a] 2 passing (12s) [chrome #0a]
Adding an assertion
Let’s add an assertion and confirm that when submitting the form with just the email address, the form throws an error, indicating that for example, the name field has not been filled out. As before, locate your CSS class used to find the “Send Message” button, in this case it’s .wpcf7-submit
so you point the browser to go ahead and submit the form. Now, the CAPTCHA alone will prevent us from automating an actual submission, but we can still check and ensure input validation feedback is provided to the user. Add the next three lines of code:
var errorMessage = '.your-name > .wpcf7-not-valid-tip'; browser.waitForExist(errorMessage, 1000); assert.equal(browser.getText(errorMessage), "The field is required.");
Breaking this down, the first line simply assigns the class that we’re looking for to a variable. The second line is a perfect example why WebDriverIO is an excellent framework – this little piece of code waits until our error message appears, and is enabled for us to select it. By default, the wait period is 500ms, however I’ve changed this to 1 second, to be 100% sure that the element is visible. The main advantage of using waitForExist();
over for example browser.pause(1000);
, is that the former function will wait until the exact moment an element is visible, and continue execution then, rather than waiting the full specified time, as with the latter, and extending the duration of the test execution unnecessarily.
Your complete JavaScript test file should in the end resemble something of the following:
var assert = require('assert'); describe('Homepage', function() { it('should display the correct title', function () { browser.url('https://swarmonline.com'); var title = browser.getTitle(); assert.equal(title, "SwarmOnline | Mobile and Web App Development Experts"); }); }); describe('Contact', function() { it('should implement and force input validation on contact form', function () { browser.url('https://swarmonline.com/contact'); var inputEmail = '.your-email > .wpcf7-email'; browser.setValue(inputEmail, 'test@test.com'); browser.click('.wpcf7-submit'); var errorMessage = '.your-name > .wpcf7-not-valid-tip'; browser.waitForExist(errorMessage, 1000); assert.equal(browser.getText(errorMessage), "The field is required."); }); });
Going further
This framework integrates almost seamlessly into a CI implementation (like Jenkins), and allows for easy generation of reports. Using the JUnit reporter, you can generate XML reports, and customize the output. These will then be absorbed by your CI system, and give you the ability to run tests at every build, and easily see the test run status. Take a look at the WebDriverIO guide page, for more details on the various plugins and services you can add, such as testing in the cloud, and testing apps on iOS and Android devices.
To conclude, WebDriverIO is a great tool to automate testing which you would usually carry out manually, probably as part of a regression test suite. It is also a great investment in terms of testing as you develop, and picking up issues earlier, rather than later, which would impact the project costs and deadlines.
Get in touch now for consultation or for more information on Swarm’s services.