Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Toto-hitori committed May 5, 2024
2 parents 3ff080c + 546e6e5 commit 65d8612
Show file tree
Hide file tree
Showing 36 changed files with 444 additions and 104 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: End 2 End Tests

on:
push:
branches:
- test/e2e

jobs:
e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: sudo apt install -y openssl
- run: openssl req -newkey rsa:2048 -nodes -keyout server.key -out server.csr -subj "/CN=localhost"
- run: openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
- run: openssl pkcs12 -export -out server.p12 -inkey server.key -in server.crt -passout pass:${{ secrets.E2E_SSL_PASSWORD }} -name tomcat
- run: sudo mkdir /certs
- run: sudo mv server.p12 /certs/keystore.p12
- name: Set up environment variables
run: |
echo "DATABASE_USER=${{ secrets.DATABASE_USER }}" >> .env
echo "DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}" >> .env
echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> .env
echo "REACT_APP_API_ENDPOINT=https://localhost:8443" >> ./webapp/.env
echo "SSL_PASSWORD=${{ secrets.E2E_SSL_PASSWORD }}" >> .env
- run: mv .env ./webapp/e2e/.env
- run: ls ./webapp -la
- run: cat ./webapp/.env
- run: docker compose -f ./webapp/e2e/docker-compose.yml up -d
- run: npm --prefix webapp install
- run: docker ps -a
- run: docker logs api-defaultASW
- run: npm --prefix webapp run build
- run: npm --prefix webapp run test:e2eci
25 changes: 25 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,31 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: sudo apt install -y openssl
- run: openssl req -newkey rsa:2048 -nodes -keyout server.key -out server.csr -subj "/CN=localhost"
- run: openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
- run: openssl pkcs12 -export -out server.p12 -inkey server.key -in server.crt -passout pass:${{ secrets.E2E_SSL_PASSWORD }} -name tomcat
- run: sudo mkdir /certs
- run: sudo mv server.p12 /certs/keystore.p12
- name: Set up environment variables
run: |
echo "DATABASE_USER=${{ secrets.DATABASE_USER }}" >> .env
echo "DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}" >> .env
echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> .env
echo "REACT_APP_API_ENDPOINT=https://localhost:8443" >> ./webapp/.env
echo "SSL_PASSWORD=${{ secrets.E2E_SSL_PASSWORD }}" >> .env
- run: mv .env ./webapp/e2e/.env
- run: docker compose -f ./webapp/e2e/docker-compose.yml up -d
- run: npm --prefix webapp install
- run: npm --prefix webapp run build
- run: npm --prefix webapp run test:e2eci
docker-push-api:
runs-on: ubuntu-latest
needs: [ unit-tests ]
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# 🧠🤔 KiWiq 🥝❓📚


