Skip to content

Commit

Permalink
feat: add e2e tests with playwright
Browse files Browse the repository at this point in the history
  • Loading branch information
sgomez committed Nov 21, 2023
1 parent 1156818 commit 245b77a
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 3 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ MAILER_DSN=smtp://localhost:1025
MAIL_FROM=[email protected]
MAILER_SECRET=CHANGE_ME
MAILER_URL=http://localhost:3000/api/mailer/
WEBMAIL_URL=http://localhost:8025/
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,11 @@ next-env.d.ts

# prisma migrations
!prisma/migrations/**/*.sql

# Playwright
/test-results/
/playwright-report/
/blob-report/
/playwright/.auth/
/playwright/.cache/

28 changes: 28 additions & 0 deletions e2e/auth.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { test as setup } from 'next/experimental/testmode/playwright'

export const USER_AUTH_FILE = 'playwright/.auth/user.json'

setup('authenticate as user', async ({ page, request }) => {
// Insert email
await page.goto('/signin')
await page.getByPlaceholder('Introduce tu email').fill('[email protected]')
await page.getByRole('button', { name: 'Continuar con el email' }).click()

// Open WebMail
await page.getByRole('button', { name: 'Abrir UCOWebMail' }).click()
const webMailPage = await page.waitForEvent('popup')
await webMailPage.getByText('[email protected]').first().click()

// Open login link
await webMailPage
.frameLocator('#preview-html')
.getByRole('link', { name: 'Sign in' })
.click()

// Store credentials
const loggedPage = await webMailPage.waitForEvent('popup')
await loggedPage.context().storageState({ path: USER_AUTH_FILE })

// Purge WebMail
await request.delete('http://localhost:8025/api/v1/messages')
})
44 changes: 44 additions & 0 deletions e2e/login/do-login.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { expect, test } from 'next/experimental/testmode/playwright'

test.describe('Do login with email', () => {
test.afterEach(async ({ request }) => {
await request.delete('http://localhost:8025/api/v1/messages')
})

test('open login page', async ({ page }) => {
// Arrange
await page.goto('/')

// Act
await page.getByRole('button', { name: 'avatar' }).click()
await page.getByText('Iniciar sesión').click()

// Assert
await expect(page).toHaveURL('/signin')
await expect(page.locator('body')).toHaveText(/Iniciar sesión en/)
})

test('receive email login link', async ({ page, request }) => {
// Arrange
await page.goto('/signin')
const email = `noreply+${+new Date()}@uco.es`

// Act
await page.getByPlaceholder('Introduce tu email').fill(email)
await page.getByRole('button', { name: 'Continuar con el email' }).click()

// Assert
await expect(page).toHaveURL('/verify')
await expect(page.locator('body')).toHaveText(/Verifica tu correo/)

const response = await request.get('http://localhost:8025/api/v1/messages')
expect(response.ok()).toBeTruthy()
expect(await response.json()).toEqual(
expect.arrayContaining([
expect.objectContaining({
Raw: expect.objectContaining({ To: [email] }),
}),
]),
)
})
})
14 changes: 14 additions & 0 deletions e2e/main/dark-mode.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// import { expect, test } from '@playwright/test'
import { expect, test } from 'next/experimental/testmode/playwright'

test('switch from dark mode to light mode', async ({ page }) => {
// Arrange
await page.goto('/')
const htmlElement = page.locator('html')

// Act
await page.getByTestId('theme-switcher').click()

// Assert
await expect(htmlElement).toHaveClass('light')
})
11 changes: 11 additions & 0 deletions e2e/main/main.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// import { expect, test } from '@playwright/test'
import { expect, test } from 'next/experimental/testmode/playwright'

test('/', async ({ page }) => {
// Arrange
// Act
await page.goto('/')

// Assert
await expect(page.locator('body')).toHaveText(/Codex/)
})
19 changes: 19 additions & 0 deletions e2e/settings/open-settings.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { expect, test } from 'next/experimental/testmode/playwright'

import { USER_AUTH_FILE } from '../auth.setup'

test.describe('open settings page', () => {
test.use({ storageState: USER_AUTH_FILE })

test('open from main menu', async ({ page }) => {
// Arrange
await page.goto('/')
// Act
await page.getByRole('button', { name: 'avatar' }).click()
await page.getByText('[email protected]').click()

// Assert
await expect(page).toHaveURL('/settings/profile')
await expect(page.locator('body')).toHaveText(/Ajustes de usuario/)
})
})
20 changes: 20 additions & 0 deletions e2e/settings/update-settings.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect, test } from 'next/experimental/testmode/playwright'

import { USER_AUTH_FILE } from '../auth.setup'

