From 7b7478c0a9745671036f3941f43d9eeb2af23a31 Mon Sep 17 00:00:00 2001 From: Lauris Skraucis Date: Mon, 11 Aug 2025 17:23:26 +0200 Subject: [PATCH] feat: atoms e2e tests (#22926) * feat: atoms example app e2e * chore: build atoms when e2e examples app * docs: readme * fix: add env variable * fix: env var * chore: playwright at monorepo version * fix: workflow * chore: increase timeout to have time to build atoms * increase timeout for e2e * bump e2e instance * go back to 4cpu --- .github/workflows/atoms-e2e.yml | 57 +++++++++++++++++++ packages/platform/atoms/README.md | 18 +++++- packages/platform/examples/base/.gitignore | 6 +- packages/platform/examples/base/package.json | 6 +- .../examples/base/playwright.config.ts | 47 +++++++++++++++ .../create-event-type.e2e.ts | 21 +++++++ yarn.lock | 1 + 7 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/atoms-e2e.yml create mode 100644 packages/platform/examples/base/playwright.config.ts create mode 100644 packages/platform/examples/base/tests/create-event-type-atom/create-event-type.e2e.ts diff --git a/.github/workflows/atoms-e2e.yml b/.github/workflows/atoms-e2e.yml new file mode 100644 index 0000000000..87d64e1555 --- /dev/null +++ b/.github/workflows/atoms-e2e.yml @@ -0,0 +1,57 @@ +name: Atoms E2E Tests + +on: + pull_request: + branches: + - main + paths: + - 'packages/platform/atoms/**' + - 'packages/platform/examples/base/**' + - 'apps/api/v2/**' + - '.github/workflows/atoms-e2e.yml' + +permissions: + actions: write + contents: read + +env: + NODE_OPTIONS: --max-old-space-size=8096 + ATOMS_E2E_OAUTH_CLIENT_ID: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID }} + ATOMS_E2E_OAUTH_CLIENT_SECRET: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_SECRET }} + ATOMS_E2E_API_URL: ${{ secrets.ATOMS_E2E_API_URL }} + ATOMS_E2E_ORG_ID: ${{ secrets.ATOMS_E2E_ORG_ID }} + ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED }} + DATABASE_DIRECT_URL: ${{ secrets.CI_DATABASE_URL }} + DATABASE_URL: ${{ secrets.CI_DATABASE_URL }} + +jobs: + atoms-e2e: + timeout-minutes: 15 + name: Atoms E2E Tests + runs-on: buildjet-4vcpu-ubuntu-2204 + steps: + - uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - uses: actions/checkout@v4 + - uses: ./.github/actions/dangerous-git-checkout + - uses: ./.github/actions/yarn-install + - uses: ./.github/actions/yarn-playwright-install + - name: Run Atoms E2E Tests + working-directory: packages/platform/examples/base + run: yarn test:e2e + - name: Upload Test Results + uses: actions/upload-artifact@v4 + if: always() + with: + name: atoms-e2e-test-results + path: test-results + retention-days: 7 + - name: Upload Playwright Report + uses: actions/upload-artifact@v4 + if: always() + with: + name: atoms-e2e-playwright-report + path: playwright-report + retention-days: 7 diff --git a/packages/platform/atoms/README.md b/packages/platform/atoms/README.md index 5842a6e039..47099885bf 100644 --- a/packages/platform/atoms/README.md +++ b/packages/platform/atoms/README.md @@ -36,4 +36,20 @@ changesets will publish atoms to npm only if the `"version"` in the atoms `packa The following 2 articles teach how to write good change summaries for each PR when it deserves to end up in CHANGELOG.md - https://keepachangelog.com/en/1.0.0/ -- https://docs.gitlab.com/development/changelog/ \ No newline at end of file +- https://docs.gitlab.com/development/changelog/ + +### Testing +Atoms are tested in CI using e2e tests within the example platform app. To run them locally: +1. Go to "packages/platform/atoms" and run `yarn dev-on` and then `yarn build` - this will create local build of atoms. +2. Setup environment variables in "packages/platform/examples/base/.env" file. You will need your own platform oAuth client to populate NEXT_PUBLIC_X_CAL_ID (oAuth id), X_CAL_SECRET_KEY (oAuth secret), VITE_BOOKER_EMBED_OAUTH_CLIENT_ID (oAuth id) and ORGANIZATION_ID (organization id to which oAuth client belongs) - all of these are available in the platform settings dashboard after creating the oAuth client. +``` +NEXT_PUBLIC_X_CAL_ID="" +X_CAL_SECRET_KEY="" +NEXT_PUBLIC_CALCOM_API_URL="https://api.cal.com/v2" +VITE_BOOKER_EMBED_OAUTH_CLIENT_ID="" +VITE_BOOKER_EMBED_API_URL="https://api.cal.com/v2" +ORGANIZATION_ID="" +``` +3. Go to "packages/platform/examples/base" and run `yarn dev:e2e` - this will start the example platform app and run e2e tests by using locally built atoms. Because it is not running within CI it will open a browser and run tests. + + diff --git a/packages/platform/examples/base/.gitignore b/packages/platform/examples/base/.gitignore index f303df6b8c..9184ed8722 100644 --- a/packages/platform/examples/base/.gitignore +++ b/packages/platform/examples/base/.gitignore @@ -35,4 +35,8 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts .yarn -dev.db \ No newline at end of file +dev.db + +# playwright +test-results +playwright-report diff --git a/packages/platform/examples/base/package.json b/packages/platform/examples/base/package.json index d454fb85f7..ca28ee000c 100644 --- a/packages/platform/examples/base/package.json +++ b/packages/platform/examples/base/package.json @@ -3,10 +3,13 @@ "version": "0.1.0", "private": true, "scripts": { + "dev:e2e": "PORT=4322 next dev", "dev": "PORT=4321 next dev", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "test:e2e": "playwright test", + "test:e2e:ui": "playwright test --ui" }, "dependencies": { "@calcom/atoms": "*", @@ -18,6 +21,7 @@ "react-select": "^5.8.0" }, "devDependencies": { + "@playwright/test": "^1.45.3", "@types/node": "^20.3.1", "@types/react": "^18", "@types/react-dom": "^18", diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts new file mode 100644 index 0000000000..02dcec57fc --- /dev/null +++ b/packages/platform/examples/base/playwright.config.ts @@ -0,0 +1,47 @@ +import { defineConfig, devices } from '@playwright/test'; + +const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; +const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; + +const headless = !!process.env.CI || !!process.env.PLAYWRIGHT_HEADLESS; + +export default defineConfig({ + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, + timeout: DEFAULT_TEST_TIMEOUT, + fullyParallel: true, + reporter: [ + ['list'], + ['html', { outputFolder: './test-results/reports/playwright-html-report', open: 'never' }], + ], + outputDir: './test-results/results', + use: { + baseURL: 'http://localhost:4322', + locale: 'en-US', + trace: 'retain-on-failure', + headless, + }, + projects: [ + { + name: '@calcom/base', + testDir: './tests', + testMatch: /.*\.e2e\.tsx?/, + expect: { + timeout: DEFAULT_EXPECT_TIMEOUT, + }, + use: { + ...devices['Desktop Chrome'], + locale: 'en-US', + }, + }, + ], + webServer: { + command: process.env.CI + ? `yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && rm -f prisma/dev.db && yarn prisma db push && NEXT_PUBLIC_IS_E2E=1 NODE_ENV=test NEXT_PUBLIC_X_CAL_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID}" X_CAL_SECRET_KEY="${process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET}" NEXT_PUBLIC_CALCOM_API_URL="${process.env.ATOMS_E2E_API_URL}" VITE_BOOKER_EMBED_OAUTH_CLIENT_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED}" VITE_BOOKER_EMBED_API_URL="${process.env.ATOMS_E2E_API_URL}" ORGANIZATION_ID=${process.env.ATOMS_E2E_ORG_ID} yarn dev:e2e` + : `rm -f prisma/dev.db && yarn prisma db push && yarn dev:e2e`, + url: 'http://localhost:4322', + timeout: 600_000, + reuseExistingServer: !process.env.CI, + }, +}); diff --git a/packages/platform/examples/base/tests/create-event-type-atom/create-event-type.e2e.ts b/packages/platform/examples/base/tests/create-event-type-atom/create-event-type.e2e.ts new file mode 100644 index 0000000000..54af2fe69f --- /dev/null +++ b/packages/platform/examples/base/tests/create-event-type-atom/create-event-type.e2e.ts @@ -0,0 +1,21 @@ +import { test, expect } from '@playwright/test'; + +test('create event type using CreateEventTypeAtom', async ({ page }) => { + await page.goto('/'); + + await page.goto('/event-types'); + + await expect(page).toHaveURL('/event-types'); + + await expect(page.locator('body')).toBeVisible(); + + await page.fill('[data-testid="event-type-quick-chat"]', 'e2e event'); + + await page.fill('textarea[placeholder="A quick video meeting."]', 'This is an e2e test event description'); + + await page.waitForSelector('button[type="submit"]:has-text("Continue")', { state: 'visible' }); + await page.click('button[type="submit"]:has-text("Continue")'); + + await expect(page.locator('h1:has-text("E2e Event")')).toBeVisible(); + await expect(page.locator('p:has-text("/e2e-event")')).toBeVisible(); +}); diff --git a/yarn.lock b/yarn.lock index e1a942af6a..a066768505 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2730,6 +2730,7 @@ __metadata: resolution: "@calcom/base@workspace:packages/platform/examples/base" dependencies: "@calcom/atoms": "*" + "@playwright/test": ^1.45.3 "@prisma/client": 5.4.2 "@types/node": ^20.3.1 "@types/react": ^18