Meta Refresh is an event organised by HasGeek that focuses on design, user experience and the front-end web. The current iteration of Meta Refresh (2015) will be held in Bangalore on April 16-17.

Wingify will be hosting the Delhi run-up event for Meta Refresh. The session will focus on how designers, engineers, optimization specialists and businesses can use data (statistics) to drive design opinion, thereby optimizing their websites and web applications. The premise being that the data speaks for itself at any point of time, and provides you with validations or rejections on your hypothesis. A data-centric approach towards web-design serves the same cause. The design / layout of any website is based on certain intuitions of the designer, and many a times there is a conflict of interests between the designer and the business team. How about tweaking the website to bridge the gap between design and business?

If this is a topic that interests you we encourage you to join us for the run-up even at our office on March 21, starting at 10am. It would be a great opportunity for you to:

  1. Speak - If you have a similar topic in mind, or even a different one that goes with the theme of Meta Refresh 2015 (web in your pockets), propose a session at the talk funnel.
  2. Learn - RSVP for the event at the same link and be present for the event to learn from the community.
  3. Interact - Mingle and chat with us and other attendees about design, usability, or anything at all.

We look forward to seeing you at the event!

Event Time: March 21, 10am - 3pm


Wingify Software Pvt. Ltd.
14th Floor, KLJ Tower North,
Netaji Subhash Place,
Pitam Pura,
Delhi - 110034

Google Maps:

Get In Touch

You can mail us at [email protected] or give us a call at +91-9654585776.

At Wingify, we believe in open source and actively seek opportunities to give back to the community. We make use of a lot of open source technologies and libraries in our day to day work. And to share back the love, we have open sourced quite a few things over the past.

Pravendra Singh, a hacker, recently went on to actually collect and visualize data about open source contributions of some of the leading startups in India.

Something really cool that came into picture from his infographics was that Wingify was leading other organizations in terms of the most starred repository - our Please.js. Moreover, we have three more of our repositories that made it to the top 10!

There are more such cool infographics in his blog post - Open Source Presence Infographic of Indian Startups.

We keep doing a lot of cool open source stuff and if you are into such things, don’t forget to follow us on github and on twitter.

We, at Wingify, have been writing e2e test cases for our A/B testing app for the past 5 months using protractor. Writing e2e scripts is easy but making them work 90% of the times on all browsers makes you go nuts! Sometimes, I feel that the browser is moody, but of course, we have to deal with all its moods and make sure that test cases are robust.

Getting your e2e tests to run smoothly everytime comes with experience. And, learning from my experiences testing our app, here is a post describing them.

An Overview of Protractor

Protractor is a specially designed wrapper around WebDriverJs to automate e2e testing for angular apps. The following figure gives an overview of the architecture involved for automation and testing :

Setting up protractor and add-ons

For basic setup, go through the Protractor official documentation.

Once the setup is done, you are ready to write and run e2e scripts. Next you need a report of failed and passed test cases along with screenshots. protractor-html-screenshot-reporter , an npm module, provides you with an Html report of the test cases along with screenshots. Set it up as mentioned in npm documentation

Test Scenario and Test Data follow a one-to-many relationship, so we can’t hardcode the test data within the code. For example: The same login test script can be used to test the login of different types of users. To make life easy, it is a better option to make use of .xls files (Microsoft Excel, OpenOffice etc) and import data dynamically into the script, while execution. xlsjs npm module lets us fetch the data from an .xls file and use it in script. Follow the below mentioned steps to set it up :

  • Install xlsjs
npm install xlsjs
  • Define a JavaScript utility function as :
