-
Notifications
You must be signed in to change notification settings - Fork 138
Expand file tree
/
Copy pathplaywright.config.ts
More file actions
191 lines (165 loc) · 7.04 KB
/
Copy pathplaywright.config.ts
File metadata and controls
191 lines (165 loc) · 7.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
import { defineConfig, devices } from '@playwright/test';
// Default secrets profile — auto-detect from base URL, fall back to 'local'
if (!process.env.E2E_PROFILE) {
const baseUrl = process.env.E2E_BASE_URL || '';
process.env.E2E_PROFILE = baseUrl.includes('adepttech') ? 'adepttech' : 'local';
}
// Anchor timestamp for backend fresh-vs-reused detection (see global-setup.ts).
// Captured here because this module evaluates before Playwright starts (or
// skips starting, per reuseExistingServer) the webServer processes below.
if (!process.env.E2E_RUN_START) {
process.env.E2E_RUN_START = String(Date.now());
}
// Test environment ports (separate from dev to avoid conflicts)
const BACKEND_PORT = process.env.BACKEND_PORT || '5543';
const FRONTEND_PORT = process.env.FRONTEND_PORT || '5540';
/**
* Playwright configuration for Stratos E2E tests
* Migrated from Protractor configuration
*/
export default defineConfig({
// Test directory
testDir: './e2e/tests',
// Run tests in parallel
fullyParallel: true,
// Fail the build on CI if you accidentally left test.only in the source code
forbidOnly: !!process.env.CI,
// Retry on CI only
retries: process.env.CI ? 2 : 0,
// Worker count: configurable via E2E_WORKERS env var.
// Each worker gets its own authenticated session to avoid session contention.
// Default: CI=4, local=half CPU cores (Playwright default)
workers: process.env.E2E_WORKERS
? parseInt(process.env.E2E_WORKERS)
: (process.env.CI ? 4 : undefined),
// Reporter configuration
reporter: [
['html', { outputFolder: 'e2e-reports/html' }],
['json', { outputFile: 'e2e-reports/results.json' }],
['list']
],
// Shared settings for all the projects below
use: {
// Base URL for navigation
baseURL: process.env.E2E_BASE_URL || `https://localhost:${FRONTEND_PORT}`,
// Collect trace when retrying the failed test
trace: 'on-first-retry',
// Screenshot on failure (override via E2E_SCREENSHOTS env var)
screenshot: (process.env.E2E_SCREENSHOTS as any) || 'only-on-failure',
// Video on failure (override via E2E_VIDEO env var)
video: (process.env.E2E_VIDEO as any) || 'retain-on-failure',
// Accept self-signed certificates (dev environment)
ignoreHTTPSErrors: true,
// Maximum time each action can take
actionTimeout: 10000,
// Maximum navigation time
navigationTimeout: 30000,
},
// Global timeout for each test
// SSO login fixtures can take 15-20s each (headless browser OAuth flow)
timeout: 90000,
// Run-level backstop: caps total wall-clock time for the whole test run,
// independent of any single test's timeout. The full 3-browser suite
// legitimately runs ~4h, and future tiers must fit under this ceiling
// too, so 6h leaves headroom without masking a genuinely stuck run
// (e.g. a hung fixture whose per-test timeout is itself defeated, as
// measured in the 32.5-minute teardown hang this backstop guards against).
globalTimeout: 6 * 60 * 60 * 1000,
// Report test environment status before tests start
globalSetup: './e2e/global-setup.ts',
// Kill test servers (identified by STRATOS_E2E env var) after tests complete
globalTeardown: './e2e/global-teardown.ts',
// Expect timeout
expect: {
timeout: 5000,
},
// Configure projects — auth setup runs once, then tests reuse saved state
projects: [
{
name: 'setup',
testDir: './e2e',
testMatch: /auth\.setup\.ts/,
// Not fully parallel: 'authenticate as admin' and 'authenticate as
// user' both call registerDefaultCloudFoundry(), whose idempotence
// check is check-then-act (GET-then-POST, see
// endpoint-management.helper.ts) — on a cold DB, two workers running
// this project concurrently can both observe "not registered" and
// both POST, duplicating the CF endpoint registration and breaking
// every list page with "Request failed". Deliberately NOT
// `mode: 'serial'`: serial would abort the user-setup test entirely
// if admin-setup fails, whereas non-parallel here just forces the
// two tests onto one worker so they run one at a time, in file order.
fullyParallel: false,
use: { storageState: undefined },
},
{
name: 'chromium',
dependencies: ['setup'],
use: {
...devices['Desktop Chrome'],
// Default to admin state — fixtures override per-test as needed
storageState: 'e2e/.auth/admin.json',
// Chrome-specific options matching Protractor config
launchOptions: {
args: [
'--no-sandbox',
'--disable-dev-shm-usage',
'--disable-infobars',
'--allow-insecure-localhost',
],
},
},
},
{
name: 'firefox',
dependencies: ['setup'],
use: { ...devices['Desktop Firefox'], storageState: 'e2e/.auth/admin.json' },
},
{
name: 'webkit',
dependencies: ['setup'],
use: { ...devices['Desktop Safari'], storageState: 'e2e/.auth/admin.json' },
},
],
// Auto-start backend and frontend for tests using dedicated ports.
// Reuses existing servers if already running on these ports.
//
// Process identification: STRATOS_E2E=e2e:<backend_port> is set as an env
// var on both backend and frontend processes. This appears in the command
// line visible to pkill/pgrep, enabling targeted cleanup without PID files
// (which can become stale if a process crashes).
//
// The backend port is the session ID — one ID covers both processes.
//
// ps aux | grep 'STRATOS_E2E=e2e' # find all test sessions
// ps aux | grep 'e2e:5543' # find a specific session
// pkill -f 'e2e:5543' # kill a specific session
// Skip local servers when targeting a remote deployment
...(process.env.E2E_BASE_URL ? {} : {
webServer: [
{
// Isolate the e2e database: jetstream runs from src/jetstream, where the
// dev stack's config.properties sets SQLITE_KEEP_DB=true — without an
// override the e2e server SHARES the dev sqlite and each auth.setup
// registers a duplicate endpoint into it (stale duplicates then fail
// every list page with "Request failed"). A fresh dedicated file per
// run keeps e2e deterministic and leaves the dev database alone.
command: `cd src/jetstream && mkdir -p ../../dist/e2e-db && STRATOS_E2E=e2e:${BACKEND_PORT} CONSOLE_PROXY_TLS_ADDRESS=:${BACKEND_PORT} SQLITE_DB_DIR=../../dist/e2e-db SQLITE_KEEP_DB=false ../../dist/bin/jetstream`,
url: `https://localhost:${BACKEND_PORT}/pp/v1/info`,
reuseExistingServer: true,
ignoreHTTPSErrors: true,
timeout: 30000,
env: {
SESSION_STORE_EXPIRY: '360',
},
},
{
command: `STRATOS_E2E=e2e:${BACKEND_PORT} BACKEND_PORT=${BACKEND_PORT} bun run ng serve --port ${FRONTEND_PORT} --proxy-config proxy.conf.cjs`,
url: `https://localhost:${FRONTEND_PORT}`,
reuseExistingServer: true,
ignoreHTTPSErrors: true,
timeout: 120000,
},
],
}),
});