test.describe('update user settings', () => {
test.use({ storageState: USER_AUTH_FILE })

test('update name', async ({ page }) => {
// Arrange
await page.goto('/settings/profile')
// Act
await page.getByPlaceholder('Nombre').fill('John Doe')
await page.getByRole('button', { name: 'Enviar' }).click()
await page.reload()

// Assert
await expect(page).toHaveURL('/settings/profile')
await expect(page.getByPlaceholder('Nombre')).toHaveValue('John Doe')
})
})
8 changes: 7 additions & 1 deletion jest.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ const createJestConfig = nextJest({
const config = {
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],

collectCoverage: true,
collectCoverageFrom: [
'src/**/*.{ts,tsx}'
],
coverageDirectory: "<rootDir>/coverage",
coverageReporters: ["html", "text"],
testEnvironment: 'jest-environment-jsdom',
testMatch: ['<rootDir>/src/**/*.(spec|test).ts']
}

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
"start": "next start",
"lint": "next lint",
"prepare": "husky install",
"test": "jest",
"test": "jest --watchAll",
"test:ci": "jest --coverage=no",
"test:e2e": "playwright test",
"pretest:e2e": "playwright install",
"test:e2e:ui": "playwright test --ui",
"pretest:e2e:ui": "playwright install",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"prisma:migrate": "prisma migrate dev",
Expand Down Expand Up @@ -38,6 +43,7 @@
"devDependencies": {
"@commitlint/cli": "^18.4.2",
"@commitlint/config-conventional": "^18.4.2",
"@playwright/test": "^1.40.0",
"@storybook/addon-essentials": "^7.5.3",
"@storybook/addon-interactions": "^7.5.3",
"@storybook/addon-links": "^7.5.3",
Expand Down
27 changes: 27 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { defineConfig, devices } from 'next/experimental/testmode/playwright'
import path from 'path'

const PORT = process.env.PORT || 3000
const baseURL = `http://localhost:${PORT}`

export default defineConfig({
projects: [
{
name: 'Desktop Chrome',
use: {
...devices['Desktop Chrome'],
},
},
],
reporter: 'html',
testDir: path.join(__dirname, 'e2e'),
use: {
baseURL,
trace: 'retry-with-trace',
},
webServer: {
command: 'yarn dev --experimental-test-proxy',
reuseExistingServer: !process.env.CI,
url: 'http://localhost:3000',
},
})
4 changes: 3 additions & 1 deletion src/app/(auth)/verify/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export const metadata: Metadata = {
title: 'Codex | Verifica tu correo',
}

const WEBMAIL_URL = process.env.WEBMAIL_URL as string

export default async function Page() {
const session = await auth()

Expand All @@ -28,7 +30,7 @@ export default async function Page() {
size="lg"
radius="none"
as={Link}
href="https://webmail.uco.es"
href={WEBMAIL_URL}
target="_blank"
>
Abrir UCOWebMail
Expand Down
1 change: 1 addition & 0 deletions src/components/ThemeSwitcher/ThemeSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default function ThemeSwitcher() {
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
startContent={<SunIcon />}
endContent={<MoonIcon />}
data-testid="theme-switcher"
/>
)
}
26 changes: 26 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2852,6 +2852,13 @@
picocolors "^1.0.0"
tslib "^2.6.0"

"@playwright/test@^1.40.0":
version "1.40.0"
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.40.0.tgz#d06c506977dd7863aa16e07f2136351ecc1be6ed"
integrity sha512-PdW+kn4eV99iP5gxWNSDQCbhMaDVej+RXL5xr6t04nbKLCBwYtA046t7ofoczHOm8u6c+45hpDKQVZqtqwkeQg==
dependencies:
playwright "1.40.0"

"@pmmmwh/react-refresh-webpack-plugin@^0.5.5":
version "0.5.11"
resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz#7c2268cedaa0644d677e8c4f377bc8fb304f714a"
Expand Down Expand Up @@ -8533,6 +8540,11 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==

[email protected]:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==

fsevents@^2.3.2, fsevents@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
Expand Down Expand Up @@ -11359,6 +11371,20 @@ pkg-dir@^7.0.0:
dependencies:
find-up "^6.3.0"

[email protected]:
version "1.40.0"
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.40.0.tgz#82f61e5504cb3097803b6f8bbd98190dd34bdf14"
integrity sha512-fvKewVJpGeca8t0ipM56jkVSU6Eo0RmFvQ/MaCQNDYm+sdvKkMBBWTE1FdeMqIdumRaXXjZChWHvIzCGM/tA/Q==

[email protected]:
version "1.40.0"
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.40.0.tgz#2a1824b9fe5c4fe52ed53db9ea68003543a99df0"
integrity sha512-gyHAgQjiDf1m34Xpwzaqb76KgfzYrhK7iih+2IzcOCoZWr/8ZqmdBw+t0RU85ZmfJMgtgAiNtBQ/KS2325INXw==
dependencies:
playwright-core "1.40.0"
optionalDependencies:
fsevents "2.3.2"

pnp-webpack-plugin@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz#65741384f6d8056f36e2255a8d67ffc20866f5c9"
Expand Down

0 comments on commit 245b77a

Please sign in to comment.