Skip to content
This repository has been archived by the owner on Jul 24, 2023. It is now read-only.

Commit

Permalink
Merge pull request #173 from ictsc/feature/add_e2e_test
Browse files Browse the repository at this point in the history
add: playwright を導入 / add: index と navbar のテストを追加
  • Loading branch information
K-shir0 committed Jul 2, 2023
2 parents 21a745f + 9156efd commit f60774f
Show file tree
Hide file tree
Showing 26 changed files with 545 additions and 146 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
// devDependenciesのimportを禁止
"optionalDependencies": false
}
]
],
"no-unused-vars": "off"
},
"env": {
"jest": true
Expand Down
8 changes: 8 additions & 0 deletions __e2e__/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { test } from "@playwright/test";

import IndexPage from "./pages/Index";

test("画面項目が表示されること", async ({ page }) => {
await IndexPage.goto(page);
await IndexPage.validate(page);
});
156 changes: 156 additions & 0 deletions __e2e__/navbar.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { expect, test } from "@playwright/test";

import IndexPage from "./pages/Index";
import LoginPage from "./pages/login";
import ICTSCNavbar from "./pages/navbar";
import ProblemsPage from "./pages/problems";
import ProfilePage from "./pages/profile";
import RankingPage from "./pages/ranking";
import ScoringPage from "./pages/scoring";
import TeamInfoPage from "./pages/teamInfo";
import UsersPage from "./pages/users";

test.describe("未ログイン状態", () => {
test("ログインページに遷移できる", async ({ page }) => {
// setup
await IndexPage.goto(page);
await IndexPage.validate(page);

// when
await ICTSCNavbar.LoginLink(page).click();

// then
await LoginPage.waitFormSelector(page);
expect(page.url().split("/").pop()).toBe("login");
await LoginPage.validate(page);
});
});

test.describe("ログイン状態", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/login");

await page.fill("#username", "admin");
await page.fill("#password", "password");
await page.click("#loginBtn");

// ログインに成功しましたというアラートが出るまで待つ
await page.waitForURL("/");
// await page.waitForSelector(".alert-success");
});

test("ルールページに遷移できる", async ({ page }) => {
// setup
await IndexPage.goto(page);
await IndexPage.validate(page);

// when
await ICTSCNavbar.RuleLink(page).click();

// then
await IndexPage.waitFormSelector(page);
expect(page.url().split("/").pop()).toBe("");
await IndexPage.validate(page);
});

test("チーム情報ページに遷移できる", async ({ page }) => {
// setup
await IndexPage.goto(page);
await IndexPage.validate(page);

// when
await ICTSCNavbar.TeamInfoLink(page).click();

// then
await TeamInfoPage.waitFormSelector(page);
expect(page.url().split("/").pop()).toBe("team_info");
await TeamInfoPage.validate(page);
});

test("問題ページに遷移できる", async ({ page }) => {
// setup
await IndexPage.goto(page);
await IndexPage.validate(page);

// when
await ICTSCNavbar.ProblemsLink(page).click();

// then
await ProblemsPage.waitFormSelector(page);
expect(page.url().split("/").pop()).toBe("problems");
await ProblemsPage.validate(page);
});

test("順位ページに遷移できる", async ({ page }) => {
// setup
await IndexPage.goto(page);
await IndexPage.validate(page);

// when
await ICTSCNavbar.RankingLink(page).click();

// then
await RankingPage.waitFormSelector(page);
expect(page.url().split("/").pop()).toBe("ranking");
await RankingPage.validate(page);
});

test("参加者ページに遷移できる", async ({ page }) => {
// setup
await IndexPage.goto(page);
await IndexPage.validate(page);

// when
await ICTSCNavbar.UsersLink(page).click();

// then
await UsersPage.waitFormSelector(page);
expect(page.url().split("/").pop()).toBe("users");
await UsersPage.validate(page);
});

