diff --git a/backend/db_test/test_data.sql b/backend/db_test/test_data.sql index db8d57f8..d1d8e14c 100644 --- a/backend/db_test/test_data.sql +++ b/backend/db_test/test_data.sql @@ -260,3 +260,8 @@ INSERT INTO "Matches"("Id","Team1Player1Id","Team1Player1Rating","Team1Player2Id INSERT INTO "Matches"("Id","Team1Player1Id","Team1Player1Rating","Team1Player2Id","Team1Player2Rating","Team2Player1Id","Team2Player1Rating","Team2Player2Id","Team2Player2Rating","Date","WinningTeamRatingChange","Team1Won","LosingTeamRatingChange", "GameId") VALUES ('4510','150','823','230','1068','70','1385','210','819','2019-11-06 13:57:41.732','9','false','-9', '3'); INSERT INTO "Matches"("Id","Team1Player1Id","Team1Player1Rating","Team1Player2Id","Team1Player2Rating","Team2Player1Id","Team2Player1Rating","Team2Player2Id","Team2Player2Rating","Date","WinningTeamRatingChange","Team1Won","LosingTeamRatingChange", "GameId") VALUES ('4520','150','814','90','1063','50','950','220','906','2019-11-07 16:15:51.246','16','true','-16', '3'); INSERT INTO "Matches"("Id","Team1Player1Id","Team1Player1Rating","Team1Player2Id","Team1Player2Rating","Team2Player1Id","Team2Player1Rating","Team2Player2Id","Team2Player2Rating","Date","WinningTeamRatingChange","Team1Won","LosingTeamRatingChange", "GameId") VALUES ('4530','90','1079','150','830','240','960','220','890','2019-11-08 12:16:44.265','15','true','-15', '3'); + +-- Shift Ids' Serials to avoid errors when inserting new rows +ALTER SEQUENCE "Users_Id_seq1" RESTART WITH 300; +ALTER SEQUENCE "Users_Id_seq" RESTART WITH 300; +ALTER SEQUENCE "Matches_Id_seq" RESTART WITH 5000; diff --git a/cypress/integration/pages/AddMatchPage.ts b/cypress/integration/pages/AddMatchPage.ts new file mode 100644 index 00000000..2cafb317 --- /dev/null +++ b/cypress/integration/pages/AddMatchPage.ts @@ -0,0 +1,36 @@ +import { Page } from './Page' +import { Player } from '../types/Player' +import { DashboardPage } from './DashboardPage' + +export class AddMatchPage extends Page { + constructor(private gameName: string) { + super(`/${gameName}/create-match`) + } + + visit(): AddMatchPage { + super.visit() + return this + } + + locate(): void { + super.locate() + this.getContent() + .should('contain.text', 'Team 1') + .should('contain.text', 'Team 2') + } + + selectTeam1Player1(player: Player): AddMatchPage { + cy.get('#team1-player-input-0').select(player.name) + return this + } + + selectTeam2Player1(player: Player): AddMatchPage { + cy.get('#team2-player-input-0').select(player.name) + return this + } + + team1Wins(): DashboardPage { + cy.get('#team1-win-button').click() + return new DashboardPage(this.gameName) + } +} diff --git a/cypress/integration/pages/CreatePlayerPage.ts b/cypress/integration/pages/AddPlayerPage.ts similarity index 85% rename from cypress/integration/pages/CreatePlayerPage.ts rename to cypress/integration/pages/AddPlayerPage.ts index a2f2a445..b8e60985 100644 --- a/cypress/integration/pages/CreatePlayerPage.ts +++ b/cypress/integration/pages/AddPlayerPage.ts @@ -3,12 +3,12 @@ import { SelectGamePage } from './SelectGamePage' import { Player } from '../types/Player' import { DashboardPage } from './DashboardPage' -export class CreatePlayerPage extends Page { +export class AddPlayerPage extends Page { constructor(private gameName: string) { super(`/${gameName}/add-player`) } - visit(): CreatePlayerPage { + visit(): AddPlayerPage { super.visit() return this } @@ -23,7 +23,7 @@ export class CreatePlayerPage extends Page { return new DashboardPage(this.gameName) } - addPlayer(player: Player, score: number): CreatePlayerPage { + addPlayer(player: Player, score: number): AddPlayerPage { const content = this.getContent() content.get('#player-name-input').clear().type(player.name) content diff --git a/cypress/integration/pages/DashboardPage.ts b/cypress/integration/pages/DashboardPage.ts index efee1f19..e643f6e4 100644 --- a/cypress/integration/pages/DashboardPage.ts +++ b/cypress/integration/pages/DashboardPage.ts @@ -1,5 +1,7 @@ import { Page } from './Page' import { SelectGamePage } from './SelectGamePage' +import { AddMatchPage } from './AddMatchPage' +import { MatchListPage } from './MatchListPage' import { LeaderboardPage } from './LeaderboardPage' export class DashboardPage extends Page { @@ -21,11 +23,21 @@ export class DashboardPage extends Page { .should('contain.text', 'Add Match') } + goToAddMatch(): AddMatchPage { + cy.get('#add-match-button').click() + return new AddMatchPage(this.gameName) + } + goToGameSelection(): SelectGamePage { this.getHeader().get('#logo').click() return new SelectGamePage() } + goToMatchesList(): MatchListPage { + this.getContent().get('#show-all-matches').click() + return new MatchListPage(this.gameName) + } + goToLeaderboard(): LeaderboardPage { this.getContent().get('#show-leaderboard').click() return new LeaderboardPage(this.gameName) diff --git a/cypress/integration/pages/MatchListPage.ts b/cypress/integration/pages/MatchListPage.ts new file mode 100644 index 00000000..b950bf89 --- /dev/null +++ b/cypress/integration/pages/MatchListPage.ts @@ -0,0 +1,7 @@ +import { Page } from './Page' + +export class MatchListPage extends Page { + constructor(private gameName: string) { + super(`/${gameName}/match-list`) + } +} diff --git a/cypress/integration/tests/add-match.ts b/cypress/integration/tests/add-match.ts new file mode 100644 index 00000000..fd669342 --- /dev/null +++ b/cypress/integration/tests/add-match.ts @@ -0,0 +1,44 @@ +import { AddMatchPage } from '../pages/AddMatchPage' +import { FOOSBALL_GAME } from '../utils/data' +import { AddPlayerPage } from '../pages/AddPlayerPage' +import { generateRandomPlayer } from '../utils/gen' +import { LeaderboardPage } from '../pages/LeaderboardPage' + +describe('Create match page', () => { + const addMatchPage = new AddMatchPage(FOOSBALL_GAME.name) + before(() => { + addMatchPage.visit() + }) + it('renders', () => { + addMatchPage.locate() + }) +}) + +describe('Leaderboard', () => { + const player1 = generateRandomPlayer() + const player1score = 1010 + const player1newscore= 1026 + const player2 = generateRandomPlayer() + const player2score = 1020 + const player2newscore= 1004 + describe('when player 1 and player 2 exist in foosball and first wins once over second', () => { + let leaderboard: LeaderboardPage + beforeEach(() => { + leaderboard = new AddPlayerPage(FOOSBALL_GAME.name) + .visit() + .addPlayer(player1, player1score) + .addPlayer(player2, player2score) + .goToSelectGamePage() + .selectGame(FOOSBALL_GAME.name) + .goToAddMatch() + .selectTeam1Player1(player1) + .selectTeam2Player1(player2) + .team1Wins() + .goToLeaderboard() + }) + it('contains players with resulting scores', () => { + leaderboard.locatePlayerWithScore(player1, player1newscore) + leaderboard.locatePlayerWithScore(player2, player2newscore) + }) + }) +}) diff --git a/cypress/integration/tests/add-player.ts b/cypress/integration/tests/add-player.ts new file mode 100644 index 00000000..19c15413 --- /dev/null +++ b/cypress/integration/tests/add-player.ts @@ -0,0 +1,72 @@ +import { AddPlayerPage } from '../pages/AddPlayerPage' +import { FOOSBALL_GAME, TENNIS_GAME } from '../utils/data' +import { Player } from '../types/Player' +import { generateRandomPlayer } from '../utils/gen' + +describe('Add player page', () => { + const addPlayerPage = new AddPlayerPage(FOOSBALL_GAME.name) + before(() => { + addPlayerPage.visit() + }) + it('renders', () => { + addPlayerPage.locate() + }) + describe('when a random player is added to foosball', () => { + let player: Player + const score = 1001 + beforeEach(() => { + player = generateRandomPlayer() + addPlayerPage.addPlayer(player, score) + }) + it('is seen in the leaderboard without reload', () => { + const leaderboard = addPlayerPage + .goToSelectGamePage() + .selectGame(FOOSBALL_GAME.name) + .goToLeaderboard() + leaderboard.locatePlayerWithScore(player, score) + }) + }) +}) + +describe('A player added to foosball is not added to tennis', () => { + const addPlayerPage = new AddPlayerPage(FOOSBALL_GAME.name) + describe('when a player is added to foosball', () => { + let player: Player + const score = 1001 + beforeEach(() => { + player = generateRandomPlayer() + addPlayerPage + .visit() + .addPlayer(player, score) + }) + it('is not added to tennis', () => { + addPlayerPage + .goToSelectGamePage() + .selectGame(TENNIS_GAME.name) + .goToLeaderboard() + .missPlayerWithScore(player, score) + }) + }) +}) + +describe('Same player can be added to foosball and to tennis', () => { + describe('when a player is added to foosball', () => { + let player: Player + const score = 1001 + beforeEach(() => { + player = generateRandomPlayer() + new AddPlayerPage(FOOSBALL_GAME.name) + .visit() + .addPlayer(player, score) + }) + it('can be added to tennis', () => { + new AddPlayerPage(TENNIS_GAME.name) + .visit() + .addPlayer(player, score) + .goToSelectGamePage() + .selectGame(TENNIS_GAME.name) + .goToLeaderboard() + .locatePlayerWithScore(player, score) + }) + }) +}) diff --git a/cypress/integration/tests/create-player.ts b/cypress/integration/tests/create-player.ts deleted file mode 100644 index 5ed9181b..00000000 --- a/cypress/integration/tests/create-player.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CreatePlayerPage } from '../pages/CreatePlayerPage' -import { FOOSBALL_GAME } from '../utils/data' -import { Player } from '../types/Player' -import { generateRandomPlayer } from '../utils/gen' - -describe('Create player page', () => { - const addPlayerPage = new CreatePlayerPage(FOOSBALL_GAME.name) - before(() => { - addPlayerPage.visit() - }) - it('renders', () => { - addPlayerPage.locate() - }) - describe('when a random player is added to foosball', () => { - let player: Player - const score = 1001 - beforeEach(() => { - player = generateRandomPlayer() - addPlayerPage.addPlayer(player, score) - }) - it('is seen in the leaderboard without reload', () => { - const leaderboard = addPlayerPage - .goToDashboard() - .goToLeaderboard() - leaderboard.locatePlayerWithScore(player, score) - }) - }) -}) diff --git a/cypress/integration/tests/dashboard.ts b/cypress/integration/tests/dashboard.ts index 950f2d65..82160eac 100644 --- a/cypress/integration/tests/dashboard.ts +++ b/cypress/integration/tests/dashboard.ts @@ -2,12 +2,10 @@ import { DashboardPage } from '../pages/DashboardPage' describe('Dashboard', () => { const dashboardPage = new DashboardPage('foosball') - beforeEach(() => { + before(() => { dashboardPage.visit() }) - it('contains Last Battles and Top Rating titles', () => { - dashboardPage.getContent() - .should('contain.text', 'Last Battles') - .should('contain.text', 'Top Rating') + it('renders', () => { + dashboardPage.locate() }) }) diff --git a/cypress/integration/tests/game-select.ts b/cypress/integration/tests/game-select.ts new file mode 100644 index 00000000..e637d757 --- /dev/null +++ b/cypress/integration/tests/game-select.ts @@ -0,0 +1,11 @@ +import { SelectGamePage } from '../pages/SelectGamePage' + +describe('Select Game Page', () => { + const selectGamePage = new SelectGamePage() + before(() => { + selectGamePage.visit() + }) + it('renders', () => { + selectGamePage.locate() + }) +}) diff --git a/cypress/integration/tests/navigation.ts b/cypress/integration/tests/navigation.ts new file mode 100644 index 00000000..d04712bd --- /dev/null +++ b/cypress/integration/tests/navigation.ts @@ -0,0 +1,53 @@ +import { SelectGamePage } from '../pages/SelectGamePage' +import { FOOSBALL_GAME, TENNIS_GAME } from '../utils/data' + +describe('Navigation', () => { + describe('foosball dashboard', () => { + it('is reachable', () => { + new SelectGamePage() + .visit() + .selectGame(FOOSBALL_GAME.name) + .locate() + }) + }) + + describe('foosball add match page', () => { + it('is reachable', () => { + new SelectGamePage() + .visit() + .selectGame(FOOSBALL_GAME.name) + .goToAddMatch() + .locate() + }) + }) + + describe('tennis dashboard after foosball dashboard', () => { + it('is reachable', () => { + new SelectGamePage() + .visit() + .selectGame(FOOSBALL_GAME.name) + .goToGameSelection() + .selectGame(TENNIS_GAME.name) + .locate() + }) + }) + + describe('match list page', () => { + it('is reachable', () => { + new SelectGamePage() + .visit() + .selectGame(FOOSBALL_GAME.name) + .goToMatchesList() + .locate() + }) + }) + describe('leaderboard page', () => { + it('is reachable', () => { + new SelectGamePage() + .visit() + .selectGame(FOOSBALL_GAME.name) + .goToLeaderboard() + .locate() + }) + }) +}) diff --git a/cypress/integration/types/Team.ts b/cypress/integration/types/Team.ts new file mode 100644 index 00000000..a8eea3fb --- /dev/null +++ b/cypress/integration/types/Team.ts @@ -0,0 +1,6 @@ +import { Player } from './Player' + +export interface Team { + player1: Player; + player2: Player; +} diff --git a/cypress/integration/utils/data.ts b/cypress/integration/utils/data.ts index 8845ece3..88a96b35 100644 --- a/cypress/integration/utils/data.ts +++ b/cypress/integration/utils/data.ts @@ -1,3 +1,23 @@ +import { Player } from '../types/Player' +import { Team } from '../types/Team' + export const FOOSBALL_GAME = { name: 'foosball', } + +export const TENNIS_GAME = { + name: 'tennis', +} + +export const XRadek: Player = { + name: 'XRadek', +} + +export const XTonda: Player = { + name: 'XTonda', +} + +export const Team1: Team = { + player1: XRadek, + player2: XTonda, +} diff --git a/frontend/src/app/Game.js b/frontend/src/app/Game.js index 109eb44f..7b766dac 100644 --- a/frontend/src/app/Game.js +++ b/frontend/src/app/Game.js @@ -32,7 +32,7 @@ export class GameComponent extends Component { {capitalize(selection.value.name)} - Add Match + Add Match : null } diff --git a/frontend/src/app/__snapshots__/Game.test.js.snap b/frontend/src/app/__snapshots__/Game.test.js.snap index 75f82c04..5bcf1192 100644 --- a/frontend/src/app/__snapshots__/Game.test.js.snap +++ b/frontend/src/app/__snapshots__/Game.test.js.snap @@ -42,6 +42,7 @@ exports[`GameComponent when foosball is selected renders button "Add Match" and Add Match diff --git a/frontend/src/app/components/AddPlayer/AddPlayer.js b/frontend/src/app/components/AddPlayer/AddPlayer.js index cc9e0ba3..1703dfb3 100644 --- a/frontend/src/app/components/AddPlayer/AddPlayer.js +++ b/frontend/src/app/components/AddPlayer/AddPlayer.js @@ -59,7 +59,11 @@ class AddPlayerComponent extends Component { - + diff --git a/frontend/src/app/components/CreateMatch/CreateMatch.js b/frontend/src/app/components/CreateMatch/CreateMatch.js index 0c616e51..ac51f08e 100644 --- a/frontend/src/app/components/CreateMatch/CreateMatch.js +++ b/frontend/src/app/components/CreateMatch/CreateMatch.js @@ -93,6 +93,7 @@ export class CreateMatchComponent extends Component { { const playerItems = this.createPlayerItemsWithNone() const selectInputs = this.state.selectedPlayerIds.map((playerId, index) => ( - this.playerSelected(index, Number(event.target.value))} /> )) @@ -50,7 +50,8 @@ export class SelectTeamForm extends Component { <> {this.props.teamName} {selectInputs} - diff --git a/frontend/src/app/pages/Dashboard/index.js b/frontend/src/app/pages/Dashboard/index.js index da92a23d..ff1e79ad 100644 --- a/frontend/src/app/pages/Dashboard/index.js +++ b/frontend/src/app/pages/Dashboard/index.js @@ -20,7 +20,7 @@ const DashboardComponent = ({ lastMatches, topPlayers, constructUrl }) => Last Battles - Show all... + Show all... Top Rating Show more...