Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Commit

Permalink
1080 Set up cypress (#596)
Browse files Browse the repository at this point in the history
* Setup cypress

* Update utils

* Add first e2e test

* Add functions to generate utils

* Add classNames

* Update snapshots

* Add tests for header

* Add tests for home page

* Add login page spec

* Update readme

* Remove videos
  • Loading branch information
Stafeeva authored Mar 10, 2020
1 parent 4cfe378 commit d20fe96
Show file tree
Hide file tree
Showing 17 changed files with 571 additions and 59 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ storybook-static/
coverage/
.vscode
yarn-error.log
cypress/screenshots/
cypress/plugins/
cypress/fixtures/
cypress/videos/
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ docker build . --tag=nexus-web
The following concern Plugins. [See how to manage plugin deployments](./docs/plugins.md)

- `PLUGINS_MANIFEST_PATH`: Remote end point where plugins and manifest can be found. for example, `https://bbp-nexus.epfl.ch/plugins`
- `PLUGINS_CONFIG_PATH`: A full file path where a plugins configuration can be found.
- `PLUGINS_CONFIG_PATH`: A full file path where a plugins configuration can be found.

## Deployment

Expand Down Expand Up @@ -126,3 +126,23 @@ There are several channels provided to address different issues:
### When building URLs inside the App

- Don't add the basePath in a URL, it will be added automatically by react-router.

### UI Testing

UI tests are implemented with [Cypress]('https://www.cypress.io/').

To launch Cypress window in order to test UI locally, run:

```sh
yarn test-ui
```

Make sure Nexus Web app is running locally and you use staging API, otherwise there won't be data available, and tests are likely to fail.

To run in a headless mode, use the following command:

```sh
yarn run cypress run --headless --browser chrome
```

It will run all the test scripts.
4 changes: 4 additions & 0 deletions cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"viewportWidth": 1200,
"video": false
}
36 changes: 36 additions & 0 deletions cypress/integration/e2e/e2e_create_studio.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { homePage } from '../../support';
import { createInput, createLongerInput } from '../../support/utils';

describe('User is not logged in', () => {
const studioLabel = createInput();
const description = createLongerInput();
const workspaceLabel = createInput();
const workspaceDescription = createLongerInput();
const dashboardLabel = createInput();
const dashboardDescpription = createLongerInput();

it('Creates Studio with Workspace and Dashboard', () => {
cy.visit(homePage);
cy.contains('Organizations');
cy.get('.ListItem').click();
cy.get('.ListItem').click();
cy.contains('Studios').click();
cy.contains('Create Studio').click();
cy.get('.ui-studio-label-input').type(studioLabel);
cy.get('.ui-studio-description-input').type(description);
cy.get('form').submit();
cy.wait(3000);
cy.contains(studioLabel);
cy.contains(description);
cy.contains('Add Workspace').click();
cy.get('.ui-workspace-label-input').type(workspaceLabel);
cy.get('.ui-workspace-description-input').type(workspaceDescription);
cy.get('form').submit();
cy.contains(workspaceLabel);
cy.contains('Add Dashboard').click();
cy.contains('Create Dashboard');
cy.get('.ui-dashboard-label-input').type(dashboardLabel);
cy.get('.ui-dashboard-description-input').type(dashboardDescpription);
cy.get('form').submit();
});
});
35 changes: 35 additions & 0 deletions cypress/integration/elements/header.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { homePage, docLink, reportIssueLink } from '../../support';

describe('Header', () => {
beforeEach(() => {
cy.visit(homePage);
});

it('contains the title', () => {
cy.contains('h1', 'Nexus');
});

it('contains the link to the homepage', () => {
cy.contains('a', 'Nexus').should('have.attr', 'href', '');
});

it('has the login link', () => {
cy.contains('a', 'login');
});

it('contains the link to docs', () => {
cy.contains('a', 'Documentation').should('have.attr', 'href', docLink);
});

it('contains the link to open a github issue', () => {
cy.contains('a', 'Report Issue').should(
'have.attr',
'href',
reportIssueLink
);
});

it('contains the information button', () => {
cy.get('.ui-header-info-button').should('be.visible');
});
});
24 changes: 24 additions & 0 deletions cypress/integration/pages/home.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { homePage } from '../../support';

describe('Homepage', () => {
beforeEach(() => {
cy.visit(homePage);
});

it('has a header', () => {
cy.get('header.Header').should('be.visible');
});

it('show a list of organisations', () => {
cy.contains('h1', 'Organizations');
});

it('loads organizations', () => {
cy.server();
cy.route('GET', '/orgs?deprecated=false&size=20');
});

it('allows to search for an organization', () => {
cy.get('input').type('bbp');
});
});
19 changes: 19 additions & 0 deletions cypress/integration/pages/login.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { loginPage } from '../../support';

describe('Login page', () => {
beforeEach(() => {
cy.visit(loginPage);
});

it('has a header', () => {
cy.get('header.Header').should('be.visible');
});

it('contains the Nexus logo', () => {
cy.get('.logo').should('be.visible');
});

it('has the login button', () => {
cy.contains('button', 'Log in');
});
});
25 changes: 25 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -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) => { ... })
28 changes: 28 additions & 0 deletions cypress/support/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// ***********************************************************
// 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')

