Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ff68423
feat: creates landing page
bferenczy Dec 6, 2023
8c74664
feat: creates start screen
bferenczy Dec 6, 2023
3f5456e
feat: creates ui for 'guess name' mode
bferenczy Dec 6, 2023
cb97999
feat: creates ui draft for 'assign logos' mode
bferenczy Dec 6, 2023
8c52cf0
feat: creates ui for 'end game' screen
bferenczy Dec 6, 2023
455d55f
fix: replaces chakra cards with common card component
bferenczy Dec 6, 2023
9869f47
feat: creates ui for score indicator
bferenczy Dec 6, 2023
35cbc09
feat: answer validation on 'guess name' mode
bferenczy Dec 6, 2023
92c8123
feat: show alert for correct/incorrect answer
bferenczy Dec 6, 2023
94e5086
feature: partial - setting up dnd environment
bferenczy Dec 6, 2023
ef7fa25
feat: drag-n-drop on 'assign logos' game mode
bferenczy Dec 6, 2023
fec0389
feat: answer validation on 'assign logos' mode
bferenczy Dec 6, 2023
9adc8a7
refactor: moves dnd logic to 'useDragAndDrop' hook
bferenczy Dec 6, 2023
256202c
refactor: extended typing on 'useDragAndDrop' hook
bferenczy Dec 6, 2023
3cf7379
refactor: improving responsiveness of 'assign logos' mode
bferenczy Dec 6, 2023
18f4621
refactor: answer correct/wrong alert to separate component
bferenczy Dec 6, 2023
952e701
feat: creates game loop
bferenczy Dec 6, 2023
a89756d
feat: score calculation
bferenczy Dec 6, 2023
e04d917
refactor: moves game logic to 'useGameLogic' hook
bferenczy Dec 6, 2023
f1dcc2b
feat: fetching guilds from api
bferenczy Dec 6, 2023
6d4d89a
feat: show skeleton on load
bferenczy Dec 6, 2023
0228def
feat: lift up animation on logo dragstart
bferenczy Dec 6, 2023
deaebee
refactor: directory structure
bferenczy Dec 6, 2023
8a62b4c
refactor: moves magic numbers to consts
bferenczy Dec 6, 2023
1906817
feature: only include guilds with imageurl
bferenczy Dec 6, 2023
b32dade
fix: empty progress bar on zero highscore
bferenczy Dec 7, 2023
6e88cc4
test: adds e2e tests
bferenczy Dec 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions cypress/e2e/3-guess-the-guild/0-guess-name.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
const setGameModeToGuessName = () => {
Cypress.on("window:before:load", (win) => {
Object.defineProperty(win.Math, "random", {
value: function () {
return 0.1
},
writable: false,
})
})
}

describe.skip("api fetching returns an error", () => {
it("displays error toast message", () => {
cy.intercept(`${Cypress.env("guildApiUrl")}/guilds?*`, {
statusCode: 500,
}).as("failedGuildLoad")

cy.visit("/guess-the-guild")

cy.wait("@failedGuildLoad")

cy.get(".chakra-toast", { timeout: 5000 }).should("be.visible")
})
})

describe.skip("in 'guess name' mode", () => {
beforeEach(() => {
cy.visit("/guess-the-guild")
setGameModeToGuessName()
cy.contains("Let's Go!").click()
})

it("is not possible to press submit, until an answer is selected", () => {
cy.getByDataTest("submit").should("be.disabled")
})

it("is possible to press submit, after an answer is selected", () => {
cy.getByDataTest("answer-button").first().click()
cy.getByDataTest("submit").should("not.be.disabled")
})

it("score indicator shows up", () => {
cy.get("#score-indicator").should("be.visible")
})
})

describe.skip("game mode answer submit", () => {
it("shows success message for good answer", () => {
cy.intercept(`${Cypress.env("guildApiUrl")}/guilds?*`, {
statusCode: 200,
fixture: "testGuilds.json",
}).as("guildsLoaded")

cy.visit("/guess-the-guild")
setGameModeToGuessName()

cy.contains("Let's Go!").click()
cy.getByDataTest("answer-button").first().click()
cy.getByDataTest("submit").click()
cy.get('[data-status="success"]').should("be.visible")
})

it("shows wrong answer message", () => {
cy.intercept(`${Cypress.env("guildApiUrl")}/guilds?*`, {
statusCode: 200,
fixture: "testGuilds.json",
}).as("guildsLoaded")

cy.visit("/guess-the-guild")
setGameModeToGuessName()

cy.contains("Let's Go!").click()
cy.getByDataTest("answer-button").last().click()
cy.getByDataTest("submit").click()
cy.get('[data-status="warning"]').should("be.visible")
})

it("increases score by 1 on good answer", () => {
cy.intercept(`${Cypress.env("guildApiUrl")}/guilds?*`, {
statusCode: 200,
fixture: "testGuilds.json",
}).as("guildsLoaded")

cy.visit("/guess-the-guild")
setGameModeToGuessName()

cy.contains("Let's Go!").click()

cy.get("span").contains("Score:").parent().contains("0").should("be.visible")

cy.getByDataTest("answer-button").first().click()
cy.getByDataTest("submit").click()

cy.contains("1 points").should("be.visible")
})

it("does not change score on wrong answer", () => {
cy.intercept(`${Cypress.env("guildApiUrl")}/guilds?*`, {
statusCode: 200,
fixture: "testGuilds.json",
}).as("guildsLoaded")

cy.visit("/guess-the-guild")
setGameModeToGuessName()

cy.contains("Let's Go!").click()

cy.get("span").contains("Score:").parent().contains("0").should("be.visible")

cy.getByDataTest("answer-button").last().click()
cy.getByDataTest("submit").click()

cy.get("span").contains("Score:").parent().contains("0").should("be.visible")
})
})

