diff --git a/apps/web/playwright/workflow.e2e.ts b/apps/web/playwright/workflow.e2e.ts new file mode 100644 index 0000000000..02a65898d8 --- /dev/null +++ b/apps/web/playwright/workflow.e2e.ts @@ -0,0 +1,76 @@ +import { expect } from "@playwright/test"; + +import dayjs from "@calcom/dayjs"; +import prisma from "@calcom/prisma"; +import { WorkflowMethods } from "@calcom/prisma/enums"; + +import { test } from "./lib/fixtures"; +import { selectFirstAvailableTimeSlotNextMonth, todo } from "./lib/testUtils"; + +test.afterEach(({ users }) => users.deleteAll()); + +test.describe("Workflow tests", () => { + test.describe("User Workflows", () => { + test("Create default reminder workflow & trigger when event type is booked", async ({ page, users }) => { + const user = await users.create(); + const [eventType] = user.eventTypes; + await user.login(); + await page.goto(`/workflows`); + + await page.click('[data-testid="create-button"]'); + + // select first event type + await page.getByText("Select...").click(); + await page.getByText(eventType.title, { exact: true }).click(); + + // name workflow + await page.fill('[data-testid="workflow-name"]', "Test workflow"); + + // save workflow + await page.click('[data-testid="save-workflow"]'); + + // check if workflow is saved + await expect(page.locator('[data-testid="workflow-list"] > li')).toHaveCount(1); + + // book event type + await page.goto(`/${user.username}/${eventType.slug}`); + await selectFirstAvailableTimeSlotNextMonth(page); + + await page.fill('[name="name"]', "Test"); + await page.fill('[name="email"]', "test@example.com"); + await page.press('[name="email"]', "Enter"); + + // Make sure booking is completed + await expect(page.locator("[data-testid=success-page]")).toBeVisible(); + + const booking = await prisma.booking.findFirst({ + where: { + eventTypeId: eventType.id, + }, + }); + + // check if workflow triggered + const workflowReminders = await prisma.workflowReminder.findMany({ + where: { + bookingUid: booking?.uid ?? "", + }, + }); + + expect(workflowReminders).toHaveLength(1); + + const scheduledDate = dayjs(booking?.startTime).subtract(1, "day").toDate(); + + expect(workflowReminders[0].method).toBe(WorkflowMethods.EMAIL); + expect(workflowReminders[0].scheduledDate.toISOString()).toBe(scheduledDate.toISOString()); + }); + + // add all other actions to this workflow and test if they triggered + // cancel booking and test if workflow reminders are deleted + // test all other triggers + }); + + test.describe("Team Workflows", () => { + todo("Admin can create and update team workflow"); + todo("Members can not create and update team workflows"); + }); +}); diff --git a/packages/features/ee/workflows/api/scheduleEmailReminders.ts b/packages/features/ee/workflows/api/scheduleEmailReminders.ts index 228141e549..f6ac593d94 100644 --- a/packages/features/ee/workflows/api/scheduleEmailReminders.ts +++ b/packages/features/ee/workflows/api/scheduleEmailReminders.ts @@ -32,6 +32,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { return; } + const sandboxMode = process.env.NEXT_PUBLIC_IS_E2E ? true : false; + //delete batch_ids with already past scheduled date from scheduled_sends const remindersToDelete = await prisma.workflowReminder.findMany({ where: { @@ -251,6 +253,11 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { batchId: batchId, sendAt: dayjs(reminder.scheduledDate).unix(), replyTo: reminder.booking.user?.email || senderEmail, + mailSettings: { + sandboxMode: { + enable: sandboxMode, + }, + }, }); } diff --git a/packages/features/ee/workflows/components/WorkflowDetailsPage.tsx b/packages/features/ee/workflows/components/WorkflowDetailsPage.tsx index f475526844..43066a9eff 100644 --- a/packages/features/ee/workflows/components/WorkflowDetailsPage.tsx +++ b/packages/features/ee/workflows/components/WorkflowDetailsPage.tsx @@ -118,6 +118,7 @@ export default function WorkflowDetailsPage(props: Props) {
{workflows && workflows.length > 0 ? (
-
    +
      {workflows.map((workflow) => (
    • diff --git a/packages/features/ee/workflows/components/WorkflowStepContainer.tsx b/packages/features/ee/workflows/components/WorkflowStepContainer.tsx index a0afc3f517..3ce423ddf4 100644 --- a/packages/features/ee/workflows/components/WorkflowStepContainer.tsx +++ b/packages/features/ee/workflows/components/WorkflowStepContainer.tsx @@ -274,6 +274,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {