Skip to content

Commit 15b6414

Browse files
authored
feat(test): add Playwright E2E test framework (#50)
Add comprehensive Playwright-based E2E testing framework with 201 tests covering: - User registration and email verification - Login/logout and session management - Password reset flow - Profile management and account deletion - Event browsing and registration - Access control and authorization Key components: - Page Object Model architecture for maintainable tests - Test API with localhost-only security for test data manipulation - Custom email service to support testing without email dependency - Multi-browser testing (Chromium, Firefox, Mobile Chrome, Mobile Safari) Includes PR review feedback fixes: - IP whitelist security for Test API endpoints - HTTP error handling in TestApiClient - Removed unused imports and fixed Playwright selector issues
1 parent 6b45e09 commit 15b6414

43 files changed

Lines changed: 5108 additions & 6 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,10 @@ application-local.yml
138138
/repomix-output.txt
139139
src/main/resources/application-docker-keycloak.yml
140140
.vscode/
141+
142+
# Playwright
143+
playwright/node_modules/
144+
playwright/test-results/
145+
playwright/playwright-report/
146+
playwright/reports/
147+
playwright/.env

build.gradle

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ repositories {
3939

4040
dependencies {
4141
// DigitalSanctuary Spring User Framework
42-
implementation 'com.digitalsanctuary:ds-spring-user-framework:4.0.2'
42+
implementation 'com.digitalsanctuary:ds-spring-user-framework:4.0.3'
4343

4444
// Spring Boot starters
4545
implementation 'org.springframework.boot:spring-boot-starter-actuator'
@@ -127,3 +127,42 @@ bootRun {
127127
environment SPRING_PROFILES_ACTIVE: profiles
128128
}
129129
}
130+
131+
// Playwright Test Integration
132+
tasks.register('playwrightInstall', Exec) {
133+
description = 'Install Playwright dependencies'
134+
group = 'verification'
135+
workingDir 'playwright'
136+
commandLine 'npm', 'install'
137+
}
138+
139+
tasks.register('playwrightBrowsers', Exec) {
140+
description = 'Install Playwright browsers'
141+
group = 'verification'
142+
workingDir 'playwright'
143+
commandLine 'npx', 'playwright', 'install'
144+
dependsOn 'playwrightInstall'
145+
}
146+
147+
tasks.register('playwrightTest', Exec) {
148+
description = 'Run Playwright E2E tests'
149+
group = 'verification'
150+
workingDir 'playwright'
151+
commandLine 'npx', 'playwright', 'test'
152+
dependsOn 'playwrightBrowsers'
153+
}
154+
155+
tasks.register('playwrightTestChromium', Exec) {
156+
description = 'Run Playwright E2E tests on Chromium only'
157+
group = 'verification'
158+
workingDir 'playwright'
159+
commandLine 'npx', 'playwright', 'test', '--project=chromium'
160+
dependsOn 'playwrightBrowsers'
161+
}
162+
163+
tasks.register('playwrightReport', Exec) {
164+
description = 'Show Playwright test report'
165+
group = 'verification'
166+
workingDir 'playwright'
167+
commandLine 'npx', 'playwright', 'show-report'
168+
}

playwright/.env.example

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Playwright Test Configuration
2+
# Copy this file to .env and update values as needed
3+
4+
# Base URL for the application under test
5+
BASE_URL=http://localhost:8080
6+
7+
# Test API endpoint for test data management
8+
TEST_API_URL=http://localhost:8080/api/test
9+
10+
# Set to 'true' when running in CI environment
11+
CI=false

playwright/.gitignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Build output
5+
dist/
6+
7+
# Test results
8+
reports/
9+
test-results/
10+
playwright-report/
11+
blob-report/
12+
13+
# Environment files
14+
.env
15+
.env.local
16+
17+
# IDE
18+
.idea/
19+
.vscode/
20+
21+
# OS
22+
.DS_Store
23+
Thumbs.db

playwright/package-lock.json

Lines changed: 128 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playwright/package.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "spring-user-framework-playwright-tests",
3+
"version": "1.0.0",
4+
"description": "Playwright E2E tests for Spring User Framework Demo App",
5+
"scripts": {
6+
"test": "playwright test",
7+
"test:chromium": "playwright test --project=chromium",
8+
"test:firefox": "playwright test --project=firefox",
9+
"test:webkit": "playwright test --project=webkit",
10+
"test:headed": "playwright test --headed",
11+
"test:ui": "playwright test --ui",
12+
"test:debug": "playwright test --debug",
13+
"report": "playwright show-report",
14+
"codegen": "playwright codegen http://localhost:8080"
15+
},
16+
"devDependencies": {
17+
"@playwright/test": "^1.58.0",
18+
"@types/node": "^20.10.0",
19+
"typescript": "^5.3.0",
20+
"dotenv": "^16.3.0"
21+
},
22+
"engines": {
23+
"node": ">=18"
24+
}
25+
}

playwright/playwright.config.ts

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import { defineConfig, devices } from '@playwright/test';
2+
import * as dotenv from 'dotenv';
3+
import * as path from 'path';
4+
5+
dotenv.config();
6+
7+
/**
8+
* Unique project identifier for session isolation.
9+
* This ensures this project's Playwright instance doesn't conflict with other projects.
10+
*/
11+
const PROJECT_ID = 'spring-demo-app';
12+
13+
/**
14+
* Playwright configuration for Spring User Framework Demo App E2E tests.
15+
* @see https://playwright.dev/docs/test-configuration
16+
*/
17+
export default defineConfig({
18+
testDir: './tests',
19+
20+
/* Unique output directories for this project */
21+
outputDir: path.join(__dirname, 'test-results', PROJECT_ID),
22+
23+
/* Run tests in files in parallel */
24+
fullyParallel: true,
25+
26+
/* Fail the build on CI if you accidentally left test.only in the source code */
27+
forbidOnly: !!process.env.CI,
28+
29+
/* Retry on CI only */
30+
retries: process.env.CI ? 2 : 0,
31+
32+
/* Opt out of parallel tests on CI */
33+
workers: process.env.CI ? 1 : undefined,
34+
35+
/* Reporter to use */
36+
reporter: [
37+
['html', { outputFolder: 'reports/html' }],
38+
['json', { outputFile: 'reports/results.json' }],
39+
['list']
40+
],
41+
42+
/* Shared settings for all the projects below */
43+
use: {
44+
/* Base URL to use in actions like `await page.goto('/')` */
45+
baseURL: process.env.BASE_URL || 'http://localhost:8080',
46+
47+
/* Collect trace when retrying the failed test */
48+
trace: 'on-first-retry',
49+
50+
/* Capture screenshot on failure */
51+
screenshot: 'only-on-failure',
52+
53+
/* Capture video on failure */
54+
video: 'on-first-retry',
55+
56+
/* Default timeout for actions */
57+
actionTimeout: 10000,
58+
59+
/* Default navigation timeout */
60+
navigationTimeout: 30000,
61+
62+
/* Session isolation: unique browser launch options per project */
63+
launchOptions: {
64+
args: [
65+
/* Disable shared memory usage for better isolation in containers/parallel runs */
66+
'--disable-dev-shm-usage',
67+
/* Disable GPU to prevent shared resource conflicts */
68+
'--disable-gpu',
69+
],
70+
},
71+
72+
/* Unique context options for session isolation */
73+
contextOptions: {
74+
/* Ignore HTTPS errors for local development */
75+
ignoreHTTPSErrors: true,
76+
},
77+
},
78+
79+
/* Configure global timeout */
80+
timeout: 60000,
81+
82+
/* Expect timeout */
83+
expect: {
84+
timeout: 10000,
85+
},
86+
87+
/* Configure projects for major browsers */
88+
projects: [
89+
{
90+
name: 'chromium',
91+
use: { ...devices['Desktop Chrome'] },
92+
},
93+
94+
{
95+
name: 'firefox',
96+
use: { ...devices['Desktop Firefox'] },
97+
},
98+
99+
{
100+
name: 'webkit',
101+
use: { ...devices['Desktop Safari'] },
102+
},
103+
104+
/* Test against mobile viewports */
105+
{
106+
name: 'Mobile Chrome',
107+
use: { ...devices['Pixel 5'] },
108+
},
109+
110+
{
111+
name: 'Mobile Safari',
112+
use: { ...devices['iPhone 12'] },
113+
},
114+
],
115+
116+
/* Run your local dev server before starting the tests */
117+
webServer: {
118+
command: 'cd .. && ./gradlew bootRun --args="--spring.profiles.active=local,playwright-test"',
119+
url: 'http://localhost:8080',
120+
reuseExistingServer: !process.env.CI,
121+
timeout: 120000,
122+
stdout: 'pipe',
123+
stderr: 'pipe',
124+
},
125+
});

playwright/src/fixtures/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export {
2+
test,
3+
expect,
4+
generateTestEmail,
5+
generateTestPassword,
6+
generateTestUser,
7+
loginUser,
8+
registerAndVerifyUser,
9+
createAndLoginUser,
10+
type TestUser,
11+
} from './test-fixtures';

0 commit comments

Comments
 (0)