E2E testing in a Vue.js application

I’ve been working on a Vue.js application, and I was thinking how I can test it easily. The app have a couple of interesting libraries with custom directives and widgets, some of them with scoped-slot. Additionally I have 10-12 Vue components with hierarchical structure in differents .vue files, wich means I need to test features that (as usual) implies > 1 component. And in this case, I have 4 stores.

My first approach was using Jest, it is pretty easy to install and configure. I tried with 2 small and simpliest tests in the beginning and the result was good. But when I started to think to test larger units with 2 or more components, adding scoped-slots + store + custom libraries with custom components +… each tests was incredibly big and unmantainable. Everything for a really small application with in 10-12 components. It doesn’t makes sense to me. And an important issue: scoped-slot only can be emulated, but you can’t add those to the tests.

Second and great option was create E2E tests with Nightwatch.js. I installed it and configure locally and with BrowserStack pretty fast which allow me test on my Firefox and Chrome local installation but most important run my tests on different OS (like Windows and MacOS) and Browsers (like Chrome, Firefox, Safari), but most important I could create tests really easy. Let me show quickly how you can configure it locally on my laptop (Ubuntu 19.04) (installation process is available in docs):

In my root path I have this:

In test folder I have my tests, in conf my nightwatch config files (for BrowserStack and local), in output I have the JUnit XML files (those are results of Selenium tests). If some of the tests doesn’t result as expected, an screenshot is saved in screenshots folder. And finally in log folder there are log files with issues about tests and selenium server results.

Let’s see how looks my local nightwatch settings:

module.exports = {
    src_folders: ["e2e_tests/tests"],
    selenium: {
        launch_url: process.env.HOST,
        start_process: true,
        server_path: require('selenium-server').path,
        cli_args: {
            'webdriver.gecko.driver': require('geckodriver').path,
            'webdriver.chrome.driver': require('chromedriver').path
        },
        log_path: './e2e_tests/log'
    },
    test_settings: {
        default: {
            launch_url: process.env.HOST_TEST,
            screenshots : {
                enabled : true,
                on_failure : true,
                on_error : false,
                path : "./e2e_tests/screenshots"
            },
            output_folder: "./e2e_tests/output"
        },
        chrome: {
            desiredCapabilities : {
                browserName : 'chrome',
                alwaysMatch: {
                    acceptInsecureCerts: true
                },
                chromeOptions: {
                    w3c: false
                }
            },
            webdriver: {
                port: 4444,
                start_process: true,
                server_path: require('chromedriver').path,
                log_path: './e2e_tests/log'
            }
        },
        firefox: {
            desiredCapabilities : {
                browserName : 'firefox',
                alwaysMatch: {
                    acceptInsecureCerts: true
                }
            },
            webdriver: {
                start_process: true,
                port: 4444,
                server_path: require('geckodriver').path,
                log_path: './e2e_tests/log'
            }
        }
    }
}

This settings will open my local Chrome and Firefox browsers and run tests in port 4444.
Just to test the app quickly I can create a simple test in e2e_tests/test folder like:

// e2e_tests/tests/FirstTest.js
module.exports = {
    'Checking title must contains Hello World! string in HTML title' : function (browser) {
        browser
            .url(process.env.HOST)
            .waitForElementVisible('body')
            .assert.titleContains('Hello World!')
            .end();
    }
};

If I add this script in my package.json
"e2e": "./node_modules/.bin/nightwatch e2e_tests/tests/ -c ./e2e_tests/conf/nightwatch.conf.js"
I can run my first test on Chrome and Firefox running: $ npm run e2e -- --env firefox,chrome .
And tatan!! after open both browsers simultaneously and then close automatically, I got something like:

firefox [App] Test Suite
firefox ================
firefox - Connecting to localhost on port 4444…
firefox
firefox ℹ Connected to localhost on port 4444 (7131ms).
firefox Using: firefox (77.0.1) on linux 5.3.0-59-generic platform.
firefox Results for: Checking title must contains Hello World! string
firefox ✔ Element was visible after 142 milliseconds.
firefox ✔ Testing if the page title contains 'Hello World!' (10ms)
firefox ✔ firefox [App] Checking title must contains Hello World! string (5.429s)
firefox [Filter] Test Suite
firefox ===================

