Fix a set of E2E bugs causing several CI failures (#2177)
* Fix E2E bugs causing CI failutes * Revert setup in dx Co-authored-by: zomars <zomars@me.com>
This commit is contained in:
parent
39d395bf62
commit
55587e92c1
19 changed files with 198 additions and 151 deletions
1
.github/workflows/e2e.yml
vendored
1
.github/workflows/e2e.yml
vendored
|
@ -13,7 +13,6 @@ jobs:
|
||||||
DATABASE_URL: postgresql://postgres:@localhost:5432/calendso
|
DATABASE_URL: postgresql://postgres:@localhost:5432/calendso
|
||||||
BASE_URL: http://localhost:3000
|
BASE_URL: http://localhost:3000
|
||||||
JWT_SECRET: secret
|
JWT_SECRET: secret
|
||||||
PLAYWRIGHT_SECRET: ${{ secrets.CI_PLAYWRIGHT_SECRET }}
|
|
||||||
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
|
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
|
||||||
GOOGLE_LOGIN_ENABLED: true
|
GOOGLE_LOGIN_ENABLED: true
|
||||||
# CRON_API_KEY: xxx
|
# CRON_API_KEY: xxx
|
||||||
|
|
|
@ -196,7 +196,7 @@ echo 'NEXT_PUBLIC_DEBUG=1' >> apps/web/.env
|
||||||
### E2E-Testing
|
### E2E-Testing
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# In first terminal
|
# In first terminal. Must run on port 3000.
|
||||||
yarn dx
|
yarn dx
|
||||||
# In second terminal
|
# In second terminal
|
||||||
yarn workspace @calcom/web test-e2e
|
yarn workspace @calcom/web test-e2e
|
||||||
|
|
|
@ -25,7 +25,6 @@ NEXT_PUBLIC_APP_URL='http://localhost:3000'
|
||||||
|
|
||||||
JWT_SECRET='secret'
|
JWT_SECRET='secret'
|
||||||
# This is used so we can bypass emails in auth flows for E2E testing
|
# This is used so we can bypass emails in auth flows for E2E testing
|
||||||
PLAYWRIGHT_SECRET=
|
|
||||||
|
|
||||||
# To enable SAML login, set both these variables
|
# To enable SAML login, set both these variables
|
||||||
# @see https://github.com/calcom/cal.com/tree/main/packages/ee#setting-up-saml-login
|
# @see https://github.com/calcom/cal.com/tree/main/packages/ee#setting-up-saml-login
|
||||||
|
@ -102,3 +101,6 @@ NEXT_PUBLIC_INTERCOM_APP_ID=
|
||||||
|
|
||||||
# Zendesk Config
|
# Zendesk Config
|
||||||
NEXT_PUBLIC_ZENDESK_KEY=
|
NEXT_PUBLIC_ZENDESK_KEY=
|
||||||
|
|
||||||
|
# Set it to "1" if you need to run E2E tests locally
|
||||||
|
NEXT_PUBLIC_IS_E2E=
|
||||||
|
|
|
@ -65,10 +65,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||||
await sendPasswordResetEmail(passwordEmail);
|
await sendPasswordResetEmail(passwordEmail);
|
||||||
|
|
||||||
/** So we can test the password reset flow on CI */
|
/** So we can test the password reset flow on CI */
|
||||||
if (
|
if (process.env.NEXT_PUBLIC_IS_E2E) {
|
||||||
process.env.PLAYWRIGHT_SECRET &&
|
|
||||||
req.headers["x-playwright-secret"] === process.env.PLAYWRIGHT_SECRET
|
|
||||||
) {
|
|
||||||
return res.status(201).json({ message: "Reset Requested", resetLink });
|
return res.status(201).json({ message: "Reset Requested", resetLink });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,6 @@
|
||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "@playwright/test";
|
||||||
|
|
||||||
test("Can reset forgotten password", async ({ browser }) => {
|
test("Can reset forgotten password", async ({ page }) => {
|
||||||
test.fixme(true, "TODO: This test is failing randomly, disabled for now");
|
|
||||||
// Create a new incognito browser context
|
|
||||||
const context = await browser.newContext({
|
|
||||||
extraHTTPHeaders: {
|
|
||||||
// Only needed for bypassing emails while testing
|
|
||||||
"X-Playwright-Secret": process.env.PLAYWRIGHT_SECRET || "",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
// Create a new page inside context.
|
|
||||||
const page = await context.newPage();
|
|
||||||
|
|
||||||
// Got to reset password flow
|
// Got to reset password flow
|
||||||
await page.goto("/auth/forgot-password");
|
await page.goto("/auth/forgot-password");
|
||||||
|
|
||||||
|
@ -50,6 +39,4 @@ test("Can reset forgotten password", async ({ browser }) => {
|
||||||
await page.waitForSelector("[data-testid=dashboard-shell]");
|
await page.waitForSelector("[data-testid=dashboard-shell]");
|
||||||
|
|
||||||
await expect(page.locator("[data-testid=dashboard-shell]")).toBeVisible();
|
await expect(page.locator("[data-testid=dashboard-shell]")).toBeVisible();
|
||||||
|
|
||||||
await context.close();
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,18 +1,8 @@
|
||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "@playwright/test";
|
||||||
|
|
||||||
import prisma from "@lib/prisma";
|
import { deleteAllBookingsByEmail } from "./lib/teardown";
|
||||||
|
|
||||||
import { selectFirstAvailableTimeSlotNextMonth, todo } from "./lib/testUtils";
|
import { selectFirstAvailableTimeSlotNextMonth, todo } from "./lib/testUtils";
|
||||||
|
|
||||||
const deleteBookingsByEmail = async (email: string) =>
|
|
||||||
prisma.booking.deleteMany({
|
|
||||||
where: {
|
|
||||||
user: {
|
|
||||||
email,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
test.describe("free user", () => {
|
test.describe("free user", () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await page.goto("/free");
|
await page.goto("/free");
|
||||||
|
@ -20,7 +10,7 @@ test.describe("free user", () => {
|
||||||
|
|
||||||
test.afterEach(async () => {
|
test.afterEach(async () => {
|
||||||
// delete test bookings
|
// delete test bookings
|
||||||
await deleteBookingsByEmail("free@example.com");
|
await deleteAllBookingsByEmail("free@example.com");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("only one visible event", async ({ page }) => {
|
test("only one visible event", async ({ page }) => {
|
||||||
|
@ -81,14 +71,15 @@ test.describe("pro user", () => {
|
||||||
await page.goto("/pro");
|
await page.goto("/pro");
|
||||||
});
|
});
|
||||||
|
|
||||||
test.afterEach(async () => {
|
test.afterAll(async () => {
|
||||||
// delete test bookings
|
// delete test bookings
|
||||||
await deleteBookingsByEmail("pro@example.com");
|
await deleteAllBookingsByEmail("pro@example.com");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("pro user's page has at least 2 visible events", async ({ page }) => {
|
test("pro user's page has at least 2 visible events", async ({ page }) => {
|
||||||
const $eventTypes = await page.$$("[data-testid=event-types] > *");
|
// await page.pause();
|
||||||
expect($eventTypes.length).toBeGreaterThanOrEqual(2);
|
const $eventTypes = await page.locator("[data-testid=event-types] > *");
|
||||||
|
expect(await $eventTypes.count()).toBeGreaterThanOrEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("book an event first day in next month", async ({ page }) => {
|
test("book an event first day in next month", async ({ page }) => {
|
||||||
|
|
|
@ -1,28 +1,30 @@
|
||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "@playwright/test";
|
||||||
|
|
||||||
// Using logged in state from globalSteup
|
test.describe("Change Passsword Test", () => {
|
||||||
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
// Using logged in state from globalSteup
|
||||||
|
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
||||||
|
|
||||||
test("change password", async ({ page }) => {
|
test("change password", async ({ page }) => {
|
||||||
// Try to go homepage
|
// Try to go homepage
|
||||||
await page.goto("/");
|
await page.goto("/");
|
||||||
// It should redirect you to the event-types page
|
// It should redirect you to the event-types page
|
||||||
await page.waitForSelector("[data-testid=event-types]");
|
await page.waitForSelector("[data-testid=event-types]");
|
||||||
|
|
||||||
// Go to http://localhost:3000/settings/security
|
// Go to http://localhost:3000/settings/security
|
||||||
await page.goto("/settings/security");
|
await page.goto("/settings/security");
|
||||||
|
|
||||||
// Fill form
|
// Fill form
|
||||||
await page.fill('[name="current_password"]', "pro");
|
await page.fill('[name="current_password"]', "pro");
|
||||||
await page.fill('[name="new_password"]', "pro1");
|
await page.fill('[name="new_password"]', "pro1");
|
||||||
await page.press('[name="new_password"]', "Enter");
|
await page.press('[name="new_password"]', "Enter");
|
||||||
|
|
||||||
await expect(page.locator(`text=Your password has been successfully changed.`)).toBeVisible();
|
await expect(page.locator(`text=Your password has been successfully changed.`)).toBeVisible();
|
||||||
|
|
||||||
// Let's revert back to prevent errors on other tests
|
// Let's revert back to prevent errors on other tests
|
||||||
await page.fill('[name="current_password"]', "pro1");
|
await page.fill('[name="current_password"]', "pro1");
|
||||||
await page.fill('[name="new_password"]', "pro");
|
await page.fill('[name="new_password"]', "pro");
|
||||||
await page.press('[name="new_password"]', "Enter");
|
await page.press('[name="new_password"]', "Enter");
|
||||||
|
|
||||||
await expect(page.locator(`text=Your password has been successfully changed.`)).toBeVisible();
|
await expect(page.locator(`text=Your password has been successfully changed.`)).toBeVisible();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,81 +1,92 @@
|
||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "@playwright/test";
|
||||||
|
|
||||||
import { randomString } from "../lib/random";
|
import { randomString } from "../lib/random";
|
||||||
|
import { deleteEventTypeByTitle } from "./lib/teardown";
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.describe("Event Types tests", () => {
|
||||||
await page.goto("/event-types");
|
test.beforeEach(async ({ page }) => {
|
||||||
// We wait until loading is finished
|
await page.goto("/event-types");
|
||||||
await page.waitForSelector('[data-testid="event-types"]');
|
// We wait until loading is finished
|
||||||
});
|
await page.waitForSelector('[data-testid="event-types"]');
|
||||||
|
|
||||||
test.describe("pro user", () => {
|
|
||||||
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
|
||||||
|
|
||||||
test("has at least 2 events", async ({ page }) => {
|
|
||||||
const $eventTypes = await page.$$("[data-testid=event-types] > *");
|
|
||||||
|
|
||||||
expect($eventTypes.length).toBeGreaterThanOrEqual(2);
|
|
||||||
for (const $el of $eventTypes) {
|
|
||||||
expect(await $el.getAttribute("data-disabled")).toBe("0");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("can add new event type", async ({ page }) => {
|
test.describe("pro user", () => {
|
||||||
await page.click("[data-testid=new-event-type]");
|
let isCreated;
|
||||||
const nonce = randomString(3);
|
let eventTitle;
|
||||||
const eventTitle = `hello ${nonce}`;
|
|
||||||
|
|
||||||
await page.fill("[name=title]", eventTitle);
|
test.afterAll(async () => {
|
||||||
await page.fill("[name=length]", "10");
|
if (isCreated) await deleteEventTypeByTitle(eventTitle);
|
||||||
await page.click("[type=submit]");
|
});
|
||||||
|
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
||||||
|
|
||||||
await page.waitForNavigation({
|
test("has at least 2 events", async ({ page }) => {
|
||||||
url(url) {
|
const $eventTypes = await page.locator("[data-testid=event-types] > *");
|
||||||
return url.pathname !== "/event-types";
|
const count = await $eventTypes.count();
|
||||||
},
|
expect(count).toBeGreaterThanOrEqual(2);
|
||||||
|
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
expect(await $eventTypes.nth(i).getAttribute("data-disabled")).toBe("0");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await page.goto("/event-types");
|
test("can add new event type", async ({ page }) => {
|
||||||
|
await page.click("[data-testid=new-event-type]");
|
||||||
|
const nonce = randomString(3);
|
||||||
|
eventTitle = `hello ${nonce}`;
|
||||||
|
|
||||||
await expect(page.locator(`text='${eventTitle}'`)).toBeVisible();
|
await page.fill("[name=title]", eventTitle);
|
||||||
|
await page.fill("[name=length]", "10");
|
||||||
|
await page.click("[type=submit]");
|
||||||
|
|
||||||
|
await page.waitForNavigation({
|
||||||
|
url(url) {
|
||||||
|
return url.pathname !== "/event-types";
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.goto("/event-types");
|
||||||
|
|
||||||
|
isCreated = await expect(page.locator(`text='${eventTitle}'`)).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("can duplicate an existing event type", async ({ page }) => {
|
||||||
|
const firstTitle = await page.locator("[data-testid=event-type-title-3]").innerText();
|
||||||
|
const firstFullSlug = await page.locator("[data-testid=event-type-slug-3]").innerText();
|
||||||
|
const firstSlug = firstFullSlug.split("/")[2];
|
||||||
|
|
||||||
|
await page.click("[data-testid=event-type-options-3]");
|
||||||
|
await page.click("[data-testid=event-type-duplicate-3]");
|
||||||
|
|
||||||
|
const url = await page.url();
|
||||||
|
const params = new URLSearchParams(url);
|
||||||
|
|
||||||
|
await expect(params.get("title")).toBe(firstTitle);
|
||||||
|
await expect(params.get("slug")).toBe(firstSlug);
|
||||||
|
|
||||||
|
const formTitle = await page.inputValue("[name=title]");
|
||||||
|
const formSlug = await page.inputValue("[name=slug]");
|
||||||
|
|
||||||
|
await expect(formTitle).toBe(firstTitle);
|
||||||
|
await expect(formSlug).toBe(firstSlug);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("can duplicate an existing event type", async ({ page }) => {
|
test.describe("free user", () => {
|
||||||
const firstTitle = await page.locator("[data-testid=event-type-title-3]").innerText();
|
test.use({ storageState: "playwright/artifacts/freeStorageState.json" });
|
||||||
const firstFullSlug = await page.locator("[data-testid=event-type-slug-3]").innerText();
|
|
||||||
const firstSlug = firstFullSlug.split("/")[2];
|
|
||||||
|
|
||||||
await page.click("[data-testid=event-type-options-3]");
|
test("has at least 2 events where first is enabled", async ({ page }) => {
|
||||||
await page.click("[data-testid=event-type-duplicate-3]");
|
const $eventTypes = await page.locator("[data-testid=event-types] > *");
|
||||||
|
const count = await $eventTypes.count();
|
||||||
|
expect(count).toBeGreaterThanOrEqual(2);
|
||||||
|
|
||||||
const url = await page.url();
|
const $first = await $eventTypes.first();
|
||||||
const params = new URLSearchParams(url);
|
const $last = await $eventTypes.last()!;
|
||||||
|
expect(await $first.getAttribute("data-disabled")).toBe("0");
|
||||||
|
expect(await $last.getAttribute("data-disabled")).toBe("1");
|
||||||
|
});
|
||||||
|
|
||||||
await expect(params.get("title")).toBe(firstTitle);
|
test("can not add new event type", async ({ page }) => {
|
||||||
await expect(params.get("slug")).toBe(firstSlug);
|
await expect(page.locator("[data-testid=new-event-type]")).toBeDisabled();
|
||||||
|
});
|
||||||
const formTitle = await page.inputValue("[name=title]");
|
|
||||||
const formSlug = await page.inputValue("[name=slug]");
|
|
||||||
|
|
||||||
await expect(formTitle).toBe(firstTitle);
|
|
||||||
await expect(formSlug).toBe(firstSlug);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test.describe("free user", () => {
|
|
||||||
test.use({ storageState: "playwright/artifacts/freeStorageState.json" });
|
|
||||||
|
|
||||||
test("has at least 2 events where first is enabled", async ({ page }) => {
|
|
||||||
const $eventTypes = await page.$$("[data-testid=event-types] > *");
|
|
||||||
|
|
||||||
expect($eventTypes.length).toBeGreaterThanOrEqual(2);
|
|
||||||
const [$first] = $eventTypes;
|
|
||||||
const $last = $eventTypes.pop()!;
|
|
||||||
expect(await $first.getAttribute("data-disabled")).toBe("0");
|
|
||||||
expect(await $last.getAttribute("data-disabled")).toBe("1");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("can not add new event type", async ({ page }) => {
|
|
||||||
await expect(page.locator("[data-testid=new-event-type]")).toBeDisabled();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "@playwright/test";
|
||||||
|
|
||||||
import { hasIntegrationInstalled } from "../lib/integrations/getIntegrations";
|
import { hasIntegrationInstalled } from "../lib/integrations/getIntegrations";
|
||||||
|
import * as teardown from "./lib/teardown";
|
||||||
import { selectFirstAvailableTimeSlotNextMonth, todo } from "./lib/testUtils";
|
import { selectFirstAvailableTimeSlotNextMonth, todo } from "./lib/testUtils";
|
||||||
|
|
||||||
test.describe.serial("Stripe integration", () => {
|
test.describe.serial("Stripe integration", () => {
|
||||||
|
test.afterAll(() => {
|
||||||
|
teardown.deleteAllPaymentsByEmail("pro@example.com");
|
||||||
|
teardown.deleteAllBookingsByEmail("pro@example.com");
|
||||||
|
});
|
||||||
test.skip(!hasIntegrationInstalled("stripe_payment"), "It should only run if Stripe is installed");
|
test.skip(!hasIntegrationInstalled("stripe_payment"), "It should only run if Stripe is installed");
|
||||||
|
|
||||||
test.describe.serial("Stripe integration dashboard", () => {
|
test.describe.serial("Stripe integration dashboard", () => {
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "@playwright/test";
|
||||||
|
|
||||||
|
import * as teardown from "./lib/teardown";
|
||||||
import { createHttpServer, selectFirstAvailableTimeSlotNextMonth, todo, waitFor } from "./lib/testUtils";
|
import { createHttpServer, selectFirstAvailableTimeSlotNextMonth, todo, waitFor } from "./lib/testUtils";
|
||||||
|
|
||||||
test.describe("integrations", () => {
|
test.describe("integrations", () => {
|
||||||
|
//teardown
|
||||||
|
test.afterAll(async () => {
|
||||||
|
await teardown.deleteAllWebhooksByEmail("pro@example.com");
|
||||||
|
await teardown.deleteAllBookingsByEmail("pro@example.com");
|
||||||
|
});
|
||||||
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
|
|
40
apps/web/playwright/lib/teardown.ts
Normal file
40
apps/web/playwright/lib/teardown.ts
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
|
export const deleteAllBookingsByEmail = async (email: string) =>
|
||||||
|
prisma.booking.deleteMany({
|
||||||
|
where: {
|
||||||
|
user: {
|
||||||
|
email,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const deleteEventTypeByTitle = async (title: string) => {
|
||||||
|
const event = (await prisma.eventType.findFirst({
|
||||||
|
select: { id: true },
|
||||||
|
where: { title: title },
|
||||||
|
}))!;
|
||||||
|
await prisma.eventType.delete({ where: { id: event.id } });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteAllWebhooksByEmail = async (email: string) => {
|
||||||
|
await prisma.webhook.deleteMany({
|
||||||
|
where: {
|
||||||
|
user: {
|
||||||
|
email,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteAllPaymentsByEmail = async (email: string) => {
|
||||||
|
await prisma.payment.deleteMany({
|
||||||
|
where: {
|
||||||
|
booking: {
|
||||||
|
user: {
|
||||||
|
email,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
|
@ -1,11 +1,13 @@
|
||||||
import { test } from "@playwright/test";
|
import { test } from "@playwright/test";
|
||||||
|
|
||||||
// Using logged in state from globalSteup
|
test.describe("Login tests", () => {
|
||||||
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
// Using logged in state from globalSteup
|
||||||
|
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
||||||
|
|
||||||
test("login with pro@example.com", async ({ page }) => {
|
test("login with pro@example.com", async ({ page }) => {
|
||||||
// Try to go homepage
|
// Try to go homepage
|
||||||
await page.goto("/");
|
await page.goto("/");
|
||||||
// It should redirect you to the event-types page
|
// It should redirect you to the event-types page
|
||||||
await page.waitForSelector("[data-testid=event-types]");
|
await page.waitForSelector("[data-testid=event-types]");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,13 +2,15 @@ import { test } from "@playwright/test";
|
||||||
|
|
||||||
import { IS_SAML_LOGIN_ENABLED } from "../server/lib/constants";
|
import { IS_SAML_LOGIN_ENABLED } from "../server/lib/constants";
|
||||||
|
|
||||||
// Using logged in state from globalSteup
|
test.describe("SAML tests", () => {
|
||||||
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
// Using logged in state from globalSteup
|
||||||
|
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
||||||
|
|
||||||
test("test SAML configuration UI with pro@example.com", async ({ page }) => {
|
test("test SAML configuration UI with pro@example.com", async ({ page }) => {
|
||||||
test.skip(!IS_SAML_LOGIN_ENABLED, "It should only run if SAML is enabled");
|
test.skip(!IS_SAML_LOGIN_ENABLED, "It should only run if SAML is enabled");
|
||||||
// Try to go Security page
|
// Try to go Security page
|
||||||
await page.goto("/settings/security");
|
await page.goto("/settings/security");
|
||||||
// It should redirect you to the event-types page
|
// It should redirect you to the event-types page
|
||||||
await page.waitForSelector("[data-testid=saml_config]");
|
await page.waitForSelector("[data-testid=saml_config]");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "@playwright/test";
|
||||||
|
|
||||||
// Using logged in state from globalSteup
|
test.describe("Trial account tests", () => {
|
||||||
test.use({ storageState: "playwright/artifacts/trialStorageState.json" });
|
// Using logged in state from globalSteup
|
||||||
|
test.use({ storageState: "playwright/artifacts/trialStorageState.json" });
|
||||||
|
|
||||||
test("Trial banner should be visible to TRIAL users", async ({ page }) => {
|
test("Trial banner should be visible to TRIAL users", async ({ page }) => {
|
||||||
// Try to go homepage
|
// Try to go homepage
|
||||||
await page.goto("/");
|
await page.goto("/");
|
||||||
// It should redirect you to the event-types page
|
// It should redirect you to the event-types page
|
||||||
await page.waitForSelector("[data-testid=event-types]");
|
await page.waitForSelector("[data-testid=event-types]");
|
||||||
|
|
||||||
await expect(page.locator(`[data-testid=trial-banner]`)).toBeVisible();
|
await expect(page.locator(`[data-testid=trial-banner]`)).toBeVisible();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
"start": "turbo run start --scope=\"@calcom/web\"",
|
"start": "turbo run start --scope=\"@calcom/web\"",
|
||||||
"test": "turbo run test",
|
"test": "turbo run test",
|
||||||
"test-playwright": "yarn playwright test",
|
"test-playwright": "yarn playwright test --config=tests/config/playwright.config.ts",
|
||||||
"test-e2e": "turbo run test-e2e --concurrency=1",
|
"test-e2e": "turbo run test-e2e --concurrency=1",
|
||||||
"type-check": "turbo run type-check"
|
"type-check": "turbo run type-check"
|
||||||
},
|
},
|
||||||
|
|
0
packages/prisma/zod/custom/eventtype.ts
Normal file → Executable file
0
packages/prisma/zod/custom/eventtype.ts
Normal file → Executable file
0
packages/prisma/zod/webhook.ts
Normal file → Executable file
0
packages/prisma/zod/webhook.ts
Normal file → Executable file
|
@ -19,6 +19,8 @@ const testDir = path.join(__dirname, "..", "..", "apps/web/playwright");
|
||||||
|
|
||||||
const config: PlaywrightTestConfig = {
|
const config: PlaywrightTestConfig = {
|
||||||
forbidOnly: !!process.env.CI,
|
forbidOnly: !!process.env.CI,
|
||||||
|
retries: 1,
|
||||||
|
workers: 1,
|
||||||
timeout: 60_000,
|
timeout: 60_000,
|
||||||
reporter: [
|
reporter: [
|
||||||
[process.env.CI ? "github" : "list"],
|
[process.env.CI ? "github" : "list"],
|
||||||
|
@ -28,7 +30,7 @@ const config: PlaywrightTestConfig = {
|
||||||
globalSetup: require.resolve("./globalSetup"),
|
globalSetup: require.resolve("./globalSetup"),
|
||||||
outputDir,
|
outputDir,
|
||||||
webServer: {
|
webServer: {
|
||||||
command: "yarn workspace @calcom/web start -p 3000",
|
command: "NEXT_PUBLIC_IS_E2E=1 yarn workspace @calcom/web start -p 3000",
|
||||||
port: 3000,
|
port: 3000,
|
||||||
timeout: 60_000,
|
timeout: 60_000,
|
||||||
reuseExistingServer: !process.env.CI,
|
reuseExistingServer: !process.env.CI,
|
||||||
|
|
11
turbo.json
11
turbo.json
|
@ -20,7 +20,6 @@
|
||||||
"@calcom/web#build": {
|
"@calcom/web#build": {
|
||||||
"dependsOn": [
|
"dependsOn": [
|
||||||
"^build",
|
"^build",
|
||||||
"@calcom/prisma#db-deploy",
|
|
||||||
"$BASE_URL",
|
"$BASE_URL",
|
||||||
"$CALENDSO_ENCRYPTION_KEY",
|
"$CALENDSO_ENCRYPTION_KEY",
|
||||||
"$CRON_API_KEY",
|
"$CRON_API_KEY",
|
||||||
|
@ -46,7 +45,6 @@
|
||||||
"$PAYMENT_FEE_FIXED",
|
"$PAYMENT_FEE_FIXED",
|
||||||
"$PAYMENT_FEE_PERCENTAGE",
|
"$PAYMENT_FEE_PERCENTAGE",
|
||||||
"$PGSSLMODE",
|
"$PGSSLMODE",
|
||||||
"$PLAYWRIGHT_SECRET",
|
|
||||||
"$SAML_ADMINS",
|
"$SAML_ADMINS",
|
||||||
"$SAML_DATABASE_URL",
|
"$SAML_DATABASE_URL",
|
||||||
"$STRIPE_CLIENT_ID",
|
"$STRIPE_CLIENT_ID",
|
||||||
|
@ -64,7 +62,9 @@
|
||||||
"@calcom/web#dx": {
|
"@calcom/web#dx": {
|
||||||
"dependsOn": ["@calcom/prisma#dx"]
|
"dependsOn": ["@calcom/prisma#dx"]
|
||||||
},
|
},
|
||||||
"@calcom/web#start": {},
|
"@calcom/web#start": {
|
||||||
|
"dependsOn": ["@calcom/prisma#db-deploy"]
|
||||||
|
},
|
||||||
"@calcom/website#build": {
|
"@calcom/website#build": {
|
||||||
"dependsOn": ["$WEBSITE_BASE_URL"],
|
"dependsOn": ["$WEBSITE_BASE_URL"],
|
||||||
"outputs": [".next/**"]
|
"outputs": [".next/**"]
|
||||||
|
@ -97,12 +97,11 @@
|
||||||
},
|
},
|
||||||
"start": {},
|
"start": {},
|
||||||
"test": {
|
"test": {
|
||||||
"dependsOn": []
|
"dependsOn": ["^test"]
|
||||||
},
|
},
|
||||||
"test-e2e": {
|
"test-e2e": {
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"dependsOn": ["^test", "@calcom/web#build", "@calcom/prisma#db-reset"],
|
"dependsOn": ["test", "@calcom/web#build", "@calcom/prisma#db-reset"]
|
||||||
"outputs": ["playwright", "test-results"]
|
|
||||||
},
|
},
|
||||||
"type-check": {
|
"type-check": {
|
||||||
"outputs": []
|
"outputs": []
|
||||||
|
|
Loading…
Reference in a new issue