diff --git a/apps/web/playwright/bookings-list.e2e.ts b/apps/web/playwright/bookings-list.e2e.ts index d5a3b70637..7c4e645c5f 100644 --- a/apps/web/playwright/bookings-list.e2e.ts +++ b/apps/web/playwright/bookings-list.e2e.ts @@ -1,4 +1,5 @@ import { expect } from "@playwright/test"; +import type { Page } from "@playwright/test"; import prisma from "@calcom/prisma"; import { BookingStatus } from "@calcom/prisma/client"; @@ -72,7 +73,7 @@ test.describe("Bookings", () => { const bookingsGetResponse = page.waitForResponse((response) => /\/api\/trpc\/bookings\/get.*/.test(response.url()) ); - await page.goto(`/bookings/upcoming`); + await page.goto(`/bookings/upcoming`, { waitUntil: "domcontentloaded" }); await bookingsGetResponse; await page.locator('[data-testid="add-filter-button"]').click(); @@ -350,7 +351,7 @@ test.describe("Bookings", () => { const bookingsGetResponse = page.waitForResponse((response) => /\/api\/trpc\/bookings\/get.*/.test(response.url()) ); - await page.goto(`/bookings/upcoming`); + await page.goto(`/bookings/upcoming`, { waitUntil: "domcontentloaded" }); await bookingsGetResponse; await page.locator('[data-testid="add-filter-button"]').click(); @@ -457,7 +458,7 @@ test.describe("Bookings", () => { const bookingsGetResponse1 = page.waitForResponse((response) => /\/api\/trpc\/bookings\/get.*/.test(response.url()) ); - await page.goto("/bookings/upcoming"); + await page.goto("/bookings/upcoming", { waitUntil: "domcontentloaded" }); await bookingsGetResponse1; await page.locator('[data-testid="add-filter-button"]').click(); @@ -470,6 +471,95 @@ test.describe("Bookings", () => { await expect(page.locator('[data-testid="booking-item"]')).toHaveCount(0); }); + + test.describe("Filter Dropdown Item Search", () => { + const filterItemsConfig = [ + { key: "eventTypeId", name: "Event Type", testId: "add-filter-item-eventTypeId" }, + { key: "teamId", name: "Team", testId: "add-filter-item-teamId" }, + { key: "userId", name: "Member", testId: "add-filter-item-userId" }, + { key: "attendeeName", name: "Attendees Name", testId: "add-filter-item-attendeeName" }, + { key: "attendeeEmail", name: "Attendee Email", testId: "add-filter-item-attendeeEmail" }, + { key: "dateRange", name: "Date Range", testId: "add-filter-item-dateRange" }, + ]; + const searchInputSelector = "[cmdk-input]"; + + const getFilterItemLocator = (page: Page, testId: string) => page.locator(`[data-testid="${testId}"]`); + + test.beforeEach(async ({ page, users }) => { + const user = await users.create(); + await user.apiLogin(); + const bookingsGetResponse = page.waitForResponse((response) => + /\/api\/trpc\/bookings\/get.*/.test(response.url()) + ); + await page.goto(`/bookings/upcoming`, { waitUntil: "domcontentloaded" }); + await bookingsGetResponse; + await page.locator('[data-testid="add-filter-button"]').click(); + await expect(page.locator(searchInputSelector)).toBeVisible(); + }); + + test("should show all filter items initially and after clearing search", async ({ page }) => { + const searchInput = page.locator(searchInputSelector); + + // Initial check: all defined filter items should be visible + for (const item of filterItemsConfig) { + await expect( + getFilterItemLocator(page, item.testId), + `Item ${item.name} should be visible initially` + ).toBeVisible(); + } + + // Type something and then clear the search + await searchInput.fill("Some text"); + await searchInput.clear(); + + // After clearing: all defined filter items should be visible again + for (const item of filterItemsConfig) { + await expect( + getFilterItemLocator(page, item.testId), + `Item ${item.name} should be visible after clearing search` + ).toBeVisible(); + } + }); + + test("search should be case-insensitive", async ({ page }) => { + const searchInput = page.locator(searchInputSelector); + + // Search for "member" (lowercase) + await searchInput.fill("member"); + await expect(getFilterItemLocator(page, "add-filter-item-userId")).toBeVisible(); + await expect(getFilterItemLocator(page, "add-filter-item-eventTypeId")).toBeHidden(); + await expect(getFilterItemLocator(page, "add-filter-item-teamId")).toBeHidden(); + }); + + test("should individually find each filter item by its full name", async ({ page }) => { + const searchInput = page.locator(searchInputSelector); + + for (const targetItem of filterItemsConfig) { + await searchInput.fill(targetItem.name); + + // Check that the target item is visible + await expect( + getFilterItemLocator(page, targetItem.testId), + `Searching for "${targetItem.name}", item "${targetItem.name}" should be visible` + ).toBeVisible(); + + await searchInput.clear(); + } + }); + + test("should show no items for a non-matching search term", async ({ page }) => { + const searchInput = page.locator(searchInputSelector); + const nonExistentTerm = "NonExistentFilterXYZ123"; + await searchInput.fill(nonExistentTerm); + + for (const item of filterItemsConfig) { + await expect( + getFilterItemLocator(page, item.testId), + `Item ${item.name} should be hidden for non-matching term '${nonExistentTerm}'` + ).toBeHidden(); + } + }); + }); }); async function createBooking({