diff --git a/tests/integration-tests/.env.example b/tests/integration-tests/.env.example new file mode 100644 index 00000000000..e0df65cbe63 --- /dev/null +++ b/tests/integration-tests/.env.example @@ -0,0 +1,3 @@ +EMAIL= +PASSWORD_BASE64= +BASE_URL= \ No newline at end of file diff --git a/tests/integration-tests/.gitignore b/tests/integration-tests/.gitignore new file mode 100644 index 00000000000..e1a45d37362 --- /dev/null +++ b/tests/integration-tests/.gitignore @@ -0,0 +1,8 @@ + +# Playwright +node_modules/ +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ +playwright/.auth \ No newline at end of file diff --git a/tests/integration-tests/README.md b/tests/integration-tests/README.md new file mode 100644 index 00000000000..2138582d75c --- /dev/null +++ b/tests/integration-tests/README.md @@ -0,0 +1,110 @@ +# Integration Tests + +This directory contains end-to-end integration tests for the application using Playwright. + +## Prerequisites + +- Node.js (v18 or higher) +- npm or yarn +- Playwright browsers installed + +## Setup + +1. Install dependencies: +```bash +npm install +# or +yarn install +``` + +2. Install Playwright browsers: +```bash +npx playwright install +``` + +3. Create a `.env` file in the `tests/integration-tests` directory with the following variables: +```env +BASE_URL=http://localhost:3000 # Your application URL +EMAIL=your-email@example.com # Your test user email +PASSWORD_BASE64=base64-encoded-password # Your test user password in base64 +``` + +## Running Tests + +### Authentication Setup + +First, you need to set up the authentication state: + +```bash +npx playwright test auth.setup.ts +``` + +This will create a `playwright/.auth/user.json` file containing the authentication state. + +### Running All Tests + +```bash +npx playwright test +``` + +### Running Specific Test Files + +```bash +# Run a specific test file +npx playwright test projects.spec.ts + +# Run tests in a specific browser +npx playwright test --project=chromium +``` + +### Running Tests in UI Mode + +```bash +npx playwright test --ui +``` + +### Debugging Tests + +```bash +# Run tests in debug mode +npx playwright test --debug + +# Run a specific test in debug mode +npx playwright test projects.spec.ts --debug +``` + +## Test Structure + +- `auth.setup.ts`: Handles user authentication and creates a persistent auth state +- `projects.spec.ts`: Contains the actual test cases for the projects functionality + +## Test Reports + +After running tests, you can view the HTML report: + +```bash +npx playwright show-report +``` + +## Troubleshooting + +1. If tests fail due to authentication: + - Delete the `playwright/.auth/user.json` file + - Run `npx playwright test auth.setup.ts` again + - Try running your tests + +2. If you need to see what's happening during test execution: + - Use `--debug` flag + - Or run with `--headed` flag to see the browser + +3. If you need to update the auth state: + - Delete the existing auth file + - Run the auth setup again + - Run your tests + +## CI/CD Integration + +For CI/CD environments, make sure to: +1. Set the appropriate environment variables +2. Run `npx playwright install-deps` before running tests +3. Use `--reporter=html` for test reports \ No newline at end of file diff --git a/tests/integration-tests/package.json b/tests/integration-tests/package.json new file mode 100644 index 00000000000..4764d314ef4 --- /dev/null +++ b/tests/integration-tests/package.json @@ -0,0 +1,14 @@ +{ + "name": "integration-tests", + "version": "1.0.0", + "main": "index.js", + "scripts": {}, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "devDependencies": { + "@playwright/test": "^1.51.1", + "@types/node": "^22.13.14" + } +} diff --git a/tests/integration-tests/playwright.config.ts b/tests/integration-tests/playwright.config.ts new file mode 100644 index 00000000000..b2cf076e442 --- /dev/null +++ b/tests/integration-tests/playwright.config.ts @@ -0,0 +1,71 @@ +import { defineConfig, devices } from "@playwright/test"; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +import dotenv from "dotenv"; +import path from "path"; +dotenv.config({ path: path.resolve(__dirname, ".env") }); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: "./tests", + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: "html", + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: process.env.BASE_URL || "http://localhost:3000", + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: "on-first-retry", + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: "setup", + testMatch: /auth.setup.ts$/, + }, + { + name: "chromium", + use: { + ...devices["Desktop Chrome"], + storageState: "./playwright/.auth/user.json", + }, + dependencies: ["setup"], + testMatch: /.*\.spec\.ts$/, + }, + + { + name: "firefox", + use: { + ...devices["Desktop Firefox"], + storageState: "playwright/.auth/user.json", + }, + dependencies: ["setup"], + testMatch: /.*\.spec\.ts/, + }, + + { + name: "webkit", + use: { + ...devices["Desktop Safari"], + storageState: "playwright/.auth/user.json", + }, + dependencies: ["setup"], + testMatch: /.*\.spec\.ts/, + }, + ], +}); diff --git a/tests/integration-tests/tests/auth.setup.ts b/tests/integration-tests/tests/auth.setup.ts new file mode 100644 index 00000000000..865e76118d0 --- /dev/null +++ b/tests/integration-tests/tests/auth.setup.ts @@ -0,0 +1,31 @@ +import { test as setup } from '@playwright/test'; +import path from 'path'; + +const authFile = path.join(__dirname, '../playwright/.auth/user.json'); + +setup('authenticate', async ({ page }) => { + + const BASE_URL = process.env.BASE_URL; + const EMAIL = process.env.EMAIL; + // decode the password + const PWD = Buffer.from(process.env.PASSWORD_BASE64 || '', 'base64').toString('utf-8'); + if (!BASE_URL || !EMAIL || !PWD) { + throw new Error('BASE_URL, EMAIL or PWD is not set'); + } + await page.goto(BASE_URL); + await page.getByRole('textbox', { name: 'Email' }).click(); + await page.getByRole('textbox', { name: 'Email' }).fill(EMAIL); + await page.getByRole('textbox', { name: 'Email' }).press('Enter'); + if (await page.getByRole('button', { name: 'Continue' }).isVisible()) { + await page.getByRole('button', { name: 'Continue' }).click(); + } + await page.getByRole('textbox', { name: 'password' }).click(); + await page.getByRole('textbox', { name: 'password' }).fill(PWD); + + await page.keyboard.press('Enter'); + + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(1000); + + await page.context().storageState({ path: authFile }); +}); diff --git a/tests/integration-tests/tests/projects.spec.ts b/tests/integration-tests/tests/projects.spec.ts new file mode 100644 index 00000000000..0efccfd0d31 --- /dev/null +++ b/tests/integration-tests/tests/projects.spec.ts @@ -0,0 +1,20 @@ +import { test, expect } from '@playwright/test'; + +// This is a test file +test('basic test', async () => { + expect(true).toBeTruthy(); +}); + +test.describe('Project tests', () => { + test.beforeEach(async ({ page }) => { + // The page should already be authenticated due to storageState + await page.goto('/'); + // Wait for the page to be fully loaded + await page.waitForLoadState('networkidle'); + }); + + test('should load projects page', async ({ page }) => { + // Basic test to verify page loads + await page.getByRole('listitem').getByText('Home').click(); + }); +}); diff --git a/tests/integration-tests/yarn.lock b/tests/integration-tests/yarn.lock new file mode 100644 index 00000000000..a06a19f9f3b --- /dev/null +++ b/tests/integration-tests/yarn.lock @@ -0,0 +1,41 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@playwright/test@^1.51.1": + version "1.52.0" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.52.0.tgz#267ec595b43a8f4fa5e444ea503689629e91a5b8" + integrity sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g== + dependencies: + playwright "1.52.0" + +"@types/node@^22.13.14": + version "22.15.30" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.30.tgz#3a20431783e28dd0b0326f84ab386a2ec81d921d" + integrity sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA== + dependencies: + undici-types "~6.21.0" + +fsevents@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +playwright-core@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.52.0.tgz#238f1f0c3edd4ebba0434ce3f4401900319a3dca" + integrity sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg== + +playwright@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.52.0.tgz#26cb9a63346651e1c54c8805acfd85683173d4bd" + integrity sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw== + dependencies: + playwright-core "1.52.0" + optionalDependencies: + fsevents "2.3.2" + +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==