diff --git a/client/src/config/globals.js b/client/src/config/globals.js index 3d502bd..53e9894 100644 --- a/client/src/config/globals.js +++ b/client/src/config/globals.js @@ -54,7 +54,8 @@ export const globals = { UPDATE_SPECTATORS: 'updateSpectators', RESTART_GAME: 'restartGame', ASSIGN_DEDICATED_MOD: 'assignDedicatedMod', - KICK_PERSON: 'kickPerson' + KICK_PERSON: 'kickPerson', + UPDATE_GAME_ROLES: 'updateGameRoles' }, TIMER_EVENTS: function () { return [ @@ -68,7 +69,8 @@ export const globals = { return [ this.EVENT_IDS.PLAYER_JOINED, this.EVENT_IDS.ADD_SPECTATOR, - this.EVENT_IDS.KICK_PERSON + this.EVENT_IDS.KICK_PERSON, + this.EVENT_IDS.UPDATE_GAME_ROLES ]; }, IN_PROGRESS_EVENTS: function () { diff --git a/client/src/images/save-svgrepo-com.svg b/client/src/images/save-svgrepo-com.svg new file mode 100644 index 0000000..964878e --- /dev/null +++ b/client/src/images/save-svgrepo-com.svg @@ -0,0 +1,4 @@ + + + + diff --git a/client/src/modules/front_end_components/HTMLFragments.js b/client/src/modules/front_end_components/HTMLFragments.js index 83d89aa..812e08a 100644 --- a/client/src/modules/front_end_components/HTMLFragments.js +++ b/client/src/modules/front_end_components/HTMLFragments.js @@ -45,10 +45,8 @@ export const HTMLFragments = { `, START_GAME_PROMPT: - `
- -

All players must join to start.

-
`, + ` + `, GAME_CONTROL_PROMPT: `
@@ -361,21 +359,21 @@ export const HTMLFragments = {
- add one - info - edit - remove + add one + info + edit + remove
`, DECK_SELECT_ROLE_DEFAULT: `
- add one - info + add one + info
`, DECK_SELECT_ROLE_ADDED_TO_DECK: `
- remove one - info + remove one + info
` }; diff --git a/client/src/modules/game_creation/GameCreationStepManager.js b/client/src/modules/game_creation/GameCreationStepManager.js index 3624518..bc60eb8 100644 --- a/client/src/modules/game_creation/GameCreationStepManager.js +++ b/client/src/modules/game_creation/GameCreationStepManager.js @@ -191,7 +191,7 @@ export class GameCreationStepManager { showButtons(false, true, this.steps[step].forwardHandler, null); break; case 2: - this.renderRoleSelectionStep(this.currentGame, containerId, step, this.deckManager); + this.renderRoleSelectionStep(this.currentGame, containerId, step); showButtons(true, true, this.steps[step].forwardHandler, this.steps[step].backHandler); break; case 3: @@ -216,7 +216,7 @@ export class GameCreationStepManager { document.getElementById('step-' + stepNumber)?.remove(); } - renderRoleSelectionStep = (game, containerId, step, deckManager) => { + renderRoleSelectionStep = (game, containerId, step) => { const stepContainer = document.createElement('div'); setAttributes(stepContainer, { id: 'step-' + step, class: 'flex-row-container-left-align step' }); @@ -225,13 +225,13 @@ export class GameCreationStepManager { document.getElementById(containerId).appendChild(stepContainer); - this.roleBox = new RoleBox(stepContainer, deckManager); - deckManager.roleBox = this.roleBox; + this.roleBox = new RoleBox(stepContainer, this.deckManager); + this.deckManager.roleBox = this.roleBox; this.roleBox.loadDefaultRoles(); this.roleBox.loadCustomRolesFromCookies(); this.roleBox.displayDefaultRoles(document.getElementById('role-select')); - deckManager.loadDeckTemplates(this.roleBox); + this.deckManager.loadDeckTemplates(this.roleBox); const exportHandler = (e) => { if (e.type === 'click' || e.code === 'Enter') { @@ -290,9 +290,9 @@ export class GameCreationStepManager { document.getElementById('custom-role-hamburger').addEventListener('click', clickHandler); - deckManager.updateDeckStatus(); + this.deckManager.updateDeckStatus(); - initializeRemainingEventListeners(deckManager, this.roleBox); + initializeRemainingEventListeners(this.deckManager, this.roleBox); }; } diff --git a/client/src/modules/game_creation/RoleBox.js b/client/src/modules/game_creation/RoleBox.js index 0e1e290..ea4c555 100644 --- a/client/src/modules/game_creation/RoleBox.js +++ b/client/src/modules/game_creation/RoleBox.js @@ -49,7 +49,8 @@ export class RoleBox { id: createRandomId(), role: roleObj.role, team: roleObj.team, - description: roleObj.description + description: roleObj.description, + custom: true }; }); // we know it is valid JSON from the validate function } @@ -73,7 +74,8 @@ export class RoleBox { id: createRandomId(), role: roleObj.role, team: roleObj.team, - description: roleObj.description + description: roleObj.description, + custom: true }; }); // we know it is valid JSON from the validate function const initialLength = this.customRoles.length; @@ -107,6 +109,26 @@ export class RoleBox { reader.readAsText(file); } + loadSelectedRolesFromCurrentGame = (game) => { + for (const card of game.deck) { + if (card.quantity) { + for (let i = 0; i < card.quantity; i ++) { + if (!this.deckManager.hasRole(card.role)) { + const role = this.getDefaultRole(card.role) + ? this.getDefaultRole(card.role) + : this.getCustomRole(card.role); + role.id = card.id; + this.deckManager.addToDeck(role); + } else { + this.deckManager.addCopyOfCard(card.role); + } + } + } + } + + this.deckManager.updateDeckStatus(); + } + // via https://stackoverflow.com/a/18197341 downloadCustomRoles = (filename, text) => { const element = document.createElement('a'); diff --git a/client/src/modules/game_state/states/Lobby.js b/client/src/modules/game_state/states/Lobby.js index 14cbe0f..9520f17 100644 --- a/client/src/modules/game_state/states/Lobby.js +++ b/client/src/modules/game_state/states/Lobby.js @@ -4,6 +4,9 @@ import { globals } from '../../../config/globals.js'; import { HTMLFragments } from '../../front_end_components/HTMLFragments.js'; import { Confirmation } from '../../front_end_components/Confirmation.js'; import { SharedStateUtil } from './shared/SharedStateUtil.js'; +import { GameCreationStepManager } from '../../game_creation/GameCreationStepManager.js'; +import { DeckStateManager } from '../../game_creation/DeckStateManager.js'; +import { hiddenMenus } from '../../../view_templates/CreateTemplate.js'; export class Lobby { constructor (containerId, stateBucket, socket) { @@ -11,6 +14,7 @@ export class Lobby { this.socket = socket; this.container = document.getElementById(containerId); this.container.innerHTML = HTMLFragments.LOBBY; + this.gameCreationStepManager = new GameCreationStepManager(new DeckStateManager()); this.startGameHandler = (e) => { e.preventDefault(); @@ -38,13 +42,45 @@ export class Lobby { ); }); }; + + this.editRolesHandler = (e) => { + e.preventDefault(); + document.querySelector('#mid-game-role-editor')?.remove(); + const roleEditContainer = document.createElement('div'); + roleEditContainer.setAttribute('id', 'mid-game-role-editor'); + roleEditContainer.innerHTML = hiddenMenus; + document.body.appendChild(roleEditContainer); + this.gameCreationStepManager.deckManager.deck = []; + this.gameCreationStepManager + .renderRoleSelectionStep(this.stateBucket.currentGameState, 'mid-game-role-editor', '2'); + this.gameCreationStepManager.roleBox.loadSelectedRolesFromCurrentGame(this.stateBucket.currentGameState); + const saveButton = document.createElement('button'); + saveButton.classList.add('app-button'); + saveButton.setAttribute('id', 'save-role-changes-button'); + saveButton.innerHTML = '

Save

'; + saveButton.addEventListener('click', () => { + if (this.gameCreationStepManager.deckManager.getDeckSize() > 50) { + toast('Your deck is too large. The max is 50 cards.', 'error', true); + } else if (this.gameCreationStepManager.deckManager.getDeckSize() < 1) { + toast('You must add at least one card', 'error', true); + } else { + document.querySelector('#mid-game-role-editor')?.remove(); + this.socket.emit( + globals.SOCKET_EVENTS.IN_GAME_MESSAGE, + globals.EVENT_IDS.UPDATE_GAME_ROLES, + stateBucket.currentGameState.accessCode, + { deck: this.gameCreationStepManager.deckManager.deck.filter((card) => card.quantity > 0) }, + () => { + toast('Roles updated successfully!', 'success'); + } + ); + } + }); + roleEditContainer.appendChild(saveButton); + }; } - populateHeader () { - const timeString = getTimeString(this.stateBucket.currentGameState); - const time = this.container.querySelector('#game-time'); - time.innerText = timeString; - + setLink (timeString) { const linkContainer = this.container.querySelector('#game-link'); linkContainer.innerHTML = '\'copy\'/'; const link = window.location.protocol + '//' + window.location.host + @@ -56,8 +92,27 @@ export class Lobby { linkContainer.prepend(linkDiv); activateLink(linkContainer, link); + return link; + } + + setPlayerCount () { const playerCount = this.container.querySelector('#game-player-count'); playerCount.innerText = this.stateBucket.currentGameState.gameSize + ' Players'; + const inLobbyCount = this.stateBucket.currentGameState.people.filter( + p => p.userType !== globals.USER_TYPES.MODERATOR && p.userType !== globals.USER_TYPES.SPECTATOR + ).length; + document.querySelector("label[for='lobby-players']").innerText = + 'Participants (' + inLobbyCount + '/' + this.stateBucket.currentGameState.gameSize + ' Players)'; + } + + populateHeader () { + const timeString = getTimeString(this.stateBucket.currentGameState); + const time = this.container.querySelector('#game-time'); + time.innerText = timeString; + + const link = this.setLink(timeString); + + this.setPlayerCount(); const spectatorHandler = (e) => { if (e.type === 'click' || e.code === 'Enter') { @@ -158,12 +213,20 @@ export class Lobby { } } }); + + this.socket.on(globals.EVENT_IDS.UPDATE_GAME_ROLES, (deck, gameSize) => { + this.stateBucket.currentGameState.deck = deck; + this.stateBucket.currentGameState.gameSize = gameSize; + this.setLink(getTimeString(this.stateBucket.currentGameState)); + this.setPlayerCount(); + }); } displayStartGamePromptForModerators () { const existingPrompt = document.getElementById('start-game-prompt'); if (existingPrompt) { enableOrDisableStartButton(this.stateBucket.currentGameState, existingPrompt, this.startGameHandler); + document.getElementById('edit-roles-button').addEventListener('click', this.editRolesHandler); } else { const newPrompt = document.createElement('div'); newPrompt.setAttribute('id', 'start-game-prompt'); @@ -171,6 +234,7 @@ export class Lobby { document.body.appendChild(newPrompt); enableOrDisableStartButton(this.stateBucket.currentGameState, newPrompt, this.startGameHandler); + document.getElementById('edit-roles-button').addEventListener('click', this.editRolesHandler); } } diff --git a/client/src/modules/game_state/states/shared/SharedStateUtil.js b/client/src/modules/game_state/states/shared/SharedStateUtil.js index 0d8c60c..15e7f49 100644 --- a/client/src/modules/game_state/states/shared/SharedStateUtil.js +++ b/client/src/modules/game_state/states/shared/SharedStateUtil.js @@ -315,14 +315,15 @@ function processGameState ( break; } - activateRoleInfoButton(stateBucket.currentGameState.deck); + activateRoleInfoButton(); } -function activateRoleInfoButton (deck) { - deck.sort((a, b) => { - return a.team === globals.ALIGNMENT.GOOD ? -1 : 1; - }); +function activateRoleInfoButton () { document.getElementById('role-info-button').addEventListener('click', (e) => { + const deck = stateBucket.currentGameState.deck; + deck.sort((a, b) => { + return a.team === globals.ALIGNMENT.GOOD ? -1 : 1; + }); e.preventDefault(); document.getElementById('role-info-prompt').innerHTML = HTMLFragments.ROLE_INFO_MODAL; const modalContent = document.getElementById('game-role-info-container'); diff --git a/client/src/modules/page_handlers/createHandler.js b/client/src/modules/page_handlers/createHandler.js index 2447c9e..47e53ab 100644 --- a/client/src/modules/page_handlers/createHandler.js +++ b/client/src/modules/page_handlers/createHandler.js @@ -1,8 +1,8 @@ import { injectNavbar } from '../front_end_components/Navbar.js'; -import createTemplate from '../../view_templates/CreateTemplate.js'; +import { fullCreateTemplate } from '../../view_templates/CreateTemplate.js'; export const createHandler = (gameCreationStepManager) => { injectNavbar(); - document.getElementById('game-creation-container').innerHTML = createTemplate; + document.getElementById('game-creation-container').innerHTML = fullCreateTemplate; gameCreationStepManager.renderStep('creation-step-container', 1); }; diff --git a/client/src/scripts/join.js b/client/src/scripts/join.js index e0d816f..3496832 100644 --- a/client/src/scripts/join.js +++ b/client/src/scripts/join.js @@ -31,6 +31,7 @@ const joinHandler = (e) => { .then((res) => { const json = JSON.parse(res.content); UserUtility.setAnonymousUserId(json.cookie, json.environment); + resetJoinButtonState(e, res, joinHandler); window.location = '/game/' + accessCode; }).catch((res) => { handleJoinError(e, res, joinHandler); @@ -59,10 +60,14 @@ function sendJoinRequest (e, name, accessCode) { ); } -function handleJoinError (e, res, joinHandler) { +function resetJoinButtonState (e, res, joinHandler) { document.getElementById('join-game-form').onsubmit = joinHandler; e.submitter.classList.remove('submitted'); e.submitter.setAttribute('value', 'Join'); +} + +function handleJoinError (e, res, joinHandler) { + resetJoinButtonState(e, res, joinHandler); if (res.status === 404) { toast('This game was not found.', 'error', true, true, 'long'); diff --git a/client/src/styles/GLOBAL.css b/client/src/styles/GLOBAL.css index 61da69d..d07e0da 100644 --- a/client/src/styles/GLOBAL.css +++ b/client/src/styles/GLOBAL.css @@ -663,8 +663,8 @@ input { } .info-message { - padding: 5px; - font-size: 16px; + padding: 10px; + font-size: 18px; } } diff --git a/client/src/styles/create.css b/client/src/styles/create.css index f357a98..74bdba4 100644 --- a/client/src/styles/create.css +++ b/client/src/styles/create.css @@ -385,7 +385,7 @@ select { display: flex; } -#game-time { +#creation-step-container #game-time { display: flex; flex-wrap: wrap; border-radius: 5px; @@ -673,7 +673,7 @@ input[type="number"] { @media(max-width: 550px) { #custom-roles-container, #deck-status-container { - min-width: 90%; + min-width: 85%; } h1 { font-size: 32px; diff --git a/client/src/styles/game.css b/client/src/styles/game.css index 36c7f4f..7eeb61f 100644 --- a/client/src/styles/game.css +++ b/client/src/styles/game.css @@ -106,16 +106,66 @@ max-width: 17em; } -#return-to-lobby-button, #end-of-game-buttons #return-to-lobby-button, #mod-transfer-button { +#save-role-changes-button { + padding: 10px; + font-size: 25px; + margin: 0.5em 0; +} + +#save-role-changes-button img { + width: 20px; + margin-left: 10px; +} + +#return-to-lobby-button, +#end-of-game-buttons #return-to-lobby-button, +#mod-transfer-button, +#edit-roles-button, +#save-role-changes-button { background-color: #045EA6; border: 2px solid #024070; } -#return-to-lobby-button:hover, #end-of-game-buttons #return-to-lobby-button:hover, #mod-transfer-button:hover { +#return-to-lobby-button:hover, +#end-of-game-buttons #return-to-lobby-button:hover, +#mod-transfer-button:hover, +#edit-roles-button:hover, +#save-role-changes-button:hover { background-color: rgba(0, 120, 215, 0.45); border: 2px solid #045EA6; } +#mid-game-role-editor { + display: flex; + border-radius: 5px; + position: fixed; + width: 100%; + height: 100%; + z-index: 100001; + background-color: #000000d4; + align-items: center; + justify-content: center; + font-family: 'signika-negative', sans-serif; + flex-direction: column; + overflow: auto; +} + +#mid-game-role-editor #step-2 { + width: 100%; + display: flex; + justify-content: center; + overflow: auto; + align-items: center; +} + +#save-button { + +} + +#mid-game-role-editor #custom-roles-container { + height: fit-content; +} + #play-pause-placeholder { width: 60px; height: 60px; @@ -435,7 +485,7 @@ h1 { background-color: #361a1a; } -#role-name { +#game-role #role-name { position: absolute; top: 6%; left: 50%; @@ -461,7 +511,7 @@ h1 { width: 78%; } -#role-description { +#game-role #role-description { overflow: auto; position: absolute; bottom: 6%; @@ -479,6 +529,7 @@ h1 { #game-link img { width: 20px; + height: 20px; margin-left: 0.5em; } @@ -529,26 +580,6 @@ label[for='moderator'] { } #start-game-prompt, #game-control-prompt { - padding: 0.5em 0; - display: flex; - flex-direction: column; - align-items: center; - justify-content: space-evenly; - position: fixed; - z-index: 3; - font-family: 'signika-negative', sans-serif; - font-weight: 100; - box-shadow: 0 -6px 15px rgb(0 0 0 / 50%); - bottom: 0; - border-radius: 5px; - font-size: 20px; - height: 100px; - margin: 0 auto; - background-color: #1b1a24; - width: 100%; -} - -#game-control-prompt { padding: 0.5em 0; display: flex; flex-direction: row; @@ -571,7 +602,7 @@ label[for='moderator'] { background-color: #1b1a24; } -#game-control-prompt button { +#game-control-prompt button, #start-game-prompt button { margin: 0 15px; min-width: 5em; } @@ -592,7 +623,7 @@ label[for='moderator'] { box-shadow: 0 -6px 40px black; } -#start-game-button, #end-game-button, #return-to-lobby-button { +#start-game-button, #end-game-button, #return-to-lobby-button, #edit-roles-button { font-family: 'signika-negative', sans-serif !important; padding: 10px; border-radius: 5px; @@ -610,7 +641,6 @@ label[for='moderator'] { #start-game-button { background-color: #1c8a36; - margin-bottom: 10px; animation: shadow-pulse 1.5s infinite ease-out; } @@ -959,7 +989,7 @@ canvas { height: 65px; } - #start-game-button, #end-game-button, #return-to-lobby-button { + #start-game-button, #end-game-button, #return-to-lobby-button, #edit-roles-button { font-size: 20px; padding: 5px; } diff --git a/client/src/view_templates/CreateTemplate.js b/client/src/view_templates/CreateTemplate.js index 5752461..ab673dd 100644 --- a/client/src/view_templates/CreateTemplate.js +++ b/client/src/view_templates/CreateTemplate.js @@ -1,4 +1,4 @@ -const template = +export const hiddenMenus = ` + `; + +export const fullCreateTemplate = + hiddenMenus + `

Create A Game

@@ -69,5 +72,3 @@ const template =
`; - -export default template; diff --git a/client/src/views/game.html b/client/src/views/game.html index be5a021..3a1470d 100644 --- a/client/src/views/game.html +++ b/client/src/views/game.html @@ -14,6 +14,7 @@ + diff --git a/server/config/globals.js b/server/config/globals.js index af4bced..26fac56 100644 --- a/server/config/globals.js +++ b/server/config/globals.js @@ -56,7 +56,8 @@ const globals = { UPDATE_SOCKET: 'updateSocket', ASSIGN_DEDICATED_MOD: 'assignDedicatedMod', TIMER_EVENT: 'timerEvent', - KICK_PERSON: 'kickPerson' + KICK_PERSON: 'kickPerson', + UPDATE_GAME_ROLES: 'updateGameRoles' }, SYNCABLE_EVENTS: function () { return [ @@ -76,7 +77,8 @@ const globals = { this.EVENT_IDS.RESUME_TIMER, this.EVENT_IDS.PAUSE_TIMER, this.EVENT_IDS.END_TIMER, - this.EVENT_IDS.KICK_PERSON + this.EVENT_IDS.KICK_PERSON, + this.EVENT_IDS.UPDATE_GAME_ROLES ]; }, TIMER_EVENTS: function () { diff --git a/server/model/GameCreationRequest.js b/server/model/GameCreationRequest.js index 29e20a7..e2ab638 100644 --- a/server/model/GameCreationRequest.js +++ b/server/model/GameCreationRequest.js @@ -29,6 +29,33 @@ class GameCreationRequest { return Promise.resolve(); } }; + + static deckIsValid = (deck) => { + if (Array.isArray(deck) && deck.length > 0) { + for (const entry of deck) { + if (entry !== null + && typeof entry === 'object' + && typeof entry.role === 'string' + && entry.role.length > 0 + && entry.role.length <= globals.MAX_CUSTOM_ROLE_NAME_LENGTH + && typeof entry.team === 'string' + && (entry.team === globals.ALIGNMENT.GOOD || entry.team === globals.ALIGNMENT.EVIL) + && typeof entry.description === 'string' + && entry.description.length > 0 + && entry.description.length <= globals.MAX_CUSTOM_ROLE_DESCRIPTION_LENGTH + && (!entry.custom || typeof entry.custom === 'boolean') + && typeof entry.quantity === 'number' + && entry.quantity >= 1 + && entry.quantity <= 50 + ) { + continue; + } + return false; + } + return true; + } + return false; + } } function valid (gameParams) { @@ -39,7 +66,7 @@ function valid (gameParams) { && gameParams.moderatorName.length > 0 && gameParams.moderatorName.length <= 30 && timerParamsAreValid(gameParams.hasTimer, gameParams.timerParams) - && deckIsValid(gameParams.deck); + && GameCreationRequest.deckIsValid(gameParams.deck); } function timerParamsAreValid (hasTimer, timerParams) { @@ -58,31 +85,4 @@ function timerParamsAreValid (hasTimer, timerParams) { } } -function deckIsValid (deck) { - if (Array.isArray(deck) && deck.length > 0) { - for (const entry of deck) { - if (entry !== null - && typeof entry === 'object' - && typeof entry.role === 'string' - && entry.role.length > 0 - && entry.role.length <= globals.MAX_CUSTOM_ROLE_NAME_LENGTH - && typeof entry.team === 'string' - && (entry.team === globals.ALIGNMENT.GOOD || entry.team === globals.ALIGNMENT.EVIL) - && typeof entry.description === 'string' - && entry.description.length > 0 - && entry.description.length <= globals.MAX_CUSTOM_ROLE_DESCRIPTION_LENGTH - && (!entry.custom || typeof entry.custom === 'boolean') - && typeof entry.quantity === 'number' - && entry.quantity >= 1 - && entry.quantity <= 50 - ) { - continue; - } - return false; - } - return true; - } - return false; -} - module.exports = GameCreationRequest; diff --git a/server/modules/Events.js b/server/modules/Events.js index eb1cd8f..fc02fd0 100644 --- a/server/modules/Events.js +++ b/server/modules/Events.js @@ -1,6 +1,7 @@ const globals = require('../config/globals'); const GameStateCurator = require('./GameStateCurator'); const UsernameGenerator = require('./UsernameGenerator'); +const GameCreationRequest = require('../model/GameCreationRequest'); const EVENT_IDS = globals.EVENT_IDS; const Events = [ @@ -57,6 +58,28 @@ const Events = [ ); } }, + { + id: EVENT_IDS.UPDATE_GAME_ROLES, + stateChange: async (game, socketArgs, vars) => { + if (GameCreationRequest.deckIsValid(socketArgs.deck)) { + game.deck = socketArgs.deck; + game.gameSize = socketArgs.deck.reduce( + (accumulator, currentValue) => accumulator + currentValue.quantity, + 0 + ); + } + }, + communicate: async (game, socketArgs, vars) => { + if (vars.ackFn) { + vars.ackFn(); + } + vars.gameManager.namespace.in(game.accessCode).emit( + EVENT_IDS.UPDATE_GAME_ROLES, + game.deck, + game.gameSize + ); + } + }, { id: EVENT_IDS.ADD_SPECTATOR, stateChange: async (game, socketArgs, vars) => { diff --git a/server/modules/singletons/GameManager.js b/server/modules/singletons/GameManager.js index 3149ae7..5443f14 100644 --- a/server/modules/singletons/GameManager.js +++ b/server/modules/singletons/GameManager.js @@ -302,6 +302,10 @@ class GameManager { return array; }; + deal = () => { + + } + isGameFull = (game) => { return !game.people.find((person) => person.userType === globals.USER_TYPES.PLAYER && person.assigned === false); } diff --git a/spec/e2e/game_spec.js b/spec/e2e/game_spec.js index 05d73f5..a3295de 100644 --- a/spec/e2e/game_spec.js +++ b/spec/e2e/game_spec.js @@ -332,7 +332,7 @@ describe('game page', () => { } ]); expect(document.getElementById('end-of-game-header')).not.toBeNull(); - expect(document.getElementById('restart-game-button')).not.toBeNull(); + expect(document.getElementById('return-to-lobby-button')).not.toBeNull(); }); afterAll(() => {