test-proxy-recorder 0.1.2 → 0.1.4
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/dist/index-De4mgziH.d.cts +96 -0
- package/dist/index-De4mgziH.d.ts +96 -0
- package/dist/index.cjs +121 -41
- package/dist/index.d.cts +7 -48
- package/dist/index.d.ts +7 -48
- package/dist/index.mjs +119 -41
- package/dist/playwright/index.cjs +11 -4
- package/dist/playwright/index.d.cts +3 -50
- package/dist/playwright/index.d.ts +3 -50
- package/dist/playwright/index.mjs +11 -4
- package/dist/proxy.js +115 -37
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import http from 'http';
|
|
3
|
+
import https from 'https';
|
|
3
4
|
import httpProxy from 'http-proxy';
|
|
4
5
|
import { WebSocket, WebSocketServer } from 'ws';
|
|
5
6
|
import path from 'path';
|
|
7
|
+
import filenamify from 'filenamify';
|
|
6
8
|
|
|
7
9
|
// src/ProxyServer.ts
|
|
8
10
|
|
|
@@ -38,6 +40,24 @@ async function saveRecordingSession(recordingsDir, session) {
|
|
|
38
40
|
`Saved ${session.recordings.length} HTTP recordings and ${session.websocketRecordings?.length || 0} WebSocket recordings to ${filePath}`
|
|
39
41
|
);
|
|
40
42
|
}
|
|
43
|
+
var QUERY_HASH_LENGTH = 8;
|
|
44
|
+
function getReqID(req) {
|
|
45
|
+
const urlParts = req.url.split("?");
|
|
46
|
+
const pathname = urlParts[0];
|
|
47
|
+
const query = urlParts[1] || "";
|
|
48
|
+
const pathPart = pathname === "/" ? "root" : pathname.slice(1);
|
|
49
|
+
const normalizedPath = filenamify(pathPart, { replacement: "_" });
|
|
50
|
+
const queryHash = generateQueryHash(query);
|
|
51
|
+
const filename = `${req.method}_${normalizedPath}${queryHash}.json`;
|
|
52
|
+
return filenamify(filename, { replacement: "_" });
|
|
53
|
+
}
|
|
54
|
+
function generateQueryHash(query) {
|
|
55
|
+
if (!query) {
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
58
|
+
const hash = Buffer.from(query).toString("base64").replaceAll(/[^a-zA-Z0-9]/g, "").slice(0, Math.max(0, QUERY_HASH_LENGTH));
|
|
59
|
+
return `_${hash}`;
|
|
60
|
+
}
|
|
41
61
|
|
|
42
62
|
// src/utils/httpHelpers.ts
|
|
43
63
|
var CONTENT_TYPE_JSON = "application/json";
|
|
@@ -53,28 +73,6 @@ function sendJsonResponse(res, statusCode, data) {
|
|
|
53
73
|
res.end(JSON.stringify(data));
|
|
54
74
|
}
|
|
55
75
|
|
|
56
|
-
// src/utils/requestKeyGenerator.ts
|
|
57
|
-
var QUERY_HASH_LENGTH = 8;
|
|
58
|
-
function generateRequestKey(req) {
|
|
59
|
-
const urlParts = req.url.split("?");
|
|
60
|
-
const pathname = urlParts[0];
|
|
61
|
-
const query = urlParts[1] || "";
|
|
62
|
-
const normalizedPath = normalizePathname(pathname);
|
|
63
|
-
const queryHash = generateQueryHash(query);
|
|
64
|
-
return `${req.method}_${normalizedPath}${queryHash}.json`;
|
|
65
|
-
}
|
|
66
|
-
function normalizePathname(pathname) {
|
|
67
|
-
const normalized = pathname.replaceAll("/", "_").replace(/^_/, "");
|
|
68
|
-
return normalized || "root";
|
|
69
|
-
}
|
|
70
|
-
function generateQueryHash(query) {
|
|
71
|
-
if (!query) {
|
|
72
|
-
return "";
|
|
73
|
-
}
|
|
74
|
-
const hash = Buffer.from(query).toString("base64").replaceAll(/[^a-zA-Z0-9]/g, "").slice(0, Math.max(0, QUERY_HASH_LENGTH));
|
|
75
|
-
return `_${hash}`;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
76
|
// src/ProxyServer.ts
|
|
79
77
|
var ProxyServer = class {
|
|
80
78
|
targets;
|
|
@@ -86,6 +84,10 @@ var ProxyServer = class {
|
|
|
86
84
|
proxy;
|
|
87
85
|
currentSession;
|
|
88
86
|
recordingsDir;
|
|
87
|
+
requestSequenceMap;
|
|
88
|
+
// Track sequence per request key
|
|
89
|
+
replaySequenceMap;
|
|
90
|
+
// Track replay position per request key
|
|
89
91
|
constructor(targets, recordingsDir) {
|
|
90
92
|
this.targets = targets;
|
|
91
93
|
this.currentTargetIndex = 0;
|
|
@@ -95,6 +97,8 @@ var ProxyServer = class {
|
|
|
95
97
|
this.modeTimeout = null;
|
|
96
98
|
this.currentSession = null;
|
|
97
99
|
this.recordingsDir = recordingsDir;
|
|
100
|
+
this.requestSequenceMap = /* @__PURE__ */ new Map();
|
|
101
|
+
this.replaySequenceMap = /* @__PURE__ */ new Map();
|
|
98
102
|
this.proxy = httpProxy.createProxyServer({
|
|
99
103
|
secure: false,
|
|
100
104
|
changeOrigin: true
|
|
@@ -133,10 +137,19 @@ var ProxyServer = class {
|
|
|
133
137
|
res.end(JSON.stringify({ error: "Proxy error", message: err.message }));
|
|
134
138
|
}
|
|
135
139
|
handleProxyResponse(proxyRes, req) {
|
|
140
|
+
this.addCorsHeaders(proxyRes, req);
|
|
136
141
|
if (this.mode === Modes.record && this.recordingId) {
|
|
137
142
|
this.recordResponse(req, proxyRes);
|
|
138
143
|
}
|
|
139
144
|
}
|
|
145
|
+
addCorsHeaders(proxyRes, req) {
|
|
146
|
+
const origin = req.headers.origin;
|
|
147
|
+
proxyRes.headers["access-control-allow-origin"] = origin || "*";
|
|
148
|
+
proxyRes.headers["access-control-allow-credentials"] = "true";
|
|
149
|
+
proxyRes.headers["access-control-allow-headers"] = req.headers["access-control-request-headers"] || "Origin, X-Requested-With, Content-Type, Accept, Authorization";
|
|
150
|
+
proxyRes.headers["access-control-allow-methods"] = "GET, POST, PUT, DELETE, PATCH, OPTIONS";
|
|
151
|
+
proxyRes.headers["access-control-expose-headers"] = "*";
|
|
152
|
+
}
|
|
140
153
|
getTarget() {
|
|
141
154
|
const target = this.targets[this.currentTargetIndex];
|
|
142
155
|
this.currentTargetIndex = (this.currentTargetIndex + 1) % this.targets.length;
|
|
@@ -200,6 +213,7 @@ var ProxyServer = class {
|
|
|
200
213
|
this.recordingId = null;
|
|
201
214
|
this.replayId = null;
|
|
202
215
|
this.currentSession = null;
|
|
216
|
+
clearTimeout(this.modeTimeout || 0);
|
|
203
217
|
console.log("Switched to transparent mode");
|
|
204
218
|
}
|
|
205
219
|
switchToRecordMode(id) {
|
|
@@ -210,6 +224,7 @@ var ProxyServer = class {
|
|
|
210
224
|
this.recordingId = id;
|
|
211
225
|
this.replayId = null;
|
|
212
226
|
this.currentSession = { id, recordings: [], websocketRecordings: [] };
|
|
227
|
+
this.requestSequenceMap.clear();
|
|
213
228
|
console.log(`Switched to record mode with ID: ${id}`);
|
|
214
229
|
}
|
|
215
230
|
switchToReplayMode(id) {
|
|
@@ -220,6 +235,7 @@ var ProxyServer = class {
|
|
|
220
235
|
this.replayId = id;
|
|
221
236
|
this.recordingId = null;
|
|
222
237
|
this.currentSession = null;
|
|
238
|
+
this.replaySequenceMap.clear();
|
|
223
239
|
console.log(`Switched to replay mode with ID: ${id}`);
|
|
224
240
|
}
|
|
225
241
|
setupModeTimeout(timeout) {
|
|
@@ -250,7 +266,9 @@ var ProxyServer = class {
|
|
|
250
266
|
if (!this.currentSession) {
|
|
251
267
|
return;
|
|
252
268
|
}
|
|
253
|
-
const key =
|
|
269
|
+
const key = getReqID(req);
|
|
270
|
+
const currentSequence = this.requestSequenceMap.get(key) || 0;
|
|
271
|
+
this.requestSequenceMap.set(key, currentSequence + 1);
|
|
254
272
|
const record = {
|
|
255
273
|
request: {
|
|
256
274
|
method: req.method,
|
|
@@ -259,7 +277,8 @@ var ProxyServer = class {
|
|
|
259
277
|
body: body || null
|
|
260
278
|
},
|
|
261
279
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
262
|
-
key
|
|
280
|
+
key,
|
|
281
|
+
sequence: currentSequence
|
|
263
282
|
};
|
|
264
283
|
this.currentSession.recordings.push(record);
|
|
265
284
|
}
|
|
@@ -267,8 +286,10 @@ var ProxyServer = class {
|
|
|
267
286
|
if (!this.currentSession) {
|
|
268
287
|
return;
|
|
269
288
|
}
|
|
270
|
-
const key =
|
|
271
|
-
const record = this.currentSession.recordings.
|
|
289
|
+
const key = getReqID(req);
|
|
290
|
+
const record = this.currentSession.recordings.findLast(
|
|
291
|
+
(r) => r.key === key && !r.response
|
|
292
|
+
);
|
|
272
293
|
if (!record) {
|
|
273
294
|
console.error("Request record not found for response:", key);
|
|
274
295
|
return;
|
|
@@ -289,21 +310,35 @@ var ProxyServer = class {
|
|
|
289
310
|
});
|
|
290
311
|
}
|
|
291
312
|
async handleReplayRequest(req, res) {
|
|
292
|
-
const key =
|
|
313
|
+
const key = getReqID(req);
|
|
293
314
|
const filePath = getRecordingPath(this.recordingsDir, this.replayId);
|
|
294
315
|
try {
|
|
295
316
|
const session = await loadRecordingSession(filePath);
|
|
296
|
-
const
|
|
317
|
+
const currentSequence = this.replaySequenceMap.get(key) || 0;
|
|
318
|
+
const record = session.recordings.find(
|
|
319
|
+
(r) => r.key === key && r.sequence === currentSequence
|
|
320
|
+
);
|
|
297
321
|
if (!record) {
|
|
298
|
-
throw new Error(
|
|
322
|
+
throw new Error(
|
|
323
|
+
`No recording found for ${key} with sequence ${currentSequence}`
|
|
324
|
+
);
|
|
299
325
|
}
|
|
300
326
|
if (!record.response) {
|
|
301
327
|
throw new Error("No response recorded for this request");
|
|
302
328
|
}
|
|
329
|
+
this.replaySequenceMap.set(key, currentSequence + 1);
|
|
303
330
|
const { statusCode, headers, body } = record.response;
|
|
304
|
-
|
|
331
|
+
const origin = req.headers.origin;
|
|
332
|
+
const responseHeaders = {
|
|
333
|
+
...headers,
|
|
334
|
+
"access-control-allow-origin": origin || "*",
|
|
335
|
+
"access-control-allow-credentials": "true"
|
|
336
|
+
};
|
|
337
|
+
res.writeHead(statusCode, responseHeaders);
|
|
305
338
|
res.end(body);
|
|
306
|
-
console.log(
|
|
339
|
+
console.log(
|
|
340
|
+
`Replayed: ${req.method} ${req.url} (sequence: ${currentSequence})`
|
|
341
|
+
);
|
|
307
342
|
} catch (error) {
|
|
308
343
|
this.handleReplayError(res, error, key, filePath);
|
|
309
344
|
}
|
|
@@ -319,6 +354,9 @@ var ProxyServer = class {
|
|
|
319
354
|
});
|
|
320
355
|
}
|
|
321
356
|
async handleRequest(req, res) {
|
|
357
|
+
if (req.method === "OPTIONS") {
|
|
358
|
+
return this.handleCorsPreflightRequest(req, res);
|
|
359
|
+
}
|
|
322
360
|
if (req.url === CONTROL_ENDPOINT) {
|
|
323
361
|
return this.handleControlRequest(req, res);
|
|
324
362
|
}
|
|
@@ -327,23 +365,63 @@ var ProxyServer = class {
|
|
|
327
365
|
}
|
|
328
366
|
await this.handleProxyRequest(req, res);
|
|
329
367
|
}
|
|
368
|
+
handleCorsPreflightRequest(req, res) {
|
|
369
|
+
const origin = req.headers.origin;
|
|
370
|
+
res.writeHead(HTTP_STATUS_OK, {
|
|
371
|
+
"Access-Control-Allow-Origin": origin || "*",
|
|
372
|
+
"Access-Control-Allow-Credentials": "true",
|
|
373
|
+
"Access-Control-Allow-Headers": req.headers["access-control-request-headers"] || "Origin, X-Requested-With, Content-Type, Accept, Authorization",
|
|
374
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
375
|
+
"Access-Control-Max-Age": "86400"
|
|
376
|
+
// 24 hours
|
|
377
|
+
});
|
|
378
|
+
res.end();
|
|
379
|
+
}
|
|
330
380
|
async handleProxyRequest(req, res) {
|
|
331
381
|
const target = this.getTarget();
|
|
332
382
|
console.log(`[${this.mode}] ${req.method} ${req.url} -> ${target}`);
|
|
333
383
|
if (this.mode === Modes.record) {
|
|
334
|
-
await this.
|
|
384
|
+
await this.bufferAndProxyRequest(req, res, target);
|
|
385
|
+
} else {
|
|
386
|
+
this.proxy.web(req, res, { target });
|
|
335
387
|
}
|
|
336
|
-
this.proxy.web(req, res, { target });
|
|
337
388
|
}
|
|
338
|
-
async
|
|
389
|
+
async bufferAndProxyRequest(req, res, target) {
|
|
339
390
|
const chunks = [];
|
|
340
391
|
req.on("data", (chunk) => {
|
|
341
392
|
chunks.push(chunk);
|
|
342
393
|
});
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
await this.saveRequestRecord(req, body);
|
|
394
|
+
await new Promise((resolve) => {
|
|
395
|
+
req.on("end", () => resolve());
|
|
346
396
|
});
|
|
397
|
+
const body = Buffer.concat(chunks).toString("utf8");
|
|
398
|
+
await this.saveRequestRecord(req, body);
|
|
399
|
+
const targetUrl = new URL(target);
|
|
400
|
+
const isHttps = targetUrl.protocol === "https:";
|
|
401
|
+
const requestModule = isHttps ? https : http;
|
|
402
|
+
const defaultPort = isHttps ? 443 : 80;
|
|
403
|
+
const proxyReq = requestModule.request(
|
|
404
|
+
{
|
|
405
|
+
hostname: targetUrl.hostname,
|
|
406
|
+
port: targetUrl.port || defaultPort,
|
|
407
|
+
path: req.url,
|
|
408
|
+
method: req.method,
|
|
409
|
+
headers: req.headers
|
|
410
|
+
},
|
|
411
|
+
(proxyRes) => {
|
|
412
|
+
this.addCorsHeaders(proxyRes, req);
|
|
413
|
+
this.recordResponse(req, proxyRes);
|
|
414
|
+
res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
|
|
415
|
+
proxyRes.pipe(res);
|
|
416
|
+
}
|
|
417
|
+
);
|
|
418
|
+
proxyReq.on("error", (err) => {
|
|
419
|
+
this.handleProxyError(err, req, res);
|
|
420
|
+
});
|
|
421
|
+
if (chunks.length > 0) {
|
|
422
|
+
proxyReq.write(Buffer.concat(chunks));
|
|
423
|
+
}
|
|
424
|
+
proxyReq.end();
|
|
347
425
|
}
|
|
348
426
|
handleUpgrade(req, socket, head) {
|
|
349
427
|
if (this.mode === Modes.replay) {
|
|
@@ -546,15 +624,15 @@ function generateSessionId(testInfo) {
|
|
|
546
624
|
}
|
|
547
625
|
async function startRecording(testInfo) {
|
|
548
626
|
const sessionId = generateSessionId(testInfo);
|
|
549
|
-
await setProxyMode(
|
|
627
|
+
await setProxyMode(Modes.record, sessionId);
|
|
550
628
|
}
|
|
551
629
|
async function startReplay(testInfo) {
|
|
552
630
|
const sessionId = generateSessionId(testInfo);
|
|
553
|
-
await setProxyMode(
|
|
631
|
+
await setProxyMode(Modes.replay, sessionId);
|
|
554
632
|
}
|
|
555
633
|
async function stopProxy(testInfo) {
|
|
556
634
|
const sessionId = generateSessionId(testInfo);
|
|
557
|
-
await setProxyMode(
|
|
635
|
+
await setProxyMode(Modes.transparent, sessionId);
|
|
558
636
|
}
|
|
559
637
|
var playwrightProxy = {
|
|
560
638
|
/**
|
|
@@ -573,7 +651,7 @@ var playwrightProxy = {
|
|
|
573
651
|
*/
|
|
574
652
|
async after(testInfo) {
|
|
575
653
|
const sessionId = generateSessionId(testInfo);
|
|
576
|
-
await setProxyMode(
|
|
654
|
+
await setProxyMode(Modes.transparent, sessionId);
|
|
577
655
|
}
|
|
578
656
|
};
|
|
579
657
|
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// src/types.ts
|
|
4
|
+
var Modes = {
|
|
5
|
+
transparent: "transparent",
|
|
6
|
+
record: "record",
|
|
7
|
+
replay: "replay"
|
|
8
|
+
};
|
|
9
|
+
|
|
3
10
|
// src/playwright/index.ts
|
|
4
11
|
var INTERNAL_API_URL = process.env.INTERNAL_API_URL || "http://localhost:8100";
|
|
5
12
|
async function setProxyMode(mode, sessionId, timeout) {
|
|
@@ -31,15 +38,15 @@ function generateSessionId(testInfo) {
|
|
|
31
38
|
}
|
|
32
39
|
async function startRecording(testInfo) {
|
|
33
40
|
const sessionId = generateSessionId(testInfo);
|
|
34
|
-
await setProxyMode(
|
|
41
|
+
await setProxyMode(Modes.record, sessionId);
|
|
35
42
|
}
|
|
36
43
|
async function startReplay(testInfo) {
|
|
37
44
|
const sessionId = generateSessionId(testInfo);
|
|
38
|
-
await setProxyMode(
|
|
45
|
+
await setProxyMode(Modes.replay, sessionId);
|
|
39
46
|
}
|
|
40
47
|
async function stopProxy(testInfo) {
|
|
41
48
|
const sessionId = generateSessionId(testInfo);
|
|
42
|
-
await setProxyMode(
|
|
49
|
+
await setProxyMode(Modes.transparent, sessionId);
|
|
43
50
|
}
|
|
44
51
|
var playwrightProxy = {
|
|
45
52
|
/**
|
|
@@ -58,7 +65,7 @@ var playwrightProxy = {
|
|
|
58
65
|
*/
|
|
59
66
|
async after(testInfo) {
|
|
60
67
|
const sessionId = generateSessionId(testInfo);
|
|
61
|
-
await setProxyMode(
|
|
68
|
+
await setProxyMode(Modes.transparent, sessionId);
|
|
62
69
|
}
|
|
63
70
|
};
|
|
64
71
|
|
|
@@ -1,50 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
type PlaywrightTestInfo = Pick<TestInfo, 'title'>;
|
|
5
|
-
/**
|
|
6
|
-
* Set the proxy mode for a given session
|
|
7
|
-
* @param mode - The proxy mode to set (recording, replay, transparent)
|
|
8
|
-
* @param sessionId - Unique identifier for the session
|
|
9
|
-
* @param timeout - Optional timeout in milliseconds
|
|
10
|
-
*/
|
|
11
|
-
declare function setProxyMode(mode: ProxyMode, sessionId: string, timeout?: number): Promise<void>;
|
|
12
|
-
/**
|
|
13
|
-
* Generate a session ID from test info
|
|
14
|
-
* @param testInfo - Playwright test info object
|
|
15
|
-
*/
|
|
16
|
-
declare function generateSessionId(testInfo: PlaywrightTestInfo): string;
|
|
17
|
-
/**
|
|
18
|
-
* Start recording for a test
|
|
19
|
-
* @param testInfo - Playwright test info object
|
|
20
|
-
*/
|
|
21
|
-
declare function startRecording(testInfo: PlaywrightTestInfo): Promise<void>;
|
|
22
|
-
/**
|
|
23
|
-
* Start replay for a test
|
|
24
|
-
* @param testInfo - Playwright test info object
|
|
25
|
-
*/
|
|
26
|
-
declare function startReplay(testInfo: PlaywrightTestInfo): Promise<void>;
|
|
27
|
-
/**
|
|
28
|
-
* Stop recording/replay and return to transparent mode
|
|
29
|
-
* @param testInfo - Playwright test info object
|
|
30
|
-
*/
|
|
31
|
-
declare function stopProxy(testInfo: PlaywrightTestInfo): Promise<void>;
|
|
32
|
-
/**
|
|
33
|
-
* Playwright test fixture helper for managing proxy mode
|
|
34
|
-
* Use this in beforeEach/afterEach hooks
|
|
35
|
-
*/
|
|
36
|
-
declare const playwrightProxy: {
|
|
37
|
-
/**
|
|
38
|
-
* Setup before test - sets the proxy mode
|
|
39
|
-
* @param testInfo - Playwright test info object
|
|
40
|
-
* @param mode - The proxy mode to use for this test
|
|
41
|
-
*/
|
|
42
|
-
before(testInfo: PlaywrightTestInfo, mode: ProxyMode): Promise<void>;
|
|
43
|
-
/**
|
|
44
|
-
* Cleanup after test - returns to transparent mode
|
|
45
|
-
* @param testInfo - Playwright test info object
|
|
46
|
-
*/
|
|
47
|
-
after(testInfo: PlaywrightTestInfo): Promise<void>;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export { type PlaywrightTestInfo, type ProxyMode, generateSessionId, playwrightProxy, setProxyMode, startRecording, startReplay, stopProxy };
|
|
1
|
+
import '@playwright/test';
|
|
2
|
+
export { P as PlaywrightTestInfo, g as generateSessionId, p as playwrightProxy, s as setProxyMode, b as startRecording, c as startReplay, d as stopProxy } from '../index-De4mgziH.cjs';
|
|
3
|
+
import 'node:http';
|
|
@@ -1,50 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
type PlaywrightTestInfo = Pick<TestInfo, 'title'>;
|
|
5
|
-
/**
|
|
6
|
-
* Set the proxy mode for a given session
|
|
7
|
-
* @param mode - The proxy mode to set (recording, replay, transparent)
|
|
8
|
-
* @param sessionId - Unique identifier for the session
|
|
9
|
-
* @param timeout - Optional timeout in milliseconds
|
|
10
|
-
*/
|
|
11
|
-
declare function setProxyMode(mode: ProxyMode, sessionId: string, timeout?: number): Promise<void>;
|
|
12
|
-
/**
|
|
13
|
-
* Generate a session ID from test info
|
|
14
|
-
* @param testInfo - Playwright test info object
|
|
15
|
-
*/
|
|
16
|
-
declare function generateSessionId(testInfo: PlaywrightTestInfo): string;
|
|
17
|
-
/**
|
|
18
|
-
* Start recording for a test
|
|
19
|
-
* @param testInfo - Playwright test info object
|
|
20
|
-
*/
|
|
21
|
-
declare function startRecording(testInfo: PlaywrightTestInfo): Promise<void>;
|
|
22
|
-
/**
|
|
23
|
-
* Start replay for a test
|
|
24
|
-
* @param testInfo - Playwright test info object
|
|
25
|
-
*/
|
|
26
|
-
declare function startReplay(testInfo: PlaywrightTestInfo): Promise<void>;
|
|
27
|
-
/**
|
|
28
|
-
* Stop recording/replay and return to transparent mode
|
|
29
|
-
* @param testInfo - Playwright test info object
|
|
30
|
-
*/
|
|
31
|
-
declare function stopProxy(testInfo: PlaywrightTestInfo): Promise<void>;
|
|
32
|
-
/**
|
|
33
|
-
* Playwright test fixture helper for managing proxy mode
|
|
34
|
-
* Use this in beforeEach/afterEach hooks
|
|
35
|
-
*/
|
|
36
|
-
declare const playwrightProxy: {
|
|
37
|
-
/**
|
|
38
|
-
* Setup before test - sets the proxy mode
|
|
39
|
-
* @param testInfo - Playwright test info object
|
|
40
|
-
* @param mode - The proxy mode to use for this test
|
|
41
|
-
*/
|
|
42
|
-
before(testInfo: PlaywrightTestInfo, mode: ProxyMode): Promise<void>;
|
|
43
|
-
/**
|
|
44
|
-
* Cleanup after test - returns to transparent mode
|
|
45
|
-
* @param testInfo - Playwright test info object
|
|
46
|
-
*/
|
|
47
|
-
after(testInfo: PlaywrightTestInfo): Promise<void>;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export { type PlaywrightTestInfo, type ProxyMode, generateSessionId, playwrightProxy, setProxyMode, startRecording, startReplay, stopProxy };
|
|
1
|
+
import '@playwright/test';
|
|
2
|
+
export { P as PlaywrightTestInfo, g as generateSessionId, p as playwrightProxy, s as setProxyMode, b as startRecording, c as startReplay, d as stopProxy } from '../index-De4mgziH.js';
|
|
3
|
+
import 'node:http';
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var Modes = {
|
|
3
|
+
transparent: "transparent",
|
|
4
|
+
record: "record",
|
|
5
|
+
replay: "replay"
|
|
6
|
+
};
|
|
7
|
+
|
|
1
8
|
// src/playwright/index.ts
|
|
2
9
|
var INTERNAL_API_URL = process.env.INTERNAL_API_URL || "http://localhost:8100";
|
|
3
10
|
async function setProxyMode(mode, sessionId, timeout) {
|
|
@@ -29,15 +36,15 @@ function generateSessionId(testInfo) {
|
|
|
29
36
|
}
|
|
30
37
|
async function startRecording(testInfo) {
|
|
31
38
|
const sessionId = generateSessionId(testInfo);
|
|
32
|
-
await setProxyMode(
|
|
39
|
+
await setProxyMode(Modes.record, sessionId);
|
|
33
40
|
}
|
|
34
41
|
async function startReplay(testInfo) {
|
|
35
42
|
const sessionId = generateSessionId(testInfo);
|
|
36
|
-
await setProxyMode(
|
|
43
|
+
await setProxyMode(Modes.replay, sessionId);
|
|
37
44
|
}
|
|
38
45
|
async function stopProxy(testInfo) {
|
|
39
46
|
const sessionId = generateSessionId(testInfo);
|
|
40
|
-
await setProxyMode(
|
|
47
|
+
await setProxyMode(Modes.transparent, sessionId);
|
|
41
48
|
}
|
|
42
49
|
var playwrightProxy = {
|
|
43
50
|
/**
|
|
@@ -56,7 +63,7 @@ var playwrightProxy = {
|
|
|
56
63
|
*/
|
|
57
64
|
async after(testInfo) {
|
|
58
65
|
const sessionId = generateSessionId(testInfo);
|
|
59
|
-
await setProxyMode(
|
|
66
|
+
await setProxyMode(Modes.transparent, sessionId);
|
|
60
67
|
}
|
|
61
68
|
};
|
|
62
69
|
|