Skip to content

Commit 6469626

Browse files
committed
feat: add e2e tests
1 parent 1cd83a3 commit 6469626

File tree

8 files changed

+365
-278
lines changed

8 files changed

+365
-278
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import type { Page } from "@playwright/test";
2+
3+
import { expect, test } from "../../fixtures";
4+
5+
const TRIGGER_NAME = "timezone_trigger";
6+
const DEFAULT_TIMEZONE = "Etc/GMT";
7+
8+
async function createTrigger(page: Page, name: string, cronExpression: string, fileName: string, functionName: string) {
9+
await page.getByRole("button", { name: "Add Triggers" }).click();
10+
await page.getByRole("textbox", { name: "Name", exact: true }).fill(name);
11+
await page.getByTestId("select-trigger-type").click();
12+
await page.getByRole("option", { name: "Scheduler" }).click();
13+
await page.getByRole("textbox", { name: "Cron expression" }).fill(cronExpression);
14+
await page.getByTestId("select-file").click();
15+
await page.getByRole("option", { name: fileName }).click();
16+
await page.getByRole("textbox", { name: "Function name" }).fill(functionName);
17+
await page.getByRole("button", { name: "Save", exact: true }).click();
18+
}
19+
20+
async function returnToTriggersList(page: Page) {
21+
await page.getByRole("button", { name: "Return back" }).click();
22+
}
23+
24+
async function hoverTriggerInfo(page: Page, triggerName: string) {
25+
await page.locator(`button[aria-label='Trigger information for "${triggerName}"']`).hover();
26+
}
27+
28+
async function selectTimezone(page: Page, searchTerm: string, optionName: RegExp) {
29+
await page.getByRole("combobox", { name: DEFAULT_TIMEZONE }).click();
30+
await page.keyboard.type(searchTerm);
31+
await page.getByRole("option", { name: optionName }).click();
32+
}
33+
34+
test.describe("Trigger Timezone Features", () => {
35+
test.beforeEach(async ({ dashboardPage }) => {
36+
await dashboardPage.createProjectFromMenu();
37+
});
38+
39+
test("Trigger shows default UTC timezone in info popover", async ({ page }) => {
40+
await createTrigger(page, TRIGGER_NAME, "5 4 * * *", "program.py", "on_trigger");
41+
await returnToTriggersList(page);
42+
43+
await hoverTriggerInfo(page, TRIGGER_NAME);
44+
45+
await expect(page.getByTestId("trigger-detail-timezone")).toHaveText("UTC");
46+
});
47+
48+
test("Edit trigger timezone and verify change in info popover", async ({ page }) => {
49+
await createTrigger(page, TRIGGER_NAME, "5 4 * * *", "program.py", "on_trigger");
50+
await returnToTriggersList(page);
51+
52+
await page.getByText(TRIGGER_NAME).click();
53+
await selectTimezone(page, "jeru", /Jerusalem/);
54+
await page.getByRole("button", { name: "Save", exact: true }).click();
55+
56+
await hoverTriggerInfo(page, TRIGGER_NAME);
57+
58+
await expect(page.getByTestId("trigger-detail-timezone")).toHaveText("Asia/Jerusalem");
59+
});
60+
61+
test("Invalid timezone input retains original value", async ({ page }) => {
62+
await createTrigger(page, TRIGGER_NAME, "5 4 * * *", "program.py", "on_trigger");
63+
64+
await page.getByRole("combobox", { name: DEFAULT_TIMEZONE }).fill("invalid_timezone");
65+
await page.getByRole("textbox", { name: "Cron expression" }).click();
66+
67+
await expect(page.getByRole("combobox", { name: DEFAULT_TIMEZONE })).toBeVisible();
68+
});
69+
});

src/components/organisms/configuration/triggers/add.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { NameAndConnectionFields, SchedulerFields, SchedulerInfo, WebhookFields
88
import { TriggerSpecificFields } from "./formParts/fileAndFunction";
99
import { SelectOption } from "@interfaces/components";
1010
import { LoggerService, TriggersService } from "@services";
11-
import { namespaces } from "@src/constants";
11+
import { defaultTimezoneValue, namespaces } from "@src/constants";
1212
import { emptySelectItem } from "@src/constants/forms";
1313
import { TriggerTypes } from "@src/enums";
1414
import { TriggerFormIds } from "@src/enums/components";
@@ -51,7 +51,7 @@ export const AddTrigger = () => {
5151
filter: "",
5252
isDurable: false,
5353
isSync: false,
54-
timezone: "UTC",
54+
timezone: defaultTimezoneValue,
5555
},
5656
resolver: triggerResolver,
5757
});