chrome [App] Test Suite
chrome ================
chrome - Connecting to localhost on port 4444…
chrome
chrome ℹ Connected to localhost on port 4444 (2494ms).
chrome Using: chrome (83.0.4103.116) on Linux platform.
chrome Results for: Checking title must contains Hello World! string
chrome ✔ Element was visible after 58 milliseconds.
chrome ✔ Testing if the page title contains 'Hello World!' (12ms)
chrome ✔ chrome [App] Checking title must contains Hello World! string (1.944s)
chrome [Filter] Test Suite
chrome ===================

OK. 2 total assertions passed (6.023s)

Now let’s see how looks my nightwatch config file for BrowserStack, so we can run our tests in multiple browsers and OS remotely:

// e2e_tests/conf/browserstack.nightwatch.conf.js

nightwatch_config = {
    src_folders: ["e2e_tests/tests"],
    selenium: {
        start_process: false,
        host: "hub-cloud.browserstack.com",
        port: 80,
        log_path: './e2e_tests/log',
        output_folder: "./e2e_tests/output"
    },
    test_settings: {
        default: {
            launch_url: process.env.HOST,
            screenshots : {
                enabled : true,
                on_failure : true,
                on_error : false,
                path : "./e2e_tests/screenshots"
            },
            log_path: './e2e_tests/log',
            output_folder: "./e2e_tests/output"
        },
        chrome_win10: {
            desiredCapabilities : {
                'browserstack.user': process.env.BROWSERSTACK_USER,
                'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
                'os': 'Windows',
                'os_version': '10',
                'browser': 'Chrome',
                'browser_version': (process.env.CHROME_W10_VERSION) ? process.env.CHROME_W10_VERSION : '83.0',
                'resolution': '1280x800'
            },
            webdriver: {
                log_path: './e2e_tests/log'
            },
            log_path: './e2e_tests/log',
            output_folder: "./e2e_tests/output"
        },
        chrome_catalina: {
            desiredCapabilities: {
                'browserstack.user': process.env.BROWSERSTACK_USER,
                'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
                'os': 'OS X',
                'os_version': 'Catalina',
                'browser': 'Chrome',
                'browser_version': (process.env.CHROME_CATALINA_VERSION) ? process.env.CHROME_CATALINA_VERSION :  '83.0',
                'resolution': '1280x800'
            },
            webdriver: {
                log_path: './e2e_tests/log'
            },
            log_path: './e2e_tests/log',
            output_folder: "./e2e_tests/output"
        },
        firefox_win10: {
            desiredCapabilities : {
                'browserstack.user': process.env.BROWSERSTACK_USER,
                'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
                'os': 'Windows',
                'os_version': '10',
                'browser': 'Firefox',
                'browser_version': (process.env.FIREFOX_W10_VERSION) ? process.env.FIREFOX_W10_VERSION : '77.0',
                'resolution': '1280x800'
            },
            webdriver: {
                log_path: './e2e_tests/log'
            },
            log_path: './e2e_tests/log',
            output_folder: "./e2e_tests/output"
        },
        firefox_catalina: {
            desiredCapabilities : {
                'browserstack.user': process.env.BROWSERSTACK_USER,
                'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
                'os': 'OS X',
                'os_version': 'Catalina',
                'browser': 'Firefox',
                'browser_version': (process.env.FIREFOX_CATALINA_VERSION) ? process.env.FIREFOX_CATALINA_VERSION : '77.0',
                'resolution': '1280x800'
            },
            webdriver: {
                log_path: './e2e_tests/log'
            },
            log_path: './e2e_tests/log',
            output_folder: "./e2e_tests/output"
        },
        safari_catalina: {
            desiredCapabilities: {
                'browserstack.user': process.env.BROWSERSTACK_USER,
                'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
                'os': 'OS X',
                'os_version': 'Catalina',
                'browser': 'Safari',
                'browser_version': (process.env.SAFARI_CATALINA_VERSION) ? process.env.SAFARI_CATALINA_VERSION : '13.0',
                'resolution': '1280x800'
            },
            webdriver: {
                log_path: './e2e_tests/log'
            },
            log_path: './e2e_tests/log',
            output_folder: "./e2e_tests/output"
        }
    }
};

// Code to copy seleniumhost/port into test settings
for(var i in nightwatch_config.test_settings){
    var config = nightwatch_config.test_settings[i];
    config['selenium_host'] = nightwatch_config.selenium.host;
    config['selenium_port'] = nightwatch_config.selenium.port;
}

