Skip to content

Commit ccdf86d

Browse files
authored
ui testing (#140)
* use cypress to run ui tests * provide few ideas for test to be developed (see TODO in cypress tests) * different enabling changes: 1. enable logout button 2. enable profile button 3. force redirect to 403 when accessing not authorized pages * 404 page + simple tests
1 parent 2e9a3c5 commit ccdf86d

21 files changed

+2694
-79
lines changed

.github/workflows/graphQL_tests.yml

-41
This file was deleted.

.github/workflows/test.yml

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: tests
2+
'on':
3+
push:
4+
pull_request:
5+
types:
6+
- opened
7+
- synchronize
8+
- reopened
9+
jobs:
10+
graphql:
11+
name: 'graphql tests - Node.js v${{ matrix.node }}'
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
node:
16+
- 16
17+
steps:
18+
- uses: actions/setup-node@v3
19+
with:
20+
node-version: '${{ matrix.node }}'
21+
- uses: actions/checkout@v3
22+
- name: 'Cache node_modules'
23+
uses: actions/cache@v3
24+
with:
25+
path: ~/.npm
26+
key: ${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('**/package.json') }}
27+
restore-keys: |
28+
${{ runner.os }}-node-v${{ matrix.node }}-
29+
- name: Setup Docker
30+
run: ./start.sh dev
31+
- name: Install Dependencies
32+
run: npm install
33+
working-directory: configuration-api
34+
- name: populate DB
35+
run: node main/mongo/populateDB.js
36+
working-directory: configuration-api
37+
- name: Run configuration api tests
38+
run: node main/advancedAuth.js & npm test
39+
working-directory: configuration-api
40+
- name: stop Docker
41+
run: ./stop.sh dev
42+
cypress:
43+
name: 'cypress tests - Node.js v${{ matrix.node }}'
44+
runs-on: ubuntu-latest
45+
strategy:
46+
matrix:
47+
node:
48+
- 16
49+
steps:
50+
- uses: actions/setup-node@v3
51+
with:
52+
node-version: '${{ matrix.node }}'
53+
- uses: actions/checkout@v3
54+
- name: 'Cache node_modules'
55+
uses: actions/cache@v3
56+
with:
57+
path: ~/.npm
58+
key: ${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('**/package.json') }}
59+
restore-keys: |
60+
${{ runner.os }}-node-v${{ matrix.node }}-
61+
- name: Add hosts to /etc/hosts
62+
run: |
63+
sudo echo "127.0.0.1 keycloak" | sudo tee -a /etc/hosts
64+
- name: set-up environment
65+
run: cp .env.docker .env
66+
- name: Setup Docker
67+
run: ./start.sh silent
68+
- name: Install Dependencies
69+
run: npm install
70+
- name: Run cypress tests
71+
run: npm run cypress:test
72+
- name: stop Docker
73+
run: ./stop.sh

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,7 @@ dist
132132
npm-debug.log*
133133
yarn-debug.log*
134134
yarn-error.log*
135+
136+
# cypress
137+
cypress/videos
138+
cypress/screenshots

README.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,24 @@ $ npm install
197197
$ npm run storybook
198198
```
199199

200+
### How to test the UI with Cypress
201+
202+
To test UI with Cypress the UI and API should be up and running, once completed:
203+
204+
```bash
205+
$ npm install
206+
$ npm run cypress:test
207+
```
208+
209+
If you want to open cypress studio to run tests in the UI, or add new tests:
210+
211+
```bash
212+
$ npm run cypress:open
213+
```
214+
200215
### How to test the Configuration API
201216

202-
To test Graphql is **mandatory** to set up the Configuration API
217+
To test GraphQL is **mandatory** to set up the Configuration API
203218
first, once completed:
204219

205220
```bash

