Entorno para test E2E
This commit is contained in:
parent
42b197c16d
commit
94b6515a03
6
.gitignore
vendored
6
.gitignore
vendored
@ -10,3 +10,9 @@ dist-ssr
|
||||
server/dist
|
||||
public/dist
|
||||
out
|
||||
|
||||
playwright-report/
|
||||
test-results/
|
||||
blob-report/
|
||||
apps/server/.env.e2e
|
||||
apps/web/.env.e2e
|
||||
|
||||
29
apps/server/.env.e2e.example
Normal file
29
apps/server/.env.e2e.example
Normal file
@ -0,0 +1,29 @@
|
||||
NODE_ENV=test
|
||||
PORT=3002
|
||||
API_BASE_PATH=/api/v1
|
||||
FRONTEND_URL=http://127.0.0.1:5173
|
||||
TRUST_PROXY=0
|
||||
TIMEZONE=Europe/Madrid
|
||||
DB_DIALECT=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_NAME=uecko_erp_e2e
|
||||
DB_USER=replace-with-e2e-user
|
||||
DB_PASS=replace-with-e2e-password
|
||||
DB_LOGGING=false
|
||||
DB_SSL=false
|
||||
DB_SYNC_MODE=none
|
||||
WARMUP_TIMEOUT_MS=30000
|
||||
WARMUP_STRICT=false
|
||||
JWT_SECRET=replace-with-a-dedicated-e2e-secret-of-at-least-32-characters
|
||||
JWT_ACCESS_EXPIRATION=15m
|
||||
JWT_REFRESH_EXPIRATION=7d
|
||||
TEMPLATES_PATH=./storage/e2e/templates
|
||||
DOCUMENTS_PATH=./storage/e2e/documents
|
||||
SIGNED_DOCUMENTS_PATH=./storage/e2e/signed-documents
|
||||
FASTREPORT_BIN=replace-with-fastreport-binary-path
|
||||
SIGNING_SERVICE_URL=http://127.0.0.1:3003
|
||||
SIGNING_SERVICE_METHOD=POST
|
||||
SIGNING_SERVICE_TIMEOUT_MS=5000
|
||||
SIGNING_SERVICE_MAX_RETRIES=0
|
||||
COMPANY_CERTIFICATES_PATH=./storage/e2e/certificates
|
||||
2
apps/web/.env.e2e.example
Normal file
2
apps/web/.env.e2e.example
Normal file
@ -0,0 +1,2 @@
|
||||
VITE_API_SERVER_URL=http://127.0.0.1:3002/api/v1
|
||||
VITE_FORCE_INITIAL_ONBOARDING=false
|
||||
@ -21,11 +21,15 @@
|
||||
"check": "biome check .",
|
||||
"check:write": "biome check --write --unsafe .",
|
||||
"test:frontend": "node --experimental-test-module-mocks --import tsx --test",
|
||||
"test:e2e": "playwright test",
|
||||
"test:e2e:ui": "playwright test --ui",
|
||||
"test:e2e:headed": "playwright test --headed",
|
||||
"test:unit": "node --import tsx --test",
|
||||
"typecheck": "tsc -p tsconfig.json --noEmit"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.4.11",
|
||||
"@playwright/test": "^1.63.0",
|
||||
"@repo/typescript-config": "workspace:*",
|
||||
"@tailwindcss/postcss": "^4.2.2",
|
||||
"@typescript-eslint/eslint-plugin": "^8.58.1",
|
||||
|
||||
40
playwright.config.ts
Normal file
40
playwright.config.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { defineConfig, devices } from "@playwright/test";
|
||||
|
||||
const localBaseUrl = "http://127.0.0.1:5173";
|
||||
const baseURL = process.env.E2E_BASE_URL ?? localBaseUrl;
|
||||
const startLocalStack = !process.env.E2E_BASE_URL;
|
||||
|
||||
export default defineConfig({
|
||||
testDir: "./tests/e2e",
|
||||
timeout: 30_000,
|
||||
expect: { timeout: 5_000 },
|
||||
fullyParallel: true,
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
reporter: [["html", { open: "never" }]],
|
||||
use: {
|
||||
baseURL,
|
||||
testIdAttribute: "data-testid",
|
||||
trace: "on-first-retry",
|
||||
screenshot: "only-on-failure",
|
||||
video: "retain-on-failure",
|
||||
},
|
||||
projects: [{ name: "chromium", use: { ...devices["Desktop Chrome"] } }],
|
||||
webServer: startLocalStack
|
||||
? [
|
||||
{
|
||||
command:
|
||||
"node tests/e2e/support/ensure-e2e-database.mjs && cd apps/server && node --env-file=.env.e2e --import=tsx src/index.ts",
|
||||
url: "http://127.0.0.1:3002/api/v1/__ready",
|
||||
timeout: 120_000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
{
|
||||
command: "cd apps/web && pnpm dev -- --mode e2e --port 5173",
|
||||
url: localBaseUrl,
|
||||
timeout: 120_000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
]
|
||||
: undefined,
|
||||
});
|
||||
@ -11,6 +11,9 @@ importers:
|
||||
'@biomejs/biome':
|
||||
specifier: 2.4.11
|
||||
version: 2.4.11
|
||||
'@playwright/test':
|
||||
specifier: ^1.63.0
|
||||
version: 1.63.0
|
||||
'@repo/typescript-config':
|
||||
specifier: workspace:*
|
||||
version: link:packages/typescript-config
|
||||
@ -3074,6 +3077,11 @@ packages:
|
||||
resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
|
||||
'@playwright/test@1.63.0':
|
||||
resolution: {integrity: sha512-oxMK4vllB9RK5NQ2l1pq1IfOf2AvnEuj/vYGDj0H2nMtmtZpKtCwt/l00GEO6xjGfpBNAvjovvYdCm50dRQkpQ==}
|
||||
engines: {node: '>=20'}
|
||||
hasBin: true
|
||||
|
||||
'@radix-ui/number@1.1.3':
|
||||
resolution: {integrity: sha512-Road2bidD0uu/1BGDOWNdPI06g0lIRy6IF9GZcIrDK2KGItfor8IQwQa+yM2ERgHM1MmHxaxpTzk0/Jp42lNfA==}
|
||||
|
||||
@ -6952,6 +6960,16 @@ packages:
|
||||
pkg-types@1.3.1:
|
||||
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
|
||||
|
||||
playwright-core@1.63.0:
|
||||
resolution: {integrity: sha512-rYCsBF/M5HjUch52bbtVONEFjv6Xu8sm8h72dNlR5bzIE1fvC/bxgspzkjSfU+MweEMmPM8KJebG6nnyxo5mCg==}
|
||||
engines: {node: '>=20'}
|
||||
hasBin: true
|
||||
|
||||
playwright@1.63.0:
|
||||
resolution: {integrity: sha512-+7ziBLidS4NaNCdt57SUDT+wYmmd5fmiQejUic/kb+YsYSCPyOOE9sebzMjNmQrsnNpDJqd4WHvV/8lfKfUDUg==}
|
||||
engines: {node: '>=20'}
|
||||
hasBin: true
|
||||
|
||||
plop@4.0.5:
|
||||
resolution: {integrity: sha512-pJz6oWC9LyBp5mBrRp8AUV2RNiuGW+t/HOs4zwN+b/3YxoObZOOFvjn1mJMpAeKi2pbXADMFOOVQVTVXEdDHDw==}
|
||||
engines: {node: '>=18'}
|
||||
@ -9238,6 +9256,10 @@ snapshots:
|
||||
'@parcel/watcher-win32-ia32': 2.5.6
|
||||
'@parcel/watcher-win32-x64': 2.5.6
|
||||
|
||||
'@playwright/test@1.63.0':
|
||||
dependencies:
|
||||
playwright: 1.63.0
|
||||
|
||||
'@radix-ui/number@1.1.3': {}
|
||||
|
||||
'@radix-ui/primitive@1.1.3': {}
|
||||
@ -13054,6 +13076,12 @@ snapshots:
|
||||
mlly: 1.8.2
|
||||
pathe: 2.0.3
|
||||
|
||||
playwright-core@1.63.0: {}
|
||||
|
||||
playwright@1.63.0:
|
||||
dependencies:
|
||||
playwright-core: 1.63.0
|
||||
|
||||
plop@4.0.5(@types/node@25.9.1):
|
||||
dependencies:
|
||||
'@types/liftoff': 4.0.3
|
||||
|
||||
0
tests/e2e/.gitkeep
Normal file
0
tests/e2e/.gitkeep
Normal file
29
tests/e2e/README.md
Normal file
29
tests/e2e/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Infraestructura E2E
|
||||
|
||||
Suite de Playwright para navegador, frontend, backend y MariaDB E2E. Aún no contiene pruebas funcionales.
|
||||
|
||||
## Estructura
|
||||
|
||||
El primer nivel debe coincidir exactamente con el módulo propietario en `modules`: por ejemplo, `identity` usará `tests/e2e/identity/login.spec.ts` y facturas de clientes `tests/e2e/customer-invoices/`. No usar `auth`, `invoices` ni `settings`. `support/` es exclusivamente infraestructura transversal.
|
||||
|
||||
## Variables y base de datos
|
||||
|
||||
Copia `apps/server/.env.e2e.example` a `apps/server/.env.e2e` y completa una MariaDB exclusiva E2E; `DB_NAME` nunca debe ser la base de desarrollo. Copia `apps/web/.env.e2e.example` a `apps/web/.env.e2e`.
|
||||
|
||||
El backend arranca con `node --env-file=.env.e2e`, que prevalece sobre `.env`. La plantilla usa `DB_SYNC_MODE=none`; no hay reset, seed ni operación destructiva en esta fase. Las futuras operaciones destructivas deberán rechazar cualquier base que no sea E2E.
|
||||
|
||||
`E2E_BASE_URL` permite usar un stack E2E ya iniciado y evita levantar procesos locales. Futuras credenciales: `E2E_USER_EMAIL` y `E2E_USER_PASSWORD`, nunca versionadas.
|
||||
|
||||
## Ejecución
|
||||
|
||||
```bash
|
||||
pnpm test:e2e
|
||||
pnpm test:e2e:ui
|
||||
pnpm test:e2e:headed
|
||||
```
|
||||
|
||||
Localmente se espera backend en `http://127.0.0.1:3002/api/v1/__ready` y Vite en `http://127.0.0.1:5173`.
|
||||
|
||||
## Selectores
|
||||
|
||||
Prioridad: `id` técnico estable, `data-testid`, atributo técnico como `name` y CSS estable solo excepcionalmente. No usar textos, labels o `aria-label` traducibles, Tailwind visual, `nth-child` ni DOM incidental. Playwright configura `data-testid`.
|
||||
0
tests/e2e/support/.gitkeep
Normal file
0
tests/e2e/support/.gitkeep
Normal file
13
tests/e2e/support/ensure-e2e-database.mjs
Normal file
13
tests/e2e/support/ensure-e2e-database.mjs
Normal file
@ -0,0 +1,13 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const envFile = resolve("apps/server/.env.e2e");
|
||||
const databaseName = readFileSync(envFile, "utf8")
|
||||
.split(/\r?\n/)
|
||||
.find((line) => line.startsWith("DB_NAME="))
|
||||
?.slice("DB_NAME=".length)
|
||||
.trim();
|
||||
|
||||
if (databaseName !== "uecko_erp_e2e") {
|
||||
throw new Error("E2E requires DB_NAME=uecko_erp_e2e in apps/server/.env.e2e.");
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user