text: /* global client */
  /* eslint-env mocha */
  const chai = require('chai')
  chai.should()
  const testCaseFactory = require('./test-case-factory')
  
  describe('Utility features', () => {
    it('should be able to run together with plain Nightwatch tests', () => {
      return testCaseFactory
        .create('include-plain-nightwatch-tests', { includePlainNightwatchTests: true })
        .feature('addition')
        .scenario('small numbers')
        .given('User is on the simple calculator page', () => client.init())
        .and('User enter 4 in A field', () => client.setValue('#a', 4))
        .and('User enter 5 in B field', () => client.setValue('#b', 5))
        .when('User press Add button', () => client.click('#add'))
        .then('The result should contain 9', () => client.assert.containsText('#result', 9))
        .scenario('big numbers')
        .given('User is on the simple calculator page')
        .and('User enter 4 in A field')
        .and('User enter 5 in B field')
        .when('User press Add button')
        .then('The result should contain 9')
        .feature('subtraction')
        .scenario('small numbers')
        .given('User is on the simple calculator page')
        .and('User enter 9 in A field', () => client.setValue('#a', 9))
        .and('User enter 3 in B field', () => client.setValue('#b', 3))
        .when('User press Subtract button', () => client.click('#subtract'))
        .then('The result should contain 6', () => client.assert.containsText('#result', 6))
        .scenario('big numbers')
        .given('User is on the simple calculator page')
        .and('User enter 4 in A field')
        .and('User enter 5 in B field')
        .when('User press Subtract button')
        .then('The result should contain -1', () => client.assert.containsText('#result', -1))
        .run()
        .then((result) => {
          result.features[0].result.status.should.be.passed
          result.features[0].result.scenarioCounts.should.deep.equal({passed: 2})
          result.features[0].scenarios[0].result.status.should.be.passed
          result.features[0].scenarios[0].result.stepCounts.should.deep.equal({passed: 5})
          result.features[0].scenarios[1].result.status.should.be.passed
          result.features[0].scenarios[1].result.stepCounts.should.deep.equal({passed: 5})
          result.features[1].result.status.should.be.passed
          result.features[1].result.scenarioCounts.should.deep.equal({passed: 2})
          result.features[1].scenarios[0].result.status.should.be.passed
          result.features[1].scenarios[0].result.stepCounts.should.deep.equal({passed: 5})
          result.features[1].scenarios[1].result.status.should.be.passed
          result.features[1].scenarios[1].result.stepCounts.should.deep.equal({passed: 5})
          result.output.should.contain('OK. 4  total assertions passed.')
        })
    })
  
    it('should handle page objects failure', () => {
      return testCaseFactory
        .create('page-object-failure-test')
        .pageObject('calculator', `module.exports = {
    elements: {
      numberA: '#a',
      numberB: '#b',
      addButton: '#add',
      result: '#result'
    }
  }`)
        .feature('addition')
        .scenario('small numbers')
        .given('User is on the simple calculator page', () => client.init())
        .and('User enter 4 in A field', () => {
          const calculator = client.page.calculator()
          return calculator.setValue('@numberA', 4)
        })
        .and('User enter 5 in B field', () => {
          const calculator = client.page.calculator()
          return calculator.setValue('@numberB', 5)
        })
        .when('User press Add button', () => {
          const calculator = client.page.calculator()
          return calculator.click('@addButton')
        })
        .then('The result should contain 10', () => {
          const calculator = client.page.calculator()
          return calculator.assert.containsText('@result', 10)
        })
        .run()
        .then((result) => {
          result.features[0].result.status.should.be.failed
          result.features[0].result.scenarioCounts.should.deep.equal({failed: 1})
          result.features[0].scenarios[0].result.status.should.be.failed
          result.features[0].scenarios[0].result.stepCounts.should.deep.equal({passed: 4, failed: 1})
        })
    })
  
    it('should handle paralell tests', () => {
      return testCaseFactory
        .create('paralell-test', { paralell: true })
        .feature('addition')
        .scenario('small numbers')
        .given('User is on the simple calculator page', () => client.init())
        .and('User enter 4 in A field', () => client.setValue('#a', 4))
        .and('User enter 5 in B field', () => client.setValue('#b', 5))
        .when('User press Add button', () => client.click('#add'))
        .then('The result should contain 9', () => client.assert.containsText('#result', 9))
        .scenario('big numbers')
        .given('User is on the simple calculator page')
        .and('User enter 4 in A field')
        .and('User enter 5 in B field')
        .when('User press Add button')
        .then('The result should contain 9')
        .feature('subtraction')
        .scenario('small numbers')
        .given('User is on the simple calculator page')
        .and('User enter 9 in A field', () => client.setValue('#a', 9))
        .and('User enter 3 in B field', () => client.setValue('#b', 3))
        .when('User press Subtract button', () => client.click('#subtract'))
        .then('The result should contain 6', () => client.assert.containsText('#result', 6))
        .scenario('big numbers')
        .given('User is on the simple calculator page')
        .and('User enter 4 in A field')
        .and('User enter 5 in B field')
        .when('User press Subtract button')
        .then('The result should contain -1', () => client.assert.containsText('#result', -1))
        .run()
        .then((result) => {
          result.features[0].result.status.should.be.passed
          result.features[0].result.scenarioCounts.should.deep.equal({passed: 2})
          result.features[0].scenarios[0].result.status.should.be.passed
          result.features[0].scenarios[0].result.stepCounts.should.deep.equal({passed: 5})
          result.features[0].scenarios[1].result.status.should.be.passed
          result.features[0].scenarios[1].result.stepCounts.should.deep.equal({passed: 5})
          result.features[1].result.status.should.be.passed
          result.features[1].result.scenarioCounts.should.deep.equal({passed: 2})
          result.features[1].scenarios[0].result.status.should.be.passed
          result.features[1].scenarios[0].result.stepCounts.should.deep.equal({passed: 5})
          result.features[1].scenarios[1].result.status.should.be.passed
          result.features[1].scenarios[1].result.stepCounts.should.deep.equal({passed: 5})
        })
    })
  
    it('should handle event handlers without callback', () => {
      return testCaseFactory
        .create('event-handlers-without-callback-test', { eventHandlersWithoutCallback: true })
        .feature('addition')
        .scenario('small numbers')
        .given('Nothing', () => {})
        .when('Nothing')
        .then('Nothing')
        .scenario('big numbers')
        .given('Nothing')
        .when('Nothing')
        .then('Nothing')
        .feature('subtraction')
        .scenario('small numbers')
        .given('Nothing')
        .when('Nothing')
        .then('Nothing')
        .scenario('big numbers')
        .given('Nothing')
        .when('Nothing')
        .then('Nothing')
        .run()
        .then((result) => {
          result.ipcMessages.should.contain('<F<f<S<ss><ss><ss>S><S<ss><ss><ss>S>f><f<S<ss><ss><ss>S><S<ss><ss><ss>S>f>F>')
        })
    })
  
    it('should handle event handlers with callback', () => {
      return testCaseFactory
        .create('event-handlers-with-callback-test', { eventHandlersWithCallback: true })
        .feature('addition')
        .scenario('small numbers')
        .given('Nothing', () => {})
        .when('Nothing')
        .then('Nothing')
        .scenario('big numbers')
        .given('Nothing')
        .when('Nothing')
        .then('Nothing')
        .feature('subtraction')
        .scenario('small numbers')
        .given('Nothing')
        .when('Nothing')
        .then('Nothing')
        .scenario('big numbers')
        .given('Nothing')
        .when('Nothing')
        .then('Nothing')
        .run()
        .then((result) => {
          result.ipcMessages.should.contain('2additionsmall numbersNothingNothingNothingNothingNothingNothingsmall numbersbig numbersNothingNothingNothingNothingNothingNothingbig numbersadditionsubtractionsmall numbersNothingNothingNothingNothingNothingNothingsmall numbersbig numbersNothingNothingNothingNothingNothingNothingbig numberssubtraction2')
        })
    })
  
    it('should handle hooks', () => {
      return testCaseFactory
        .create('hooks-test', { hooks: true })
        .feature('addition')
        .scenario('small numbers')
        .given('Nothing', function () {})
        .when('Nothing')
        .then('Nothing')
        .scenario('big numbers')
        .given('Nothing')
        .when('Nothing')
        .then('Nothing')
        .feature('subtraction')
        .scenario('small numbers', ['a'])
        .given('Nothing')
        .when('Nothing')
        .then('Nothing')
        .scenario('big numbers', ['b'])
        .given('Nothing')
        .when('Nothing')
        .then('Nothing')
        .run()
        .then((result) => {
          result.ipcMessages.should.contain('<SS><SS><SS><SS>')
          result.ipcMessages.should.contain([
            'before-a-b-small numbers',
            'before-a-b-big numbers',
            'before-b-cb-big numbers',
            'before-b-promise-big numbers',
            'after-b-promise-big numbers',
            'after-b-cb-big numbers',
            'after-b-big numbers'
          ].join(''))
        })
    })
  
    it('should be able to run using Gulp build tool', () => {
      return testCaseFactory
        .create('gulp-build-test', { gulp: true })
        .feature('addition')
        .scenario('small numbers')
        .given('User is on the simple calculator page', () => client.init())
        .and('User enter 4 in A field', () => client.setValue('#a', 4))
        .and('User enter 5 in B field', () => client.setValue('#b', 5))
        .when('User press Add button', () => client.click('#add'))
        .then('The result should contain 9', () => client.assert.containsText('#result', 9))
        .scenario('big numbers')
        .given('User is on the simple calculator page')
        .and('User enter 4 in A field')
        .and('User enter 5 in B field')
        .when('User press Add button')
        .then('The result should contain 9')
        .feature('subtraction')
        .scenario('small numbers')
        .given('User is on the simple calculator page')
        .and('User enter 9 in A field', () => client.setValue('#a', 9))
        .and('User enter 3 in B field', () => client.setValue('#b', 3))
        .when('User press Subtract button', () => client.click('#subtract'))
        .then('The result should contain 6', () => client.assert.containsText('#result', 6))
        .scenario('big numbers')
        .given('User is on the simple calculator page')
        .and('User enter 4 in A field')
        .and('User enter 5 in B field')
        .when('User press Subtract button')
        .then('The result should contain -1', () => client.assert.containsText('#result', -1))
        .run()
        .then((result) => {
          result.features[0].result.status.should.be.passed
          result.features[0].result.scenarioCounts.should.deep.equal({passed: 2})
          result.features[0].scenarios[0].result.status.should.be.passed
          result.features[0].scenarios[0].result.stepCounts.should.deep.equal({passed: 5})
          result.features[0].scenarios[1].result.status.should.be.passed
          result.features[0].scenarios[1].result.stepCounts.should.deep.equal({passed: 5})
          result.features[1].result.status.should.be.passed
          result.features[1].result.scenarioCounts.should.deep.equal({passed: 2})
          result.features[1].scenarios[0].result.status.should.be.passed
          result.features[1].scenarios[0].result.stepCounts.should.deep.equal({passed: 5})
          result.features[1].scenarios[1].result.status.should.be.passed
          result.features[1].scenarios[1].result.stepCounts.should.deep.equal({passed: 5})
          result.output.should.contain('Finished \'default\' after')
        })
    })
  
    it('should be able to run using Grunt build tool', () => {
      return testCaseFactory
        .create('grunt-build-test', { grunt: true })
        .feature('addition')
        .scenario('small numbers')
        .given('User is on the simple calculator page', () => client.init())
        .and('User enter 4 in A field', () => client.setValue('#a', 4))
        .and('User enter 5 in B field', () => client.setValue('#b', 5))
        .when('User press Add button', () => client.click('#add'))
        .then('The result should contain 9', () => client.assert.containsText('#result', 9))
        .scenario('big numbers')
        .given('User is on the simple calculator page')
        .and('User enter 4 in A field')
        .and('User enter 5 in B field')
        .when('User press Add button')
        .then('The result should contain 9')
        .feature('subtraction')
        .scenario('small numbers')
        .given('User is on the simple calculator page')
        .and('User enter 9 in A field', () => client.setValue('#a', 9))
        .and('User enter 3 in B field', () => client.setValue('#b', 3))
        .when('User press Subtract button', () => client.click('#subtract'))
        .then('The result should contain 6', () => client.assert.containsText('#result', 6))
        .scenario('big numbers')
        .given('User is on the simple calculator page')
        .and('User enter 4 in A field')
        .and('User enter 5 in B field')
        .when('User press Subtract button')
        .then('The result should contain -1', () => client.assert.containsText('#result', -1))
        .run()
        .then((result) => {
          result.features[0].result.status.should.be.passed
          result.features[0].result.scenarioCounts.should.deep.equal({passed: 2})
          result.features[0].scenarios[0].result.status.should.be.passed
          result.features[0].scenarios[0].result.stepCounts.should.deep.equal({passed: 5})
          result.features[0].scenarios[1].result.status.should.be.passed
          result.features[0].scenarios[1].result.stepCounts.should.deep.equal({passed: 5})
          result.features[1].result.status.should.be.passed
          result.features[1].result.scenarioCounts.should.deep.equal({passed: 2})
          result.features[1].scenarios[0].result.status.should.be.passed
          result.features[1].scenarios[0].result.stepCounts.should.deep.equal({passed: 5})
          result.features[1].scenarios[1].result.status.should.be.passed
          result.features[1].scenarios[1].result.stepCounts.should.deep.equal({passed: 5})
          result.output.should.contain('Running "nightwatch:default" (nightwatch) task')
        })
    })
  
    it('should be able to run using programmatical API', () => {
      return testCaseFactory
        .create('run-programmatical-test', { programmatical: true })
        .feature('addition')
        .scenario('small numbers')
        .given('User is on the simple calculator page', () => client.init())
        .and('User enter 4 in A field', () => client.setValue('#a', 4))
        .and('User enter 5 in B field', () => client.setValue('#b', 5))
        .when('User press Add button', () => client.click('#add'))
        .then('The result should contain 9', () => client.assert.containsText('#result', 9))
        .scenario('big numbers')
        .given('User is on the simple calculator page')
        .and('User enter 4 in A field')
        .and('User enter 5 in B field')
        .when('User press Add button')
        .then('The result should contain 9')
        .feature('subtraction')
        .scenario('small numbers')
        .given('User is on the simple calculator page')
        .and('User enter 9 in A field', () => client.setValue('#a', 9))
        .and('User enter 3 in B field', () => client.setValue('#b', 3))
        .when('User press Subtract button', () => client.click('#subtract'))
        .then('The result should contain 6', () => client.assert.containsText('#result', 6))
        .scenario('big numbers')
        .given('User is on the simple calculator page')
        .and('User enter 4 in A field')
        .and('User enter 5 in B field')
        .when('User press Subtract button')
        .then('The result should contain -1', () => client.assert.containsText('#result', -1))
        .run()
        .then((result) => {
          result.features[0].result.status.should.be.passed
          result.features[0].result.scenarioCounts.should.deep.equal({passed: 2})
          result.features[0].scenarios[0].result.status.should.be.passed
          result.features[0].scenarios[0].result.stepCounts.should.deep.equal({passed: 5})
          result.features[0].scenarios[1].result.status.should.be.passed
          result.features[0].scenarios[1].result.stepCounts.should.deep.equal({passed: 5})
          result.features[1].result.status.should.be.passed
          result.features[1].result.scenarioCounts.should.deep.equal({passed: 2})
          result.features[1].scenarios[0].result.status.should.be.passed
          result.features[1].scenarios[0].result.stepCounts.should.deep.equal({passed: 5})
          result.features[1].scenarios[1].result.status.should.be.passed
          result.features[1].scenarios[1].result.stepCounts.should.deep.equal({passed: 5})
        })
    })
  
    it('should be able to provide Nightwatch client as step definition first parameter', () => {
      return testCaseFactory
        .create('test-nightwatch-client-as-parameter')
        .feature('addition')
        .scenario('small numbers')
        .given('User is on the simple calculator page', () => client.init())
        .and('User enter "4" in A field', (a) => client.setValue('#a', a))
        .and('User enter "5" in B field', (b) => client.setValue('#b', b))
        .when('User press Add button', () => client.click('#add'))
        .then('The result should contain "9"', (result) => client.assert.containsText('#result', result))
        .scenario('big numbers')
        .given('User is on the simple calculator page')
        .and('User enter "44" in A field')
        .and('User enter "55" in B field')
        .when('User press Add button')
        .then('The result should contain "99"')
        .run()
        .then((result) => {
          result.features[0].result.status.should.be.passed
          result.features[0].result.scenarioCounts.should.deep.equal({passed: 2})
          result.features[0].scenarios[0].result.status.should.be.passed
          result.features[0].scenarios[0].result.stepCounts.should.deep.equal({passed: 5})
          result.features[0].scenarios[1].result.status.should.be.passed
          result.features[0].scenarios[1].result.stepCounts.should.deep.equal({passed: 5})
        })
    })
  })
  