Vue: How do you add E2E tests after not including them in initial webpack template?

So there is no command that you can run to fix and add e2e, you need to fix it manually.

Edit

So it seems you created your project it was template 1.1.0

https://github.com/vuejs-templates/webpack/tree/1.1.0/template

So run

npm add chromedriver cross-spawn@^5.0.1 nightwatch@^0.9.12 selenium-server

I have removed chromedriver and selenium-server as the latest version won't hurt.

And download the content of this folder

https://github.com/vuejs-templates/webpack/tree/1.1.0/template/test/e2e

Also add/update "scripts" in package.json

"e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e",

Original answer

But the easiest way to do that would be to create two new projects project1, project2, name both of them project1 and add e2e in one and not in second. Then you can generate a git diff patch between the two. As per the latest template the patch file is below

e2e.patch

diff --git a/README.md b/README.md
index 500b31c..5960190 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,9 @@ npm run build --report
 # run unit tests
 npm run unit

+# run e2e tests
+npm run e2e
+
 # run all tests
 npm test
 ```
diff --git a/package.json b/package.json
index a4e8741..09d6452 100644
--- a/package.json
+++ b/package.json
@@ -8,8 +8,9 @@
     "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
     "start": "npm run dev",
     "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
-    "test": "npm run unit",
-    "lint": "eslint --ext .js,.vue src test/unit",
+    "e2e": "node test/e2e/runner.js",
+    "test": "npm run unit && npm run e2e",
+    "lint": "eslint --ext .js,.vue src test/unit test/e2e/specs",
     "build": "node build/build.js"
   },
   "dependencies": {
@@ -28,10 +29,13 @@
     "babel-plugin-transform-vue-jsx": "^3.5.0",
     "babel-preset-env": "^1.3.2",
     "babel-preset-stage-2": "^6.22.0",
+    "babel-register": "^6.22.0",
     "chai": "^4.1.2",
     "chalk": "^2.0.1",
+    "chromedriver": "^2.27.2",
     "copy-webpack-plugin": "^4.0.1",
     "cross-env": "^5.0.1",
+    "cross-spawn": "^5.0.1",
     "css-loader": "^0.28.0",
     "eslint": "^4.15.0",
     "eslint-config-standard": "^10.2.1",
@@ -57,6 +61,7 @@
     "karma-spec-reporter": "0.0.31",
     "karma-webpack": "^2.0.2",
     "mocha": "^3.2.0",
+    "nightwatch": "^0.9.12",
     "node-notifier": "^5.1.2",
     "optimize-css-assets-webpack-plugin": "^3.2.0",
     "ora": "^1.2.0",
@@ -66,6 +71,7 @@
     "postcss-loader": "^2.0.8",
     "postcss-url": "^7.2.1",
     "rimraf": "^2.6.0",
+    "selenium-server": "^3.0.1",
     "semver": "^5.3.0",
     "shelljs": "^0.7.6",
     "sinon": "^4.0.0",
diff --git a/test/e2e/custom-assertions/elementCount.js b/test/e2e/custom-assertions/elementCount.js
new file mode 100644
index 0000000..818e602
--- /dev/null
+++ b/test/e2e/custom-assertions/elementCount.js
@@ -0,0 +1,27 @@
+// A custom Nightwatch assertion.
+// The assertion name is the filename.
+// Example usage:
+//
+//   browser.assert.elementCount(selector, count)
+//
+// For more information on custom assertions see:
+// http://nightwatchjs.org/guide#writing-custom-assertions
+
+exports.assertion = function (selector, count) {
+  this.message = 'Testing if element <' + selector + '> has count: ' + count
+  this.expected = count
+  this.pass = function (val) {
+    return val === this.expected
+  }
+  this.value = function (res) {
+    return res.value
+  }
+  this.command = function (cb) {
+    var self = this
+    return this.api.execute(function (selector) {
+      return document.querySelectorAll(selector).length
+    }, [selector], function (res) {
+      cb.call(self, res)
+    })
+  }
+}
diff --git a/test/e2e/nightwatch.conf.js b/test/e2e/nightwatch.conf.js
new file mode 100644
index 0000000..f019c0a
--- /dev/null
+++ b/test/e2e/nightwatch.conf.js
@@ -0,0 +1,46 @@
+require('babel-register')
+var config = require('../../config')
+
+// http://nightwatchjs.org/gettingstarted#settings-file
+module.exports = {
+  src_folders: ['test/e2e/specs'],
+  output_folder: 'test/e2e/reports',
+  custom_assertions_path: ['test/e2e/custom-assertions'],
+
+  selenium: {
+    start_process: true,
+    server_path: require('selenium-server').path,
+    host: '127.0.0.1',
+    port: 4444,
+    cli_args: {
+      'webdriver.chrome.driver': require('chromedriver').path
+    }
+  },
+
+  test_settings: {
+    default: {
+      selenium_port: 4444,
+      selenium_host: 'localhost',
+      silent: true,
+      globals: {
+        devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
+      }
+    },
+
+    chrome: {
+      desiredCapabilities: {
+        browserName: 'chrome',
+        javascriptEnabled: true,
+        acceptSslCerts: true
+      }
+    },
+
+    firefox: {
+      desiredCapabilities: {
+        browserName: 'firefox',
+        javascriptEnabled: true,
+        acceptSslCerts: true
+      }
+    }
+  }
+}
diff --git a/test/e2e/runner.js b/test/e2e/runner.js
new file mode 100644
index 0000000..2722032
--- /dev/null
+++ b/test/e2e/runner.js
@@ -0,0 +1,48 @@
+// 1. start the dev server using production config
+process.env.NODE_ENV = 'testing'
+
+const webpack = require('webpack')
+const DevServer = require('webpack-dev-server')
+
+const webpackConfig = require('../../build/webpack.prod.conf')
+const devConfigPromise = require('../../build/webpack.dev.conf')
+
+let server
+
+devConfigPromise.then(devConfig => {
+  const devServerOptions = devConfig.devServer
+  const compiler = webpack(webpackConfig)
+  server = new DevServer(compiler, devServerOptions)
+  const port = devServerOptions.port
+  const host = devServerOptions.host
+  return server.listen(port, host)
+})
+.then(() => {
+  // 2. run the nightwatch test suite against it
+  // to run in additional browsers:
+  //    1. add an entry in test/e2e/nightwatch.conf.js under "test_settings"
+  //    2. add it to the --env flag below
+  // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
+  // For more information on Nightwatch's config file, see
+  // http://nightwatchjs.org/guide#settings-file
+  let opts = process.argv.slice(2)
+  if (opts.indexOf('--config') === -1) {
+    opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
+  }
+  if (opts.indexOf('--env') === -1) {
+    opts = opts.concat(['--env', 'chrome'])
+  }
+
+  const spawn = require('cross-spawn')
+  const runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
+
+  runner.on('exit', function (code) {
+    server.close()
+    process.exit(code)
+  })
+
+  runner.on('error', function (err) {
+    server.close()
+    throw err
+  })
+})
diff --git a/test/e2e/specs/test.js b/test/e2e/specs/test.js
new file mode 100644
index 0000000..a7b1bd9
--- /dev/null
+++ b/test/e2e/specs/test.js
@@ -0,0 +1,19 @@
+// For authoring Nightwatch tests, see
+// http://nightwatchjs.org/guide#usage
+
+module.exports = {
+  'default e2e tests': function (browser) {
+    // automatically uses dev Server port from /config.index.js
+    // default: http://localhost:8080
+    // see nightwatch.conf.js
+    const devServer = browser.globals.devServerURL
+
+    browser
+      .url(devServer)
+      .waitForElementVisible('#app', 5000)
+      .assert.elementPresent('.hello')
+      .assert.containsText('h1', 'Welcome to Your Vue.js App')
+      .assert.elementCount('img', 1)
+      .end()
+  }
+}

Save this file to your project as e2e.patch. Make sure you have made git repo in the project by running below

git init 
git add .
git commit -m "first version"

And then apply the patch to add e2e

git apply < e2e.patch
git add .
git commit -m "Added e2e"

These vue-cli v2 templates are "rendered" based on what you choose in the menu. When you choose e2e, the e2e flag is activated and every code that has {{#e2e}} (or similar) is added in the generated project. All you have to do is look for it in the template source.

So, basically, using karma+mocha, to have what the e2e flag adds you should:

  • Add the missing npm packages:

    npm i -D [email protected] [email protected] [email protected] [email protected] [email protected]
    
  • Create a test\e2e folder and add the 4 initial files of the e2e template folder (click here to see the folder).

    • Files
      • custom-assertions/elementCount.js
      • specs/test.js
        • Notice the template has: 'default e2e tests': function {{#if_eq lintConfig "airbnb"}}test{{/if_eq}}(browser) { which you probably want to be 'default e2e tests': function test(browser) { (regardless of having airbnb lint or not, won't hurt).
      • nightwatch.conf.js
      • runner.js
    • Example:

      # Being at the root of your project
      curl https://raw.githubusercontent.com/vuejs-templates/webpack/develop/template/test/e2e/custom-assertions/elementCount.js --create-dirs -o test/e2e/custom-assertions/elementCount.js
      curl https://raw.githubusercontent.com/vuejs-templates/webpack/develop/template/test/e2e/specs/test.js --create-dirs -o test/e2e/specs/test.js
      curl https://raw.githubusercontent.com/vuejs-templates/webpack/develop/template/test/e2e/nightwatch.conf.js --create-dirs -o test/e2e/nightwatch.conf.js
      curl https://raw.githubusercontent.com/vuejs-templates/webpack/develop/template/test/e2e/runner.js --create-dirs -o test/e2e/runner.js
      
  • Update the npm scripts in your package.json:

    • Add the e2e script:

      "scripts": {
          (...)
          "e2e": "node test/e2e/runner.js",
      
    • If you want npm test to also run e2e, add && npm run e2e to the test script as well:

      "test": "npm run unit && npm run e2e",
      
    • If you have linting activated, and want to lint the e2e specs, add test/e2e/specs folder:

      "lint": "eslint --ext .js,.vue src test/unit test/e2e/specs",
      

From looking at the template, that should be all.