Fix: Show smsReminderNumber on booking success page (#8596)

This commit is contained in:
Hariom Balhara
2023-05-02 16:58:39 +00:00
committed by GitHub
parent 9ba90e18de
commit ada88a2f7e
18 changed files with 83 additions and 137 deletions
+3 -1
View File
@@ -27,6 +27,7 @@ import { getBookingWithResponses } from "@calcom/features/bookings/lib/get-booki
import {
SystemField,
getBookingFieldsWithSystemFields,
SMS_REMINDER_NUMBER_FIELD,
} from "@calcom/features/bookings/lib/getBookingFields";
import { parseRecurringEvent } from "@calcom/lib";
import { APP_NAME } from "@calcom/lib/constants";
@@ -487,7 +488,8 @@ export default function Success(props: SuccessProps) {
// We show rescheduleReason at the top
if (!field) return null;
const isSystemField = SystemField.safeParse(field.name);
if (isSystemField.success) return null;
// SMS_REMINDER_NUMBER_FIELD is a system field but doesn't have a dedicated place in the UI. So, it would be shown through the following responses list
if (isSystemField.success && field.name !== SMS_REMINDER_NUMBER_FIELD) return null;
const label = field.label || t(field.defaultLabel || "");
@@ -19,7 +19,10 @@ test("Can delete user account", async ({ page, users }) => {
const $passwordField = page.locator("[data-testid=password]");
await $passwordField.fill(user.username);
await Promise.all([page.waitForNavigation({ url: "/auth/logout" }), page.click("text=Delete my account")]);
await Promise.all([
page.waitForURL((url) => url.pathname === "/auth/logout"),
page.click("text=Delete my account"),
]);
await expect(page.locator(`[id="modal-title"]`)).toHaveText("You've been logged out");
});
@@ -17,9 +17,7 @@ test("Can reset forgotten password", async ({ page, users }) => {
// Press Enter
await Promise.all([
page.waitForNavigation({
url: (u) => u.pathname.startsWith("/auth/forgot-password/"),
}),
page.waitForURL((u) => u.pathname.startsWith("/auth/forgot-password/")),
page.press('input[name="email"]', "Enter"),
]);
@@ -38,7 +36,7 @@ test("Can reset forgotten password", async ({ page, users }) => {
await expect(page.locator(`text=Password updated`)).toBeVisible();
// Click button:has-text("Login")
await Promise.all([
page.waitForNavigation({ url: (u) => u.pathname.startsWith("/auth/login") }),
page.waitForURL((u) => u.pathname.startsWith("/auth/login")),
page.click('a:has-text("Login")'),
]);
+9 -17
View File
@@ -31,10 +31,8 @@ testBothBookers.describe("free user", (bookerVariant) => {
// eslint-disable-next-line playwright/no-conditional-in-test
if (bookerVariant !== "new-booker") {
// Navigate to book page
await page.waitForNavigation({
url(url) {
return url.pathname.endsWith("/book");
},
await page.waitForURL((url) => {
return url.pathname.endsWith("/book");
});
}
@@ -84,19 +82,15 @@ testBothBookers.describe("pro user", () => {
await page.waitForSelector('[data-testid="bookings"]');
await page.locator('[data-testid="edit_booking"]').nth(0).click();
await page.locator('[data-testid="reschedule"]').click();
await page.waitForNavigation({
url: (url) => {
const bookingId = url.searchParams.get("rescheduleUid");
return !!bookingId;
},
await page.waitForURL((url) => {
const bookingId = url.searchParams.get("rescheduleUid");
return !!bookingId;
});
await selectSecondAvailableTimeSlotNextMonth(page);
// --- fill form
await page.locator('[data-testid="confirm-reschedule-button"]').click();
await page.waitForNavigation({
url(url) {
return url.pathname.startsWith("/booking");
},
await page.waitForURL((url) => {
return url.pathname.startsWith("/booking");
});
});
@@ -108,10 +102,8 @@ testBothBookers.describe("pro user", () => {
await page.goto("/bookings/upcoming");
await page.locator('[data-testid="cancel"]').first().click();
await page.waitForNavigation({
url: (url) => {
return url.pathname.startsWith("/booking");
},
await page.waitForURL((url) => {
return url.pathname.startsWith("/booking");
});
await page.locator('[data-testid="cancel"]').click();
+4 -5
View File
@@ -71,10 +71,8 @@ testBothBookers.describe("Booking with Seats", (bookerVariant) => {
// to change the test as little as possible.
// eslint-disable-next-line playwright/no-conditional-in-test
if (bookerVariant === "old-booker") {
await page.waitForNavigation({
url(url) {
return url.pathname.endsWith("/book");
},
await page.waitForURL((url) => {
return url.pathname.endsWith("/book");
});
}
@@ -192,7 +190,7 @@ testBothBookers.describe("Booking with Seats", (bookerVariant) => {
await page.locator('[data-testid="confirm-reschedule-button"]').click();
await page.waitForNavigation({ url: /.*booking/ });
await page.waitForURL(/.*booking/);
await page.goto(`/reschedule/${references[1].referenceUid}`);
@@ -200,6 +198,7 @@ testBothBookers.describe("Booking with Seats", (bookerVariant) => {
await page.locator('[data-testid="confirm-reschedule-button"]').click();
// Using waitForUrl here fails the assertion `expect(oldBooking?.status).toBe(BookingStatus.CANCELLED);` probably because waitForUrl is considered complete before waitForNavigation and till that time the booking is not cancelled
await page.waitForNavigation({ url: /.*booking/ });
// Should expect old booking to be cancelled
@@ -31,19 +31,15 @@ test.skip("dynamic booking", async ({ page, users }) => {
await page.goto("/bookings/upcoming");
await page.locator('[data-testid="edit_booking"]').nth(0).click();
await page.locator('[data-testid="reschedule"]').click();
await page.waitForNavigation({
url: (url) => {
const bookingId = url.searchParams.get("rescheduleUid");
return !!bookingId;
},
await page.waitForURL((url) => {
const bookingId = url.searchParams.get("rescheduleUid");
return !!bookingId;
});
await selectSecondAvailableTimeSlotNextMonth(page);
// --- fill form
await page.locator('[data-testid="confirm-reschedule-button"]').click();
await page.waitForNavigation({
url(url) {
return url.pathname.startsWith("/booking");
},
await page.waitForURL((url) => {
return url.pathname.startsWith("/booking");
});
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
});
@@ -51,10 +47,8 @@ test.skip("dynamic booking", async ({ page, users }) => {
await test.step("Can cancel the recently created booking", async () => {
await page.goto("/bookings/upcoming");
await page.locator('[data-testid="cancel"]').first().click();
await page.waitForNavigation({
url: (url) => {
return url.pathname.startsWith("/booking");
},
await page.waitForURL((url) => {
return url.pathname.startsWith("/booking");
});
await page.locator('[data-testid="cancel"]').click();
+15 -21
View File
@@ -36,14 +36,12 @@ async function expectToBeNavigatingToEmbedTypesDialog(
if (!embedUrl) {
throw new Error("Couldn't find embedUrl");
}
await page.waitForNavigation({
url: (url) => {
return (
url.pathname === basePage &&
url.searchParams.get("dialog") === "embed" &&
url.searchParams.get("embedUrl") === embedUrl
);
},
await page.waitForURL((url) => {
return (
url.pathname === basePage &&
url.searchParams.get("dialog") === "embed" &&
url.searchParams.get("embedUrl") === embedUrl
);
});
}
@@ -54,16 +52,14 @@ async function expectToBeNavigatingToEmbedCodeAndPreviewDialog(
if (!embedUrl) {
throw new Error("Couldn't find embedUrl");
}
await page.waitForNavigation({
url: (url) => {
return (
url.pathname === basePage &&
url.searchParams.get("dialog") === "embed" &&
url.searchParams.get("embedUrl") === embedUrl &&
url.searchParams.get("embedType") === embedType &&
url.searchParams.get("embedTabName") === "embed-code"
);
},
await page.waitForURL((url) => {
return (
url.pathname === basePage &&
url.searchParams.get("dialog") === "embed" &&
url.searchParams.get("embedUrl") === embedUrl &&
url.searchParams.get("embedType") === embedType &&
url.searchParams.get("embedTabName") === "embed-code"
);
});
}
@@ -183,9 +179,7 @@ test.describe("Embed Code Generator Tests", () => {
await page.goto(`/event-types`);
await Promise.all([
page.locator('[href*="/event-types/"]').first().click(),
page.waitForNavigation({
url: (url) => url.pathname.startsWith("/event-types/"),
}),
page.waitForURL((url) => url.pathname.startsWith("/event-types/")),
]);
});
+6 -12
View File
@@ -94,10 +94,8 @@ test.describe("Event Types tests", () => {
const $eventTypes = page.locator("[data-testid=event-types] > li a");
const firstEventTypeElement = $eventTypes.first();
await firstEventTypeElement.click();
await page.waitForNavigation({
url: (url) => {
return !!url.pathname.match(/\/event-types\/.+/);
},
await page.waitForURL((url) => {
return !!url.pathname.match(/\/event-types\/.+/);
});
await page.locator("[data-testid=update-eventtype]").click();
const toast = await page.waitForSelector("div[class*='data-testid-toast-success']");
@@ -108,10 +106,8 @@ test.describe("Event Types tests", () => {
const $eventTypes = page.locator("[data-testid=event-types] > li a");
const firstEventTypeElement = $eventTypes.first();
await firstEventTypeElement.click();
await page.waitForNavigation({
url: (url) => {
return !!url.pathname.match(/\/event-types\/.+/);
},
await page.waitForURL((url) => {
return !!url.pathname.match(/\/event-types\/.+/);
});
const locationData = ["location 1", "location 2", "location 3"];
@@ -153,10 +149,8 @@ test.describe("Event Types tests", () => {
// to change the test as little as possible.
// eslint-disable-next-line playwright/no-conditional-in-test
if (bookerVariant === "old-booker") {
await page.waitForNavigation({
url(url) {
return url.pathname.endsWith("/book");
},
await page.waitForURL((url) => {
return url.pathname.endsWith("/book");
});
}
+2 -2
View File
@@ -346,12 +346,12 @@ export async function getPaymentCredential(page: Page) {
/** We start the Stripe flow */
await Promise.all([
page.waitForNavigation({ url: "https://connect.stripe.com/oauth/v2/authorize?*" }),
page.waitForURL("https://connect.stripe.com/oauth/v2/authorize?*"),
page.click('[data-testid="install-app-button"]'),
]);
await Promise.all([
page.waitForNavigation({ url: "/apps/installed/payment?hl=stripe" }),
page.waitForURL("/apps/installed/payment?hl=stripe"),
/** We skip filling Stripe forms (testing mode only) */
page.click('[id="skip-account-app"]'),
]);
@@ -49,7 +49,7 @@ test.describe("Stripe integration", () => {
await page.fill('[name="name"]', "Stripe Stripeson");
await page.fill('[name="email"]', "test@example.com");
await Promise.all([page.waitForNavigation({ url: "/payment/*" }), page.press('[name="email"]', "Enter")]);
await Promise.all([page.waitForURL("/payment/*"), page.press('[name="email"]', "Enter")]);
const stripeFrame = page
.frameLocator('iframe[src^="https://js.stripe.com/v3/elements-inner-card-"]')
+4 -8
View File
@@ -114,10 +114,8 @@ async function bookEventOnThisPage(page: Page) {
await bookTimeSlot(page);
// Make sure we're navigated to the success page
await page.waitForNavigation({
url(url) {
return url.pathname.startsWith("/booking");
},
await page.waitForURL((url) => {
return url.pathname.startsWith("/booking");
});
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
}
@@ -156,10 +154,8 @@ export const createNewEventType = async (page: Page, args: { eventTitle: string
await page.fill("[name=length]", "10");
await page.click("[type=submit]");
await page.waitForNavigation({
url(url) {
return url.pathname !== "/event-types";
},
await page.waitForURL((url) => {
return url.pathname !== "/event-types";
});
};
@@ -362,8 +362,8 @@ async function rescheduleFromTheLinkOnPage({
await page.waitForLoadState();
await selectFirstAvailableTimeSlotNextMonth(page);
if (bookerVariant === "old-booker") {
await page.waitForNavigation({
url: (url) => url.pathname.endsWith("/book"),
await page.waitForURL((url) => {
return url.pathname.endsWith("/book");
});
}
await page.click('[data-testid="confirm-reschedule-button"]');
@@ -380,8 +380,8 @@ async function openBookingFormInPreviewTab(
await previewTabPage.waitForLoadState();
await selectFirstAvailableTimeSlotNextMonth(previewTabPage);
if (bookerVariant === "old-booker") {
await previewTabPage.waitForNavigation({
url: (url) => url.pathname.endsWith("/book"),
await previewTabPage.waitForURL((url) => {
return url.pathname.endsWith("/book");
});
}
return previewTabPage;
+2 -4
View File
@@ -149,10 +149,8 @@ testBothBookers.describe("Reschedule Tests", async () => {
await page.locator('[data-testid="confirm-reschedule-button"]').click();
await page.waitForNavigation({
url(url) {
return url.pathname.indexOf("/payment") > -1;
},
await page.waitForURL((url) => {
return url.pathname.indexOf("/payment") > -1;
});
await expect(page).toHaveURL(/.*payment/);
+1 -3
View File
@@ -24,9 +24,7 @@ test("add webhook & test that creating an event triggers a webhook call", async
await Promise.all([
page.click("[type=submit]"),
page.waitForNavigation({
url: (url) => url.pathname.endsWith("/settings/developer/webhooks"),
}),
page.waitForURL((url) => url.pathname.endsWith("/settings/developer/webhooks")),
]);
// page contains the url
@@ -130,9 +130,7 @@ test.describe("Routing Forms", () => {
// Install app
await page.goto(`/apps/routing-forms`);
await page.click('[data-testid="install-app-button"]');
await page.waitForNavigation({
url: (url) => url.pathname === `/apps/routing-forms/forms`,
});
await page.waitForURL((url) => url.pathname === `/apps/routing-forms/forms`);
});
test.afterEach(async ({ users }) => {
@@ -163,9 +161,7 @@ test.describe("Routing Forms", () => {
// Install app
await page.goto(`/apps/routing-forms`);
await page.click('[data-testid="install-app-button"]');
await page.waitForNavigation({
url: (url) => url.pathname === `/apps/routing-forms/forms`,
});
await page.waitForURL((url) => url.pathname === `/apps/routing-forms/forms`);
return user;
};
@@ -260,17 +256,13 @@ test.describe("Routing Forms", () => {
// Router should be publicly accessible
await users.logout();
page.goto(`/router?form=${routingForm.id}&Test field=event-routing`);
await page.waitForNavigation({
url(url) {
return url.pathname.endsWith("/pro/30min");
},
await page.waitForURL((url) => {
return url.pathname.endsWith("/pro/30min");
});
page.goto(`/router?form=${routingForm.id}&Test field=external-redirect`);
await page.waitForNavigation({
url(url) {
return url.hostname.includes("google.com");
},
await page.waitForURL((url) => {
return url.hostname.includes("google.com");
});
await page.goto(`/router?form=${routingForm.id}&Test field=custom-page`);
@@ -352,19 +344,15 @@ async function fillSeededForm(page: Page, routingFormId: string) {
await gotoRoutingLink(page, routingFormId);
await page.fill('[data-testid="form-field"]', "event-routing");
page.click('button[type="submit"]');
await page.waitForNavigation({
url(url) {
return url.pathname.endsWith("/pro/30min");
},
await page.waitForURL((url) => {
return url.pathname.endsWith("/pro/30min");
});
await gotoRoutingLink(page, routingFormId);
await page.fill('[data-testid="form-field"]', "external-redirect");
page.click('button[type="submit"]');
await page.waitForNavigation({
url(url) {
return url.hostname.includes("google.com");
},
await page.waitForURL((url) => {
return url.hostname.includes("google.com");
});
await gotoRoutingLink(page, routingFormId);
@@ -19,14 +19,10 @@ const installApps = async (page: Page, users: Fixtures["users"]) => {
await user.login();
await page.goto(`/apps/routing-forms`);
await page.click('[data-testid="install-app-button"]');
await page.waitForNavigation({
url: (url) => url.pathname === `/apps/routing-forms/forms`,
});
await page.waitForURL((url) => url.pathname === `/apps/routing-forms/forms`);
await page.goto(`/apps/typeform`);
await page.click('[data-testid="install-app-button"]');
await page.waitForNavigation({
url: (url) => url.pathname === `/apps/typeform/how-to-use`,
});
await page.waitForURL((url) => url.pathname === `/apps/typeform/how-to-use`);
};
test.describe("Typeform App", () => {
@@ -93,10 +93,8 @@ async function selectFirstAvailableTimeSlotNextMonth(frame: Frame, page: Page) {
export async function bookFirstEvent(username: string, frame: Frame, page: Page) {
// Click first event type
await frame.click('[data-testid="event-type-link"]');
await frame.waitForNavigation({
url(url) {
return !!url.pathname.match(new RegExp(`/${username}/.*$`));
},
await frame.waitForURL((url) => {
return !!url.pathname.match(new RegExp(`/${username}/.*$`));
});
// Let current month dates fully render.
@@ -107,10 +105,8 @@ export async function bookFirstEvent(username: string, frame: Frame, page: Page)
// expect(await page.screenshot()).toMatchSnapshot("availability-page-1.png");
const eventSlug = new URL(frame.url()).pathname;
await selectFirstAvailableTimeSlotNextMonth(frame, page);
await frame.waitForNavigation({
url(url) {
return url.pathname.includes(`/${username}/book`);
},
await frame.waitForURL((url) => {
return url.pathname.includes(`/${username}/book`);
});
// expect(await page.screenshot()).toMatchSnapshot("booking-page.png");
// --- fill form
@@ -136,10 +132,8 @@ export async function bookFirstEvent(username: string, frame: Frame, page: Page)
export async function rescheduleEvent(username, frame, page) {
await selectFirstAvailableTimeSlotNextMonth(frame, page);
await frame.waitForNavigation({
url(url) {
return url.pathname.includes(`/${username}/book`);
},
await frame.waitForURL((url) => {
return url.pathname.includes(`/${username}/book`);
});
// --- fill form
await frame.press('[name="email"]', "Enter");
+1 -1
View File
@@ -12,7 +12,7 @@ const outputDir = path.join(__dirname, "test-results");
// So, if not in CI, keep the timers high, if the test is stuck somewhere and there is unnecessary wait developer can see in browser that it's stuck
const DEFAULT_NAVIGATION_TIMEOUT = process.env.CI ? 15000 : 50000;
const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 10000 : 50000;
const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 15000 : 50000;
// Test Timeout can hit due to slow expect, slow navigation.
// So, it should me much higher than sum of expect and navigation timeouts as there can be many async expects and navigations in a single test