diff --git a/client/e2e/fixtures/gameList.ts b/client/e2e/fixtures/gameList.ts new file mode 100644 index 0000000..6cad9c8 --- /dev/null +++ b/client/e2e/fixtures/gameList.ts @@ -0,0 +1,191 @@ +export default { + data: [ + { + _id: "671363aaf22203668e1adb7c", + gameName: "Diablo Immortal", + gameImage: "https://www.freetogame.com/g/521/thumbnail.jpg", + gameDescription: + "Built for mobile and also released on PC, Diablo Immortal fills in the gaps between Diablo II and III in an MMOARPG environment.", + reviews: [ + { + text: "Addictive gameplay, but could use better optimization.", + rating: 4, + username: "diablofan", + email: "diablo@example.com", + latitude: "35.6895", + longitude: "139.6917", + _id: "671363aaf22203668e1adb7d", + }, + ], + reviewCount: 1, + avgRating: 4, + }, + { + _id: "671363aaf22203668e1adb83", + gameName: "Enlisted", + gameImage: "https://www.freetogame.com/g/508/thumbnail.jpg", + gameDescription: + "Get ready to command your own World War II military squad in Gaijin and Darkflow Software’s MMO squad-based shooter Enlisted.", + reviews: [ + { + text: "Realistic and immersive experience!", + rating: 5, + username: "historybuff", + email: "enlisted@example.com", + latitude: "52.5200", + longitude: "13.4050", + _id: "671363aaf22203668e1adb84", + }, + ], + reviewCount: 1, + avgRating: 5, + }, + { + _id: "671363aaf22203668e1adb85", + gameName: "Forge of Empires", + gameImage: "https://www.freetogame.com/g/345/thumbnail.jpg", + gameDescription: + "A free to play 2D browser-based online strategy game, become the leader and raise your city.", + reviews: [ + { + text: "Addictive city-building gameplay!", + rating: 4, + username: "citybuilder", + email: "forgeofempires@example.com", + latitude: "51.5074", + longitude: "-0.1278", + _id: "671363aaf22203668e1adb86", + }, + ], + reviewCount: 1, + avgRating: 4, + }, + { + _id: "671363aaf22203668e1adb87", + gameName: "Genshin Impact", + gameImage: "https://www.freetogame.com/g/475/thumbnail.jpg", + gameDescription: + "If you’ve been looking for a game to scratch that open-world action RPG itch, one with perhaps a bit of Asian flair, then you’re going to want to check out miHoYo’s Genshin Impact.", + reviews: [ + { + text: "Stunning visuals and engaging combat!", + rating: 5, + username: "adventurer", + email: "genshin@example.com", + latitude: "35.6895", + longitude: "139.6917", + _id: "671363aaf22203668e1adb88", + }, + ], + reviewCount: 1, + avgRating: 5, + }, + { + _id: "671363aaf22203668e1adb89", + gameName: "Fall Guys", + gameImage: "https://www.freetogame.com/g/523/thumbnail.jpg", + gameDescription: + "Play the most competitive massively multiplayer party royale game featuring beans ever for free on a variety of platforms.", + reviews: [ + { + text: "Hilarious chaos and addictive gameplay!", + rating: 5, + username: "beanlover", + email: "fallguys@example.com", + latitude: "51.5074", + longitude: "-0.1278", + _id: "671363aaf22203668e1adb8a", + }, + { + text: "Great fun with friends, but needs more content.", + rating: 4, + username: "partygamer", + email: "party@example.com", + latitude: "37.7749", + longitude: "-122.4194", + _id: "671363aaf22203668e1adb8b", + }, + ], + reviewCount: 2, + avgRating: 4.5, + }, + { + _id: "671363aaf22203668e1adb7e", + gameName: "Lost Ark", + gameImage: "https://www.freetogame.com/g/517/thumbnail.jpg", + gameDescription: + "Smilegate’s free-to-play multiplayer ARPG is a massive adventure filled with lands waiting to be explored, people waiting to be met, and an ancient evil waiting to be destroyed.", + reviews: [ + { + text: "Incredible world design and engaging combat!", + rating: 5, + username: "arkexplorer", + email: "lostark@example.com", + latitude: "37.5665", + longitude: "126.9780", + _id: "671363aaf22203668e1adb7f", + }, + { + text: "Fun, but too much grinding.", + rating: 3, + username: "casualgamer", + email: "casual@example.com", + latitude: "40.7128", + longitude: "-74.0060", + _id: "671363aaf22203668e1adb80", + }, + ], + reviewCount: 2, + avgRating: 4, + }, + { + _id: "671363aaf22203668e1adb81", + gameName: "PUBG: BATTLEGROUNDS", + gameImage: "https://www.freetogame.com/g/516/thumbnail.jpg", + gameDescription: + "Get into the action in one of the longest running battle royale games PUBG Battlegrounds.", + reviews: [ + { + text: "Intense matches and satisfying gunplay!", + rating: 4, + username: "pubgplayer", + email: "pubg@example.com", + latitude: "37.7749", + longitude: "-122.4194", + _id: "671363aaf22203668e1adb82", + }, + ], + reviewCount: 1, + avgRating: 4, + }, + { + _id: "671363aaf22203668e1adb79", + gameName: "Overwatch 2", + gameImage: "https://www.freetogame.com/g/540/thumbnail.jpg", + gameDescription: + "A hero-focused first-person team shooter from Blizzard Entertainment.", + reviews: [ + { + text: "Exciting gameplay and diverse characters!", + rating: 5, + username: "overwatchfan", + email: "overwatch@example.com", + latitude: "40.7128", + longitude: "-74.0060", + _id: "671363aaf22203668e1adb7a", + }, + { + text: "Could use more content, but still enjoyable.", + rating: 4, + username: "gamer123", + email: "gamer@example.com", + latitude: "51.5074", + longitude: "-0.1278", + _id: "671363aaf22203668e1adb7b", + }, + ], + reviewCount: 2, + avgRating: 4.5, + }, + ], +}; diff --git a/client/e2e/fixtures/index.ts b/client/e2e/fixtures/index.ts index 23bf351..4598103 100644 --- a/client/e2e/fixtures/index.ts +++ b/client/e2e/fixtures/index.ts @@ -1,5 +1,11 @@ +import createModeratorResponse from "../fixtures/createModerator"; +import gameListResponse from "../fixtures/gameList"; import moderatorExistsResponse from "../fixtures/moderatorExists"; import moderatorNotExistsResponse from "../fixtures/moderatorNotExists"; -import createModerator from "../fixtures/createModerator"; -export { moderatorExistsResponse, moderatorNotExistsResponse, createModerator }; +export { + createModeratorResponse, + gameListResponse, + moderatorExistsResponse, + moderatorNotExistsResponse, +}; diff --git a/client/e2e/support/constants.ts b/client/e2e/support/constants.ts index 1d72ab8..a417caf 100644 --- a/client/e2e/support/constants.ts +++ b/client/e2e/support/constants.ts @@ -6,4 +6,5 @@ export const API_ROUTES = { LOGIN: serverURL("/api/auth/login"), CHECK_MODERATOR: serverURL("/api/auth/check-moderator"), CREATE_MODERATOR: serverURL("/api/auth/create-moderator"), + GAME_LIST: serverURL("/api/review/list-review"), }; diff --git a/client/e2e/tests/home.spec.ts b/client/e2e/tests/home.spec.ts index fbd8bf4..2e141f0 100644 --- a/client/e2e/tests/home.spec.ts +++ b/client/e2e/tests/home.spec.ts @@ -1,27 +1,46 @@ -import { test, expect } from "@playwright/test"; +import { expect, test } from "@playwright/test"; +import { gameListResponse } from "../fixtures"; +import { API_ROUTES } from "../support/constants"; + +test("Home page: Rendered successfully and show hero text", async ({ + page, +}) => { + await page.route(API_ROUTES.GAME_LIST, async (route) => { + await route.fulfill({ json: { data: [] } }); + }); -test("Home page rendered successfully", async ({ page }) => { await page.goto("/"); await expect( page.locator("text=Find your next captivating gaming moment") ).toBeVisible(); }); +test("Game List: No games found", async ({ page }) => { + await page.route(API_ROUTES.GAME_LIST, async (route) => { + await route.fulfill({ json: { data: [] } }); + }); + + await page.goto("/"); + await expect(page.locator("text=No game listed")).toBeVisible(); + await expect(page.locator("text=Only Moderator can list game")).toBeVisible(); +}); + test("Game List: should display game cards with images, titles, and review counts", async ({ page, }) => { + await page.route(API_ROUTES.GAME_LIST, async (route) => { + await route.fulfill({ json: gameListResponse }); + }); + await page.goto("/"); - // Check that the grid exists await expect(page.locator(".grid")).toBeVisible(); const gameCards = page.locator(".grid .col-span-1"); const cardCount = await gameCards.count(); // Get the number of game cards - // Check if the count is greater than 1 expect(cardCount).toBeGreaterThan(1); - // Check the first game card const firstGameCard = gameCards.first(); await expect(firstGameCard.locator("img")).toHaveAttribute( "src", @@ -32,7 +51,6 @@ test("Game List: should display game cards with images, titles, and review count /Game Image/ ); - // Check game card details await expect(firstGameCard.locator("p.text-lg")).toBeVisible(); await expect(firstGameCard.locator("p.text-lg")).not.toBeEmpty(); diff --git a/client/e2e/tests/login.spec.ts b/client/e2e/tests/login.spec.ts index 7ea1cbc..b6afcc1 100644 --- a/client/e2e/tests/login.spec.ts +++ b/client/e2e/tests/login.spec.ts @@ -1,37 +1,37 @@ -import { expect, Page, test } from "@playwright/test"; -import { API_ROUTES } from "../support/constants"; +import { expect, test } from "@playwright/test"; import { + createModeratorResponse, moderatorExistsResponse, moderatorNotExistsResponse, } from "../fixtures"; +import { API_ROUTES } from "../support/constants"; -export const interceptCheckModerator = async (page: Page, json: any) => { +test("login page rendered successfully", async ({ page }) => { await page.route(API_ROUTES.CHECK_MODERATOR, async (route) => { - const response = await route.fetch(); - await route.fulfill({ - response, - json, - }); + await route.fulfill({ json: moderatorExistsResponse }); }); await page.goto("/login"); -}; -test("login page rendered successfully", async ({ page }) => { - interceptCheckModerator(page, moderatorExistsResponse); - await page.waitForResponse(API_ROUTES.CHECK_MODERATOR); await expect(page.locator('role=button[name="Login"]')).toBeVisible(); }); test("create moderator page rendered successfully", async ({ page }) => { - interceptCheckModerator(page, moderatorNotExistsResponse); - await page.waitForResponse(API_ROUTES.CHECK_MODERATOR); + await page.route(API_ROUTES.CHECK_MODERATOR, async (route) => { + await route.fulfill({ json: moderatorNotExistsResponse }); + }); + + await page.goto("/login"); + await expect(page.locator('role=button[name="Create"]')).toBeVisible(); }); test("login validations", async ({ page }) => { - interceptCheckModerator(page, moderatorExistsResponse); - await page.waitForResponse(API_ROUTES.CHECK_MODERATOR); + await page.route(API_ROUTES.CHECK_MODERATOR, async (route) => { + await route.fulfill({ json: moderatorExistsResponse }); + }); + + await page.goto("/login"); await page.click("button"); await expect(page.locator("text=Invalid email address")).toBeVisible(); @@ -41,8 +41,11 @@ test("login validations", async ({ page }) => { }); test("create moderator validations", async ({ page }) => { - interceptCheckModerator(page, moderatorNotExistsResponse); - await page.waitForResponse(API_ROUTES.CHECK_MODERATOR); + await page.route(API_ROUTES.CHECK_MODERATOR, async (route) => { + await route.fulfill({ json: moderatorNotExistsResponse }); + }); + + await page.goto("/login"); await page.click("button"); await expect(page.locator("text=Invalid email address")).toBeVisible(); @@ -53,6 +56,10 @@ test("create moderator validations", async ({ page }) => { }); test("should toggle the password visibility", async ({ page }) => { + await page.route(API_ROUTES.CHECK_MODERATOR, async (route) => { + await route.fulfill({ json: moderatorNotExistsResponse }); + }); + await page.goto("/login"); await page.fill('input[placeholder="Password"]', "password123"); @@ -71,61 +78,50 @@ test("should toggle the password visibility", async ({ page }) => { ); }); -// test("should create an account for new users", async ({ page }) => { -// await interceptCheckModerator(page, "moderatorNotExists.json"); - -// await page.route(API_ROUTES.CREATE_MODERATOR, (route) => -// route.fulfill({ -// status: 200, -// body: JSON.stringify({ -// success: true, -// message: "Moderator created! Please login!", -// }), -// }) -// ); - -// const response = await page.waitForResponse(API_ROUTES.CHECK_MODERATOR); -// const data = await response.json(); -// const userExists = data.userExists; - -// if (!userExists) { -// await expect(page.locator("text=Create Account")).toBeVisible(); -// await page.fill('input[placeholder="Name"]', "John Doe"); -// await page.fill('input[placeholder="Email"]', "john@example.com"); -// await page.fill('input[placeholder="Password"]', "password123"); -// await page.click("button"); - -// const createModeratorResponse = await page.waitForResponse( -// API_ROUTES.CREATE_MODERATOR -// ); -// const createModeratorData = await createModeratorResponse.json(); - -// expect(createModeratorData.success).toBeTruthy(); -// await expect( -// page.locator("text=Moderator created! Please login!") -// ).toBeVisible(); -// } -// }); - -// test("should login an existing user", async ({ page }) => { -// await interceptCheckModerator(page, "moderatorExists.json"); - -// await page.route(API_ROUTES.LOGIN, (route) => -// route.fulfill({ -// status: 200, -// body: JSON.stringify({ token: "mockToken" }), -// }) -// ); - -// await page.fill('input[placeholder="Email"]', "john@example.com"); -// await page.fill('input[placeholder="Password"]', "password123"); -// await page.click("button"); - -// const loginResponse = await page.waitForResponse(API_ROUTES.LOGIN); -// const loginData = await loginResponse.json(); - -// expect(loginData.token).toBe("mockToken"); -// await expect(page.locator("text=Login successfully")).toBeVisible(); - -// await expect(page).toHaveURL("/admin"); -// }); +test("should create an account for new users", async ({ page }) => { + await page.route(API_ROUTES.CHECK_MODERATOR, async (route) => { + await route.fulfill({ json: moderatorNotExistsResponse }); + }); + + await page.goto("/login"); + + await expect(page.locator("text=Create Account")).toBeVisible(); + + await page.fill('input[placeholder="Name"]', "John Doe"); + await page.fill('input[placeholder="Email"]', "john@example.com"); + await page.fill('input[placeholder="Password"]', "password123"); + + await page.route(API_ROUTES.CREATE_MODERATOR, async (route) => { + await route.fulfill({ json: createModeratorResponse }); + }); + + await page.click("button"); + + await expect( + page.locator("text=Moderator created! Please login!") + ).toBeVisible(); +}); + +test("should login an existing user", async ({ page }) => { + await page.route(API_ROUTES.CHECK_MODERATOR, async (route) => { + await route.fulfill({ json: moderatorExistsResponse }); + }); + + await page.goto("/login"); + + await page.fill('input[placeholder="Email"]', "john@example.com"); + await page.fill('input[placeholder="Password"]', "password123"); + + await page.route(API_ROUTES.LOGIN, async (route) => { + await route.fulfill({ + json: { + token: "mockToken", + }, + }); + }); + + await page.click("button"); + + await expect(page.locator("text=Login successfully")).toBeVisible(); + await expect(page).toHaveURL("/admin"); +});