Skip to content

Commit

Permalink
feat(e2e): add e2e tests for team management
Browse files Browse the repository at this point in the history
  • Loading branch information
Matej Tarca authored and matejtarca committed Oct 28, 2023
1 parent 3109cf0 commit be685b7
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 10 deletions.
16 changes: 12 additions & 4 deletions e2e/applicationForm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ test.describe("application form", () => {
await page
.getByLabel("Label")
.fill("What is your experience with hackathons?");
await page.getByLabel("Name (has to be unique across the form)").fill("experience");
await page
.getByLabel("Name (has to be unique across the form)")
.fill("experience");
await page.getByText("Select a field type").click();
await page.getByLabel("textarea").getByText("textarea").click();
await page.getByLabel("Required").check();
Expand All @@ -74,7 +76,9 @@ test.describe("application form", () => {
await page
.getByLabel("Label")
.fill("I have been at the hackathon in the past.");
await page.getByLabel("Name (has to be unique across the form)").fill("hackathonsPast");
await page
.getByLabel("Name (has to be unique across the form)")
.fill("hackathonsPast");
await page.getByText("Select a field type").click();
await page.getByLabel("checkbox").getByText("checkbox").click();
await page.getByRole("button", { name: "Save new field" }).click();
Expand All @@ -85,7 +89,9 @@ test.describe("application form", () => {

await page.getByRole("button", { name: "Create new field" }).click();
await page.getByLabel("Label").fill("What company do you work for?");
await page.getByLabel("Name (has to be unique across the form)").fill("company");
await page
.getByLabel("Name (has to be unique across the form)")
.fill("company");
await page.getByText("Select a field type").click();
await page.getByLabel("text", { exact: true }).getByText("text").click();
await page.getByRole("button", { name: "Save new field" }).click();
Expand All @@ -107,7 +113,9 @@ test.describe("application form", () => {
await page
.getByLabel("Label")
.fill("I have been at the hackathon in the past.");
await page.getByLabel("Name (has to be unique across the form)").fill("hackathonsPast");
await page
.getByLabel("Name (has to be unique across the form)")
.fill("hackathonsPast");
await page.getByText("Select a field type").click();
await page.getByLabel("checkbox").getByText("checkbox").click();
await page.getByRole("button", { name: "Save new field" }).click();
Expand Down
19 changes: 14 additions & 5 deletions e2e/fixtures/ApplicationPage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Page, Locator } from "@playwright/test";
import { expect } from "@playwright/test";
import type { Page } from "@playwright/test";

export class ApplicationPage {
constructor(public readonly page: Page) {}
Expand All @@ -8,11 +7,21 @@ export class ApplicationPage {
await this.page.goto("/");
}

async openSignedIn() {
async openSignedIn(
{ hackerIndex }: { hackerIndex: number } = { hackerIndex: 1 }
) {
await this.page.getByRole("link", { name: "Sign in" }).click();

await this.page.fill('input[name="email"]', "[email protected]");
await this.page.fill('input[name="password"]', "test123");
if (hackerIndex > 1) {
await this.page.fill(
'input[name="email"]',
`test-hacker-${hackerIndex}@test.com`
);
await this.page.fill('input[name="password"]', "test123");
} else {
await this.page.fill('input[name="email"]', "[email protected]");
await this.page.fill('input[name="password"]', "test123");
}

await this.page.getByRole("button", { name: /^Sign in$/ }).click();
}
Expand Down
36 changes: 35 additions & 1 deletion e2e/helpers/prepareDBBeforeTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ async function clearDb(prisma: PrismaClient) {
await prisma.formField.deleteMany();
await prisma.applicationFormStep.deleteMany();
await prisma.application.deleteMany();
await prisma.team.deleteMany();
await prisma.hacker.deleteMany();
await prisma.organizer.deleteMany();
await prisma.user.deleteMany();
Expand All @@ -16,7 +17,15 @@ async function clearDb(prisma: PrismaClient) {
await prisma.optionList.deleteMany();
}

export async function main(prisma: PrismaClient) {
type Options = {
numberOfHackers?: number;
};
export async function main(
prisma: PrismaClient,
options: Options = {
numberOfHackers: 1,
}
) {
await clearDb(prisma);

const { id: hackathonId } = await prisma.hackathon.create({
Expand Down Expand Up @@ -51,6 +60,31 @@ export async function main(prisma: PrismaClient) {
},
});

if (options.numberOfHackers && options.numberOfHackers > 1) {
for (let i = 0; i < options.numberOfHackers - 1; i++) {
const { id: userId } = await prisma.user.create({
data: {
email: `test-hacker-${i + 2}@test.com`,
password: await hash("test123"),
},
});

const { id: hackerId } = await prisma.hacker.create({
data: {
userId,
hackathonId,
},
});

await prisma.application.create({
data: {
hackerId,
statusId: 1,
},
});
}
}

const { id: userOrganizerId } = await prisma.user.create({
data: {
email: "[email protected]",
Expand Down
203 changes: 203 additions & 0 deletions e2e/team.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
import { test, expect } from "./fixtures/custom-test";
import { PrismaClient } from "@prisma/client";
import prepareDBBeforeTest from "./helpers/prepareDBBeforeTest";

let teamCode = "";

test.describe("Team", () => {
test.describe.configure({ mode: "serial" });

test.beforeAll(async () => {
const prisma = new PrismaClient();

await prepareDBBeforeTest(prisma, {
numberOfHackers: 2,
});

await prisma.$disconnect();
});

test("unsigned user cannot create a team", async ({
page,
applicationPage,
}) => {
await applicationPage.openUnsigned();

await expect(page.getByText("Your team")).toBeVisible();
await expect(
page.getByText("You can create or join teams after you sign in")
).toBeVisible();
await expect(
page.getByRole("button", { name: "Create new team" })
).not.toBeVisible();

await expect(
page.getByRole("button", { name: "Join existing team" })
).not.toBeVisible();
});

test("signed in hacker can create a team", async ({
page,
applicationPage,
}) => {
await applicationPage.openSignedIn();

await expect(page.getByText("Your team")).toBeVisible();
await expect(
page.getByRole("button", { name: "Create new team" })
).toBeVisible();
await expect(
page.getByRole("button", { name: "Join existing team" })
).toBeVisible();

await page.getByRole("button", { name: "Create new team" }).click();

await expect(
page.getByRole("heading", { name: "Create new team" })
).toBeVisible();
await page.getByLabel("Team name").fill("Best team");
await page.getByRole("button", { name: "Create" }).click();

await expect(page.getByText("Team name:")).toBeVisible();
await expect(page.getByText("Best team")).toBeVisible();
await expect(page.getByText("Team members (1/4):")).toBeVisible();
await expect(page.getByText("[email protected] (owner)")).toBeVisible();
await expect(
page.getByRole("button", { name: "Leave team" })
).not.toBeVisible();

// Editing team name
await page.getByRole("button", { name: "Edit team name" }).click();
await expect(
page.getByRole("heading", { name: "Edit team name" })
).toBeVisible();
await expect(page.getByLabel("Team name", { exact: true })).toHaveValue(
"Best team"
);
await page.getByLabel("Team name", { exact: true }).fill("Test team");
await page.getByRole("button", { name: "Save" }).click();

await expect(page.getByText("Team name:")).toBeVisible();
await expect(page.getByText("Test team")).toBeVisible();
await expect(page.getByText("Best team")).not.toBeVisible();

// Copying team code
await page.getByRole("button", { name: "Copy team code" }).click();
teamCode = await page.evaluate("navigator.clipboard.readText()");
expect(teamCode).not.toBe("");
});

test("signed in hacker can join a team", async ({
page,
applicationPage,
}) => {
await applicationPage.openSignedIn({ hackerIndex: 2 });

await expect(page.getByText("Your team")).toBeVisible();
await expect(
page.getByRole("button", { name: "Join existing team" })
).toBeVisible();

await page.getByRole("button", { name: "Join existing team" }).click();

await expect(
page.getByRole("heading", { name: "Join existing team" })
).toBeVisible();
await page.getByLabel("Team code").fill(teamCode);
await page.getByRole("button", { name: "Join" }).click();

await expect(page.getByText("Team name:")).toBeVisible();
await expect(page.getByText("Test team")).toBeVisible();
await expect(page.getByText("Team members (2/4):")).toBeVisible();
await expect(
page.getByRole("button", { name: "Leave team" })
).toBeVisible();
await expect(page.getByText("[email protected] (owner)")).toBeVisible();
await expect(page.getByText("[email protected]")).toBeVisible();
await expect(page.getByText("Kick")).not.toBeVisible();
});

test("owner can kick a team member", async ({ page, applicationPage }) => {
await applicationPage.openSignedIn();

await expect(page.getByText("Team members (2/4):")).toBeVisible();
await expect(page.getByText("[email protected]")).toBeVisible();

await page.getByRole("button", { name: "Kick" }).click();
await expect(
page.getByText("Are you sure you want to kick [email protected]?")
).toBeVisible();
await page.getByRole("button", { name: "No" }).click();

await expect(
page.getByText("Are you sure you want to kick [email protected]?")
).not.toBeVisible();

await expect(page.getByText("Team members (2/4):")).toBeVisible();
await expect(page.getByText("[email protected]")).toBeVisible();

await page.getByRole("button", { name: "Kick" }).click();
await expect(
page.getByText("Are you sure you want to kick [email protected]?")
).toBeVisible();
await page.getByRole("button", { name: "Yes" }).click();

await expect(page.getByText("Team members (1/4):")).toBeVisible();
await expect(page.getByText("[email protected]")).not.toBeVisible();
});

test("member can leave a team", async ({ page, applicationPage }) => {
await applicationPage.openSignedIn({ hackerIndex: 2 });

await page.getByRole("button", { name: "Join existing team" }).click();
await page.getByLabel("Team code").fill(teamCode);
await page.getByRole("button", { name: "Join" }).click();

await expect(page.getByText("Test team")).toBeVisible();

await page.getByRole("button", { name: "Leave team" }).click();
await expect(
page.getByText("Are you sure you want to leave this team?")
).toBeVisible();
await page.getByRole("button", { name: "No" }).click();

await expect(page.getByText("Test team")).toBeVisible();

await page.getByRole("button", { name: "Leave team" }).click();
await expect(
page.getByText("Are you sure you want to leave this team?")
).toBeVisible();
await page.getByRole("button", { name: "Yes" }).click();

await expect(page.getByText("Test team")).not.toBeVisible();
await expect(
page.getByRole("button", { name: "Join existing team" })
).toBeVisible();
});

test("hacker can join a team after submitting application", async ({
page,
applicationPage,
}) => {
await applicationPage.openSignedIn({ hackerIndex: 2 });

await expect(page.getByText("Application status: open")).toBeVisible();

await page.getByText("General info").click();
await expect(
page.getByRole("heading", { name: "General info" })
).toBeVisible();
await page.getByLabel("Full name").fill("Test Hacker 2");
await page.getByRole("button", { name: "Save" }).click();

await page.getByRole("button", { name: "Submit application" }).click();
await page.getByRole("button", { name: "Yes" }).click();
await expect(page.getByText("Application status: submitted")).toBeVisible();

await page.getByRole("button", { name: "Join existing team" }).click();
await page.getByLabel("Team code").fill(teamCode);
await page.getByRole("button", { name: "Join" }).click();

await expect(page.getByText("Test team")).toBeVisible();
});
});
1 change: 1 addition & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export default defineConfig({

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "retry-with-trace",
permissions: ["clipboard-read", "clipboard-write"],
},

/* Configure projects for major browsers */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ const TeamInfo = ({
}}
variant="ghost"
size="icon"
aria-label="Copy team code"
>
<DocumentDuplicateIcon className="w-4 h-4 mr-1 inline" />
</Button>
Expand Down

0 comments on commit be685b7

Please sign in to comment.