207 lines
6.1 KiB
TypeScript
207 lines
6.1 KiB
TypeScript
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()
|
|
}
|