diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9694a53a1..dd95eb0d9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,6 +58,26 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }} EMPATHY_API_KEY: ${{ secrets.EMPATHY_API_KEY }} + + e2e-tests: + needs: [unit-tests] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - run: npm --prefix users/authservice install + - run: npm --prefix users/userservice install + - run: npm --prefix users/groupservice install + - run: npm --prefix llmservice install + - run: npm --prefix mathGame install + - run: npm --prefix apiservice install + - run: npm --prefix gatewayservice install + - run: npm --prefix webapp install + - run: npm --prefix wikidata install + - run: npm --prefix webapp run build + - run: npm --prefix webapp run test:e2e docker-push-webapp: name: Push webapp Docker Image to GitHub Packages @@ -65,7 +85,7 @@ jobs: permissions: contents: read packages: write - needs: [] + needs: [e2e-tests] if: github.event_name == 'push' steps: - uses: actions/checkout@v4 @@ -91,7 +111,7 @@ jobs: permissions: contents: read packages: write - needs: [] + needs: [e2e-tests] if: github.event_name == 'push' steps: - uses: actions/checkout@v4 @@ -114,7 +134,7 @@ jobs: permissions: contents: read packages: write - needs: [] + needs: [e2e-tests] if: github.event_name == 'push' steps: - uses: actions/checkout@v4 @@ -137,7 +157,7 @@ jobs: permissions: contents: read packages: write - needs: [] + needs: [e2e-tests] if: github.event_name == 'push' steps: - uses: actions/checkout@v4 @@ -160,7 +180,7 @@ jobs: permissions: contents: read packages: write - needs: [] + needs: [e2e-tests] if: github.event_name == 'push' steps: - uses: actions/checkout@v4 @@ -187,7 +207,7 @@ jobs: permissions: contents: read packages: write - needs: [] + needs: [e2e-tests] if: github.event_name == 'push' steps: - uses: actions/checkout@v4 @@ -210,7 +230,7 @@ jobs: permissions: contents: read packages: write - needs: [] + needs: [e2e-tests] if: github.event_name == 'push' steps: - uses: actions/checkout@v4 @@ -233,7 +253,7 @@ jobs: permissions: contents: read packages: write - needs: [] + needs: [e2e-tests] if: github.event_name == 'push' steps: - uses: actions/checkout@v4 @@ -256,7 +276,7 @@ jobs: permissions: contents: read packages: write - needs: [] + needs: [e2e-tests] if: github.event_name == 'push' steps: - uses: actions/checkout@v4 diff --git a/docker-compose.yml b/docker-compose.yml index 68311db60..65f6b82f5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,6 @@ services: - "27017:27017" networks: - mynetwork - mathgame: container_name: mathgame-wichat_es2a image: ghcr.io/arquisoft/wichat_es2a/mathgame:latest @@ -26,6 +25,7 @@ services: environment: DEPLOY_HOST: ${DEPLOY_HOST:-localhost} WEBAPP_PORT: ${WEBAPP_PORT:-3000} + MATHGAME_PORT: 3002 restart: always authservice: diff --git a/mathGame/app.js b/mathGame/app.js new file mode 100644 index 000000000..80abad9c4 --- /dev/null +++ b/mathGame/app.js @@ -0,0 +1,22 @@ +const express = require('express'); +const cors = require('cors'); +const mathGameRoutes = require('./mathGameRoutes'); + +// Crear la aplicación Express +const app = express(); + +// Middleware +app.use(cors()); +app.use(express.json()); +app.disable('x-powered-by'); // Para mayor seguridad + +// Usar las rutas del mathGame +app.use('/mathgame', mathGameRoutes); + +// Ruta de salud para verificar que el servicio esté funcionando +app.get('/health', (req, res) => { + res.status(200).json({ status: 'OK', message: 'MathGame service is running' }); +}); + +// Exportamos la aplicación Express +module.exports = app; diff --git a/mathGame/mathGameRoutes.js b/mathGame/mathGameRoutes.js index d9046fa65..1c4771222 100644 --- a/mathGame/mathGameRoutes.js +++ b/mathGame/mathGameRoutes.js @@ -1,9 +1,9 @@ const express = require('express'); -const app = express(); -app.disable('x-powered-by'); +const router = express.Router(); const service = require('./service/mathGameService'); -app.use(express.json()); +// Configuración básica +router.use(express.json()); @@ -23,7 +23,7 @@ app.use(express.json()); * correct: 90 * } */ -app.get('/mathgame/question', (req, res) => { +router.get('/question', (req, res) => { try { const raw = req.query.base; const base = raw != null && !Number.isNaN(parseInt(raw, 10)) @@ -55,7 +55,7 @@ app.get('/mathgame/question', (req, res) => { * isCorrect: boolean * } */ -app.post('/mathgame/verify', (req, res) => { +router.post('/verify', (req, res) => { try { const { choice, correct } = req.body; const isCorrect = Number(choice) === Number(correct); @@ -66,4 +66,4 @@ app.post('/mathgame/verify', (req, res) => { } }); -module.exports = app; +module.exports = router; diff --git a/mathGame/mathGameRoutes.test.js b/mathGame/mathGameRoutes.test.js index 03faa5f6f..295e003be 100644 --- a/mathGame/mathGameRoutes.test.js +++ b/mathGame/mathGameRoutes.test.js @@ -1,7 +1,11 @@ const request = require('supertest'); -const app = require('./mathGameRoutes'); -const service = require('./service/mathGameService'); const express = require('express'); +const router = require('./mathGameRoutes'); +const service = require('./service/mathGameService'); + +// Crear una aplicación Express para los tests +const app = express(); +app.use('/mathgame', router); jest.mock('./service/mathGameService'); diff --git a/mathGame/package-lock.json b/mathGame/package-lock.json index 09c5c3093..8ca708e95 100644 --- a/mathGame/package-lock.json +++ b/mathGame/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "cors": "^2.8.5", "express": "^5.1.0", "mathgame": "file:" }, @@ -1651,6 +1652,19 @@ "dev": true, "license": "MIT" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -3573,6 +3587,15 @@ "node": ">=8" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", diff --git a/mathGame/package.json b/mathGame/package.json index 5a77b8f40..46e31ebde 100644 --- a/mathGame/package.json +++ b/mathGame/package.json @@ -22,6 +22,7 @@ "supertest": "^7.0.0" }, "dependencies": { + "cors": "^2.8.5", "express": "^5.1.0", "mathgame": "file:" } diff --git a/webapp/e2e/jest.config.js b/webapp/e2e/jest.config.js index bf51e18cf..635ca93c4 100644 --- a/webapp/e2e/jest.config.js +++ b/webapp/e2e/jest.config.js @@ -1,5 +1,5 @@ module.exports = { testMatch: ["**/steps/*.js"], - testTimeout: 120000, + testTimeout: 1000000, setupFilesAfterEnv: ["expect-puppeteer"] } \ No newline at end of file diff --git a/webapp/e2e/steps/game-category.steps.js b/webapp/e2e/steps/game-category.steps.js index 01077750f..de3aa4b9f 100644 --- a/webapp/e2e/steps/game-category.steps.js +++ b/webapp/e2e/steps/game-category.steps.js @@ -1,5 +1,5 @@ const puppeteer = require('puppeteer'); -const { defineFeature, loadFeature }=require('jest-cucumber'); +const { defineFeature, loadFeature } = require('jest-cucumber'); const setDefaultOptions = require('expect-puppeteer').setDefaultOptions const feature = loadFeature('./features/game-category.feature'); @@ -7,11 +7,33 @@ let page; let browser; defineFeature(feature, test => { - + beforeAll(async () => { + // 1. Crear usuario de test si no existe + try { + await fetch(`http://localhost:8000/adduser`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + username: 'NataliaBB', + password: 'Contrasena$2', + confirmPassword: 'Contrasena$2', + avatarOptions: { + hair: "short", + eyes: "happy", + mouth: "smile", + hairColor: "brown", + skinColor: "light" + } + }) + }); + } catch (e) { + console.warn("⚠️ El usuario ya puede existir o hubo un error al crearlo:", e.message); + } + browser = process.env.GITHUB_ACTIONS - ? await puppeteer.launch({headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox']}) - : await puppeteer.launch({ headless: false, slowMo: 100 }); + ? await puppeteer.launch({ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'] }) + : await puppeteer.launch({ headless: false, slowMo: 10 }); page = await browser.newPage(); //Way of setting up the timeout setDefaultOptions({ timeout: 60000 }) @@ -20,69 +42,66 @@ defineFeature(feature, test => { .goto("http://localhost:3000", { waitUntil: "networkidle0", }) - .catch(() => {}); + .catch(() => { }); }); - test('User choose a category and start game', ({given,when,then}) => { - + test('User choose a category and start game', ({ given, when, then }) => { + let username; let password; let category; let dificulty; - given('Registered user login' , async () => { + given('Registered user login', async () => { // Definimos los datos de usuario y contraseña - username = "NataliaBA" - password = "Contrasena$1" + username = "NataliaBB"; + + password = "Contrasena$2"; // Definimos la categoría a seleccionar - category = "Lugares" + category = "Banderas" dificulty = "medio" // Introduces los datos de usuario y contraseña - await expect(page).toFill('[data-testid="username-field"] input', username); - await expect(page).toFill('[data-testid="password-field"] input', password); + await page.waitForSelector('[data-testid="username-field"] input', { visible: true, timeout: 60000 }); + await expect(page).toFill('[data-testid="username-field"] input', username, { timeout: 60000 }); - await expect(page).toClick("button", { text: "Login" }); + await page.waitForSelector('[data-testid="password-field"] input', { visible: true, timeout: 60000 }); + await expect(page).toFill('[data-testid="password-field"] input', password, { timeout: 60000 }); + + await page.waitForSelector('button', { visible: true, timeout: 60000 }); + await expect(page).toClick("button", { text: "Login", timeout: 60000 }); }); when('User choose category and press start button', async () => { - - // Abre el Select para escoger la categoría - await expect(page).toClick('[aria-labelledby="category-select-label"]'); - - // Escoge la categoría del menú desplegable - await page.click('li[data-value="'+category+'"]'); - - // Abre el Select para escoger la dificultad - await expect(page).toClick('[aria-labelledby="level-select-label"]'); + await page.waitForSelector('[data-testid="category-select"]', { visible: true, timeout: 60000 }); + await expect(page).toClick('[data-testid="category-select"]', { timeout: 60000 }); - // Escoge la dificultad "Medio" del menú desplegable - await page.click('li[data-value="'+dificulty+'"]'); + await page.waitForSelector(`[data-testid="category-option-${category}"`, { visible: true, timeout: 60000 }); + await page.click(`[data-testid="category-option-${category}"`, { timeout: 60000 }); - // Finalmente, hacer clic en el botón para comenzar el juego. - await expect(page).toClick('button', { text: 'Comenzar a jugar' }); + await page.waitForSelector('[data-testid="level-select"]', { visible: true, timeout: 500000 }); + await expect(page).toClick('[data-testid="level-select"]', { timeout: 500000 }); - + await page.waitForSelector(`[data-testid="level-option-${dificulty}"]`, { visible: true, timeout: 500000 }); + await page.click(`[data-testid="level-option-${dificulty}"]`, { timeout: 500000 }); + await page.waitForSelector('[data-testid="start-game-button"]', { visible: true, timeout: 500000 }); + await expect(page).toClick('[data-testid="start-game-button"]', { text: 'Comenzar a jugar', timeout: 500000 }); }); then('Game start in this category', async () => { - - // Espera a que el div que contiene el texto sea visible. - await page.waitForSelector('div', { text: '¿A qué lugar corresponde la siguiente foto?' }); - - // Verifica que el texto esté presente en el div. - // Se comprueba el texto de la pregunta que se muestra en el juego. - // Ya que cada categoría tiene su propia pregunta. - await expect(page).toMatchElement('div', { text: '¿A qué lugar corresponde la siguiente foto?' }); - + await page.waitForFunction( + () => document.body.innerText.includes('¿De qué país es esta bandera?'), + { timeout: 500000 } + ); + await expect(page).toMatchElement('div', { text: '¿De qué país es esta bandera?', timeout: 500000 }); }); }) - afterAll(async ()=>{ + afterAll(async () => { browser.close() }) diff --git a/webapp/e2e/steps/game-play.steps.js b/webapp/e2e/steps/game-play.steps.js index 7f2e1a492..26f945e37 100644 --- a/webapp/e2e/steps/game-play.steps.js +++ b/webapp/e2e/steps/game-play.steps.js @@ -9,9 +9,31 @@ let browser; defineFeature(feature, test => { beforeAll(async () => { + // 1. Crear usuario de test si no existe + try { + await fetch(`http://localhost:8000/adduser`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + username: 'NataliaBC', + password: 'Contrasena$3', + confirmPassword: 'Contrasena$3', + avatarOptions: { + hair: "short", + eyes: "happy", + mouth: "smile", + hairColor: "brown", + skinColor: "light" + } + }) + }); + } catch (e) { + console.warn("⚠️ El usuario ya puede existir o hubo un error al crearlo:", e.message); + } + browser = process.env.GITHUB_ACTIONS ? await puppeteer.launch({ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'] }) - : await puppeteer.launch({ headless: false, slowMo: 100 }); + : await puppeteer.launch({ headless: false, slowMo: 10 }); page = await browser.newPage(); //Way of setting up the timeout setDefaultOptions({ timeout: 60000 }) @@ -33,49 +55,53 @@ defineFeature(feature, test => { given('Registered user login', async () => { // Definimos los datos de usuario y contraseña - username = "NataliaBA" - password = "Contrasena$1" + username = "NataliaBC" + password = "Contrasena$3" // Definimos la categoría a seleccionar category = "Banderas" - dificulty = "facil" - + dificulty = "medio" + // Introduces los datos de usuario y contraseña - await expect(page).toFill('[data-testid="username-field"] input', username); - await expect(page).toFill('[data-testid="password-field"] input', password); + await page.waitForSelector('[data-testid="username-field"] input', { visible: true, timeout: 60000 }); + await expect(page).toFill('[data-testid="username-field"] input', username, { timeout: 60000 }); + await page.waitForSelector('[data-testid="password-field"] input', { visible: true, timeout: 60000 }); + await expect(page).toFill('[data-testid="password-field"] input', password, { timeout: 60000 }); - await expect(page).toClick("button", { text: "Login" }); + await page.waitForSelector("button", { visible: true, timeout: 60000 }); + await expect(page).toClick("button", { text: "Login", timeout: 60000 }); }); when('User choose category, press start button and play', async () => { - // Abre el Select para escoger la categoría (Futbolistas) - await expect(page).toClick('[aria-labelledby="category-select-label"]'); + await page.waitForSelector('[data-testid="category-select"]', { visible: true, timeout: 60000 }); + await expect(page).toClick('[data-testid="category-select"]', { timeout: 60000 }); - // Escoge la categoría "Futbolistas" del menú desplegable - await page.click('li[data-value="'+category+'"]'); + await page.waitForSelector(`[data-testid="category-option-${category}"`, { visible: true, timeout: 60000 }); + await page.click(`[data-testid="category-option-${category}"`, { timeout: 60000 }); - // Abre el Select para escoger la dificultad - await expect(page).toClick('[aria-labelledby="level-select-label"]'); + await page.waitForSelector('[data-testid="level-select"]', { visible: true, timeout: 500000 }); + await expect(page).toClick('[data-testid="level-select"]', { timeout: 500000 }); - // Escoge la dificultad "Medio" del menú desplegable - await page.click('li[data-value="'+dificulty+'"]'); + await page.waitForSelector(`[data-testid="level-option-${dificulty}"]`, { visible: true, timeout: 500000 }); + await page.click(`[data-testid="level-option-${dificulty}"]`, { timeout: 500000 }); - // Finalmente, hacer clic en el botón para comenzar el juego. - await expect(page).toClick('button', { text: 'Comenzar a jugar' }); + await page.waitForSelector('[data-testid="start-game-button"]', { visible: true, timeout: 500000 }); + await expect(page).toClick('[data-testid="start-game-button"]', { text: 'Comenzar a jugar', timeout: 500000 }); + // Realiza 10 respuestas durante el juego for (let i = 0; i < 10; i++) { // Esperamos que se cargue la imagen - await page.waitForSelector('img[alt="Imagen del juego"]', { visible: true }); + await page.waitForSelector('[data-testid="image-game"]', { visible: true, timeout: 500000 }); // Esperamos a que las opciones estén disponibles - await page.waitForSelector(`[data-testid^="respuesta-"]`, { visible: true }); + await page.waitForSelector(`[data-testid^="respuesta-"]`, { visible: true, timeout: 500000 }); // Seleccionamos todas las opciones disponibles const opciones = await page.$$(`[data-testid^="respuesta-"]`); if (opciones.length > 0) { // Hacer clic en la primera opción disponible - await opciones[0].click(); + await opciones[0].click({ timeout: 500000 }); } // Esperar un poco antes de continuar @@ -84,7 +110,7 @@ defineFeature(feature, test => { }); then('User sees the game summary', async () => { - await page.waitForSelector('h4', { text: 'Resumen del Juego', timeout: 10000 }); + await page.waitForSelector('[data-testid="resumenJuego"]', { text: 'Resumen del Juego', timeout: 500000 }); const resumenTexto = await page.$eval('h4', el => el.textContent); expect(resumenTexto).toContain('Resumen del Juego'); }); diff --git a/webapp/e2e/steps/history.steps.js b/webapp/e2e/steps/history.steps.js index 10ef81dd5..7752a60ea 100644 --- a/webapp/e2e/steps/history.steps.js +++ b/webapp/e2e/steps/history.steps.js @@ -1,5 +1,6 @@ const puppeteer = require('puppeteer'); const { defineFeature, loadFeature } = require('jest-cucumber'); +const { response } = require('../../../wikidata/src/wikidataRoutes'); const setDefaultOptions = require('expect-puppeteer').setDefaultOptions; const feature = loadFeature('./features/history.feature'); @@ -9,10 +10,74 @@ let browser; defineFeature(feature, test => { beforeAll(async () => { + let userId = null; + + // 1. Crear usuario de test si no existe + try { + const res = await fetch(`http://localhost:8000/adduser`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + username: 'NataliaBA', + password: 'Contrasena$1', + confirmPassword: 'Contrasena$1', + avatarOptions: { + hair: "short", + eyes: "happy", + mouth: "smile", + hairColor: "brown", + skinColor: "light" + } + }) + }); + + const user = await res.json(); + userId = user._id; // Guardar el ID del usuario creado + } catch (e) { + console.warn("⚠️ El usuario ya puede existir o hubo un error al crearlo:", e.message); + + // Si ya existe, recuperamos su ID con un GET (asumiendo que hay endpoint) + const res = await fetch(`http://localhost:8000/user/username/NataliaBA`); + const user = await res.json(); + userId = user._id; + } + + // 2. Insertar historial (partida de prueba) + if (userId) { + try { + await fetch(`http://localhost:3001/game/start`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ userId }) + }); + + await fetch(`http://localhost:3001/game/end`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + userId, + username: 'NataliaBA', + duration: 20, + correct: 9, + wrong: 1, + isCompleted: true, + category: 'Ciencia', + level: 'Difícil', + totalQuestions: 10, + answered: 10, + points: 90 + }) + }); + } catch (e) { + console.error("❌ Error al insertar partida de prueba:", e.message); + } + } + browser = process.env.GITHUB_ACTIONS ? await puppeteer.launch({ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'] }) - : await puppeteer.launch({ headless: false, slowMo: 100, defaultViewport: { width: 1920, height: 1080 } }); + : await puppeteer.launch({ headless: false, slowMo: 10, defaultViewport: { width: 1920, height: 1080 } }); page = await browser.newPage(); + await page.setViewport({ width: 1200, height: 800 }); setDefaultOptions({ timeout: 60000 }); await page @@ -28,20 +93,24 @@ defineFeature(feature, test => { let password; given('Registered user login', async () => { - username = "NataliaBA" - password = "Contrasena$1" + username = "NataliaBA"; + password = "Contrasena$1"; - await expect(page).toFill('[data-testid="username-field"] input', username); - await expect(page).toFill('[data-testid="password-field"] input', password); - await expect(page).toClick("button", { text: "Login" }); + await page.waitForSelector('[data-testid="username-field"] input', { visible: true, timeout: 60000 }); + await expect(page).toFill('[data-testid="username-field"] input', username, { timeout: 60000 }); + await page.waitForSelector('[data-testid="password-field"] input', { visible: true, timeout: 60000 }); + await expect(page).toFill('[data-testid="password-field"] input', password, { timeout: 60000 }); + await page.waitForSelector("button", { text: "Login", timeout: 60000 }); + await expect(page).toClick("button", { text: "Login", timeout: 60000 }); }); when('User navigates to the history page', async () => { - await expect(page).toClick('a', { text: 'Historial' }); + await page.waitForSelector('[data-testid="nav-history"]', { text: "Historial", timeout: 500000 }); + await expect(page).toClick('[data-testid="nav-history"]'); }); then('User sees a list of past games', async () => { - await page.waitForSelector('h4', { text: 'Historial de Partidas', timeout: 10000 }); + await page.waitForSelector('[data-testid="history-title"]', { text: 'Historial de Partidas', timeout: 500000 }); const historyHeader = await page.$eval('h4', el => el.textContent); expect(historyHeader).toContain('Historial de Partidas'); }); diff --git a/webapp/e2e/steps/login-form.steps.js b/webapp/e2e/steps/login-form.steps.js index 21d4100c5..4a70e7770 100644 --- a/webapp/e2e/steps/login-form.steps.js +++ b/webapp/e2e/steps/login-form.steps.js @@ -10,10 +10,32 @@ const webappIp = process.env.DEPLOY_HOST || 'localhost'; const webappPort = process.env.WEBAPP_PORT || '3000'; defineFeature(feature, test => { - + beforeAll(async () => { + // 1. Crear usuario de test si no existe + try { + await fetch(`http://localhost:8000/adduser`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + username: 'NataliaBA', + password: 'Contrasena$1', + confirmPassword: 'Contrasena$1', + avatarOptions: { + hair: "short", + eyes: "happy", + mouth: "smile", + hairColor: "brown", + skinColor: "light" + } + }) + }); + } catch (e) { + console.warn("⚠️ El usuario ya puede existir o hubo un error al crearlo:", e.message); + } + browser = process.env.GITHUB_ACTIONS - ? await puppeteer.launch({headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox']}) + ? await puppeteer.launch({ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'] }) : await puppeteer.launch({ headless: false, slowMo: 100 }); page = await browser.newPage(); setDefaultOptions({ timeout: 10000 }); @@ -22,26 +44,36 @@ defineFeature(feature, test => { .goto(`http://${webappIp}:${webappPort}`, { waitUntil: "networkidle0", }) - .catch(() => {}); + .catch(() => { }); }); - test('The user has an account and wants to log in', ({given, when, then}) => { - - username = "NataliaBA" - password = "Contrasena$1" + test('The user has an account and wants to log in', ({ given, when, then }) => { + + const username = "NataliaBA"; + const password = "Contrasena$1"; given('A registered user', async () => { - await expect(page).toMatchElement('h1', { text: "Log in to your account" }); + await page.waitForSelector('h1', { visible: true, timeout: 60000 }); + await expect(page).toMatchElement('h1', { text: "Log in to your account", timeout: 60000 }); }); when('I fill the login credentials and press submit', async () => { - await expect(page).toFill('[data-testid="username-field"] input', username); - await expect(page).toFill('[data-testid="password-field"] input', password); - await expect(page).toClick('button', { text: 'Login' }); + await page.waitForSelector('[data-testid="username-field"] input', { visible: true, timeout: 60000 }); + await expect(page).toFill('[data-testid="username-field"] input', username, { timeout: 60000 }); + + await page.waitForSelector('[data-testid="password-field"] input', { visible: true, timeout: 60000 }); + await expect(page).toFill('[data-testid="password-field"] input', password, { timeout: 60000 }); + + await page.waitForSelector('button', { visible: true, timeout: 60000 }); + await expect(page).toClick('button', { text: 'Login', timeout: 60000 }); }); then('I should be logged in successfully', async () => { - await expect(page).toMatchElement('h1', { text: "WICHAT" }); + await page.waitForFunction( + () => document.body.innerText.includes('WICHAT'), + { timeout: 60000 } + ); + await expect(page).toMatchElement('h1', { text: "WICHAT", timeout: 60000 }); }); }); diff --git a/webapp/e2e/steps/logout-session.steps.js b/webapp/e2e/steps/logout-session.steps.js index 437213c98..3d0b04e89 100644 --- a/webapp/e2e/steps/logout-session.steps.js +++ b/webapp/e2e/steps/logout-session.steps.js @@ -9,6 +9,28 @@ let browser; defineFeature(feature, test => { beforeAll(async () => { + // 1. Crear usuario de test si no existe + try { + await fetch(`http://localhost:8000/adduser`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + username: 'NataliaBA', + password: 'Contrasena$1', + confirmPassword: 'Contrasena$1', + avatarOptions: { + hair: "short", + eyes: "happy", + mouth: "smile", + hairColor: "brown", + skinColor: "light" + } + }) + }); + } catch (e) { + console.warn("⚠️ El usuario ya puede existir o hubo un error al crearlo:", e.message); + } + browser = process.env.GITHUB_ACTIONS ? await puppeteer.launch({ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'] }) : await puppeteer.launch({ headless: false, slowMo: 100 }); @@ -28,11 +50,16 @@ defineFeature(feature, test => { let password; given('User in home view', async () => { - username = "NataliaBA" - password = "Contrasena$1" - await expect(page).toFill('[data-testid="username-field"] input', username); - await expect(page).toFill('[data-testid="password-field"] input', password); - await expect(page).toClick("button", { text: "Login" }); + username = "NataliaBD" + password = "Contrasena$4" + await page.waitForSelector('[data-testid="username-field"] input', { visible: true, timeout: 60000 }); + await expect(page).toFill('[data-testid="username-field"] input', username, { timeout: 60000 }); + + await page.waitForSelector('[data-testid="password-field"] input', { visible: true, timeout: 60000 }); + await expect(page).toFill('[data-testid="password-field"] input', password, { timeout: 60000 }); + + await page.waitForSelector("button", { visible: true, timeout: 60000 }); + await expect(page).toClick("button", { text: "Login", timeout: 60000 }); }); @@ -40,16 +67,16 @@ defineFeature(feature, test => { // 1. Click en el botón de menú (usando tu XPath original) const [menuButton] = await page.$x('//*[@id="root"]/div/header/div/div/div[3]/button'); if (!menuButton) throw new Error('Botón de menú no encontrado'); - await menuButton.click(); - + await menuButton.click({ timeout: 60000 }); + // 2. Esperar y hacer clic en el
con el texto exacto
const [logoutItem] = await page.$x('//li[.//p[normalize-space()="Cerrar Sesión"]]');
if (!logoutItem) throw new Error('Opción de logout no encontrada');
- await logoutItem.click();
+ await logoutItem.click({ timeout: 60000 });
});
then('User logs out and sees the login view', async () => {
- await page.waitForSelector('h1', { text: 'Log in to your account', timeout: 10000 });
+ await page.waitForSelector('h1', { visible: true, text: 'Log in to your account', timeout: 60000 });
const titulo = await page.$eval('h1', el => el.textContent);
expect(titulo).toContain('Log in to your account');
});
diff --git a/webapp/e2e/steps/register-and-avatar.steps.js b/webapp/e2e/steps/register-and-avatar.steps.js
index 68ba6f545..418030811 100644
--- a/webapp/e2e/steps/register-and-avatar.steps.js
+++ b/webapp/e2e/steps/register-and-avatar.steps.js
@@ -1,5 +1,5 @@
const puppeteer = require('puppeteer');
-const { defineFeature, loadFeature }=require('jest-cucumber');
+const { defineFeature, loadFeature } = require('jest-cucumber');
const setDefaultOptions = require('expect-puppeteer').setDefaultOptions
const feature = loadFeature('./features/register-and-avatar.feature');
@@ -7,10 +7,10 @@ let page;
let browser;
defineFeature(feature, test => {
-
+
beforeAll(async () => {
browser = process.env.GITHUB_ACTIONS
- ? await puppeteer.launch({headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox']})
+ ? await puppeteer.launch({ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'] })
: await puppeteer.launch({ headless: false, slowMo: 100 });
page = await browser.newPage();
//Way of setting up the timeout
@@ -20,51 +20,70 @@ defineFeature(feature, test => {
.goto("http://localhost:3000", {
waitUntil: "networkidle0",
})
- .catch(() => {});
+ .catch(() => { });
});
- test('User is not registered in the site', ({given,when,then}) => {
-
+ test('User is not registered in the site', ({ given, when, then }) => {
+
let username;
let password;
given('An unregistered user', async () => {
- username = "prueba" + Math.floor(Math.random() * 1000);
+ username = "prueba1" + Math.floor(Math.random() * 1000);
password = "EstoEsUnaPassDePrueba123."
- await expect(page).toClick("a", { text: "Sign up" });
-
+ await page.waitForSelector("a", { text: "Sing up", timeout: 60000 });
+ await expect(page).toClick("a", { text: "Sign up", timeout: 60000 });
+
});
when('I fill in the data in the form, edit my avatar, and press send.', async () => {
- await expect(page).toFill('input[name="username"]', username);
- await expect(page).toFill('input[name="password"]', password);
- await expect(page).toFill('input[name="confirmPassword"]', password);
+ await page.waitForSelector('input[name="username"]', { visible: true, timeout: 60000 });
+ await expect(page).toFill('input[name="username"]', username, { timeout: 60000 });
+
+ await page.waitForSelector('input[name="password"]', { visible: true, timeout: 60000 });
+ await expect(page).toFill('input[name="password"]', password, { timeout: 60000 });
+
+ await page.waitForSelector('input[name="confirmPassword"]', { visible: true, timeout: 60000 });
+ await expect(page).toFill('input[name="confirmPassword"]', password, { timeout: 60000 });
// Piel
- await expect(page).toClick('button[aria-label="skin"]');
- await expect(page).toClick('button', { text: 'Bronze' });
+ await page.waitForSelector('button[aria-label="skin"]', { visible: true, timeout: 60000 });
+ await expect(page).toClick('button[aria-label="skin"]', { timeout: 60000 });
+ await page.waitForSelector('button', { visible: true, timeout: 60000 });
+ await expect(page).toClick('button', { text: 'Bronze', timeout: 60000 });
// Pelo
- await expect(page).toClick('button[aria-label="hair"]');
- await expect(page).toClick('button', { text: 'Blonde' });
- await expect(page).toClick('button', { text: 'curlyShortHair' });
+ await page.waitForSelector('button[aria-label="hair"]', { visible: true, timeout: 60000 });
+ await expect(page).toClick('button[aria-label="hair"]', { timeout: 60000 });
+ await page.waitForSelector('button', { visible: true, timeout: 60000 });
+ await expect(page).toClick('button', { text: 'Blonde', timeout: 60000 });
+ await page.waitForSelector('button', { visible: true, timeout: 60000 });
+ await expect(page).toClick('button', { text: 'curlyShortHair', timeout: 60000 });
// Ojos
- await expect(page).toClick('button[aria-label="eyes"]');
- await expect(page).toClick('button', { text: 'starstruck' });
+ await page.waitForSelector('button[aria-label="eyes"]', { visible: true, timeout: 60000 });
+ await expect(page).toClick('button[aria-label="eyes"]', { timeout: 60000 });
+ await page.waitForSelector('button', { visible: true, timeout: 60000 });
+ await expect(page).toClick('button', { text: 'starstruck', timeout: 60000 });
// Boca
- await expect(page).toClick('button[aria-label="mouth"]');
- await expect(page).toClick('button', { text: 'unimpressed' });
- await expect(page).toClick('button', { text: 'Sign up' })
+ await page.waitForSelector('button[aria-label="mouth"]', { visible: true, timeout: 60000 });
+ await expect(page).toClick('button[aria-label="mouth"]', { timeout: 60000 });
+ await page.waitForSelector('button', { visible: true, timeout: 60000 });
+ await expect(page).toClick('button', { text: 'unimpressed', timeout: 60000 });
+
+ // Enviar el formulario
+ await page.waitForSelector('button', { visible: true, timeout: 60000 });
+ await expect(page).toClick('button', { text: 'Sign up', timeout: 60000 });
});
then('The user should be redirected to the Login page', async () => {
- await expect(page).toMatchElement("h1", { text: "Log in to your account" });
+ await page.waitForSelector("h1", { visible: true, timeout: 60000 });
+ await expect(page).toMatchElement("h1", { text: "Log in to your account", timeout: 60000 });
});
})
- afterAll(async ()=>{
+ afterAll(async () => {
browser.close()
})
diff --git a/webapp/e2e/steps/register-form.steps.js b/webapp/e2e/steps/register-form.steps.js
index 1b79570a5..ab939d641 100644
--- a/webapp/e2e/steps/register-form.steps.js
+++ b/webapp/e2e/steps/register-form.steps.js
@@ -1,5 +1,5 @@
const puppeteer = require('puppeteer');
-const { defineFeature, loadFeature }=require('jest-cucumber');
+const { defineFeature, loadFeature } = require('jest-cucumber');
const setDefaultOptions = require('expect-puppeteer').setDefaultOptions
const feature = loadFeature('./features/register-form.feature');
@@ -7,48 +7,56 @@ let page;
let browser;
defineFeature(feature, test => {
-
+
beforeAll(async () => {
browser = process.env.GITHUB_ACTIONS
- ? await puppeteer.launch({headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox']})
+ ? await puppeteer.launch({ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'] })
: await puppeteer.launch({ headless: false, slowMo: 100 });
page = await browser.newPage();
//Way of setting up the timeout
- setDefaultOptions({ timeout: 10000 })
+ setDefaultOptions({ timeout: 60000 })
await page
.goto("http://localhost:3000", {
waitUntil: "networkidle0",
})
- .catch(() => {});
+ .catch(() => { });
});
- test('The user is not registered in the site', ({given,when,then}) => {
-
+ test('The user is not registered in the site', ({ given, when, then }) => {
+
let username;
let password;
given('An unregistered user', async () => {
- username = "prueba" + Math.floor(Math.random() * 1000);
- password = "EstoEsUnaPassDePrueba123."
- await expect(page).toClick("a", { text: "Sign up" });
-
+ username = "prueba2" + Math.floor(Math.random() * 1000);
+ password = "EstoEsUnaPassDePrueba123-"
+ await page.waitForSelector("a", { text: "Sign up", timeout: 60000 });
+ await expect(page).toClick("a", { text: "Sign up", timeout: 60000 });
+
});
when('I fill the data in the form and press submit', async () => {
- await expect(page).toFill('input[name="username"]', username);
- await expect(page).toFill('input[name="password"]', password);
- await expect(page).toFill('input[name="confirmPassword"]', password);
+ await page.waitForSelector('input[name="username"]', { visible: true, timeout: 60000 });
+ await expect(page).toFill('input[name="username"]', username, { timeout: 60000 });
+
+ await page.waitForSelector('input[name="password"]', { visible: true, timeout: 60000 });
+ await expect(page).toFill('input[name="password"]', password, { timeout: 60000 });
+
+ await page.waitForSelector('input[name="confirmPassword"]', { visible: true, timeout: 60000 });
+ await expect(page).toFill('input[name="confirmPassword"]', password, { timeout: 60000 });
- await expect(page).toClick('button', { text: 'Sign up' })
+ await page.waitForSelector('button', { visible: true, timeout: 60000 });
+ await expect(page).toClick('button', { text: 'Sign up', timeout: 60000 });
});
then('The user should be redirected to the Login page', async () => {
- await expect(page).toMatchElement("h1", { text: "Log in to your account" });
+ await page.waitForSelector("h1", { visible: true, timeout: 60000 });
+ await expect(page).toMatchElement("h1", { text: "Log in to your account", timeout: 60000 });
});
})
- afterAll(async ()=>{
+ afterAll(async () => {
browser.close()
})
diff --git a/webapp/e2e/test-environment-setup.js b/webapp/e2e/test-environment-setup.js
index de2db6c24..96497ca3a 100644
--- a/webapp/e2e/test-environment-setup.js
+++ b/webapp/e2e/test-environment-setup.js
@@ -17,7 +17,12 @@ async function startServer() {
authservice = await require("../../users/authservice/auth-service");
llmservice = await require("../../llmservice/llm-service");
gatewayservice = await require("../../gatewayservice/gateway-service");
- wikidataservice = await require("../../wikidata/src/wikidataRoutes");
+ const wikidataApp = require("../../wikidata/src/wikidataRoutes");
+ const wikidataServer = wikidataApp.listen(3001, () => {
+ console.log("📚 Wikidata Service listening at http://localhost:3001");
+ });
+ process.env.WIKIDATA_PORT = 3001;
+
groupservice = await require("../../users/groupservice/group-service");
}
diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index ce2a7dde2..af1963f67 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -74,14 +74,14 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.26.2",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
- "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.27.1",
"js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
+ "picocolors": "^1.1.1"
},
"engines": {
"node": ">=6.9.0"
@@ -369,18 +369,18 @@
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
- "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
- "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -410,25 +410,25 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz",
- "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz",
+ "integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==",
"license": "MIT",
"dependencies": {
- "@babel/template": "^7.25.9",
- "@babel/types": "^7.26.0"
+ "@babel/template": "^7.27.1",
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.26.3",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz",
- "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==",
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz",
+ "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.26.3"
+ "@babel/types": "^7.27.1"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -1993,26 +1993,23 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
- "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz",
+ "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==",
"license": "MIT",
- "dependencies": {
- "regenerator-runtime": "^0.14.0"
- },
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/template": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
- "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.25.9",
- "@babel/parser": "^7.25.9",
- "@babel/types": "^7.25.9"
+ "@babel/code-frame": "^7.27.1",
+ "@babel/parser": "^7.27.2",
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2037,13 +2034,13 @@
}
},
"node_modules/@babel/types": {
- "version": "7.26.3",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz",
- "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz",
+ "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==",
"license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.25.9",
- "@babel/helper-validator-identifier": "^7.25.9"
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -5850,9 +5847,9 @@
}
},
"node_modules/axios": {
- "version": "1.7.9",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
- "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
+ "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
@@ -11230,9 +11227,9 @@
}
},
"node_modules/http-proxy-middleware": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
- "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==",
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz",
+ "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==",
"license": "MIT",
"dependencies": {
"@types/http-proxy": "^1.17.8",
@@ -21263,12 +21260,6 @@
"node": ">=4"
}
},
- "node_modules/regenerator-runtime": {
- "version": "0.14.1",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
- "license": "MIT"
- },
"node_modules/regenerator-transform": {
"version": "0.15.2",
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
diff --git a/webapp/src/components/AddUser.js b/webapp/src/components/AddUser.js
index f6f93f5bd..b01316db4 100644
--- a/webapp/src/components/AddUser.js
+++ b/webapp/src/components/AddUser.js
@@ -1,5 +1,5 @@
// src/components/AddUser.js
-import React, { useState, useEffect } from 'react';
+import React, { useState } from 'react';
import axios from 'axios';
import {
Container, Grid, Typography, TextField,
@@ -25,7 +25,6 @@ const AddUser = () => {
const [showPassword, setShowPassword] = useState(false); // mostrar contraseña
const [showConfirmPassword, setShowConfirmPassword] = useState(false); // mostrar confirmar contraseña
// Para el avatar
- const [avatarUrl, setAvatarUrl] = useState('');
const [avatarOptions, setAvatarOptions] = useState({
hairColor: '3a1a00',
eyes: 'cheery',
@@ -36,13 +35,6 @@ const AddUser = () => {
const navigate = useNavigate();
- // Según vayamos cambiando el avatar, se va mostrando
- useEffect(() => {
- const { hairColor, eyes, hair, mouth, skinColor } = avatarOptions;
- const newAvatarUrl = `https://api.dicebear.com/9.x/big-smile/svg?hairColor=${hairColor}&eyes=${eyes}&hair=${hair}&mouth=${mouth}&skinColor=${skinColor}`;
- setAvatarUrl(newAvatarUrl);
- }, [avatarOptions]);
-
const addUser = async () => {
try {
await axios.post(`${apiEndpoint}/adduser`, {
diff --git a/webapp/src/components/Contact.jsx b/webapp/src/components/Contact.jsx
index 4d0377bf2..f603a82b3 100644
--- a/webapp/src/components/Contact.jsx
+++ b/webapp/src/components/Contact.jsx
@@ -11,7 +11,7 @@ const teamMembers = [
{ name: 'Marcos Llanos Vega', role: 'Desarrollador Frontend', email: 'UO218982@uniovi.com', github: 'https://github.com/softwaremarcos', avatar: imageM },
{ name: 'David Covián Gómez', role: 'Desarrollador Backend', email: 'UO295168@uniovi.com', github: 'https://github.com/DavidCG-27', avatar: imageM },
{ name: 'Darío Cristóbal González', role: 'Diseñador Backend', email: 'UO294401@uniovi.com', github: 'https://github.com/daariio92', avatar: imageM },
- { name: 'Hugo Fernández Rogríguez', role: 'Diseñador LLM y despliegue', email: 'UO289157@uniovi.com', github: 'https://github.com/hugo-fdez', avatar: imageM },
+ { name: 'Hugo Fernández Rodríguez', role: 'Diseñador LLM y despliegue', email: 'UO289157@uniovi.com', github: 'https://github.com/hugo-fdez', avatar: imageM },
{ name: 'Hugo Prendes Menéndez', role: 'Diseñador LLM', email: 'UO288294@uniovi.com', github: 'https://github.com/prendess', avatar: imageM },
];
@@ -59,7 +59,7 @@ const Contact = () => {
}}>
{/* Avatar con borde redondeado */}
{
'David Covián Gómez',
'Marcos Llanos Vega',
'Darío Cristóbal González',
- 'Hugo Fernández Rogríguez',
+ 'Hugo Fernández Rodríguez',
'Hugo Prendes Menéndez'
];
const roles = [
diff --git a/webapp/src/components/FriendList.jsx b/webapp/src/components/FriendList.jsx
index afc7a264c..bd3b69251 100644
--- a/webapp/src/components/FriendList.jsx
+++ b/webapp/src/components/FriendList.jsx
@@ -1,5 +1,4 @@
import React, { useEffect, useState } from 'react';
-import profilePic from '../media/fotousuario.png';
import { Box, Typography, List, ListItem, ListItemAvatar, Avatar, ListItemText, IconButton, Dialog, DialogActions, DialogContent, DialogTitle, Button } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import axios from 'axios';
@@ -10,8 +9,6 @@ import HistoryIcon from '@mui/icons-material/History';
const apiEndpoint = process.env.REACT_APP_GATEWAY_URL || 'http://localhost:8000';
-const apiEndpoint2 = process.env.USER_SERVICE_ENDPOINT || 'http://localhost:8001';
-
// Función para construir la URL del avatar de DiceBear desde avatarOptions
const getAvatarUrl = (options) => {
if (!options) return '';
diff --git a/webapp/src/components/GameHistoryTable.jsx b/webapp/src/components/GameHistoryTable.jsx
index ed43d2e7f..64affa3fe 100644
--- a/webapp/src/components/GameHistoryTable.jsx
+++ b/webapp/src/components/GameHistoryTable.jsx
@@ -22,7 +22,7 @@ const GameHistoryTable = ({ gameHistory = [], theme }) => {
const usedTheme = theme || defaultTheme;
return (
diff --git a/webapp/src/components/GameHistoryUI.jsx b/webapp/src/components/GameHistoryUI.jsx
index c77561dea..f2756a453 100644
--- a/webapp/src/components/GameHistoryUI.jsx
+++ b/webapp/src/components/GameHistoryUI.jsx
@@ -70,7 +70,7 @@ const GameHistoryUI = () => {
if (!Array.isArray(gameHistory) || gameHistory.length === 0) {
return (