[![Deploy on release](https://github.com/Arquisoft/wiq_en2b/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_en2b/actions/workflows/release.yml)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_en2b&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_en2b)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_en2b&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_en2b)

Visit our page [here!!!](http://kiwiq.run.place/).

![](https://github.com/Arquisoft/wiq_en2b/blob/readme/add_qr_code/docs/images/KiWiQ_QR_code_small_300x300.png)
Expand Down Expand Up @@ -33,10 +39,6 @@ Gonzalo Suárez Losada | <a href="https://github.com/uo283928"><img src="https:/
***


[![Deploy on release](https://github.com/Arquisoft/wiq_en2b/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_en2b/actions/workflows/release.yml)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_en2b&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_en2b)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_en2b&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_en2b)

This is a repository for the [Software Architecture course](http://arquisoft.github.io/) in [2023/2024 edition](https://arquisoft.github.io/course2324.html).

This repo is a basic application composed of several components.
Expand Down
10 changes: 5 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
volumes:
- postgres_data:/var/lib/postgresql/data
image: postgres:latest
profiles: ["dev", "prod"]
profiles: ["dev", "prod","e2e"]
networks:
mynetwork:

api:
container_name: api-${teamname:-defaultASW}
image: ghcr.io/arquisoft/wiq_en2b/api:latest
profiles: ["dev", "prod"]
profiles: ["dev", "prod","e2e"]
build:
context: ./api
args:
Expand All @@ -42,7 +42,7 @@
question-generator:
container_name: question-generator-${teamname:-defaultASW}
image: ghcr.io/arquisoft/wiq_en2b/question-generator:latest
profiles: ["dev", "prod"]
profiles: ["dev", "prod","e2e"]
build:
context: ./questiongenerator
args:
Expand All @@ -60,7 +60,7 @@
kiwiq:
image: ghcr.io/arquisoft/wiq_en2b/kiwiq:latest
container_name: kiwiq
profiles: ["dev", "prod"]
profiles: ["dev", "prod","e2e"]
networks:
mynetwork:
links:
Expand All @@ -77,7 +77,7 @@
webapp:
container_name: webapp-${teamname:-defaultASW}
image: ghcr.io/arquisoft/wiq_en2b/webapp:latest
profiles: [ "dev", "prod" ]
profiles: [ "dev", "prod","e2e" ]
build:
args:
REACT_APP_API_ENDPOINT: ${API_URI}
Expand Down
62 changes: 62 additions & 0 deletions webapp/e2e/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
version: '3'
services:
WIQ_DB:
container_name: postgresql-${teamname:-defaultASW}
environment:
POSTGRES_USER: ${DATABASE_USER}
POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
image: postgres:latest
networks:
mynetwork:

api:
container_name: api-${teamname:-defaultASW}
build:
context: ../../api
args:
DATABASE_USER: ${DATABASE_USER}
DATABASE_PASSWORD: ${DATABASE_PASSWORD}
JWT_SECRET: ${JWT_SECRET}
SSL_PASSWORD: ${SSL_PASSWORD}
dockerfile: Dockerfile
environment:
- DATABASE_URL=jdbc:postgresql://WIQ_DB:5432/wiq
- DATABASE_USER=${DATABASE_USER}
- DATABASE_PASSWORD=${DATABASE_PASSWORD}
- JWT_SECRET=${JWT_SECRET}
- SSL_PASSWORD=${SSL_PASSWORD}
ports:
- 8443:8443
networks:
mynetwork:
volumes:
- /certs:/etc/letsencrypt/live/kiwiq.run.place:ro
depends_on:
- WIQ_DB

question-generator:
container_name: question-generator-${teamname:-defaultASW}
build:
context: ../../questiongenerator
args:
DATABASE_USER: ${DATABASE_USER}
DATABASE_PASSWORD: ${DATABASE_PASSWORD}
dockerfile: Dockerfile
environment:
- DATABASE_URL=jdbc:postgresql://WIQ_DB:5432/wiq
- DATABASE_USER=${DATABASE_USER}
- DATABASE_PASSWORD=${DATABASE_PASSWORD}
networks:
mynetwork:
depends_on:
- WIQ_DB

volumes:
postgres_data:
certs:

networks:
mynetwork:
driver: bridge
29 changes: 29 additions & 0 deletions webapp/e2e/e2e_utils/e2e_utils_login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Note: e2e Testing purposes only!
* Auxiliar function for login an user using its credentials from the root directory of the website.
* It also ensures the task has been performed successfully.
*
* @param username The username for the user. Currently we are using codes for each test case.
* @param email The email for the user. If none is defined, the username (a code) + '@gmail.com' is used
* @param password The password for the user. If none is defined, the username (a code) + '.ps' is used
* Beware of constraits for the user password.
* @param page The website
*/
async function loginUserFromRootDirectory(username, email = username + "@gmail.com", password = username + ".ps", page) {

// login process
await expect(page).toClick("button[data-testid='Login'");
await expect(page).toFill("#user", email);
await expect(page).toFill("#password", password);
await expect(page).toClick("button[data-testid='Login'");

// Checking for the process to be correct
await new Promise(resolve => setTimeout(resolve, 6000)); // Waiting for page to fully load
let header = await page.$eval("h2", (element) => {
return element.innerHTML
})
let value = header === "Bienvenid@ " + username || header === "Welcome " + username;
expect(value).toBeTruthy();

}
modules.export ={loginUserFromRootDirectory};
25 changes: 25 additions & 0 deletions webapp/e2e/e2e_utils/e2e_utils_logout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const {waitForPageToLoad} = require('../e2e_utils/e2e_utils_timeout.js');

/**
* Note: e2e Testing purposes only!
* Auxiliar function for logging out an user from any directory of the user.
* Beware if the user is playing a game when logging out
* It also ensures the task has been performed successfully.
*
* @param {*} page The website
*/
async function logOutUser(page) {
// Logging out
await expect(page).toClick("#lateralMenuButton");
await expect(page).toClick("button[data-testid='LogOut']");

// Checking for the log out to be sucessful
waitForPageToLoad();
let header = await page.$eval("button[data-testid='Login']", (element) => {
return element.innerHTML
})
let value = header === "Login" || "Iniciar sesión";

expect(value).toBeTruthy();
}
modules.export = {logOutUser}
34 changes: 34 additions & 0 deletions webapp/e2e/e2e_utils/e2e_utils_register.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Note: e2e Testing purposes only!
* Auxiliar function for registering a new user from the root directory of the website.
* It also ensures the task has been performed successfully.
*
* @param {*} username The username for the new user. Currently we are using codes for each test case.
* @param {*} page The website
* @returns An array with the credentials of the user created [email, username]
*/
async function registerUserFromRootDirectory(username, page) {
// Credentials for the new user
let email = username + "@email.com"
let password = username + "ps"

// Registeing process
await expect(page).toClick("span[class='chakra-link css-1bicqx'");
await expect(page).toFill("input[id='user'", email);
await expect(page).toFill("input[id='username'", username);
await expect(page).toFill("#password", password);
await expect(page).toFill("input[id='field-:r5:']", password);
await expect(page).toClick("button[data-testid='Sign up'");

// Checking for the process to be correct
await new Promise(resolve => setTimeout(resolve, 6000)); // Waiting for page to fully load
let header = await page.$eval("h2", (element) => {
return element.innerHTML
})
let value = header === "Bienvenid@ " + username || header === "Welcome " + username;
expect(value).toBeTruthy();

return [email, password];
}

modules.export ={registerUserFromRootDirectory};
11 changes: 11 additions & 0 deletions webapp/e2e/e2e_utils/e2e_utils_timeout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Note: e2e Testing purposes only!
* Auxiliar function that times out the tests for some time, so the page can be fully loaded.
* @param {*} timeout_ms Amount of ms to wait.
*/
async function waitForPageToLoad(timeout_ms = 6000) {
await new Promise(resolve => setTimeout(resolve, timeout_ms));

}

modules.export = {waitForPageToLoad}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Feature: Starting an entire game

Scenario: A non-logged user wants to play an entire game (Kiwi Quest gamemode)
Given A non-logged user in the main menu
Scenario: A logged user wants to play an entire game (Kiwi Quest gamemode)
Given A logged user in the main menu
When Clicking the button to start a new game (Kiwi Quest gamemode)

And Waiting for the question to load
Expand Down
2 changes: 1 addition & 1 deletion webapp/e2e/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
testMatch: ["**/steps/*.js"],
testMatch: ["**/playing_full_game_pos*.steps.js","**/about.steps.js", "**/login_positive.steps.js"],
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
testTimeout: 30000
}
41 changes: 29 additions & 12 deletions webapp/e2e/steps/about.steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ defineFeature(feature, test => {

beforeAll(async () => {
browser = process.env.GITHUB_ACTIONS
? await puppeteer.launch()
: await puppeteer.launch({ headless: false, slowMo: 100 });
? await puppeteer.launch({ ignoreHTTPSErrors: true})
: await puppeteer.launch({ headless: false, slowMo: 100, ignoreHTTPSErrors: true });
page = await browser.newPage();
//Way of setting up the timeout
setDefaultOptions({ timeout: 10000 })
Expand All @@ -24,17 +24,10 @@ defineFeature(feature, test => {

test("A logged user wants to see the about screen of the webpage", ({given,when,and,then}) => {

let username;
let password;
let username = "t.about";

given("A logged user in the main menu", async () => {
username = "test@email.com"
password = "password"

await expect(page).toClick("button[data-testid='Login'");
await expect(page).toFill("#user", username);
await expect(page).toFill("#password", password);
await expect(page).toClick("button[data-testid='Login'");
await registerUserFromRootDirectory(username,page)
});

when("The user presses the button for deploying the lateral menu", async () => {
Expand All @@ -57,4 +50,28 @@ defineFeature(feature, test => {
afterAll((done) => {
done();
});
});
});

async function registerUserFromRootDirectory(username, page) {
// Credentials for the new user
let email = username + "@email.com"
let password = username + "psw"

// Registering process
await expect(page).toClick("span[class='chakra-link css-1bicqx'");
await expect(page).toFill("input[id='user'", email);
await expect(page).toFill("input[id='username'", username);
await expect(page).toFill("#password", password);
await expect(page).toFill("input[id='field-:r5:']", password);
await expect(page).toClick("button[data-testid='Sign up'");

// Checking for the process to be correct
await new Promise(resolve => setTimeout(resolve, 5000)); // Waiting for page to fully load
let header = await page.$eval("h2", (element) => {
return element.innerHTML
})
let value = header === "Bienvenid@ " + username || header === "Welcome " + username;
expect(value).toBeTruthy();

return [email, password];
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ defineFeature(feature, test => {

afterAll((done) => {
done();
browser.close();
});
});
Loading

0 comments on commit 65d8612

Please sign in to comment.