feat: enhance Playwright configuration and CI workflow for E2E testing
- Updated playwright.config.js to allow dynamic base URL configuration via environment variables, improving flexibility for different environments. - Modified .gitea/workflows/test.yml to include steps for starting a development stack, seeding test data, and stopping the stack after tests, enhancing the CI process for end-to-end testing. - Refactored login test in dev-smoke-test.spec.js to use a dedicated function for submitting the login form, improving code clarity and maintainability.
This commit is contained in:
parent
1f2c8ea0f1
commit
50b8ff12cd
|
|
@ -57,7 +57,6 @@ jobs:
|
|||
playwright-tests:
|
||||
if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: [lint-backend, build-frontend]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
|
@ -67,19 +66,53 @@ jobs:
|
|||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install Playwright
|
||||
- name: Start dev stack for E2E
|
||||
env:
|
||||
DEV_ALLOWED_ORIGINS: http://127.0.0.1:3098,http://localhost:3098,http://host.docker.internal:3098,https://dev.shinkan.jinkendo.de
|
||||
run: |
|
||||
npm install -D @playwright/test
|
||||
npx playwright install --with-deps chromium
|
||||
docker compose -f docker-compose.dev-env.yml up -d --build
|
||||
echo "Warte auf Frontend + API (/health) …"
|
||||
for i in $(seq 1 90); do
|
||||
if curl -sf http://127.0.0.1:3098/health >/dev/null 2>&1; then
|
||||
echo "Health OK (Versuch $i)"
|
||||
exit 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
echo "Timeout: /health nicht erreichbar"
|
||||
curl -v http://127.0.0.1:3098/health || true
|
||||
docker compose -f docker-compose.dev-env.yml logs --tail=120
|
||||
exit 1
|
||||
|
||||
- name: Run Playwright tests
|
||||
- name: Seed E2E test user (erste Registrierung in frischer DB)
|
||||
env:
|
||||
TEST_EMAIL: lars@stommer.com
|
||||
TEST_PASSWORD: 12345678
|
||||
run: |
|
||||
curl -sf -X POST "http://127.0.0.1:3098/api/auth/register" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"email\":\"${TEST_EMAIL}\",\"password\":\"${TEST_PASSWORD}\",\"name\":\"Playwright CI\"}" \
|
||||
|| echo "(Registrierung übersprungen — Nutzer existiert evtl. schon)"
|
||||
|
||||
- name: Install Playwright
|
||||
run: |
|
||||
npm ci || npm install
|
||||
npx playwright install --with-deps chromium
|
||||
|
||||
- name: Run Playwright tests
|
||||
env:
|
||||
PLAYWRIGHT_BASE_URL: http://127.0.0.1:3098
|
||||
TEST_EMAIL: lars@stommer.com
|
||||
TEST_PASSWORD: 12345678
|
||||
run: |
|
||||
mkdir -p screenshots
|
||||
npx playwright test
|
||||
echo "✓ Playwright tests passed"
|
||||
|
||||
- name: Stop dev stack
|
||||
if: always()
|
||||
run: docker compose -f docker-compose.dev-env.yml down
|
||||
|
||||
- name: Upload test screenshots
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v4
|
||||
|
|
|
|||
76
package-lock.json
generated
Normal file
76
package-lock.json
generated
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"name": "shinkan-jinkendo",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "shinkan-jinkendo",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.49.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.59.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.1.tgz",
|
||||
"integrity": "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright": "1.59.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.59.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz",
|
||||
"integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.59.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.59.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz",
|
||||
"integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
package.json
Normal file
11
package.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "shinkan-jinkendo",
|
||||
"private": true,
|
||||
"description": "Workspace-Metadaten für E2E (Playwright). Frontend: frontend/",
|
||||
"scripts": {
|
||||
"test:e2e": "playwright test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.49.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,11 @@
|
|||
// CI: PLAYWRIGHT_BASE_URL=http://127.0.0.1:3098 nach docker compose dev-env
|
||||
// Lokal gegen LAN/Dev: export PLAYWRIGHT_BASE_URL=http://192.168.x.x:3098
|
||||
|
||||
const rawBase =
|
||||
process.env.PLAYWRIGHT_BASE_URL ||
|
||||
process.env.BASE_URL ||
|
||||
'http://127.0.0.1:3098';
|
||||
|
||||
module.exports = {
|
||||
testDir: './tests',
|
||||
timeout: 30000,
|
||||
|
|
@ -6,7 +14,7 @@ module.exports = {
|
|||
headless: true,
|
||||
viewport: { width: 390, height: 844 },
|
||||
screenshot: 'only-on-failure',
|
||||
baseURL: 'http://192.168.2.49:3098',
|
||||
baseURL: rawBase.replace(/\/$/, ''),
|
||||
},
|
||||
reporter: 'list',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@ const { test, expect } = require('@playwright/test');
|
|||
const TEST_EMAIL = process.env.TEST_EMAIL || 'lars@stommer.com';
|
||||
const TEST_PASSWORD = process.env.TEST_PASSWORD || '12345678';
|
||||
|
||||
/** Primärer Submit auf der Login-Seite (nicht den Tab "Login" vs. "Registrieren"). */
|
||||
async function submitLoginForm(page) {
|
||||
await page.getByRole('button', { name: 'Anmelden' }).click();
|
||||
}
|
||||
|
||||
async function login(page) {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
|
@ -12,7 +17,7 @@ async function login(page) {
|
|||
|
||||
await page.fill('input[type="email"]', TEST_EMAIL);
|
||||
await page.fill('input[type="password"]', TEST_PASSWORD);
|
||||
await page.click('button:has-text("Login")');
|
||||
await submitLoginForm(page);
|
||||
await page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
|
|
@ -21,10 +26,10 @@ test('1. Login funktioniert', async ({ page }) => {
|
|||
await page.waitForSelector('input[type="email"]', { timeout: 10000 });
|
||||
await page.fill('input[type="email"]', TEST_EMAIL);
|
||||
await page.fill('input[type="password"]', TEST_PASSWORD);
|
||||
await page.click('button:has-text("Login")');
|
||||
await submitLoginForm(page);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Nach Login sollte Login-Button verschwinden
|
||||
// Nach Login soll der Tab "Login" (Moduswahl) verschwinden — nicht der Submit "Anmelden"
|
||||
const loginButton = page.locator('button:has-text("Login")');
|
||||
await expect(loginButton).toHaveCount(0, { timeout: 10000 });
|
||||
|
||||
|
|
@ -73,7 +78,7 @@ test('4. Navigation zu Vereine', async ({ page }) => {
|
|||
console.log('✓ Vereine-Seite erreichbar');
|
||||
});
|
||||
|
||||
test('5. Desktop-Sidebar sichtbar (Desktop)', async ({ page, context }) => {
|
||||
test('5. Desktop-Sidebar sichtbar (Desktop)', async ({ page }) => {
|
||||
// Desktop-Viewport
|
||||
await page.setViewportSize({ width: 1280, height: 800 });
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user