module.exports = nightwatch_config;

In this file config will run my tests in BrowserStack on Chrome and Firefox in Windows10 and Catalina OS (Mac) and Safari on Catalina OS. Results of those tests will be in e2e_tests/output, but in BrowserStack App Live Dashboard as well with a nice Video and Screenshots. Awesome, eh?

In my package.json I added other script for BrowserStack tests: "e2e:browserstack": "node ./e2e_tests/conf/local.runner.js -c ./e2e_tests/conf/browserstack.nightwatch.conf.js"
So now I can run my tests just running: $ npm run e2e:browserstack -- --env firefox_win10,safari_catalina
I will get in my console something similar to:

Connecting local
Connected. Now testing…
firefox_win10 Using insecure HTTP connection on port 80. Consider using SSL by setting port to 443 in your Nightwatch configuration.
firefox_win10 [App] Test Suite
firefox_win10 ================
firefox_win10 - Connecting to hub-cloud.browserstack.com on port 80…
firefox_win10
firefox_win10 ℹ Connected to hub-cloud.browserstack.com on port 80 (10779ms).
firefox_win10 Using: firefox (77.0) on windows 10.0 platform.
firefox_win10 Results for: Checking title must contains Hello World! string
firefox_win10 ✔ Element was visible after 1999 milliseconds.
firefox_win10 ✔ Testing if the page title contains 'Hello World!' (418ms)
firefox_win10 ✔ firefox_win10 [App] Checking title must contains Hello World
! string (7.624s)
firefox_win10 Using insecure HTTP connection on port 80. Consider using SSL by setting port to 443 in your Nightwatch configuration.

In my BrowserStack App Live build for Firefox on Windows 10 I will see something like:

So finally, now I just need to add more tests and add it to my CI/CD pipeline.

Aaaaaaaaaand, today we have a super clasic Argentine musician who wrote incredible rock music since 80’s. One of him masterpiece is «El amor después del amor» (it’s Love after love).

 

Emigrate to Canada as a Developer

With the objective to help and inspire to families interested in emigrating to Canada as workers I recently talked about this issues through YouTube Live. It is in my native language: Spanish. You can use the YouTube translation feature.

Without any more preambles here the video:

That’s it, enjoy!

HEY HEY wait… music! This time I have something special. A few days ago a co-worker introduced me an incredible trumpeter: Ibrahim Maalouf! I never heard nothing similar… enjoy the trip:

 

Vue: watch a store object/array property

A few days ago using Vuex I tried to use watcher vue’s property to apply some changes in a specific vue’s component according to a store property. It looks easy to do, just adding to my component:

watch: {
    '$store.state.myStore.aProperty': function(newValue) {
        // do something
    }
}


If this.$store.state.myStore.aProperty it is not an object or array it should work perfectly. But in my case I would like to watch an array of objects. So this solution would not work, that’s because we should use deep property it’s something like:

watch: {
'$store.state.myStore.aProperty': {
deep: true,
handler(newValue): {
// do something
}
}
}

To my surprise this doesn’t work either, looking on internet (including in my favorite lifeguard: StackOverflow), I couldn’t find the solution easly. In fact I had to think about the issue and find my solution on my own, that’s because I’m writting it. Let’s see how looks my store and what’s the change I’m interested to watch:

let myStore = {
    aProperty: {}
};
export default {
    state: myStore,
    mutations: {
        setAProperty: (state, newValue) => {
          state.aProperty[newValue.key]= [];  
          state.aProperty[newValue.key].push(newValue.value)
        }
    }
}

I’m using a new key for my store object and as a value an array where I’m using the push method to add a new value.

Looks like push doesn’t dispatch the correct event to watch vue’s feature. But if I use assign values it works, it’s like: state.aProperty = otherObject it works. So I use a auxiliar variable to save a copy of the current store and re-assign it to the store object in order to dispatch the correct event for watch feature:

let myStore = {
    aProperty: {}
};
export default {
    state: myStore,
    mutations: {
        setAProperty: (state, newValue) => {
            let auxVar = Object.assign({}, state.aProperty);
            auxVar[newValue] = [];
            auxVar[newValue].push(newValue.value); // Using push in auxiliar var
            state.aProperty = auxVar; // This line will dispatch the correct event
        }
    }
}

