End-to-End (E2E) testing is another relevant Black-Box testing strategy, where an automatic test is used to drive a browser in order to test your Web app, emulating real users interactions throughout your web pages / application.
Simplifying⌠E2E testing can be used to discover bugs using your Web front-end like a real person is actually using it. This type of E2E testing allows to write tests like the following (expressed in natural language):
Open Chrome browser and navigate to https://mysuperwebapp.example.com
Fill username and password fields
Assert that the user is logged in and that its personal workspace page loads and content is shown
Assert that the page header includes and shows a clickable logout button.
Or simulate and test the typical chat application, like:
Open Firefox and login as Bob
Open Chrome and login as Alice
Bob clicks the button to start a chat with Alice, he writes âhelloâ and clicks âsendâ button
Assert that Chrome browser is showing a âNew Messageâ notification popup to Alice
Alice clicks on the notification, writes âhey!â and pushes the âsendâ button
Assert that Firefox is showing the âhey!â Message on the Bobâs chat page element.
Several tools can be used to automate your browsers, among them Selenium is one of the most used.
In particular, Selenium 2 is a server app that implements and exposes the W3C Webdriver specification API , which provides a uniform API to remotely instruct the behaviour of web browsers. Selenium is able to receive Webdriver commands to automate browser activities using their specific drivers.
Then, if you are writing tests in Node.js, you can use frameworks like Webdriver.io, Nightwatch.js or WebdriverJs to write your E2E tests using Selenium under the hood.
The following picture shows how this workflow looks like:
Currently we are using Webdriver.io framework as Node.js bindings for Selenium, and it is amazing. Webdriver.io exposes a rich set of APIs, including starting multiple browser instances and a seamless integration with W3C Webdriver API, Selenium, Mocha, Chai and Should. Moreover, Webdriver.io provides CSS and XPath Selectors to select and check DOM elements in an easy way.
Some basic steps are required to start E2E testing with Node.js: download and install Selenium standalone server (it requires Java RE), download the drivers for each browser we need to use, install Webdriver.io, write tests, launch Selenium server, run your Node.js testsâŚ
But, here is how to simplify this flow ;)
2) Install this cool Node.js package: selenium-standalone
npm i selenium-standalone
This latter package allows to download, install, configure and programmatically run (but not only) the Selenium Server and all the required browser drivers. Well done!
3) Write tests and run them, with Mocha (for example)
The following code snippet shows how to configure and run Selenium before each test suite suing Mocha:
const driversConf = { chrome: { version: '2.28', arch: process.arch, baseURL: 'https://chromedriver.storage.googleapis.com' }, firefox: { version: '0.15.0', arch: process.arch, baseURL: 'https://github.com/mozilla/geckodriver/releases/download' } }; before(function (done) { selenium.install({ version: '3.3.1', baseURL: 'https://selenium-release.storage.googleapis.com', drivers: driversConf }, function (err) { err ? console.log('Error installing: ', err) : console.log('Installation OK.'); selenium.start({ version: "3.3.1" , drivers: driversConf}, (err, child) => { if (err) console.log('Error in start: ', err); console.log('Starting Selenium Server...'); serverProcess = child; console.log('Selenium running, pid: ', child.pid); done(); }); }); });
While, here is a test case, written using Webdriver.io API.
The test case initialises two browsers (Chrome and Firefox) and opens them at two app URLs, do a login and tests a basic chat interaction.
Please note that thanks to the latest Node.js version (v. 7.8.0, at time of writing) we can benefit of the new cool async/await JavaScript feature.
describe('Launching two browsers to start a chat', function () { it('should init the chat...', async function () { browser = webdriverio.multiremote({ agentBrowser: { desiredCapabilities: { browserName: 'chrome' } }, customerBrowser: { desiredCapabilities: { browserName: 'firefox' } } }); const agentBrowser = browser.select('agentBrowser').init(); const customerBrowser = browser.select('customerBrowser').init(); await Promise.all([ agentBrowser .url('https://mysuperwebapp.amazingchat.co/login') .setValue('#userid', 'antonio') .setValue('#passwd', 'aNiceSecret') .submitForm('form[name="login"]'), customerBrowser.url('https://anotherwebappchat.amazingchat.co/start) .waitForExist('.chat_widget', 20000) ]); await customerBrowser.click('.chat_label') .waitForVisible('.chat_button', 5000) .click('.chat_button') .pause(2000); await agentBrowser .waitForExist('.newChat', 20000) .click('.newChat') .waitForExist('textarea.chat', 20000) .element('textarea.chat').setValue('Hi, I\'m Antonio, how are you?') .keys('Enter') .pause(1000); await customerBrowser .waitForVisible('#chatTextarea', 20000) .element('#chatTextarea') .setValue('Hello, thanks for asking, it\'s ok.') .keys('Enter') .pause(7000); return; }) });
Launching the test like a generic Mocha suite, we can actually see two browsers opening, navigating and doing click/write/chat actions. Then, using an assert or BDD-style testing framework (like Chai / Should) it is possible to write all the required checks on application / page status and elements.
Massive E2E testing allows also to define a good suite of automatic regression tests: you change your app, you run all the tests, if they pass you are sure changes didnât break the application and, consequently, your end-user experience.