chore: add a few more integration tests

This commit is contained in:
Roman Hotsiy 2018-02-17 21:27:15 +02:00
parent 13165fb8fc
commit b33b9543fa
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
14 changed files with 1008 additions and 400 deletions

View File

@ -1,6 +1,7 @@
{ {
"ignoreTestFiles": "*.js.map", "ignoreTestFiles": "*.js.map",
"integrationFolder": "e2e/.build", "integrationFolder": "e2e/integration",
"pluginsFile": "e2e/plugins/index.js",
"fixturesFolder": false, "fixturesFolder": false,
"supportFile": false, "supportFile": false,
"fileServerFolder": ".", "fileServerFolder": ".",

View File

@ -0,0 +1,50 @@
describe('Menu', () => {
before(() => {
cy.visit('e2e/standalone.html');
});
it('should have valid items count', function() {
cy
.get('.menu-content')
.find('li')
.should('have.length', 6 + (2 + 8 + 4) + (1 + 8));
});
it('should sync active menu items while scroll', function() {
cy
.contains('h1', 'Introduction')
.scrollIntoView()
.get('.menu-item.active:not(.-depth0)')
.should('have.text', 'Introduction');
cy
.contains('h2', 'Add a new pet to the store')
.scrollIntoView()
.get('.menu-item.active:not(.-depth0)')
.should('have.length', 2)
.last()
.should('have.text', 'Add a new pet to the store')
.should('be.visible');
});
it('should update URL hash on clicking on menu items', function() {
cy.contains('.menu-item.-depth1', 'pet').click({ force: true });
cy.location('hash').should('equal', '#tag/pet');
cy.contains('.menu-item', 'Find pet by ID').click({ force: true });
cy.location('hash').should('equal', '#operation/getPetById');
cy.contains('.menu-item', 'OpenAPI Specification').click({ force: true });
cy.location('hash').should('equal', '#section/OpenAPI-Specification');
});
it('should deactivate tag when other is activated', function() {
const petItem = () => cy.contains('.menu-item.-depth1', 'pet');
petItem()
.click({ force: true })
.should('have.class', 'active');
cy.contains('.menu-item.-depth1', 'store').click({ force: true });
petItem().should('not.have.class', 'active');
});
});

View File

@ -0,0 +1,38 @@
describe('Search', () => {
before(() => {
cy.visit('e2e/standalone.html');
});
it('should be closed by default', function() {
cy
.get('.menu-content div')
.filter('.search-box')
.should('have.length', 0);
});
it('should not open for less than 3 symbols', function() {
cy.get('.search-input').type('in', { force: true });
cy
.get('.menu-content div')
.filter('.search-box')
.should('have.length', 0);
});
it('should find 3 results when typed int', function() {
cy.get('.search-input').type('t', { force: true });
cy
.get('.search-results')
.find('li')
.should('have.length', 3)
.first()
.should('contain', 'Introduction');
});
it('should clear when ESQ is pressed', function() {
cy.get('.search-input').type('{esc}', { force: true });
cy
.get('.menu-content div')
.filter('.search-box')
.should('have.length', 0);
});
});

View File

@ -0,0 +1,20 @@
describe('Standalone bundle test', function() {
function baseCheck(name: string, url: string) {
describe(name, () => {
before(() => {
cy.visit(url);
});
it('Render and check no errors', function() {
cy.get('.api-info').should('exist');
});
it('Render and click all the menu items', function() {
cy.get('.menu-content li').click({ multiple: true, force: true });
});
});
}
baseCheck('OAS3 mode', 'e2e/standalone.html');
baseCheck('OAS2 compatibility mode', 'e2e/standalone-compatibility.html');
});

View File

@ -0,0 +1,29 @@
const wp = require('@cypress/webpack-preprocessor');
const webpackOptions = {
resolve: {
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
exclude: [/node_modules/],
use: [
{
loader: 'awesome-typescript-loader',
options: {
configFileName: 'e2e/tsconfig.json',
},
},
],
},
],
},
};
const options = {
webpackOptions,
};
module.exports = wp(options);

5
e2e/plugins/index.js Normal file
View File

