test: Create E2E tests for bookings with custom/required Phone + other questions (#11502)
Co-authored-by: gitstart-calcom <gitstart-calcom@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Co-authored-by: Shivam Kalra <shivamkalra98@gmail.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Morgan Vernay <morgan@cal.com>pull/12001/head
parent
2550485c49
commit
614741d207
|
@ -0,0 +1,387 @@
|
||||||
|
import { loginUser } from "../fixtures/regularBookings";
|
||||||
|
import { test } from "../lib/fixtures";
|
||||||
|
|
||||||
|
test.describe("Booking With Phone Question and Each Other Question", () => {
|
||||||
|
const bookingOptions = { hasPlaceholder: true, isRequired: true };
|
||||||
|
|
||||||
|
test.beforeEach(async ({ page, users, bookingPage }) => {
|
||||||
|
await loginUser(users);
|
||||||
|
await page.goto("/event-types");
|
||||||
|
await bookingPage.goToEventType("30 min");
|
||||||
|
await bookingPage.goToTab("event_advanced_tab_title");
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe("Booking With Phone Question and Address Question", () => {
|
||||||
|
test("Phone and Address required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("address", "address-test", "address test", true, "address test");
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Address question (both required)",
|
||||||
|
secondQuestion: "address",
|
||||||
|
options: bookingOptions,
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Phone and Address not required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("address", "address-test", "address test", false, "address test");
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Address question (only phone required)",
|
||||||
|
secondQuestion: "address",
|
||||||
|
options: { ...bookingOptions, isRequired: false },
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe("Booking With Phone Question and checkbox group Question", () => {
|
||||||
|
const bookingOptions = { hasPlaceholder: false, isRequired: true };
|
||||||
|
test("Phone and checkbox group required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("checkbox", "checkbox-test", "checkbox test", true);
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and checkbox group question (both required)",
|
||||||
|
secondQuestion: "checkbox",
|
||||||
|
options: bookingOptions,
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Phone and checkbox group not required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("checkbox", "checkbox-test", "checkbox test", false);
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and checkbox group question (only phone required)",
|
||||||
|
secondQuestion: "checkbox",
|
||||||
|
options: { ...bookingOptions, isRequired: false },
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe("Booking With Phone Question and checkbox Question", () => {
|
||||||
|
test("Phone and checkbox required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("boolean", "boolean-test", "boolean test", true);
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and checkbox question (both required)",
|
||||||
|
secondQuestion: "boolean",
|
||||||
|
options: bookingOptions,
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
test("Phone and checkbox not required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("boolean", "boolean-test", "boolean test", false);
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and checkbox (only phone required)",
|
||||||
|
secondQuestion: "boolean",
|
||||||
|
options: { ...bookingOptions, isRequired: false },
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe("Booking With Phone Question and Long text Question", () => {
|
||||||
|
test("Phone and Long text required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("textarea", "textarea-test", "textarea test", true, "textarea test");
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Long Text question (both required)",
|
||||||
|
secondQuestion: "textarea",
|
||||||
|
options: bookingOptions,
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Phone and Long text not required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("textarea", "textarea-test", "textarea test", false, "textarea test");
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Long Text question (only phone required)",
|
||||||
|
secondQuestion: "textarea",
|
||||||
|
options: { ...bookingOptions, isRequired: false },
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe("Booking With Phone Question and Multi email Question", () => {
|
||||||
|
const bookingOptions = { hasPlaceholder: true, isRequired: true };
|
||||||
|
test("Phone and Multi email required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion(
|
||||||
|
"multiemail",
|
||||||
|
"multiemail-test",
|
||||||
|
"multiemail test",
|
||||||
|
true,
|
||||||
|
"multiemail test"
|
||||||
|
);
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Multi Email question (both required)",
|
||||||
|
secondQuestion: "multiemail",
|
||||||
|
options: bookingOptions,
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Phone and Multi email not required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion(
|
||||||
|
"multiemail",
|
||||||
|
"multiemail-test",
|
||||||
|
"multiemail test",
|
||||||
|
false,
|
||||||
|
"multiemail test"
|
||||||
|
);
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Multi Email question (only phone required)",
|
||||||
|
secondQuestion: "multiemail",
|
||||||
|
options: { ...bookingOptions, isRequired: false },
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe("Booking With Phone Question and multiselect Question", () => {
|
||||||
|
test("Phone and multiselect text required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("multiselect", "multiselect-test", "multiselect test", true);
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Multi Select question (both required)",
|
||||||
|
secondQuestion: "multiselect",
|
||||||
|
options: bookingOptions,
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Phone and multiselect text not required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("multiselect", "multiselect-test", "multiselect test", false);
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Multi Select question (only phone required)",
|
||||||
|
secondQuestion: "multiselect",
|
||||||
|
options: { ...bookingOptions, isRequired: false },
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe("Booking With Phone Question and Number Question", () => {
|
||||||
|
test("Phone and Number required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("number", "number-test", "number test", true, "number test");
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Number question (both required)",
|
||||||
|
secondQuestion: "number",
|
||||||
|
options: bookingOptions,
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Phone and Number not required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("number", "number-test", "number test", false, "number test");
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Number question (only phone required)",
|
||||||
|
secondQuestion: "number",
|
||||||
|
options: { ...bookingOptions, isRequired: false },
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe("Booking With Phone Question and Radio group Question", () => {
|
||||||
|
test("Phone and Radio group required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("radio", "radio-test", "radio test", true);
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Radio question (both required)",
|
||||||
|
secondQuestion: "radio",
|
||||||
|
options: bookingOptions,
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Phone and Radio group not required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("radio", "radio-test", "radio test", false);
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Radio question (only phone required)",
|
||||||
|
secondQuestion: "radio",
|
||||||
|
options: { ...bookingOptions, isRequired: false },
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe("Booking With Phone Question and select Question", () => {
|
||||||
|
test("Phone and select required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("select", "select-test", "select test", true, "select test");
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Select question (both required)",
|
||||||
|
secondQuestion: "select",
|
||||||
|
options: bookingOptions,
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Phone and select not required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("select", "select-test", "select test", false, "select test");
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Select question (only phone required)",
|
||||||
|
secondQuestion: "select",
|
||||||
|
options: { ...bookingOptions, isRequired: false },
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe("Booking With Phone Question and Short text question", () => {
|
||||||
|
const bookingOptions = { hasPlaceholder: true, isRequired: true };
|
||||||
|
test("Phone and Short text required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("text", "text-test", "text test", true, "text test");
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Text question (both required)",
|
||||||
|
secondQuestion: "text",
|
||||||
|
options: bookingOptions,
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Phone and Short text not required", async ({ bookingPage }) => {
|
||||||
|
await bookingPage.addQuestion("phone", "phone-test", "phone test", true, "phone test");
|
||||||
|
await bookingPage.addQuestion("text", "text-test", "text test", false, "text test");
|
||||||
|
await bookingPage.updateEventType();
|
||||||
|
const eventTypePage = await bookingPage.previewEventType();
|
||||||
|
await bookingPage.selectTimeSlot(eventTypePage);
|
||||||
|
await bookingPage.fillAndConfirmBooking({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText: "Please share anything that will help prepare for our meeting.",
|
||||||
|
question: "phone",
|
||||||
|
fillText: "Test Phone question and Text question (only phone required)",
|
||||||
|
secondQuestion: "text",
|
||||||
|
options: { ...bookingOptions, isRequired: false },
|
||||||
|
});
|
||||||
|
await bookingPage.cancelAndRescheduleBooking(eventTypePage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,250 @@
|
||||||
|
import { expect, type Page } from "@playwright/test";
|
||||||
|
|
||||||
|
import type { createUsersFixture } from "./users";
|
||||||
|
|
||||||
|
const reschedulePlaceholderText = "Let others know why you need to reschedule";
|
||||||
|
export const scheduleSuccessfullyText = "This meeting is scheduled";
|
||||||
|
|
||||||
|
const EMAIL = "test@test.com";
|
||||||
|
const EMAIL2 = "test2@test.com";
|
||||||
|
const PHONE = "+55 (32) 983289947";
|
||||||
|
|
||||||
|
type BookingOptions = {
|
||||||
|
hasPlaceholder?: boolean;
|
||||||
|
isReschedule?: boolean;
|
||||||
|
isRequired?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface QuestionActions {
|
||||||
|
[key: string]: () => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
type customLocators = {
|
||||||
|
shouldChangeSelectLocator: boolean;
|
||||||
|
shouldUseLastRadioGroupLocator: boolean;
|
||||||
|
shouldUseFirstRadioGroupLocator: boolean;
|
||||||
|
shouldChangeMultiSelectLocator: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type fillAndConfirmBookingParams = {
|
||||||
|
eventTypePage: Page;
|
||||||
|
placeholderText: string;
|
||||||
|
question: string;
|
||||||
|
fillText: string;
|
||||||
|
secondQuestion: string;
|
||||||
|
options: BookingOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
type UserFixture = ReturnType<typeof createUsersFixture>;
|
||||||
|
|
||||||
|
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 async function loginUser(users: UserFixture) {
|
||||||
|
const pro = await users.create({ name: "testuser" });
|
||||||
|
await pro.apiLogin();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createBookingPageFixture(page: Page) {
|
||||||
|
return {
|
||||||
|
goToEventType: async (eventType: string) => {
|
||||||
|
await page.getByRole("link", { name: eventType }).click();
|
||||||
|
},
|
||||||
|
goToTab: async (tabName: string) => {
|
||||||
|
await page.getByTestId(`vertical-tab-${tabName}`).click();
|
||||||
|
},
|
||||||
|
addQuestion: async (
|
||||||
|
questionType: string,
|
||||||
|
identifier: string,
|
||||||
|
label: string,
|
||||||
|
isRequired: boolean,
|
||||||
|
placeholder?: string
|
||||||
|
) => {
|
||||||
|
await page.getByTestId("add-field").click();
|
||||||
|
await page.locator("#test-field-type > .bg-default > div > div:nth-child(2)").first().click();
|
||||||
|
await page.getByTestId(`select-option-${questionType}`).click();
|
||||||
|
await page.getByLabel("Identifier").dblclick();
|
||||||
|
await page.getByLabel("Identifier").fill(identifier);
|
||||||
|
await page.getByLabel("Label").click();
|
||||||
|
await page.getByLabel("Label").fill(label);
|
||||||
|
if (placeholder) {
|
||||||
|
await page.getByLabel("Placeholder").click();
|
||||||
|
await page.getByLabel("Placeholder").fill(placeholder);
|
||||||
|
}
|
||||||
|
if (!isRequired) {
|
||||||
|
await page.getByRole("radio", { name: "No" }).click();
|
||||||
|
}
|
||||||
|
await page.getByTestId("field-add-save").click();
|
||||||
|
},
|
||||||
|
updateEventType: async () => {
|
||||||
|
await page.getByTestId("update-eventtype").click();
|
||||||
|
},
|
||||||
|
previewEventType: async () => {
|
||||||
|
const eventtypePromise = page.waitForEvent("popup");
|
||||||
|
await page.getByTestId("preview-button").click();
|
||||||
|
return eventtypePromise;
|
||||||
|
},
|
||||||
|
selectTimeSlot: async (eventTypePage: Page) => {
|
||||||
|
while (await eventTypePage.getByRole("button", { name: "View next" }).isVisible()) {
|
||||||
|
await eventTypePage.getByRole("button", { name: "View next" }).click();
|
||||||
|
}
|
||||||
|
await eventTypePage.getByTestId("time").first().click();
|
||||||
|
},
|
||||||
|
clickReschedule: async () => {
|
||||||
|
await page.getByText("Reschedule").click();
|
||||||
|
},
|
||||||
|
navigateToAvailableTimeSlot: async () => {
|
||||||
|
while (await page.getByRole("button", { name: "View next" }).isVisible()) {
|
||||||
|
await page.getByRole("button", { name: "View next" }).click();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectFirstAvailableTime: async () => {
|
||||||
|
await page.getByTestId("time").first().click();
|
||||||
|
},
|
||||||
|
fillRescheduleReasonAndConfirm: async () => {
|
||||||
|
await page.getByPlaceholder(reschedulePlaceholderText).click();
|
||||||
|
await page.getByPlaceholder(reschedulePlaceholderText).fill("Test reschedule");
|
||||||
|
await page.getByTestId("confirm-reschedule-button").click();
|
||||||
|
},
|
||||||
|
verifyReschedulingSuccess: async () => {
|
||||||
|
await expect(page.getByText(scheduleSuccessfullyText)).toBeVisible();
|
||||||
|
},
|
||||||
|
cancelBookingWithReason: async () => {
|
||||||
|
await page.getByTestId("cancel").click();
|
||||||
|
await page.getByTestId("cancel_reason").fill("Test cancel");
|
||||||
|
await page.getByTestId("confirm_cancel").click();
|
||||||
|
},
|
||||||
|
verifyBookingCancellation: async () => {
|
||||||
|
await expect(page.getByTestId("cancelled-headline")).toBeVisible();
|
||||||
|
},
|
||||||
|
cancelAndRescheduleBooking: async (eventTypePage: Page) => {
|
||||||
|
await eventTypePage.getByText("Reschedule").click();
|
||||||
|
while (await eventTypePage.getByRole("button", { name: "View next" }).isVisible()) {
|
||||||
|
await eventTypePage.getByRole("button", { name: "View next" }).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();
|
||||||
|
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();
|
||||||
|
await expect(eventTypePage.getByTestId("cancelled-headline")).toBeVisible();
|
||||||
|
},
|
||||||
|
|
||||||
|
fillAndConfirmBooking: async ({
|
||||||
|
eventTypePage,
|
||||||
|
placeholderText,
|
||||||
|
question,
|
||||||
|
fillText,
|
||||||
|
secondQuestion,
|
||||||
|
options,
|
||||||
|
}: fillAndConfirmBookingParams) => {
|
||||||
|
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();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ import type { ExpectedUrlDetails } from "../../../../playwright.config";
|
||||||
import { createBookingsFixture } from "../fixtures/bookings";
|
import { createBookingsFixture } from "../fixtures/bookings";
|
||||||
import { createEmbedsFixture } from "../fixtures/embeds";
|
import { createEmbedsFixture } from "../fixtures/embeds";
|
||||||
import { createPaymentsFixture } from "../fixtures/payments";
|
import { createPaymentsFixture } from "../fixtures/payments";
|
||||||
|
import { createBookingPageFixture } from "../fixtures/regularBookings";
|
||||||
import { createRoutingFormsFixture } from "../fixtures/routingForms";
|
import { createRoutingFormsFixture } from "../fixtures/routingForms";
|
||||||
import { createServersFixture } from "../fixtures/servers";
|
import { createServersFixture } from "../fixtures/servers";
|
||||||
import { createUsersFixture } from "../fixtures/users";
|
import { createUsersFixture } from "../fixtures/users";
|
||||||
|
@ -24,6 +25,7 @@ export interface Fixtures {
|
||||||
prisma: typeof prisma;
|
prisma: typeof prisma;
|
||||||
emails?: API;
|
emails?: API;
|
||||||
routingForms: ReturnType<typeof createRoutingFormsFixture>;
|
routingForms: ReturnType<typeof createRoutingFormsFixture>;
|
||||||
|
bookingPage: ReturnType<typeof createBookingPageFixture>;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -80,4 +82,8 @@ export const test = base.extend<Fixtures>({
|
||||||
await use(undefined);
|
await use(undefined);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
bookingPage: async ({ page }, use) => {
|
||||||
|
const bookingPage = createBookingPageFixture(page);
|
||||||
|
await use(bookingPage);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue