test: add e2e tests for team filter in bookings list (#27144)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Keith Williams
2026-01-22 12:12:02 -03:00
committed by GitHub
co-authored by Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent dc4404f88c
commit a2a4ca41ec
+183 -4
View File
@@ -1,9 +1,7 @@
import { expect } from "@playwright/test";
import type { Page } from "@playwright/test";
import { prisma } from "@calcom/prisma";
import { BookingStatus, MembershipRole, SchedulingType } from "@calcom/prisma/enums";
import type { Page } from "@playwright/test";
import { expect } from "@playwright/test";
import { addFilter } from "./filter-helpers";
import { createTeamEventType } from "./fixtures/users";
import type { Fixtures } from "./lib/fixtures";
@@ -567,6 +565,187 @@ test.describe("Bookings", () => {
}
});
});
test.describe("Team filter", () => {
test("Team filter shows bookings for direct team event types", async ({ page, users, bookings }) => {
const owner = await users.create(
{ name: "Team Owner" },
{
hasTeam: true,
teamRole: MembershipRole.OWNER,
}
);
const { team } = await owner.getFirstTeamMembership();
const teamEvent = await owner.getFirstTeamEvent(team.id);
const teamBookingFixture = await createBooking({
title: "Team Event Booking",
bookingsFixture: bookings,
relativeDate: 5,
organizer: owner,
organizerEventType: teamEvent,
attendees: [{ name: "Test Attendee", email: "attendee@example.com", timeZone: "Europe/Berlin" }],
});
const teamBooking = await teamBookingFixture.self();
const personalBookingFixture = await createBooking({
title: "Personal Event Booking",
bookingsFixture: bookings,
relativeDate: 4,
organizer: owner,
organizerEventType: owner.eventTypes[0],
attendees: [{ name: "Personal Attendee", email: "personal@example.com", timeZone: "Europe/Berlin" }],
});
await personalBookingFixture.self();
await owner.apiLogin();
const bookingsGetResponse = page.waitForResponse((response) =>
/\/api\/trpc\/bookings\/get.*/.test(response.url())
);
await page.goto(`/bookings/upcoming`, { waitUntil: "domcontentloaded" });
await bookingsGetResponse;
await addFilter(page, "teamId");
const bookingsGetResponse2 = page.waitForResponse(
(response) => response.url().includes("/api/trpc/bookings/get?batch=1") && response.status() === 200
);
await page.locator(`[data-testid="select-filter-options-teamId"] [role="option"]`).first().click();
await bookingsGetResponse2;
const upcomingBookingsTable = page.locator('[data-testid="upcoming-bookings"]');
const bookingListItems = upcomingBookingsTable.locator('[data-testid="booking-item"]');
const bookingListCount = await bookingListItems.count();
expect(bookingListCount).toBe(1);
await expect(bookingListItems.first().locator(`text=${teamBooking!.title}`)).toBeVisible();
});
test("Team filter shows bookings for managed event types (child events)", async ({
page,
users,
bookings,
}) => {
const { adminUser, memberUser } = await setupManagedEvent({ users });
const memberManagedEvent = await memberUser.getFirstEventAsOwner();
const managedEventBookingFixture = await createBooking({
title: "Managed Event Booking",
bookingsFixture: bookings,
relativeDate: 5,
organizer: memberUser,
organizerEventType: memberManagedEvent,
attendees: [{ name: "Managed Attendee", email: "managed@example.com", timeZone: "Europe/Berlin" }],
});
const managedEventBooking = await managedEventBookingFixture.self();
const personalBookingFixture = await createBooking({
title: "Personal Event Booking",
bookingsFixture: bookings,
relativeDate: 4,
organizer: adminUser,
organizerEventType: adminUser.eventTypes[0],
attendees: [{ name: "Personal Attendee", email: "personal@example.com", timeZone: "Europe/Berlin" }],
});
await personalBookingFixture.self();
await adminUser.apiLogin();
const bookingsGetResponse = page.waitForResponse((response) =>
/\/api\/trpc\/bookings\/get.*/.test(response.url())
);
await page.goto(`/bookings/upcoming`, { waitUntil: "domcontentloaded" });
await bookingsGetResponse;
await addFilter(page, "teamId");
const bookingsGetResponse2 = page.waitForResponse(
(response) => response.url().includes("/api/trpc/bookings/get?batch=1") && response.status() === 200
);
await page.locator(`[data-testid="select-filter-options-teamId"] [role="option"]`).first().click();
await bookingsGetResponse2;
const upcomingBookingsTable = page.locator('[data-testid="upcoming-bookings"]');
const bookingListItems = upcomingBookingsTable.locator('[data-testid="booking-item"]');
const bookingListCount = await bookingListItems.count();
expect(bookingListCount).toBe(1);
await expect(bookingListItems.first().locator(`text=${managedEventBooking!.title}`)).toBeVisible();
});
test("Team filter excludes bookings from other teams", async ({ page, users, bookings }) => {
const owner = await users.create(
{ name: "Multi-Team Owner" },
{
hasTeam: true,
numberOfTeams: 2,
teamRole: MembershipRole.OWNER,
}
);
const memberships = await prisma.membership.findMany({
where: { userId: owner.id },
include: { team: true },
orderBy: { teamId: "asc" },
});
const team1 = memberships[0].team;
const team2 = memberships[1].team;
const team1Event = await createTeamEventType(
{ id: owner.id },
{ id: team1.id },
{ teamEventSlug: "team1-event" }
);
const team2Event = await createTeamEventType(
{ id: owner.id },
{ id: team2.id },
{ teamEventSlug: "team2-event" }
);
const team1BookingFixture = await createBooking({
title: "Team 1 Booking",
bookingsFixture: bookings,
relativeDate: 5,
organizer: owner,
organizerEventType: team1Event,
attendees: [{ name: "Team1 Attendee", email: "team1@example.com", timeZone: "Europe/Berlin" }],
});
await team1BookingFixture.self();
const team2BookingFixture = await createBooking({
title: "Team 2 Booking",
bookingsFixture: bookings,
relativeDate: 4,
organizer: owner,
organizerEventType: team2Event,
attendees: [{ name: "Team2 Attendee", email: "team2@example.com", timeZone: "Europe/Berlin" }],
});
await team2BookingFixture.self();
await owner.apiLogin();
const bookingsGetResponse = page.waitForResponse((response) =>
/\/api\/trpc\/bookings\/get.*/.test(response.url())
);
await page.goto(`/bookings/upcoming`, { waitUntil: "domcontentloaded" });
await bookingsGetResponse;
await addFilter(page, "teamId");
const bookingsGetResponse2 = page.waitForResponse(
(response) => response.url().includes("/api/trpc/bookings/get?batch=1") && response.status() === 200
);
await page.locator(`[data-testid="select-filter-options-teamId"] [role="option"]`).first().click();
await bookingsGetResponse2;
const upcomingBookingsTable = page.locator('[data-testid="upcoming-bookings"]');
const bookingListItems = upcomingBookingsTable.locator('[data-testid="booking-item"]');
const bookingListCount = await bookingListItems.count();
expect(bookingListCount).toBe(1);
});
});
});
async function createBooking({