test-proxy-recorder 0.1.4 → 0.1.6
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 +345 -152
- package/dist/{index-De4mgziH.d.cts → index-CBjvm5rb.d.cts} +5 -1
- package/dist/{index-De4mgziH.d.ts → index-CBjvm5rb.d.ts} +5 -1
- package/dist/index.cjs +210 -35
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.mjs +210 -35
- package/dist/playwright/index.cjs +39 -3
- package/dist/playwright/index.d.cts +1 -1
- package/dist/playwright/index.d.ts +1 -1
- package/dist/playwright/index.mjs +39 -3
- package/dist/proxy.js +173 -34
- package/package.json +8 -3
package/dist/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ var Modes = {
|
|
|
35
35
|
};
|
|
36
36
|
var JSON_INDENT_SPACES = 2;
|
|
37
37
|
function getRecordingPath(recordingsDir, id) {
|
|
38
|
-
return path__default.default.join(recordingsDir, `${id}.json`);
|
|
38
|
+
return path__default.default.join(recordingsDir, `${id}.mock.json`);
|
|
39
39
|
}
|
|
40
40
|
async function loadRecordingSession(filePath) {
|
|
41
41
|
const fileContent = await fs__default.default.readFile(filePath, "utf8");
|
|
@@ -43,6 +43,8 @@ async function loadRecordingSession(filePath) {
|
|
|
43
43
|
}
|
|
44
44
|
async function saveRecordingSession(recordingsDir, session) {
|
|
45
45
|
const filePath = getRecordingPath(recordingsDir, session.id);
|
|
46
|
+
const dirPath = path__default.default.dirname(filePath);
|
|
47
|
+
await fs__default.default.mkdir(dirPath, { recursive: true });
|
|
46
48
|
await fs__default.default.writeFile(
|
|
47
49
|
filePath,
|
|
48
50
|
JSON.stringify(session, null, JSON_INDENT_SPACES)
|
|
@@ -127,6 +129,7 @@ var ProxyServer = class {
|
|
|
127
129
|
this.handleUpgrade(req, socket, head);
|
|
128
130
|
});
|
|
129
131
|
server.listen(port, () => {
|
|
132
|
+
process.env.TEST_PROXY_RECORDER_PORT = String(port);
|
|
130
133
|
this.logServerStartup(port);
|
|
131
134
|
});
|
|
132
135
|
return server;
|
|
@@ -135,14 +138,17 @@ var ProxyServer = class {
|
|
|
135
138
|
this.proxy.on("error", this.handleProxyError.bind(this));
|
|
136
139
|
this.proxy.on("proxyRes", this.handleProxyResponse.bind(this));
|
|
137
140
|
}
|
|
138
|
-
handleProxyError(err,
|
|
141
|
+
handleProxyError(err, req, res) {
|
|
139
142
|
console.error("Proxy error:", err);
|
|
140
143
|
if (!(res instanceof http__default.default.ServerResponse)) {
|
|
141
144
|
return;
|
|
142
145
|
}
|
|
143
146
|
if (!res.headersSent) {
|
|
147
|
+
const origin = req.headers.origin;
|
|
144
148
|
res.writeHead(HTTP_STATUS_BAD_GATEWAY, {
|
|
145
|
-
"Content-Type": "application/json"
|
|
149
|
+
"Content-Type": "application/json",
|
|
150
|
+
"Access-Control-Allow-Origin": origin || "*",
|
|
151
|
+
"Access-Control-Allow-Credentials": "true"
|
|
146
152
|
});
|
|
147
153
|
}
|
|
148
154
|
res.end(JSON.stringify({ error: "Proxy error", message: err.message }));
|
|
@@ -198,7 +204,7 @@ var ProxyServer = class {
|
|
|
198
204
|
async switchMode(mode, id) {
|
|
199
205
|
if (this.currentSession) {
|
|
200
206
|
console.log("Switching mode, saving current session first");
|
|
201
|
-
await this.saveCurrentSession();
|
|
207
|
+
await this.saveCurrentSession(true);
|
|
202
208
|
console.log("Session saved, continuing with mode switch");
|
|
203
209
|
}
|
|
204
210
|
switch (mode) {
|
|
@@ -253,13 +259,13 @@ var ProxyServer = class {
|
|
|
253
259
|
if (timeout && timeout > 0) {
|
|
254
260
|
this.modeTimeout = setTimeout(async () => {
|
|
255
261
|
console.log("Timeout reached, switching back to transparent mode");
|
|
256
|
-
await this.saveCurrentSession();
|
|
262
|
+
await this.saveCurrentSession(true);
|
|
257
263
|
this.switchToTransparentMode();
|
|
258
264
|
this.modeTimeout = null;
|
|
259
265
|
}, timeout);
|
|
260
266
|
}
|
|
261
267
|
}
|
|
262
|
-
async saveCurrentSession() {
|
|
268
|
+
async saveCurrentSession(filterIncomplete = false) {
|
|
263
269
|
if (!this.currentSession) {
|
|
264
270
|
console.log("No current session to save");
|
|
265
271
|
return;
|
|
@@ -268,13 +274,27 @@ var ProxyServer = class {
|
|
|
268
274
|
console.log("Session has no recordings, skipping save");
|
|
269
275
|
return;
|
|
270
276
|
}
|
|
277
|
+
if (filterIncomplete) {
|
|
278
|
+
const incompleteCount = this.currentSession.recordings.filter(
|
|
279
|
+
(r) => !r.response
|
|
280
|
+
).length;
|
|
281
|
+
if (incompleteCount > 0) {
|
|
282
|
+
console.log(
|
|
283
|
+
`Removing ${incompleteCount} incomplete recording(s) without responses`
|
|
284
|
+
);
|
|
285
|
+
this.currentSession.recordings = this.currentSession.recordings.filter(
|
|
286
|
+
(r) => r.response
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
271
290
|
console.log(
|
|
272
291
|
`Saving session with ${this.currentSession.recordings.length} HTTP and ${this.currentSession.websocketRecordings.length} WebSocket recordings`
|
|
273
292
|
);
|
|
274
293
|
await saveRecordingSession(this.recordingsDir, this.currentSession);
|
|
275
294
|
}
|
|
276
|
-
|
|
295
|
+
saveRequestRecordSync(req, body) {
|
|
277
296
|
if (!this.currentSession) {
|
|
297
|
+
console.log("saveRequestRecordSync: No current session");
|
|
278
298
|
return;
|
|
279
299
|
}
|
|
280
300
|
const key = getReqID(req);
|
|
@@ -292,6 +312,30 @@ var ProxyServer = class {
|
|
|
292
312
|
sequence: currentSequence
|
|
293
313
|
};
|
|
294
314
|
this.currentSession.recordings.push(record);
|
|
315
|
+
console.log(
|
|
316
|
+
// eslint-disable-next-line sonarjs/no-nested-template-literals
|
|
317
|
+
`saveRequestRecordSync: Saved ${req.method} ${req.url} (key: ${key}, seq: ${currentSequence}, body: ${body ? `${body.length} chars` : "null"}, total: ${this.currentSession.recordings.length}, sessionId: ${this.currentSession.id})`
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
updateRequestBodySync(req, body) {
|
|
321
|
+
if (!this.currentSession) {
|
|
322
|
+
console.log("updateRequestBodySync: No current session");
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const key = getReqID(req);
|
|
326
|
+
const record = this.currentSession.recordings.findLast(
|
|
327
|
+
(r) => r.key === key && !r.response
|
|
328
|
+
);
|
|
329
|
+
if (!record) {
|
|
330
|
+
console.error(
|
|
331
|
+
`updateRequestBodySync: Could not find request record for ${req.method} ${req.url}`
|
|
332
|
+
);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
record.request.body = body || null;
|
|
336
|
+
console.log(
|
|
337
|
+
`updateRequestBodySync: Updated body for ${req.method} ${req.url} (${body.length} chars)`
|
|
338
|
+
);
|
|
295
339
|
}
|
|
296
340
|
async recordResponse(req, proxyRes) {
|
|
297
341
|
if (!this.currentSession) {
|
|
@@ -320,49 +364,105 @@ var ProxyServer = class {
|
|
|
320
364
|
console.log(`Recorded: ${req.method} ${req.url}`);
|
|
321
365
|
});
|
|
322
366
|
}
|
|
367
|
+
async recordResponseData(req, proxyRes, body) {
|
|
368
|
+
if (!this.currentSession) {
|
|
369
|
+
console.log("recordResponseData: No current session");
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
const key = getReqID(req);
|
|
373
|
+
const record = this.currentSession.recordings.findLast(
|
|
374
|
+
(r) => r.key === key && !r.response
|
|
375
|
+
);
|
|
376
|
+
if (!record) {
|
|
377
|
+
const host = req.headers.host || "unknown";
|
|
378
|
+
const recordsWithKey = this.currentSession.recordings.filter(
|
|
379
|
+
(r) => r.key === key
|
|
380
|
+
);
|
|
381
|
+
console.error(
|
|
382
|
+
`Request record not found for response: ${key} at ${req.method} ${host}${req.url}`
|
|
383
|
+
);
|
|
384
|
+
console.error(
|
|
385
|
+
` Total recordings: ${this.currentSession.recordings.length}, with this key: ${recordsWithKey.length}`
|
|
386
|
+
);
|
|
387
|
+
console.error(
|
|
388
|
+
` Records with key:`,
|
|
389
|
+
recordsWithKey.map((r) => ({
|
|
390
|
+
seq: r.sequence,
|
|
391
|
+
hasResponse: !!r.response
|
|
392
|
+
}))
|
|
393
|
+
);
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
record.response = {
|
|
397
|
+
statusCode: proxyRes.statusCode,
|
|
398
|
+
headers: proxyRes.headers,
|
|
399
|
+
body: body || null
|
|
400
|
+
};
|
|
401
|
+
await this.saveCurrentSession();
|
|
402
|
+
console.log(
|
|
403
|
+
`recordResponseData: Recorded response for ${req.method} ${req.url}`
|
|
404
|
+
);
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
323
407
|
async handleReplayRequest(req, res) {
|
|
324
408
|
const key = getReqID(req);
|
|
325
409
|
const filePath = getRecordingPath(this.recordingsDir, this.replayId);
|
|
326
410
|
try {
|
|
327
411
|
const session = await loadRecordingSession(filePath);
|
|
328
|
-
const
|
|
329
|
-
const
|
|
330
|
-
(r) => r.key === key && r.
|
|
412
|
+
const host = req.headers.host || "unknown";
|
|
413
|
+
const recordsWithKey = session.recordings.filter(
|
|
414
|
+
(r) => r.key === key && r.response
|
|
331
415
|
);
|
|
332
|
-
if (
|
|
416
|
+
if (recordsWithKey.length === 0) {
|
|
333
417
|
throw new Error(
|
|
334
|
-
`No recording found for ${key}
|
|
418
|
+
`No recording found for ${key} at ${req.method} ${host}${req.url}`
|
|
335
419
|
);
|
|
336
420
|
}
|
|
421
|
+
const usageCount = this.replaySequenceMap.get(key) || 0;
|
|
422
|
+
const recordIndex = usageCount % recordsWithKey.length;
|
|
423
|
+
const record = recordsWithKey[recordIndex];
|
|
424
|
+
console.log(
|
|
425
|
+
`Replaying ${req.method} ${req.url} (usage: ${usageCount}, using recording ${recordIndex}/${recordsWithKey.length})`
|
|
426
|
+
);
|
|
427
|
+
this.replaySequenceMap.set(key, usageCount + 1);
|
|
337
428
|
if (!record.response) {
|
|
338
|
-
throw new Error(
|
|
429
|
+
throw new Error(
|
|
430
|
+
`No response recorded for this request: ${req.method} ${host}${req.url}`
|
|
431
|
+
);
|
|
339
432
|
}
|
|
340
|
-
this.replaySequenceMap.set(key, currentSequence + 1);
|
|
341
433
|
const { statusCode, headers, body } = record.response;
|
|
342
434
|
const origin = req.headers.origin;
|
|
343
435
|
const responseHeaders = {
|
|
344
436
|
...headers,
|
|
345
437
|
"access-control-allow-origin": origin || "*",
|
|
346
|
-
"access-control-allow-credentials": "true"
|
|
438
|
+
"access-control-allow-credentials": "true",
|
|
439
|
+
"access-control-allow-headers": req.headers["access-control-request-headers"] || "Origin, X-Requested-With, Content-Type, Accept, Authorization",
|
|
440
|
+
"access-control-allow-methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
441
|
+
"access-control-expose-headers": "*"
|
|
347
442
|
};
|
|
348
443
|
res.writeHead(statusCode, responseHeaders);
|
|
349
444
|
res.end(body);
|
|
350
|
-
console.log(
|
|
351
|
-
`Replayed: ${req.method} ${req.url} (sequence: ${currentSequence})`
|
|
352
|
-
);
|
|
353
445
|
} catch (error) {
|
|
354
|
-
this.handleReplayError(res, error, key, filePath);
|
|
446
|
+
this.handleReplayError(req, res, error, key, filePath);
|
|
355
447
|
}
|
|
356
448
|
}
|
|
357
|
-
handleReplayError(res, err, key, filePath) {
|
|
449
|
+
handleReplayError(req, res, err, key, filePath) {
|
|
358
450
|
const isFileNotFound = err instanceof Error && "code" in err && err.code === "ENOENT";
|
|
359
451
|
console.error("Replay error:", err);
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
452
|
+
const origin = req.headers.origin;
|
|
453
|
+
res.writeHead(HTTP_STATUS_NOT_FOUND, {
|
|
454
|
+
"Content-Type": "application/json",
|
|
455
|
+
"Access-Control-Allow-Origin": origin || "*",
|
|
456
|
+
"Access-Control-Allow-Credentials": "true"
|
|
365
457
|
});
|
|
458
|
+
res.end(
|
|
459
|
+
JSON.stringify({
|
|
460
|
+
error: isFileNotFound ? "Recording file not found" : "Recording not found",
|
|
461
|
+
message: err instanceof Error ? err.message : "Unknown error",
|
|
462
|
+
key,
|
|
463
|
+
filePath
|
|
464
|
+
})
|
|
465
|
+
);
|
|
366
466
|
}
|
|
367
467
|
async handleRequest(req, res) {
|
|
368
468
|
if (req.method === "OPTIONS") {
|
|
@@ -392,6 +492,7 @@ var ProxyServer = class {
|
|
|
392
492
|
const target = this.getTarget();
|
|
393
493
|
console.log(`[${this.mode}] ${req.method} ${req.url} -> ${target}`);
|
|
394
494
|
if (this.mode === Modes.record) {
|
|
495
|
+
this.saveRequestRecordSync(req, null);
|
|
395
496
|
await this.bufferAndProxyRequest(req, res, target);
|
|
396
497
|
} else {
|
|
397
498
|
this.proxy.web(req, res, { target });
|
|
@@ -402,11 +503,20 @@ var ProxyServer = class {
|
|
|
402
503
|
req.on("data", (chunk) => {
|
|
403
504
|
chunks.push(chunk);
|
|
404
505
|
});
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
506
|
+
try {
|
|
507
|
+
await new Promise((resolve, reject) => {
|
|
508
|
+
req.on("end", () => resolve());
|
|
509
|
+
req.on("error", (err) => reject(err));
|
|
510
|
+
setTimeout(
|
|
511
|
+
() => reject(new Error("Request buffering timeout")),
|
|
512
|
+
3e4
|
|
513
|
+
);
|
|
514
|
+
});
|
|
515
|
+
} catch (error) {
|
|
516
|
+
console.error("Error buffering request:", error);
|
|
517
|
+
}
|
|
408
518
|
const body = Buffer.concat(chunks).toString("utf8");
|
|
409
|
-
|
|
519
|
+
this.updateRequestBodySync(req, body);
|
|
410
520
|
const targetUrl = new URL(target);
|
|
411
521
|
const isHttps = targetUrl.protocol === "https:";
|
|
412
522
|
const requestModule = isHttps ? https__default.default : http__default.default;
|
|
@@ -421,9 +531,38 @@ var ProxyServer = class {
|
|
|
421
531
|
},
|
|
422
532
|
(proxyRes) => {
|
|
423
533
|
this.addCorsHeaders(proxyRes, req);
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
534
|
+
const responseChunks = [];
|
|
535
|
+
proxyRes.on("data", (chunk) => {
|
|
536
|
+
responseChunks.push(chunk);
|
|
537
|
+
});
|
|
538
|
+
proxyRes.on("end", async () => {
|
|
539
|
+
const responseBody = Buffer.concat(responseChunks);
|
|
540
|
+
const recorded = await this.recordResponseData(
|
|
541
|
+
req,
|
|
542
|
+
proxyRes,
|
|
543
|
+
responseBody.toString("utf8")
|
|
544
|
+
);
|
|
545
|
+
const origin = req.headers.origin;
|
|
546
|
+
const responseHeaders = {
|
|
547
|
+
...proxyRes.headers,
|
|
548
|
+
"access-control-allow-origin": origin || "*",
|
|
549
|
+
"access-control-allow-credentials": "true",
|
|
550
|
+
"access-control-allow-headers": req.headers["access-control-request-headers"] || "Origin, X-Requested-With, Content-Type, Accept, Authorization",
|
|
551
|
+
"access-control-allow-methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
552
|
+
"access-control-expose-headers": "*"
|
|
553
|
+
};
|
|
554
|
+
res.writeHead(proxyRes.statusCode || 200, responseHeaders);
|
|
555
|
+
res.end(responseBody);
|
|
556
|
+
if (recorded) {
|
|
557
|
+
console.log(`Recorded: ${req.method} ${req.url}`);
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
proxyRes.on("error", (err) => {
|
|
561
|
+
console.error("Proxy response error:", err);
|
|
562
|
+
if (!res.headersSent) {
|
|
563
|
+
this.handleProxyError(err, req, res);
|
|
564
|
+
}
|
|
565
|
+
});
|
|
427
566
|
}
|
|
428
567
|
);
|
|
429
568
|
proxyReq.on("error", (err) => {
|
|
@@ -605,15 +744,25 @@ var ProxyServer = class {
|
|
|
605
744
|
};
|
|
606
745
|
|
|
607
746
|
// src/playwright/index.ts
|
|
608
|
-
|
|
747
|
+
function getProxyPort() {
|
|
748
|
+
const envPort = process.env.TEST_PROXY_RECORDER_PORT;
|
|
749
|
+
if (envPort) {
|
|
750
|
+
const parsed = Number.parseInt(envPort, 10);
|
|
751
|
+
if (!Number.isNaN(parsed)) {
|
|
752
|
+
return parsed;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
return 8100;
|
|
756
|
+
}
|
|
609
757
|
async function setProxyMode(mode, sessionId, timeout) {
|
|
758
|
+
const proxyPort = getProxyPort();
|
|
610
759
|
try {
|
|
611
760
|
const body = {
|
|
612
761
|
mode,
|
|
613
762
|
id: sessionId,
|
|
614
763
|
...timeout && { timeout }
|
|
615
764
|
};
|
|
616
|
-
const response = await fetch(
|
|
765
|
+
const response = await fetch(`http://127.0.0.1:${proxyPort}/__control`, {
|
|
617
766
|
method: "POST",
|
|
618
767
|
headers: { "Content-Type": "application/json" },
|
|
619
768
|
body: JSON.stringify(body)
|
|
@@ -630,8 +779,34 @@ async function setProxyMode(mode, sessionId, timeout) {
|
|
|
630
779
|
throw error;
|
|
631
780
|
}
|
|
632
781
|
}
|
|
782
|
+
function parseSpecFilePath(specPath) {
|
|
783
|
+
const folderMatch = specPath.match(/^(.+?)\/([^/]+)\.(spec|test)\.ts$/);
|
|
784
|
+
if (folderMatch) {
|
|
785
|
+
return { folder: folderMatch[1], fileName: folderMatch[2] };
|
|
786
|
+
}
|
|
787
|
+
const fileMatch = specPath.match(/^([^/]+)\.(spec|test)\.ts$/);
|
|
788
|
+
if (fileMatch) {
|
|
789
|
+
return { folder: null, fileName: fileMatch[1] };
|
|
790
|
+
}
|
|
791
|
+
return { folder: null, fileName: null };
|
|
792
|
+
}
|
|
793
|
+
function buildSessionPath(folder, fileName, testName) {
|
|
794
|
+
if (folder && fileName) {
|
|
795
|
+
return `${folder}/${fileName}__${testName}`;
|
|
796
|
+
}
|
|
797
|
+
if (fileName) {
|
|
798
|
+
return `${fileName}__${testName}`;
|
|
799
|
+
}
|
|
800
|
+
return testName;
|
|
801
|
+
}
|
|
633
802
|
function generateSessionId(testInfo) {
|
|
634
|
-
|
|
803
|
+
const { titlePath } = testInfo;
|
|
804
|
+
if (!titlePath || titlePath.length === 0) {
|
|
805
|
+
return testInfo.title.toLowerCase().replaceAll(/\s+/g, "-");
|
|
806
|
+
}
|
|
807
|
+
const { folder, fileName } = parseSpecFilePath(titlePath[0]);
|
|
808
|
+
const testName = titlePath.at(-1).toLowerCase().replaceAll(/\s+/g, "-");
|
|
809
|
+
return buildSessionPath(folder, fileName, testName);
|
|
635
810
|
}
|
|
636
811
|
async function startRecording(testInfo) {
|
|
637
812
|
const sessionId = generateSessionId(testInfo);
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import http from 'node:http';
|
|
2
|
-
export { C as ControlRequest, M as Mode, P as PlaywrightTestInfo, R as Recording, a as RecordingSession, W as WebSocketRecording, g as generateSessionId, p as playwrightProxy, s as setProxyMode, b as startRecording, c as startReplay, d as stopProxy } from './index-
|
|
2
|
+
export { C as ControlRequest, M as Mode, P as PlaywrightTestInfo, R as Recording, a as RecordingSession, W as WebSocketRecording, g as generateSessionId, p as playwrightProxy, s as setProxyMode, b as startRecording, c as startReplay, d as stopProxy } from './index-CBjvm5rb.cjs';
|
|
3
3
|
import '@playwright/test';
|
|
4
4
|
|
|
5
5
|
declare class ProxyServer {
|
|
@@ -30,8 +30,10 @@ declare class ProxyServer {
|
|
|
30
30
|
private switchToReplayMode;
|
|
31
31
|
private setupModeTimeout;
|
|
32
32
|
private saveCurrentSession;
|
|
33
|
-
private
|
|
33
|
+
private saveRequestRecordSync;
|
|
34
|
+
private updateRequestBodySync;
|
|
34
35
|
private recordResponse;
|
|
36
|
+
private recordResponseData;
|
|
35
37
|
private handleReplayRequest;
|
|
36
38
|
private handleReplayError;
|
|
37
39
|
private handleRequest;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import http from 'node:http';
|
|
2
|
-
export { C as ControlRequest, M as Mode, P as PlaywrightTestInfo, R as Recording, a as RecordingSession, W as WebSocketRecording, g as generateSessionId, p as playwrightProxy, s as setProxyMode, b as startRecording, c as startReplay, d as stopProxy } from './index-
|
|
2
|
+
export { C as ControlRequest, M as Mode, P as PlaywrightTestInfo, R as Recording, a as RecordingSession, W as WebSocketRecording, g as generateSessionId, p as playwrightProxy, s as setProxyMode, b as startRecording, c as startReplay, d as stopProxy } from './index-CBjvm5rb.js';
|
|
3
3
|
import '@playwright/test';
|
|
4
4
|
|
|
5
5
|
declare class ProxyServer {
|
|
@@ -30,8 +30,10 @@ declare class ProxyServer {
|
|
|
30
30
|
private switchToReplayMode;
|
|
31
31
|
private setupModeTimeout;
|
|
32
32
|
private saveCurrentSession;
|
|
33
|
-
private
|
|
33
|
+
private saveRequestRecordSync;
|
|
34
|
+
private updateRequestBodySync;
|
|
34
35
|
private recordResponse;
|
|
36
|
+
private recordResponseData;
|
|
35
37
|
private handleReplayRequest;
|
|
36
38
|
private handleReplayError;
|
|
37
39
|
private handleRequest;
|