Vue: Как вы добавляете тесты E2E после того, как не включаете их в исходный шаблон веб-пакета?

Чтобы начать свой проект, я запустил vue init webpack my-project, но исключил тесты E2E. Теперь я передумал и действительно хочу включить тесты E2E. Как я могу добавить их в свой проект?

Примечание для читателей: Ответ Таруна Лалвани мне очень понравился. Однако вы можете рассмотреть возможность использования TestCafe, поскольку он работает без какой-либо конфигурации.


Я попытался создать фиктивный проект с помощью команды vue init webpack my--project, чтобы я мог скопировать и вставить каталог test / e2e, а затем попытаться работать оттуда, но это не сработало. Я также скопировал сценарий npm, попытался запустить 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 <[email protected]>",
  "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"
  ]
}

person Adam Zerner    schedule 20.01.2018    source источник
comment
Какой тестовый раннер вы используете? Шутка? Мокко?   -  person acdcjunior    schedule 17.04.2018
comment
Я использую Mocha для своих модульных тестов.   -  person Adam Zerner    schedule 17.04.2018


Ответы (3)


Таким образом, нет команды, которую вы можете запустить, чтобы исправить и добавить 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

Я удалил chromedriver и selenium-server, так как последняя версия не помешает.

И скачиваем содержимое этой папки

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

Также добавьте / обновите "скрипты" в package.json

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

Исходный ответ

Но самый простой способ сделать это - создать два новых проекта project1, project2, назвать оба из них 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. Убедитесь, что вы сделали репозиторий git в проекте, выполнив ниже

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

А затем примените патч, чтобы добавить e2e

git apply < e2e.patch
git add .
git commit -m "Added e2e"
person Tarun Lalwani    schedule 17.04.2018
comment
Когда я добавил ваш файл e2e.patch и затем запустил git apply < e2e.patch, я получил следующую ошибку: code/premium-poker-tools [master●] » git apply < e2e.patch error: patch failed: package.json:8 error: package.json: patch does not apply. Я думаю, что проблема здесь такая же, как и с подходом acdcjunior - я начал этот проект 6+ месяцев назад, поэтому создаваемый вами git diff отличается от того, для чего был бы git diff, когда я изначально создавал свой проект. - person Adam Zerner; 17.04.2018
comment
@AdamZerner, пожалуйста, посмотрите правку. Надеюсь, это поможет вам - person Tarun Lalwani; 17.04.2018
comment
Я получаю ошибки для @^x.y.z пакетов: code/premium-poker-tools [master] » npm add chromedriver cross-spawn@^5.0.1 nightwatch@^0.9.12 selenium-server zsh: no matches found: cross-spawn@^5.0.1 - person Adam Zerner; 17.04.2018
comment
В ссылке указано, что он есть npmjs.com/package/cross-spawn. Я бы просто попробовал с npm add cross-spawn - person Tarun Lalwani; 17.04.2018
comment
Это работает, спасибо! Однако несколько предостережений. Мне пришлось удалить @^ и для пакета nightwatch (в дополнение к cross-spawn). Мне также пришлось удалить кучу {{#if_eq lintConfig "airbnb"}} вещей из различных файлов в папке test/e2e. - person Adam Zerner; 17.04.2018

Эти шаблоны vue-cli v2 «отображаются» на основе того, что вы выбираете в меню. Когда вы выбираете e2e, активируется флаг e2e, и каждый код, имеющий {{#e2e}} (или аналогичный), добавляется в сгенерированный проект. Все, что вам нужно сделать, это найти его в источнике шаблона.

Итак, в основном, используя карма + мокко, чтобы получить то, что добавляет флаг e2e, вы должны:

  • Добавьте недостающие пакеты npm:

    npm i -D [email protected] [email protected] [email protected] [email protected] [email protected]
    
  • Создайте папку test\e2e и добавьте 4 исходных файла шаблона e2e-шаблона. папку (щелкните здесь, чтобы увидеть папку).

    • Files
    • Пример:

      # 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
      
  • Обновите сценарии npm в своем package.json:

    • Добавьте сценарий e2e:

      "scripts": {
          (...)
          "e2e": "node test/e2e/runner.js",
      
    • Если вы хотите, чтобы npm test также запускал e2e, добавьте также && npm run e2e в test скрипт:

      "test": "npm run unit && npm run e2e",
      
    • Если у вас активирован линтинг и вы хотите, чтобы он соответствовал спецификациям e2e, добавьте папку test/e2e/specs:

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

Глядя на шаблон, это должно быть все.

person acdcjunior    schedule 17.04.2018
comment
Я получил сообщение об отсутствии модуля webpack-dev-server npm. Я установил его, а затем запустил npm update, просто чтобы убедиться, что все обновлено. После этого и повторной попытки npm run e2e я получил следующую ошибку: /Users/adamzerner/code/premium-poker-tools/test/e2e/runner.js:12 devConfigPromise.then(devConfig => { TypeError: devConfigPromise.then is not a function Эти проблемы могли быть вызваны тем, что я начал свой проект более 6 месяцев назад. - person Adam Zerner; 17.04.2018
comment
Ой, понятно. Тогда можешь опубликовать свой текущий package.json? Мне нужно будет проверить каждую вашу зависимость и то, что у вас должно быть. - person acdcjunior; 17.04.2018
comment
Или, если вы не меняли какой-либо пакет, если вы сообщите нам точную дату создания проекта (чтобы мы могли видеть точный шаблон, который вы использовали), это может быть еще одна возможность. - person acdcjunior; 17.04.2018
comment
Только что добавил мой точный package.json файл. Я думаю, что проблема не только в пакетах npm. Например. ошибка devConfigPromise.then is not a function возникает из-за того, что фактический код в webpack.dev.conf отличается (в этом случае он должен вернуть обещание, а он этого не делает). - person Adam Zerner; 17.04.2018

Самый простой способ добавить тест e2e в существующий проект vue - запустить

vue add e2e-cypress

Это автоматически установит все требования.

person Pervaiz Dattoo    schedule 04.11.2019