test: flaky e2e tests (#26308)
* fix another * fix flakes * Update apps/web/playwright/fixtures/apps.ts Co-authored-by: Keith Williams <keithwillcode@gmail.com> * fix * fix * test fix * fix test * tweak --------- Co-authored-by: Keith Williams <keithwillcode@gmail.com>
This commit is contained in:
co-authored by
Keith Williams
parent
2c7cb530a1
commit
cc8da034c0
@@ -1,12 +1,3 @@
|
||||
import { expect } from "@playwright/test";
|
||||
import { JSDOM } from "jsdom";
|
||||
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { generateHashedLink } from "@calcom/lib/generateHashedLink";
|
||||
import { randomString } from "@calcom/lib/random";
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
import type { Schedule, TimeRange } from "@calcom/types/schedule";
|
||||
|
||||
import { test, todo } from "./lib/fixtures";
|
||||
import {
|
||||
bookFirstEvent,
|
||||
@@ -20,6 +11,13 @@ import {
|
||||
testName,
|
||||
cancelBookingFromBookingsList,
|
||||
} from "./lib/testUtils";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { generateHashedLink } from "@calcom/lib/generateHashedLink";
|
||||
import { randomString } from "@calcom/lib/random";
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
import type { Schedule, TimeRange } from "@calcom/types/schedule";
|
||||
import { expect } from "@playwright/test";
|
||||
import { JSDOM } from "jsdom";
|
||||
|
||||
const freeUserObj = { name: `Free-user-${randomString(3)}` };
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
@@ -33,7 +31,9 @@ test("check SSR and OG - User Event Type", async ({ page, users }) => {
|
||||
name,
|
||||
});
|
||||
const responsePromise = page.waitForResponse(
|
||||
(response) => response.url().includes(`/${user.username}/30-min`) && response.status() === 200
|
||||
(response) =>
|
||||
response.url().includes(`/${user.username}/30-min`) &&
|
||||
response.status() === 200
|
||||
);
|
||||
await page.goto(`/${user.username}/30-min`);
|
||||
await page.content();
|
||||
@@ -42,17 +42,27 @@ test("check SSR and OG - User Event Type", async ({ page, users }) => {
|
||||
const document = new JSDOM(ssrResponse).window.document;
|
||||
|
||||
const titleText = document.querySelector("title")?.textContent;
|
||||
const ogImage = document.querySelector('meta[property="og:image"]')?.getAttribute("content");
|
||||
const ogUrl = document.querySelector('meta[property="og:url"]')?.getAttribute("content");
|
||||
const canonicalLink = document.querySelector('link[rel="canonical"]')?.getAttribute("href");
|
||||
const ogImage = document
|
||||
.querySelector('meta[property="og:image"]')
|
||||
?.getAttribute("content");
|
||||
const ogUrl = document
|
||||
.querySelector('meta[property="og:url"]')
|
||||
?.getAttribute("content");
|
||||
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();
|
||||
const avatarLocators = await page
|
||||
.locator('[data-testid="avatar-href"]')
|
||||
.all();
|
||||
expect(avatarLocators.length).toBe(1);
|
||||
|
||||
for (const avatarLocator of avatarLocators) {
|
||||
expect(await avatarLocator.getAttribute("href")).toEqual(`${WEBAPP_URL}/${user.username}?redirect=false`);
|
||||
expect(await avatarLocator.getAttribute("href")).toEqual(
|
||||
`${WEBAPP_URL}/${user.username}?redirect=false`
|
||||
);
|
||||
}
|
||||
|
||||
expect(canonicalLink).toEqual(`${WEBAPP_URL}/${user.username}/30-min`);
|
||||
@@ -157,7 +167,10 @@ test.describe("pro user", () => {
|
||||
await page.goto("/bookings/upcoming");
|
||||
await page.waitForSelector('[data-testid="bookings"]');
|
||||
// Click the ellipsis menu button to open the dropdown
|
||||
await page.locator('[data-testid="booking-actions-dropdown"]').nth(0).click();
|
||||
await page
|
||||
.locator('[data-testid="booking-actions-dropdown"]')
|
||||
.nth(0)
|
||||
.click();
|
||||
await page.locator('[data-testid="reschedule"]').click();
|
||||
await page.waitForURL((url) => {
|
||||
const bookingId = url.searchParams.get("rescheduleUid");
|
||||
@@ -178,17 +191,31 @@ test.describe("pro user", () => {
|
||||
}) => {
|
||||
const [pro] = users.get();
|
||||
const [eventType] = pro.eventTypes;
|
||||
const bookingFixture = await bookings.create(pro.id, pro.username, eventType.id);
|
||||
const bookingFixture = await bookings.create(
|
||||
pro.id,
|
||||
pro.username,
|
||||
eventType.id
|
||||
);
|
||||
|
||||
// open the wrong eventType (rescheduleUid created for /30min event)
|
||||
await page.goto(`${pro.username}/${pro.eventTypes[1].slug}?rescheduleUid=${bookingFixture.uid}`);
|
||||
await page.goto(
|
||||
`${pro.username}/${pro.eventTypes[1].slug}?rescheduleUid=${bookingFixture.uid}`
|
||||
);
|
||||
|
||||
await expect(page).toHaveURL(new RegExp(`${pro.username}/${eventType.slug}`));
|
||||
await expect(page).toHaveURL(
|
||||
new RegExp(`${pro.username}/${eventType.slug}`)
|
||||
);
|
||||
});
|
||||
|
||||
test("it returns a 404 when a requested event type does not exist", async ({ page, users }) => {
|
||||
test("it returns a 404 when a requested event type does not exist", async ({
|
||||
page,
|
||||
users,
|
||||
}) => {
|
||||
const [pro] = users.get();
|
||||
const unexistingPageUrl = new URL(`${pro.username}/invalid-event-type`, WEBAPP_URL);
|
||||
const unexistingPageUrl = new URL(
|
||||
`${pro.username}/invalid-event-type`,
|
||||
WEBAPP_URL
|
||||
);
|
||||
const response = await page.goto(unexistingPageUrl.href);
|
||||
expect(response?.status()).toBe(404);
|
||||
});
|
||||
@@ -200,8 +227,12 @@ test.describe("pro user", () => {
|
||||
// Because it tests the entire booking flow + the cancellation + rebooking
|
||||
test.setTimeout(testInfo.timeout * 3);
|
||||
await bookFirstEvent(page);
|
||||
await expect(page.locator(`[data-testid="attendee-email-${testEmail}"]`)).toHaveText(testEmail);
|
||||
await expect(page.locator(`[data-testid="attendee-name-${testName}"]`)).toHaveText(testName);
|
||||
await expect(
|
||||
page.locator(`[data-testid="attendee-email-${testEmail}"]`)
|
||||
).toHaveText(testEmail);
|
||||
await expect(
|
||||
page.locator(`[data-testid="attendee-name-${testName}"]`)
|
||||
).toHaveText(testName);
|
||||
|
||||
const [pro] = users.get();
|
||||
await pro.apiLogin();
|
||||
@@ -224,8 +255,12 @@ test.describe("pro user", () => {
|
||||
// Because it tests the entire booking flow + the cancellation + rebooking
|
||||
test.setTimeout(testInfo.timeout * 3);
|
||||
await bookFirstEvent(page);
|
||||
await expect(page.locator(`[data-testid="attendee-email-${testEmail}"]`)).toHaveText(testEmail);
|
||||
await expect(page.locator(`[data-testid="attendee-name-${testName}"]`)).toHaveText(testName);
|
||||
await expect(
|
||||
page.locator(`[data-testid="attendee-email-${testEmail}"]`)
|
||||
).toHaveText(testEmail);
|
||||
await expect(
|
||||
page.locator(`[data-testid="attendee-name-${testName}"]`)
|
||||
).toHaveText(testName);
|
||||
|
||||
const [pro] = users.get();
|
||||
await pro.apiLogin();
|
||||
@@ -242,7 +277,9 @@ test.describe("pro user", () => {
|
||||
await page.goto(`/reschedule/${bookingUid}`);
|
||||
|
||||
expect(page.url()).not.toContain("rescheduleUid");
|
||||
const cancelledHeadline = page.locator('[data-testid="cancelled-headline"]');
|
||||
const cancelledHeadline = page.locator(
|
||||
'[data-testid="cancelled-headline"]'
|
||||
);
|
||||
await expect(cancelledHeadline).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -257,14 +294,18 @@ test.describe("pro user", () => {
|
||||
await page.goto("/bookings/unconfirmed");
|
||||
await Promise.all([
|
||||
page.click('[data-testid="confirm"]'),
|
||||
page.waitForResponse((response) => response.url().includes("/api/trpc/bookings/confirm")),
|
||||
page.waitForResponse((response) =>
|
||||
response.url().includes("/api/trpc/bookings/confirm")
|
||||
),
|
||||
]);
|
||||
// This is the only booking in there that needed confirmation and now it should be empty screen
|
||||
await expect(page.locator('[data-testid="empty-screen"]')).toBeVisible();
|
||||
});
|
||||
|
||||
test("can book an unconfirmed event multiple times", async ({ page }) => {
|
||||
await page.locator('[data-testid="event-type-link"]:has-text("Opt in")').click();
|
||||
await page
|
||||
.locator('[data-testid="event-type-link"]:has-text("Opt in")')
|
||||
.click();
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
|
||||
const pageUrl = page.url();
|
||||
@@ -281,7 +322,9 @@ test.describe("pro user", () => {
|
||||
test("booking an unconfirmed event with the same email brings you to the original request", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.locator('[data-testid="event-type-link"]:has-text("Opt in")').click();
|
||||
await page
|
||||
.locator('[data-testid="event-type-link"]:has-text("Opt in")')
|
||||
.click();
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
|
||||
const pageUrl = page.url();
|
||||
@@ -312,12 +355,17 @@ test.describe("pro user", () => {
|
||||
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
|
||||
|
||||
const promises = additionalGuests.map(async (email) => {
|
||||
await expect(page.locator(`[data-testid="attendee-email-${email}"]`)).toHaveText(email);
|
||||
await expect(
|
||||
page.locator(`[data-testid="attendee-email-${email}"]`)
|
||||
).toHaveText(email);
|
||||
});
|
||||
await Promise.all(promises);
|
||||
});
|
||||
|
||||
test("Time slots should be reserved when selected", async ({ page, browser }) => {
|
||||
test("Time slots should be reserved when selected", async ({
|
||||
page,
|
||||
browser,
|
||||
}) => {
|
||||
const initialUrl = page.url();
|
||||
await page.locator('[data-testid="event-type-link"]').first().click();
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
@@ -325,16 +373,29 @@ test.describe("pro user", () => {
|
||||
const pageTwoInNewContext = await newContext.newPage();
|
||||
await pageTwoInNewContext.goto(initialUrl);
|
||||
await pageTwoInNewContext.waitForURL(initialUrl);
|
||||
await pageTwoInNewContext.locator('[data-testid="event-type-link"]').first().click();
|
||||
await pageTwoInNewContext
|
||||
.locator('[data-testid="event-type-link"]')
|
||||
.first()
|
||||
.click();
|
||||
|
||||
await pageTwoInNewContext.locator('[data-testid="incrementMonth"]').waitFor();
|
||||
await pageTwoInNewContext
|
||||
.locator('[data-testid="incrementMonth"]')
|
||||
.waitFor();
|
||||
await pageTwoInNewContext.click('[data-testid="incrementMonth"]');
|
||||
await pageTwoInNewContext.locator('[data-testid="day"][data-disabled="false"]').nth(0).waitFor();
|
||||
await pageTwoInNewContext.locator('[data-testid="day"][data-disabled="false"]').nth(0).click();
|
||||
await pageTwoInNewContext
|
||||
.locator('[data-testid="day"][data-disabled="false"]')
|
||||
.nth(0)
|
||||
.waitFor();
|
||||
await pageTwoInNewContext
|
||||
.locator('[data-testid="day"][data-disabled="false"]')
|
||||
.nth(0)
|
||||
.click();
|
||||
|
||||
// 9:30 should be the first available time slot
|
||||
await pageTwoInNewContext.locator('[data-testid="time"]').nth(0).waitFor();
|
||||
const firstSlotAvailable = pageTwoInNewContext.locator('[data-testid="time"]').nth(0);
|
||||
const firstSlotAvailable = pageTwoInNewContext
|
||||
.locator('[data-testid="time"]')
|
||||
.nth(0);
|
||||
// Find text inside the element
|
||||
const firstSlotAvailableText = await firstSlotAvailable.innerText();
|
||||
expect(firstSlotAvailableText).toContain("9:30");
|
||||
@@ -346,7 +407,9 @@ test.describe("pro user", () => {
|
||||
}) => {
|
||||
const initialUrl = page.url();
|
||||
await page.waitForSelector('[data-testid="event-type-link"]');
|
||||
const eventTypeLink = page.locator('[data-testid="event-type-link"]').first();
|
||||
const eventTypeLink = page
|
||||
.locator('[data-testid="event-type-link"]')
|
||||
.first();
|
||||
await eventTypeLink.click();
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
|
||||
@@ -355,7 +418,9 @@ test.describe("pro user", () => {
|
||||
await pageTwo.waitForURL(initialUrl);
|
||||
|
||||
await pageTwo.waitForSelector('[data-testid="event-type-link"]');
|
||||
const eventTypeLinkTwo = pageTwo.locator('[data-testid="event-type-link"]').first();
|
||||
const eventTypeLinkTwo = pageTwo
|
||||
.locator('[data-testid="event-type-link"]')
|
||||
.first();
|
||||
await eventTypeLinkTwo.waitFor();
|
||||
await eventTypeLinkTwo.click();
|
||||
|
||||
@@ -364,8 +429,14 @@ test.describe("pro user", () => {
|
||||
|
||||
await pageTwo.locator('[data-testid="incrementMonth"]').waitFor();
|
||||
await pageTwo.click('[data-testid="incrementMonth"]');
|
||||
await pageTwo.locator('[data-testid="day"][data-disabled="false"]').nth(0).waitFor();
|
||||
await pageTwo.locator('[data-testid="day"][data-disabled="false"]').nth(0).click();
|
||||
await pageTwo
|
||||
.locator('[data-testid="day"][data-disabled="false"]')
|
||||
.nth(0)
|
||||
.waitFor();
|
||||
await pageTwo
|
||||
.locator('[data-testid="day"][data-disabled="false"]')
|
||||
.nth(0)
|
||||
.click();
|
||||
|
||||
await pageTwo.locator('[data-testid="time"]').nth(0).waitFor();
|
||||
const firstSlotAvailable = pageTwo.locator('[data-testid="time"]').nth(0);
|
||||
@@ -384,7 +455,9 @@ test.describe("prefill", () => {
|
||||
|
||||
await test.step("from session", async () => {
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
await expect(page.locator('[name="name"]')).toHaveValue(prefill.name || "");
|
||||
await expect(page.locator('[name="name"]')).toHaveValue(
|
||||
prefill.name || ""
|
||||
);
|
||||
await expect(page.locator('[name="email"]')).toHaveValue(prefill.email);
|
||||
});
|
||||
|
||||
@@ -399,7 +472,9 @@ test.describe("prefill", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("Persist the field values when going back and coming back to the booking form", async ({ page }) => {
|
||||
test("Persist the field values when going back and coming back to the booking form", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/pro/30min");
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
await page.fill('[name="name"]', "John Doe");
|
||||
@@ -409,7 +484,9 @@ test.describe("prefill", () => {
|
||||
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
await expect(page.locator('[name="name"]')).toHaveValue("John Doe");
|
||||
await expect(page.locator('[name="email"]')).toHaveValue("john@example.com");
|
||||
await expect(page.locator('[name="email"]')).toHaveValue(
|
||||
"john@example.com"
|
||||
);
|
||||
await expect(page.locator('[name="notes"]')).toHaveValue("Test notes");
|
||||
});
|
||||
|
||||
@@ -429,7 +506,9 @@ test.describe("prefill", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("skip confirm step if all fields are prefilled from query params", async ({ page }) => {
|
||||
test("skip confirm step if all fields are prefilled from query params", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/pro/30min");
|
||||
const url = new URL(page.url());
|
||||
url.searchParams.set("name", testName);
|
||||
@@ -440,7 +519,9 @@ test.describe("prefill", () => {
|
||||
await page.goto(url.toString());
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
|
||||
await expect(page.locator('[data-testid="skip-confirm-book-button"]')).toBeVisible();
|
||||
await expect(
|
||||
page.locator('[data-testid="skip-confirm-book-button"]')
|
||||
).toBeVisible();
|
||||
await page.click('[data-testid="skip-confirm-book-button"]');
|
||||
|
||||
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
|
||||
@@ -455,7 +536,15 @@ test.describe("Booking on different layouts", () => {
|
||||
start: new Date(new Date().setUTCHours(9, 0, 0, 0)),
|
||||
end: new Date(new Date().setUTCHours(17, 0, 0, 0)),
|
||||
};
|
||||
const schedule: Schedule = [[], [dateRanges], [dateRanges], [dateRanges], [dateRanges], [dateRanges], []];
|
||||
const schedule: Schedule = [
|
||||
[],
|
||||
[dateRanges],
|
||||
[dateRanges],
|
||||
[dateRanges],
|
||||
[dateRanges],
|
||||
[dateRanges],
|
||||
[],
|
||||
];
|
||||
|
||||
const user = await users.create({ schedule });
|
||||
await page.goto(`/${user.username}`);
|
||||
@@ -490,6 +579,13 @@ test.describe("Booking on different layouts", () => {
|
||||
|
||||
await page.click('[data-testid="incrementMonth"]');
|
||||
|
||||
await page.waitForURL((url) => {
|
||||
return url.searchParams.has("month");
|
||||
})
|
||||
|
||||
await page.reload();
|
||||
await page.waitForLoadState("networkidle");
|
||||
|
||||
await page.locator('[data-testid="time"]').nth(1).click();
|
||||
|
||||
// Fill what is this meeting about? name email and notes
|
||||
@@ -513,7 +609,15 @@ test.describe("Booking round robin event", () => {
|
||||
end: new Date(new Date().setUTCHours(17, 0, 0, 0)),
|
||||
};
|
||||
|
||||
const schedule: Schedule = [[], [dateRanges], [dateRanges], [dateRanges], [dateRanges], [dateRanges], []];
|
||||
const schedule: Schedule = [
|
||||
[],
|
||||
[dateRanges],
|
||||
[dateRanges],
|
||||
[dateRanges],
|
||||
[dateRanges],
|
||||
[dateRanges],
|
||||
[],
|
||||
];
|
||||
|
||||
const testUser = await users.create(
|
||||
{ schedule },
|
||||
@@ -621,12 +725,16 @@ test.describe("Event type with disabled cancellation and rescheduling", () => {
|
||||
bookingId = pathSegments[pathSegments.length - 1];
|
||||
});
|
||||
|
||||
test("Reschedule and cancel buttons should be hidden on success page", async ({ page }) => {
|
||||
test("Reschedule and cancel buttons should be hidden on success page", async ({
|
||||
page,
|
||||
}) => {
|
||||
await expect(page.locator('[data-testid="reschedule-link"]')).toBeHidden();
|
||||
await expect(page.locator('[data-testid="cancel"]')).toBeHidden();
|
||||
});
|
||||
|
||||
test("Direct access to reschedule/{bookingId} should redirect to success page", async ({ page }) => {
|
||||
test("Direct access to reschedule/{bookingId} should redirect to success page", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto(`/reschedule/${bookingId}`);
|
||||
|
||||
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
|
||||
@@ -634,15 +742,21 @@ test.describe("Event type with disabled cancellation and rescheduling", () => {
|
||||
await page.waitForURL((url) => url.pathname === `/booking/${bookingId}`);
|
||||
});
|
||||
|
||||
test("Using rescheduleUid query parameter should redirect to success page", async ({ page }) => {
|
||||
await page.goto(`/${user.username}/no-cancel-no-reschedule?rescheduleUid=${bookingId}`);
|
||||
test("Using rescheduleUid query parameter should redirect to success page", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto(
|
||||
`/${user.username}/no-cancel-no-reschedule?rescheduleUid=${bookingId}`
|
||||
);
|
||||
|
||||
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
|
||||
|
||||
await page.waitForURL((url) => url.pathname === `/booking/${bookingId}`);
|
||||
});
|
||||
|
||||
test("Should prevent cancellation and show an error message", async ({ page }) => {
|
||||
test("Should prevent cancellation and show an error message", async ({
|
||||
page,
|
||||
}) => {
|
||||
const csrfTokenResponse = await page.request.get("/api/csrf");
|
||||
const { csrfToken } = await csrfTokenResponse.json();
|
||||
const response = await page.request.post("/api/cancel", {
|
||||
@@ -657,10 +771,15 @@ test.describe("Event type with disabled cancellation and rescheduling", () => {
|
||||
|
||||
expect(response.status()).toBe(400);
|
||||
const responseBody = await response.json();
|
||||
expect(responseBody.message).toBe("This event type does not allow cancellations");
|
||||
expect(responseBody.message).toBe(
|
||||
"This event type does not allow cancellations"
|
||||
);
|
||||
});
|
||||
});
|
||||
test("Should throw error when both seatsPerTimeSlot and recurringEvent are set", async ({ page, users }) => {
|
||||
test("Should throw error when both seatsPerTimeSlot and recurringEvent are set", async ({
|
||||
page,
|
||||
users,
|
||||
}) => {
|
||||
const user = await users.create({
|
||||
name: `Test-user-${randomString(4)}`,
|
||||
eventTypes: [
|
||||
@@ -699,7 +818,11 @@ test.describe("GTM container", () => {
|
||||
await users.create();
|
||||
});
|
||||
|
||||
test("global GTM should not be loaded on private booking link", async ({ page, users, prisma }) => {
|
||||
test("global GTM should not be loaded on private booking link", async ({
|
||||
page,
|
||||
users,
|
||||
prisma,
|
||||
}) => {
|
||||
const [user] = users.get();
|
||||
const eventType = await user.getFirstEventAsOwner();
|
||||
|
||||
@@ -722,9 +845,12 @@ test.describe("GTM container", () => {
|
||||
});
|
||||
|
||||
const getScheduleRespPromise = page.waitForResponse(
|
||||
(response) => response.url().includes("getSchedule") && response.status() === 200
|
||||
(response) =>
|
||||
response.url().includes("getSchedule") && response.status() === 200
|
||||
);
|
||||
await page.goto(
|
||||
`/d/${eventWithPrivateLink.hashedLink[0]?.link}/${eventWithPrivateLink.slug}`
|
||||
);
|
||||
await page.goto(`/d/${eventWithPrivateLink.hashedLink[0]?.link}/${eventWithPrivateLink.slug}`);
|
||||
await page.waitForLoadState("domcontentloaded");
|
||||
await getScheduleRespPromise;
|
||||
|
||||
@@ -732,15 +858,23 @@ test.describe("GTM container", () => {
|
||||
await expect(injectedScript).not.toBeAttached();
|
||||
});
|
||||
|
||||
test("global GTM should be loaded on non-booking pages", async ({ page, users }) => {
|
||||
test.skip(!process.env.NEXT_PUBLIC_BODY_SCRIPTS, "Skipping test as NEXT_PUBLIC_BODY_SCRIPTS is not set");
|
||||
test("global GTM should be loaded on non-booking pages", async ({
|
||||
page,
|
||||
users,
|
||||
}) => {
|
||||
test.skip(
|
||||
!process.env.NEXT_PUBLIC_BODY_SCRIPTS,
|
||||
"Skipping test as NEXT_PUBLIC_BODY_SCRIPTS is not set"
|
||||
);
|
||||
|
||||
const [user] = users.get();
|
||||
await user.apiLogin();
|
||||
|
||||
// Go to /insights page and wait for one of the common API call to complete
|
||||
const eventsByStatusRespPromise = page.waitForResponse(
|
||||
(response) => response.url().includes("getEventTypesFromGroup") && response.status() === 200
|
||||
(response) =>
|
||||
response.url().includes("getEventTypesFromGroup") &&
|
||||
response.status() === 200
|
||||
);
|
||||
await page.goto(`/insights`);
|
||||
await page.waitForLoadState("domcontentloaded");
|
||||
@@ -755,7 +889,11 @@ test.describe("GTM container", () => {
|
||||
});
|
||||
|
||||
test.describe("Past booking cancellation", () => {
|
||||
test("Cancel button should be hidden for past bookings", async ({ page, users, bookings }) => {
|
||||
test("Cancel button should be hidden for past bookings", async ({
|
||||
page,
|
||||
users,
|
||||
bookings,
|
||||
}) => {
|
||||
const user = await users.create({
|
||||
name: "Test User",
|
||||
});
|
||||
@@ -766,15 +904,23 @@ test.describe("Past booking cancellation", () => {
|
||||
pastDate.setDate(pastDate.getDate() - 1);
|
||||
const endDate = new Date(pastDate.getTime() + 30 * 60 * 1000);
|
||||
|
||||
const booking = await bookings.create(user.id, user.username, user.eventTypes[0].id, {
|
||||
title: "Past Meeting",
|
||||
startTime: pastDate,
|
||||
endTime: endDate,
|
||||
status: "ACCEPTED",
|
||||
});
|
||||
const booking = await bookings.create(
|
||||
user.id,
|
||||
user.username,
|
||||
user.eventTypes[0].id,
|
||||
{
|
||||
title: "Past Meeting",
|
||||
startTime: pastDate,
|
||||
endTime: endDate,
|
||||
status: "ACCEPTED",
|
||||
}
|
||||
);
|
||||
|
||||
await page.goto("/bookings/past");
|
||||
await page.locator('[data-testid="booking-actions-dropdown"]').nth(0).click();
|
||||
await page
|
||||
.locator('[data-testid="booking-actions-dropdown"]')
|
||||
.nth(0)
|
||||
.click();
|
||||
await expect(page.locator('[data-testid="cancel"]')).toBeDisabled();
|
||||
|
||||
await page.goto(`/booking/${booking.uid}`);
|
||||
|
||||
@@ -117,7 +117,7 @@ export function createAppsFixture(page: Page) {
|
||||
},
|
||||
goToAppsTab: async () => {
|
||||
await page.getByTestId("vertical-tab-apps").click();
|
||||
await expect(page.getByTestId("vertical-tab-apps")).toHaveAttribute("aria-current", "page");
|
||||
await expect(page.getByTestId("vertical-tab-apps").first()).toHaveAttribute("aria-current", "page");
|
||||
},
|
||||
activeApp: async (app: string) => {
|
||||
await page.locator(`[data-testid='${app}-app-switch']`).click();
|
||||
@@ -127,7 +127,7 @@ export function createAppsFixture(page: Page) {
|
||||
},
|
||||
verifyAppsInfoNew: async (app: string, eventTypeId: number) => {
|
||||
await page.goto(`event-types/${eventTypeId}?tabName=apps`);
|
||||
await expect(page.getByTestId("vertical-tab-apps")).toHaveAttribute("aria-current", "page"); // fix the race condition
|
||||
await expect(page.getByTestId("vertical-tab-apps").first()).toHaveAttribute("aria-current", "page"); // fix the race condition
|
||||
await expect(page.locator(`[data-testid='${app}-app-switch'][data-state="checked"]`)).toBeVisible();
|
||||
},
|
||||
};
|
||||
|
||||
@@ -34,7 +34,7 @@ test.describe("Managed Event Types", () => {
|
||||
// Let's create a team
|
||||
// Going to create an event type
|
||||
await page.goto("/event-types");
|
||||
const tabItem = page.getByTestId(`horizontal-tab-Owner`);
|
||||
const tabItem = page.getByTestId("horizontal-tab-Owner").first();
|
||||
await expect(tabItem).toBeVisible();
|
||||
// We wait until loading is finished
|
||||
await page.waitForSelector('[data-testid="event-types"]');
|
||||
|
||||
@@ -11,7 +11,7 @@ test.afterEach(({ users }) => users.deleteAll());
|
||||
|
||||
async function goToAppsTab(page: Page, eventTypeId?: number) {
|
||||
await page.goto(`event-types/${eventTypeId}?tabName=apps`);
|
||||
await expect(page.getByTestId("vertical-tab-apps")).toHaveAttribute("aria-current", "page");
|
||||
await expect(page.getByTestId("vertical-tab-apps").first()).toHaveAttribute("aria-current", "page");
|
||||
}
|
||||
|
||||
test.describe("Payment app", () => {
|
||||
|
||||
Reference in New Issue
Block a user