mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-21 16:16:33 +03:00
chore: add a few more integration tests
This commit is contained in:
parent
13165fb8fc
commit
b33b9543fa
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"ignoreTestFiles": "*.js.map",
|
||||
"integrationFolder": "e2e/.build",
|
||||
"integrationFolder": "e2e/integration",
|
||||
"pluginsFile": "e2e/plugins/index.js",
|
||||
"fixturesFolder": false,
|
||||
"supportFile": false,
|
||||
"fileServerFolder": ".",
|
||||
|
|
50
e2e/integration/menu.e2e.ts
Normal file
50
e2e/integration/menu.e2e.ts
Normal 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');
|
||||
});
|
||||
});
|
38
e2e/integration/search.e2e.ts
Normal file
38
e2e/integration/search.e2e.ts
Normal 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);
|
||||
});
|
||||
});
|
20
e2e/integration/standalone.e2e.ts
Normal file
20
e2e/integration/standalone.e2e.ts
Normal 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');
|
||||
});
|
29
e2e/plugins/cy-ts-preprocessor.js
Normal file
29
e2e/plugins/cy-ts-preprocessor.js
Normal 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
5
e2e/plugins/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
const cypressTypeScriptPreprocessor = require('./cy-ts-preprocessor');
|
||||
|
||||
module.exports = on => {
|
||||
on('file:preprocessor', cypressTypeScriptPreprocessor);
|
||||
};
|
|
@ -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 });
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,8 +1,8 @@
|
|||
<html>
|
||||
|
||||
<body>
|
||||
<redoc spec-url="../demo/openapi.yaml"></redoc>
|
||||
<redoc spec-url="../demo/openapi.yaml" native-scrollbars></redoc>
|
||||
<script src="../bundles/redoc.standalone.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
|
@ -1,15 +1,14 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"module": "es2015",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"target": "es5",
|
||||
"target": "es2015",
|
||||
"noImplicitAny": false,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"strictNullChecks": true,
|
||||
"sourceMap": true,
|
||||
"outDir": "e2e/.build",
|
||||
"pretty": true,
|
||||
"lib": [
|
||||
"es2015",
|
||||
|
@ -22,7 +21,7 @@
|
|||
},
|
||||
"compileOnSave": false,
|
||||
"include": [
|
||||
"./node_modules/cypress",
|
||||
"e2e"
|
||||
"integration/*.ts",
|
||||
"../node_modules/cypress"
|
||||
]
|
||||
}
|
10
package.json
10
package.json
|
@ -9,9 +9,7 @@
|
|||
"start:prod": "webpack-dev-server --env.prod",
|
||||
"test": "npm run lint && npm run unit && npm run e2e",
|
||||
"unit": "jest",
|
||||
"e2e": "npm run e2e:clean && npm run e2e:tsc && cypress run",
|
||||
"e2e:tsc": "tsc -p tsconfig.e2e.json",
|
||||
"e2e:clean": "rimraf e2e/.build",
|
||||
"e2e": "cypress run",
|
||||
"cy:open": "cypress open",
|
||||
"bundle:clean": "rimraf bundles",
|
||||
"bundle:standalone": "webpack -p --env.lib --env.standalone --env.prod",
|
||||
|
@ -26,7 +24,7 @@
|
|||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/cypress": "^1.1.3",
|
||||
"@cypress/webpack-preprocessor": "^1.1.3",
|
||||
"@types/dompurify": "^0.0.31",
|
||||
"@types/enzyme": "^3.1.8",
|
||||
"@types/enzyme-to-json": "^1.5.0",
|
||||
|
@ -83,6 +81,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@types/marked": "^0.3.0",
|
||||
"classnames": "^2.2.5",
|
||||
"decko": "^1.2.0",
|
||||
"dompurify": "^1.0.2",
|
||||
"eventemitter3": "^3.0.0",
|
||||
|
@ -104,6 +103,9 @@
|
|||
"styled-components": "^3.1.0",
|
||||
"swagger2openapi": "^2.11.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/chai": "4.0.8"
|
||||
},
|
||||
"jest": {
|
||||
"mapCoverage": true,
|
||||
"transform": {
|
||||
|
|
|
@ -7,7 +7,9 @@ import { SearchStore } from '../../services/SearchStore';
|
|||
import { MenuItem } from '../SideMenu/MenuItem';
|
||||
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);
|
||||
box-sizing: border-box;
|
||||
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" />
|
||||
</svg>
|
||||
))`
|
||||
)).attrs({
|
||||
className: 'search-icon',
|
||||
})`
|
||||
position: absolute;
|
||||
left: ${props => props.theme.spacingUnit}px;
|
||||
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;
|
||||
background-color: #ededed;
|
||||
min-height: 150px;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { deprecatedCss } from '../../common-elements';
|
||||
import styled, { css, withProps } from '../../styled-components';
|
||||
import * as classnames from 'classnames';
|
||||
|
||||
export const OperationBadge = withProps<{ type: string }>(styled.span).attrs({
|
||||
className: props => `operation-type ${props.type}`,
|
||||
|
@ -112,7 +113,12 @@ export const MenuItemLabel = withProps<{
|
|||
depth: number;
|
||||
active: boolean;
|
||||
deprecated?: boolean;
|
||||
}>(styled.label)`
|
||||
}>(styled.label).attrs({
|
||||
className: props =>
|
||||
classnames('menu-item', '-depth' + props.depth, {
|
||||
active: props.active,
|
||||
}),
|
||||
})`
|
||||
cursor: pointer;
|
||||
color: ${props => (props.active ? props.theme.colors.main : props.theme.colors.text)};
|
||||
margin: 0;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
"node_modules",
|
||||
".tmp",
|
||||
"lib",
|
||||
"e2e"
|
||||
"e2e/**"
|
||||
],
|
||||
"include": [
|
||||
"./custom.d.ts",
|
||||
|
|
Loading…
Reference in New Issue
Block a user