@ -0,0 +1,5 @@
const cypressTypeScriptPreprocessor = require('./cy-ts-preprocessor');
module.exports = on => {
on('file:preprocessor', cypressTypeScriptPreprocessor);
};

View File

@ -1,29 +0,0 @@
describe('Standalone bundle test', function() {
describe('OAS3 mode', () => {
before(() => {
cy.visit('e2e/standalone.html');
});
it('Render and check no errors', function() {
cy.get('.api-info').should('exist');
});
it('Render and click all the menu items', function() {
cy.get('.menu-content li').click({ multiple: true, force: true });
});
});
describe('OAS2 compatibility mode', () => {
before(() => {
cy.visit('e2e/standalone.html');
});
it('Render and check no errors', function() {
cy.get('.api-info').should('exist');
});
it('Render and click all the menu items', function() {
cy.get('.menu-content li').click({ multiple: true, force: true });
});
});
});

View File

@ -1,8 +1,8 @@
<html> <html>
<body> <body>
<redoc spec-url="../demo/openapi.yaml"></redoc> <redoc spec-url="../demo/openapi.yaml" native-scrollbars></redoc>
<script src="../bundles/redoc.standalone.js"></script> <script src="../bundles/redoc.standalone.js"></script>
</body> </body>
</html> </html>

View File

