Vue:在初始 webpack 模板中不包含 E2E 测试后,如何添加它们?

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

为了开始我的项目,我 运行 vue init webpack my-project,但我排除了 E2E 测试。现在我改变了主意 do 想要包括 E2E 测试。如何将它们添加到我的项目中?

读者注意:对我来说效果很好。但是您可能需要考虑使用 TestCafe,因为它无需任何配置即可工作。


我试过使用命令 vue init webpack my--project 创建一个虚拟项目,这样我就可以复制粘贴 test/e2e 目录,然后尝试从那里开始工作,但没有成功。我也复制粘贴了 npm 脚本,尝试了 运行ning npm run e2e,然后根据收到的错误消息更新了我的代码。

我遇到了 TypeError: webpack.optimize.ModuleConcatenationPlugin is not a constructor 错误。 const webpack = require('webpack'),并且我已经 运行 npm update 确保 webpack 节点模块是最新的,所以我不知道为什么会出现该错误.

无论如何,这种尝试 运行 npm run e2e 然后根据错误消息更新我的代码的方法似乎不太可能成功。


package.json

{
  "name": "premium-poker-tools",
  "version": "1.0.0",
  "description": "A Vue.js project",
  "author": "Adam Zerner <azerner3@gmail.com>",
  "private": true,
  "scripts": {
    "dev": "node build/dev-server.js",
    "start": "node build/dev-server.js",
    "build": "node build/build.js",
    "test": "BABEL_ENV=test karma start test/unit/karma.conf.js",
    "deploy": "git subtree push --prefix dist heroku master"
  },
  "dependencies": {
    "bootstrap": "^3.3.7",
    "bootstrap-sass": "^3.3.7",
    "chart.js": "^2.5.0",
    "express-sslify": "^1.2.0",
    "jquery": "^3.2.1",
    "lodash": "^4.17.4",
    "vue": "^2.4.2",
    "vue-analytics": "^5.1.1",
    "vue-chartjs": "^2.8.7",
    "vue-router": "^2.7.0",
    "vue-slider-component": "^2.5.8",
    "vuex": "^3.0.0"
  },
  "devDependencies": {
    "autoprefixer": "^7.1.2",
    "babel-core": "^6.22.1",
    "babel-loader": "^7.1.1",
    "babel-plugin-istanbul": "^4.1.1",
    "babel-plugin-transform-runtime": "^6.22.0",
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.3.2",
    "babel-preset-stage-2": "^6.22.0",
    "babel-register": "^6.22.0",
    "chai": "^3.5.0",
    "chalk": "^2.0.1",
    "connect-history-api-fallback": "^1.3.0",
    "copy-webpack-plugin": "^4.0.1",
    "cross-env": "^5.0.1",
    "css-loader": "^0.28.0",
    "cssnano": "^3.10.0",
    "eventsource-polyfill": "^0.9.6",
    "express": "^4.14.1",
    "extract-text-webpack-plugin": "^2.0.0",
    "file-loader": "^0.11.1",
    "friendly-errors-webpack-plugin": "^1.1.3",
    "html-webpack-plugin": "^2.28.0",
    "http-proxy-middleware": "^0.17.3",
    "inject-loader": "^3.0.0",
    "karma": "^1.4.1",
    "karma-coverage": "^1.1.1",
    "karma-mocha": "^1.3.0",
    "karma-phantomjs-launcher": "^1.0.2",
    "karma-phantomjs-shim": "^1.4.0",
    "karma-sinon-chai": "^1.3.1",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-spec-reporter": "0.0.31",
    "karma-webpack": "^2.0.2",
    "mocha": "^3.2.0",
    "node-sass": "^4.5.3",
    "opn": "^5.1.0",
    "optimize-css-assets-webpack-plugin": "^2.0.0",
    "ora": "^1.2.0",
    "phantomjs-prebuilt": "^2.1.14",
    "rimraf": "^2.6.0",
    "sass-loader": "^6.0.6",
    "semver": "^5.3.0",
    "shelljs": "^0.7.6",
    "sinon": "^2.1.0",
    "sinon-chai": "^2.8.0",
    "url-loader": "^0.5.8",
    "vue-loader": "^13.0.4",
    "vue-style-loader": "^3.0.1",
    "vue-template-compiler": "^2.4.2",
    "webpack": "^2.6.1",
    "webpack-bundle-analyzer": "^2.2.1",
    "webpack-dev-middleware": "^1.10.0",
    "webpack-hot-middleware": "^2.18.0",
    "webpack-merge": "^4.1.0",
    "worker-loader": "^1.1.1"
  },
  "engines": {
    "node": ">= 4.0.0",
    "npm": ">= 3.0.0"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

因此没有可以运行修复和添加e2e的命令,您需要手动修复。

编辑

看来您创建的项目是模板 1.1.0

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

所以运行

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

我已经删除了 chromedriverselenium-server,因为最新版本不会造成伤害。

并下载此文件夹的内容

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

还有add/update"scripts"在package.json

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

原回答

但最简单的方法是创建两个新项目 project1project2,将它们命名为 project1 并在其中一个而不是第二个中添加 e2e。然后你可以在两者之间生成一个 git diff 补丁。根据最新模板,补丁文件如下

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()
+  }
+}

将此文件作为 e2e.patch 保存到您的项目中。确保你已经通过下面的 运行ning

在项目中创建了 git repo
git init 
git add .
git commit -m "first version"

然后应用补丁添加e2e

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

这些 vue-cli v2 模板 "rendered" 基于您在菜单中选择的内容。当您选择 e2e 时,e2e 标志被激活,每个具有 {{#e2e}}(或类似)的代码都会添加到生成的项目中。您所要做的就是在 template source.

中查找它

所以,基本上,使用 karma+mocha,要获得 e2e 标志添加的东西,你应该:

  • 补充缺失的npm packages:

    npm i -D babel-register@6.22.0 chromedriver@2.27.2 cross-spawn@5.0.1 nightwatch@0.9.12 selenium-server@3.0.1
    
  • 创建一个test\e2e文件夹并添加e2e template folder (click here to see the folder)的4个初始文件。

    • 文件
    • 示例:

      # 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
      
  • 更新 package.json 中的 npm scripts:

    • 添加e2e脚本:

      "scripts": {
          (...)
          "e2e": "node test/e2e/runner.js",
      
    • 如果您希望 npm test 也 运行 e2e,请将 && npm run e2e 添加到 test 脚本中:

      "test": "npm run unit && npm run e2e",
      
    • 如果您激活了 linting,并希望对 e2e 规范进行 lint,请添加 test/e2e/specs 文件夹:

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

从模板来看,应该就这些了。

在现有的vue项目中添加e2e测试最简单的方法是运行

vue add e2e-cypress

这将自动安装所有要求。