enable agent to run e2e tests agaisnt fresh db
This commit is contained in:
parent
d3ccae9c75
commit
446568963f
38
AGENTS.md
38
AGENTS.md
@ -21,3 +21,41 @@
|
||||
## Tests
|
||||
Use JUnit 5 for backend unit test
|
||||
Use Playwright for frontend end-to-end tests
|
||||
|
||||
## Full-stack end-to-end tests
|
||||
|
||||
Agents running end-to-end tests must use free ports so they do not interfere with
|
||||
an existing development server. Find two currently available ports with:
|
||||
|
||||
```bash
|
||||
node -e "const net=require('net');let left=2,ports=[];for(let i=0;i<2;i++){const s=net.createServer();s.listen(0,'127.0.0.1',()=>{ports.push(s.address().port);s.close(()=>{if(!--left)console.log(ports.join(' '))})})}"
|
||||
```
|
||||
|
||||
Start the backend from the repository root, substituting the first free port and
|
||||
the normal local database credentials:
|
||||
|
||||
```bash
|
||||
DB_URL=jdbc:postgresql://localhost:5432/postgres \
|
||||
DB_USERNAME=root \
|
||||
DB_PASSWORD=root \
|
||||
DB_REINITIALIZE=true \
|
||||
SERVER_PORT=<backend-port> \
|
||||
mvn exec:java
|
||||
```
|
||||
|
||||
`DB_REINITIALIZE=true` drops and recreates the application's tables at startup,
|
||||
so only use it for a disposable test database. `SERVER_PORT` defaults to `7070`
|
||||
when omitted.
|
||||
|
||||
From `frontend/`, run Playwright using the second free port. Playwright starts
|
||||
Vite on that port, and Vite proxies API requests to the backend:
|
||||
|
||||
```bash
|
||||
VITE_API_TARGET=http://127.0.0.1:<backend-port> \
|
||||
PLAYWRIGHT_BASE_URL=http://127.0.0.1:<frontend-port> \
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
Keep the backend running until Playwright finishes, then stop it. The free-port
|
||||
check and server startup should happen close together because another process
|
||||
can claim a released port in between.
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import { defineConfig, devices } from '@playwright/test'
|
||||
|
||||
const baseURL = process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:3000'
|
||||
const frontendPort = new URL(baseURL).port || (baseURL.startsWith('https:') ? '443' : '80')
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './tests',
|
||||
fullyParallel: false,
|
||||
@ -8,7 +11,7 @@ export default defineConfig({
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
reporter: 'html',
|
||||
use: {
|
||||
baseURL: 'http://localhost:3000',
|
||||
baseURL,
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
projects: [
|
||||
@ -18,8 +21,8 @@ export default defineConfig({
|
||||
},
|
||||
],
|
||||
webServer: {
|
||||
command: 'npm run dev',
|
||||
url: 'http://localhost:3000',
|
||||
command: `npm run dev -- --port ${frontendPort}`,
|
||||
url: baseURL,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
})
|
||||
|
||||
@ -13,7 +13,7 @@ import io.javalin.http.HttpStatus
|
||||
|
||||
fun main() {
|
||||
val database = Database(DatabaseConfig.fromEnvironment())
|
||||
database.initialize()
|
||||
database.initialize(reinitialize = System.getenv("DB_REINITIALIZE").toBoolean())
|
||||
val users = UserRepository(database)
|
||||
val loginService = LoginService(users, SessionRepository(database))
|
||||
val entities = EntityDefinitionRepository(database)
|
||||
|
||||
@ -35,9 +35,15 @@ class Database(private val config: DatabaseConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
fun initialize() {
|
||||
fun initialize(reinitialize: Boolean = false) {
|
||||
getConnection().use { connection ->
|
||||
connection.createStatement().use { statement ->
|
||||
if (reinitialize) {
|
||||
statement.execute(DROP_ENTITY_FIELDS_TABLE)
|
||||
statement.execute(DROP_ENTITY_DEFINITIONS_TABLE)
|
||||
statement.execute(DROP_SESSIONS_TABLE)
|
||||
statement.execute(DROP_USERS_TABLE)
|
||||
}
|
||||
statement.execute(CREATE_USERS_TABLE)
|
||||
statement.execute(ADD_USER_ROLE)
|
||||
statement.execute(CREATE_SESSIONS_TABLE)
|
||||
@ -67,6 +73,11 @@ class Database(private val config: DatabaseConfig) {
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val DROP_ENTITY_FIELDS_TABLE = "DROP TABLE IF EXISTS entity_fields"
|
||||
const val DROP_ENTITY_DEFINITIONS_TABLE = "DROP TABLE IF EXISTS entity_definitions"
|
||||
const val DROP_SESSIONS_TABLE = "DROP TABLE IF EXISTS sessions"
|
||||
const val DROP_USERS_TABLE = "DROP TABLE IF EXISTS users"
|
||||
|
||||
const val CREATE_USERS_TABLE = """
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user