Back to Repositories

Validating Nightwatch E2E Plugin Integration in Vue CLI

This test suite validates the Nightwatch E2E testing plugin integration with Vue CLI. It verifies plugin installation, configuration handling, and test execution across different environments and setups.

Test Coverage Overview

The test suite provides comprehensive coverage of Nightwatch E2E testing functionality in Vue CLI projects.

  • Basic test execution validation
  • Custom URL testing support
  • Single test file execution
  • Selenium server integration
  • Parallel test execution capabilities
  • Cross-browser testing with Firefox

Implementation Analysis

The implementation uses Jest as the test runner framework with async/await patterns for clean test organization. It leverages Vue CLI’s test utilities for project creation and server setup, with careful attention to environment-specific configurations.

  • Async test setup and teardown
  • Project fixture generation
  • Custom configuration file handling
  • Environment-specific timeout adjustments

Technical Details

  • Testing Framework: Jest
  • E2E Tool: Nightwatch.js
  • Key Dependencies: @vue/cli-test-utils, fs-extra
  • Configuration Files: nightwatch.json, nightwatch.conf.js
  • Test Environments: Headless, Firefox, Selenium
  • Custom Globals Support

Best Practices Demonstrated

The test suite exemplifies robust E2E testing practices with proper setup and teardown procedures, environment handling, and configuration management.

  • Dynamic timeout configuration
  • Resource cleanup
  • Environment-specific test skipping
  • Flexible configuration options
  • Parallel execution support
  • Cross-browser testing considerations

vuejs/vue-cli

packages/@vue/cli-plugin-e2e-nightwatch/__tests__/nightwatchPlugin.spec.js

            
jest.setTimeout(process.env.APPVEYOR ? 300000 : 120000)

const fs = require('fs-extra')
const path = require('path')
const create = require('@vue/cli-test-utils/createTestProject')
const createServer = require('@vue/cli-test-utils/createServer')

describe('nightwatch e2e plugin', () => {
  let project

  beforeAll(async () => {
    project = await create('e2e-nightwatch', {
      plugins: {
        '@vue/cli-plugin-babel': {},
        '@vue/cli-plugin-e2e-nightwatch': {},
        '@vue/cli-plugin-eslint': {
          config: 'airbnb',
          lintOn: 'save'
        }
      }
    })

    await project.run('vue-cli-service lint')

    await fs.copy(path.join(__dirname, './lib/globals-generated.js'),
      path.join(project.dir, 'tests/e2e/globals-generated.js'))

    const config = {
      globals_path: './tests/e2e/globals-generated.js'
    }
    await project.write('nightwatch.json', JSON.stringify(config))
  })

  test('should run all tests successfully', async () => {
    await project.run(`vue-cli-service test:e2e --headless`)
    let results = await project.read('test_results.json')
    results = JSON.parse(results)
    expect(Object.keys(results.modules)).toEqual([
      'test-with-pageobjects',
      'test'
    ])
  })

  test('should accept the --url cli option', async () => {
    let server
    try {
      await project.run(`vue-cli-service build`)
      server = createServer({ root: path.join(project.dir, 'dist') })
      await new Promise((resolve, reject) => {
        server.listen(8080, err => {
          if (err) return reject(err)
          resolve()
        })
      })
      await project.run(`vue-cli-service test:e2e --headless --url http://127.0.0.1:8080/`)

      let results = await project.read('test_results.json')
      results = JSON.parse(results)
      expect(Object.keys(results.modules)).toEqual([
        'test-with-pageobjects',
        'test'
      ])
    } finally {
      server && server.close()
    }
  })

  test('should run single test with custom nightwatch.json', async () => {
    await project.run(`vue-cli-service test:e2e --headless -t tests/e2e/specs/test.js`)
    let results = await project.read('test_results.json')
    results = JSON.parse(results)
    expect(Object.keys(results.modules)).toEqual([
      'test'
    ])
  })

  test.skip('should run single test with custom nightwatch.json and selenium server', async () => {
    await project.run(`vue-cli-service test:e2e --headless --use-selenium -t tests/e2e/specs/test.js`)
    let results = await project.read('test_results.json')
    results = JSON.parse(results)

    let testSettings = await project.read('test_settings.json')
    testSettings = JSON.parse(testSettings)

    expect(testSettings).toHaveProperty('selenium')
    expect(testSettings.selenium.start_process).toStrictEqual(true)
    expect(testSettings.selenium).toHaveProperty('cli_args')
    expect(Object.keys(results.modules)).toEqual([
      'test'
    ])
  })

  test.skip('should run tests in parallel', async () => {
    await project.run(`vue-cli-service test:e2e --headless --parallel`)
    let results = await project.read('test_results.json')
    results = JSON.parse(results)

    let testSettings = await project.read('test_settings.json')
    testSettings = JSON.parse(testSettings)

    expect(testSettings.parallel_mode).toStrictEqual(true)
    expect(testSettings.test_workers).toStrictEqual({
      enabled: true,
      workers: 'auto'
    })

    expect(Object.keys(results.modules).sort()).toEqual([
      'test', 'test-with-pageobjects'
    ])
  })

  // This test requires Firefox to be installed
  const testFn = process.env.APPVEYOR ? test.skip : test
  testFn('should run single test with custom nightwatch.conf.js in firefox', async () => {
    // nightwatch.conf.js take priority over nightwatch.json
    const copyConfig = fs.copy(path.join(__dirname, './lib/nightwatch.conf.js'),
      path.join(project.dir, 'nightwatch.conf.js'))

    const copyGlobals = fs.copy(path.join(__dirname, './lib/globals-gecko.js'),
      path.join(project.dir, 'tests/e2e/globals-gecko.js'))

    await Promise.all([copyConfig, copyGlobals])

    await project.run(`vue-cli-service test:e2e --headless --env firefox -t tests/e2e/specs/test.js`)
    let results = await project.read('test_results_gecko.json')
    results = JSON.parse(results)

    expect(Object.keys(results.modules)).toEqual([
      'test'
    ])
    expect(results.modules.test).toHaveProperty('reportPrefix')
    expect(results.modules.test.reportPrefix).toMatch(/^FIREFOX_.+/)
  })
})