diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml new file mode 100644 index 0000000..ba47476 --- /dev/null +++ b/.github/workflows/e2e-tests.yml @@ -0,0 +1,51 @@ +name: E2E Tests + +on: + push: + branches: [main, feature/*] + pull_request: + branches: [main] + +jobs: + test: + name: Run E2E Tests + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '18.x' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Install Playwright Browsers + run: npx playwright install --with-deps + + - name: Run E2E tests + run: npx playwright test --project=chromium --reporter=html,junit --output=test-results/ + env: + NEXT_PUBLIC_E2E: '1' + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v3 + with: + name: test-results + path: | + test-results/ + playwright-report/ + + - name: Upload test report + if: always() + uses: actions/upload-artifact@v3 + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/e2e/visual-regression.spec.ts b/e2e/visual-regression.spec.ts new file mode 100644 index 0000000..e600d4e --- /dev/null +++ b/e2e/visual-regression.spec.ts @@ -0,0 +1,18 @@ +import { test, expect } from '@playwright/test'; + +test.describe('Visual Regression Tests', () => { + test('landing page matches screenshot', async ({ page }) => { + await page.goto('/?e2eConnected=false'); + await expect(page).toHaveScreenshot('landing-page.png', { fullPage: true }); + }); + + test('chat page matches screenshot', async ({ page }) => { + await page.goto('/chat?e2eConnected=true'); + await expect(page).toHaveScreenshot('chat-page.png', { fullPage: true }); + }); + + test('profile page matches screenshot', async ({ page }) => { + await page.goto('/profile?e2eConnected=true'); + await expect(page).toHaveScreenshot('profile-page.png', { fullPage: true }); + }); +}); diff --git a/playwright.config.ts b/playwright.config.ts index 3b6ed21..384b8de 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -3,12 +3,22 @@ import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: 'e2e', timeout: 30_000, - expect: { timeout: 5_000 }, + expect: { + timeout: 5_000, + toHaveScreenshot: { maxDiffPixelRatio: 0.01 }, // Tolerate 1% difference in visual tests + }, fullyParallel: true, - reporter: [['list']], + retries: 1, // Retry failed tests once + reporter: [ + ['list'], + ['html', { open: 'never' }], // HTML report + ['junit', { outputFile: 'test-results/e2e-junit.xml' }], // JUnit report for CI + ], use: { baseURL: 'http://localhost:3001', trace: 'on-first-retry', + screenshot: 'only-on-failure', + video: 'on-first-retry', }, webServer: { command: 'NEXT_PUBLIC_E2E=1 next dev -p 3001', @@ -19,7 +29,14 @@ export default defineConfig({ projects: [ { name: 'chromium', - use: { ...devices['Desktop Chrome'] }, + use: { + ...devices['Desktop Chrome'], + viewport: { width: 1280, height: 720 }, + }, + }, + { + name: 'mobile', + use: { ...devices['iPhone 13'] }, }, ], });