mirror of
https://github.com/jpros/tacticalrmm-web.git
synced 2026-01-20 03:50:21 +00:00
remove jest and add cypress for frontend testing
This commit is contained in:
10
cypress.json
Executable file
10
cypress.json
Executable file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"baseUrl": "http://localhost:8080/",
|
||||
"fixturesFolder": "test/cypress/fixtures",
|
||||
"integrationFolder": "test/cypress/integration",
|
||||
"pluginsFile": "test/cypress/plugins/index.js",
|
||||
"screenshotsFolder": "test/cypress/screenshots",
|
||||
"supportFile": "test/cypress/support/index.js",
|
||||
"videosFolder": "test/cypress/videos",
|
||||
"video": true
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
module.exports = {
|
||||
globals: {
|
||||
__DEV__: true
|
||||
},
|
||||
setupFilesAfterEnv: [
|
||||
'<rootDir>/test/jest/jest.setup.js'
|
||||
],
|
||||
// noStackTrace: true,
|
||||
// bail: true,
|
||||
// cache: false,
|
||||
// verbose: true,
|
||||
// watch: true,
|
||||
collectCoverage: false,
|
||||
coverageDirectory: '<rootDir>/test/jest/coverage',
|
||||
collectCoverageFrom: [
|
||||
'<rootDir>/src/**/*.vue',
|
||||
'<rootDir>/src/**/*.js',
|
||||
'<rootDir>/src/**/*.ts',
|
||||
'<rootDir>/src/**/*.jsx'
|
||||
],
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
// branches: 50,
|
||||
// functions: 50,
|
||||
// lines: 50,
|
||||
// statements: 50
|
||||
}
|
||||
},
|
||||
testMatch: [
|
||||
'<rootDir>/test/jest/__tests__/**/*.spec.js',
|
||||
'<rootDir>/test/jest/__tests__/**/*.test.js',
|
||||
'<rootDir>/src/**/__tests__/*_jest.spec.js'
|
||||
],
|
||||
moduleFileExtensions: [
|
||||
'vue',
|
||||
'js',
|
||||
'jsx',
|
||||
'json',
|
||||
'ts',
|
||||
'tsx'
|
||||
],
|
||||
moduleNameMapper: {
|
||||
'^vue$': '<rootDir>/node_modules/vue/dist/vue.common.js',
|
||||
'^test-utils$': '<rootDir>/node_modules/@vue/test-utils/dist/vue-test-utils.js',
|
||||
'^quasar$': '<rootDir>/node_modules/quasar/dist/quasar.common.js',
|
||||
'^~/(.*)$': '<rootDir>/$1',
|
||||
'^@/(.*)$': '<rootDir>/src/$1',
|
||||
'^src/(.*)$': '<rootDir>/src/$1',
|
||||
'.*css$': '<rootDir>/test/jest/utils/stub.css',
|
||||
|
||||
},
|
||||
transform: {
|
||||
'.*\\.vue$': 'vue-jest',
|
||||
'.*\\.js$': 'babel-jest',
|
||||
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
|
||||
// use these if NPM is being flaky
|
||||
//'.*\\.vue$': '<rootDir>/node_modules/@quasar/quasar-app-extension-testing-unit-jest/node_modules/vue-jest',
|
||||
//'.*\\.js$': '<rootDir>/node_modules/@quasar/quasar-app-extension-testing-unit-jest/node_modules/babel-jest'
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
'<rootDir>/node_modules/(?!quasar/lang)'
|
||||
],
|
||||
snapshotSerializers: [
|
||||
'<rootDir>/node_modules/jest-serializer-vue'
|
||||
]
|
||||
}
|
||||
3875
package-lock.json
generated
3875
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,8 @@
|
||||
"scripts": {
|
||||
"serve": "quasar dev",
|
||||
"build": "quasar build",
|
||||
"test:unit": "quasar test --unit jest"
|
||||
"test:e2e": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress open\"",
|
||||
"test:e2e:ci": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@quasar/extras": "^1.9.17",
|
||||
@@ -21,12 +22,13 @@
|
||||
"@quasar/app": "^2.1.15",
|
||||
"@quasar/cli": "^1.1.3",
|
||||
"@quasar/quasar-app-extension-testing": "^1.0.3",
|
||||
"@quasar/quasar-app-extension-testing-unit-jest": "^1.0.1",
|
||||
"@quasar/quasar-app-extension-testing-e2e-cypress": "^3.0.1",
|
||||
"core-js": "^3.8.1",
|
||||
"flush-promises": "^1.0.2",
|
||||
"fs-extra": "^9.0.1",
|
||||
"prismjs": "^1.22.0",
|
||||
"vue-prism-editor": "^1.2.2"
|
||||
"vue-prism-editor": "^1.2.2",
|
||||
"eslint-plugin-cypress": "^2.11.1"
|
||||
},
|
||||
"browserslist": [
|
||||
"last 4 Chrome versions",
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
{
|
||||
"@quasar/testing": {
|
||||
"harnesses": [
|
||||
"unit-jest"
|
||||
]
|
||||
},
|
||||
"@quasar/testing-unit-jest": {
|
||||
"babel": "babelrc",
|
||||
"@quasar/testing": {},
|
||||
"@quasar/testing-e2e-cypress": {
|
||||
"options": [
|
||||
"scripts"
|
||||
]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"unit-jest": {
|
||||
"runnerCommand": "jest"
|
||||
"e2e-cypress": {
|
||||
"runnerCommand": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\""
|
||||
}
|
||||
}
|
||||
7
test/cypress/.eslintrc.js
Normal file
7
test/cypress/.eslintrc.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
// Add Cypress-specific lint rules, globals and Cypress plugin
|
||||
// See https://github.com/cypress-io/eslint-plugin-cypress#rules
|
||||
'plugin:cypress/recommended',
|
||||
],
|
||||
};
|
||||
2
test/cypress/.gitignore
vendored
Normal file
2
test/cypress/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
videos/*
|
||||
screenshots/*
|
||||
5
test/cypress/fixtures/example.json
Executable file
5
test/cypress/fixtures/example.json
Executable 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"
|
||||
}
|
||||
42
test/cypress/integration/home.spec.js
Executable file
42
test/cypress/integration/home.spec.js
Executable file
@@ -0,0 +1,42 @@
|
||||
/// <reference path="cypress" />
|
||||
/// <reference path="../support/index.d.ts" />
|
||||
|
||||
// Use `cy.dataCy` custom command for more robust tests
|
||||
// See https://docs.cypress.io/guides/references/best-practices.html#Selecting-Elements
|
||||
|
||||
// ** This file is an example of how to write Cypress tests, you can safely delete it **
|
||||
|
||||
// This test will pass when run against a clean Quasar project
|
||||
describe('Landing', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/');
|
||||
});
|
||||
it('.should() - assert that <title> is correct', () => {
|
||||
cy.title().should('include', 'Quasar');
|
||||
});
|
||||
});
|
||||
|
||||
// ** The following code is an example to show you how to write some tests for your home page **
|
||||
//
|
||||
// describe('Home page tests', () => {
|
||||
// beforeEach(() => {
|
||||
// cy.visit('/');
|
||||
// });
|
||||
// it('has pretty background', () => {
|
||||
// cy.dataCy('landing-wrapper')
|
||||
// .should('have.css', 'background').and('match', /(".+(\/img\/background).+\.png)/);
|
||||
// });
|
||||
// it('has pretty logo', () => {
|
||||
// cy.dataCy('landing-wrapper img')
|
||||
// .should('have.class', 'logo-main')
|
||||
// .and('have.attr', 'src')
|
||||
// .and('match', /^(data:image\/svg\+xml).+/);
|
||||
// });
|
||||
// it('has very important information', () => {
|
||||
// cy.dataCy('instruction-wrapper')
|
||||
// .should('contain', 'SETUP INSTRUCTIONS')
|
||||
// .and('contain', 'Configure Authentication')
|
||||
// .and('contain', 'Database Configuration and CRUD operations')
|
||||
// .and('contain', 'Continuous Integration & Continuous Deployment CI/CD');
|
||||
// });
|
||||
// });
|
||||
19
test/cypress/plugins/index.js
Executable file
19
test/cypress/plugins/index.js
Executable file
@@ -0,0 +1,19 @@
|
||||
/* eslint-env node */
|
||||
// ***********************************************************
|
||||
// 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)
|
||||
|
||||
// cypress/plugins/index.js
|
||||
|
||||
module.exports = (/*on, config*/) => {
|
||||
//
|
||||
};
|
||||
50
test/cypress/support/commands.js
Executable file
50
test/cypress/support/commands.js
Executable file
@@ -0,0 +1,50 @@
|
||||
// ***********************************************
|
||||
// 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) => { ... })
|
||||
|
||||
Cypress.Commands.add('dataCy', (value) => {
|
||||
return cy.get(`[data-cy=${value}]`);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('testRoute', (route) => {
|
||||
cy.location().should((loc) => {
|
||||
expect(loc.hash).to.contain(route);
|
||||
});
|
||||
});
|
||||
|
||||
// these two commands let you persist local storage between tests
|
||||
const LOCAL_STORAGE_MEMORY = {};
|
||||
|
||||
Cypress.Commands.add('saveLocalStorage', () => {
|
||||
Object.keys(localStorage).forEach((key) => {
|
||||
LOCAL_STORAGE_MEMORY[key] = localStorage[key];
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('restoreLocalStorage', () => {
|
||||
Object.keys(LOCAL_STORAGE_MEMORY).forEach((key) => {
|
||||
localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]);
|
||||
});
|
||||
});
|
||||
27
test/cypress/support/index.d.ts
vendored
Normal file
27
test/cypress/support/index.d.ts
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
declare namespace Cypress {
|
||||
interface Chainable {
|
||||
/**
|
||||
* Custom command to select DOM element by data-cy attribute.
|
||||
* @example cy.dataCy('greeting')
|
||||
*/
|
||||
dataCy<E extends Node = HTMLElement>(value: string): Chainable<JQuery<E>>;
|
||||
|
||||
/**
|
||||
* Custom command to test being on a given route.
|
||||
* @example cy.testRoute('home')
|
||||
*/
|
||||
testRoute(value: string): void;
|
||||
|
||||
/**
|
||||
* Persist current local storage data.
|
||||
* @example cy.saveLocalStorage()
|
||||
*/
|
||||
saveLocalStorage(): void;
|
||||
|
||||
/**
|
||||
* Restore saved data to local storage.
|
||||
* @example cy.restoreLocalStorage()
|
||||
*/
|
||||
restoreLocalStorage(): void;
|
||||
}
|
||||
}
|
||||
27
test/cypress/support/index.js
Executable file
27
test/cypress/support/index.js
Executable file
@@ -0,0 +1,27 @@
|
||||
// ***********************************************************
|
||||
// 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';
|
||||
|
||||
const resizeObserverLoopError = 'ResizeObserver loop limit exceeded';
|
||||
|
||||
Cypress.on('uncaught:exception', (err) => {
|
||||
if (err.message.includes(resizeObserverLoopError)) {
|
||||
// returning false here prevents Cypress from
|
||||
// failing the test
|
||||
return false;
|
||||
}
|
||||
});
|
||||
@@ -1,52 +0,0 @@
|
||||
// No console.log() / setTimeout
|
||||
// console.log = jest.fn(() => { throw new Error('Do not use console.log() in production') })
|
||||
jest.setTimeout(1000)
|
||||
|
||||
// jest speedup when errors are part of the game
|
||||
// Error.stackTraceLimit = 0
|
||||
|
||||
global.Promise = require('promise')
|
||||
|
||||
/*
|
||||
import chai from 'chai'
|
||||
// Make sure chai and jasmine ".not" play nice together
|
||||
// https://medium.com/@RubenOostinga/combining-chai-and-jest-matchers-d12d1ffd0303
|
||||
// updated here: https://www.andrewsouthpaw.com/jest-chai/
|
||||
const originalNot = Object.getOwnPropertyDescriptor(chai.Assertion.prototype, 'not').get
|
||||
Object.defineProperty(chai.Assertion.prototype, 'not', {
|
||||
get() {
|
||||
Object.assign(this, this.assignedNot)
|
||||
return originalNot.apply(this)
|
||||
},
|
||||
set(newNot) {
|
||||
this.assignedNot = newNot
|
||||
return newNot
|
||||
}
|
||||
})
|
||||
|
||||
// Combine both jest and chai matchers on expect
|
||||
const originalExpect = global.expect
|
||||
|
||||
global.expect = (actual) => {
|
||||
const originalMatchers = originalExpect(actual)
|
||||
const chaiMatchers = chai.expect(actual)
|
||||
|
||||
// Add middleware to Chai matchers to increment Jest assertions made
|
||||
const { assertionsMade } = originalExpect.getState()
|
||||
Object.defineProperty(chaiMatchers, 'to', {
|
||||
get() {
|
||||
originalExpect.setState({ assertionsMade: assertionsMade + 1 })
|
||||
return chai.expect(actual)
|
||||
},
|
||||
})
|
||||
|
||||
const combinedMatchers = Object.assign(chaiMatchers, originalMatchers)
|
||||
return combinedMatchers
|
||||
}
|
||||
Object.keys(originalExpect).forEach(key => (global.expect[key] = originalExpect[key]))
|
||||
*/
|
||||
|
||||
// do this to make sure we don't get multiple hits from both webpacks when running SSR
|
||||
setTimeout(()=>{
|
||||
// do nothing
|
||||
}, 1)
|
||||
@@ -1,70 +0,0 @@
|
||||
// this is mapped in jest.config.js to resolve @vue/test-utils
|
||||
import { createLocalVue, shallowMount } from 'test-utils'
|
||||
|
||||
import Vuex from 'vuex'
|
||||
import VueRouter from 'vue-router'
|
||||
import Quasar, { Cookies } from 'quasar'
|
||||
|
||||
const mockSsrContext = () => {
|
||||
return {
|
||||
req: {
|
||||
headers: {}
|
||||
},
|
||||
res: {
|
||||
setHeader: () => undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://eddyerburgh.me/mock-vuex-in-vue-unit-tests
|
||||
export const mountQuasar = (component, options = {}) => {
|
||||
const localVue = createLocalVue()
|
||||
const app = {}
|
||||
|
||||
localVue.use(Vuex)
|
||||
localVue.use(VueRouter)
|
||||
localVue.use(Quasar)
|
||||
const store = new Vuex.Store({})
|
||||
const router = new VueRouter()
|
||||
|
||||
if (options) {
|
||||
const ssrContext = options.ssr ? mockSsrContext() : null
|
||||
|
||||
if (options.cookies) {
|
||||
const cookieStorage = ssrContext ? Cookies.parseSSR(ssrContext) : Cookies
|
||||
const cookies = options.cookies
|
||||
Object.keys(cookies).forEach(key => {
|
||||
cookieStorage.set(key, cookies[key])
|
||||
})
|
||||
}
|
||||
|
||||
if (options.plugins) {
|
||||
options.plugins.forEach(plugin => {
|
||||
plugin({ app, store, router, Vue: localVue, ssrContext })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// mock vue-i18n
|
||||
const $t = () => {}
|
||||
const $tc = () => {}
|
||||
const $n = () => {}
|
||||
const $d = () => {}
|
||||
|
||||
return shallowMount(component, {
|
||||
localVue: localVue,
|
||||
store,
|
||||
router,
|
||||
mocks: { $t, $tc, $n, $d },
|
||||
// Injections for Components with a QPage root Element
|
||||
provide: {
|
||||
pageContainer: true,
|
||||
layout: {
|
||||
header: {},
|
||||
right: {},
|
||||
footer: {},
|
||||
left: {}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import * as All from "quasar";
|
||||
import Vue from "vue";
|
||||
|
||||
const {
|
||||
Quasar,
|
||||
Dialog,
|
||||
Loading,
|
||||
LoadingBar,
|
||||
Meta,
|
||||
Notify,
|
||||
ClosePopup } = All;
|
||||
|
||||
const components = Object.keys(All).reduce((object, key) => {
|
||||
const val = All[key];
|
||||
if (val && val.component && val.component.name != null) {
|
||||
object[key] = val;
|
||||
}
|
||||
return object;
|
||||
}, {});
|
||||
|
||||
Vue.use(Quasar, {
|
||||
components,
|
||||
plugins: [
|
||||
Dialog,
|
||||
Loading,
|
||||
LoadingBar,
|
||||
Meta,
|
||||
Notify
|
||||
],
|
||||
directives: [
|
||||
ClosePopup
|
||||
]
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
/* for mocking out css files in jest.config.js */
|
||||
/*
|
||||
|
||||
moduleNameMapper: {
|
||||
...
|
||||
'.*css$': '<rootDir>/test/jest/utils/stub.css'
|
||||
},
|
||||
|
||||
*/
|
||||
Reference in New Issue
Block a user