fix: All flaky e2e tests (#16758)
* test * fix: flaky e2e tests (The Endgame) * Update pr.yml * Update * revert * revert * add * update * fix * fis another * update * another * fix type error * Update team-invitation.e2e.ts * update a test * another fix * last update * update
This commit is contained in:
@@ -6,141 +6,37 @@ export type TApp = {
|
||||
organizerInputPlaceholder?: string;
|
||||
label: string;
|
||||
};
|
||||
type TAllApps = {
|
||||
[key: string]: TApp;
|
||||
};
|
||||
|
||||
const ALL_APPS: TAllApps = {
|
||||
around: {
|
||||
slug: "around",
|
||||
type: "integrations:around_video",
|
||||
organizerInputPlaceholder: "https://www.around.co/rick",
|
||||
label: "Around Video",
|
||||
},
|
||||
campfire: {
|
||||
slug: "campfire",
|
||||
type: "integrations:campfire_video",
|
||||
organizerInputPlaceholder: "https://party.campfire.to/your-team",
|
||||
label: "Campfire",
|
||||
},
|
||||
demodesk: {
|
||||
slug: "demodesk",
|
||||
type: "integrations:demodesk_video",
|
||||
organizerInputPlaceholder: "https://demodesk.com/meet/mylink",
|
||||
label: "Demodesk",
|
||||
},
|
||||
discord: {
|
||||
slug: "discord",
|
||||
type: "integrations:discord_video",
|
||||
organizerInputPlaceholder: "https://discord.gg/420gg69",
|
||||
label: "Discord",
|
||||
},
|
||||
eightxeight: {
|
||||
slug: "eightxeight",
|
||||
type: "integrations:eightxeight_video",
|
||||
organizerInputPlaceholder: "https://8x8.vc/company",
|
||||
label: "8x8",
|
||||
},
|
||||
"element-call": {
|
||||
slug: "element-call",
|
||||
type: "integrations:element-call_video",
|
||||
organizerInputPlaceholder: "https://call.element.io/",
|
||||
label: "Element Call",
|
||||
},
|
||||
facetime: {
|
||||
slug: "facetime",
|
||||
type: "integrations:facetime_video",
|
||||
organizerInputPlaceholder: "https://facetime.apple.com/join=#v=1&p=zU9w7QzuEe",
|
||||
label: "Facetime",
|
||||
},
|
||||
mirotalk: {
|
||||
slug: "mirotalk",
|
||||
type: "integrations:mirotalk_video",
|
||||
organizerInputPlaceholder: "https://p2p.mirotalk.com/join/80085ShinyPhone",
|
||||
label: "Mirotalk",
|
||||
},
|
||||
ping: {
|
||||
slug: "ping",
|
||||
type: "integrations:ping_video",
|
||||
organizerInputPlaceholder: "https://www.ping.gg/call/theo",
|
||||
label: "Ping.gg",
|
||||
},
|
||||
riverside: {
|
||||
slug: "riverside",
|
||||
type: "integrations:riverside_video",
|
||||
organizerInputPlaceholder: "https://riverside.fm/studio/abc123",
|
||||
label: "Riverside Video",
|
||||
},
|
||||
roam: {
|
||||
slug: "roam",
|
||||
type: "integrations:roam_video",
|
||||
organizerInputPlaceholder: "https://ro.am/r/#/p/yHwFBQrRTMuptqKYo_wu8A/huzRiHnR-np4RGYKV-c0pQ",
|
||||
label: "Roam",
|
||||
},
|
||||
salesroom: {
|
||||
slug: "salesroom",
|
||||
type: "integrations:salesroom_video",
|
||||
organizerInputPlaceholder: "https://user.sr.chat",
|
||||
label: "Salesroom",
|
||||
},
|
||||
sirius_video: {
|
||||
slug: "sirius_video",
|
||||
type: "integrations:sirius_video_video",
|
||||
organizerInputPlaceholder: "https://sirius.video/sebastian",
|
||||
label: "Sirius Video",
|
||||
},
|
||||
whereby: {
|
||||
slug: "whereby",
|
||||
type: "integrations:whereby_video",
|
||||
label: "Whereby Video",
|
||||
organizerInputPlaceholder: "https://www.whereby.com/cal",
|
||||
},
|
||||
const APP: TApp = {
|
||||
slug: "around",
|
||||
type: "integrations:around_video",
|
||||
organizerInputPlaceholder: "https://www.around.co/rick",
|
||||
label: "Around Video",
|
||||
};
|
||||
|
||||
const ALL_APPS_ARRAY: TApp[] = Object.values(ALL_APPS);
|
||||
/**
|
||||
* @todo add tests for
|
||||
* shimmervideo
|
||||
* sylapsvideo
|
||||
* googlevideo
|
||||
* huddle
|
||||
* jelly
|
||||
* jistivideo
|
||||
* office365video
|
||||
* mirotalk
|
||||
* tandemvideo
|
||||
* webex
|
||||
* zoomvideo
|
||||
*/
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
test.afterEach(({ users }) => users.deleteAll());
|
||||
|
||||
test.describe("check non-oAuth link-based conferencing apps", () => {
|
||||
ALL_APPS_ARRAY.forEach((app) => {
|
||||
test(`check conferencing app: ${app.slug} by skipping the configure step`, async ({
|
||||
appsPage,
|
||||
page,
|
||||
users,
|
||||
}) => {
|
||||
const user = await users.create();
|
||||
await user.apiLogin();
|
||||
await page.goto("apps/categories/conferencing");
|
||||
await appsPage.installConferencingAppSkipConfigure(app.slug);
|
||||
await appsPage.verifyConferencingApp(app);
|
||||
});
|
||||
test(`check conferencing app: ${APP.slug} by skipping the configure step`, async ({
|
||||
appsPage,
|
||||
page,
|
||||
users,
|
||||
}) => {
|
||||
const user = await users.create();
|
||||
await user.apiLogin();
|
||||
await appsPage.installConferencingAppSkipConfigure(APP.slug);
|
||||
await appsPage.verifyConferencingApp(APP);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("check non-oAuth link-based conferencing apps using the new flow", () => {
|
||||
ALL_APPS_ARRAY.forEach((app) => {
|
||||
test(`can add ${app.slug} app and book with it`, async ({ appsPage, page, users }) => {
|
||||
const user = await users.create();
|
||||
await user.apiLogin();
|
||||
const eventTypes = await user.getUserEventsAsOwner();
|
||||
const eventTypeIds = eventTypes.map((item) => item.id).filter((item, index) => index < 1);
|
||||
await appsPage.installConferencingAppNewFlow(app, eventTypeIds);
|
||||
await appsPage.verifyConferencingAppNew(app, eventTypeIds);
|
||||
});
|
||||
test(`can add ${APP.slug} app and book with it`, async ({ appsPage, page, users }) => {
|
||||
const user = await users.create();
|
||||
await user.apiLogin();
|
||||
const eventTypes = await user.getUserEventsAsOwner();
|
||||
const eventTypeIds = eventTypes.map((item) => item.id).filter((item, index) => index < 1);
|
||||
await appsPage.installConferencingAppNewFlow(APP, eventTypeIds);
|
||||
await appsPage.verifyConferencingAppNew(APP, eventTypeIds);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -44,6 +44,7 @@ test("check SSR and OG - User Event Type", async ({ page, users }) => {
|
||||
const canonicalLink = document.querySelector('link[rel="canonical"]')?.getAttribute("href");
|
||||
expect(titleText).toContain(name);
|
||||
expect(ogUrl).toEqual(`${WEBAPP_URL}/${user.username}/30-min`);
|
||||
await page.waitForSelector('[data-testid="avatar-href"]');
|
||||
const avatarLocators = await page.locator('[data-testid="avatar-href"]').all();
|
||||
expect(avatarLocators.length).toBe(1);
|
||||
|
||||
@@ -285,18 +286,13 @@ testBothFutureAndLegacyRoutes.describe("pro user", () => {
|
||||
});
|
||||
|
||||
test("Time slots should be reserved when selected", async ({ context, page }) => {
|
||||
await page.click('[data-testid="event-type-link"]');
|
||||
|
||||
const initialUrl = page.url();
|
||||
await page.locator('[data-testid="event-type-link"]').first().click();
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
const pageTwo = await context.newPage();
|
||||
await pageTwo.goto(initialUrl);
|
||||
await pageTwo.waitForURL(initialUrl);
|
||||
|
||||
await pageTwo.waitForSelector('[data-testid="event-type-link"]');
|
||||
const eventTypeLink = pageTwo.locator('[data-testid="event-type-link"]').first();
|
||||
await eventTypeLink.waitFor();
|
||||
await eventTypeLink.click();
|
||||
await pageTwo.locator('[data-testid="event-type-link"]').first().click();
|
||||
|
||||
await pageTwo.locator('[data-testid="incrementMonth"]').waitFor();
|
||||
await pageTwo.click('[data-testid="incrementMonth"]');
|
||||
|
||||
@@ -47,7 +47,7 @@ export function createAppsFixture(page: Page) {
|
||||
},
|
||||
|
||||
installConferencingAppSkipConfigure: async (app: string) => {
|
||||
await page.getByTestId(`app-store-app-card-${app}`).click();
|
||||
await page.goto(`apps/${app}`);
|
||||
await page.getByTestId("install-app-button").click();
|
||||
await page.waitForURL(`apps/installation/event-types?slug=${app}`);
|
||||
await page.click('[data-testid="set-up-later"]');
|
||||
@@ -79,7 +79,6 @@ export function createAppsFixture(page: Page) {
|
||||
await page.click(`[data-testid="select-event-type-${id}"]`);
|
||||
}
|
||||
await page.click(`[data-testid="save-event-types"]`);
|
||||
page.waitForLoadState("networkidle");
|
||||
|
||||
for (let eindex = 0; eindex < eventTypeIds.length; eindex++) {
|
||||
if (!app.organizerInputPlaceholder) continue;
|
||||
|
||||
@@ -42,7 +42,7 @@ export const createBookingsFixture = (page: Page, workerInfo: WorkerInfo) => {
|
||||
const startDate = startDateParam || dayjs().add(1, "day").toDate();
|
||||
const seed = `${username}:${dayjs(startDate).utc().format()}:${new Date().getTime()}:${
|
||||
workerInfo.workerIndex
|
||||
}`;
|
||||
}:${Math.random()}`;
|
||||
const uid = translator.fromUUID(uuidv5(seed, uuidv5.URL));
|
||||
const booking = await prisma.booking.create({
|
||||
data: {
|
||||
|
||||
@@ -372,7 +372,7 @@ export const createUsersFixture = (
|
||||
},
|
||||
{
|
||||
id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad",
|
||||
action: { type: "externalRedirectUrl", value: "https://google.com" },
|
||||
action: { type: "externalRedirectUrl", value: "https://cal.com" },
|
||||
queryValue: {
|
||||
id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad",
|
||||
type: "group",
|
||||
|
||||
@@ -8,7 +8,7 @@ import { v4 as uuidv4 } from "uuid";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
|
||||
import { test, todo } from "./lib/fixtures";
|
||||
import { submitAndWaitForResponse } from "./lib/testUtils";
|
||||
import { submitAndWaitForJsonResponse } from "./lib/testUtils";
|
||||
|
||||
declare let global: {
|
||||
E2E_EMAILS?: ({ text: string } | Record<string, unknown>)[];
|
||||
@@ -132,7 +132,7 @@ async function bookEvent(page: Page, calLink: string) {
|
||||
await page.fill('[name="name"]', "Integration User");
|
||||
await page.fill('[name="email"]', "integration-user@example.com");
|
||||
|
||||
const response = await submitAndWaitForResponse(page, "**/api/book/event", {
|
||||
const response = await submitAndWaitForJsonResponse(page, "**/api/book/event", {
|
||||
action: () => page.press('[name="email"]', "Enter"),
|
||||
});
|
||||
const responseObj = await response.json();
|
||||
|
||||
@@ -218,7 +218,7 @@ export async function installAppleCalendar(page: Page) {
|
||||
}
|
||||
|
||||
export async function getInviteLink(page: Page) {
|
||||
const json = await submitAndWaitForResponse(page, "/api/trpc/teams/createInvite?batch=1", {
|
||||
const json = await submitAndWaitForJsonResponse(page, "/api/trpc/teams/createInvite?batch=1", {
|
||||
action: () => page.locator(`[data-testid="copy-invite-link-button"]`).click(),
|
||||
});
|
||||
return json[0].result.data.json.inviteLink as string;
|
||||
@@ -446,7 +446,17 @@ export async function submitAndWaitForResponse(
|
||||
await action();
|
||||
const response = await submitPromise;
|
||||
expect(response.status()).toBe(expectedStatusCode);
|
||||
return response.json();
|
||||
}
|
||||
export async function submitAndWaitForJsonResponse(
|
||||
page: Page,
|
||||
url: string,
|
||||
{ action = () => page.locator('[type="submit"]').click(), expectedStatusCode = 200 } = {}
|
||||
) {
|
||||
const submitPromise = page.waitForResponse(url);
|
||||
await action();
|
||||
const response = await submitPromise;
|
||||
expect(response.status()).toBe(expectedStatusCode);
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
export async function confirmReschedule(page: Page, url = "/api/book/event") {
|
||||
|
||||
@@ -70,7 +70,7 @@ test.describe("Manage Booking Questions", () => {
|
||||
const firstEventTypeElement = $eventTypes.first();
|
||||
|
||||
await firstEventTypeElement.click();
|
||||
await page.click('[href$="tabName=advanced"]');
|
||||
await page.getByTestId("vertical-tab-event_advanced_tab_title").click();
|
||||
});
|
||||
|
||||
await test.step("Add Question and see that it's shown on Booking Page at appropriate position", async () => {
|
||||
@@ -116,7 +116,7 @@ test.describe("Manage Booking Questions", () => {
|
||||
});
|
||||
|
||||
await test.step("Open the 'Name' field dialog", async () => {
|
||||
await page.click('[href$="tabName=advanced"]');
|
||||
await page.getByTestId("vertical-tab-event_advanced_tab_title").click();
|
||||
await page.locator('[data-testid="field-name"] [data-testid="edit-field-action"]').click();
|
||||
});
|
||||
|
||||
@@ -742,17 +742,10 @@ test.describe("Text area min and max characters text", () => {
|
||||
// We wait until loading is finished
|
||||
await page.waitForSelector('[data-testid="event-types"]');
|
||||
await createNewEventType(page, { eventTitle });
|
||||
await page.waitForSelector(`text=${eventTitle}`);
|
||||
|
||||
// Click on the event type
|
||||
await page.click(`text=${eventTitle}`);
|
||||
await page.waitForSelector(`text=${eventTitle}`);
|
||||
|
||||
// goto the advanced tab
|
||||
await page.click('[href$="tabName=advanced"]');
|
||||
await page.waitForSelector('[data-testid="event-title"]');
|
||||
await page.getByTestId("vertical-tab-event_advanced_tab_title").click();
|
||||
const insertQuestion = async (questionName: string) => {
|
||||
const element = page.locator('[data-testid="add-field"]');
|
||||
await element.scrollIntoViewIfNeeded();
|
||||
await element.click();
|
||||
const locatorForSelect = page.locator("[id=test-field-type]").nth(0);
|
||||
await locatorForSelect.click();
|
||||
|
||||
@@ -219,6 +219,7 @@ test.describe("Bookings", () => {
|
||||
|
||||
const { team } = await owner.getFirstTeamMembership();
|
||||
const teamEvent = await owner.getFirstTeamEvent(team.id);
|
||||
const eventHostsObj = [...teamMatesObj, { name: "pro-user" }];
|
||||
await owner.apiLogin();
|
||||
|
||||
await markPhoneNumberAsRequiredField(page, teamEvent.id);
|
||||
@@ -235,7 +236,7 @@ test.describe("Bookings", () => {
|
||||
page,
|
||||
team,
|
||||
event: teamEvent,
|
||||
teamMatesObj,
|
||||
teamMatesObj: eventHostsObj,
|
||||
opts: { attendeePhoneNumber: "+918888888888" },
|
||||
});
|
||||
|
||||
|
||||
@@ -296,12 +296,11 @@ test.describe("Organization", () => {
|
||||
|
||||
await test.step("Signing up with the previous username of the migrated user - shouldn't be allowed", async () => {
|
||||
await page.goto("/signup");
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
|
||||
await page.locator('[data-testid="continue-with-email-button"]').click();
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
const usernameInput = page.locator('input[name="username"]');
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
await usernameInput.fill(existingUser.username!);
|
||||
await page.locator('input[name="username"]').fill(existingUser.username!);
|
||||
await page
|
||||
.locator('input[name="email"]')
|
||||
.fill(`${existingUser.username}-differnet-email@example.com`);
|
||||
@@ -431,7 +430,7 @@ async function signupFromInviteLink({
|
||||
const context = await browser.newContext();
|
||||
const inviteLinkPage = await context.newPage();
|
||||
await inviteLinkPage.goto(inviteLink);
|
||||
await inviteLinkPage.waitForLoadState("networkidle");
|
||||
await expect(inviteLinkPage.locator("text=Create your account")).toBeVisible();
|
||||
|
||||
// Check required fields
|
||||
const button = inviteLinkPage.locator("button[type=submit][disabled]");
|
||||
@@ -460,7 +459,7 @@ export async function signupFromEmailInviteLink({
|
||||
const signupPage = await context.newPage();
|
||||
|
||||
signupPage.goto(inviteLink);
|
||||
await signupPage.locator(`[data-testid="signup-usernamefield"]`).waitFor({ state: "visible" });
|
||||
await expect(signupPage.locator("text=Create your account")).toBeVisible();
|
||||
await expect(signupPage.locator(`[data-testid="signup-usernamefield"]`)).toBeDisabled();
|
||||
// await for value. initial value is ""
|
||||
if (expectedUsername) {
|
||||
@@ -472,7 +471,6 @@ export async function signupFromEmailInviteLink({
|
||||
await expect(signupPage.locator(`[data-testid="signup-emailfield"]`)).toHaveValue(expectedEmail);
|
||||
}
|
||||
|
||||
await signupPage.waitForLoadState("networkidle");
|
||||
// Check required fields
|
||||
await signupPage.locator("input[name=password]").fill(`P4ssw0rd!`);
|
||||
await signupPage.locator("button[type=submit]").click();
|
||||
|
||||
@@ -81,8 +81,7 @@ test.describe("Out of office", () => {
|
||||
|
||||
await page.getByTestId("team_username_select").click();
|
||||
|
||||
await page.locator("#react-select-3-input").fill("user");
|
||||
await page.locator("#react-select-3-input").press("Enter");
|
||||
await page.locator("#react-select-3-option-0").click();
|
||||
|
||||
// send request
|
||||
await saveAndWaitForResponse(page);
|
||||
@@ -160,8 +159,7 @@ test.describe("Out of office", () => {
|
||||
|
||||
await page.getByTestId("team_username_select").click();
|
||||
|
||||
await page.locator("#react-select-3-input").fill("userThree");
|
||||
await page.locator("#react-select-3-input").press("Enter");
|
||||
await page.locator("#react-select-3-option-1").click();
|
||||
|
||||
// send request
|
||||
await saveAndWaitForResponse(page);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { Page } from "@playwright/test";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
@@ -342,7 +343,7 @@ test.describe("Reschedule Tests", async () => {
|
||||
});
|
||||
|
||||
test.describe("Organization", () => {
|
||||
test("Booking should be rescheduleable for a user that was moved to an organization", async ({
|
||||
test("Booking should be rescheduleable for a user that was moved to an organization through org domain", async ({
|
||||
users,
|
||||
bookings,
|
||||
orgs,
|
||||
@@ -361,59 +362,73 @@ test.describe("Reschedule Tests", async () => {
|
||||
const eventType = orgMember.eventTypes[0];
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const orgSlug = org.slug!;
|
||||
const getNonOrgUrlFromOrgUrl = (url: string) => url.replace(orgSlug, "app");
|
||||
await test.step("Try rescheduling through org domain", async () => {
|
||||
const booking = await bookings.create(orgMember.id, orgMember.username, eventType.id);
|
||||
const booking = await bookings.create(orgMember.id, orgMember.username, eventType.id);
|
||||
|
||||
return await doOnOrgDomain(
|
||||
{
|
||||
orgSlug: orgSlug,
|
||||
page,
|
||||
},
|
||||
async ({ page, goToUrlWithErrorHandling }) => {
|
||||
const result = await goToUrlWithErrorHandling(`/reschedule/${booking.uid}`);
|
||||
// Verify that the reschedule page was opened on the org domain with correct username
|
||||
expectUrlToBeABookingPageOnOrgForUsername({
|
||||
url: result.url,
|
||||
orgSlug,
|
||||
username: profileUsername,
|
||||
});
|
||||
return await doOnOrgDomain(
|
||||
{
|
||||
orgSlug: orgSlug,
|
||||
page,
|
||||
},
|
||||
async ({ page, goToUrlWithErrorHandling }) => {
|
||||
const result = await goToUrlWithErrorHandling(`/reschedule/${booking.uid}`);
|
||||
expectUrlToBeABookingPageOnOrgForUsername({
|
||||
url: result.url,
|
||||
orgSlug,
|
||||
username: profileUsername,
|
||||
});
|
||||
|
||||
const rescheduleUrlToBeOpenedInOrgContext = getNonOrgUrlFromOrgUrl(result.url);
|
||||
await page.goto(rescheduleUrlToBeOpenedInOrgContext);
|
||||
await expectSuccessfulReschedule();
|
||||
return { url: result.url };
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
await test.step("Try rescheduling through non-org domain", async () => {
|
||||
const booking = await bookings.create(orgMember.id, orgMember.username, eventType.id);
|
||||
|
||||
// Opening the non-org URL and expecting a redirect to the org domain by reschedule endpoint
|
||||
const result = await goToUrlWithErrorHandling({ url: `/reschedule/${booking.uid}`, page });
|
||||
|
||||
await doOnOrgDomain(
|
||||
{
|
||||
orgSlug: orgSlug,
|
||||
page,
|
||||
},
|
||||
async ({ page }) => {
|
||||
await page.goto(getNonOrgUrlFromOrgUrl(result.url));
|
||||
await expectSuccessfulReschedule();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
async function expectSuccessfulReschedule() {
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
const { protocol, host } = new URL(page.url());
|
||||
// Needed since we we're expecting a non-org URL, causing timeouts.
|
||||
const url = getNonOrgUrlFromOrgUrl(`${protocol}//${host}/api/book/event`);
|
||||
await confirmReschedule(page, url);
|
||||
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
|
||||
}
|
||||
const rescheduleUrlToBeOpenedInOrgContext = getNonOrgUrlFromOrgUrl(result.url, orgSlug);
|
||||
await page.goto(rescheduleUrlToBeOpenedInOrgContext);
|
||||
await expectSuccessfulReschedule(page, orgSlug);
|
||||
return { url: result.url };
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("Booking should be rescheduleable for a user that was moved to an organization through non-org domain", async ({
|
||||
users,
|
||||
bookings,
|
||||
orgs,
|
||||
page,
|
||||
}) => {
|
||||
const org = await orgs.create({
|
||||
name: "TestOrg",
|
||||
});
|
||||
const orgMember = await users.create({
|
||||
username: "username-outside-org",
|
||||
organizationId: org.id,
|
||||
profileUsername: "username-inside-org",
|
||||
roleInOrganization: MembershipRole.MEMBER,
|
||||
});
|
||||
const eventType = orgMember.eventTypes[0];
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const orgSlug = org.slug!;
|
||||
const booking = await bookings.create(orgMember.id, orgMember.username, eventType.id);
|
||||
|
||||
const result = await goToUrlWithErrorHandling({ url: `/reschedule/${booking.uid}`, page });
|
||||
|
||||
await doOnOrgDomain(
|
||||
{
|
||||
orgSlug: orgSlug,
|
||||
page,
|
||||
},
|
||||
async ({ page }) => {
|
||||
await page.goto(getNonOrgUrlFromOrgUrl(result.url, orgSlug));
|
||||
await expectSuccessfulReschedule(page, orgSlug);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const getNonOrgUrlFromOrgUrl = (url: string, orgSlug: string) => url.replace(orgSlug, "app");
|
||||
|
||||
async function expectSuccessfulReschedule(page: Page, orgSlug: string) {
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
const { protocol, host } = new URL(page.url());
|
||||
// Needed since we we're expecting a non-org URL, causing timeouts.
|
||||
const url = getNonOrgUrlFromOrgUrl(`${protocol}//${host}/api/book/event`, orgSlug);
|
||||
await confirmReschedule(page, url);
|
||||
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ test.describe("Signup Main Page Test", async () => {
|
||||
|
||||
test("Continue with email button must exist / work", async ({ page }) => {
|
||||
await page.goto("/signup");
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
|
||||
await page.locator('[data-testid="continue-with-email-button"]').click();
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
});
|
||||
|
||||
test("Continue with google button must exist / work", async ({ page }) => {
|
||||
@@ -45,9 +45,9 @@ test.describe("Email Signup Flow Test", async () => {
|
||||
});
|
||||
|
||||
await page.goto("/signup");
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
|
||||
await page.locator('[data-testid="continue-with-email-button"]').click();
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
|
||||
const alertMessage = "Username or email is already taken";
|
||||
|
||||
@@ -74,9 +74,9 @@ test.describe("Email Signup Flow Test", async () => {
|
||||
});
|
||||
|
||||
await page.goto("/signup");
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
|
||||
await page.locator('[data-testid="continue-with-email-button"]').click();
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
|
||||
const alertMessage = "Username or email is already taken";
|
||||
|
||||
@@ -107,9 +107,9 @@ test.describe("Email Signup Flow Test", async () => {
|
||||
|
||||
// Signup with premium username name
|
||||
await page.goto("/signup");
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
|
||||
await page.locator('[data-testid="continue-with-email-button"]').click();
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
|
||||
// Fill form
|
||||
await page.locator('input[name="username"]').fill("rock");
|
||||
@@ -137,9 +137,9 @@ test.describe("Email Signup Flow Test", async () => {
|
||||
});
|
||||
|
||||
await page.goto("/signup");
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
|
||||
await page.locator('[data-testid="continue-with-email-button"]').click();
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
|
||||
// Fill form
|
||||
await page.locator('input[name="username"]').fill(userToCreate.username);
|
||||
@@ -158,9 +158,9 @@ test.describe("Email Signup Flow Test", async () => {
|
||||
test("Signup fields prefilled with query params", async ({ page, users }) => {
|
||||
const signupUrlWithParams = "/signup?username=rick-jones&email=rick-jones%40example.com";
|
||||
await page.goto(signupUrlWithParams);
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
|
||||
await page.locator('[data-testid="continue-with-email-button"]').click();
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
|
||||
// Fill form
|
||||
const usernameInput = page.locator('input[name="username"]');
|
||||
@@ -241,9 +241,9 @@ test.describe("Email Signup Flow Test", async () => {
|
||||
});
|
||||
|
||||
await page.goto("/signup");
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
|
||||
await page.locator('[data-testid="continue-with-email-button"]').click();
|
||||
await expect(page.locator("text=Create your account")).toBeVisible();
|
||||
|
||||
// Fill form
|
||||
await page.locator('input[name="username"]').fill(userToCreate.username);
|
||||
|
||||
@@ -48,7 +48,7 @@ test.describe("Team", () => {
|
||||
const context = await browser.newContext();
|
||||
const newPage = await context.newPage();
|
||||
await newPage.goto(inviteLink);
|
||||
await newPage.waitForLoadState("networkidle");
|
||||
await expect(newPage.locator("text=Create your account")).toBeVisible();
|
||||
|
||||
// Check required fields
|
||||
const button = newPage.locator("button[type=submit][disabled]");
|
||||
|
||||
@@ -143,7 +143,7 @@ test.describe("Routing Forms", () => {
|
||||
option: 2,
|
||||
page,
|
||||
});
|
||||
await page.fill("[name=externalRedirectUrl]", "https://www.google.com");
|
||||
await page.fill("[name=externalRedirectUrl]", "https://cal.com");
|
||||
await saveCurrentForm(page);
|
||||
|
||||
const { fields } = await addAllTypesOfFieldsAndSaveForm(formId, page, {
|
||||
@@ -171,7 +171,7 @@ test.describe("Routing Forms", () => {
|
||||
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForURL((url) => {
|
||||
return url.hostname.includes("google.com");
|
||||
return url.hostname.includes("cal.com");
|
||||
});
|
||||
|
||||
const url = new URL(page.url());
|
||||
@@ -332,9 +332,7 @@ test.describe("Routing Forms", () => {
|
||||
|
||||
await page.goto(`/router?form=${routingForm.id}&Test field=external-redirect`);
|
||||
await page.waitForURL((url) => {
|
||||
return (
|
||||
url.hostname.includes("google.com") && url.searchParams.get("Test field") === "external-redirect"
|
||||
);
|
||||
return url.hostname.includes("cal.com") && url.searchParams.get("Test field") === "external-redirect";
|
||||
});
|
||||
|
||||
await page.goto(`/router?form=${routingForm.id}&Test field=custom-page`);
|
||||
@@ -389,7 +387,7 @@ test.describe("Routing Forms", () => {
|
||||
routingType = await page.locator('[data-testid="test-routing-result-type"]').innerText();
|
||||
route = await page.locator('[data-testid="test-routing-result"]').innerText();
|
||||
expect(routingType).toBe("External Redirect");
|
||||
expect(route).toBe("https://google.com");
|
||||
expect(route).toBe("https://cal.com");
|
||||
await page.click('[data-testid="dialog-rejection"]');
|
||||
|
||||
// Multiselect(Legacy)
|
||||
@@ -467,7 +465,7 @@ async function fillSeededForm(page: Page, routingFormId: string) {
|
||||
await fillAllOptionsBasedFields();
|
||||
page.click('button[type="submit"]');
|
||||
await page.waitForURL((url) => {
|
||||
return url.hostname.includes("google.com");
|
||||
return url.hostname.includes("cal.com");
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ async function seedAppData() {
|
||||
},
|
||||
{
|
||||
id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad",
|
||||
action: { type: "externalRedirectUrl", value: "https://google.com" },
|
||||
action: { type: "externalRedirectUrl", value: "https://cal.com" },
|
||||
queryValue: {
|
||||
id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad",
|
||||
type: "group",
|
||||
|
||||
Reference in New Issue
Block a user