Add cypress component tests

This commit is contained in:
Matthias 2021-12-17 19:40:15 +01:00
parent a99b2d0ac7
commit 0a99eaea9e
17 changed files with 827 additions and 131 deletions

View File

@ -4,6 +4,7 @@ on:
push:
branches:
- main
- ci/**
pull_request:
branches:
- main
@ -30,6 +31,14 @@ jobs:
- name: Run type check
run: yarn check-types
# Install NPM dependencies, cache them correctly
# and run all Cypress tests
- name: Cypress run
uses: cypress-io/github-action@v2
with:
build: yarn build
start: yarn start
- name: Run Tests
run: yarn test:unit

7
cypress.json Normal file
View File

@ -0,0 +1,7 @@
{
"testFiles": "**/*.spec.ts",
"video": false,
"component": {
"componentFolder": "src"
}
}

View 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"
}

13
cypress/plugins/index.js Normal file
View File

@ -0,0 +1,13 @@
// cypress/plugins/index.js
const { startDevServer } = require('@cypress/webpack-dev-server');
const webpackConfig = require('@vue/cli-service/webpack.config');
module.exports = (on, config) => {
on('dev-server:start', (options) => {
return startDevServer({
options,
webpackConfig,
});
});
};

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) => { ... })

20
cypress/support/index.js Normal file
View 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')

View File