RELEASE_NOTES.md

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
- Reduce size of some graphical elements (e.g. topbar)
1313
- Close side bar on navlink click (#132)
1414
- Implement access control to pages / menus based on role / group
15+
- Set-up logout link (#137)
16+
- Set-up link to profile (#137)
1517

1618
### Bug fixes
1719

@@ -23,6 +25,8 @@
2325

2426
### Continuous Integration
2527

28+
- Add basic UI test based on cypress (#4)
29+
2630
### Technical debt
2731

2832
## 0.6

cypress.config.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const { defineConfig } = require('cypress');
2+
3+
module.exports = defineConfig({
4+
video: false,
5+
screenshotOnRunFailure: false,
6+
env: {
7+
'cypress-react-selector': {
8+
root: '#root'
9+
}
10+
},
11+
e2e: {
12+
experimentalStudio: true,
13+
baseUrl: 'http://localhost:3000',
14+
chromeWebSecurity: false,
15+
experimentalSessionAndOrigin: true
16+
}
17+
});

cypress/e2e/spec.cy.js

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
describe('Test page access', () => {
2+
it('Admin can access admin pages', () => {
3+
cy.login('admin@mail.com', 'admin');
4+
cy.waitForReact(2000, '#root');
5+
cy.visit('http://localhost:3000');
6+
cy.wait(50).contains('Security');
7+
cy.wait(50).contains('Data Management');
8+
cy.wait(50).contains('Administration');
9+
cy.wait(50).contains('Tenants');
10+
cy.get('[href="/Tenant"] > .MuiButtonBase-root > .MuiListItemText-root > .MuiTypography-root').click();
11+
cy.wait(50)
12+
.get(
13+
'[style="opacity: 1; transform: none; transform-origin: 0px 0px 0px; transition: opacity 0ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, transform 0ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"] > .css-1jq2n4l > .MuiCardHeader-root > .MuiCardHeader-content > .MuiCardHeader-title'
14+
)
15+
.should('have.text', 'Tenant1');
16+
/* ==== End Cypress Studio ==== */
17+
});
18+
it('User1 cannot access Admin pages', () => {
19+
cy.login('user1@mail.com', 'user1');
20+
cy.waitForReact(2000, '#root');
21+
cy.visit('http://localhost:3000');
22+
cy.wait(500).contains('Security');
23+
cy.wait(500).contains('Data Management');
24+
cy.visit('http://localhost:3000/Tenant');
25+
cy.wait(500).contains('403');
26+
cy.visit('http://localhost:3000/Service');
27+
cy.wait(500).contains('403');
28+
cy.visit('http://localhost:3000/ResourceType');
29+
cy.wait(500).contains('403');
30+
});
31+
it('Not existing pages causes 404', () => {
32+
cy.login('admin@mail.com', 'admin');
33+
cy.waitForReact(2000, '#root');
34+
cy.visit('http://localhost:3000/myPage');
35+
cy.wait(500).contains('404');
36+
/* ==== End Cypress Studio ==== */
37+
});
38+
});
39+
40+
describe('Test Tenants', () => {
41+
//TODO
42+
});
43+
44+
describe('Test Services', () => {
45+
//TODO
46+
});
47+
48+
describe('Test Policies', () => {
49+
//TODO
50+
});
51+
52+
describe('Test Resource Type', () => {
53+
//TODO
54+
});
55+
56+
describe('Test Toolbar', () => {
57+
it('Change Tenant', () => {
58+
cy.login('admin@mail.com', 'admin');
59+
/* ==== Generated with Cypress Studio ==== */
60+
cy.visit('http://localhost:3000');
61+
cy.waitForReact(2000, '#root');
62+
//TODO
63+
/* ==== End Cypress Studio ==== */
64+
});
65+
it('Change Language', () => {
66+
cy.login('user1@mail.com', 'user1');
67+
/* ==== Generated with Cypress Studio ==== */
68+
cy.visit('http://localhost:3000');
69+
cy.waitForReact(2000, '#root');
70+
//TODO
71+
/* ==== End Cypress Studio ==== */
72+
});
73+
});

cypress/support/e2e.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import 'cypress-react-selector';
2+
3+
Cypress.Commands.add('login', (username, password) => {
4+
cy.visit('http://localhost:3000');
5+
cy.get('#username').type(username);
6+
cy.get('#password').type(password);
7+
cy.wait(100).get('form').contains('Sign In').click();
8+
});
9+
10+
Cypress.on('uncaught:exception', (err, runnable) => {
11+
//TODO: this is required because the exception is not handled by the ui.
12+
if (err.message.includes('Expected Iterable, but did not find one for field "Query.getUserPreferences"')) {
13+
return false;
14+
}
15+
// we still want to ensure there are no other unexpected
16+
// errors, so we let them fail the test
17+
});

docker-compose.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ services:
6262
management-ui:
6363
build:
6464
context: ./
65-
dockerfile: ./Dockerfile
65+
dockerfile: ./dockerfile
6666
volumes:
6767
- .env.docker:/usr/share/nginx/.env
6868
image: orchestracities/management-ui
@@ -74,7 +74,7 @@ services:
7474
configuration-api:
7575
build:
7676
context: ./configuration-api
77-
dockerfile: ./Dockerfile
77+
dockerfile: ./dockerfile
7878
env_file: .env
7979
image: orchestracities/configuration-api
8080
ports:

documentation/stories/shared/Usermenu.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ UsrMenu.propTypes = {
3535

3636
UsrMenu.defaultProps = {
3737
language: { language: 'defaultBrowser', setLanguage: () => {} },
38-
userData: {},
38+
userData: { name: 'EasterEgg' },
3939
token: undefined
4040
};

documentation/stories/shared/Usermenu.stories.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ export const Main = Template.bind({});
3838
// More on args: https://storybook.js.org/docs/react/writing-stories/args
3939
Main.args = {
4040
language: { language: 'defaultBrowser', setLanguage: () => {} },
41-
userData: {},
41+
userData: { name: 'EasterEgg' },
4242
token: ''
4343
};

0 commit comments

Comments
 (0)