diff --git a/apps/web/playwright/insights.e2e.ts b/apps/web/playwright/insights.e2e.ts new file mode 100644 index 0000000000..bcf0a71b53 --- /dev/null +++ b/apps/web/playwright/insights.e2e.ts @@ -0,0 +1,239 @@ +import { expect } from "@playwright/test"; + +import { randomString } from "@calcom/lib/random"; +import prisma from "@calcom/prisma"; + +import { test } from "./lib/fixtures"; + +test.describe.configure({ mode: "parallel" }); + +const createTeamsAndMembership = async (userIdOne: number, userIdTwo: number) => { + const teamOne = await prisma.team.create({ + data: { + name: "test-insights", + slug: `test-insights-${Date.now()}-${randomString(5)}}`, + }, + }); + + const teamTwo = await prisma.team.create({ + data: { + name: "test-insights-2", + slug: `test-insights-2-${Date.now()}-${randomString(5)}}`, + }, + }); + if (!userIdOne || !userIdTwo || !teamOne || !teamTwo) { + throw new Error("Failed to create test data"); + } + + // create memberships + await prisma.membership.create({ + data: { + userId: userIdOne, + teamId: teamOne.id, + accepted: true, + role: "ADMIN", + }, + }); + await prisma.membership.create({ + data: { + teamId: teamTwo.id, + userId: userIdOne, + accepted: true, + role: "ADMIN", + }, + }); + await prisma.membership.create({ + data: { + teamId: teamOne.id, + userId: userIdTwo, + accepted: true, + role: "MEMBER", + }, + }); + await prisma.membership.create({ + data: { + teamId: teamTwo.id, + userId: userIdTwo, + accepted: true, + role: "MEMBER", + }, + }); + return { teamOne, teamTwo }; +}; + +test.afterAll(async ({ users }) => { + await users.deleteAll(); +}); + +test.describe("Insights", async () => { + test("should be able to go to insights as admins", async ({ page, users }) => { + const user = await users.create(); + const userTwo = await users.create(); + await createTeamsAndMembership(user.id, userTwo.id); + + await user.apiLogin(); + + // go to insights page + await page.goto("/insights"); + await page.waitForLoadState("networkidle"); + + // expect url to have isAll and TeamId in query params + expect(page.url()).toContain("isAll=false"); + expect(page.url()).toContain("teamId="); + }); + + test("should be able to go to insights as members", async ({ page, users }) => { + const user = await users.create(); + const userTwo = await users.create(); + + await userTwo.apiLogin(); + + await createTeamsAndMembership(user.id, userTwo.id); + // go to insights page + await page.goto("/insights"); + + await page.waitForLoadState("networkidle"); + + // expect url to have isAll and TeamId in query params + + expect(page.url()).toContain("isAll=false"); + expect(page.url()).not.toContain("teamId="); + }); + + test("team select filter should have 2 teams and your account option only as member", async ({ + page, + users, + }) => { + const user = await users.create(); + const userTwo = await users.create(); + + await user.apiLogin(); + + await createTeamsAndMembership(user.id, userTwo.id); + // go to insights page + await page.goto("/insights"); + + await page.waitForLoadState("networkidle"); + + // get div from team select filter with this class flex flex-col gap-0.5 [&>*:first-child]:mt-1 [&>*:last-child]:mb-1 + await page.getByTestId("dashboard-shell").getByText("Team: test-insights").click(); + await page + .locator('div[class="flex flex-col gap-0.5 [&>*:first-child]:mt-1 [&>*:last-child]:mb-1"]') + .click(); + const teamSelectFilter = await page.locator( + 'div[class="hover:bg-muted flex items-center py-2 pl-3 pr-2.5 hover:cursor-pointer"]' + ); + + await expect(teamSelectFilter).toHaveCount(3); + }); + + test("Insights Organization should have isAll option true", async ({ users, page }) => { + const owner = await users.create(undefined, { + hasTeam: true, + isUnpublished: true, + isOrg: true, + hasSubteam: true, + }); + await owner.apiLogin(); + + await page.goto("/insights"); + await page.waitForLoadState("networkidle"); + + await page.getByTestId("dashboard-shell").getByText("All").nth(1).click(); + + const teamSelectFilter = await page.locator( + 'div[class="hover:bg-muted flex items-center py-2 pl-3 pr-2.5 hover:cursor-pointer"]' + ); + + await expect(teamSelectFilter).toHaveCount(4); + }); + + test("should have all option in team-and-self filter as admin", async ({ page, users }) => { + const owner = await users.create(); + const member = await users.create(); + + await createTeamsAndMembership(owner.id, member.id); + + await owner.apiLogin(); + + await page.goto("/insights"); + + // get div from team select filter with this class flex flex-col gap-0.5 [&>*:first-child]:mt-1 [&>*:last-child]:mb-1 + await page.getByTestId("dashboard-shell").getByText("Team: test-insights").click(); + await page + .locator('div[class="flex flex-col gap-0.5 [&>*:first-child]:mt-1 [&>*:last-child]:mb-1"]') + .click(); + const teamSelectFilter = await page.locator( + 'div[class="hover:bg-muted flex items-center py-2 pl-3 pr-2.5 hover:cursor-pointer"]' + ); + + await expect(teamSelectFilter).toHaveCount(3); + }); + + test("should be able to switch between teams and self profile for insights", async ({ page, users }) => { + const owner = await users.create(); + const member = await users.create(); + + await createTeamsAndMembership(owner.id, member.id); + + await owner.apiLogin(); + + await page.goto("/insights"); + + // get div from team select filter with this class flex flex-col gap-0.5 [&>*:first-child]:mt-1 [&>*:last-child]:mb-1 + await page.getByTestId("dashboard-shell").getByText("Team: test-insights").click(); + await page + .locator('div[class="flex flex-col gap-0.5 [&>*:first-child]:mt-1 [&>*:last-child]:mb-1"]') + .click(); + const teamSelectFilter = await page.locator( + 'div[class="hover:bg-muted flex items-center py-2 pl-3 pr-2.5 hover:cursor-pointer"]' + ); + + await expect(teamSelectFilter).toHaveCount(3); + + // switch to self profile + await page.getByTestId("dashboard-shell").getByText("Your Account").click(); + + // switch to team 1 + await page.getByTestId("dashboard-shell").getByText("test-insights").nth(0).click(); + + // switch to team 2 + await page.getByTestId("dashboard-shell").getByText("test-insights-2").click(); + }); + + test("should be able to switch between memberUsers", async ({ page, users }) => { + const owner = await users.create(); + const member = await users.create(); + + await createTeamsAndMembership(owner.id, member.id); + + await owner.apiLogin(); + + await page.goto("/insights"); + + await page.getByText("Add filter").click(); + + await page.getByRole("button", { name: "User" }).click(); + //