@ -1,15 +1,14 @@
{ {
"compilerOptions": { "compilerOptions": {
"experimentalDecorators": true, "experimentalDecorators": true,
"module": "es2015", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"target": "es5", "target": "es2015",
"noImplicitAny": false, "noImplicitAny": false,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"strictNullChecks": true, "strictNullChecks": true,
"sourceMap": true, "sourceMap": true,
"outDir": "e2e/.build",
"pretty": true, "pretty": true,
"lib": [ "lib": [
"es2015", "es2015",
@ -22,7 +21,7 @@
}, },
"compileOnSave": false, "compileOnSave": false,
"include": [ "include": [
"./node_modules/cypress", "integration/*.ts",
"e2e" "../node_modules/cypress"
] ]
} }

View File

@ -9,9 +9,7 @@
"start:prod": "webpack-dev-server --env.prod", "start:prod": "webpack-dev-server --env.prod",
"test": "npm run lint && npm run unit && npm run e2e", "test": "npm run lint && npm run unit && npm run e2e",
"unit": "jest", "unit": "jest",
"e2e": "npm run e2e:clean && npm run e2e:tsc && cypress run", "e2e": "cypress run",
"e2e:tsc": "tsc -p tsconfig.e2e.json",
"e2e:clean": "rimraf e2e/.build",
"cy:open": "cypress open", "cy:open": "cypress open",
"bundle:clean": "rimraf bundles", "bundle:clean": "rimraf bundles",
"bundle:standalone": "webpack -p --env.lib --env.standalone --env.prod", "bundle:standalone": "webpack -p --env.lib --env.standalone --env.prod",
@ -26,7 +24,7 @@
"author": "", "author": "",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/cypress": "^1.1.3", "@cypress/webpack-preprocessor": "^1.1.3",
"@types/dompurify": "^0.0.31", "@types/dompurify": "^0.0.31",
"@types/enzyme": "^3.1.8", "@types/enzyme": "^3.1.8",
"@types/enzyme-to-json": "^1.5.0", "@types/enzyme-to-json": "^1.5.0",
@ -83,6 +81,7 @@
}, },
"dependencies": { "dependencies": {
"@types/marked": "^0.3.0", "@types/marked": "^0.3.0",
"classnames": "^2.2.5",
"decko": "^1.2.0", "decko": "^1.2.0",
"dompurify": "^1.0.2", "dompurify": "^1.0.2",
"eventemitter3": "^3.0.0", "eventemitter3": "^3.0.0",
@ -104,6 +103,9 @@
"styled-components": "^3.1.0", "styled-components": "^3.1.0",
"swagger2openapi": "^2.11.0" "swagger2openapi": "^2.11.0"
}, },
"resolutions": {
"@types/chai": "4.0.8"
},
"jest": { "jest": {
"mapCoverage": true, "mapCoverage": true,
"transform": { "transform": {

View File

@ -7,7 +7,9 @@ import { SearchStore } from '../../services/SearchStore';
import { MenuItem } from '../SideMenu/MenuItem'; import { MenuItem } from '../SideMenu/MenuItem';
import { MenuItemLabel } from '../SideMenu/styled.elements'; import { MenuItemLabel } from '../SideMenu/styled.elements';
const SearchInput = styled.input` const SearchInput = styled.input.attrs({
className: 'search-input',
})`
width: calc(100% - ${props => props.theme.spacingUnit * 2}px); width: calc(100% - ${props => props.theme.spacingUnit * 2}px);
box-sizing: border-box; box-sizing: border-box;
margin: 0 ${props => props.theme.spacingUnit}px; margin: 0 ${props => props.theme.spacingUnit}px;
@ -32,7 +34,9 @@ const SearchIcon = styled((props: any) => (
> >
<path d="M968.2,849.4L667.3,549c83.9-136.5,66.7-317.4-51.7-435.6C477.1-25,252.5-25,113.9,113.4c-138.5,138.3-138.5,362.6,0,501C219.2,730.1,413.2,743,547.6,666.5l301.9,301.4c43.6,43.6,76.9,14.9,104.2-12.4C981,928.3,1011.8,893,968.2,849.4z M524.5,522c-88.9,88.7-233,88.7-321.8,0c-88.9-88.7-88.9-232.6,0-321.3c88.9-88.7,233-88.7,321.8,0C613.4,289.4,613.4,433.3,524.5,522z" /> <path d="M968.2,849.4L667.3,549c83.9-136.5,66.7-317.4-51.7-435.6C477.1-25,252.5-25,113.9,113.4c-138.5,138.3-138.5,362.6,0,501C219.2,730.1,413.2,743,547.6,666.5l301.9,301.4c43.6,43.6,76.9,14.9,104.2-12.4C981,928.3,1011.8,893,968.2,849.4z M524.5,522c-88.9,88.7-233,88.7-321.8,0c-88.9-88.7-88.9-232.6,0-321.3c88.9-88.7,233-88.7,321.8,0C613.4,289.4,613.4,433.3,524.5,522z" />
</svg> </svg>
))` )).attrs({
className: 'search-icon',
})`
position: absolute; position: absolute;
left: ${props => props.theme.spacingUnit}px; left: ${props => props.theme.spacingUnit}px;
height: 1.8em; height: 1.8em;
@ -43,7 +47,9 @@ const SearchIcon = styled((props: any) => (
} }
`; `;
const SearchResultsBox = styled.div` const SearchResultsBox = styled.div.attrs({
className: 'search-results',
})`
padding: ${props => props.theme.spacingUnit / 4}px 0; padding: ${props => props.theme.spacingUnit / 4}px 0;
background-color: #ededed; background-color: #ededed;
min-height: 150px; min-height: 150px;

View File

@ -1,5 +1,6 @@
import { deprecatedCss } from '../../common-elements'; import { deprecatedCss } from '../../common-elements';
import styled, { css, withProps } from '../../styled-components'; import styled, { css, withProps } from '../../styled-components';
import * as classnames from 'classnames';
export const OperationBadge = withProps<{ type: string }>(styled.span).attrs({ export const OperationBadge = withProps<{ type: string }>(styled.span).attrs({
className: props => `operation-type ${props.type}`, className: props => `operation-type ${props.type}`,
@ -112,7 +113,12 @@ export const MenuItemLabel = withProps<{
depth: number; depth: number;
active: boolean; active: boolean;
deprecated?: boolean; deprecated?: boolean;
}>(styled.label)` }>(styled.label).attrs({
className: props =>
classnames('menu-item', '-depth' + props.depth, {
active: props.active,
}),
})`
cursor: pointer; cursor: pointer;
color: ${props => (props.active ? props.theme.colors.main : props.theme.colors.text)}; color: ${props => (props.active ? props.theme.colors.main : props.theme.colors.text)};
margin: 0; margin: 0;

View File

@ -29,7 +29,7 @@
"node_modules", "node_modules",
".tmp", ".tmp",
"lib", "lib",
"e2e" "e2e/**"
], ],
"include": [ "include": [
"./custom.d.ts", "./custom.d.ts",

1189
yarn.lock

File diff suppressed because it is too large Load Diff