import './commands';

export const homePage = 'http://localhost:8000';
export const loginPage = 'http://localhost:8000/login';

export const docLink = 'https://bluebrainnexus.io/docs';
export const reportIssueLink =
'https://github.com/BlueBrain/nexus/issues/new?labels=frontend,nexus-web';
51 changes: 51 additions & 0 deletions cypress/support/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const inputs = [
'thalamus',
'neurotransmitters',
'angiography',
'cerebrospinal',
'mapping',
'cortex',
'synaptic',
'vestibular',
'optogenetics',
'neuron',
'microglia',
'insula',
'expression',
'phenotyping',
'connectome',
'sensory',
'spinal',
'cord',
'data',
'ion',
'potential',
'stem',
'integrative',
'project',
'cognition',
'neocortical',
'biomedical',
'molecular',
'polyphenols',
'trans-resveratrol',
'angiographic',
'multimerization',
'derivatives',
'randomized',
'vivarium',
'monophosphate',
'protein',
'measurements',
'procedure',
];

const randomValue = array => array[Math.floor(Math.random() * array.length)];

export const createInput = () => {
return randomValue(inputs) + '-cy-test';
};

export const createLongerInput = () => {
return randomValue(inputs) + ' ' + randomValue(inputs) + 'cypress test';
};
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"start": "NODE_ENV=development DEBUG=* webpack --mode development --config-name server && node dist/server.js",
"build": "NODE_ENV=production webpack --mode production",
"test": "jest",
"test-ui": "yarn run cypress open",
"codecov": "codecov",
"lint": "tslint --project tsconfig.json",
"style": "prettier --check \"./src/**/*.{ts,tsx,js,jsx,less}\"",
Expand All @@ -27,6 +28,7 @@
"codemirror": "^5.44.0",
"connected-react-router": "^6.3.2",
"cookie-parser": "^1.4.4",
"cypress": "^4.1.0",
"cytoscape": "^3.12.0",
"cytoscape-cola": "^2.3.0",
"deep-object-diff": "^1.1.0",
Expand Down Expand Up @@ -133,7 +135,10 @@
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/__mocks__/fileMock.js",
"\\.(css|less)$": "<rootDir>/src/__mocks__/styleMock.js"
}
},
"testPathIgnorePatterns": [
"<rootDir>/cypress/"
]
},
"prettier": {
"singleQuote": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const DashboardConfigEditorComponent: React.FunctionComponent<DashboardConfigEdi
message: 'Please input a label!',
},
],
})(<Input />)}
})(<Input className="ui-dashboard-label-input" />)}
</Form.Item>
<Form.Item
label={
Expand All @@ -97,7 +97,7 @@ const DashboardConfigEditorComponent: React.FunctionComponent<DashboardConfigEdi
required: false,
},
],
})(<TextArea />)}
})(<TextArea className="ui-dashboard-description-input" />)}
</Form.Item>
<Form.Item
label={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ exports[`Header component Should render correctly 1`] = `
>
<Button
block={false}
className="ui-header-info-button"
ghost={false}
htmlType="button"
icon="info-circle"
Expand Down
6 changes: 5 additions & 1 deletion src/shared/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,11 @@ const Header: React.FunctionComponent<HeaderProps> = ({
title="Information"
placement="bottomRight"
>
<Button size="small" icon="info-circle" />
<Button
size="small"
icon="info-circle"
className="ui-header-info-button"
/>
</Popover>
{name ? (
<Dropdown overlay={menu}>
Expand Down
4 changes: 2 additions & 2 deletions src/shared/components/Studio/StudioEditorForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const StudioEditorForm: React.FC<{
message: 'Please input a label!',
},
],
})(<Input />)}
})(<Input className="ui-studio-label-input" />)}
</Form.Item>
<Form.Item
label={
Expand All @@ -72,7 +72,7 @@ const StudioEditorForm: React.FC<{
>
{getFieldDecorator('description', {
initialValue: description,
})(<TextArea />)}
})(<TextArea className="ui-studio-description-input" />)}
</Form.Item>
<Button type="primary" htmlType="submit">
Save
Expand Down
4 changes: 2 additions & 2 deletions src/shared/components/Studio/WorkspaceEditorForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const WorkspaceEditorForm: React.FC<{
message: 'Please input a label!',
},
],
})(<Input />)}
})(<Input className="ui-workspace-label-input" />)}
</Form.Item>
<Form.Item
label={
Expand All @@ -72,7 +72,7 @@ const WorkspaceEditorForm: React.FC<{
>
{getFieldDecorator('description', {
initialValue: description,
})(<TextArea />)}
})(<TextArea className="ui-workspace-description-input" />)}
</Form.Item>
<Button type="primary" htmlType="submit">
Save
Expand Down
Loading

0 comments on commit d20fe96

Please sign in to comment.