diff --git a/apps/web/playwright/booking/phoneQuestione2e/phone-and-address-question.e2e.ts b/apps/web/playwright/booking/phoneQuestione2e/phone-and-address-question.e2e.ts new file mode 100644 index 0000000000..056571f858 --- /dev/null +++ b/apps/web/playwright/booking/phoneQuestione2e/phone-and-address-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Phone Question and Address Question", () => { + const bookingOptions = { hasPlaceholder: true, isRequired: true }; + test("Phone and Address required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "address", + "Test Phone question and Address question (both required)", + bookingOptions + ); + }); + + test("Phone and Address not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "address", + "Test Phone question and Address question (only Phone required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/phoneQuestione2e/phone-and-checkbox-group-question.e2e.ts b/apps/web/playwright/booking/phoneQuestione2e/phone-and-checkbox-group-question.e2e.ts new file mode 100644 index 0000000000..dcfa63323e --- /dev/null +++ b/apps/web/playwright/booking/phoneQuestione2e/phone-and-checkbox-group-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Phone Question and checkbox group Question", () => { + const bookingOptions = { hasPlaceholder: false, isRequired: true }; + test("Phone and checkbox group required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "checkbox", + "Test Phone question and checkbox group question (both required)", + bookingOptions + ); + }); + + test("Phone and checkbox group not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "checkbox", + "Test Phone question and checkbox group question (only phone required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/phoneQuestione2e/phone-and-checkbox-question.e2e.ts b/apps/web/playwright/booking/phoneQuestione2e/phone-and-checkbox-question.e2e.ts new file mode 100644 index 0000000000..7ecf116668 --- /dev/null +++ b/apps/web/playwright/booking/phoneQuestione2e/phone-and-checkbox-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Phone Question and checkbox Question", () => { + const bookingOptions = { hasPlaceholder: false, isRequired: true }; + test("Phone and checkbox required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "boolean", + "Test Phone question and checkbox question (both required)", + bookingOptions + ); + }); + + test("Phone and checkbox not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "boolean", + "Test Phone question and checkbox question (only phone required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/phoneQuestione2e/phone-and-long-text-question.e2e.ts b/apps/web/playwright/booking/phoneQuestione2e/phone-and-long-text-question.e2e.ts new file mode 100644 index 0000000000..242f214bbb --- /dev/null +++ b/apps/web/playwright/booking/phoneQuestione2e/phone-and-long-text-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Phone Question and Long text Question", () => { + const bookingOptions = { hasPlaceholder: true, isRequired: true }; + test("Phone and Long text required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "textarea", + "Test Phone question and Long text question (both required)", + bookingOptions + ); + }); + + test("Phone and Long text not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "textarea", + "Test Phone question and Long text question (only Phone required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/phoneQuestione2e/phone-and-multiple-emails-question.e2e.ts b/apps/web/playwright/booking/phoneQuestione2e/phone-and-multiple-emails-question.e2e.ts new file mode 100644 index 0000000000..393e58c161 --- /dev/null +++ b/apps/web/playwright/booking/phoneQuestione2e/phone-and-multiple-emails-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Phone Question and Multi email Question", () => { + const bookingOptions = { hasPlaceholder: true, isRequired: true }; + test("Phone and Multi email required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "multiemail", + "Test Phone question and Multi email question (both required)", + bookingOptions + ); + }); + + test("Phone and Multi email not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "multiemail", + "Test Phone question and Multi email question (only phone required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/phoneQuestione2e/phone-and-multiselect-question.e2e.ts b/apps/web/playwright/booking/phoneQuestione2e/phone-and-multiselect-question.e2e.ts new file mode 100644 index 0000000000..a6119d8922 --- /dev/null +++ b/apps/web/playwright/booking/phoneQuestione2e/phone-and-multiselect-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Phone Question and multiselect Question", () => { + const bookingOptions = { hasPlaceholder: false, isRequired: true }; + test("Phone and multiselect text required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "multiselect", + "Test Phone question and multiselect question (both required)", + bookingOptions + ); + }); + + test("Phone and multiselect text not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "multiselect", + "Test Phone question and multiselect question (only phone required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/phoneQuestione2e/phone-and-number-question.e2e.ts b/apps/web/playwright/booking/phoneQuestione2e/phone-and-number-question.e2e.ts new file mode 100644 index 0000000000..da53592b9a --- /dev/null +++ b/apps/web/playwright/booking/phoneQuestione2e/phone-and-number-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Phone Question and Number Question", () => { + const bookingOptions = { hasPlaceholder: true, isRequired: true }; + test("Phone and Number required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "number", + "Test Phone question and number question (both required)", + bookingOptions + ); + }); + + test("Phone and Number not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "number", + "Test Phone question and number question (only phone required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/phoneQuestione2e/phone-and-radio-group-question.e2e.ts b/apps/web/playwright/booking/phoneQuestione2e/phone-and-radio-group-question.e2e.ts new file mode 100644 index 0000000000..2e9f0ccff9 --- /dev/null +++ b/apps/web/playwright/booking/phoneQuestione2e/phone-and-radio-group-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Phone Question and Radio group Question", () => { + const bookingOptions = { hasPlaceholder: false, isRequired: true }; + test("Phone and Radio group required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "radio", + "Test Phone question and Radio group question (both required)", + bookingOptions + ); + }); + + test("Phone and Radio group not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "radio", + "Test Phone question and Radio group question (only phone required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/phoneQuestione2e/phone-and-select-question.e2e.ts b/apps/web/playwright/booking/phoneQuestione2e/phone-and-select-question.e2e.ts new file mode 100644 index 0000000000..bb963f956b --- /dev/null +++ b/apps/web/playwright/booking/phoneQuestione2e/phone-and-select-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Phone Question and select Question", () => { + const bookingOptions = { hasPlaceholder: false, isRequired: true }; + test("Phone and select required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "select", + "Test Phone question and select question (both required)", + bookingOptions + ); + }); + + test("Phone and select not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "select", + "Test Phone question and select question (only phone required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/phoneQuestione2e/phone-and-short-text-question.e2e.ts b/apps/web/playwright/booking/phoneQuestione2e/phone-and-short-text-question.e2e.ts new file mode 100644 index 0000000000..82bac518e3 --- /dev/null +++ b/apps/web/playwright/booking/phoneQuestione2e/phone-and-short-text-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Phone Question and Short text question", () => { + const bookingOptions = { hasPlaceholder: true, isRequired: true }; + test("Phone and Short text required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "text", + "Test Phone question and Short Text question (both required)", + bookingOptions + ); + }); + + test("Phone and Short text not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "text", + "Test Phone question and Short Text question (only phone required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-address-question.e2e.ts b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-address-question.e2e.ts new file mode 100644 index 0000000000..2cefe7d923 --- /dev/null +++ b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-address-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Radio Group Question and Address Question", () => { + const bookingOptions = { hasPlaceholder: true, isRequired: true }; + test("Radio Group and Address required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "address", + "Test Radio Group question and Address question (both required)", + bookingOptions + ); + }); + + test("Radio Group and Address not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "address", + "Test Radio Group question and Address question (only radio Group required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-checkbox-group-question.e2e.ts b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-checkbox-group-question.e2e.ts new file mode 100644 index 0000000000..0c917a7097 --- /dev/null +++ b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-checkbox-group-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Radio Group Question and checkbox group Question", () => { + const bookingOptions = { hasPlaceholder: false, isRequired: true }; + test("Radio Group and checkbox group required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "checkbox", + "Test Radio Group question and checkbox group question (both required)", + bookingOptions + ); + }); + + test("Radio Group and checkbox group not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "checkbox", + "Test Radio Group question and checkbox group question (only radio required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-checkbox-question.e2e.ts b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-checkbox-question.e2e.ts new file mode 100644 index 0000000000..ed2f7660bf --- /dev/null +++ b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-checkbox-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Radio Group Question and checkbox Question", () => { + const bookingOptions = { hasPlaceholder: false, isRequired: true }; + test("Radio Group and checkbox required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "boolean", + "Test Radio Group question and checkbox question (both required)", + bookingOptions + ); + }); + + test("Radio Group and checkbox not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "boolean", + "Test Radio Group question and checkbox question (only radio required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-long-text-question.e2e.ts b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-long-text-question.e2e.ts new file mode 100644 index 0000000000..53b245a3b8 --- /dev/null +++ b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-long-text-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Radio Group Question and Long text Question", () => { + const bookingOptions = { hasPlaceholder: true, isRequired: true }; + test("Radio Group and Long text required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "textarea", + "Test Radio Group question and Long text question (both required)", + bookingOptions + ); + }); + + test("Radio Group and Long text not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "textarea", + "Test Radio Group question and Long text question (only radio required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-multiple-emails-question.e2e.ts b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-multiple-emails-question.e2e.ts new file mode 100644 index 0000000000..18231bb3e6 --- /dev/null +++ b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-multiple-emails-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Radio Group Question and Multi email Question", () => { + const bookingOptions = { hasPlaceholder: true, isRequired: true }; + test("Radio Group and Multi email required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "multiemail", + "Test Radio Group question and Multi email question (both required)", + bookingOptions + ); + }); + + test("Radio Group and Multi email not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "multiemail", + "Test Radio Group question and Multi email question (only radio required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-multiselect-question.e2e.ts b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-multiselect-question.e2e.ts new file mode 100644 index 0000000000..ff7cbecd2d --- /dev/null +++ b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-multiselect-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Radio Group Question and multiselect Question", () => { + const bookingOptions = { hasPlaceholder: false, isRequired: true }; + test("Radio Group and multiselect text required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "multiselect", + "Test Radio Group question and multiselect question (both required)", + bookingOptions + ); + }); + + test("Radio Group and multiselect text not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "multiselect", + "Test Radio Group question and multiselect question (only radio required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-number-question.e2e.ts b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-number-question.e2e.ts new file mode 100644 index 0000000000..a1e6041f58 --- /dev/null +++ b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-number-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Radio Group Question and Number Question", () => { + const bookingOptions = { hasPlaceholder: true, isRequired: true }; + test("Radio Group and Number required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "number", + "Test Radio Group question and number question (both required)", + bookingOptions + ); + }); + + test("Radio Group and Number not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "number", + "Test Radio Group question and number question (only radio group required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-phone-question.e2e.ts b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-phone-question.e2e.ts new file mode 100644 index 0000000000..3e7a79da64 --- /dev/null +++ b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-phone-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Radio Group Question and Phone group Question", () => { + const bookingOptions = { hasPlaceholder: false, isRequired: true }; + test("Radio Group and Radio group required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "phone", + "Test Radio Group question and Phone question (both required)", + bookingOptions + ); + }); + + test("Radio Group and Radio group not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "phone", + users, + "radio", + "Test Radio Group question and Phone question (only radio group required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-select-question.e2e.ts b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-select-question.e2e.ts new file mode 100644 index 0000000000..33fa4f4917 --- /dev/null +++ b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-select-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Radio Group Question and select Question", () => { + const bookingOptions = { hasPlaceholder: false, isRequired: true }; + test("Radio Group and select required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "select", + "Test Radio Group question and select question (both required)", + bookingOptions + ); + }); + + test("Radio Group and select not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "select", + "Test Radio Group question and select question (only radio group required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-short-text-question.e2e.ts b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-short-text-question.e2e.ts new file mode 100644 index 0000000000..0cecfc1b7b --- /dev/null +++ b/apps/web/playwright/booking/radioGroupQuestione2e/radio-group-and-short-text-question.e2e.ts @@ -0,0 +1,31 @@ +import { test } from "../../lib/fixtures"; +import { initialCommonSteps } from "../utils/bookingUtils"; + +test.describe.configure({ mode: "parallel" }); + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Booking With Radio Group Question and Short text question", () => { + const bookingOptions = { hasPlaceholder: true, isRequired: true }; + test("Radio Group and Short text required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "text", + "Test Radio Group question and Short Text question (both required)", + bookingOptions + ); + }); + + test("Radio Group and Short text not required", async ({ page, users }) => { + await initialCommonSteps( + page, + "radio", + users, + "text", + "Test Radio Group question and Short Text question (only radio required)", + { ...bookingOptions, isRequired: false } + ); + }); +}); diff --git a/apps/web/playwright/booking/utils/bookingUtils.ts b/apps/web/playwright/booking/utils/bookingUtils.ts new file mode 100644 index 0000000000..e393e5d11e --- /dev/null +++ b/apps/web/playwright/booking/utils/bookingUtils.ts @@ -0,0 +1,244 @@ +import { expect, type Page } from "@playwright/test"; + +import type { Fixtures } from "@calcom/web/playwright/lib/fixtures"; + +const EMAIL = "test@test.com"; +const EMAIL2 = "test2@test.com"; +const PHONE = "+55 (32) 983289947"; +const scheduleSuccessfullyText = "This meeting is scheduled"; +const reschedulePlaceholderText = "Let others know why you need to reschedule"; + +interface QuestionActions { + [key: string]: () => Promise; +} + +type BookingOptions = { + hasPlaceholder?: boolean; + isReschedule?: boolean; + isRequired?: boolean; +}; + +type customLocators = { + shouldChangeSelectLocator: boolean; + shouldUseLastRadioGroupLocator: boolean; + shouldUseFirstRadioGroupLocator: boolean; + shouldChangeMultiSelectLocator: boolean; +}; + +export const loginUser = async (page: Page, users: Fixtures["users"]) => { + const pro = await users.create({ name: "testuser" }); + await pro.apiLogin(); + await page.goto("/event-types"); +}; + +const fillQuestion = async (eventTypePage: Page, questionType: string, customLocators: customLocators) => { + const questionActions: QuestionActions = { + phone: async () => { + await eventTypePage.locator('input[name="phone-test"]').clear(); + await eventTypePage.locator('input[name="phone-test"]').fill(PHONE); + }, + multiemail: async () => { + await eventTypePage.getByRole("button", { name: `${questionType} test` }).click(); + await eventTypePage.getByPlaceholder(`${questionType} test`).fill(EMAIL); + await eventTypePage.getByTestId("add-another-guest").last().click(); + await eventTypePage.getByPlaceholder(`${questionType} test`).last().fill(EMAIL2); + }, + checkbox: async () => { + if (customLocators.shouldUseLastRadioGroupLocator || customLocators.shouldChangeMultiSelectLocator) { + await eventTypePage.getByLabel("Option 1").last().click(); + await eventTypePage.getByLabel("Option 2").last().click(); + } else if (customLocators.shouldUseFirstRadioGroupLocator) { + await eventTypePage.getByLabel("Option 1").first().click(); + await eventTypePage.getByLabel("Option 2").first().click(); + } else { + await eventTypePage.getByLabel("Option 1").click(); + await eventTypePage.getByLabel("Option 2").click(); + } + }, + multiselect: async () => { + if (customLocators.shouldChangeMultiSelectLocator) { + await eventTypePage.locator("form svg").nth(1).click(); + await eventTypePage.getByTestId("select-option-Option 1").click(); + } else { + await eventTypePage.locator("form svg").last().click(); + await eventTypePage.getByTestId("select-option-Option 1").click(); + } + }, + boolean: async () => { + await eventTypePage.getByLabel(`${questionType} test`).check(); + }, + radio: async () => { + await eventTypePage.locator('[id="radio-test\\.option\\.0\\.radio"]').click(); + }, + select: async () => { + if (customLocators.shouldChangeSelectLocator) { + await eventTypePage.locator("form svg").nth(1).click(); + await eventTypePage.getByTestId("select-option-Option 1").click(); + } else { + await eventTypePage.locator("form svg").last().click(); + await eventTypePage.getByTestId("select-option-Option 1").click(); + } + }, + number: async () => { + await eventTypePage.getByPlaceholder(`${questionType} test`).click(); + await eventTypePage.getByPlaceholder(`${questionType} test`).fill("123"); + }, + address: async () => { + await eventTypePage.getByPlaceholder(`${questionType} test`).click(); + await eventTypePage.getByPlaceholder(`${questionType} test`).fill("address test"); + }, + textarea: async () => { + await eventTypePage.getByPlaceholder(`${questionType} test`).click(); + await eventTypePage.getByPlaceholder(`${questionType} test`).fill("textarea test"); + }, + text: async () => { + await eventTypePage.getByPlaceholder(`${questionType} test`).click(); + await eventTypePage.getByPlaceholder(`${questionType} test`).fill("text test"); + }, + }; + + if (questionActions[questionType]) { + await questionActions[questionType](); + } +}; + +export const fillAndConfirmBooking = async ( + eventTypePage: Page, + placeholderText: string, + question: string, + fillText: string, + secondQuestion: string, + options: BookingOptions +) => { + const confirmButton = options.isReschedule ? "confirm-reschedule-button" : "confirm-book-button"; + + await expect(eventTypePage.getByText(`${secondQuestion} test`).first()).toBeVisible(); + await eventTypePage.getByPlaceholder(placeholderText).fill(fillText); + + // Change the selector for specifics cases related to select question + const shouldChangeSelectLocator = (question: string, secondQuestion: string): boolean => + question === "select" && ["multiemail", "multiselect"].includes(secondQuestion); + + const shouldUseLastRadioGroupLocator = (question: string, secondQuestion: string): boolean => + question === "radio" && secondQuestion === "checkbox"; + + const shouldUseFirstRadioGroupLocator = (question: string, secondQuestion: string): boolean => + question === "checkbox" && secondQuestion === "radio"; + + const shouldChangeMultiSelectLocator = (question: string, secondQuestion: string): boolean => + question === "multiselect" && ["address", "checkbox", "multiemail", "select"].includes(secondQuestion); + + const customLocators = { + shouldChangeSelectLocator: shouldChangeSelectLocator(question, secondQuestion), + shouldUseLastRadioGroupLocator: shouldUseLastRadioGroupLocator(question, secondQuestion), + shouldUseFirstRadioGroupLocator: shouldUseFirstRadioGroupLocator(question, secondQuestion), + shouldChangeMultiSelectLocator: shouldChangeMultiSelectLocator(question, secondQuestion), + }; + + // Fill the first question + await fillQuestion(eventTypePage, question, customLocators); + + // Fill the second question if is required + options.isRequired && (await fillQuestion(eventTypePage, secondQuestion, customLocators)); + + await eventTypePage.getByTestId(confirmButton).click(); + const scheduleSuccessfullyPage = eventTypePage.getByText(scheduleSuccessfullyText); + await scheduleSuccessfullyPage.waitFor({ state: "visible" }); + await expect(scheduleSuccessfullyPage).toBeVisible(); +}; + +export const initialCommonSteps = async ( + bookingPage: Page, + question: string, + users: Fixtures["users"], + secondQuestion: string, + message: string, + options: BookingOptions +) => { + const firstQuestionHasPlaceholder = [ + "address", + "textarea", + "multiemail", + "number", + "text", + "phone", + ].includes(question); + + //Logs in a test user and navigates to the event types page. + loginUser(bookingPage, users); + + // Go to event type settings + await bookingPage.getByRole("link", { name: "30 min" }).click(); + + // Go to advanced tab + await bookingPage.getByTestId("vertical-tab-event_advanced_tab_title").click(); + + // Add first and second question and fill both + await bookingPage.getByTestId("add-field").click(); + await bookingPage.locator("#test-field-type > .bg-default > div > div:nth-child(2)").first().click(); + await bookingPage.getByTestId(`select-option-${question}`).click(); + await bookingPage.getByLabel("Identifier").dblclick(); + await bookingPage.getByLabel("Identifier").fill(`${question}-test`); + await bookingPage.getByLabel("Label").click(); + await bookingPage.getByLabel("Label").fill(`${question} test`); + + // Fill the placeholder if the question has one + if (firstQuestionHasPlaceholder) { + await bookingPage.getByLabel("Placeholder").click(); + await bookingPage.getByLabel("Placeholder").fill(`${question} test`); + } + await bookingPage.getByTestId("field-add-save").click(); + await bookingPage.getByTestId("add-field").click(); + await bookingPage.locator("#test-field-type > .bg-default > div > div:nth-child(2)").first().click(); + await bookingPage.getByTestId(`select-option-${secondQuestion}`).click(); + await bookingPage.getByLabel("Identifier").dblclick(); + await bookingPage.getByLabel("Identifier").fill(`${secondQuestion}-test`); + await bookingPage.getByLabel("Label").click(); + await bookingPage.getByLabel("Label").fill(`${secondQuestion} test`); + if (options.hasPlaceholder) { + await bookingPage.getByLabel("Placeholder").dblclick(); + await bookingPage.getByLabel("Placeholder").fill(`${secondQuestion} test`); + } + if (!options.isRequired) { + await bookingPage.getByRole("radio", { name: "No" }).click(); + } + await bookingPage.getByTestId("field-add-save").click(); + await expect(bookingPage.getByTestId(`field-${question}-test`)).toBeVisible(); + await expect(bookingPage.getByTestId(`field-${secondQuestion}-test`)).toBeVisible(); + await bookingPage.getByTestId("update-eventtype").click(); + + // Go to booking page + const eventtypePromise = bookingPage.waitForEvent("popup"); + await bookingPage.getByTestId("preview-button").click(); + const eventTypePage = await eventtypePromise; + + // Select the first available time + await eventTypePage.getByTestId("time").first().click(); + fillAndConfirmBooking( + eventTypePage, + "Please share anything that will help prepare for our meeting.", + question, + message, + secondQuestion, + options + ); + + // Go to final steps + await rescheduleAndCancel(eventTypePage); +}; +const rescheduleAndCancel = async (eventTypePage: Page) => { + await eventTypePage.getByText("Reschedule").click(); + await eventTypePage.getByTestId("time").first().click(); + await eventTypePage.getByPlaceholder(reschedulePlaceholderText).click(); + await eventTypePage.getByPlaceholder(reschedulePlaceholderText).fill("Test reschedule"); + await eventTypePage.getByTestId("confirm-reschedule-button").click(); + + // Check if the rescheduled page is visible + await expect(eventTypePage.getByText(scheduleSuccessfullyText)).toBeVisible(); + await eventTypePage.getByTestId("cancel").click(); + await eventTypePage.getByTestId("cancel_reason").fill("Test cancel"); + await eventTypePage.getByTestId("confirm_cancel").click(); + + // Check if the cancelled page is visible + await expect(eventTypePage.getByTestId("cancelled-headline")).toBeVisible(); +};