@playwright-test-runner/core 1.0.10 โ†’ 1.0.12

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.
@@ -1,409 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || (function () {
20
- var ownKeys = function(o) {
21
- ownKeys = Object.getOwnPropertyNames || function (o) {
22
- var ar = [];
23
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
- return ar;
25
- };
26
- return ownKeys(o);
27
- };
28
- return function (mod) {
29
- if (mod && mod.__esModule) return mod;
30
- var result = {};
31
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
- __setModuleDefault(result, mod);
33
- return result;
34
- };
35
- })();
36
- var __importDefault = (this && this.__importDefault) || function (mod) {
37
- return (mod && mod.__esModule) ? mod : { "default": mod };
38
- };
39
- Object.defineProperty(exports, "__esModule", { value: true });
40
- exports.ReportDaemon = void 0;
41
- exports.createDaemon = createDaemon;
42
- const express_1 = __importDefault(require("express"));
43
- const test_runner_1 = require("./test-runner");
44
- const path = __importStar(require("path"));
45
- const fs = __importStar(require("fs/promises"));
46
- const cors_1 = __importDefault(require("cors"));
47
- class ReportDaemon {
48
- app;
49
- runner;
50
- port;
51
- projectRoot;
52
- testsDir;
53
- server = null;
54
- constructor(options = {}) {
55
- this.port = options.port || 9324; // Porta fissa per il daemon
56
- this.projectRoot = options.projectRoot || process.env.INIT_CWD || process.cwd();
57
- this.testsDir = options.testsDir || 'tests';
58
- this.app = (0, express_1.default)();
59
- this.runner = new test_runner_1.PlaywrightTestRunner({
60
- projectRoot: this.projectRoot,
61
- testsDir: this.testsDir,
62
- });
63
- this.setupMiddleware();
64
- this.setupRoutes();
65
- }
66
- setupMiddleware() {
67
- this.app.use((0, cors_1.default)());
68
- this.app.use(express_1.default.json());
69
- this.app.use(express_1.default.static(path.join(__dirname, '../public')));
70
- }
71
- setupRoutes() {
72
- // Health check
73
- this.app.get('/health', (req, res) => {
74
- res.json({
75
- status: 'ok',
76
- projectRoot: this.projectRoot,
77
- testsDir: this.testsDir,
78
- port: this.port,
79
- });
80
- });
81
- // Serve il report direttamente sulla root
82
- this.app.get('/', async (req, res) => {
83
- const reportPath = path.join(this.projectRoot, 'playwright-report', 'index.html');
84
- try {
85
- await fs.access(reportPath);
86
- // Serve l'intero folder playwright-report come statico
87
- express_1.default.static(path.join(this.projectRoot, 'playwright-report'))(req, res, () => {
88
- res.sendFile(reportPath);
89
- });
90
- }
91
- catch {
92
- res.status(404).send(`
93
- <!DOCTYPE html>
94
- <html>
95
- <head>
96
- <title>Playwright Test Reports</title>
97
- <style>
98
- body {
99
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
100
- max-width: 800px;
101
- margin: 50px auto;
102
- padding: 20px;
103
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
104
- color: white;
105
- }
106
- .container {
107
- background: rgba(255, 255, 255, 0.1);
108
- backdrop-filter: blur(10px);
109
- border-radius: 20px;
110
- padding: 40px;
111
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
112
- }
113
- h1 { margin-top: 0; }
114
- .btn {
115
- display: inline-block;
116
- background: white;
117
- color: #667eea;
118
- padding: 12px 24px;
119
- border-radius: 8px;
120
- text-decoration: none;
121
- font-weight: 600;
122
- margin: 10px 10px 10px 0;
123
- transition: transform 0.2s;
124
- }
125
- .btn:hover {
126
- transform: translateY(-2px);
127
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
128
- }
129
- .info {
130
- background: rgba(255, 255, 255, 0.1);
131
- padding: 20px;
132
- border-radius: 10px;
133
- margin: 20px 0;
134
- }
135
- code {
136
- background: rgba(0, 0, 0, 0.3);
137
- padding: 2px 8px;
138
- border-radius: 4px;
139
- font-family: 'Courier New', monospace;
140
- }
141
- </style>
142
- </head>
143
- <body>
144
- <div class="container">
145
- <h1>๐Ÿ“Š Playwright Test Reports</h1>
146
- <p>Nessun report disponibile al momento.</p>
147
-
148
- <div class="info">
149
- <h3>Come generare un report:</h3>
150
- <ol>
151
- <li>Esegui i test: <code>npx playwright-test</code></li>
152
- <li>Oppure usa la Web UI: <code>npx playwright-ui</code></li>
153
- <li>Oppure usa il comando run: <code>npm run test:e2e</code></li>
154
- </ol>
155
- </div>
156
-
157
- <div style="margin-top: 30px;">
158
- <a href="/api/run" class="btn">๐Ÿš€ Esegui Test Ora</a>
159
- <a href="/dashboard" class="btn">๐Ÿ“‹ Dashboard</a>
160
- </div>
161
-
162
- <div style="margin-top: 30px; font-size: 14px; opacity: 0.8;">
163
- <p><strong>Progetto:</strong> ${this.projectRoot}</p>
164
- <p><strong>Test Directory:</strong> ${this.testsDir}</p>
165
- <p><strong>Server attivo su:</strong> http://localhost:${this.port}</p>
166
- </div>
167
- </div>
168
- </body>
169
- </html>
170
- `);
171
- }
172
- });
173
- // Serve tutti gli asset del report
174
- this.app.use('/data', express_1.default.static(path.join(this.projectRoot, 'playwright-report', 'data')));
175
- this.app.use('/trace', express_1.default.static(path.join(this.projectRoot, 'playwright-report', 'trace')));
176
- // API per eseguire i test
177
- this.app.post('/api/run', async (req, res) => {
178
- try {
179
- console.log('๐Ÿš€ Esecuzione test in corso...');
180
- const result = await this.runner.runTests({
181
- reporter: 'html',
182
- headed: false,
183
- ...req.body,
184
- });
185
- res.json({
186
- success: result.success,
187
- output: result.output,
188
- error: result.error,
189
- reportUrl: `http://localhost:${this.port}`,
190
- });
191
- if (result.success) {
192
- console.log(`โœ… Test completati! Report disponibile su http://localhost:${this.port}`);
193
- }
194
- }
195
- catch (error) {
196
- console.error('โŒ Errore durante l\'esecuzione dei test:', error.message);
197
- res.status(500).json({
198
- success: false,
199
- error: error.message,
200
- });
201
- }
202
- });
203
- // API per ottenere la lista dei test
204
- this.app.get('/api/tests', async (req, res) => {
205
- try {
206
- const files = await this.runner.getTestFiles();
207
- res.json({
208
- success: true,
209
- count: files.length,
210
- files,
211
- });
212
- }
213
- catch (error) {
214
- res.status(500).json({
215
- success: false,
216
- error: error.message,
217
- });
218
- }
219
- });
220
- // Dashboard per gestire i test
221
- this.app.get('/dashboard', (req, res) => {
222
- res.send(`
223
- <!DOCTYPE html>
224
- <html>
225
- <head>
226
- <title>Playwright Test Dashboard</title>
227
- <style>
228
- body {
229
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
230
- max-width: 1000px;
231
- margin: 0 auto;
232
- padding: 20px;
233
- background: #f5f5f5;
234
- }
235
- .header {
236
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
237
- color: white;
238
- padding: 30px;
239
- border-radius: 10px;
240
- margin-bottom: 20px;
241
- }
242
- .card {
243
- background: white;
244
- padding: 20px;
245
- border-radius: 10px;
246
- margin-bottom: 20px;
247
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
248
- }
249
- .btn {
250
- background: #667eea;
251
- color: white;
252
- border: none;
253
- padding: 12px 24px;
254
- border-radius: 6px;
255
- cursor: pointer;
256
- font-size: 16px;
257
- margin-right: 10px;
258
- }
259
- .btn:hover { background: #5568d3; }
260
- .btn-success { background: #48bb78; }
261
- .btn-success:hover { background: #38a169; }
262
- #output {
263
- background: #1a202c;
264
- color: #e2e8f0;
265
- padding: 20px;
266
- border-radius: 6px;
267
- font-family: 'Courier New', monospace;
268
- white-space: pre-wrap;
269
- max-height: 400px;
270
- overflow-y: auto;
271
- }
272
- </style>
273
- </head>
274
- <body>
275
- <div class="header">
276
- <h1>๐Ÿ“Š Playwright Test Dashboard</h1>
277
- <p>Gestisci e visualizza i tuoi test E2E</p>
278
- </div>
279
-
280
- <div class="card">
281
- <h2>โšก Azioni Rapide</h2>
282
- <button class="btn" onclick="runTests()">โ–ถ๏ธ Esegui Tutti i Test</button>
283
- <button class="btn btn-success" onclick="viewReport()">๐Ÿ“Š Visualizza Report</button>
284
- <button class="btn" onclick="getTestList()">๐Ÿ“‹ Lista Test</button>
285
- </div>
286
-
287
- <div class="card">
288
- <h3>๐Ÿ“ Output</h3>
289
- <div id="output">Pronto per eseguire i test...</div>
290
- </div>
291
-
292
- <div class="card">
293
- <h3>โ„น๏ธ Informazioni</h3>
294
- <p><strong>Progetto:</strong> ${this.projectRoot}</p>
295
- <p><strong>Directory Test:</strong> ${this.testsDir}</p>
296
- <p><strong>Server:</strong> http://localhost:${this.port}</p>
297
- </div>
298
-
299
- <script>
300
- function log(message) {
301
- document.getElementById('output').textContent = message;
302
- }
303
-
304
- async function runTests() {
305
- log('๐Ÿš€ Esecuzione test in corso...\\n\\nAttendi, questo potrebbe richiedere alcuni minuti...');
306
-
307
- try {
308
- const response = await fetch('/api/run', {
309
- method: 'POST',
310
- headers: { 'Content-Type': 'application/json' },
311
- body: JSON.stringify({ reporter: 'html', headed: false })
312
- });
313
-
314
- const result = await response.json();
315
-
316
- if (result.success) {
317
- log('โœ… Test completati con successo!\\n\\n' + result.output);
318
- setTimeout(() => {
319
- window.location.href = '/';
320
- }, 2000);
321
- } else {
322
- log('โŒ Errore durante l\\'esecuzione dei test:\\n\\n' + (result.error || result.output));
323
- }
324
- } catch (error) {
325
- log('โŒ Errore di rete: ' + error.message);
326
- }
327
- }
328
-
329
- function viewReport() {
330
- window.location.href = '/';
331
- }
332
-
333
- async function getTestList() {
334
- log('๐Ÿ“‹ Caricamento lista test...');
335
-
336
- try {
337
- const response = await fetch('/api/tests');
338
- const result = await response.json();
339
-
340
- if (result.success) {
341
- log('โœ… Trovati ' + result.count + ' file di test:\\n\\n' +
342
- result.files.map(f => ' โ€ข ' + f).join('\\n'));
343
- } else {
344
- log('โŒ Errore: ' + result.error);
345
- }
346
- } catch (error) {
347
- log('โŒ Errore di rete: ' + error.message);
348
- }
349
- }
350
- </script>
351
- </body>
352
- </html>
353
- `);
354
- });
355
- }
356
- async start() {
357
- return new Promise((resolve, reject) => {
358
- this.server = this.app.listen(this.port, () => {
359
- console.log(`
360
- โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
361
- โ•‘ โ•‘
362
- โ•‘ ๐ŸŽญ Playwright Report Server ATTIVO โ•‘
363
- โ•‘ โ•‘
364
- โ•‘ ๐Ÿ“Š Report disponibile su: โ•‘
365
- โ•‘ โ†’ http://localhost:${this.port} โ•‘
366
- โ•‘ โ•‘
367
- โ•‘ ๐Ÿ“‹ Dashboard: โ•‘
368
- โ•‘ โ†’ http://localhost:${this.port}/dashboard โ•‘
369
- โ•‘ โ•‘
370
- โ•‘ ๐Ÿ“ Progetto: ${this.projectRoot.slice(-40).padEnd(40)}โ•‘
371
- โ•‘ ๐Ÿ“‚ Test Dir: ${this.testsDir.padEnd(40)} โ•‘
372
- โ•‘ โ•‘
373
- โ•‘ ๐Ÿ’ก Il server rimarrร  attivo in background โ•‘
374
- โ•‘ โ•‘
375
- โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
376
- `);
377
- resolve();
378
- }).on('error', (error) => {
379
- if (error.code === 'EADDRINUSE') {
380
- console.log(`
381
- โš ๏ธ La porta ${this.port} รจ giร  in uso.
382
-
383
- Il server dei report รจ probabilmente giร  attivo.
384
- Accedi a: http://localhost:${this.port}
385
-
386
- Per usare una porta diversa:
387
- npx playwright-daemon --port <numero>
388
- `);
389
- resolve(); // Non รจ un errore fatale
390
- }
391
- else {
392
- reject(error);
393
- }
394
- });
395
- });
396
- }
397
- stop() {
398
- if (this.server) {
399
- this.server.close();
400
- console.log('\n๐Ÿ‘‹ Report server fermato\n');
401
- }
402
- }
403
- }
404
- exports.ReportDaemon = ReportDaemon;
405
- // Export per uso programmatico
406
- function createDaemon(options = {}) {
407
- return new ReportDaemon(options);
408
- }
409
- //# sourceMappingURL=report-daemon.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"report-daemon.js","sourceRoot":"","sources":["../src/report-daemon.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts DELETED
@@ -1,18 +0,0 @@
1
- import express from 'express';
2
- export interface ServerOptions {
3
- port?: number;
4
- projectRoot?: string;
5
- testsDir?: string;
6
- }
7
- export declare class PlaywrightServer {
8
- private app;
9
- private port;
10
- private testRunner;
11
- private reportProcess;
12
- constructor(options?: ServerOptions);
13
- private setupMiddleware;
14
- private setupRoutes;
15
- start(): void;
16
- getApp(): express.Application;
17
- }
18
- //# sourceMappingURL=server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,OAA8B,MAAM,SAAS,CAAC;AAIrD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,aAAa,CAAa;gBAEtB,OAAO,GAAE,aAAkB;IAYvC,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,WAAW;IAuFZ,KAAK,IAAI,IAAI;IAYb,MAAM,IAAI,OAAO,CAAC,WAAW;CAGrC"}
package/dist/server.js DELETED
@@ -1,127 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PlaywrightServer = void 0;
7
- const express_1 = __importDefault(require("express"));
8
- const cors_1 = __importDefault(require("cors"));
9
- const test_runner_1 = require("./test-runner");
10
- class PlaywrightServer {
11
- app;
12
- port;
13
- testRunner;
14
- reportProcess = null;
15
- constructor(options = {}) {
16
- this.app = (0, express_1.default)();
17
- this.port = options.port || 3000;
18
- this.testRunner = new test_runner_1.PlaywrightTestRunner({
19
- projectRoot: options.projectRoot,
20
- testsDir: options.testsDir,
21
- });
22
- this.setupMiddleware();
23
- this.setupRoutes();
24
- }
25
- setupMiddleware() {
26
- this.app.use((0, cors_1.default)());
27
- this.app.use(express_1.default.json());
28
- }
29
- setupRoutes() {
30
- this.app.get('/health', (req, res) => {
31
- res.json({ status: 'ok', service: 'playwright-test-runner' });
32
- });
33
- this.app.get('/tests', async (req, res) => {
34
- try {
35
- const files = await this.testRunner.getTestFiles();
36
- res.json({
37
- success: true,
38
- count: files.length,
39
- files,
40
- });
41
- }
42
- catch (error) {
43
- res.status(500).json({
44
- success: false,
45
- error: error.message,
46
- });
47
- }
48
- });
49
- this.app.post('/run', async (req, res) => {
50
- try {
51
- const options = {
52
- reporter: req.body.reporter || 'html',
53
- headed: req.body.headed || false,
54
- };
55
- const result = await this.testRunner.runTests(options);
56
- res.json({
57
- success: result.success,
58
- output: result.output,
59
- error: result.error,
60
- reportPath: result.reportPath,
61
- });
62
- }
63
- catch (error) {
64
- res.status(500).json({
65
- success: false,
66
- error: error.message,
67
- });
68
- }
69
- });
70
- this.app.post('/report/show', async (req, res) => {
71
- try {
72
- if (this.reportProcess) {
73
- return res.json({
74
- success: true,
75
- message: 'Report giร  in esecuzione',
76
- url: 'http://localhost:9323',
77
- });
78
- }
79
- const { url, process } = await this.testRunner.showReport();
80
- this.reportProcess = process;
81
- res.json({
82
- success: true,
83
- message: 'Report UI avviato',
84
- url,
85
- });
86
- }
87
- catch (error) {
88
- res.status(500).json({
89
- success: false,
90
- error: error.message,
91
- });
92
- }
93
- });
94
- this.app.post('/report/stop', (req, res) => {
95
- if (this.reportProcess) {
96
- this.reportProcess.kill();
97
- this.reportProcess = null;
98
- res.json({
99
- success: true,
100
- message: 'Report UI fermato',
101
- });
102
- }
103
- else {
104
- res.json({
105
- success: false,
106
- message: 'Nessun report in esecuzione',
107
- });
108
- }
109
- });
110
- }
111
- start() {
112
- this.app.listen(this.port, () => {
113
- console.log(`๐ŸŽญ Playwright Test Runner server in esecuzione su http://localhost:${this.port}`);
114
- console.log(`\nEndpoint disponibili:`);
115
- console.log(` GET /health - Health check`);
116
- console.log(` GET /tests - Lista dei test disponibili`);
117
- console.log(` POST /run - Esegui i test`);
118
- console.log(` POST /report/show - Mostra report UI`);
119
- console.log(` POST /report/stop - Ferma report UI`);
120
- });
121
- }
122
- getApp() {
123
- return this.app;
124
- }
125
- }
126
- exports.PlaywrightServer = PlaywrightServer;
127
- //# sourceMappingURL=server.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/web-cli.d.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=web-cli.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"web-cli.d.ts","sourceRoot":"","sources":["../src/web-cli.ts"],"names":[],"mappings":""}
package/dist/web-cli.js DELETED
@@ -1,64 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- const web_ui_1 = require("./web-ui");
5
- const args = process.argv.slice(2);
6
- function parseArgs() {
7
- // Usa INIT_CWD (directory da cui npm/npx รจ stato chiamato) invece di cwd
8
- const options = {
9
- port: 3001,
10
- projectRoot: process.env.INIT_CWD || process.cwd(),
11
- testsDir: 'tests',
12
- };
13
- for (let i = 0; i < args.length; i++) {
14
- switch (args[i]) {
15
- case '--port':
16
- case '-p':
17
- options.port = Number(args[++i]);
18
- break;
19
- case '--project':
20
- case '-r':
21
- options.projectRoot = args[++i];
22
- break;
23
- case '--tests-dir':
24
- case '-t':
25
- options.testsDir = args[++i];
26
- break;
27
- case '--help':
28
- case '-h':
29
- console.log(`
30
- Playwright Test Runner - Web UI
31
-
32
- Usage:
33
- playwright-ui [options]
34
-
35
- Options:
36
- -p, --port <port> Porta del server (default: 3001)
37
- -r, --project <path> Root del progetto (default: current directory)
38
- -t, --tests-dir <dir> Cartella dei test (default: tests)
39
- -h, --help Mostra questo messaggio
40
-
41
- Esempi:
42
- playwright-ui
43
- playwright-ui --port 4000
44
- playwright-ui --project /path/to/project --tests-dir e2e
45
-
46
- Questo comando:
47
- 1. Avvia un server web con interfaccia grafica
48
- 2. Apri http://localhost:3001 nel browser
49
- 3. Lancia i test con un click dal browser
50
- `);
51
- process.exit(0);
52
- }
53
- }
54
- return options;
55
- }
56
- const options = parseArgs();
57
- const webUI = new web_ui_1.PlaywrightWebUI(options);
58
- webUI.start();
59
- // Keep process alive and handle graceful shutdown
60
- process.on('SIGINT', () => {
61
- console.log('\n\n๐Ÿ‘‹ Chiusura server...');
62
- process.exit(0);
63
- });
64
- //# sourceMappingURL=web-cli.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"web-cli.js","sourceRoot":"","sources":["../src/web-cli.ts"],"names":[],"mappings":";;;AAEA,qCAA2C;AAE3C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,SAAS,SAAS;IAChB,yEAAyE;IACzE,MAAM,OAAO,GAAQ;QACnB,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE;QAClD,QAAQ,EAAE,OAAO;KAClB,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACjC,MAAM;YACR,KAAK,WAAW,CAAC;YACjB,KAAK,IAAI;gBACP,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChC,MAAM;YACR,KAAK,aAAa,CAAC;YACnB,KAAK,IAAI;gBACP,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7B,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;SAqBX,CAAC,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;AAC5B,MAAM,KAAK,GAAG,IAAI,wBAAe,CAAC,OAAO,CAAC,CAAC;AAC3C,KAAK,CAAC,KAAK,EAAE,CAAC;AAEd,kDAAkD;AAClD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/dist/web-ui.d.ts DELETED
@@ -1,19 +0,0 @@
1
- import express from 'express';
2
- export interface WebUIOptions {
3
- port?: number;
4
- projectRoot?: string;
5
- testsDir?: string;
6
- }
7
- export declare class PlaywrightWebUI {
8
- private app;
9
- private port;
10
- private testRunner;
11
- private reportProcess;
12
- constructor(options?: WebUIOptions);
13
- private setupMiddleware;
14
- private setupRoutes;
15
- start(): void;
16
- getApp(): express.Application;
17
- }
18
- export declare function createWebUI(options?: WebUIOptions): PlaywrightWebUI;
19
- //# sourceMappingURL=web-ui.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"web-ui.d.ts","sourceRoot":"","sources":["../src/web-ui.ts"],"names":[],"mappings":"AAAA,OAAO,OAA8B,MAAM,SAAS,CAAC;AAKrD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,aAAa,CAAa;gBAEtB,OAAO,GAAE,YAAiB;IAYtC,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,WAAW;IA6FZ,KAAK,IAAI,IAAI;IAYb,MAAM,IAAI,OAAO,CAAC,WAAW;CAGrC;AAED,wBAAgB,WAAW,CAAC,OAAO,GAAE,YAAiB,mBAErD"}