cellFromXLS = function (cellId) {
'use strict';
//Define sheetNumber
var sheetNumber = 0;
//Define file Path name
var fileNamePath = path.join(dirPath, 'data1.xls');
//NodeJs read file
var XLS;
if (typeof require !== 'undefined') {
XLS = require('xlsjs');
//Working with workbook
var workbook = XLS.readFile(fileNamePath);
var sheetNamelist = workbook.SheetNames;
var value = workbook.Sheets[sheetNamelist[sheetNumber]][cellId].v;
return value;
  • Call function as:
var email = cellFromXLS('B1');

Test both Angular.js and non-Angular.js based pages

Our use case involves using Protractor for an Angular.js based app, but it works pretty well for non-Angular.js pages as well. Simply set the following flag to true and access the webdriver instance using browser.driver instead of element as shown below :

beforeEach(function() {
browser.ignoreSynchronization = true;

For instance, the following code for an angular page:


would be written as shown below for non angular page:


Sounds cool? Now let’s dig deeper in the protractor world.

A piece of protractor code

Before we start with the advance functions, let’s have a look at a simple login test case, where we verify that the user should be redirected to a welcome page after login.

//Jasmine describe statement : Describes the test
describe('APP LOGIN::', function() {
//before Each : This piece of code executes before all it statement
beforeEach(function() {
var ptor = protractor.getInstance();
//Jasmine it statement : What "it" will do.
it('Verify that the user is logged in', function() {
//Delete all cookies
//Enter UserName
element.all(by.model('username')).get(0).sendKeys('[email protected]');
//Enter Password
//Click Submit button
element(by.css('.login-form button[type="submit"]')).click();
//Wait for the current URL to change to welcome
browser.driver.wait(function() {
return browser.driver.getCurrentUrl().then(function(url) {
return (/welcome/).test(url);
//Jasmine expect statement : compare actual and expected value
/* Write other it blocks */

Let’s study the code:

Describe , it and expect are jasmine framework methods to write the tests easily. Read more about them here.

beforeEach function in the code above executes before all it blocks, however, you might not want to execute the code in beforeEach for all it blocks.

Tip: To control its execution you can use a flag variable as shown in the code below.

//use pageLoadedStatus flag
var pageLoadedStatus = false;
beforeEach(function() {
if (!pageLoadedStatus) {
//browser.ignoreSynchronization = true;
var ptor = protractor.getInstance();
pageLoadedStatus = true;

Multiple ways to select elements:

by.css		 by.model	   by.repeater		by.binding	    by.xpath

Interacting with the DOM:

  • element: returns a single element
  • element.all: returns a collection of elements. Use get(index), first(), and last() functions to get a single element out of the collection.

Other awesome functions

  • filter : Similar to get(index), first() and last() functions, filter takes a collection of elements and returns a single element. The only difference is that the element can be selected based on the specified condition. This is useful when there is a dynamic/long list of elements having same selector path and you need to get an element using its text or any unique property.

Let’s take this example of clicking on a date from a calendar.

All the dates elements have the same selector. Therefore, define a filter function as :

clickDateByText = function (tileText) {
'use strict';
//Select all date elements and apply filter function
element.all(by.css('.dates_selector')).filter(function (elem) {
//Return the element or elements
return elem.getText().then(function (text) {
//Match the text
return text === tileText;
}).then(function (filteredElements) {
//filteredElements is the list of filtered elements

Now to click on date 17, simply call the function as :

  • each : Use it when the same action has to be taken for all elements having common selector. For example : clearing the list of input fields in a Signup form.
element.all(by.css('form>input')).each(function (inputs) {
  • map : Mapping a collection of elements in an array without use of protractor map function involves a lot of code to deal with all the proimises one by one. On the contrary, using map function for the same purpose is a piece of cake. Map function iterates through each element found with the locator and then resolves all the promises to return a promise with an array of values. For example : To get the text of all elements (with ng-repeat = ‘option in Options’) in an array, write the code as :
var optionTexts = element.all(by.repeater('option in Options')).map(function (Options) {
return Options.getText();
optionTexts.then(function (array) {

Tips and tricks

  • Manage Browser logs: There will always be certain scenarios which would not be covered in e2e scripts. Therefore, it is a smart move to always check browser console errors for any unexpected issue in the app. The following piece of code allows you to keep a check at browser logs and fails the test cases if there are any errors :
afterEach(function () {
browser.manage().logs().get('browser').then(function (browserLog) {
if (browserLog.length) {
console.error('log: ' + JSON.stringify(browserLog));
  • Combine element statements to move around the dom : Xpath provides an excellent way to move up and down the dom.
// use '..' to select parent of an element
element(by.css('input')).element(by.xpath('..')); // Resulting element will be the parent of input
// use 'following-sibling' to select the sibling

Common UseCase: Error messages are often displayed as a sibling to input or submit types. Therefore, instead of using a different selector path for error message, xpath can be used to pick the sibling.

To verify the error message “invalid URL”, simply write the assertion as:

element(by.model('Url')).sendkeys('http://').then(function (ele){
expect(ele.element(by.xpath('following-sibling::span')).getText()).toEqual('Invalid URL');
  • Never use protractor element statements inside loop: The simple reason is that the webdriverJS (protractor) API is asynchronous. Element statements returns a promise and that promise is in unresolved state while the code below the statements continues to execute. This leads to unpredictable results. Hence, it is advisable to use recursive functions instead of loops.

  • Debug the tests using elementexplorer.js: elementexplorer.js lets you test the page interactively. You will find this JS file in node_modules/protractor/bin directory. Start the selenium server and run command:

node elementexplorer

Browser will load the URL and you will see > prompt. Use browser, element and protractor variables to interact with page.

Note: Make sure that the developer tools are closed while running commands in elementexplorer.js prompt, otherwise you will face an unexpected error as “TypeError: Cannot read property ‘click’ of null”

Maintaining and reusing test cases

Let’s admit it, e2e test cases are not easy to be maintained and updated. You have to organize the tests in a way that they can be edited easily. Let’s have a glance at Page-Objects, common-files and tests approach that we follow at Wingify, using nodeJS require and exports functions.

  • page-objects: Page-objects is a commonly used practice across the industry while writing e2e tests. It enables you to write clean tests by listing all the information about the elements in a page-object file. This means that you only need to change the page object file, in case of any change in template of app.

Our Application has more than 50 screens. Therefore we list all the page-objects i.e. dom elements of each screen in a seprate JS file. Take a look at login screen page-object file :

/*File Name : loginPage.js*/
var loginPage = function () {
'use strict';
this.userName = element(by.model('username')).get(0);
this.password = element(by.model('password'));
this.submitButton = element(by.css('.login-form button[type="submit"]'));
//******************** functions *******************
this.setUserName = function (username) {
this.clickSubmit = function () {;
module.exports = {
log: new loginPage()
  • common-module: The idea is to divide the entire e2e scenario in small reusable functions in a way that these functions can be used in other e2e scenarios as well. These reusable functions can be grouped in different files for maintainblity. The login and logout module is used in many e2e scenarios. So, both can be clubbed in a file as shown below :
/*File Name : LoginOut.js*/
var loginPage = require('loginPage.js'),
userName = '[email protected]',
pass = '12345';

exports.login = function () {
//delete all cookies
browser.driver.wait(function () {
return browser.driver.getCurrentUrl().then(function (url) {
return (/welcome/).test(url);
browser.manage().getCookie('login').then(function (cookie) {

exports.logout = function () {
//logout script
  • e2e-scripts: Include all the common-module functions to write the complete e2e-script as shown below :
/*File Name : CreateNewUserE2E.js*/
var loginMod = require('loginOut.js');
describe('Create a new user in the account and verify', function () {
/*Load Test Url */
'use strict';
it('Verify login', function () {
/* Rest of the modules to verify user creation */
it('Verify logout', function () {

To conclude

  • Take an extra step to write test cases in a way that they can be edited and maintained with ease.
  • Create a modular approach keeping scalability in mind.
  • Dive deep in the protractor world, use protractor’s awesome functions and have fun!!

Hope this post was a good enough reference to help you write end-to-end tests in a better way. If things might be unclear, or you have any questions, let us know via comments.

To begin with, lets talk about two of the most important things are that come to mind when we talk about performance testing.

The Metrics to Measure

First lets consider the metrics to measure. Few important metrics that should always be considered are:

  1. Response time which could include Javascript file load time, Image load time, CSS file load time, Content Download time etc.

  2. Number of HTTP Request and HTTP Response status.


Coming to second part i.e. Dependencies. Now this could be broadly classified by 2 groups:

  1. Client-side testing
  2. Server-side (API level) testing

Most of the people focus on testing their servers and APIs. But server-side testing is not enough these days, as its hard to find applications which do not use Javascript/Ajax today.

In single-page apps, the performance equally depends on both the client-side and the server-side.

Since single-page apps are Javascript/Ajax enabled, measuring performance from server/API level is not enough. Even poorly written javascript code can majorly affect the performance of the app.

Client-side performance testing can also be done using popular tools like Google Page Speed or But they cannot test different modules of the application separately. They’d just test the URLs you enter. To test different sections of your application, we can follow a different approach.

In this blog post, I’m going to show you how to use the most popular open-source tool (JMeter)[] to performance test AJAX-enabled websites.


A well-known limitation of JMeter is that it isn’t a browser i.e its inability to execute Javascript. This and that when JMeter makes a request to a page, AJAX calls are not automatically executed. JMeter does store Javascript requests when recorded but this is done as individual sampler.

Now to overcome this challenge we have a few options we can work on:

  1. Use WebDriver Sampler to measure the response time in a real time browser. Combining this with JMeter load test, we can measure the real time user experience when we apply severe load.

  2. Use JUnit Sampler to create selenium scripts using tools like Eclipse. Using this approach one can export JAR fie to JMeter and run the test in browser.

  3. Simulate an Ajax request using JSR223 sampler.

Lets talk in further detail about these methods to performance test.

Using JMeter WebDriver Sampler with Selenium

Web Driver Sampler automates the execution and collection of Performance metrics on the Browser (client-side). You can download this plugin from the link shared below.

A large part of performance testing, up to this point, has been on the server side of things. However, with the advancement of technology, HTML5, JS and CSS improvements, more and more logic and behaviour have been pushed down to the client. This adds to the overall perceived performance of website/webapp, but this metric is not available in JMeter.

Simply add the following to your test plan:

  1. Firefox Driver Config
  2. Web Driver Sampler
  3. View Results Table

Now add the following JavaScript code in WebDriver Sampler


The only problem with approach is that the automation capability is limited. But again that depends on the application.

For more info, visit

Using JUnit Sampler

Using this method all we need to do is create a JAR file using Eclipse and export it to JMeter.

Creating JAR using Eclipse

  1. Create a JUnit Test case in your project.

  2. Write the following selenium code to open your homepage.

package wing;

import static org.junit.Assert.*;


import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

public class home {

public void test() throws MalformedURLException {
WebDriver driver2 = new RemoteWebDriver(new URL(""),DesiredCapabilities.firefox());



Note: In the above code we are using RemoteWebDriver to open the browser on a different machine since we will integrate our test with jenkins.

Once this is done you just need to export the JUnit test case to JMeter. Just copy the JAR file into JMeter/extras/JUnit folder and restart JMeter.

After this just click on “Search for JUnit 4 annotations” in case you created a JUnit 4 test case and you ll find the JAR file with class name in drop down.

Simulate an Ajax request using JSR223 sampler

Normally this method is not recommended. But if above solutions don’t work well with your system you can go for Beanshell and use any scripting language like groovy to create Ajax request.


Below are some points to keep in mind while creating performance test plan:

  1. Create custom scripts for different use cases and create a threshold for various metrics.
  2. You can also use headless browser testing using HtmlUnitDriver or Xvfb depending on your system. This approach would work well if you need to combine these with your load test.
  3. You can integrate your tests with Jenkins using the performance plugin. It really helps with reporting and you can simply run it with each new build. In fact, that is also how we do it here at Wingify.
  4. Client-Side performance testing is always done using 1 or 2 threads. But if you need to use it with your load test then you can simulate as many threads as you wish to.

There’s a lot more exciting stuff you can do to handle Javascript/Ajax enabled applications. This is just a brief summary of the work we do here at Wingify. Hope this helps you get started. There can be many ways you can achieve amazing results. If you have any questions/comments, or create something awesome, we will be more than happy to hear from you.

Back in November, I, along with some colleagues from Wingify went to Singapore to attend CSSConf and JSConf Asia. A part of DevFest Asia, it is the best way to meet and connect with front-end designers and developers in South East Asia. It was the first time CSSConf was happening in Asia, and our own Kushagra Gour had the opportunity to speak at it. He talked about 10 Commandments for efficient CSS architecture. The conference venue was Hotel Amara Sanctuary, on the island of Sentosa, Singapore.


The day began with boarding the MRT and the Sentosa Express to get to the venue, and meanwhile being mesmerized by the marvelous Singaporean skyscrapers. A sip of coffee at the Jimmy Monkey Cafe made our eyes open wide, and began Thomas’ introduction to Asia’s first CSSConf. It is commendable for a small bunch of people to organize conferences for the community at such large scale, working part time.

The quality of the talks at the conference was way above our expectations for a first-time event. The speakers and the topics they spoke about were pretty interesting. Below are the talks that I found really intriguing, and I recommend everyone to go through the videos and slides for them:

No More Tools by Karolina Szczur

Her talk made an interesting point: with all the rapid development happening in the front-end realm, we’re making use of tools more than ever, which when mixed with biases and preferences, do more harm than good. She explained what puts apart good tools from the bad ones, and the telltale signs of a tool doing more harm than good.

Build Scalable, Automated CSS Both You and Your ’Back-End’ Coders Can Love by Christian Lilley

As front-end developers, we have been conditioned to live and breathe CSS, both good and bad parts, beckoning a love-hate relationship with it. But it is rather cumbersome for someone new coming in ease into the concept of cascading style sheets, and that coupled with misused practices makes people think of CSS as some sort of dark magic. Christian’s talk separates the good parts from the bad ones, and points the listeners into a direction everyone can take to make CSS a language everyone can love.

Inside the AirBnB brand evolution by Fiona Tey

AirBnB’s product is so simple, yet efficient to use, especially their mobile app that it makes you feel a sense of satisfaction competing products or even luxurious hotels couldn’t match. Booking for a stay with the locals via AirBnB has always been exciting inspiring for me. And today it was a fortunate time to see the face behind such great product design.

What are we doing, anyway? by Ben Schwartz

If you’re like me, perhaps you ask yourself this question as the sun rises each morning. Recall a time when that wasn’t really the question? Ben’s talk took the listeners on a nostalgic ride to the years of hacking around and creating things from the past. Recall spending nights working on creating things as the first ray of sun hits the window, the pride of showing around your project in your peer group, hours upon hours of creative brainstorming to build something exciting? Ben extracts out the secret sauce for that feeling of happiness that stems from creating something and how to hold on to it to keep treading that road.

Words of Wisdom


JSConf had multitude of interesting talks. Below are the ones I found rather inspiring to attend:

Bad Form by Chris Lienert

“Your password must contain an uppercase and a lowercase letter, a number, a dinosaur’s name and your grandmother’s maiden name”: do sights of such messages make you cringe? Or perhaps you recall the frustration of filling out a large form and you missed out checking those terms and conditions and the page complains by asking you to fill everything over again? If you do, this talk will let you share your frustrations and learn about what you as a developer can do to create better forms for a better web.

Fun with JavaScript and Sensors by Jan Jongboom

In terms of what JavaScript can do on the browser and on mobile devices, Firefox OS is the best example of openness and accessibility to the lower language features. Jan, in his talk introduces several sensor APIs, primarily for Firefox OS that you could make use of to create your next big innovative app or game. Perhaps you could even mix and match the data from various sensors, or perhaps from a set of devices put together to create something awesome!

Translation Workflow and Formatting Complex Translations by Tingan Ho

Tingan goes about solving the problem of i18n and l10n by introducing concepts like CLDR, pluralization, and ICU’s message formats. He also publishes his localization module l10ns at the end of his talk. If you’re planning to translate your app into multiple languages, especially east-Asian ones, this is a must see talk.

WebTorrent by Feross Aboukhadijeh

BitTorrent is a great protocol to share data between users across the world. Feross introduces the underlying functionality of BitTorrent and the advantages of a distributed network when compared to a centralized one. He also highlights certain shortcomings of the protocol that are centralized, like torrent files and tracker servers, and how we could solve these problems. Finally he describes WebTorrent, a project that makes use of WebRTC and special “hybrid clients” to connect to the BitTorrent network.

Gibbering at Algoraves - JS in Live Audiovisual Performances by Charlie Roberts

Possess certain skills like the ability to play music and you have the chance to perform it live in front of an audience. But writing code, especially JavaScript isn’t that way. That’s what we thought before this talk. Charlie introduces Gibber, a creative coding environment that lets you create music and visuals on the fly. Be ready for a trippy ride of a JavaScript live coding performance towards the end of the talk!

It might seem like I’ve described every talk at both the events, but the truth is that the quality of the talks was so impressive that it is hard to not praise the speakers for the efforts they have put in to prepare a stellar presentation. Looking forward to the next installment of DevFest Asia in 2015!