No logs assertion for Nightwatch

Ensure React's PropTypes are respected

React’s property types are very helpful in ensuring good code quality.

One drawback of using PropTypes is that any violation is only reported to the console, as an error message.

It is too easy to change the code in one place which will break the property requirements in another. That breaking change can go unnoticed. The only way to notice it is to go through the application with the open console.

If you happen to use automated testing (which you should) it’s easy to add code to check for this problem.

I’m using nightwatch and I created small custom assertion which will fail if there were any console messages.

Thanks to Ramda code is very concise.

// content of noConsoleLogs.js file
const R = require('ramda');

exports.assertion = function () {
  this.message = 'Testing if any console errors are present';
  this.expected = '';
  this.pass = R.not;
  this.value = R.compose(R.join('\n'), R.map(R.prop('message')));
  this.command = callback => this.api.getLog('browser', callback);
};

this.message is the message printed to the console when this assertion is running.

this.expected is the value which needs to match what’s being returned from this.value for the assertion to pass. In this case, it’s an empty string which means we are expecting no messages.

this.pass is the method which determines if the assertion passed or not. Simply using R.not means only empty string will pass, everything else will cause the assertion to fail.

this.value extract the assertion value from the result of this.command. What it does is for all messages extract message property. Then it joins them with the newline as a separator. This gives readable output as each message will be on its own line (proceeded by script and line number when the message originated).

Finally this.command is the Nightwatch’s command to actually get log messages from the browser.

To use it’s just a matter of putting the assertion near the end of test case:

module.exports = {
  'Basic test': browser => {
    browser
      .url('http://example.com')
      .waitForElementVisible('#profile', 1000)
      .click('#profile')
      .assert.noConsoleLogs()
      .end();
  }
};

This piece of code already saved me from breaking changes and I know it will continue doing so in the future.