meta: introduce Cypress end-to-end testing (via #4827)
* `test/e2e` -> `test/e2e-selenium` * add Cypress * ESLint fixes * MOAR cypress * `integration` -> `tests` * wire Cypress up to a hot e2e server * linter fixes * don't run in CI
This commit is contained in:
88
.eslintrc
88
.eslintrc
@@ -1,52 +1,36 @@
|
||||
{
|
||||
"parser": "babel-eslint",
|
||||
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"es6": true
|
||||
},
|
||||
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended"
|
||||
],
|
||||
|
||||
"plugins": [
|
||||
"react",
|
||||
"mocha",
|
||||
"import"
|
||||
],
|
||||
|
||||
"settings": {
|
||||
"react": {
|
||||
"pragma": "React",
|
||||
"version": "15.0"
|
||||
}
|
||||
},
|
||||
|
||||
"rules": {
|
||||
"semi": [2, "never"],
|
||||
"strict": 0,
|
||||
"quotes": [2, "double", { "allowTemplateLiterals": true }],
|
||||
"no-unused-vars": 2,
|
||||
"no-multi-spaces": 1,
|
||||
"camelcase": 1,
|
||||
"no-use-before-define": [2,"nofunc"],
|
||||
"no-underscore-dangle": 0,
|
||||
"no-unused-expressions": 1,
|
||||
"comma-dangle": 0,
|
||||
"no-console": ["error", { allow: ["warn", "error"] }],
|
||||
"react/jsx-no-bind": 1,
|
||||
"react/jsx-no-target-blank": 2,
|
||||
"react/display-name": 0,
|
||||
"mocha/no-exclusive-tests": "error",
|
||||
"import/no-extraneous-dependencies": [2]
|
||||
}
|
||||
}
|
||||
parser: babel-eslint
|
||||
env:
|
||||
browser: true
|
||||
node: true
|
||||
es6: true
|
||||
parserOptions:
|
||||
ecmaFeatures:
|
||||
jsx: true
|
||||
extends:
|
||||
- eslint:recommended
|
||||
- plugin:react/recommended
|
||||
plugins:
|
||||
- react
|
||||
- mocha
|
||||
- import
|
||||
settings:
|
||||
react:
|
||||
pragma: React
|
||||
version: '15.0'
|
||||
rules:
|
||||
semi: [2, never]
|
||||
strict: 0
|
||||
quotes: [2, double, { allowTemplateLiterals: true }]
|
||||
no-unused-vars: 2
|
||||
no-multi-spaces: 1
|
||||
camelcase: 1
|
||||
no-use-before-define: [2, nofunc]
|
||||
no-underscore-dangle: 0
|
||||
no-unused-expressions: 1
|
||||
comma-dangle: 0
|
||||
no-console: [2, { allow: [warn, error] }]
|
||||
react/jsx-no-bind: 1
|
||||
react/jsx-no-target-blank: 2
|
||||
react/display-name: 0
|
||||
mocha/no-exclusive-tests: 2
|
||||
import/no-extraneous-dependencies: 2
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -10,3 +10,7 @@ npm-debug.log*
|
||||
selenium-debug.log
|
||||
test/e2e/db.json
|
||||
docs/_book
|
||||
|
||||
# Cypress
|
||||
test/e2e-cypress/screenshots
|
||||
test/e2e-cypress/videos
|
||||
10
cypress.json
Normal file
10
cypress.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"fileServerFolder": "test/e2e-cypress/static",
|
||||
"fixturesFolder": "test/e2e-cypress/fixtures",
|
||||
"integrationFolder": "test/e2e-cypress/tests",
|
||||
"pluginsFile": "test/e2e-cypress/plugins/index.js",
|
||||
"screenshotsFolder": "test/e2e-cypress/screenshots",
|
||||
"supportFile": "test/e2e-cypress/support/index.js",
|
||||
"videosFolder": "test/e2e-cypress/videos",
|
||||
"baseUrl": "http://localhost:3230/"
|
||||
}
|
||||
@@ -88,7 +88,7 @@ module.exports = function(rules, options) {
|
||||
plugins.push( new webpack.NoEmitOnErrorsPlugin())
|
||||
|
||||
} else { // development mode
|
||||
plugins.push(new CopyWebpackPlugin([ { from: "test/e2e/specs", to: "test-specs" } ]))
|
||||
plugins.push(new CopyWebpackPlugin([ { from: "test/e2e-selenium/specs", to: "test-specs" } ]))
|
||||
}
|
||||
|
||||
plugins.push(
|
||||
|
||||
8066
package-lock.json
generated
8066
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@@ -32,11 +32,14 @@
|
||||
"test-in-node": "run-s lint-errors just-test-in-node",
|
||||
"just-test-in-node": "mocha --require test/setup.js --recursive --compilers js:babel-core/register --require source-map-support test/core test/components test/bugs test/swagger-ui-dist-package test/xss",
|
||||
"just-check-coverage": "nyc npm run just-test-in-node",
|
||||
"test-e2e": "sleep 3 && nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json",
|
||||
"e2e-initial-render": "nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json --group initial-render",
|
||||
"mock-api": "json-server --watch test/e2e/db.json --port 3204",
|
||||
"hot-e2e-server": "webpack-dev-server --port 3230 --content-base test/e2e/helpers --host 0.0.0.0 --config webpack-hot-dev-server.config.js --inline --hot --progress",
|
||||
"e2e": "run-p -r hot-e2e-server mock-api test-e2e",
|
||||
"test-e2e-cypress": "cypress run",
|
||||
"test-e2e-selenium": "sleep 3 && nightwatch test/e2e-selenium/scenarios/ --config test/e2e-selenium/nightwatch.json",
|
||||
"e2e-initial-render": "nightwatch test/e2e-selenium/scenarios/ --config test/e2e-selenium/nightwatch.json --group initial-render",
|
||||
"mock-api": "json-server --watch test/e2e-selenium/db.json --port 3204",
|
||||
"hot-e2e-cypress-server": "webpack-dev-server --port 3230 --content-base test/e2e-cypress/static --host 0.0.0.0 --config webpack-hot-dev-server.config.js --inline --hot --progress",
|
||||
"hot-e2e-selenium-server": "webpack-dev-server --port 3230 --content-base test/e2e-selenium/helpers --host 0.0.0.0 --config webpack-hot-dev-server.config.js --inline --hot --progress",
|
||||
"e2e-cypress": "run-p -r hot-e2e-cypress-server mock-api test-e2e-cypress",
|
||||
"e2e-selenium": "run-p -r hot-e2e-selenium-server mock-api test-e2e-selenium",
|
||||
"open-static": "node -e 'require(\"open\")(\"http://localhost:3002\")'",
|
||||
"serve-static": "http-server dist/ -i -a 0.0.0.0 -p 3002",
|
||||
"start": "npm-run-all --parallel serve-static open-static"
|
||||
@@ -94,6 +97,7 @@
|
||||
"chromedriver": "^2.38.3",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.28.11",
|
||||
"cypress": "^3.1.0",
|
||||
"dedent": "^0.7.0",
|
||||
"deepmerge": "^2.1.0",
|
||||
"enzyme": "^2.7.1",
|
||||
|
||||
5
test/e2e-cypress/fixtures/example.json
Normal file
5
test/e2e-cypress/fixtures/example.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
||||
17
test/e2e-cypress/plugins/index.js
Normal file
17
test/e2e-cypress/plugins/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
swagger: "2.0"
|
||||
76
test/e2e-cypress/static/index.html
Normal file
76
test/e2e-cypress/static/index.html
Normal file
@@ -0,0 +1,76 @@
|
||||
<!-- HTML for dev server -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
body {
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
window["SwaggerUIBundle"] = window["swagger-ui-bundle"]
|
||||
window["SwaggerUIStandalonePreset"] = window["swagger-ui-standalone-preset"]
|
||||
// Build a system
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "",
|
||||
dom_id: '#swagger-ui',
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
onComplete: () => {
|
||||
if(window.completeCount) {
|
||||
window.completeCount++
|
||||
} else {
|
||||
window.completeCount = 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
window.ui = ui
|
||||
|
||||
ui.initOAuth({
|
||||
clientId: "your-client-id",
|
||||
clientSecret: "your-client-secret-if-required",
|
||||
realm: "your-realms",
|
||||
appName: "your-app-name",
|
||||
scopeSeparator: " ",
|
||||
additionalQueryStringParams: {}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
25
test/e2e-cypress/support/commands.js
Normal file
25
test/e2e-cypress/support/commands.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add("login", (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
20
test/e2e-cypress/support/index.js
Normal file
20
test/e2e-cypress/support/index.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import "./commands"
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
8
test/e2e-cypress/tests/.eslintrc
Normal file
8
test/e2e-cypress/tests/.eslintrc
Normal file
@@ -0,0 +1,8 @@
|
||||
globals:
|
||||
cy: false
|
||||
Cypress: false
|
||||
expect: false
|
||||
assert: false
|
||||
|
||||
rules:
|
||||
"no-console": 0
|
||||
5
test/e2e-cypress/tests/deep-linking.js
Normal file
5
test/e2e-cypress/tests/deep-linking.js
Normal file
@@ -0,0 +1,5 @@
|
||||
describe("The Home Page", function () {
|
||||
it("successfully loads", function () {
|
||||
cy.visit("/")
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user