From eaa1ad6578fcaf640ba4cda87affc098d3bdda1d Mon Sep 17 00:00:00 2001 From: Rajiv Sahal Date: Wed, 17 Sep 2025 14:50:38 +0530 Subject: [PATCH] feat: e2e tests for `Connect` atoms (#23433) * e2e tests for apple connect atom * update globalEnv for turbo.json * update pages for tests * update playwright config so we can use env variables inside tests * update packages * update variable names * update playwright config * fix: import variables from env instead of separate files * update env variables for atoms e2e yml --- packages/platform/examples/base/package.json | 1 + .../examples/base/playwright.config.ts | 6 ++ .../examples/base/src/pages/calendars.tsx | 2 +- .../examples/base/src/pages/index.tsx | 9 ++- .../tests/connect-atoms/apple-connect.e2e.ts | 60 +++++++++++++++++++ turbo.json | 2 + 6 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 packages/platform/examples/base/tests/connect-atoms/apple-connect.e2e.ts diff --git a/packages/platform/examples/base/package.json b/packages/platform/examples/base/package.json index 3c7cc12cfb..d761c05f05 100644 --- a/packages/platform/examples/base/package.json +++ b/packages/platform/examples/base/package.json @@ -26,6 +26,7 @@ "@types/react": "^18", "@types/react-dom": "^18", "autoprefixer": "^10.0.1", + "dotenv": "^17.2.1", "eslint": "^8.34.0", "eslint-config-next": "14.0.4", "postcss": "^8", diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 240045c3eb..d77d9e7136 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -1,4 +1,10 @@ import { defineConfig, devices } from "@playwright/test"; +import dotenv from "dotenv"; +import path from "path"; + +const envPath = process.env.CI ? path.resolve(__dirname, ".env") : path.resolve(__dirname, ".env.local"); + +dotenv.config({ path: envPath }); const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; diff --git a/packages/platform/examples/base/src/pages/calendars.tsx b/packages/platform/examples/base/src/pages/calendars.tsx index 2cd2e8d59a..d521ccf1c1 100644 --- a/packages/platform/examples/base/src/pages/calendars.tsx +++ b/packages/platform/examples/base/src/pages/calendars.tsx @@ -9,7 +9,7 @@ export default function Calendars(props: { calUsername: string; calEmail: string return (
-
+
@@ -19,7 +23,7 @@ export default function Home(props: { calUsername: string; calEmail: string }) {

To get started, connect your google calendar.

-
+
{ + router.push(`/calendars`); + }} isMultiCalendar={true} className="h-[40px] bg-gradient-to-r from-[#8A2387] via-[#E94057] to-[#F27121] text-center text-base font-semibold text-transparent text-white hover:bg-orange-700" /> diff --git a/packages/platform/examples/base/tests/connect-atoms/apple-connect.e2e.ts b/packages/platform/examples/base/tests/connect-atoms/apple-connect.e2e.ts new file mode 100644 index 0000000000..eed8380b03 --- /dev/null +++ b/packages/platform/examples/base/tests/connect-atoms/apple-connect.e2e.ts @@ -0,0 +1,60 @@ +import { test, expect } from "@playwright/test"; + +test("connect calendar using the apple connect atom", async ({ page }) => { + const appleId = process.env.ATOMS_E2E_APPLE_ID; + const appSpecificPassword = process.env.ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE; + + await page.goto("/"); + + await expect(page.locator("body")).toBeVisible(); + + await expect(page.locator('[data-testid="connect-atoms"]')).toBeVisible(); + + await page.locator('[data-testid="connect-atoms"] button:has-text("Connect Apple Calendar")').click(); + + await expect(page.locator('[role="dialog"]')).toBeVisible(); + + await expect(page.locator('[role="dialog"] fieldset[data-testid="apple-calendar-form"]')).toBeVisible(); + + await expect(page.locator('[data-testid="apple-calendar-email"]')).toBeVisible(); + await page.locator('[data-testid="apple-calendar-email"]').fill(appleId ?? ""); + + await expect(page.locator('[data-testid="apple-calendar-password"]')).toBeVisible(); + await page.locator('[data-testid="apple-calendar-password"]').fill(appSpecificPassword ?? ""); + + await page.locator('[data-testid="apple-calendar-login-button"]').click(); + + await expect(page).toHaveURL("/calendars"); + + await expect(page.locator("body")).toBeVisible(); + + await expect(page.locator('[data-testid="calendars-settings-atom"]')).toBeVisible(); + + await expect(page.locator('h2:has-text("Add to calendar")')).toBeVisible(); + + await expect(page.locator('label:has-text("Add events to")')).toBeVisible(); + + await expect(page.locator('[data-testid="select-control"]')).toBeVisible(); + await page.locator('[data-testid="select-control"]').click(); + + await page.keyboard.press("ArrowDown"); + await page.keyboard.press("Enter"); + + await expect(page.locator('h4:has-text("Check for conflicts")')).toBeVisible(); + + await expect(page.locator('[data-testid="list"]')).toBeVisible(); + await page.locator('[data-testid="list"] button:has(svg[data-name="start-icon"])').click(); + await page.locator('[data-testid="dialog-rejection"]').click(); + + await expect(page.locator('[data-testid="list"] button[role="switch"]').first()).toBeVisible(); + await page.locator('[data-testid="list"] button[role="switch"]').first().click(); + + await expect(page.locator('[data-testid="list"] button[role="switch"]').last()).toBeVisible(); + await page.locator('[data-testid="list"] button[role="switch"]').last().click(); + + await expect(page.locator('[data-testid="list"] button[role="switch"]').first()).toBeVisible(); + await page.locator('[data-testid="list"] button[role="switch"]').first().click(); + + await page.locator('[data-testid="list"] button:has(svg[data-name="start-icon"])').click(); + await page.locator('[data-testid="dialog-confirmation"]').click(); +}); diff --git a/turbo.json b/turbo.json index 1042760af8..5ab7c99b39 100644 --- a/turbo.json +++ b/turbo.json @@ -276,6 +276,8 @@ "NEXT_PUBLIC_WEBAPP_URL", "NEXT_PUBLIC_WEBSITE_URL", "BUILD_STANDALONE", + "ATOMS_E2E_APPLE_ID", + "ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE", "INTERCOM_API_TOKEN", "NEXT_PUBLIC_INTERCOM_APP_ID" ],