src/components/organisms/configuration/triggers/edit.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { useLocation, useNavigate, useParams } from "react-router-dom";
88
import { NameAndConnectionFields, SchedulerFields, SchedulerInfo, WebhookFields } from "./formParts";
99
import { TriggerSpecificFields } from "./formParts/fileAndFunction";
1010
import { TriggersService } from "@services";
11-
import { extraTriggerTypes, featureFlags } from "@src/constants";
11+
import { defaultTimezoneValue, extraTriggerTypes, featureFlags } from "@src/constants";
1212
import { emptySelectItem } from "@src/constants/forms";
1313
import { TriggerTypes } from "@src/enums";
1414
import { TriggerFormIds } from "@src/enums/components";
@@ -64,7 +64,7 @@ export const EditTrigger = ({
6464
cron: "",
6565
eventTypeSelect: emptySelectItem,
6666
filter: "",
67-
timezone: "UTC",
67+
timezone: defaultTimezoneValue,
6868
isDurable: false,
6969
isSync: false,
7070
},
@@ -120,7 +120,7 @@ export const EditTrigger = ({
120120
filePath: { label: trigger?.path, value: trigger?.path },
121121
entryFunction: trigger?.entryFunction,
122122
cron: trigger?.schedule,
123-
timezone: trigger?.timezone || "UTC",
123+
timezone: trigger?.timezone || defaultTimezoneValue,
124124
eventTypeSelect: { label: trigger?.eventType, value: trigger?.eventType },
125125
filter: trigger?.filter,
126126
isDurable: trigger?.isDurable || false,

src/components/organisms/configuration/triggers/formParts/scheduler.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React, { useEffect } from "react";
33
import { Controller, useFormContext, useWatch } from "react-hook-form";
44
import { useTranslation } from "react-i18next";
55

6+
import { defaultTimezoneValue } from "@src/constants";
67
import { TriggerForm } from "@src/types/models";
78

89
import { ErrorMessage, Input } from "@components/atoms";
@@ -18,13 +19,20 @@ export const SchedulerFields = () => {
1819
} = useFormContext<TriggerForm>();
1920

2021
const cronValue = useWatch({ control, name: "cron" });
22+
const timezoneValue = useWatch({ control, name: "timezone" });
2123

2224
useEffect(() => {
2325
if (cronValue) {
2426
setValue("cron", cronValue);
2527
}
2628
}, [cronValue, setValue]);
2729

30+
useEffect(() => {
31+
if (!timezoneValue) {
32+
setValue("timezone", defaultTimezoneValue);
33+
}
34+
}, [timezoneValue, setValue]);
35+
2836
return (
2937
<div className="flex flex-col gap-6">
3038
<div className="relative">
@@ -46,6 +54,7 @@ export const SchedulerFields = () => {
4654
name="timezone"
4755
render={({ field: { onChange, value } }) => (
4856
<TimezoneSelect
57+
aria-label={value}
4958
isError={!!errors.timezone}
5059
onChange={(selectedOption) => onChange(selectedOption?.value)}
5160
value={value}

src/components/organisms/configuration/triggers/triggerInfoPopover.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React, { ComponentType, useCallback, useEffect, useMemo, useState } from
33
import { useTranslation } from "react-i18next";
44

55
import { IntegrationsService } from "@services/integrations.service";
6+
import { defaultTimezoneValue } from "@src/constants";
67
import { TriggerTypes } from "@src/enums";
78
import { IntegrationsMap } from "@src/enums/components/connection.enum";
89
import { useCacheStore } from "@src/store";
@@ -37,7 +38,12 @@ export const TriggerInfoPopover = ({ triggerId }: { triggerId: string }) => {
3738
const configureTriggerDisplay = useCallback(
3839
async (trigger: Trigger) => {
3940
if (trigger.sourceType === TriggerTypes.schedule) {
40-
setScheduleDetails([{ label: t("cron"), value: trigger.schedule }, ...baseDetails]);
41+
const timezoneDisplay = trigger.timezone === defaultTimezoneValue ? "UTC" : trigger.timezone;
42+
setScheduleDetails([
43+
{ label: t("cron"), value: trigger.schedule },
44+
{ label: t("timezone"), value: timezoneDisplay },
45+
...baseDetails,
46+
]);
4147
return;
4248
}
4349

src/constants/global.constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,4 @@ export const systemCookies = {
4646
};
4747
export const defaultManifestFileName = "autokitteh.yaml";
4848
export const optionalManifestFileName = "autokitteh.yaml.user";
49+
export const defaultTimezoneValue = "Etc/GMT";

src/constants/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export {
3535
optionalManifestFileName,
3636
msClarityId,
3737
appMode,
38+
defaultTimezoneValue,
3839
} from "@constants/global.constants";
3940
export { integrationToEditComponent } from "@constants/connections/editComponentsMapping.constants";
4041
export { formsPerIntegrationsMapping } from "@constants/connections/formsPerIntegrationsMapping.constants";

0 commit comments

Comments
 (0)