From ba311382177e17eb05e0476efe666d8b18f46fc2 Mon Sep 17 00:00:00 2001 From: Catalin Pit Date: Fri, 15 Sep 2023 15:57:18 +0300 Subject: [PATCH] feat: add more tests --- apps/web/src/tests/auth.setup.ts | 13 ++++ apps/web/src/tests/documenso.pdf | 57 ++++++++++++++++ apps/web/src/tests/test-auth-flow.spec.ts | 22 +++---- .../src/tests/test-document-upload.spec.ts | 66 +++++++++++++++++++ playwright.config.ts | 25 ++++--- 5 files changed, 162 insertions(+), 21 deletions(-) create mode 100644 apps/web/src/tests/auth.setup.ts create mode 100644 apps/web/src/tests/documenso.pdf create mode 100644 apps/web/src/tests/test-document-upload.spec.ts diff --git a/apps/web/src/tests/auth.setup.ts b/apps/web/src/tests/auth.setup.ts new file mode 100644 index 000000000..0e6bfa3bc --- /dev/null +++ b/apps/web/src/tests/auth.setup.ts @@ -0,0 +1,13 @@ +import { type Page, expect, test as setup } from '@playwright/test'; + +import { STORAGE_STATE } from '../../../../playwright.config'; + +setup('authenticate', async ({ page }: { page: Page }) => { + await page.goto('/'); + await page.getByLabel('Email').fill(process.env.E2E_TEST_USER_EMAIL); + await page.getByLabel('Password').fill(process.env.E2E_TEST_USER_PASSWORD); + await page.getByRole('button', { name: 'Sign In' }).click(); + await page.waitForURL('/documents'); + await expect(page).toHaveURL('/documents'); + await page.context().storageState({ path: STORAGE_STATE }); +}); diff --git a/apps/web/src/tests/documenso.pdf b/apps/web/src/tests/documenso.pdf new file mode 100644 index 000000000..32fa96a36 --- /dev/null +++ b/apps/web/src/tests/documenso.pdf @@ -0,0 +1,57 @@ +%PDF-1.4 +%Óëéá +1 0 obj +<> +endobj +3 0 obj +<> +endobj +4 0 obj +<> stream +1 0 0 -1 0 842 cm +q +.75 0 0 .75 0 0 cm +1 1 1 RG 1 1 1 rg +/G3 gs +0 0 794 1123 re +f +Q + +endstream +endobj +2 0 obj +<>>> +/MediaBox [0 0 596 842] +/Contents 4 0 R +/StructParents 0 +/Parent 5 0 R>> +endobj +5 0 obj +<> +endobj +6 0 obj +<> +endobj +xref +0 7 +0000000000 65535 f +0000000015 00000 n +0000000269 00000 n +0000000100 00000 n +0000000137 00000 n +0000000457 00000 n +0000000512 00000 n +trailer +<> +startxref +559 +%%EOF diff --git a/apps/web/src/tests/test-auth-flow.spec.ts b/apps/web/src/tests/test-auth-flow.spec.ts index 2dcbe667f..53a7e1815 100644 --- a/apps/web/src/tests/test-auth-flow.spec.ts +++ b/apps/web/src/tests/test-auth-flow.spec.ts @@ -1,12 +1,12 @@ -import { expect, test } from '@playwright/test'; +import { type Page, expect, test } from '@playwright/test'; test.use({ storageState: { cookies: [], origins: [] } }); -test('sign up with email and password', async ({ page }) => { - await page.goto('http://localhost:3000/signup'); - await page.getByLabel('Name').fill('John Doe'); - await page.getByLabel('Email').fill('johndoe2023@documenso.com'); - await page.getByLabel('Password').fill('my_secure_password'); +test('user can sign up with email and password', async ({ page }: { page: Page }) => { + await page.goto('/signup'); + await page.getByLabel('Name').fill(process.env.E2E_TEST_USERNAME); + await page.getByLabel('Email').fill(process.env.E2E_TEST_USER_EMAIL); + await page.getByLabel('Password').fill(process.env.E2E_TEST_USER_PASSWORD); const canvas = page.locator('canvas'); const box = await canvas.boundingBox(); @@ -21,11 +21,11 @@ test('sign up with email and password', async ({ page }) => { await page.getByRole('button', { name: 'Sign Up' }).click(); }); -test('user can login with user and password', async ({ page }) => { - await page.goto('http://localhost:3000/signin'); - await page.getByLabel('Email').fill('johndoe2023@documenso.com'); - await page.getByLabel('Password').fill('my_secure_password'); +test('user can login with user and password', async ({ page }: { page: Page }) => { + await page.goto('/signin'); + await page.getByLabel('Email').fill(process.env.E2E_TEST_USER_EMAIL); + await page.getByLabel('Password').fill(process.env.E2E_TEST_USER_PASSWORD); await page.getByRole('button', { name: 'Sign In' }).click(); - await expect(page).toHaveURL('http://localhost:3000/documents'); + await expect(page).toHaveURL('/documents'); }); diff --git a/apps/web/src/tests/test-document-upload.spec.ts b/apps/web/src/tests/test-document-upload.spec.ts new file mode 100644 index 000000000..a2c5bbbd8 --- /dev/null +++ b/apps/web/src/tests/test-document-upload.spec.ts @@ -0,0 +1,66 @@ +import { type Page, expect, test } from '@playwright/test'; + +/* + There was a bit of code duplication because each test starts from the first step - which is uploading a document. + Then each subsequent test adds a new step. So, for each test we repeat the steps from the previous tests. + + I extracted the most common steps into functions and then I call them in each test. + Also, the document upload is used in all tests, so I added it to the beforeEach hook. +*/ +const addSigner = async (page: Page) => { + await page.getByLabel('Email*').fill('example@email.com'); + await page.getByLabel('Name').fill('User'); + await page.getByRole('button', { name: 'Continue' }).click(); +}; + +const addSignatureField = async (page: Page) => { + await page.getByRole('button', { name: 'User Signature' }).dragTo(page.locator('canvas')); + await page.getByRole('button', { name: 'Continue' }).click(); +}; + +test.describe('Document upload test', () => { + test.beforeEach(async ({ page }: { page: Page }) => { + await page.goto('/'); + + await expect(page).toHaveTitle('Documenso - The Open Source DocuSign Alternative'); + + await page + .getByText('Add a documentDrag & drop your document here.') + .locator('input[type=file]') + .setInputFiles('./apps/web/src/tests/documenso.pdf'); + }); + + test('user can see /documents page', async ({ page }: { page: Page }) => { + await page.goto('/'); + + await expect(page).toHaveTitle('Documenso - The Open Source DocuSign Alternative'); + }); + + test('user can add 1 signer', async ({ page }: { page: Page }) => { + await addSigner(page); + }); + + test('user can add signature field', async ({ page }: { page: Page }) => { + await addSigner(page); + + await addSignatureField(page); + }); + + test('user can add subject and message', async ({ page }: { page: Page }) => { + await addSigner(page); + + await addSignatureField(page); + + await page + .locator('div') + .filter({ hasText: /^Subject \(Optional\)$/ }) + .locator('input') + .fill('New document'); + await page + .locator('div') + .filter({ hasText: /^Message \(Optional\)$/ }) + .locator('textarea') + .fill('Please sign it in and send it back to me.'); + await page.getByRole('button', { name: 'Send' }).click(); + }); +}); diff --git a/playwright.config.ts b/playwright.config.ts index e5aae93e4..54e6bd9dd 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -4,7 +4,11 @@ import { defineConfig, devices } from '@playwright/test'; * Read environment variables from file. * https://github.com/motdotla/dotenv */ -// require('dotenv').config(); +import { config as dotenvConfig } from 'dotenv'; + +dotenvConfig(); + +export const STORAGE_STATE = 'playwright/.auth/user.json'; /** * See https://playwright.dev/docs/test-configuration. @@ -24,7 +28,7 @@ export default defineConfig({ /* 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: 'http://127.0.0.1:3000', + baseURL: 'http://localhost:3000', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', @@ -33,32 +37,33 @@ export default defineConfig({ /* Configure projects for major browsers */ projects: [ { name: 'setup', testMatch: /.*\.setup\.ts/ }, + { + name: 'Authenticated User Tests', + testMatch: /.*\.spec\.ts/, + testIgnore: /test-auth-flow\.spec\.ts/, + dependencies: ['setup'], + use: { + storageState: STORAGE_STATE, + }, + }, { name: 'chromium', use: { ...devices['Desktop Chrome'], - // Use prepared auth state. - storageState: 'playwright/.auth/user.json', }, - dependencies: ['setup'], }, { name: 'firefox', use: { ...devices['Desktop Firefox'], - // Use prepared auth state. - storageState: 'playwright/.auth/user.json', }, - dependencies: ['setup'], }, { name: 'webkit', use: { ...devices['Desktop Safari'], - storageState: 'playwright/.auth/user.json', }, - dependencies: ['setup'], }, ],