test("採点ページに遷移できる", async ({ page }) => {
// setup
await IndexPage.goto(page);
await IndexPage.validate(page);

// when
await ICTSCNavbar.ScoringLink(page).click();

// then
await ScoringPage.waitFormSelector(page);
expect(page.url().split("/").pop()).toBe("scoring");
await ScoringPage.validate(page);
});

test("プロフィールページに遷移できる", async ({ page }) => {
// setup
await IndexPage.goto(page);
await IndexPage.validate(page);
await ICTSCNavbar.DropdownMenu(page).click();

// when
await ICTSCNavbar.ProfileLink(page).click();

// then
await ProfilePage.waitFormSelector(page);
expect(page.url().split("/").pop()).toBe("profile");
await ProfilePage.validate(page);
});

test("ログアウトできる", async ({ page }) => {
// setup
// 初期は problems ページに遷移しておく indexページに設定してしまうと、同じページに遷移するためテストがうまくできない
await ProblemsPage.goto(page);
await ProblemsPage.validate(page);
await ICTSCNavbar.DropdownMenu(page).click();

// when
await ICTSCNavbar.LogoutButton(page).click();

// then
await IndexPage.waitFormSelector(page);
expect(page.url().split("/").pop()).toBe("");
await expect(ICTSCNavbar.LoginLink(page)).toBeVisible();
});
});
17 changes: 17 additions & 0 deletions __e2e__/pages/Index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { expect, Page } from "@playwright/test";

import BasePage from "./page";

const IndexPage: BasePage = {
goto: async (page: Page) => {
await page.goto("/");
},
validate: async (page: Page) => {
await expect(page.locator(".title-ictsc")).toHaveText("ルール");
},
waitFormSelector: async (page: Page) => {
await page.waitForSelector(".title-ictsc >> text=ルール");
},
};

export default IndexPage;
17 changes: 17 additions & 0 deletions __e2e__/pages/login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { expect } from "@playwright/test";

import BasePage from "./page";

const LoginPage: BasePage = {
goto: async (page) => {
await page.goto("/login");
},
validate: async (page) => {
await expect(page.locator(".title-ictsc")).toHaveText("ログイン");
},
waitFormSelector: async (page) => {
await page.waitForSelector(".title-ictsc >> text=ログイン");
},
};

export default LoginPage;
16 changes: 16 additions & 0 deletions __e2e__/pages/navbar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Page } from "@playwright/test";

const ICTSCNavbar = {
RuleLink: (page: Page) => page.locator("a >> text=ルール"),
TeamInfoLink: (page: Page) => page.locator("a >> text=チーム情報"),
ProblemsLink: (page: Page) => page.locator("a >> text=問題"),
RankingLink: (page: Page) => page.locator("a >> text=順位"),
UsersLink: (page: Page) => page.locator("a >> text=参加者"),
ScoringLink: (page: Page) => page.locator("a >> text=採点"),
LoginLink: (page: Page) => page.locator("a >> text=ログイン"),
DropdownMenu: (page: Page) => page.getByText("admin", { exact: true }),
ProfileLink: (page: Page) => page.locator("a >> text=プロフィール"),
LogoutButton: (page: Page) => page.locator("button >> text=ログアウト"),
};

export default ICTSCNavbar;
11 changes: 11 additions & 0 deletions __e2e__/pages/page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Page } from "@playwright/test";

type BasePage = {
goto(page: Page): Promise<void>;

validate(page: Page): Promise<void>;

waitFormSelector(page: Page): Promise<void>;
};

export default BasePage;
17 changes: 17 additions & 0 deletions __e2e__/pages/problems.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { expect } from "@playwright/test";

import BasePage from "./page";

const ProblemsPage: BasePage = {
goto: async (page) => {
await page.goto("/problems");
},
validate: async (page) => {
await expect(page.locator(".title-ictsc")).toHaveText("問題一覧");
},
waitFormSelector: async (page) => {
await page.waitForSelector(".title-ictsc >> text=問題");
},
};

export default ProblemsPage;
17 changes: 17 additions & 0 deletions __e2e__/pages/profile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { expect } from "@playwright/test";

import BasePage from "./page";

