import { expect, type Page, test } from "@playwright/test" import { serializeBookingSearchParams } from "@scandic-hotels/booking-flow/utils/url" import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum" test("can make a search with city", async ({ page }) => { await page.goto("/en") // Search for city const combobox = page.getByRole("combobox", { name: /where to/i }) await combobox.click() await combobox.fill("stockholm") await page.getByRole("option", { name: /stockholm sweden/i }).click() // Open datepicker // If we had better accessibility for our datepicker this would be so much easier const today = new Date() const tomorrow = new Date(today) tomorrow.setDate(today.getDate() + 1) await page .getByRole("button", { name: new RegExp(`${formatDate(today)}.*${formatDate(tomorrow)}`), }) .click() // Select future dates const twoDaysFromNow = new Date(today) twoDaysFromNow.setDate(today.getDate() + 2) await clickDatePickerDate(page, twoDaysFromNow) const threeDaysFromNow = new Date(today) threeDaysFromNow.setDate(today.getDate() + 3) await clickDatePickerDate(page, threeDaysFromNow) await page .getByRole("button", { name: /select dates/i, }) .click() // Select rooms and guests // Once again, better accessibility would make this so much easier await page.getByRole("button", { name: /1 room, 1 adult/i }).click() const roomsDialog = page.getByRole("dialog") const room1section = roomsDialog.getByText(/room 1/i).locator("..") // Add 1 adult await room1section .locator("section") .filter({ hasText: /adults/i }) .getByRole("button", { name: /add/i }) .click() // Add 1 child aged 10 await room1section .locator("section") .filter({ hasText: /children/i }) .getByRole("button", { name: /add/i }) .click() await room1section.getByRole("button", { name: /age/i }).click() await page.getByRole("option", { name: /10/i }).click() await page.getByRole("button", { name: /add room/i }).click() const room2section = roomsDialog.getByText(/room 2/i).locator("..") // Add 2 adults await room2section .locator("section") .filter({ hasText: /adults/i }) .getByRole("button", { name: /add/i }) .click({ clickCount: 2 }) await roomsDialog.getByRole("button", { name: /done/i }).click() await page.getByRole("button", { name: /search/i }).click() // Assert that we navigated to the correct URL const expectedSearchParams = serializeBookingSearchParams({ rooms: [ { adults: 2, childrenInRoom: [{ age: 10, bed: ChildBedMapEnum.IN_EXTRA_BED }], }, { adults: 3, childrenInRoom: [], }, ], fromDate: twoDaysFromNow.toISOString().split("T")[0], toDate: threeDaysFromNow.toISOString().split("T")[0], city: "STOCKHOLM", }) await expect(page).toHaveURL( `/en/hotelreservation/select-hotel?${expectedSearchParams}` ) }) test("can make a search with hotel", async ({ page }) => { await page.goto("/en") // Search for hotel const combobox = page.getByRole("combobox", { name: /where to/i }) await combobox.click() await combobox.fill("downtown camper") await page.getByRole("option", { name: /downtown camper/i }).click() // Open datepicker // If we had better accessibility for our datepicker this would be so much easier const today = new Date() const tomorrow = new Date(today) tomorrow.setDate(today.getDate() + 1) await page .getByRole("button", { name: new RegExp(`${formatDate(today)}.*${formatDate(tomorrow)}`), }) .click() // Select future dates const twoDaysFromNow = new Date(today) twoDaysFromNow.setDate(today.getDate() + 2) await clickDatePickerDate(page, twoDaysFromNow) const threeDaysFromNow = new Date(today) threeDaysFromNow.setDate(today.getDate() + 3) await clickDatePickerDate(page, threeDaysFromNow) await page .getByRole("button", { name: /select dates/i, }) .click() // Select rooms and guests // Once again, better accessibility would make this so much easier await page.getByRole("button", { name: /1 room, 1 adult/i }).click() const roomsDialog = page.getByRole("dialog") const room1section = roomsDialog.getByText(/room 1/i).locator("..") // Add 1 adult await room1section .locator("section") .filter({ hasText: /adults/i }) .getByRole("button", { name: /add/i }) .click() // Add 1 child aged 10 await room1section .locator("section") .filter({ hasText: /children/i }) .getByRole("button", { name: /add/i }) .click() await room1section.getByRole("button", { name: /age/i }).click() await page.getByRole("option", { name: /10/i }).click() await page.getByRole("button", { name: /add room/i }).click() const room2section = roomsDialog.getByText(/room 2/i).locator("..") // Add 2 adults await room2section .locator("section") .filter({ hasText: /adults/i }) .getByRole("button", { name: /add/i }) .click({ clickCount: 2 }) await roomsDialog.getByRole("button", { name: /done/i }).click() await page.getByRole("button", { name: /search/i }).click() // Assert that we navigated to the correct URL const expectedSearchParams = serializeBookingSearchParams({ rooms: [ { adults: 2, childrenInRoom: [{ age: 10, bed: ChildBedMapEnum.IN_EXTRA_BED }], }, { adults: 3, childrenInRoom: [], }, ], fromDate: twoDaysFromNow.toISOString().split("T")[0], toDate: threeDaysFromNow.toISOString().split("T")[0], hotelId: "879", // Downtown Camper }) await expect(page).toHaveURL( `/en/hotelreservation/select-rate?${expectedSearchParams}` ) }) const formatDate = (date: Date) => { const day = date.getDate() const month = date.toLocaleDateString("en-US", { month: "short" }) const weekday = date.toLocaleDateString("en-US", { weekday: "short" }) return `${weekday}, ${day} ${month}` } const clickDatePickerDate = async (page: Page, date: Date) => { const dateString = date.toISOString().split("T")[0] // YYYY-MM-DD format await page.locator(`[data-day="${dateString}"]`).getByRole("button").click() }