@playwright-test-runner/core 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,43 +1,64 @@
1
1
  # Playwright Test Runner Library
2
2
 
3
- Libreria agnostica per eseguire test Playwright con server Express e UI report. Può essere installata in qualsiasi progetto TypeScript/JavaScript per eseguire test E2E.
3
+ > Libreria completa e agnostica per eseguire test Playwright con server Express, UI report e daemon server integrato.
4
4
 
5
- ## Caratteristiche
5
+ [![npm version](https://img.shields.io/npm/v/@playwright-test-runner/core.svg)](https://www.npmjs.com/package/@playwright-test-runner/core)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
7
 
7
- - Server Express con API REST per eseguire test Playwright
8
- - Lettura automatica dei file `.spec.ts` dalla cartella `tests`
9
- - Report UI integrato di Playwright
10
- - Completamente agnostico dal contesto del progetto
11
- - Facile integrazione in progetti esistenti
8
+ ## Caratteristiche Principali
12
9
 
13
- ## Installazione
10
+ - 🎭 **Playwright Integrato** - Include già Playwright e tutti i browser
11
+ - 🚀 **Daemon Server Automatico** - Report sempre disponibili su porta fissa (9324)
12
+ - 🎨 **Web UI Completa** - Interfaccia grafica per gestire i test
13
+ - 📊 **Report Interattivi** - Visualizzazione avanzata dei risultati
14
+ - 🔌 **REST API** - Controllo completo via HTTP
15
+ - 🛠️ **CLI Potenti** - 4 comandi per ogni esigenza
16
+ - ⚙️ **Zero Config** - Funziona subito, nessuna configurazione richiesta
17
+ - 🔄 **Port Management** - Gestione intelligente delle porte occupate
18
+
19
+ ## 📦 Installazione
14
20
 
15
21
  ```bash
16
22
  npm install @playwright-test-runner/core
17
23
  ```
18
24
 
19
- **IMPORTANTE:** La libreria include già Playwright e tutti i browser necessari. **NON serve installare** `@playwright/test` o eseguire `npx playwright install` nel tuo progetto!
25
+ ### Installazione Automatica del Daemon
20
26
 
21
- ## Utilizzo
27
+ Dopo l'installazione, il **daemon server** si avvia automaticamente e serve i report su `http://localhost:9324`!
22
28
 
23
- ### 1. Setup (Solo 2 Passi!)
29
+ ```
30
+ ╔════════════════════════════════════════════════════════════╗
31
+ ║ 🎭 Playwright Test Runner - Post Install ║
32
+ ╚════════════════════════════════════════════════════════════╝
24
33
 
25
- **Passo 1:** Crea una cartella `tests` nel tuo progetto
34
+ Report Server avviato in background!
26
35
 
27
- **Passo 2:** Aggiungi i tuoi file di test con estensione `.spec.ts`
36
+ 📊 Report disponibile su:
37
+ → http://localhost:9324
28
38
 
39
+ 📋 Dashboard:
40
+ → http://localhost:9324/dashboard
29
41
  ```
30
- your-project/
31
- ├── tests/ # Crea solo questa cartella!
32
- │ ├── example.spec.ts
33
- │ ├── login.spec.ts
34
- │ └── checkout.spec.ts
35
- └── package.json
42
+
43
+ **Controllo del daemon tramite variabili d'ambiente:**
44
+
45
+ ```bash
46
+ # Disabilita daemon completamente
47
+ PLAYWRIGHT_SKIP_DAEMON=true npm install
48
+
49
+ # Daemon non si avvia automaticamente (manuale)
50
+ PLAYWRIGHT_DAEMON_AUTO=false npm install
51
+
52
+ # Automaticamente disabilitato in produzione
53
+ NODE_ENV=production npm install
54
+
55
+ # Automaticamente disabilitato in CI/CD
56
+ CI=true npm install
36
57
  ```
37
58
 
38
- **NOTA:** NON serve creare `playwright.config.ts` - la libreria include già la configurazione!
59
+ ## 🚀 Utilizzo Rapido
39
60
 
40
- ### 2. Web UI (Interfaccia Grafica - NUOVO!) 🎨
61
+ ### Metodo 1: Web UI (Interfaccia Grafica) 🎨
41
62
 
42
63
  **Il modo più semplice - interfaccia web completa:**
43
64
 
@@ -45,15 +66,38 @@ your-project/
45
66
  npx playwright-ui
46
67
  ```
47
68
 
48
- Poi apri il browser su **http://localhost:3001**
69
+ Apri il browser su **http://localhost:3001**
49
70
 
50
- Interfaccia grafica che permette di:
71
+ **Funzionalità:**
51
72
  - 📋 Vedere tutti i test disponibili
52
73
  - ▶️ Eseguire i test con un click
53
74
  - 📊 Visualizzare il report interattivo
54
75
  - ⚙️ Configurare reporter e opzioni
55
76
 
56
- ### 3. Uso tramite CLI (Metodo Rapido)
77
+ ### Metodo 2: Daemon Server (Report Persistente) 🔄
78
+
79
+ Il daemon si avvia automaticamente all'installazione, ma puoi gestirlo manualmente:
80
+
81
+ ```bash
82
+ # Avvia il daemon (se non è già attivo)
83
+ npx playwright-daemon
84
+
85
+ # Controlla lo stato
86
+ npx playwright-daemon status
87
+
88
+ # Ferma il daemon
89
+ npx playwright-daemon stop
90
+
91
+ # Avvia su porta custom
92
+ npx playwright-daemon --port 9000
93
+ ```
94
+
95
+ **Accesso al daemon:**
96
+ - Report: `http://localhost:9324`
97
+ - Dashboard: `http://localhost:9324/dashboard`
98
+ - Health Check: `http://localhost:9324/health`
99
+
100
+ ### Metodo 3: CLI Esegui & Mostra ⚡
57
101
 
58
102
  **Esegui test e visualizza report automaticamente:**
59
103
 
@@ -61,243 +105,434 @@ Interfaccia grafica che permette di:
61
105
  npx playwright-test
62
106
  ```
63
107
 
64
- Questo comando:
65
- 1. ✅ Legge automaticamente i test dalla cartella `tests` del tuo progetto
108
+ **Questo comando:**
109
+ 1. ✅ Legge automaticamente i test dalla cartella `tests`
66
110
  2. ✅ Esegue tutti i test Playwright
67
111
  3. ✅ Apre automaticamente il report UI nel browser
68
112
 
69
- Opzioni disponibili:
113
+ **Opzioni disponibili:**
70
114
 
71
115
  ```bash
72
- npx playwright-test --tests-dir e2e # Usa cartella 'e2e' invece di 'tests'
73
- npx playwright-test --project /path/to/dir # Specifica root del progetto
116
+ npx playwright-test --tests-dir e2e # Usa cartella 'e2e'
117
+ npx playwright-test --project /path/to/dir # Specifica root
74
118
  npx playwright-test --help # Mostra help
75
119
  ```
76
120
 
77
- ### 4. Uso tramite Server API
121
+ ### Metodo 4: Server API REST 🔌
78
122
 
79
- Avvia il server dalla root del tuo progetto:
123
+ **Avvia server con API REST complete:**
80
124
 
81
125
  ```bash
82
126
  npx playwright-runner
83
127
  ```
84
128
 
85
- Opzioni disponibili:
129
+ **Opzioni disponibili:**
86
130
 
87
131
  ```bash
88
132
  npx playwright-runner --port 4000 # Usa porta 4000
89
- npx playwright-runner --project /path/to/project # Specifica root del progetto
90
- npx playwright-runner --tests-dir e2e # Usa cartella 'e2e' invece di 'tests'
133
+ npx playwright-runner --project /path/to/project # Specifica root
134
+ npx playwright-runner --tests-dir e2e # Usa cartella 'e2e'
135
+ ```
136
+
137
+ ## 📁 Setup Progetto
138
+
139
+ ### Passo 1: Crea la cartella tests
140
+
141
+ **IMPORTANTE:** La libreria include già Playwright. **NON serve** installare `@playwright/test` o creare `playwright.config.ts`!
142
+
143
+ ```
144
+ your-project/
145
+ ├── tests/ # ← Crea solo questa cartella!
146
+ │ ├── example.spec.ts
147
+ │ ├── login.spec.ts
148
+ │ └── checkout.spec.ts
149
+ └── package.json
91
150
  ```
92
151
 
93
- ### 5. Uso programmatico
152
+ ### Passo 2: Scrivi i tuoi test
94
153
 
95
- Crea un file `test-server.ts` nel tuo progetto:
154
+ File `tests/example.spec.ts`:
96
155
 
97
156
  ```typescript
98
- import { createServer } from '@playwright-test-runner/core';
157
+ import { test, expect } from '@playwright/test';
99
158
 
100
- const server = createServer({
101
- port: 3000,
159
+ test('homepage has title', async ({ page }) => {
160
+ await page.goto('https://playwright.dev/');
161
+ await expect(page).toHaveTitle(/Playwright/);
162
+ });
163
+
164
+ test('get started link', async ({ page }) => {
165
+ await page.goto('https://playwright.dev/');
166
+ await page.getByRole('link', { name: 'Get started' }).click();
167
+ await expect(page).toHaveURL(/.*intro/);
168
+ });
169
+ ```
170
+
171
+ ## 🎯 Comandi CLI Disponibili
172
+
173
+ La libreria fornisce **4 comandi CLI** principali:
174
+
175
+ | Comando | Descrizione | Porta |
176
+ |---------|-------------|-------|
177
+ | `playwright-daemon` | Daemon server persistente per report | 9324 |
178
+ | `playwright-ui` | Interfaccia web per gestire test | 3001 |
179
+ | `playwright-test` | Esegui test e mostra report | 9323 |
180
+ | `playwright-runner` | Server API REST completo | 3000 |
181
+
182
+ ## 🔌 API Endpoints
183
+
184
+ ### Daemon Server (porta 9324)
185
+
186
+ ```bash
187
+ # Health check
188
+ GET http://localhost:9324/health
189
+
190
+ # Dashboard interattiva
191
+ GET http://localhost:9324/dashboard
192
+
193
+ # Report HTML
194
+ GET http://localhost:9324/
195
+
196
+ # Esegui test via API
197
+ POST http://localhost:9324/api/run
198
+ Content-Type: application/json
199
+ {
200
+ "reporter": "html",
201
+ "headed": false
202
+ }
203
+
204
+ # Lista test disponibili
205
+ GET http://localhost:9324/api/tests
206
+ ```
207
+
208
+ ### API Server (porta 3000)
209
+
210
+ ```bash
211
+ # Health check
212
+ GET http://localhost:3000/health
213
+
214
+ # Lista test
215
+ GET http://localhost:3000/tests
216
+
217
+ # Esegui test
218
+ POST http://localhost:3000/run
219
+ Content-Type: application/json
220
+ {
221
+ "reporter": "html",
222
+ "headed": false
223
+ }
224
+
225
+ # Mostra report UI
226
+ POST http://localhost:3000/report/show
227
+
228
+ # Ferma report UI
229
+ POST http://localhost:3000/report/stop
230
+ ```
231
+
232
+ ## 💻 Uso Programmatico
233
+
234
+ ### Daemon Server
235
+
236
+ ```typescript
237
+ import { createDaemon } from '@playwright-test-runner/core';
238
+
239
+ const daemon = createDaemon({
240
+ port: 9324,
102
241
  projectRoot: process.cwd(),
103
- testsDir: 'tests'
242
+ testsDir: 'tests',
104
243
  });
105
244
 
106
- server.start();
245
+ await daemon.start();
246
+ // Daemon attivo su http://localhost:9324
247
+
248
+ // Ferma il daemon
249
+ daemon.stop();
107
250
  ```
108
251
 
109
- ### 4. Uso come modulo
252
+ ### Test Runner
110
253
 
111
254
  ```typescript
112
255
  import { PlaywrightTestRunner } from '@playwright-test-runner/core';
113
256
 
114
- async function runMyTests() {
115
- const runner = new PlaywrightTestRunner({
116
- projectRoot: process.cwd(),
117
- testsDir: 'tests'
118
- });
257
+ const runner = new PlaywrightTestRunner({
258
+ projectRoot: process.cwd(),
259
+ testsDir: 'tests'
260
+ });
119
261
 
120
- // Ottieni lista dei test
121
- const testFiles = await runner.getTestFiles();
122
- console.log('Test trovati:', testFiles);
262
+ // Ottieni lista dei test
263
+ const testFiles = await runner.getTestFiles();
264
+ console.log('Test trovati:', testFiles);
123
265
 
124
- // Esegui i test
125
- const result = await runner.runTests({
126
- reporter: 'html',
127
- headed: false
128
- });
266
+ // Esegui i test
267
+ const result = await runner.runTests({
268
+ reporter: 'html',
269
+ headed: false
270
+ });
129
271
 
130
- console.log('Risultato:', result);
131
- }
272
+ // Mostra report
273
+ const { url } = await runner.showReport();
274
+ console.log('Report disponibile su:', url);
132
275
 
133
- runMyTests();
276
+ // Cleanup
277
+ runner.stopReportServer();
134
278
  ```
135
279
 
136
- ## API Endpoints
280
+ ### API Server
281
+
282
+ ```typescript
283
+ import { createServer } from '@playwright-test-runner/core';
137
284
 
138
- Una volta avviato il server, saranno disponibili i seguenti endpoint:
285
+ const server = createServer({
286
+ port: 3000,
287
+ projectRoot: process.cwd(),
288
+ testsDir: 'tests'
289
+ });
139
290
 
140
- ### GET /health
291
+ server.start();
292
+ // Server attivo su http://localhost:3000
293
+ ```
141
294
 
142
- Health check del server.
295
+ ## 📋 Script package.json Consigliati
296
+
297
+ Aggiungi questi script al tuo `package.json`:
143
298
 
144
- **Response:**
145
299
  ```json
146
300
  {
147
- "status": "ok",
148
- "service": "playwright-test-runner"
301
+ "scripts": {
302
+ "test:ui": "playwright-ui",
303
+ "test:run": "playwright-test",
304
+ "test:daemon": "playwright-daemon",
305
+ "test:daemon:stop": "playwright-daemon stop",
306
+ "test:daemon:status": "playwright-daemon status",
307
+ "test:server": "playwright-runner"
308
+ }
149
309
  }
150
310
  ```
151
311
 
152
- ### GET /tests
312
+ ## 🔄 Workflow Completi
153
313
 
154
- Ottieni la lista dei file di test disponibili.
314
+ ### Sviluppo Locale
155
315
 
156
- **Response:**
157
- ```json
158
- {
159
- "success": true,
160
- "count": 3,
161
- "files": [
162
- "/path/to/project/tests/example.spec.ts",
163
- "/path/to/project/tests/login.spec.ts",
164
- "/path/to/project/tests/checkout.spec.ts"
165
- ]
166
- }
316
+ ```bash
317
+ # 1. Installa il package (daemon si avvia automaticamente)
318
+ npm install @playwright-test-runner/core
319
+
320
+ # 2. Crea i tuoi test nella cartella tests/
321
+ mkdir tests
322
+ # Aggiungi file .spec.ts
323
+
324
+ # 3. Esegui i test
325
+ npx playwright-test
326
+
327
+ # 4. I report sono automaticamente disponibili su:
328
+ # - http://localhost:9324 (daemon - sempre attivo)
329
+ # - Oppure il browser si apre automaticamente con il report
167
330
  ```
168
331
 
169
- ### POST /run
332
+ ### Produzione
333
+
334
+ ```bash
335
+ # Il daemon NON si avvia in produzione
336
+ NODE_ENV=production npm install
170
337
 
171
- Esegui i test Playwright.
338
+ # Esegui i test (se necessario)
339
+ npx playwright-test
172
340
 
173
- **Request Body:**
174
- ```json
175
- {
176
- "reporter": "html",
177
- "headed": false
178
- }
341
+ # Il report sarà in playwright-report/ ma il daemon non sarà attivo
179
342
  ```
180
343
 
181
- **Response:**
182
- ```json
183
- {
184
- "success": true,
185
- "output": "Running 3 tests...\n...",
186
- "reportPath": "/path/to/project/playwright-report"
187
- }
344
+ ### CI/CD (GitHub Actions)
345
+
346
+ ```yaml
347
+ name: E2E Tests
348
+ on: [push]
349
+
350
+ jobs:
351
+ test:
352
+ runs-on: ubuntu-latest
353
+ steps:
354
+ - uses: actions/checkout@v3
355
+ - uses: actions/setup-node@v3
356
+ with:
357
+ node-version: 18
358
+
359
+ - name: Install
360
+ run: npm install
361
+ env:
362
+ CI: true # Daemon automaticamente skippato
363
+
364
+ - name: Install browsers
365
+ run: npx playwright install --with-deps chromium
366
+
367
+ - name: Run tests
368
+ run: npx playwright-test
369
+
370
+ - name: Upload report
371
+ if: always()
372
+ uses: actions/upload-artifact@v3
373
+ with:
374
+ name: playwright-report
375
+ path: playwright-report/
188
376
  ```
189
377
 
190
- ### POST /report/show
378
+ ## 🛠️ Gestione Daemon
191
379
 
192
- Avvia il server del report UI di Playwright.
380
+ ### Comandi Daemon
193
381
 
194
- **Response:**
195
- ```json
196
- {
197
- "success": true,
198
- "message": "Report UI avviato",
199
- "url": "http://localhost:9323"
200
- }
382
+ ```bash
383
+ # Stato del daemon
384
+ npx playwright-daemon status
385
+
386
+ # Output:
387
+ # ✅ Daemon ATTIVO
388
+ # 📊 Informazioni:
389
+ # • PID: 12345
390
+ # • Porta: 9324
391
+ # • Status: ok
392
+ # 🌐 URLs:
393
+ # • Report: http://localhost:9324
394
+ # • Dashboard: http://localhost:9324/dashboard
395
+
396
+ # Fermare il daemon
397
+ npx playwright-daemon stop
398
+
399
+ # Avviare il daemon manualmente
400
+ npx playwright-daemon
401
+
402
+ # Avvio su porta custom
403
+ npx playwright-daemon --port 9000
201
404
  ```
202
405
 
203
- ### POST /report/stop
406
+ ### Troubleshooting Daemon
204
407
 
205
- Ferma il server del report UI.
408
+ ```bash
409
+ # Processo zombie sulla porta 9324
410
+ lsof -ti:9324 | xargs kill -9
206
411
 
207
- **Response:**
208
- ```json
209
- {
210
- "success": true,
211
- "message": "Report UI fermato"
212
- }
412
+ # Riavvia il daemon
413
+ npx playwright-daemon
213
414
  ```
214
415
 
215
- ## Esempio di Test
416
+ ## 📚 Guide Complete
216
417
 
217
- Crea un file `tests/example.spec.ts`:
418
+ - 📖 **[QUICKSTART.md](QUICKSTART.md)** - Guida rapida per iniziare
419
+ - 🔧 **[SETUP_SEMPLIFICATO.md](SETUP_SEMPLIFICATO.md)** - Setup zero-config
420
+ - 🌐 **[WEB_UI_GUIDE.md](WEB_UI_GUIDE.md)** - Guida all'interfaccia Web
421
+ - 🔄 **[DAEMON_GUIDE.md](DAEMON_GUIDE.md)** - Guida completa al Daemon Server
422
+ - 🔗 **[INTEGRATION.md](INTEGRATION.md)** - Integrazione con framework (React, Vue, Angular)
423
+ - 🧪 **[LOCAL_TESTING_GUIDE.md](LOCAL_TESTING_GUIDE.md)** - Testing locale con npm link
424
+ - ❌ **[TROUBLESHOOTING.md](TROUBLESHOOTING.md)** - Risoluzione problemi comuni
218
425
 
219
- ```typescript
220
- import { test, expect } from '@playwright/test';
426
+ ## 🚨 Troubleshooting Rapido
221
427
 
222
- test('homepage has title', async ({ page }) => {
223
- await page.goto('https://playwright.dev/');
224
- await expect(page).toHaveTitle(/Playwright/);
225
- });
428
+ ### Errore: "porta 9324 già in uso"
226
429
 
227
- test('get started link', async ({ page }) => {
228
- await page.goto('https://playwright.dev/');
229
- await page.getByRole('link', { name: 'Get started' }).click();
230
- await expect(page).toHaveURL(/.*intro/);
231
- });
430
+ ```bash
431
+ # Verifica stato daemon
432
+ npx playwright-daemon status
433
+
434
+ # Se appeso, killalo
435
+ lsof -ti:9324 | xargs kill -9
436
+
437
+ # Riavvia
438
+ npx playwright-daemon
232
439
  ```
233
440
 
234
- ## Workflow Completo
441
+ ### Errore: "cartella tests non trovata"
235
442
 
236
- 1. Installa la libreria nel tuo progetto
237
- 2. Crea la cartella `tests` con i tuoi file `.spec.ts`
238
- 3. Avvia il server: `npx playwright-runner`
239
- 4. Esegui i test via API: `POST http://localhost:3000/run`
240
- 5. Visualizza il report: `POST http://localhost:3000/report/show`
241
- 6. Apri il browser su `http://localhost:9323` per vedere il report UI
443
+ ```bash
444
+ # Crea la cartella tests
445
+ mkdir tests
242
446
 
243
- ## Esempio con cURL
447
+ # Aggiungi un file di test
448
+ echo 'import { test } from "@playwright/test";
449
+ test("example", async () => {});' > tests/example.spec.ts
450
+ ```
451
+
452
+ ### Daemon non si avvia in produzione
453
+
454
+ È normale! Il daemon è disabilitato automaticamente in:
455
+ - `NODE_ENV=production`
456
+ - `CI=true`
244
457
 
458
+ Per forzare l'avvio:
245
459
  ```bash
246
- # Health check
247
- curl http://localhost:3000/health
460
+ PLAYWRIGHT_DAEMON_AUTO=true npm install
461
+ ```
248
462
 
249
- # Lista test
250
- curl http://localhost:3000/tests
463
+ Consulta la [Guida Troubleshooting](TROUBLESHOOTING.md) completa per altri problemi.
251
464
 
252
- # Esegui test
253
- curl -X POST http://localhost:3000/run \
254
- -H "Content-Type: application/json" \
255
- -d '{"reporter":"html","headed":false}'
465
+ ## 🔧 Port Management Avanzato
256
466
 
257
- # Mostra report UI
258
- curl -X POST http://localhost:3000/report/show
467
+ La libreria include **gestione intelligente delle porte**:
259
468
 
260
- # Ferma report UI
261
- curl -X POST http://localhost:3000/report/stop
469
+ 1. **Controllo automatico** - Verifica se la porta è già in uso
470
+ 2. **Riutilizzo server esistente** - Se il report è già attivo, lo riutilizza
471
+ 3. **Cleanup automatico** - Chiusura pulita all'uscita del processo
472
+
473
+ Questo previene l'errore `EADDRINUSE` (porta già in uso).
474
+
475
+ ## 📊 Struttura Progetto
476
+
477
+ ```
478
+ @playwright-test-runner/core/
479
+ ├── dist/ # Build TypeScript
480
+ │ ├── cli.js # CLI per API server
481
+ │ ├── daemon-cli.js # CLI per daemon
482
+ │ ├── run-and-show.js # CLI esegui & mostra
483
+ │ ├── web-cli.js # CLI per Web UI
484
+ │ ├── server.js # Server API REST
485
+ │ ├── report-daemon.js # Daemon server
486
+ │ ├── test-runner.js # Test runner core
487
+ │ ├── web-ui.js # Web UI server
488
+ │ └── index.js # Entry point principale
489
+ ├── scripts/ # Script di utilità
490
+ │ ├── postinstall.js # Post-install auto daemon
491
+ │ ├── release.js # Script per release npm
492
+ │ ├── status-daemon.js # Controlla stato daemon
493
+ │ └── stop-daemon.js # Ferma daemon
494
+ ├── public/ # Asset Web UI
495
+ │ └── index.html # Interfaccia grafica
496
+ ├── src/ # Sorgenti TypeScript
497
+ ├── playwright.config.ts # Config Playwright inclusa
498
+ └── package.json
262
499
  ```
263
500
 
264
- ## Script package.json consigliati
501
+ ## 🚀 Pubblicazione (per Maintainer)
265
502
 
266
- Aggiungi questi script al `package.json` del tuo progetto:
503
+ La libreria include uno script interattivo per gestire versioning e pubblicazione:
267
504
 
268
- ```json
269
- {
270
- "scripts": {
271
- "test:server": "playwright-runner",
272
- "test:run": "playwright test",
273
- "test:report": "playwright show-report"
274
- }
275
- }
505
+ ```bash
506
+ # Esegui lo script di release
507
+ npm run release
508
+
509
+ # Lo script ti guiderà attraverso:
510
+ # 1. Commit automatico modifiche (se presenti)
511
+ # 2. Scelta tipo versione (PATCH/MINOR/MAJOR/CUSTOM)
512
+ # 3. Aggiornamento automatico versione
513
+ # 4. Login npm (con browser)
514
+ # 5. Pubblicazione su npm
515
+ # 6. Reminder per git push
276
516
  ```
277
517
 
278
- ## Troubleshooting
518
+ ## ✅ Requisiti
519
+
520
+ - **Node.js** >= 18
521
+ - **TypeScript** >= 5.0 (per progetti TypeScript)
522
+ - **Playwright** - ✅ Incluso nella libreria!
279
523
 
280
- Hai problemi? Consulta la [Guida al Troubleshooting](TROUBLESHOOTING.md) per risolvere i problemi più comuni:
524
+ ## 📝 Versione Corrente
281
525
 
282
- - Errore "porta 9323 già in uso" [Soluzione](TROUBLESHOOTING.md#errore-listen-eaddrinuse-address-already-in-use-19323)
283
- - ❌ Errore "cartella tests non trovata" → [Soluzione](TROUBLESHOOTING.md#errore-cartella-tests-non-trovata)
284
- - ❌ Errore "playwright: command not found" → [Soluzione](TROUBLESHOOTING.md#errore-playwright-command-not-found)
285
- - E molti altri...
526
+ **v1.0.9** - Include daemon server, port management, Web UI e CLI completi
286
527
 
287
- ## Guide Aggiuntive
528
+ ## 🤝 Contributing
288
529
 
289
- - 📖 [QUICKSTART.md](QUICKSTART.md) - Guida rapida per iniziare
290
- - 🔧 [SETUP_SEMPLIFICATO.md](SETUP_SEMPLIFICATO.md) - Setup zero-config
291
- - 🌐 [WEB_UI_GUIDE.md](WEB_UI_GUIDE.md) - Guida all'interfaccia Web
292
- - 🔗 [INTEGRATION.md](INTEGRATION.md) - Integrazione con framework (React, Vue, Angular, ecc.)
293
- - 🧪 [LOCAL_TESTING_GUIDE.md](LOCAL_TESTING_GUIDE.md) - Testing locale con npm link
530
+ Contributi benvenuti! Leggi [CONTRIBUTING.md](CONTRIBUTING.md) per le linee guida.
294
531
 
295
- ## Requisiti
532
+ ## 📄 License
296
533
 
297
- - Node.js >= 18
298
- - TypeScript >= 5.0 (per progetti TypeScript)
299
- - **Playwright è incluso nella libreria** - NON serve installarlo!
534
+ MIT © Giovanni Cannone
300
535
 
301
- ## License
536
+ ---
302
537
 
303
- MIT
538
+ **Made with ❤️ for the Playwright community**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playwright-test-runner/core",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Libreria agnostica per eseguire test Playwright con server Express e UI report",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -42,6 +42,7 @@
42
42
  "files": [
43
43
  "dist",
44
44
  "public",
45
+ "scripts",
45
46
  "playwright.config.ts"
46
47
  ],
47
48
  "directories": {
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Post-install script
5
+ * Avvia automaticamente il report daemon dopo l'installazione del package
6
+ *
7
+ * Controllo tramite variabili d'ambiente:
8
+ * - PLAYWRIGHT_SKIP_DAEMON=true - Salta completamente l'avvio del daemon
9
+ * - PLAYWRIGHT_DAEMON_AUTO=false - Non avvia il daemon automaticamente
10
+ * - NODE_ENV=production - Non avvia il daemon in produzione
11
+ */
12
+
13
+ const { spawn } = require('child_process');
14
+ const path = require('path');
15
+ const fs = require('fs');
16
+
17
+ // Evita di eseguire durante l'installazione della libreria stessa
18
+ const isLibraryInstall = process.cwd().includes('playwright-library') ||
19
+ process.cwd().includes('@playwright-test-runner');
20
+
21
+ if (isLibraryInstall) {
22
+ console.log('📦 Installazione della libreria in corso, skip post-install...');
23
+ process.exit(0);
24
+ }
25
+
26
+ // Controlli per evitare l'avvio automatico
27
+ const skipDaemon = process.env.PLAYWRIGHT_SKIP_DAEMON === 'true';
28
+ const daemonAuto = process.env.PLAYWRIGHT_DAEMON_AUTO !== 'false'; // Default: true
29
+ const isProduction = process.env.NODE_ENV === 'production';
30
+ const isCIEnvironment = process.env.CI === 'true';
31
+
32
+ if (skipDaemon) {
33
+ console.log('⏭️ PLAYWRIGHT_SKIP_DAEMON=true - Skip avvio daemon');
34
+ process.exit(0);
35
+ }
36
+
37
+ if (!daemonAuto) {
38
+ console.log('⏭️ PLAYWRIGHT_DAEMON_AUTO=false - Avvio manuale richiesto');
39
+ console.log(' Usa: npx playwright-daemon\n');
40
+ process.exit(0);
41
+ }
42
+
43
+ if (isProduction) {
44
+ console.log('🚫 NODE_ENV=production - Daemon non avviato in produzione');
45
+ console.log(' Per avviarlo comunque: PLAYWRIGHT_DAEMON_AUTO=true npm install');
46
+ console.log(' Oppure manualmente: npx playwright-daemon\n');
47
+ process.exit(0);
48
+ }
49
+
50
+ if (isCIEnvironment) {
51
+ console.log('🚫 CI=true - Daemon non avviato in ambiente CI/CD');
52
+ console.log(' Per avviarlo comunque: PLAYWRIGHT_DAEMON_AUTO=true npm install\n');
53
+ process.exit(0);
54
+ }
55
+
56
+ console.log(`
57
+ ╔════════════════════════════════════════════════════════════╗
58
+ ║ ║
59
+ ║ 🎭 Playwright Test Runner - Post Install ║
60
+ ║ ║
61
+ ╚════════════════════════════════════════════════════════════╝
62
+
63
+ 📦 Package installato con successo!
64
+
65
+ 🚀 Avvio del Report Server in background...
66
+ `);
67
+
68
+ // Determina il percorso del daemon
69
+ const projectRoot = process.env.INIT_CWD || process.cwd();
70
+ const daemonBin = path.join(__dirname, '../dist/daemon-cli.js');
71
+
72
+ // Verifica che il daemon esista
73
+ if (!fs.existsSync(daemonBin)) {
74
+ console.log('⚠️ Daemon non trovato, skip auto-start.');
75
+ console.log(' Usa: npx playwright-daemon per avviarlo manualmente\n');
76
+ process.exit(0);
77
+ }
78
+
79
+ // Crea la cartella tests se non esiste
80
+ const testsDir = path.join(projectRoot, 'tests');
81
+ if (!fs.existsSync(testsDir)) {
82
+ console.log('📁 Creazione cartella tests...');
83
+ fs.mkdirSync(testsDir, { recursive: true });
84
+
85
+ // Crea un test di esempio
86
+ const exampleTest = `import { test, expect } from '@playwright/test';
87
+
88
+ test('example test', async ({ page }) => {
89
+ await page.goto('https://example.com');
90
+ await expect(page).toHaveTitle(/Example Domain/);
91
+ });
92
+ `;
93
+
94
+ fs.writeFileSync(path.join(testsDir, 'example.spec.ts'), exampleTest);
95
+ console.log('✅ Creato file di test di esempio: tests/example.spec.ts\n');
96
+ }
97
+
98
+ // Avvia il daemon in background
99
+ try {
100
+ const daemon = spawn('node', [daemonBin, '--port', '9324'], {
101
+ detached: true,
102
+ stdio: 'ignore',
103
+ cwd: projectRoot,
104
+ env: {
105
+ ...process.env,
106
+ INIT_CWD: projectRoot,
107
+ }
108
+ });
109
+
110
+ daemon.unref(); // Permette al processo parent di uscire
111
+
112
+ console.log(`
113
+ ✅ Report Server avviato in background!
114
+
115
+ 📊 Report disponibile su:
116
+ → http://localhost:9324
117
+
118
+ 📋 Dashboard:
119
+ → http://localhost:9324/dashboard
120
+
121
+ 💡 Comandi disponibili:
122
+ • npx playwright-test - Esegui test e mostra report
123
+ • npx playwright-ui - Interfaccia web interattiva
124
+ • npx playwright-daemon - Gestisci il daemon server
125
+
126
+ 📁 Test Directory: ${testsDir}
127
+
128
+ 🎯 Prossimi Passi:
129
+ 1. Aggiungi i tuoi test nella cartella 'tests/'
130
+ 2. Esegui: npx playwright-test
131
+ 3. Visualizza i report su http://localhost:9324
132
+
133
+ ════════════════════════════════════════════════════════════
134
+
135
+ `);
136
+
137
+ // Salva il PID per future gestioni
138
+ const pidFile = path.join(projectRoot, '.playwright-daemon.pid');
139
+ fs.writeFileSync(pidFile, daemon.pid.toString());
140
+
141
+ } catch (error) {
142
+ console.error('❌ Errore durante l\'avvio del daemon:', error.message);
143
+ console.log('\n💡 Puoi avviarlo manualmente con: npx playwright-daemon\n');
144
+ }
@@ -0,0 +1,222 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Release Script
5
+ * Gestisce il versioning e la pubblicazione su npm in modo interattivo
6
+ */
7
+
8
+ const { execSync, spawn } = require('child_process');
9
+ const readline = require('readline');
10
+
11
+ console.log(`
12
+ ╔════════════════════════════════════════════════════════════╗
13
+ ║ ║
14
+ ║ 🚀 Playwright Test Runner - Release Script ║
15
+ ║ ║
16
+ ╚════════════════════════════════════════════════════════════╝
17
+ `);
18
+
19
+ // Controlla lo stato git
20
+ function checkGitStatus() {
21
+ try {
22
+ const status = execSync('git status --porcelain', { encoding: 'utf-8' });
23
+ return status.trim() !== '';
24
+ } catch (error) {
25
+ return false;
26
+ }
27
+ }
28
+
29
+ // Leggi la versione corrente
30
+ const packageJson = require('../package.json');
31
+ console.log(`📦 Versione corrente: ${packageJson.version}\n`);
32
+
33
+ // Controlla se ci sono modifiche non committate
34
+ const hasChanges = checkGitStatus();
35
+
36
+ if (hasChanges) {
37
+ console.log('⚠️ Modifiche non committate rilevate!\n');
38
+
39
+ const rlGit = readline.createInterface({
40
+ input: process.stdin,
41
+ output: process.stdout,
42
+ });
43
+
44
+ rlGit.question('Vuoi committare tutte le modifiche ora? (s/n): ', (answer) => {
45
+ if (answer.toLowerCase() === 's' || answer.toLowerCase() === 'y') {
46
+ rlGit.question('Inserisci il messaggio di commit: ', (message) => {
47
+ try {
48
+ execSync('git add .', { stdio: 'inherit' });
49
+ execSync(`git commit -m "${message}"`, { stdio: 'inherit' });
50
+ console.log('\n✅ Modifiche committate!\n');
51
+ rlGit.close();
52
+ // Piccolo delay per lasciare stdio stabilizzarsi
53
+ setTimeout(() => startRelease(), 100);
54
+ } catch (error) {
55
+ console.error('\n❌ Errore durante il commit:', error.message);
56
+ rlGit.close();
57
+ process.exit(1);
58
+ }
59
+ });
60
+ } else {
61
+ console.log('\n⚠️ Procedo senza creare tag git (solo aggiornamento version in package.json)\n');
62
+ rlGit.close();
63
+ setTimeout(() => startRelease(true), 100); // Skip git tag
64
+ }
65
+ });
66
+ } else {
67
+ startRelease();
68
+ }
69
+
70
+ function startRelease(skipGitTag = false) {
71
+ const rl = readline.createInterface({
72
+ input: process.stdin,
73
+ output: process.stdout,
74
+ });
75
+
76
+ console.log('Seleziona il tipo di versione da rilasciare:\n');
77
+ console.log(' 1. PATCH - Bug fix (es: 1.0.2 → 1.0.3)');
78
+ console.log(' 2. MINOR - Nuova feature (es: 1.0.2 → 1.1.0)');
79
+ console.log(' 3. MAJOR - Breaking change (es: 1.0.2 → 2.0.0)');
80
+ console.log(' 4. CUSTOM - Specifica versione manualmente');
81
+ console.log(' 0. ANNULLA\n');
82
+
83
+ rl.question('La tua scelta (1-4): ', (answer) => {
84
+ let versionType;
85
+
86
+ switch (answer.trim()) {
87
+ case '1':
88
+ versionType = 'patch';
89
+ break;
90
+ case '2':
91
+ versionType = 'minor';
92
+ break;
93
+ case '3':
94
+ versionType = 'major';
95
+ break;
96
+ case '4':
97
+ rl.question('Inserisci la versione (es: 2.5.0): ', (customVersion) => {
98
+ rl.close();
99
+ setTimeout(() => executeRelease(customVersion, skipGitTag), 100);
100
+ });
101
+ return;
102
+ case '0':
103
+ console.log('\n❌ Operazione annullata\n');
104
+ rl.close();
105
+ process.exit(0);
106
+ return;
107
+ default:
108
+ console.log('\n❌ Scelta non valida\n');
109
+ rl.close();
110
+ process.exit(1);
111
+ return;
112
+ }
113
+
114
+ rl.close();
115
+ setTimeout(() => executeRelease(versionType, skipGitTag), 100);
116
+ });
117
+ }
118
+
119
+ function executeRelease(versionType, skipGitTag = false) {
120
+ try {
121
+ console.log('\n━'.repeat(30));
122
+ console.log(`\n🔄 Aggiornamento versione (${versionType})...`);
123
+
124
+ // Esegui npm version
125
+ const versionCommand = skipGitTag
126
+ ? `npm version ${versionType} --no-git-tag-version`
127
+ : `npm version ${versionType}`;
128
+
129
+ execSync(versionCommand, {
130
+ encoding: 'utf-8',
131
+ stdio: 'inherit',
132
+ });
133
+
134
+ console.log('\n✅ Versione aggiornata con successo!');
135
+
136
+ if (skipGitTag) {
137
+ console.log('⚠️ Tag git NON creato (modifiche non committate)');
138
+ console.log('💡 Ricordati di committare package.json con la nuova versione\n');
139
+ }
140
+
141
+ // Aspetta che stdio si stabilizzi dopo execSync
142
+ setTimeout(() => {
143
+ askForPublish(skipGitTag);
144
+ }, 200);
145
+
146
+ } catch (error) {
147
+ console.error('\n❌ Errore durante il versioning:', error.message);
148
+ process.exit(1);
149
+ }
150
+ }
151
+
152
+ function askForPublish(skipGitTag) {
153
+ // Chiedi conferma per la pubblicazione
154
+ const rlConfirm = readline.createInterface({
155
+ input: process.stdin,
156
+ output: process.stdout,
157
+ });
158
+
159
+ rlConfirm.question('\n📤 Vuoi pubblicare su npm? (s/n): ', (publish) => {
160
+ const shouldPublish = publish.toLowerCase() === 's' || publish.toLowerCase() === 'y';
161
+
162
+ rlConfirm.close();
163
+
164
+ if (shouldPublish) {
165
+ // Usa setTimeout per lasciare che readline si chiuda completamente
166
+ setTimeout(() => {
167
+ console.log('\n━'.repeat(30));
168
+ console.log('\n🔐 Eseguo npm login...');
169
+ console.log('💡 Il browser si aprirà per l\'autenticazione');
170
+ console.log(' Premi ENTER quando richiesto, poi completa il login nel browser\n');
171
+
172
+ // Usa spawn invece di execSync per gestire meglio l'interattività
173
+ const loginProcess = spawn('npm', ['login'], {
174
+ stdio: 'inherit', // Passa stdin, stdout, stderr al processo padre
175
+ });
176
+
177
+ loginProcess.on('close', (code) => {
178
+ if (code !== 0) {
179
+ console.error('\n❌ Errore durante il login');
180
+ process.exit(1);
181
+ }
182
+
183
+ console.log('\n✅ Login completato con successo!');
184
+ console.log('\n🚀 Pubblicazione su npm...\n');
185
+
186
+ // Esegui npm publish
187
+ const publishProcess = spawn('npm', ['publish', '--access', 'public'], {
188
+ stdio: 'inherit',
189
+ });
190
+
191
+ publishProcess.on('close', (publishCode) => {
192
+ if (publishCode !== 0) {
193
+ console.error('\n❌ Errore durante la pubblicazione');
194
+ process.exit(1);
195
+ }
196
+
197
+ console.log('\n━'.repeat(30));
198
+ console.log('\n✅ Package pubblicato con successo su npm!');
199
+
200
+ if (!skipGitTag) {
201
+ console.log('\n💡 Ricordati di pushare il tag su git:');
202
+ console.log(' git push && git push --tags\n');
203
+ } else {
204
+ console.log('\n💡 Ricordati di committare e pushare:');
205
+ console.log(' git add package.json');
206
+ console.log(' git commit -m "Release vX.X.X"');
207
+ console.log(' git push\n');
208
+ }
209
+ console.log('━'.repeat(30) + '\n');
210
+
211
+ process.exit(0);
212
+ });
213
+ });
214
+ }, 300);
215
+ } else {
216
+ console.log('\n⏭️ Pubblicazione saltata');
217
+ console.log('\n💡 Per pubblicare manualmente:');
218
+ console.log(' npm login && npm publish --access public\n');
219
+ process.exit(0);
220
+ }
221
+ });
222
+ }
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Status Daemon Script
5
+ * Controlla lo stato del daemon server
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const http = require('http');
11
+
12
+ const projectRoot = process.env.INIT_CWD || process.cwd();
13
+ const pidFile = path.join(projectRoot, '.playwright-daemon.pid');
14
+ const daemonPort = 9324;
15
+
16
+ console.log('🔍 Controllo stato daemon...\n');
17
+
18
+ // Controlla il file PID
19
+ if (!fs.existsSync(pidFile)) {
20
+ console.log('❌ Daemon non attivo');
21
+ console.log(' File PID non trovato:', pidFile);
22
+ console.log('\n💡 Avvia il daemon con: npx playwright-daemon\n');
23
+ process.exit(0);
24
+ }
25
+
26
+ const pid = parseInt(fs.readFileSync(pidFile, 'utf-8').trim());
27
+
28
+ // Controlla se il processo è attivo
29
+ let processRunning = false;
30
+ try {
31
+ process.kill(pid, 0); // Signal 0 = controlla esistenza
32
+ processRunning = true;
33
+ } catch (e) {
34
+ processRunning = false;
35
+ }
36
+
37
+ if (!processRunning) {
38
+ console.log('⚠️ Processo non più attivo (PID stale)');
39
+ console.log(' Rimuovo file PID obsoleto...');
40
+ fs.unlinkSync(pidFile);
41
+ console.log('\n💡 Riavvia il daemon con: npx playwright-daemon\n');
42
+ process.exit(0);
43
+ }
44
+
45
+ // Controlla se il server risponde
46
+ const req = http.request(
47
+ {
48
+ hostname: 'localhost',
49
+ port: daemonPort,
50
+ path: '/health',
51
+ method: 'GET',
52
+ timeout: 2000,
53
+ },
54
+ (res) => {
55
+ let data = '';
56
+
57
+ res.on('data', (chunk) => {
58
+ data += chunk;
59
+ });
60
+
61
+ res.on('end', () => {
62
+ try {
63
+ const health = JSON.parse(data);
64
+
65
+ console.log('✅ Daemon ATTIVO\n');
66
+ console.log('📊 Informazioni:');
67
+ console.log(` • PID: ${pid}`);
68
+ console.log(` • Porta: ${daemonPort}`);
69
+ console.log(` • Status: ${health.status}`);
70
+ console.log(` • Progetto: ${health.projectRoot}`);
71
+ console.log(` • Test Dir: ${health.testsDir}`);
72
+ console.log('\n🌐 URLs:');
73
+ console.log(` • Report: http://localhost:${daemonPort}`);
74
+ console.log(` • Dashboard: http://localhost:${daemonPort}/dashboard`);
75
+ console.log(` • Health: http://localhost:${daemonPort}/health`);
76
+ console.log('\n💡 Comandi:');
77
+ console.log(' • npx playwright-daemon stop - Ferma il daemon');
78
+ console.log(' • npx playwright-test - Esegui test');
79
+ console.log('');
80
+
81
+ } catch (e) {
82
+ console.log('⚠️ Server risponde ma formato non valido');
83
+ console.log(' Response:', data);
84
+ }
85
+ });
86
+ }
87
+ );
88
+
89
+ req.on('error', (error) => {
90
+ console.log('❌ Daemon non risponde');
91
+ console.log(` Processo ${pid} attivo ma server non raggiungibile sulla porta ${daemonPort}`);
92
+ console.log(` Errore: ${error.message}`);
93
+ console.log('\n💡 Prova a:');
94
+ console.log(' 1. Fermare il daemon: npx playwright-daemon stop');
95
+ console.log(' 2. Riavviarlo: npx playwright-daemon\n');
96
+ });
97
+
98
+ req.on('timeout', () => {
99
+ req.destroy();
100
+ console.log('⏱️ Timeout - Il server non risponde entro 2 secondi');
101
+ console.log('\n💡 Il daemon potrebbe essere in fase di avvio o sovraccarico\n');
102
+ });
103
+
104
+ req.end();
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Stop Daemon Script
5
+ * Ferma il daemon server dei report
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ const projectRoot = process.env.INIT_CWD || process.cwd();
12
+ const pidFile = path.join(projectRoot, '.playwright-daemon.pid');
13
+
14
+ if (!fs.existsSync(pidFile)) {
15
+ console.log('ℹ️ Nessun daemon attivo trovato');
16
+ console.log(' File PID non esistente:', pidFile);
17
+ process.exit(0);
18
+ }
19
+
20
+ try {
21
+ const pid = parseInt(fs.readFileSync(pidFile, 'utf-8').trim());
22
+
23
+ try {
24
+ // Prova a killare il processo
25
+ process.kill(pid, 'SIGTERM');
26
+
27
+ console.log(`✅ Daemon fermato (PID: ${pid})`);
28
+
29
+ // Rimuovi il file PID
30
+ fs.unlinkSync(pidFile);
31
+
32
+ } catch (killError) {
33
+ if (killError.code === 'ESRCH') {
34
+ console.log(`ℹ️ Processo ${pid} non più in esecuzione`);
35
+ fs.unlinkSync(pidFile);
36
+ } else {
37
+ throw killError;
38
+ }
39
+ }
40
+
41
+ } catch (error) {
42
+ console.error('❌ Errore durante la chiusura del daemon:', error.message);
43
+ console.log('\n💡 Prova a cercare il processo manualmente:');
44
+ console.log(' lsof -ti:9324 | xargs kill -9');
45
+ process.exit(1);
46
+ }