const ProfilePage: BasePage = {
goto: async (page) => {
await page.goto("/profile");
},
validate: async (page) => {
await expect(page.locator(".title-ictsc")).toHaveText("プロフィール");
},
waitFormSelector: async (page) => {
await page.waitForSelector(".title-ictsc >> text=プロフィール");
},
};

export default ProfilePage;
17 changes: 17 additions & 0 deletions __e2e__/pages/ranking.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { expect } from "@playwright/test";

import BasePage from "./page";

const RankingPage: BasePage = {
goto: async (page) => {
await page.goto("/ranking");
},
validate: async (page) => {
await expect(page.locator(".title-ictsc")).toHaveText("ランキング");
},
waitFormSelector: async (page) => {
await page.waitForSelector(".title-ictsc >> text=ランキング");
},
};

export default RankingPage;
17 changes: 17 additions & 0 deletions __e2e__/pages/scoring.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { expect } from "@playwright/test";

import BasePage from "./page";

const ScoringPage: BasePage = {
goto: async (page) => {
await page.goto("/scoring");
},
validate: async (page) => {
await expect(page.locator("th:nth-child(1)")).toHaveText("採点");
},
waitFormSelector: async (page) => {
await page.waitForSelector("th >> text=採点");
},
};

export default ScoringPage;
17 changes: 17 additions & 0 deletions __e2e__/pages/teamInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { expect } from "@playwright/test";

import BasePage from "./page";

const TeamInfoPage: BasePage = {
goto: async (page) => {
await page.goto("/team_info");
},
validate: async (page) => {
await expect(page.locator(".title-ictsc")).toHaveText("チーム情報");
},
waitFormSelector: async (page) => {
await page.waitForSelector(".title-ictsc >> text=チーム情報");
},
};

export default TeamInfoPage;
17 changes: 17 additions & 0 deletions __e2e__/pages/users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { expect } from "@playwright/test";

import BasePage from "./page";

const UsersPage: BasePage = {
goto: async (page) => {
await page.goto("/users");
},
validate: async (page) => {
await expect(page.locator(".title-ictsc")).toHaveText("参加者一覧");
},
waitFormSelector: async (page) => {
await page.waitForSelector(".title-ictsc >> text=参加者");
},
};

export default UsersPage;
2 changes: 1 addition & 1 deletion __test__/components/Navbar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ describe("参加者ログイン状態 ICTSCNavBar", () => {
});

// verify
expect(useAuth).toHaveBeenCalledTimes(2);
expect(useAuth).toHaveBeenCalledTimes(1);
expect(logout).toHaveBeenCalledTimes(1);
});
});
Expand Down
8 changes: 5 additions & 3 deletions components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import Link from "next/link";
import { useRouter } from "next/router";

import { mutate } from "swr";

import useAuth from "@/hooks/auth";

function ICTSCNavBar() {
const router = useRouter();

const { user, logout, mutate } = useAuth();
const { user, logout } = useAuth();

const handleLogout = async () => {
const response = await logout();

if (response.status === 200) {
await mutate();
if (response.code === 200) {
await mutate(() => true, undefined, { revalidate: true });
await router.push("/");
}
};
Expand Down
6 changes: 3 additions & 3 deletions hooks/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ const useApi = () => {
get: <T>(url: string) =>
apiClient.get<Result<T>>(url).then((response) => response.data),
post: (url: string, data?: any) =>
apiClient.post(url, data).then((response) => response.data),
apiClient.post<Result<any>>(url, data).then((response) => response.data),
put: (url: string, data?: any) =>
apiClient.put(url, data).then((response) => response.data),
apiClient.put<Result<any>>(url, data).then((response) => response.data),
patch: <T>(url: string, data?: any) =>
apiClient.patch<Result<T>>(url, data).then((response) => response.data),
delete: (url: string) =>
apiClient.delete(url).then((response) => response.data),
apiClient.delete<Result<any>>(url).then((response) => response.data),
};

return { client };
Expand Down
Loading

0 comments on commit f60774f

Please sign in to comment.