@ -8,9 +8,12 @@
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint",
"check-types": "tsc --noemit",
"lint-ci": "vue-cli-service lint --no-fix"
"lint-ci": "vue-cli-service lint --no-fix",
"cypress:open": "cypress open",
"cypress:run-ct": "cypress run-ct"
},
"dependencies": {
"@cypress/vue": "^2.2.3",
"axios": "^0.24.0",
"bootstrap": "^4.6.0",
"bootstrap-vue": "^2.21.2",
@ -33,6 +36,7 @@
"vuex-class": "^0.3.2"
},
"devDependencies": {
"@cypress/webpack-dev-server": "^1.8.0",
"@types/echarts": "^4.9.12",
"@types/jest": "^27.0.3",
"@typescript-eslint/eslint-plugin": "^2.33.0",
@ -49,10 +53,12 @@
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.1.0",
"@vue/test-utils": "^1.3.0",
"cypress": "^9.1.1",
"eslint": "^6.7.2",
"eslint-config-airbnb": "^18.2.1",
"eslint-plugin-prettier": "^3.4.1",
"eslint-plugin-vue": "^7.20.0",
"html-webpack-plugin": "4",
"mutationobserver-shim": "^0.3.7",
"popper.js": "^1.16.1",
"portal-vue": "^2.1.7",

View File

@ -0,0 +1,52 @@
import { mount } from '@cypress/vue';
import ProfitPill from '@/components/general/ProfitPill.vue';
describe('ProfitPill.vue', () => {
let cmp;
it('Shows a Green pill with positive profits', async () => {
mount(ProfitPill, {
propsData: {
profitRatio: 0.051,
profitAbs: 0.1,
profitDesc: '',
stakeCurrency: 'USDT',
},
});
cy.get('div').should('have.class', 'profit-pill-profit').should('be.visible');
cy.get('div').should('contain', '5.10%');
cy.get('div').should('contain', '(0.1)');
cy.get('span').should('have.attr', 'title', 'USDT');
});
it('Shows a Red pill with positive profits', async () => {
mount(ProfitPill, {
propsData: {
profitRatio: -0.1,
profitAbs: -0.1,
profitDesc: '',
stakeCurrency: 'USDT',
},
});
cy.get('div').should('not.have.class', 'profit-pill-profit').should('be.visible');
cy.get('div').should('have.class', 'profit-pill').should('be.visible');
cy.get('div').should('contain', '-10.00%');
cy.get('div').should('contain', '(-0.1)');
cy.get('span').should('have.attr', 'title', 'USDT');
});
it('Shows a pill with 0.0 profits.', async () => {
mount(ProfitPill, {
propsData: {
profitRatio: 0.0,
profitAbs: 0.0,
profitDesc: '',
stakeCurrency: 'BTC',
},
});
cy.get('div').should('have.class', 'profit-pill').should('be.visible');
cy.get('div').should('contain', '0.00%');
cy.get('div').should('contain', '(0)');
cy.get('span').should('have.attr', 'title', 'BTC');
});
});

View File

@ -23,7 +23,7 @@
import { formatPercent, formatPrice, timestampms } from '@/shared/formatters';
import { Component, Prop, Vue } from 'vue-property-decorator';
import ProfitSymbol from '@/components/ftbot/ProfitSymbol.vue';
import ProfitSymbol from '@/components/general/ProfitSymbol.vue';
@Component({ components: { ProfitSymbol } })
export default class ProfitPill extends Vue {

View File

@ -0,0 +1,18 @@
import { mount } from '@cypress/vue';
import ProfitSymbol from '@/components/general/ProfitSymbol.vue';
describe('ProfitSymbol.vue', () => {
let cmp;
it('calculates isProfitable with negative profit', async () => {
mount(ProfitSymbol, { propsData: { profit: -0.5 } });
cy.get('div').should('have.class', 'triangle-down');
cy.get('div').should('not.have.class', 'triangle-up');
});
it('calculates isProfitable with positive profit', async () => {
mount(ProfitSymbol, { propsData: { profit: 0.5 } });
cy.get('div').should('have.class', 'triangle-up');
cy.get('div').should('not.have.class', 'triangle-down');
});
});

View File

@ -0,0 +1,13 @@
import { mount } from '@cypress/vue';
import ValuePair from './ValuePair.vue';
it('renders a message', () => {
const msg = 'Test description';
mount(ValuePair, {
propsData: {
description: msg,
},
});
cy.get('label').contains(msg);
});

View File

@ -1,58 +0,0 @@
/* eslint-disable @typescript-eslint/camelcase */
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import ProfitPill from '@/components/general/ProfitPill.vue';
describe('ProfitPill.vue', () => {
let cmp;
beforeEach(() => {
cmp = mount(ProfitPill, {
propsData: {
profitRatio: 0,
profitAbs: 0,
profitDesc: '',
stakeCurrency: 'USDT',
},
});
});
it('Shows a Green pill with positive profits', async () => {
const props = {
profitRatio: 0.051,
profitAbs: 0.1,
};
cmp.setProps(props);
await Vue.nextTick();
expect(cmp.html()).toContain('profit-pill-profit');
expect(cmp.html()).toContain('5.10%');
expect(cmp.html()).toContain('(0.1)');
expect(cmp.html()).toContain('title="USDT"');
});
it('Shows a Red pill with positive profits', async () => {
const props = {
profitRatio: -0.1,
profitAbs: -0.1,
stakeCurrency: 'USDT',
};
cmp.setProps(props);
await Vue.nextTick();
expect(cmp.html()).not.toContain('profit-pill-profit');
expect(cmp.html()).toContain('profit-pill');
expect(cmp.html()).toContain('(-0.1)');
expect(cmp.html()).toContain('-10.00%');
expect(cmp.html()).toContain('title="USDT"');
});
it('Shows a pill with 0.0 profits.', async () => {
const props = {
profitRatio: 0.0,
profitAbs: 0.0,
stakeCurrency: 'BTC',
};
cmp.setProps(props);
await Vue.nextTick();
expect(cmp.html()).toContain('profit-pill');
expect(cmp.html()).toContain('0.00%');
expect(cmp.html()).toContain('(0)');
expect(cmp.html()).toContain('title="BTC"');
});
});

View File

@ -1,40 +0,0 @@
/* eslint-disable @typescript-eslint/camelcase */
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import ProfitSymbol from '@/components/ftbot/ProfitSymbol.vue';
describe('ProfitSymbol.vue', () => {
let cmp;
beforeEach(() => {
cmp = mount(ProfitSymbol, { propsData: { profit: 0 } });
});
it('calculates isProfitable with negative profit', async () => {
const profit = -0.5;
cmp.setProps({ profit });
await Vue.nextTick();
expect(cmp.vm.isProfitable).toBe(false);
});
it('calculates isProfitable with positive profit', async () => {
const profit = 0.5;
cmp.setProps({ profit });
await Vue.nextTick();
expect(cmp.vm.isProfitable).toBe(true);
});
it('renders triangle down when profit is negative', async () => {
const profit = -0.5;
cmp.setProps({ profit });
await Vue.nextTick();
expect(cmp.html()).toContain('triangle-down');
expect(cmp.html()).not.toContain('triangle-up');
});
it('renders triangle up when profit is positive', async () => {
const profit = 0.5;
cmp.setProps({ profit });
await Vue.nextTick();
expect(cmp.html()).toContain('triangle-up');
expect(cmp.html()).not.toContain('triangle-down');
});
});

View File

@ -1,12 +0,0 @@
import { mount } from '@vue/test-utils';
import ValuePair from '@/components/general/ValuePair.vue';
describe('ValuePair.vue', () => {
it('renders description when passed', () => {
const msg = 'Test description';
const wrapper = mount(ValuePair, {
propsData: { description: msg },
});
expect(wrapper.text()).toMatch(msg);
});
});

View File

@ -15,7 +15,8 @@
"baseUrl": "src",
"types": [
"webpack-env",
"jest"
"jest",
"cypress"
],
"paths": {
"@/*": [

673
yarn.lock

File diff suppressed because it is too large Load Diff