Open Event Webapp generates static website of events from JSON data fed to it in the form of a zip or an API endpoint. Over the course of time, the features included in the generated sites have grown. We have the bookmark option, search bar, calendar view and many other facilities. Every once in awhile, it happens that when we fix an issue, another issue which was solved previously in the past resurges. This is extremely frustrating as a developer to solve the old bugs again. In software engineering field, we call these issue/bugs as regressions.
Detecting them is challenging as the reviewer has to manually go through all the pages of the site, and check each and every function. It is not uncommon that a part may be left out during the review process introducing regressions in the app. We already have proper testing for the generator part of the project with help of libraries like mocha and chai. But, up until now, we didn’t have the client-side testing aka the frontend testing in the project. We had to introduce a way to test the functionality of the site. To check if a link is dead, the search bar is working or not, bookmark function works properly or not and so on.
Enter Selenium. Selenium is a suite of tools to automate web browsers across many platforms. Using Selenium, we can control the browser and instruct it to do an ‘action’ programmatically. We can then check whether that action had the appropriate reaction and make our test cases based on this concept. There are various implementations of Selenium available in many different languages: Java, Ruby, Javascript, Python etc. As the main language used in the project is Javascript, we decided to use it.
https://www.npmjs.com/package/selenium-webdriver
https://seleniumhq.github.io/selenium/docs/api/javascript/index.html
After deciding on the framework to be used in the project, we had to find a way to integrate it in the project. We wanted to run the tests on every PR made to the repo. If it failed, the build would be stopped and it would be shown to the user. Now, the problem was that the Travis doesn’t natively support running Selenium on their virtual machine. Fortunately, we have a company called Sauce Labs which provides automated testing for the web and mobile applications. And the best part, it is totally free for open source projects. And Travis supports Sauce Labs. The details of how to connect to Sauce Labs is described in detail on this page:
https://docs.travis-ci.com/user/gui-and-headless-browsers/
Basically, we have to create an account on Sauce Labs and get a sauce_username and sauce_access_key which will be used to connect to the sauce cloud. Travis provides a sauce_connect addon which creates a tunnel which allows the Sauce browsers to easily access our application. Once the tunnel is established, the browser in the Sauce cloud can use it to access the localhost where we serve the pages of the generated sites. A little code would make it more clear at this stage:
Here is a short excerpt from the travis.yml file :-
addons: sauce_connect: username: princu7 jwt: secure: FslueGK2gtPHkRANMpUlGyCGsr1jTVuaKpP+SvYUxBYh5zbz73GMq+VsqlE29IZ1ER1+xMfWuCCvg3VA7HePyN6hzoZ/t0LADureYVPur6R5ZJgqgQpBinjpytIjo2BhN3NqaNWaIJZTLDSAT76R7HuNm01=
As we can see from the code, we have installed the sauce_connect addon and then added the sauce_username and sauce_access_key which we got when we registered on the cloud. Now, what is this gibberish we are seeing? Well, that is actually the sauce_access_key. It is just in its encrypted form. Generally, it is not a good practice to show the access keys in the source code. Anyone else can then use it and can cause harm to the resources allocated to us. You can read all about encrypting environment variables and JWT (JSON Web Tokens) here:-
https://docs.travis-ci.com/user/environment-variables/
https://docs.travis-ci.com/user/jwt
So, this sets up our tunnel to the Sauce Cloud. Here is one of the screenshots showing that our tunnel is opened and tests can be run through it.
After this, our next step is to make our test scripts run in the Sauce Cloud through the tunnel. We already use a testing framework mocha in the project. We can easily use mocha to run our client-side tests too. Here is a link to study it in a little more detail:
http://samsaccone.com/posts/testing-with-travis-and-sauce-labs.html
This is a short excerpt of the code from the test script
describe("Running Selenium tests on Chrome Driver", function() { this.timeout(600000); var driver; before(function() { if (process.env.SAUCE_USERNAME !== undefined) { driver = new webdriver.Builder() .usingServer('http://'+ process.env.SAUCE_USERNAME+':'+process.env.SAUCE_ACCESS_KEY+'@ondemand.saucelabs.com:80/wd/hub') .withCapabilities({ 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, build: process.env.TRAVIS_BUILD_NUMBER, username: process.env.SAUCE_USERNAME, accessKey: process.env.SAUCE_ACCESS_KEY, browserName: "chrome" }).build(); } else { driver = new webdriver.Builder() .withCapabilities({ browserName: "chrome" }).build(); } }); after(function() { return driver.quit(); }); describe('Testing event page', function() { before(function() { eventPage.init(driver); eventPage.visit('http://localhost:5000/live/preview/a@a.com/FOSSASIASummit'); }); it('Checking the title of the page', function(done) { eventPage.getEventName().then(function(eventName) { assert.equal(eventName, "FOSSASIA Summit"); done(); }); }); }); });
Without going too much into the detail, I would like to offer a brief overview of what is going on. At a high level, before starting any tests, we are checking whether the test is being run in a Travis environment. If yes, then we are appropriately setting up the webdriver for it to run on the Sauce Cloud through the tunnel which we opened previously. We also specify the browser on which we would like to run, which in this care here, is Chrome.
After this preliminary setup is done, we move on to the actual tests. Currently, we only have a basic test to check whether the title of the event site generated is correct or not. We had generated FOSSASIA Summit in the earlier part of the test script. So we just run the site and check its title which should obviously be ‘FOSSASIA Summit’. If due to some error it is not the case, then an error will be thrown and the Travis build we fail. Here is the screenshot of a successful passing test:
More tests will be added over the upcoming weeks.
Resources:
- https://www.npmjs.com/package/selenium-webdriver
- https://seleniumhq.github.io/selenium/docs/api/javascript/index.html
- https://docs.travis-ci.com/user/gui-and-headless-browsers/
- https://docs.travis-ci.com/user/environment-variables/
- https://docs.travis-ci.com/user/jwt
- http://samsaccone.com/posts/testing-with-travis-and-sauce-labs.html