feat(test): Add cypress for testing

This commit is contained in:
Braks
2021-11-27 16:53:24 +01:00
committed by GitHub
parent 43b68c1699
commit 796c60431f
15 changed files with 1120 additions and 124 deletions
+3 -1
View File
@@ -7,11 +7,13 @@ const baseRules = {
allowModifiers: true,
},
],
'no-unused-expressions': ['off', { allowTernary: true }],
'chai-friendly/no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }],
'prettier/prettier': ['error', {}, { usePrettierrc: true }],
}
module.exports = {
extends: ['@antfu', 'plugin:prettier/recommended'],
plugins: ['prettier'],
plugins: ['chai-friendly', 'prettier'],
rules: baseRules,
}
+57
View File
@@ -0,0 +1,57 @@
name: build-and-test
on:
push:
branches:
- main
- master
- develop
pull_request:
branches:
- main
- master
- develop
jobs:
build-and-test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node: [16]
steps:
- name: Checkout 🛎
uses: actions/checkout@master
- name: Setup node env 🏗
uses: actions/setup-node@v2.1.2
with:
node-version: ${{ matrix.node }}
check-latest: true
- name: Get yarn cache directory path 🛠
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Cache node_modules 📦
uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies 👨🏻‍💻
run: yarn
- name: Run linter 🧹
run: yarn lint
- name: Build Library 👷
run: yarn build
- name: Run tests 🧪
run: yarn test
+6
View File
@@ -0,0 +1,6 @@
{
"testFiles": "cypress/**/*.spec.ts",
"componentFolder": ".",
"video": false,
"screenshotOnRunFailure": false
}
@@ -0,0 +1,87 @@
import { getElements } from '../../../examples/Stress/utils'
import { useStore } from '~/composables'
import { FlowStore } from '~/types'
import { isGraphEdge, isGraphNode } from '~/utils'
describe('test store action setElements', () => {
const setElements = async (store: FlowStore) => {
const elements = [
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 } },
{ id: 'e1-2', source: '1', target: '2', animated: true },
]
await store.setElements(elements)
}
it('sets elements', async () => {
const store = useStore()
await setElements(store)
expect(store.elements).to.have.length(3)
store.$dispose()
})
context('elements pre-set', () => {
let store: FlowStore
beforeEach(async () => {
store = useStore()
await setElements(store)
})
afterEach(() => store.$dispose())
it('adds elements', () => {
store.addElements([{ id: '4', data: { label: 'Node 4' }, position: { x: 500, y: 500 } }])
expect(store.elements).to.have.length(4)
})
it('parses elements to flow-elements', () => {
store.getEdges.forEach((edge) => expect(!isGraphNode(edge)).to.be.true)
store.getNodes.forEach((node) => expect(!isGraphEdge(node)).to.be.true)
})
it('parses elements to flow-elements (199 elements - stress test)', async () => {
await store.setElements(getElements())
store.getEdges.forEach((edge) => expect(!isGraphNode(edge)).to.be.true)
store.getNodes.forEach((node) => expect(!isGraphEdge(node)).to.be.true)
})
it('has correct element ids', () => {
store.elements.forEach((el) => expect(['1', '2', 'e1-2']).to.include(el.id))
})
it('has correct element types', () => {
store.elements.forEach((el) => expect(['input', 'default']).to.include(el.type))
})
it('nodes have correct label', () => {
store.getNodes.forEach((el) => {
if (el.id === '1') expect(el.data.label).to.eq('Node 1')
else expect(el.data.label).to.eq('Node 2')
})
})
it('nodes have correct position', () => {
store.getNodes.forEach((el) => {
if (el.id === '1') expect(JSON.stringify(el.position)).to.eq(JSON.stringify({ x: 250, y: 5 }))
else expect(JSON.stringify(el.position)).to.eq(JSON.stringify({ x: 100, y: 100 }))
})
})
it('edge has correct target and source', () => {
store.getEdges.forEach((el) => {
expect(el.source).to.eq('1')
expect(el.target).to.eq('2')
})
})
it('edge has correct targetnode and sourceNode', () => {
store.getEdges.forEach((el) => {
expect(el.sourceNode.id).to.eq('1')
expect(el.targetNode.id).to.eq('2')
})
})
it('edge is animated', () => {
store.getEdges.forEach((el) => expect(el.animated).to.eq(true))
})
})
})
@@ -0,0 +1,51 @@
import { useStore } from '~/composables'
import { initialState } from '~/utils'
import { FlowState, FlowStore } from '~/types'
describe('test store state', () => {
let store: FlowStore
beforeEach(() => (store = useStore()))
afterEach(() => store.$dispose())
it('has any initial state', () => {
expect(store.$state).to.exist
})
it('has default initial state', () => {
const initial = initialState()
Object.keys(store.$state).forEach((state) => {
const storedState = store[<keyof FlowState>state]
const initialVal = initial[<keyof FlowState>state]
expect(JSON.stringify(storedState)).to.eq(JSON.stringify(initialVal))
})
})
it('sets state', () => {
store.setState({
zoomOnScroll: false,
})
expect(store.zoomOnScroll).to.eq(false)
})
it('takes initial options', () => {
const store = useStore({
zoomOnScroll: false,
})
expect(store.zoomOnScroll).to.eq(false)
store.$dispose()
})
it('gets custom node types', () => {
store.setState({
nodeTypes: ['custom'],
})
expect(Object.keys(store.getNodeTypes)).to.contain('custom')
})
it('gets custom edge types', () => {
store.setState({
edgeTypes: ['custom'],
})
expect(Object.keys(store.getEdgeTypes)).to.contain('custom')
})
})
+15
View File
@@ -0,0 +1,15 @@
import { resolve } from 'path'
import { startDevServer } from '@cypress/vite-dev-server'
export default ((on, config) => {
on('dev-server:start', async (options) =>
startDevServer({
options,
viteConfig: {
configFile: resolve(__dirname, '..', '..', 'vite.config.ts'),
},
}),
)
return config
}) as Cypress.PluginConfig
+25
View 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 will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+19
View File
@@ -0,0 +1,19 @@
// ***********************************************************
// 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:
// Alternatively you can use CommonJS syntax:
// require('./commands')
+7
View File
@@ -0,0 +1,7 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"target": "es2018"
},
"include": ["**/*"]
}
+1 -1
View File
@@ -27,7 +27,7 @@ const vfInstance = ref<FlowInstance>()
const onElementsRemove = (elementsToRemove: Elements) => removeElements(elementsToRemove, elements.value)
const onConnect = (params: Edge | Connection) => addEdge(params, elements.value)
const onLoad = (flowInstance: FlowInstance) => {
flowInstance.fitView({ padding: 0.1 })
flowInstance.fitView({ padding: 0.1, nodes: ['2'] })
vfInstance.value = flowInstance
}
+8 -2
View File
@@ -26,7 +26,8 @@
"dev": "vite",
"build": "vite build && vue-tsc --declaration --emitDeclarationOnly && tsc && rm -rf tmp",
"prepublishOnly": "yarn build",
"test": "exit 0;",
"test": "cypress run-ct",
"test:open": "cypress open-ct",
"lint:js": "eslint --ext \".js,.jsx,.ts,.tsx\" --fix --ignore-path .gitignore .",
"lint": "yarn lint:js"
},
@@ -42,14 +43,19 @@
},
"devDependencies": {
"@antfu/eslint-config": "^0.9.0",
"@cypress/vite-dev-server": "^2.2.1",
"@cypress/vue": "^3.0.5",
"@rollup/plugin-replace": "^2.4.2",
"@types/dagre": "^0.7.46",
"@vitejs/plugin-vue": "^1.9.3",
"@vue/compiler-sfc": "^3.2.22",
"autoprefixer": "^10.3.7",
"cypress": "8.5.0",
"dagre": "^0.8.5",
"esbuild": "0.13.4",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-chai-friendly": "^0.7.2",
"eslint-plugin-prettier": "^3.4.1",
"np": "^7.5.0",
"postcss-nested": "^5.0.6",
@@ -59,7 +65,7 @@
"typescript": "^4.4.4",
"typescript-transform-paths": "^3.3.1",
"unplugin-auto-import": "^0.4.12",
"vite": "^2.6.14",
"vite": "2.5.x",
"vite-svg-loader": "^2.2.0",
"vue": "^3.2.22",
"vue-router": "^4.0.12",
+2 -1
View File
@@ -56,7 +56,8 @@ export const isEdge = (element: Node | Edge | Connection): element is Edge =>
export const isNode = (element: Node | Edge | Connection): element is Node => 'id' in element && !isEdge(element)
export const isGraphNode = (element: any): element is GraphNode => isNode(element) && '__vf' in element
export const isGraphEdge = (element: any): element is GraphEdge => isEdge(element) && 'sourceTargetNodes' in element
export const isGraphEdge = (element: any): element is GraphEdge =>
isEdge(element) && 'sourceNode' in element && 'targetNode' in element
const getConnectedElements = (node: GraphNode, elements: Elements, dir: 'source' | 'target') => {
if (!isNode(node)) return []
+3 -2
View File
@@ -20,7 +20,8 @@
"strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"types": [
"vite/client"
"vite/client",
"cypress"
],
"paths": {
"~/*": [
@@ -32,7 +33,7 @@
{ "transform": "typescript-transform-paths", "afterDeclarations": true }
]
},
"include": ["src"],
"include": ["src", "cypress/**/*.spec.ts"],
"exclude": [
"node_modules",
"build",
+1 -1
View File
@@ -59,6 +59,6 @@ export default defineConfig({
}),
],
optimizeDeps: {
include: ['vue', '@vueuse/core'],
include: ['vue', '@vueuse/core', '@braks/revue-draggable'],
},
})
+835 -116
View File
File diff suppressed because it is too large Load Diff