* feat(appStore): add isOAuth config * refactor(appStore): EventTypeAppSettngsInterface * refactor(qr_code): split EventTypeAppCardInterface and EventTypeAppSettingsInterface * feat(appStore): redirect to onboarding for stripe and basecam * fix(ui/ScrollableArea): overflow indicator not working * feat(apps): new install app flow * fix(configureStep): get disabled props for settings * fix: getAppInstallsBySlug now use teamIds * chore: Alby to AppSettingsInterface * chore: Giphy to appsettings interface * chore: GTM migration * chore: GT4 - migration * chore: fathom migration * chore: paypal * feat: basecamp migration * feat: metapixel migration * feat:plausable * feat:stripe * fix merge issues * fix merge issues in new app install flow steps * wip: callback to onboarding * fix: imports * fix: more imports * feat: use redirect to onboarding on install flow * fix: redirect to event-type after oauth flow * When clicking on install new app button, only redirect to the new app install flow if it is an oAuth app or an app that extends the EventType feature in it's config * code refactor, skip event-type step * removed extra consoles * so that no one can change the eventTypeId in url * theme support enabled * only pass eventTypeId instead of whole evetType obj to OmniInstallAppButton * fix: clicking on event-type gives error and redirects to /apps * saved appOnboardingRedirectUrl to OAuth State * fix: a user having no team breaks the onboarding flow * add optional chaining to appMetadata.extendsFeature and appMetadata.isOAuth; * encode appOnboardingRedirectUrl * fix: dark theme ui issues * skip configure step if no-event types if user/team does not have event-type then skip configure step and goto apps/installed/[category] * exclude calendars from apps- onboarding flow * Update getAppOnboardingRedirectUrl.ts * fix: On configure step, inputs aren't showing errors * change route from `apps/onboarding` to `apps/installation` * fix: flow not correctly working for teams * should only allow team ADMIN or OWER to install an app to team * Prevent two payment apps to be enabled * removed loading state * Fix type error * undo new-app-flow from OmniInstallAppButton * remove OAuth Step, handle step numbering * fix: redirect url * getAppOnboardingRedirectUrl refactor * for debugging * Revert "for debugging" This reverts commit b9362c1a8f47f2280e684c213d7ec08d04a8ac4c. * fix: added toaster * feat: added support to select multiple events (almost) * hide button * Move inner form outside outer form using portal Due to limitations with nested forms in React Hook Form, moved the inner form outside the outer form using a portal to ensure proper form handling. * submit buttons refs madness * removed configure step we had to use query params to manage selected event-types, between routes which was causing 2 issues: * each time we selected or unselected an event the whole page was reloaded including getserversideprops being called again and again * the form was reloaded causing more issues * removed extra unwanted code * small fix * fix: type error * fix: types * implemented suggested changes * removed step footer * fixed error.message * removed commented styles * removed step footer * fix: Display team event types instead of user's on event types step when team selected * fix: typo * removed shouldLockDisableProps * refactor setUpdatedEventTypesStatus, fix type * removed extra code * can't delete while saving * added translations * fix: loading in select account step, fix handle onSelect params type * Fix typo * feat: add skip button to event-types step * use set-up-later button in tests * added skip button to configure step as well * feat: add test for analytics apps using the new app install flow * feat: add test for stripe 1 * feat: add test for stripe 2 * Fix: Redirect only those apps that extend 'EventType' to the new app install flow (#14527) * fix: type errors * fix: failing tests * fix: tests * fix test flakiness * better naming and code refactor for analytics apps tests * run tests parallelly * removed network idle, giving error * another shot at test flakiness * Fix: can't install apps without team selector dropdown on main app store page. * fix: test flakiness * fix: account select loading issue * removed getPaymentCredential (unused) * fix: only redirect after the app has been added to all the event-types * remove overflowIndicatorStyles * fixed failing test * fix: exclude org team events * undo some random merge changes --------- Co-authored-by: Morgan Vernay <morgan@cal.com> Co-authored-by: sean-brydon <sean@cal.com> Co-authored-by: Keith Williams <keithwillcode@gmail.com> Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com> Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Co-authored-by: Omar López <zomars@me.com>
510 lines
19 KiB
TypeScript
510 lines
19 KiB
TypeScript
import { expect } from "@playwright/test";
|
|
import type Prisma from "@prisma/client";
|
|
|
|
import prisma from "@calcom/prisma";
|
|
import { SchedulingType } from "@calcom/prisma/enums";
|
|
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
|
|
|
import { test } from "./lib/fixtures";
|
|
import type { Fixtures } from "./lib/fixtures";
|
|
import { todo, selectFirstAvailableTimeSlotNextMonth } from "./lib/testUtils";
|
|
|
|
test.describe.configure({ mode: "parallel" });
|
|
test.afterEach(({ users }) => users.deleteAll());
|
|
|
|
const IS_STRIPE_ENABLED = !!(
|
|
process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY &&
|
|
process.env.STRIPE_CLIENT_ID &&
|
|
process.env.STRIPE_PRIVATE_KEY &&
|
|
process.env.PAYMENT_FEE_FIXED &&
|
|
process.env.PAYMENT_FEE_PERCENTAGE
|
|
);
|
|
|
|
test.describe("Stripe integration skip true", () => {
|
|
// eslint-disable-next-line playwright/no-skipped-test
|
|
test.skip(!IS_STRIPE_ENABLED, "It should only run if Stripe is installed");
|
|
|
|
test.describe("Stripe integration dashboard", () => {
|
|
test("Can add Stripe integration", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
await user.apiLogin();
|
|
|
|
await user.installStripePersonal({ skip: true });
|
|
|
|
await expect(page.locator(`h3:has-text("Stripe")`)).toBeVisible();
|
|
await page.getByRole("list").getByRole("button").click();
|
|
await expect(page.getByRole("button", { name: "Remove App" })).toBeVisible();
|
|
});
|
|
});
|
|
test("when enabling Stripe, credentialId is included", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
|
|
await user.installStripePersonal({ skip: true });
|
|
|
|
const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.setupEventWithPrice(eventType, "stripe");
|
|
|
|
// Need to wait for the DB to be updated with the metadata
|
|
await page.waitForResponse((res) => res.url().includes("update") && res.status() === 200);
|
|
|
|
// Check event type metadata to see if credentialId is included
|
|
const eventTypeMetadata = await prisma.eventType.findFirst({
|
|
where: {
|
|
id: eventType.id,
|
|
},
|
|
select: {
|
|
metadata: true,
|
|
},
|
|
});
|
|
|
|
const metadata = EventTypeMetaDataSchema.parse(eventTypeMetadata?.metadata);
|
|
|
|
const stripeAppMetadata = metadata?.apps?.stripe;
|
|
|
|
expect(stripeAppMetadata).toHaveProperty("credentialId");
|
|
expect(typeof stripeAppMetadata?.credentialId).toBe("number");
|
|
});
|
|
test("when enabling Stripe, team credentialId is included", async ({ page, users }) => {
|
|
const ownerObj = { username: "pro-user", name: "pro-user" };
|
|
const teamMatesObj = [
|
|
{ name: "teammate-1" },
|
|
{ name: "teammate-2" },
|
|
{ name: "teammate-3" },
|
|
{ name: "teammate-4" },
|
|
];
|
|
|
|
const owner = await users.create(ownerObj, {
|
|
hasTeam: true,
|
|
teammates: teamMatesObj,
|
|
schedulingType: SchedulingType.COLLECTIVE,
|
|
});
|
|
await owner.apiLogin();
|
|
const { team } = await owner.getFirstTeamMembership();
|
|
|
|
const teamEvent = await owner.getFirstTeamEvent(team.id);
|
|
|
|
await owner.installStripeTeam({ skip: true, teamId: team.id });
|
|
await owner.setupEventWithPrice(teamEvent, "stripe");
|
|
|
|
// Need to wait for the DB to be updated with the metadata
|
|
await page.waitForResponse((res) => res.url().includes("update") && res.status() === 200);
|
|
|
|
// Check event type metadata to see if credentialId is included
|
|
const eventTypeMetadata = await prisma.eventType.findFirst({
|
|
where: {
|
|
id: teamEvent.id,
|
|
},
|
|
select: {
|
|
metadata: true,
|
|
},
|
|
});
|
|
|
|
const metadata = EventTypeMetaDataSchema.parse(eventTypeMetadata?.metadata);
|
|
|
|
const stripeAppMetadata = metadata?.apps?.stripe;
|
|
|
|
expect(stripeAppMetadata).toHaveProperty("credentialId");
|
|
expect(typeof stripeAppMetadata?.credentialId).toBe("number");
|
|
});
|
|
test("Can book a paid booking", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
|
|
await user.installStripePersonal({ skip: true });
|
|
await user.setupEventWithPrice(eventType, "stripe");
|
|
await user.bookAndPayEvent(eventType);
|
|
// success
|
|
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
|
|
});
|
|
|
|
test("Pending payment booking should not be confirmed by default", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
|
|
await user.installStripePersonal({ skip: true });
|
|
await user.setupEventWithPrice(eventType, "stripe");
|
|
|
|
// booking process without payment
|
|
await page.goto(`${user.username}/${eventType?.slug}`);
|
|
await selectFirstAvailableTimeSlotNextMonth(page);
|
|
// --- fill form
|
|
await page.fill('[name="name"]', "Stripe Stripeson");
|
|
await page.fill('[name="email"]', "test@example.com");
|
|
|
|
await Promise.all([page.waitForURL("/payment/*"), page.press('[name="email"]', "Enter")]);
|
|
|
|
await page.goto(`/bookings/upcoming`);
|
|
|
|
await expect(page.getByText("Unconfirmed")).toBeVisible();
|
|
await expect(page.getByText("Pending payment").last()).toBeVisible();
|
|
});
|
|
|
|
test("Paid booking should be able to be rescheduled", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
|
|
await user.installStripePersonal({ skip: true });
|
|
await user.setupEventWithPrice(eventType, "stripe");
|
|
await user.bookAndPayEvent(eventType);
|
|
|
|
// Rescheduling the event
|
|
await Promise.all([page.waitForURL("/booking/*"), page.click('[data-testid="reschedule-link"]')]);
|
|
|
|
await selectFirstAvailableTimeSlotNextMonth(page);
|
|
|
|
await Promise.all([
|
|
page.waitForURL("/payment/*"),
|
|
page.click('[data-testid="confirm-reschedule-button"]'),
|
|
]);
|
|
|
|
await user.makePaymentUsingStripe();
|
|
});
|
|
|
|
test("Paid booking should be able to be cancelled", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
|
|
await user.installStripePersonal({ skip: true });
|
|
await user.setupEventWithPrice(eventType, "stripe");
|
|
await user.bookAndPayEvent(eventType);
|
|
|
|
await page.click('[data-testid="cancel"]');
|
|
await page.click('[data-testid="confirm_cancel"]');
|
|
|
|
await expect(await page.locator('[data-testid="cancelled-headline"]').first()).toBeVisible();
|
|
});
|
|
|
|
test.describe("When event is paid and confirmed", () => {
|
|
let user: Awaited<ReturnType<Fixtures["users"]["create"]>>;
|
|
let eventType: Prisma.EventType;
|
|
|
|
test.beforeEach(async ({ page, users }) => {
|
|
user = await users.create();
|
|
eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
|
|
await user.installStripePersonal({ skip: true });
|
|
await user.setupEventWithPrice(eventType, "stripe");
|
|
await user.bookAndPayEvent(eventType);
|
|
await user.confirmPendingPayment();
|
|
});
|
|
|
|
test("Payment should confirm pending payment booking", async ({ page, users }) => {
|
|
await page.goto("/bookings/upcoming");
|
|
|
|
const paidBadge = page.locator('[data-testid="paid_badge"]').first();
|
|
|
|
await expect(paidBadge).toBeVisible();
|
|
expect(await paidBadge.innerText()).toBe("Paid");
|
|
});
|
|
|
|
test("Paid and confirmed booking should be able to be rescheduled", async ({ page, users }) => {
|
|
await Promise.all([page.waitForURL("/booking/*"), page.click('[data-testid="reschedule-link"]')]);
|
|
|
|
await selectFirstAvailableTimeSlotNextMonth(page);
|
|
|
|
await page.click('[data-testid="confirm-reschedule-button"]');
|
|
|
|
await expect(page.getByText("This meeting is scheduled")).toBeVisible();
|
|
});
|
|
|
|
todo("Payment should trigger a BOOKING_PAID webhook");
|
|
});
|
|
|
|
test.describe("Change stripe presented currency", () => {
|
|
test("Should be able to change currency", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
|
|
await user.installStripePersonal({ skip: true });
|
|
|
|
// Edit currency inside event type page
|
|
await page.goto(`/event-types/${eventType?.id}?tabName=apps`);
|
|
|
|
// Enable Stripe
|
|
await page.locator("#event-type-form").getByRole("switch").click();
|
|
|
|
// Set price
|
|
await page.getByTestId("stripe-price-input").fill("200");
|
|
|
|
// Select currency in dropdown
|
|
await page.getByTestId("stripe-currency-select").click();
|
|
await page.locator("#react-select-2-input").fill("mexi");
|
|
await page.locator("#react-select-2-option-81").click();
|
|
|
|
await page.getByTestId("update-eventtype").click();
|
|
|
|
// Book event
|
|
await page.goto(`${user.username}/${eventType?.slug}`);
|
|
|
|
// Confirm MXN currency it's displayed use expect
|
|
await expect(await page.getByText("MX$200.00")).toBeVisible();
|
|
|
|
await selectFirstAvailableTimeSlotNextMonth(page);
|
|
|
|
// Confirm again in book form page
|
|
await expect(await page.getByText("MX$200.00")).toBeVisible();
|
|
|
|
// --- fill form
|
|
await page.fill('[name="name"]', "Stripe Stripeson");
|
|
await page.fill('[name="email"]', "stripe@example.com");
|
|
|
|
// Confirm booking
|
|
await page.click('[data-testid="confirm-book-button"]');
|
|
|
|
// wait for url to be payment
|
|
await page.waitForURL("/payment/*");
|
|
|
|
// Confirm again in book form page
|
|
await expect(await page.getByText("MX$200.00")).toBeVisible();
|
|
});
|
|
});
|
|
});
|
|
|
|
test.describe("Stripe integration with the new app install flow skip flase", () => {
|
|
// eslint-disable-next-line playwright/no-skipped-test
|
|
test.skip(!IS_STRIPE_ENABLED, "It should only run if Stripe is installed");
|
|
|
|
test("when enabling Stripe, credentialId is included skip false", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
const eventTypes = await user.getUserEventsAsOwner();
|
|
const eventTypeIds = eventTypes.map((item) => item.id);
|
|
|
|
// await installStripe(page, "personal", false, eventTypeIds);
|
|
await user.installStripePersonal({ skip: false, eventTypeIds });
|
|
|
|
const eventTypeMetadatas = await prisma.eventType.findMany({
|
|
where: {
|
|
id: {
|
|
in: eventTypeIds,
|
|
},
|
|
},
|
|
select: {
|
|
metadata: true,
|
|
},
|
|
});
|
|
|
|
for (const eventTypeMetadata of eventTypeMetadatas) {
|
|
const metadata = EventTypeMetaDataSchema.parse(eventTypeMetadata?.metadata);
|
|
const stripeAppMetadata = metadata?.apps?.stripe;
|
|
expect(stripeAppMetadata).toHaveProperty("credentialId");
|
|
expect(typeof stripeAppMetadata?.credentialId).toBe("number");
|
|
}
|
|
});
|
|
test("when enabling Stripe, team credentialId is included skip false", async ({ page, users }) => {
|
|
const ownerObj = { username: "pro-user", name: "pro-user" };
|
|
const teamMatesObj = [
|
|
{ name: "teammate-1" },
|
|
{ name: "teammate-2" },
|
|
{ name: "teammate-3" },
|
|
{ name: "teammate-4" },
|
|
];
|
|
|
|
const owner = await users.create(ownerObj, {
|
|
hasTeam: true,
|
|
teammates: teamMatesObj,
|
|
schedulingType: SchedulingType.COLLECTIVE,
|
|
});
|
|
await owner.apiLogin();
|
|
const { team } = await owner.getFirstTeamMembership();
|
|
|
|
const teamEvent = await owner.getFirstTeamEvent(team.id);
|
|
|
|
await owner.installStripeTeam({ skip: false, teamId: team.id, eventTypeIds: [teamEvent.id] });
|
|
|
|
// Check event type metadata to see if credentialId is included
|
|
const eventTypeMetadata = await prisma.eventType.findFirst({
|
|
where: {
|
|
id: teamEvent.id,
|
|
},
|
|
select: {
|
|
metadata: true,
|
|
},
|
|
});
|
|
|
|
const metadata = EventTypeMetaDataSchema.parse(eventTypeMetadata?.metadata);
|
|
|
|
const stripeAppMetadata = metadata?.apps?.stripe;
|
|
|
|
expect(stripeAppMetadata).toHaveProperty("credentialId");
|
|
expect(typeof stripeAppMetadata?.credentialId).toBe("number");
|
|
});
|
|
test("Can book a paid booking skip false", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
|
|
await user.installStripePersonal({ skip: false, eventTypeIds: [eventType.id] });
|
|
await user.bookAndPayEvent(eventType);
|
|
// success
|
|
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
|
|
});
|
|
test("Pending payment booking should not be confirmed by default skip false", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
|
|
await user.installStripePersonal({ skip: false, eventTypeIds: [eventType.id] });
|
|
|
|
// booking process without payment
|
|
await page.goto(`${user.username}/${eventType?.slug}`);
|
|
await selectFirstAvailableTimeSlotNextMonth(page);
|
|
// --- fill form
|
|
await page.fill('[name="name"]', "Stripe Stripeson");
|
|
await page.fill('[name="email"]', "test@example.com");
|
|
|
|
await Promise.all([page.waitForURL("/payment/*"), page.press('[name="email"]', "Enter")]);
|
|
|
|
await page.goto(`/bookings/upcoming`);
|
|
|
|
await expect(page.getByText("Unconfirmed")).toBeVisible();
|
|
await expect(page.getByText("Pending payment").last()).toBeVisible();
|
|
});
|
|
|
|
test("Paid booking should be able to be rescheduled skip false", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
|
|
await user.installStripePersonal({ skip: false, eventTypeIds: [eventType.id] });
|
|
await user.bookAndPayEvent(eventType);
|
|
|
|
// Rescheduling the event
|
|
await Promise.all([page.waitForURL("/booking/*"), page.click('[data-testid="reschedule-link"]')]);
|
|
|
|
await selectFirstAvailableTimeSlotNextMonth(page);
|
|
|
|
await Promise.all([
|
|
page.waitForURL("/payment/*"),
|
|
page.click('[data-testid="confirm-reschedule-button"]'),
|
|
]);
|
|
|
|
await user.makePaymentUsingStripe();
|
|
});
|
|
|
|
test("Paid booking should be able to be cancelled skip false", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
|
|
await user.installStripePersonal({ skip: false, eventTypeIds: [eventType.id] });
|
|
await user.bookAndPayEvent(eventType);
|
|
|
|
await page.click('[data-testid="cancel"]');
|
|
await page.click('[data-testid="confirm_cancel"]');
|
|
|
|
await expect(await page.locator('[data-testid="cancelled-headline"]').first()).toBeVisible();
|
|
});
|
|
|
|
test.describe("When event is paid and confirmed skip false", () => {
|
|
let user: Awaited<ReturnType<Fixtures["users"]["create"]>>;
|
|
let eventType: Prisma.EventType;
|
|
|
|
test.beforeEach(async ({ page, users }) => {
|
|
user = await users.create();
|
|
eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
await page.goto("/apps/installed");
|
|
|
|
await user.installStripePersonal({ skip: false, eventTypeIds: [eventType.id] });
|
|
await user.bookAndPayEvent(eventType);
|
|
await user.confirmPendingPayment();
|
|
});
|
|
|
|
test("Payment should confirm pending payment booking skip false", async ({ page, users }) => {
|
|
await page.goto("/bookings/upcoming");
|
|
|
|
const paidBadge = page.locator('[data-testid="paid_badge"]').first();
|
|
|
|
await expect(paidBadge).toBeVisible();
|
|
expect(await paidBadge.innerText()).toBe("Paid");
|
|
});
|
|
|
|
test("Paid and confirmed booking should be able to be rescheduled skip false", async ({
|
|
page,
|
|
users,
|
|
}) => {
|
|
await Promise.all([page.waitForURL("/booking/*"), page.click('[data-testid="reschedule-link"]')]);
|
|
|
|
await selectFirstAvailableTimeSlotNextMonth(page);
|
|
|
|
await page.click('[data-testid="confirm-reschedule-button"]');
|
|
|
|
await expect(page.getByText("This meeting is scheduled")).toBeVisible();
|
|
});
|
|
|
|
todo("Payment should trigger a BOOKING_PAID webhook");
|
|
});
|
|
|
|
test.describe("Change stripe presented currency skip false", () => {
|
|
test("Should be able to change currency skip false", async ({ page, users }) => {
|
|
const user = await users.create();
|
|
const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType;
|
|
await user.apiLogin();
|
|
|
|
await page.goto("/apps/stripe");
|
|
/** We start the Stripe flow */
|
|
await page.click('[data-testid="install-app-button"]');
|
|
await page.click('[data-testid="install-app-button-personal"]');
|
|
|
|
await page.waitForURL("https://connect.stripe.com/oauth/v2/authorize?*");
|
|
/** We skip filling Stripe forms (testing mode only) */
|
|
await page.click('[id="skip-account-app"]');
|
|
await page.waitForURL(`apps/installation/event-types?slug=stripe`);
|
|
await page.click(`[data-testid="select-event-type-${eventType.id}"]`);
|
|
await page.click(`[data-testid="save-event-types"]`);
|
|
await page.locator('[data-testid="stripe-price-input"]').fill(`200`);
|
|
|
|
// Select currency in dropdown
|
|
await page.getByTestId("stripe-currency-select").click();
|
|
await page.locator("#react-select-2-input").fill("mexi");
|
|
await page.locator("#react-select-2-option-81").click();
|
|
|
|
await page.click(`[data-testid="configure-step-save"]`);
|
|
await page.waitForURL(`event-types`);
|
|
|
|
// Book event
|
|
await page.goto(`${user.username}/${eventType?.slug}`);
|
|
|
|
// Confirm MXN currency it's displayed use expect
|
|
await expect(await page.getByText("MX$200.00")).toBeVisible();
|
|
|
|
await selectFirstAvailableTimeSlotNextMonth(page);
|
|
|
|
// Confirm again in book form page
|
|
await expect(await page.getByText("MX$200.00")).toBeVisible();
|
|
|
|
// --- fill form
|
|
await page.fill('[name="name"]', "Stripe Stripeson");
|
|
await page.fill('[name="email"]', "stripe@example.com");
|
|
|
|
// Confirm booking
|
|
await page.click('[data-testid="confirm-book-button"]');
|
|
|
|
// wait for url to be payment
|
|
await page.waitForURL("/payment/*");
|
|
|
|
// Confirm again in book form page
|
|
await expect(await page.getByText("MX$200.00")).toBeVisible();
|
|
});
|
|
});
|
|
});
|