describe("game screen order", () => {
beforeEach(() => {
cy.intercept(`${Cypress.env("guildApiUrl")}/guilds?*`, {
statusCode: 200,
fixture: "testGuilds.json",
}).as("guildsLoaded")

cy.visit("/guess-the-guild")
setGameModeToGuessName()

cy.contains("Let's Go!").click()
})

it.skip("game continues on good answer", () => {
cy.getByDataTest("answer-button").first().click()
cy.getByDataTest("submit").click()

cy.getByDataTest("continue").should("be.visible")
cy.getByDataTest("continue").click()
cy.getByDataTest("submit").should("be.visible")
})

it.skip("game ends after wrong answer", () => {
cy.getByDataTest("answer-button").last().click()
cy.getByDataTest("submit").click()
cy.getByDataTest("end-game").should("be.visible")
cy.getByDataTest("end-game").click()
cy.contains("Game Over").should("be.visible")
})

it("game restarts after end game screen", () => {
cy.getByDataTest("answer-button").last().click()
cy.getByDataTest("submit").click()
cy.getByDataTest("end-game").click()
cy.contains("Try Again!").click()
cy.contains("GuildGesser").should("be.visible")
})
})
31 changes: 31 additions & 0 deletions cypress/e2e/3-guess-the-guild/1-assign-logos.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const setGameModeToAssignLogos = () => {
Cypress.on("window:before:load", (win) => {
Object.defineProperty(win.Math, "random", {
value: function () {
return 0.9
},
writable: false,
})
})
}

describe("assign logos game mode", () => {
beforeEach(() => {
cy.intercept(`${Cypress.env("guildApiUrl")}/guilds?*`, {
statusCode: 200,
fixture: "testGuilds.json",
}).as("guildsLoaded")

cy.visit("/guess-the-guild")
setGameModeToAssignLogos()
cy.contains("Let's Go!").click()
})

it("not possible to press submit when not all logos are assigned", () => {
cy.getByDataTest("submit").should("be.disabled")
})

it("score indicator shows up", () => {
cy.get("#score-indicator").should("be.visible")
})
})
46 changes: 46 additions & 0 deletions cypress/fixtures/testGuilds.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[
{
"id": 1,
"name": "Guild 1",
"urlName": "guild1",
"imageUrl": "",
"roles": ["Role1"],
"platforms": ["DISCORD"],
"memberCount": 1234,
"rolesCount": 5678,
"tags": ["VERIFIED"]
},
{
"id": 2,
"name": "Guild 2",
"urlName": "guild2",
"imageUrl": "",
"roles": ["Role1"],
"platforms": ["DISCORD"],
"memberCount": 1234,
"rolesCount": 5678,
"tags": ["VERIFIED"]
},
{
"id": 3,
"name": "Guild 3",
"urlName": "guild3",
"imageUrl": "",
"roles": ["Role1"],
"platforms": ["DISCORD"],
"memberCount": 1234,
"rolesCount": 5678,
"tags": ["VERIFIED"]
},
{
"id": 4,
"name": "Guild 4",
"urlName": "guild4",
"imageUrl": "",
"roles": ["Role1"],
"platforms": ["DISCORD"],
"memberCount": 1234,
"rolesCount": 5678,
"tags": ["VERIFIED"]
}
]
37 changes: 37 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@chakra-ui/anatomy": "^2.1.2",
"@chakra-ui/react": "^2.6.1",
"@chakra-ui/theme-tools": "^2.0.17",
"@dnd-kit/core": "^6.1.0",
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
"@hcaptcha/react-hcaptcha": "^1.4.4",
Expand Down
81 changes: 81 additions & 0 deletions src/components/guess-the-guild/EndGame.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Alert, Button, Divider, Heading, Text, VStack } from "@chakra-ui/react"
import pluralize from "utils/pluralize"

const EndGame = ({
score,
highscore,
onRestart,
}: {
score: number
highscore: number
onRestart: () => void
}) => {
const getMessage = () => {
if (score <= 10) return "Better luck next time!"
if (score <= 20) return "You're getting the hang of it!"
return "It looks like we're dealing with a professional 👀"
}

return (
<>
<VStack>
<Heading
as="h2"
fontSize={{ base: "xl", md: "2xl", lg: "3xl" }}
textAlign="center"
fontFamily="display"
>
Game Over
</Heading>
<Text textAlign="center">{getMessage()}</Text>

<Divider mt="4" />
<Text
as="span"
mt="1"
fontSize="xs"
fontWeight="bold"
color="gray"
textTransform="uppercase"
noOfLines={1}
>
Final Score
</Text>
<Text
fontSize={{ base: "xl", md: "2xl", lg: "3xl" }}
mt="-2"
mb="1"
fontFamily="display"
fontWeight="600"
>
{score} points
</Text>

{score > highscore && (
<>
<Alert status="success" justifyContent="center">
🎉 New Highscore!
</Alert>
</>
)}

{score <= highscore && (
<>
<Text>
Only <strong>{pluralize(highscore - score + 1, "point")}</strong> to go
to beat your current highscore!
</Text>
</>
)}

<Divider mt="2" />

<Button colorScheme="green" w="100%" mt="3" onClick={() => onRestart()}>
Try Again!
</Button>
</VStack>
</>
)
}

export default EndGame
Loading