I hope this is useful to you!


And now as usually let’s learn something interesting on music. Spinetta-Jade was a jazz / rock progressive Argentine band, with incredible exploration between Tango/Symphony rock/Jazz with high virtuosity in fretless bass (by Pedro Aznar), guitar (by Luis A. Spinetta) and other incredible musicians. I love this because it represents the exploration of popular 80’s Argentine rockers in Progressive rock and jazz, since in USA and England this stage was on the 70’s, in this case we add folk, tango and other influences that makes it a precious jewel in the Argentine culture.

 

Moving to Canada

Almost 3 years ago I haven’t written anything here! I am alive and I exist!

A few months ago I received an email from a Spanish company with an invitation to be part of a selection process to work as a developer. I never thought about the idea to move to another country for work, much less in Spain. After that experience, a few months later I received a LinkedIn messenge form a german IT recruiter for a job in Germany. That made me think I could work and move to another country.

Well, there was anything to stop me from doing it, so I started to think about it… but I guess for reasons of time and work I just abandoned the idea. Until a good day, I received an email from an Argentine recruiter living in Auckland and he had an interesting offer to work as a Sofware Develper in New Zeland. I remember that moment was like a sign that I should pay more attention about work in another country. At the same time my wife and I started to think about start a family.

If you are a Developer and think about your family, security and future, Latin America is not a good option at the moment, trust me. The question is, where could be an acceptable option? After research and try to understand what we want for our family and what is important for my career, we found Canada sounds like the best option for us.

I mean it is not just about the country, the culture, the safe place, etc. It’s about my career as well. I will spent most of my time with my colleagues, my teammates working for a product or service that I need to trust, in a company with nice values and culture aligned to my expectations, I should like this and stay motivated. So, I spent some time time thinking and discussing with my wife about our future, the objectives in my career, my next steps as a Software Developer, you know it is a really great and important change for our lifes and for my career.

The question are: Are there opportunities as a Developer in Canada? How to move to Canada if you are a Developer? What I need to move to Canada as a Developer? and there are a lot of other questions that I had around this. I sent five or six resumes to a different companies via LinkedIn without success. Fortunately I found VanHack a great company that makes a great job bringing Canadian (and European) companies closer to qualified candidates trough a modern platform and system. Try it, it’s free! it will save you a lot of time and resources trying to answer the questions I mentioned if you are thinking about work in Canada. If you spend time and effort you will get your job in Canada more easier and in less time.

Thanks to VanHack and the effort dedicated to make a plan and a hard preparation now I’m working for Pressbook an amazing Canadian company, remotely at first but ready to move to Montreal for work when visa is ready with increible teammates highly qualified and motivated creating and developing a super interesating open source product that allow hosts and mantain book production networks for academic institutions, presses and consortia. Once more time I feel I’m working for real and interesting purposes, and on the other hand with the incredible opportunity for me and my family to move to Canada soon!

Thanks Pressbooks, VanHack and God for this opportunity of a new life for me and my family.

Do you think you’ve heard tehcnically complex music? I believed that yes, I mean there are incredible genius… but let me show you something:

 

 

MavensManager: features for Poker Mavens

Mavens Manager

I developed a new product for Poker Mavens of Briggsoft Works: MavensManager.

MavensManager is a backend for owners of Poker Rooms with Poker Mavens developed with CakePHP 3.xx (API) and AngularJS (Front End). Jackpot, Rake in realtime, Stats and an Affiliate system are some of the features.

Each user can view all the reports and histories of the game, and get stats for know trends of their business.

Remembering good music

 

Cut the middleman in Programmatic Advertising

Taggify just launched a new platform that allow get your own bidder within a few minutes! You can get 1 to N bidders and distribute your endpoints selecting the location based on supply and latency.

Other great features: Up to 12000 QPS per instance and with Real-Time access to metrics!

Bamboo is a conductive pipe with no intermediaries, programmatic media buying through Real Time Bidding!

More in: http://bamboo.taggify.net

 

Leading a team

There are many ways for lead a development team. Some of them require a work of long term, and other are more practical. The long term is not viable, because the members of a team in this sector is changing constantly.

I know three ways for lead a team that is succesfull if we combine them:

Leader with direct orders
table-militar-startupThis dictatorial way can be used when a project is in crisis, about to fall. In this case the team need a decisive leader and with personality. Also is helpful when must be a make radical changes. Sometimes the members resist to radical changes, or to new labor policies.

