diff --git a/playwright/.gitignore b/playwright/.gitignore new file mode 100644 index 00000000..1f95add8 --- /dev/null +++ b/playwright/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +test-results/ +playwright-report/ +blob-report/ +playwright/.cache/ diff --git a/playwright/README.md b/playwright/README.md new file mode 100644 index 00000000..54726bd6 --- /dev/null +++ b/playwright/README.md @@ -0,0 +1,39 @@ +# DocuSeal Playwright Tests + +End-to-end tests for DocuSeal fork features. + +## Setup + +```bash +cd playwright +npm install +npm run install:browsers +``` + +## Running + +```bash +# Against local dev server (http://localhost:3000) +npm test + +# Against UAT +PLAYWRIGHT_BASE_URL=https://docuseal-uat.example.com npm test + +# Headed / debug UI +npm run test:headed +npm run test:ui +``` + +## Env vars + +- `PLAYWRIGHT_BASE_URL` — explicit target URL (overrides everything) +- `DOCUSEAL_UAT_URL` — default UAT URL when `PLAYWRIGHT_BASE_URL` absent +- `DOCUSEAL_ADMIN_EMAIL` / `DOCUSEAL_ADMIN_PASSWORD` — credentials for login helpers + +## Layout + +One spec per feature (mirrors `PLAN.md` version numbering): + +- `v0.4.0-version-display.spec.ts` +- `v0.1.0-config-overrides.spec.ts` +- ... diff --git a/playwright/package.json b/playwright/package.json new file mode 100644 index 00000000..d699339a --- /dev/null +++ b/playwright/package.json @@ -0,0 +1,15 @@ +{ + "name": "docuseal-playwright", + "private": true, + "version": "0.0.0", + "description": "Playwright end-to-end tests for DocuSeal fork features", + "scripts": { + "test": "playwright test", + "test:headed": "playwright test --headed", + "test:ui": "playwright test --ui", + "install:browsers": "playwright install --with-deps chromium" + }, + "devDependencies": { + "@playwright/test": "^1.47.0" + } +} diff --git a/playwright/playwright.config.ts b/playwright/playwright.config.ts new file mode 100644 index 00000000..a3b14206 --- /dev/null +++ b/playwright/playwright.config.ts @@ -0,0 +1,29 @@ +import { defineConfig, devices } from '@playwright/test'; + +// Base URL order: PLAYWRIGHT_BASE_URL > UAT default > localhost +const baseURL = + process.env.PLAYWRIGHT_BASE_URL || + process.env.DOCUSEAL_UAT_URL || + 'http://localhost:3000'; + +export default defineConfig({ + testDir: './tests', + fullyParallel: false, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 1 : 0, + workers: 1, + reporter: [['list'], ['html', { open: 'never' }]], + use: { + baseURL, + trace: 'on-first-retry', + screenshot: 'only-on-failure', + video: 'retain-on-failure', + ignoreHTTPSErrors: true, + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + ], +}); diff --git a/playwright/tests/helpers/auth.ts b/playwright/tests/helpers/auth.ts new file mode 100644 index 00000000..da5707ab --- /dev/null +++ b/playwright/tests/helpers/auth.ts @@ -0,0 +1,17 @@ +import { Page, expect } from '@playwright/test'; + +// Credentials come from env so tests work against any environment. +export const adminEmail = process.env.DOCUSEAL_ADMIN_EMAIL || 'admin@example.com'; +export const adminPassword = process.env.DOCUSEAL_ADMIN_PASSWORD || 'password'; + +export async function loginAs(page: Page, email: string, password: string): Promise { + await page.goto('/users/sign_in'); + await page.getByLabel(/email/i).fill(email); + await page.getByLabel(/password/i).fill(password); + await page.getByRole('button', { name: /sign in|log in/i }).click(); + await expect(page).not.toHaveURL(/sign_in/); +} + +export async function loginAsAdmin(page: Page): Promise { + await loginAs(page, adminEmail, adminPassword); +} diff --git a/playwright/tests/v0.4.0-version-display.spec.ts b/playwright/tests/v0.4.0-version-display.spec.ts new file mode 100644 index 00000000..80bf4a2d --- /dev/null +++ b/playwright/tests/v0.4.0-version-display.spec.ts @@ -0,0 +1,25 @@ +import { test, expect } from '@playwright/test'; +import { loginAsAdmin } from './helpers/auth'; + +// Phase 0.4 — Version Display +// Assumes the app is running with APP_VERSION=v0.4.0 (kustomize configmap in UAT). + +test.describe('Version display', () => { + test('navbar shows APP_VERSION below Settings link', async ({ page }) => { + await loginAsAdmin(page); + await page.goto('/'); + + const version = page.locator('#app_version'); + await expect(version).toBeVisible(); + await expect(version).toHaveText(/^v\d+\.\d+\.\d+/); + }); + + test('settings nav bottom version badge links to upstream releases', async ({ page }) => { + await loginAsAdmin(page); + await page.goto('/settings/profile'); + + const badge = page.locator('a[href="https://github.com/docusealco/docuseal/releases"]'); + await expect(badge).toBeVisible(); + await expect(badge).toHaveText(/^v\d+\.\d+\.\d+/); + }); +});