test: e2e for workflows (#9657)
* create test files
* add first e2e test
* finish first e2e test
* code clean up
* fix event type create button data-testid
* enable sandbox mode for non production environments
* comment out code for testing
* Revert "comment out code for testing"
This reverts commit 5553dacce2
.
* clean up comments
* prettier
* use NEXT_PUBLIC_IS_E2E
* use todo fn
---------
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Alan <alannnc@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Shivam Kalra <shivamkalra98@gmail.com>
pull/10297/head^2
parent
337192697f
commit
1aa3077706
|
@ -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");
|
||||
});
|
||||
});
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ export default function WorkflowDetailsPage(props: Props) {
|
|||
<div className="pl-2 pr-3 md:sticky md:top-6 md:h-0 md:pl-0">
|
||||
<div className="mb-5">
|
||||
<TextField
|
||||
data-testid="workflow-name"
|
||||
disabled={props.readOnly}
|
||||
label={`${t("workflow_name")}:`}
|
||||
type="text"
|
||||
|
|
|
@ -65,7 +65,7 @@ export default function WorkflowListPage({ workflows }: Props) {
|
|||
<>
|
||||
{workflows && workflows.length > 0 ? (
|
||||
<div className="bg-default border-subtle overflow-hidden rounded-md border sm:mx-0">
|
||||
<ul className="divide-subtle divide-y">
|
||||
<ul className="divide-subtle divide-y" data-testid="workflow-list">
|
||||
{workflows.map((workflow) => (
|
||||
<li key={workflow.id}>
|
||||
<div className="first-line:group hover:bg-muted flex w-full items-center justify-between p-4 sm:px-6">
|
||||
|
|
|
@ -274,6 +274,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
|||
<Select
|
||||
isSearchable={false}
|
||||
className="text-sm"
|
||||
id="trigger-select"
|
||||
isDisabled={props.readOnly}
|
||||
onChange={(val) => {
|
||||
if (val) {
|
||||
|
|
|
@ -61,6 +61,8 @@ export const scheduleEmailReminder = async (
|
|||
return;
|
||||
}
|
||||
|
||||
const sandboxMode = process.env.NEXT_PUBLIC_IS_E2E ? true : false;
|
||||
|
||||
let name = "";
|
||||
let attendeeName = "";
|
||||
let timeZone = "";
|
||||
|
@ -153,6 +155,11 @@ export const scheduleEmailReminder = async (
|
|||
html: emailContent.emailBody,
|
||||
batchId: batchIdResponse[1].batch_id,
|
||||
replyTo: evt.organizer.email,
|
||||
mailSettings: {
|
||||
sandboxMode: {
|
||||
enable: sandboxMode,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
@ -166,6 +173,11 @@ export const scheduleEmailReminder = async (
|
|||
html: emailContent.emailBody,
|
||||
batchId: batchIdResponse[1].batch_id,
|
||||
replyTo: evt.organizer.email,
|
||||
mailSettings: {
|
||||
sandboxMode: {
|
||||
enable: sandboxMode,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -194,6 +206,11 @@ export const scheduleEmailReminder = async (
|
|||
batchId: batchIdResponse[1].batch_id,
|
||||
sendAt: scheduledDate.unix(),
|
||||
replyTo: evt.organizer.email,
|
||||
mailSettings: {
|
||||
sandboxMode: {
|
||||
enable: sandboxMode,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.workflowReminder.create({
|
||||
|
|
|
@ -262,7 +262,9 @@ function WorkflowPage() {
|
|||
CTA={
|
||||
!readOnly && (
|
||||
<div>
|
||||
<Button type="submit">{t("save")}</Button>
|
||||
<Button data-testid="save-workflow" type="submit">
|
||||
{t("save")}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ export function CreateButton(props: CreateBtnProps) {
|
|||
? createFunction(options[0].teamId || undefined)
|
||||
: null
|
||||
}
|
||||
data-testid="create-button"
|
||||
StartIcon={Plus}
|
||||
loading={isLoading}
|
||||
variant={disableMobileButton ? "button" : "fab"}
|
||||
|
@ -98,6 +99,7 @@ export function CreateButton(props: CreateBtnProps) {
|
|||
<Button
|
||||
variant={disableMobileButton ? "button" : "fab"}
|
||||
StartIcon={Plus}
|
||||
data-testid="create-button-dropdown"
|
||||
loading={isLoading}
|
||||
{...restProps}>
|
||||
{buttonText ? buttonText : t("new")}
|
||||
|
|
Loading…
Reference in New Issue