After the release of Headless Chrome browser (v59+) most of the automation tools slowly started reducing the usage of Selenium, by replacing it with the combination of chromedriver + chrome/chromium pre-installed browser (like Travis CI does on their images).

As a replacement, I’ve tried playing around with the combination of Karma/Chai to test JavaScript functionality of certain projects we have in Qobo. It only introduced the unit test approach towards the code base.

What I wanted was user automation, emulating browsers Page Object Model (POM). The choice fell on NightwatchJS library that works with headless Chrome and needs only minor tweaking.

Setting up NightwatchJS

I’ve used a combination of NightwatchJS with Mocha test framework. Even, Nightwatch has its own support of assertion methods for checks on the browser requests.

We start with package.json for Yarn/NPM.

    {
      "devDependencies": {
        "chromedriver": "^2.31.0",
        "mocha": "^3.5.0",
        "nightwatch": "^0.9.16"
      },
      "scripts": {
        "test": "./node_modules/nightwatch/bin/nightwatch"
      }
    }

yarn install and proceeding with nightwatch configurations:

const chromedriver = require('chromedriver');

module.exports = {
  before: function(done) {
    chromedriver.start();

    done();
  },

  after: function(done) {
    chromedriver.stop();

    done();
  }
};

After we explained the library how to handle chromedriver, we set the configurations for nightwatch.json:

    {
      "src_folders": ["tests/Frontend"], 
      "output_folder": "build/coverage/",
      "custom_commands_path": "",
      "custom_assertions_path": "",
      "page_objects_path": "",
      "globals_path": "globals.js",
      "selenium": {
        "start_process": false
      },
      "test_runner": {
        "type": "mocha",
        "options": {
            "ui": "bdd",
            "reporter": "list"
        }
      },
      "test_settings": {
        "default": {
          "selenium_port": 9515,
          "selenium_host": "localhost",
          "default_path_prefix" : "",
    
          "desiredCapabilities": {
            "browserName": "chrome",
            "chromeOptions" : {
              "args" : ["--no-sandbox", "--headless", "--disable-gpu"]
            },
            "acceptSslCerts": true
          }
        }
      }
    }

NightwatchJS still uses `selenium_`` naming options in the configurations (for backward compatibility reasons), so don’t get scared by the naming.

And the final touch, testing login action:

    describe('Testing login UsersController::login() method', () => {
        var loginUrl = 'http://localhost:8000/login';
    
        before(function(browser, done) {
          done();
        });
    
        after(function(browser, done) {
          browser.end(function() {
            done();
          });
        });
    
        afterEach(function(browser, done) {
          done();
        });
    
        beforeEach(function(browser, done) {
          done();
        });
    
        it('gets [login] page', (browser) => {
    
            browser
                .url(loginUrl)
                .waitForElementVisible('.login-box').present;
        });
    
        it('trying to [login]', (browser) => {
            browser
                .url(loginUrl)
                .waitForElementVisible('.login-box', 2000)
                .assert.elementPresent('input#username')
                .setValue('input#username', 'username')
                .assert.elementPresent('input#password')
                .setValue('input#password', 'password')
                .submitForm('form')
                .pause(2000)
                .assert.elementPresent('nav');
        });
    });

Running yarn test you should get something like this:

running nightwatchjs with yarn

NightwatchJS on Travis CI

Now, is configuring Travis CI to run NightwatchJS on a PHP. Configuration file derives from project-template-cakephp , (pull request #340 with NightWatchJS).

    sudo: true
    dist: trusty
    language: php
    php:
      - 5.6
      - 7.0
      - 7.1
      - nightly
    node_js:
      - "7"
    addons:
      chrome: stable
      cache:
        yarn: true
        directories:
          - node_modules
        before_script:
          - yarn install
          - ./bin/phpserv >/dev/null 2>&1 &
          - sleep 5
          # once you're done with PHPUnit/PHPCS,
          # it's time to check the UI with yarn testscript:
          - ./vendor/bin/phpunit --group example
          - ./vendor/bin/phpunit --exclude-group example
          - ./vendor/bin/phpcs  - yarn test