If you have member without compromise or enthusiasm you would up the team with this way. But this not good to long term, because some people can be desmotivated.

The coach leader

coaching-leaderThe coach leader is a technical referent that cooperates with all the team. He take desicions together with all members. Using this method, you should share the knowledge and generate feedback constantly . Each step is explained and discussed with the workteam, empathy and enthusiasm and promoting the personal growth.

The risk of this is the low productivity because the under control.

 

The director

director-leaderWorking of this mode the leader shows the way, directs the activities and monitors all process but doesn’t participating directly. Supports all their trust in your team. This is useful in teams with high degree of motivation and compromise. In short: direct and delegate.

The great disadvantage of this is that team feel that their leader is not actively part of the team and no commitment as equals.

You must combine this ways, depending of the circumstances. Anyway, be honest, listen of your team, delegate and respect regardless of the technique used, is the most important… for me 🙂

 

Before starting a new application for Start Up projects

Many times is thought that when starting a new start up project, we must be quick in gather the requirements, quick in development process, quick in test process… etc. We must devote specially attention and time to the requirement process. This step is the more important, and this step is decisive for the success or failure of the project.

I thought some fast tips for starting a new start up project:

  • Gather information about the customer company:
    • Objectives, services, products. Is a USP? (Unique Selling Proposition).
    • Competitors.
    • Define the targeted audience for the new application (age, social sector, etc).
  • Access to the application (devices, resolutions, etc)
  • What likes/dislikes of the other applications.
  • Define the limit for the plan project: final date, resources

checking list start up

This few points seem fast, but it is a round trip with the customer of many meetings before starting the new project. In each meeting the customer will define new features and flows, and the original idea will mutate.
Mutate a started application can be very difficult, or not viable, for that reason define this points before of start is the best way of avoid the failure.

Define first… take five 🙂

 

Documenting start up projects

In software engineering become independent the people of the processes is not an easy task. Even more in  start up projects. We can know some methods and practices that we are likely to lead to success, but we are never entirely sure and that’s because every project and every workteam is a world in itself. However, we can always limit to the maximum the errors and failures following simple practices and processes that will help us not to trip over the same stones.

Why document?

One of the advantages of having trained leaders in the workteams is that we can count on your experience. They will remember cases and situations that led to the triumph of their teams and recognize those practices that led to fail. One of the problems is that in the development market and start up solutions, the workteams are disassembled and technologies and processes become obsolete quickly.road to success documenting
When a challenge arises or a new project appears, the first thing we do is look for documentation about it. Seems that there is always someone who has taken the trouble to share and document information. We have to document in detail our successes and to apply it despite the time, techonologies and workteams. We analyze and write what led us to a happy ending, or failure to learn from it. But also for others who continue to the project, or who entering the team to have everything needed to adapt and continue working -which means cost savings when it comes to bring in a new member-. It’s very common to see people coming and going every day in the development companies, and is more common to see companies lose the control of their projects by this constant employees flow.

When making decisions in a team, forms of work are chosen or agreements are made, is important to write and document a methodical way. All agreed and discussed at each meeting must be captured to take it as reference and guide for our daily work. Is very easy that the words are carried by the wind, and the responsible persons are hidden behind this fact. When the agreement is documented we have a record and evidence that sometimes it helps to keep the wheels on the road.
This documentation of agreements and meetings is also valid for customers, they also must be able to refer to everything discussed and agreed in an easy way and anytime.

How to document start up projects?

document shared start upThe customers want efficient and simple products, but mainly they want it fast and at low cost. Document takes time, therefore increases directly on the cost of the final product. Find the balance between a relatively detailed documentation and the time available to apply is one of the challenges of development of agile applications companies.

There are many methodologies to implement at low cost but in any case it requires a number of practices in the development process and a series of complaints from developers too :). In any case you will need:

  • An initial documentation to clarify the proccesses of documentation of projects.
  • A control process that ensures that all member of the teams follow the documentation process.
  • A quick and easy way to write processes, meetings, agreements, technologies used, way to application and activities taking place.
  • A tool easy to learn and does not require lot time of maintenance.

This is how a policy of documentation in your workteam will allow you the projects become independent to the people, learn from your mistakes and repeat your success.

Now, as always for closing I leave a new auditory adventure 🙂