implemented basic e2e testing

This commit is contained in:
kharhamel 2020-04-14 20:04:55 +02:00
parent 705617abe7
commit a2ed7164e4
11 changed files with 1540 additions and 0 deletions

20
docker-compose.ci.yml Normal file
View File

@ -0,0 +1,20 @@
version: '3.3'
services:
wait_app:
image: dadarek/wait-for-dependencies
depends_on:
- traefik
command: front:8080
cypress:
# the Docker image to use from https://github.com/cypress-io/cypress-docker-images
image: "cypress/included:3.2.0"
depends_on:
- traefik
environment:
# pass base url to test pointing at the web application
- CYPRESS_baseUrl=http://front:8080
working_dir: /e2e
volumes:
- ./e2e/:/e2e

View File

@ -7,6 +7,9 @@ services:
- "80:80" - "80:80"
# The Web UI (enabled by --api.insecure=true) # The Web UI (enabled by --api.insecure=true)
- "8080:8080" - "8080:8080"
depends_on:
- back
- front
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock

3
e2e/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
screenshots/
videos/
node_modules/

28
e2e/CYPRESS.md Normal file
View File

@ -0,0 +1,28 @@
# Testing with cypress
This project use [cypress](https://www.cypress.io/) to do functional testing of the website.
Unfortunately we cannot integrate it with docker-compose for the moment, so you will need to install some packages locally on your pc.
You will need to install theses dependancies on linux (don't know about mac):
```bash
sudo apt update
sudo apt install libgtk2.0-0 libgtk-3-0 libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
```
Cypress can be installed locally in the e2e directory
```bash
cd e2e
npm install
```
How to use:
```bash
npm run cy:run
npm run cy:open
```
The first command will run all tests in the terminal, while the second will open the interactive task runner which allow you to easily manage the test workflow
[More details here](https://docs.cypress.io/guides/getting-started/testing-your-app.html#Step-1-Start-your-server)

6
e2e/cypress.json Normal file
View File

@ -0,0 +1,6 @@
{
"baseUrl": "http://workadventure.localhost",
"video": false,
"pluginsFile": false,
"supportFile": false
}

View File

@ -0,0 +1,25 @@
Cypress.on('window:before:load', (win) => {
// because this is called before any scripts
// have loaded - the ga function is undefined
// so we need to create it.
win.cypressAsserter = cy.stub().as('ca')
})
describe('WorkAdventureGame', () => {
beforeEach(() => {
cy.visit('/', {
onBeforeLoad (win) {
cy.spy(win.console, 'log').as('console.log')
},
})
});
it('loads', () => {
cy.get('@console.log').should('be.calledWith', 'Started the game')
cy.get('@console.log').should('be.calledWith', 'Preloading')
cy.get('@console.log').should('be.calledWith', 'Preloading done')
cy.get('@console.log').should('be.calledWith', 'startInit')
cy.get('@console.log').should('be.calledWith', 'startInit done')
});
});

1406
e2e/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

9
e2e/package.json Normal file
View File

@ -0,0 +1,9 @@
{
"dependencies": {
"cypress": "^3.8.3"
},
"scripts": {
"cy:run": "cypress run",
"cy:open": "cypress open"
}
}

View File

@ -0,0 +1,32 @@
declare let window:any;
//this class is used to communicate with cypress, our e2e testing client
//Since cypress cannot manipulate canvas, we notified it with console logs
class CypressAsserter {
constructor() {
window.cypressAsserter = this
}
gameStarted() {
console.log('Started the game')
}
preloadStarted() {
console.log('Preloading')
}
preloadFinished() {
console.log('Preloading done')
}
initStarted() {
console.log('startInit')
}
initFinished() {
console.log('startInit done')
}
}
export const cypressAsserter = new CypressAsserter()

View File

@ -3,6 +3,7 @@ import {MessageUserPositionInterface} from "../../Connexion";
import {CurrentGamerInterface, GamerInterface, Player} from "../Player/Player"; import {CurrentGamerInterface, GamerInterface, Player} from "../Player/Player";
import {DEBUG_MODE, RESOLUTION, ZOOM_LEVEL} from "../../Enum/EnvironmentVariable"; import {DEBUG_MODE, RESOLUTION, ZOOM_LEVEL} from "../../Enum/EnvironmentVariable";
import Tile = Phaser.Tilemaps.Tile; import Tile = Phaser.Tilemaps.Tile;
import {cypressAsserter} from "../../Cypress/CypressAsserter";
export enum Textures { export enum Textures {
Rock = 'rock', Rock = 'rock',
@ -39,6 +40,7 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{
//hook preload scene //hook preload scene
preload(): void { preload(): void {
cypressAsserter.preloadStarted();
this.load.image(Textures.Tiles, 'maps/tiles.png'); this.load.image(Textures.Tiles, 'maps/tiles.png');
this.load.tilemapTiledJSON(Textures.Map, 'maps/map2.json'); this.load.tilemapTiledJSON(Textures.Map, 'maps/map2.json');
this.load.image(Textures.Rock, 'resources/objects/rockSprite.png'); this.load.image(Textures.Rock, 'resources/objects/rockSprite.png');
@ -46,6 +48,7 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{
'resources/characters/pipoya/Male 01-1.png', 'resources/characters/pipoya/Male 01-1.png',
{ frameWidth: 32, frameHeight: 32 } { frameWidth: 32, frameHeight: 32 }
); );
cypressAsserter.preloadFinished();
} }
//hook initialisation //hook initialisation
@ -53,6 +56,7 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{
//hook create scene //hook create scene
create(): void { create(): void {
cypressAsserter.initStarted();
//initalise map //initalise map
this.Map = this.add.tilemap("map"); this.Map = this.add.tilemap("map");
@ -83,6 +87,7 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{
//initialise camera //initialise camera
this.initCamera(); this.initCamera();
cypressAsserter.initFinished();
} }
//todo: in a dedicated class/function? //todo: in a dedicated class/function?

View File

@ -2,6 +2,7 @@ import 'phaser';
import GameConfig = Phaser.Types.Core.GameConfig; import GameConfig = Phaser.Types.Core.GameConfig;
import {GameManager} from "./Phaser/Game/GameManager"; import {GameManager} from "./Phaser/Game/GameManager";
import {DEBUG_MODE, RESOLUTION} from "./Enum/EnvironmentVariable"; import {DEBUG_MODE, RESOLUTION} from "./Enum/EnvironmentVariable";
import {cypressAsserter} from "./Cypress/CypressAsserter";
let gameManager = new GameManager(); let gameManager = new GameManager();
@ -20,6 +21,8 @@ const config: GameConfig = {
} }
}; };
cypressAsserter.gameStarted();
gameManager.createGame().then(() => { gameManager.createGame().then(() => {
let game = new Phaser.Game(config); let game = new Phaser.Game(config);