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

Commit 9aaf46b

Browse files
banzoFaiez ZalilaRami SellamiSebastien Dupont
authored
Feature/tests (#123)
Setup the testing framework for fadi. Add automated testing of the services using Jest and Puppeteer, test cases and scenarios specifications and implementation. Co-authored-by: Faiez Zalila <[email protected]> Co-authored-by: Rami Sellami <[email protected]> Co-authored-by: Sebastien Dupont <[email protected]>
1 parent 04a6653 commit 9aaf46b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+5952
-1
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,6 @@ teardown.log
4848
*.tgz
4949

5050
# https://github.com/ekalinin/github-markdown-toc
51-
gh-md-toc
51+
gh-md-toc
52+
53+
.vscode

.gitlab-ci.sample.yml

+12
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ stages:
99
- tf_plan
1010
- tf_apply
1111
- deployWithHelm
12+
- test
1213

1314
variables:
1415
KUBECONFIG: /etc/deploy/config
@@ -132,3 +133,14 @@ deployWithHelm:
132133
url: http://$PROJECT
133134
only:
134135
- master
136+
137+
test:
138+
stage: test
139+
image: ceticasbl/puppeteer-jest
140+
script:
141+
- cd tests/
142+
- npm run test
143+
tags:
144+
- docker
145+
only:
146+
- develop

doc/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ FADI Documentation
55
* [Users management](USERMANAGEMENT.md) - user identification and authorization (LDAP, RBAC, ...)
66
* [Reverse proxy](REVERSEPROXY.md) - Traefik reverse proxy configuration
77
* [Security](SECURITY.md) - SSL setup
8+
* [Testing](/tests/README.md) - tests for the FADI framework
89
* [TSimulus](TSIMULUS.md) - how to simulate sensors and generate realistic data with [TSimulus](https://github.com/cetic/TSimulus)
910
* [Sample self-hosted infrastructure](RANCHER_PROXMOX.md) - How to install FADI on a self hosted infrastructure using
1011
* [Proxmox](https://www.proxmox.com/en/) as a self-hosted private cloud (IaaS) provider. It provides virtual machines for the various Kubernetes nodes.

tests/.prettierrc.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"semi": false,
3+
"singleQuote": true,
4+
"useTabs": true,
5+
"tabWidth": 2,
6+
"bracketSpacing": true,
7+
"arrowParens": "avoid",
8+
"trailingComma": "es5"
9+
}

tests/README.md

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Testing the FADI framework
2+
3+
<img src="https://miro.medium.com/max/1788/1*wby6AkTf3SggijT3GSTu4w.png" height="100" align="right" alt="Jest Puppeteer">
4+
5+
[![implemented with puppeteer](https://img.shields.io/badge/implemented%20with-puppeteer-%2300D8A2)](https://pptr.dev) [![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest)
6+
7+
* [Introduction](#introduction)
8+
* [Quick start](#quick-start)
9+
* [Example](#examples)
10+
* [Documentation](#documentation)
11+
* [References](#references)
12+
13+
## Introduction
14+
15+
The FADI framework is tested using Puppeteer and Jest.
16+
17+
[Puppeteer](https://pptr.dev) is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.
18+
19+
[Jest](https://jestjs.io) is a JavaScript Testing Framework with a focus on simplicity. It works with projects using: Babel, TypeScript, Node, React, Angular, Vue and more!
20+
21+
## Quick start
22+
23+
To test the FADI framework, you need to implement the following instructions:
24+
25+
1. Install FADI framework. Refer to [the INSTALL section](../INSTALL.md).
26+
2. Create a Docker container using [the Puppeteer-Jest Docker image](https://hub.docker.com/repository/docker/fzalila/docker-puppeteer-jest). To achieve that, run the following command:
27+
28+
```bash
29+
docker container run --name testing-fadi fzalila/docker-puppeteer-jest:latest
30+
```
31+
32+
3. Inside the created container, clone the FADI repository:
33+
34+
```bash
35+
git clone https://github.com/cetic/fadi.git
36+
```
37+
38+
4. Configure [here](./lib/config.js) the urls and paths of different FADI platform services
39+
40+
5. Go to the `tests` folder and launch the tests:
41+
42+
```bash
43+
cd fadi/tests
44+
npm run test
45+
```
46+
47+
If tests pass, you should obtain the following results:
48+
49+
<img src="doc/images/test_results.png" height="500" alt="Tests results" />
50+
51+
## Examples
52+
53+
The following example checks the creation of a `example_basic` table in the `postgres` database.
54+
55+
```js
56+
it('should create a table', async () => {
57+
// Go to the indicated page
58+
await page.goto(url)
59+
60+
// Click on SQL query button
61+
await click(page, '.ltr > #menu > .links > a:nth-child(1)')
62+
63+
// type the query
64+
await typeText(page, 'CREATE TABLE example_basic (measure_ts TIMESTAMP NOT NULL,temperature FLOAT (50));', '.ltr > #content > #form > p > .jush')
65+
66+
// Execute the table creation query
67+
await click(page, '.ltr > #content > #form > p > input:nth-child(1)')
68+
69+
// Check the creation of the table
70+
await shouldExist(page, '#content > p.message')
71+
})
72+
```
73+
74+
More examples are available in the [test-scripts folder](doc/test-scripts/).
75+
76+
## Documentation
77+
78+
Test cases of the FADI framework are specified using Cockburns[[1](#references)] templates, available [here](doc/Cockburns-specification.md).
79+
80+
Test scripts specifications are available [here](doc/Test-scripts-specifications.md).
81+
82+
Two templates are available in order to define a new [test case](doc/cockburns/TC-template.md) and a new [test script](doc/test-scripts/TS-template.md).
83+
84+
## Continuous integration
85+
86+
To automate testing inside a continuous integration process, you can for example add a `test` stage to a Gitlab-CI pipeline by editing the [`.gitlab-ci.yml`](../.gitlab-ci.sample.yml) configuration:
87+
88+
```yaml
89+
stages:
90+
- deployWithHelm
91+
- test
92+
93+
deployWithHelm:
94+
[...]
95+
96+
test:
97+
stage: test
98+
image: ceticasbl/puppeteer-jest
99+
script:
100+
- cd tests/
101+
- npm run test
102+
```
103+
104+
## References
105+
106+
[1] Alistair Cockburn. 2000. Writing Effective Use Cases (1st. ed.). Addison-Wesley Longman Publishing Co., Inc., USA.

tests/TestSequencer.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const TestSequencer = require('@jest/test-sequencer').default;
2+
3+
class CustomSequencer extends TestSequencer {
4+
sort(tests) {
5+
const copyTests = Array.from(tests);
6+
return copyTests.sort((testA, testB) => (testA.path > testB.path ? 1 : -1));
7+
}}
8+
9+
module.exports = CustomSequencer;

tests/__tests__/1-adminer.test.js

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
const puppeteer = require('puppeteer')
2+
const jestpkg = require('jest')
3+
const config = require('../lib/config')
4+
const click = require('../lib/helpers').click
5+
const typeText = require('../lib/helpers').typeText
6+
const loadUrl = require('../lib/helpers').loadUrl
7+
const waitForText = require('../lib/helpers').waitForText
8+
const pressKey = require('../lib/helpers').pressKey
9+
const shouldExist = require('../lib/helpers').shouldExist
10+
const shouldNotExist = require('../lib/helpers').shouldNotExist
11+
const dragAndDrop = require('../lib/helpers').dragAndDrop
12+
const Sequencer = require('@jest/test-sequencer').default
13+
14+
const url = config.AdminerUrl
15+
//const utils = require('../lib/utils')
16+
17+
describe('Test the authentification to the Adminer service', () => {
18+
/** @type {puppeteer.Browser} */
19+
let browser
20+
21+
/** @type {puppeteer.Page} */
22+
let page
23+
24+
beforeAll(async function () {
25+
browser = await puppeteer.launch({
26+
headless: config.isHeadless,
27+
slowMo: config.slowMo,
28+
devtools: config.isDevtools,
29+
timeout: config.launchTimeout,
30+
args: ['--no-sandbox']
31+
})
32+
page = await browser.newPage()
33+
await page.setDefaultNavigationTimeout(config.waitingTimeout) //10 seconds is the industry standard
34+
await page.setViewport({
35+
width: config.viewportWidth,
36+
height: config.viewportHeight
37+
})
38+
})
39+
afterAll(async function () {
40+
await browser.close()
41+
})
42+
it('should success the authentification process', async () => {
43+
// Go to the indicated page
44+
await page.goto(url)
45+
46+
// Click on the DBMS list
47+
await click(page, '.layout > tbody > tr > td > select')
48+
49+
// Select the postgresql DBMS
50+
await page.select('.layout > tbody > tr > td > select', 'pgsql')
51+
52+
// Empty the server value content (usually 'db')
53+
await page.evaluate(() => document.querySelector(".layout > tbody > tr:nth-child(2) > td > input").value = "")
54+
55+
// Insert the server name fadi-postgresql
56+
await typeText(page, 'fadi-postgresql', ".layout > tbody > tr:nth-child(2) > td > input")
57+
58+
// Insert the user
59+
await typeText(page, 'admin', '.layout #username')
60+
61+
// Insert password
62+
await typeText(page, 'password1', '.layout > tbody > tr:nth-child(4) > td > input')
63+
64+
// insert the db name
65+
await typeText(page, 'postgres', '.layout > tbody > tr:nth-child(5) > td > input')
66+
67+
// Click on the authentification
68+
await click(page, '.ltr > #content > form > p > input')
69+
70+
await page.waitFor(6000)
71+
72+
// Check access to the authentification page
73+
const selector = await page.$('#content > h2')
74+
const text = await page.evaluate(selector => selector.textContent, selector);
75+
const result = text.includes('public')
76+
//console.log(text.includes('public'))
77+
expect(result).toBe(true)
78+
})
79+
80+
it('should create a table', async () => {
81+
// Go to the indicated page
82+
//await page.goto(url)
83+
84+
// Click on SQL query button
85+
await click(page, '.ltr > #menu > .links > a:nth-child(1)')
86+
87+
// type the query
88+
await typeText(page, 'CREATE TABLE example_basic (measure_ts TIMESTAMP NOT NULL,temperature FLOAT (50));', '.ltr > #content > #form > p > .jush')
89+
90+
// Execute the table creation query
91+
await click(page, '.ltr > #content > #form > p > input:nth-child(1)')
92+
93+
// Check the creation of the table
94+
await shouldExist(page, '#content > p.message')
95+
})
96+
})

0 commit comments

Comments
 (0)