Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: E2E regression (Playwright + MySQL 8)

on:
pull_request:
push:
branches: [main, master, demo/qa-live-before]
workflow_dispatch:

jobs:
e2e:
runs-on: ubuntu-latest
timeout-minutes: 30
services:
mysql:
image: mirror.gcr.io/library/mysql:8.0
env:
MYSQL_ROOT_PASSWORD: Test@123
MYSQL_DATABASE: bankappdb
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping -h 127.0.0.1 -uroot -pTest@123"
--health-interval=5s
--health-timeout=5s
--health-retries=30
env:
SPRING_DATASOURCE_URL: jdbc:mysql://127.0.0.1:3306/bankappdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: Test@123
MVNW_REPOURL: https://maven-central.storage-download.googleapis.com/maven2
Comment on lines +26 to +30

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟥 Untrusted pull requests expose database credentials

On external pull requests, checkout runs contributor code with SPRING_DATASOURCE_PASSWORD in the job environment. A malicious install script can read and exfiltrate that credential.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

steps:
- uses: actions/checkout@v4

- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
cache: maven

- uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm
cache-dependency-path: e2e/package-lock.json

- name: Install e2e dependencies
working-directory: e2e
run: npm ci

- name: Coverage matrix accounts for all plan rows
working-directory: e2e
run: npm run coverage:check

- name: Type-check specs
working-directory: e2e
run: npx tsc -p .

- name: Build and unit test against MySQL 8
run: ./mvnw -B -s demo/maven-settings.xml verify

- name: Start app
run: |
mkdir -p logs
setsid nohup java -jar target/bankapp-0.0.1-SNAPSHOT.jar > logs/app.log 2>&1 < /dev/null &
for i in $(seq 1 120); do
curl -sf -o /dev/null http://localhost:8080/login && exit 0
sleep 1
done
echo "App did not serve /login within 120s"; tail -n 80 logs/app.log; exit 1

- name: Install Playwright Chromium
working-directory: e2e
run: npx playwright install --with-deps chromium

- name: Run Playwright regression
working-directory: e2e
run: npx playwright test

- name: Publish coverage matrix with results
if: always()
working-directory: e2e
run: |
if [ -f results.json ]; then
node scripts/coverage.mjs --results results.json | tee coverage-matrix-results.md >> "$GITHUB_STEP_SUMMARY"
else
echo "Playwright did not produce results.json" >> "$GITHUB_STEP_SUMMARY"
fi

- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: |
e2e/playwright-report/
e2e/test-results/
e2e/results.json
e2e/coverage-matrix-results.md
logs/app.log
retention-days: 14
4 changes: 4 additions & 0 deletions e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
test-results/
playwright-report/
results.json
16 changes: 16 additions & 0 deletions e2e/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# E2E regression suite

Playwright automation of `qa/manual-test-plan.csv`. Each test title starts with its plan ID (`MT-001 ...`).
Rows that cannot be automated are listed with a reason in `qa/not-automated.csv`; `qa/coverage-matrix.md` is generated from both.

```bash
demo/start-demo.sh # MySQL 8 + app on :8080
cd e2e && npm ci
npx playwright install chromium
npx playwright test # BASE_URL overrides http://localhost:8080
npm run coverage # regenerate qa/coverage-matrix.md
npm run coverage:check # fail if any plan row is unaccounted for or the matrix is stale
```

CI: `.github/workflows/e2e.yml` runs the suite against a MySQL 8 service and posts the matrix with per-row results to the job summary.
Each test creates its own uniquely named customers, so the suite needs no DB reset and runs in parallel.
109 changes: 109 additions & 0 deletions e2e/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions e2e/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "bankapp-e2e",
"private": true,
"scripts": {
"test": "playwright test",
"coverage": "node scripts/coverage.mjs",
"coverage:check": "node scripts/coverage.mjs --check"
},
"devDependencies": {
"@playwright/test": "1.52.0",
"@types/node": "^20.0.0",
"typescript": "^5.0.0"
}
}
20 changes: 20 additions & 0 deletions e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: 0,
workers: process.env.CI ? 2 : 4,
reporter: [
['list'],
['html', { open: 'never' }],
['json', { outputFile: 'results.json' }],
],
use: {
baseURL: process.env.BASE_URL ?? 'http://localhost:8080',
trace: 'retain-on-failure',
screenshot: 'only-on-failure',
},
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
});
Loading
Loading