test-proxy-recorder 0.1.11 → 0.2.0
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 +32 -16
- package/dist/{index-Cx_Kflfl.d.cts → index-nmNRt1WE.d.cts} +9 -2
- package/dist/{index-Cx_Kflfl.d.ts → index-nmNRt1WE.d.ts} +9 -2
- package/dist/index.cjs +20 -8
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +20 -8
- package/dist/playwright/index.cjs +13 -5
- package/dist/playwright/index.d.cts +1 -1
- package/dist/playwright/index.d.ts +1 -1
- package/dist/playwright/index.mjs +13 -5
- package/dist/proxy.js +7 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,10 +99,10 @@ This marks recording files as binary, which causes long mock files to be collaps
|
|
|
99
99
|
Create `e2e/global-teardown.ts`:
|
|
100
100
|
|
|
101
101
|
```typescript
|
|
102
|
-
import {
|
|
102
|
+
import { playwrightProxy } from 'test-proxy-recorder';
|
|
103
103
|
|
|
104
104
|
async function globalTeardown() {
|
|
105
|
-
await
|
|
105
|
+
await playwrightProxy.teardown();
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
export default globalTeardown;
|
|
@@ -128,15 +128,17 @@ Create `e2e/example.spec.ts`:
|
|
|
128
128
|
import { test, expect } from '@playwright/test';
|
|
129
129
|
import { playwrightProxy } from 'test-proxy-recorder';
|
|
130
130
|
|
|
131
|
+
// Setup afterEach hook to reset proxy after each test
|
|
132
|
+
test.afterEach(async ({ page: _page }, testInfo) => {
|
|
133
|
+
await playwrightProxy.after(testInfo);
|
|
134
|
+
});
|
|
135
|
+
|
|
131
136
|
test('example test with proxy', async ({ page }, testInfo) => {
|
|
132
137
|
// Set proxy mode: 'record' to capture, 'replay' to use recordings
|
|
133
138
|
await playwrightProxy.before(testInfo, 'replay');
|
|
134
139
|
|
|
135
140
|
await page.goto('/');
|
|
136
141
|
await expect(page.getByText('Welcome')).toBeVisible();
|
|
137
|
-
|
|
138
|
-
// Always cleanup after test
|
|
139
|
-
await playwrightProxy.after(testInfo);
|
|
140
142
|
});
|
|
141
143
|
```
|
|
142
144
|
|
|
@@ -186,27 +188,38 @@ test-proxy-recorder http://localhost:8000 http://localhost:9000 --port 8100
|
|
|
186
188
|
|
|
187
189
|
### Basic Test Structure
|
|
188
190
|
|
|
189
|
-
Every test using the proxy should follow this pattern:
|
|
191
|
+
Every test file using the proxy should follow this pattern:
|
|
190
192
|
|
|
191
193
|
```typescript
|
|
192
194
|
import { test } from '@playwright/test';
|
|
193
195
|
import { playwrightProxy } from 'test-proxy-recorder';
|
|
194
196
|
|
|
197
|
+
// Setup afterEach hook once per test file
|
|
198
|
+
test.afterEach(async ({ page: _page }, testInfo) => {
|
|
199
|
+
await playwrightProxy.after(testInfo);
|
|
200
|
+
});
|
|
201
|
+
|
|
195
202
|
test('test name', async ({ page }, testInfo) => {
|
|
196
203
|
// 1. Set mode BEFORE test actions
|
|
197
204
|
await playwrightProxy.before(testInfo, 'replay');
|
|
198
205
|
|
|
199
206
|
// 2. Test code
|
|
200
207
|
await page.goto('/page');
|
|
201
|
-
|
|
202
|
-
// 3. Reset mode AFTER test completes
|
|
203
|
-
await playwrightProxy.after(testInfo);
|
|
208
|
+
// Test assertions...
|
|
204
209
|
});
|
|
205
210
|
```
|
|
206
211
|
|
|
207
212
|
### Recording vs Replay
|
|
208
213
|
|
|
209
214
|
```typescript
|
|
215
|
+
import { test } from '@playwright/test';
|
|
216
|
+
import { playwrightProxy } from 'test-proxy-recorder';
|
|
217
|
+
|
|
218
|
+
// Setup afterEach hook to automatically cleanup after each test
|
|
219
|
+
test.afterEach(async ({ page: _page }, testInfo) => {
|
|
220
|
+
await playwrightProxy.after(testInfo);
|
|
221
|
+
});
|
|
222
|
+
|
|
210
223
|
// Recording mode - captures API responses
|
|
211
224
|
test('create user', async ({ page }, testInfo) => {
|
|
212
225
|
await playwrightProxy.before(testInfo, 'record');
|
|
@@ -214,8 +227,6 @@ test('create user', async ({ page }, testInfo) => {
|
|
|
214
227
|
await page.goto('/users/new');
|
|
215
228
|
await page.fill('[name="username"]', 'testuser');
|
|
216
229
|
await page.click('button[type="submit"]');
|
|
217
|
-
|
|
218
|
-
await playwrightProxy.after(testInfo);
|
|
219
230
|
});
|
|
220
231
|
|
|
221
232
|
// Replay mode - uses recorded responses
|
|
@@ -225,8 +236,6 @@ test('create user', async ({ page }, testInfo) => {
|
|
|
225
236
|
await page.goto('/users/new');
|
|
226
237
|
await page.fill('[name="username"]', 'testuser');
|
|
227
238
|
await page.click('button[type="submit"]');
|
|
228
|
-
|
|
229
|
-
await playwrightProxy.after(testInfo);
|
|
230
239
|
});
|
|
231
240
|
```
|
|
232
241
|
|
|
@@ -244,10 +253,10 @@ Recording files are auto-generated from test names:
|
|
|
244
253
|
Create `e2e/global-teardown.ts`:
|
|
245
254
|
|
|
246
255
|
```typescript
|
|
247
|
-
import {
|
|
256
|
+
import { playwrightProxy } from 'test-proxy-recorder';
|
|
248
257
|
|
|
249
258
|
async function globalTeardown() {
|
|
250
|
-
await
|
|
259
|
+
await playwrightProxy.teardown();
|
|
251
260
|
}
|
|
252
261
|
|
|
253
262
|
export default globalTeardown;
|
|
@@ -412,8 +421,13 @@ const playwrightProxy = {
|
|
|
412
421
|
timeout?: number
|
|
413
422
|
): Promise<void>;
|
|
414
423
|
|
|
415
|
-
// Reset to transparent mode after test
|
|
424
|
+
// Reset replay session and return to transparent mode after test
|
|
425
|
+
// Resets sequence counters to ensure next replay starts fresh
|
|
416
426
|
async after(testInfo: TestInfo): Promise<void>;
|
|
427
|
+
|
|
428
|
+
// Global teardown - switches proxy to transparent mode
|
|
429
|
+
// Use in Playwright's globalTeardown configuration
|
|
430
|
+
async teardown(): Promise<void>;
|
|
417
431
|
};
|
|
418
432
|
|
|
419
433
|
// Direct mode control
|
|
@@ -438,6 +452,8 @@ async function setProxyMode(
|
|
|
438
452
|
}
|
|
439
453
|
```
|
|
440
454
|
|
|
455
|
+
**Note**: Switching to replay mode automatically resets session counters (clears served recordings tracker), allowing replay from the beginning.
|
|
456
|
+
|
|
441
457
|
**Response**:
|
|
442
458
|
|
|
443
459
|
```typescript
|
|
@@ -89,13 +89,20 @@ declare const playwrightProxy: {
|
|
|
89
89
|
* Setup before test - sets the proxy mode
|
|
90
90
|
* @param testInfo - Playwright test info object
|
|
91
91
|
* @param mode - The proxy mode to use for this test
|
|
92
|
+
* @param timeout - Optional timeout in milliseconds
|
|
92
93
|
*/
|
|
93
|
-
before(testInfo: PlaywrightTestInfo, mode: Mode): Promise<void>;
|
|
94
|
+
before(testInfo: PlaywrightTestInfo, mode: Mode, timeout?: number): Promise<void>;
|
|
94
95
|
/**
|
|
95
|
-
* Cleanup after test -
|
|
96
|
+
* Cleanup after test - resets replay session by re-entering replay mode
|
|
97
|
+
* switchToReplayMode automatically clears sequence counters
|
|
96
98
|
* @param testInfo - Playwright test info object
|
|
97
99
|
*/
|
|
98
100
|
after(testInfo: PlaywrightTestInfo): Promise<void>;
|
|
101
|
+
/**
|
|
102
|
+
* Global teardown - switches proxy to transparent mode
|
|
103
|
+
* Use this in Playwright's globalTeardown to ensure clean state
|
|
104
|
+
*/
|
|
105
|
+
teardown(): Promise<void>;
|
|
99
106
|
};
|
|
100
107
|
|
|
101
108
|
export { type ControlRequest as C, type Mode as M, type PlaywrightTestInfo as P, type Recording as R, type WebSocketRecording as W, type RecordingSession as a, startRecording as b, startReplay as c, stopProxy as d, generateSessionId as g, playwrightProxy as p, setProxyMode as s };
|
|
@@ -89,13 +89,20 @@ declare const playwrightProxy: {
|
|
|
89
89
|
* Setup before test - sets the proxy mode
|
|
90
90
|
* @param testInfo - Playwright test info object
|
|
91
91
|
* @param mode - The proxy mode to use for this test
|
|
92
|
+
* @param timeout - Optional timeout in milliseconds
|
|
92
93
|
*/
|
|
93
|
-
before(testInfo: PlaywrightTestInfo, mode: Mode): Promise<void>;
|
|
94
|
+
before(testInfo: PlaywrightTestInfo, mode: Mode, timeout?: number): Promise<void>;
|
|
94
95
|
/**
|
|
95
|
-
* Cleanup after test -
|
|
96
|
+
* Cleanup after test - resets replay session by re-entering replay mode
|
|
97
|
+
* switchToReplayMode automatically clears sequence counters
|
|
96
98
|
* @param testInfo - Playwright test info object
|
|
97
99
|
*/
|
|
98
100
|
after(testInfo: PlaywrightTestInfo): Promise<void>;
|
|
101
|
+
/**
|
|
102
|
+
* Global teardown - switches proxy to transparent mode
|
|
103
|
+
* Use this in Playwright's globalTeardown to ensure clean state
|
|
104
|
+
*/
|
|
105
|
+
teardown(): Promise<void>;
|
|
99
106
|
};
|
|
100
107
|
|
|
101
108
|
export { type ControlRequest as C, type Mode as M, type PlaywrightTestInfo as P, type Recording as R, type WebSocketRecording as W, type RecordingSession as a, startRecording as b, startReplay as c, stopProxy as d, generateSessionId as g, playwrightProxy as p, setProxyMode as s };
|
package/dist/index.cjs
CHANGED
|
@@ -529,7 +529,11 @@ var ProxyServer = class {
|
|
|
529
529
|
}
|
|
530
530
|
const servedForThisKey = sessionState.servedRecordingIdsByKey.get(key);
|
|
531
531
|
const host = req.headers.host || "unknown";
|
|
532
|
-
const recordsWithKey = session.recordings.filter((r) => r.key === key && r.response).toSorted((a, b) =>
|
|
532
|
+
const recordsWithKey = session.recordings.filter((r) => r.key === key && r.response).toSorted((a, b) => {
|
|
533
|
+
const aSeq = a.sequence !== void 0 ? a.sequence : a.recordingId;
|
|
534
|
+
const bSeq = b.sequence !== void 0 ? b.sequence : b.recordingId;
|
|
535
|
+
return aSeq - bSeq;
|
|
536
|
+
});
|
|
533
537
|
if (recordsWithKey.length === 0) {
|
|
534
538
|
const errorMsg = `No recording found for ${key} at ${req.method} ${host}${req.url}`;
|
|
535
539
|
console.error(`[REPLAY ERROR] ${errorMsg} (session: ${recordingId})`);
|
|
@@ -552,7 +556,7 @@ var ProxyServer = class {
|
|
|
552
556
|
}
|
|
553
557
|
const requestCount = servedForThisKey.size + 1;
|
|
554
558
|
console.log(
|
|
555
|
-
`[
|
|
559
|
+
`[replay request #${requestCount}] ${req.method} ${req.url} (session: ${recordingId}, total: ${recordsWithKey.length}, served: ${servedForThisKey.size})`
|
|
556
560
|
);
|
|
557
561
|
let record;
|
|
558
562
|
for (const rec of recordsWithKey) {
|
|
@@ -569,7 +573,7 @@ var ProxyServer = class {
|
|
|
569
573
|
}
|
|
570
574
|
servedForThisKey.add(record.recordingId);
|
|
571
575
|
console.log(
|
|
572
|
-
`[
|
|
576
|
+
`[replay serving] recordingId: ${record.recordingId}, session: ${recordingId}, body_len: ${record.response?.body?.length || 0}`
|
|
573
577
|
);
|
|
574
578
|
if (!record.response) {
|
|
575
579
|
throw new Error(
|
|
@@ -953,19 +957,27 @@ var playwrightProxy = {
|
|
|
953
957
|
* Setup before test - sets the proxy mode
|
|
954
958
|
* @param testInfo - Playwright test info object
|
|
955
959
|
* @param mode - The proxy mode to use for this test
|
|
960
|
+
* @param timeout - Optional timeout in milliseconds
|
|
956
961
|
*/
|
|
957
|
-
async before(testInfo, mode) {
|
|
962
|
+
async before(testInfo, mode, timeout) {
|
|
958
963
|
const sessionId = generateSessionId(testInfo);
|
|
959
|
-
|
|
960
|
-
await setProxyMode(mode, sessionId);
|
|
964
|
+
await setProxyMode(mode, sessionId, timeout);
|
|
961
965
|
},
|
|
962
966
|
/**
|
|
963
|
-
* Cleanup after test -
|
|
967
|
+
* Cleanup after test - resets replay session by re-entering replay mode
|
|
968
|
+
* switchToReplayMode automatically clears sequence counters
|
|
964
969
|
* @param testInfo - Playwright test info object
|
|
965
970
|
*/
|
|
966
971
|
async after(testInfo) {
|
|
967
972
|
const sessionId = generateSessionId(testInfo);
|
|
968
|
-
await setProxyMode(Modes.
|
|
973
|
+
await setProxyMode(Modes.replay, sessionId);
|
|
974
|
+
},
|
|
975
|
+
/**
|
|
976
|
+
* Global teardown - switches proxy to transparent mode
|
|
977
|
+
* Use this in Playwright's globalTeardown to ensure clean state
|
|
978
|
+
*/
|
|
979
|
+
async teardown() {
|
|
980
|
+
await setProxyMode(Modes.transparent);
|
|
969
981
|
}
|
|
970
982
|
};
|
|
971
983
|
|
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-nmNRt1WE.cjs';
|
|
3
3
|
import '@playwright/test';
|
|
4
4
|
|
|
5
5
|
declare class ProxyServer {
|
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-nmNRt1WE.js';
|
|
3
3
|
import '@playwright/test';
|
|
4
4
|
|
|
5
5
|
declare class ProxyServer {
|
package/dist/index.mjs
CHANGED
|
@@ -517,7 +517,11 @@ var ProxyServer = class {
|
|
|
517
517
|
}
|
|
518
518
|
const servedForThisKey = sessionState.servedRecordingIdsByKey.get(key);
|
|
519
519
|
const host = req.headers.host || "unknown";
|
|
520
|
-
const recordsWithKey = session.recordings.filter((r) => r.key === key && r.response).toSorted((a, b) =>
|
|
520
|
+
const recordsWithKey = session.recordings.filter((r) => r.key === key && r.response).toSorted((a, b) => {
|
|
521
|
+
const aSeq = a.sequence !== void 0 ? a.sequence : a.recordingId;
|
|
522
|
+
const bSeq = b.sequence !== void 0 ? b.sequence : b.recordingId;
|
|
523
|
+
return aSeq - bSeq;
|
|
524
|
+
});
|
|
521
525
|
if (recordsWithKey.length === 0) {
|
|
522
526
|
const errorMsg = `No recording found for ${key} at ${req.method} ${host}${req.url}`;
|
|
523
527
|
console.error(`[REPLAY ERROR] ${errorMsg} (session: ${recordingId})`);
|
|
@@ -540,7 +544,7 @@ var ProxyServer = class {
|
|
|
540
544
|
}
|
|
541
545
|
const requestCount = servedForThisKey.size + 1;
|
|
542
546
|
console.log(
|
|
543
|
-
`[
|
|
547
|
+
`[replay request #${requestCount}] ${req.method} ${req.url} (session: ${recordingId}, total: ${recordsWithKey.length}, served: ${servedForThisKey.size})`
|
|
544
548
|
);
|
|
545
549
|
let record;
|
|
546
550
|
for (const rec of recordsWithKey) {
|
|
@@ -557,7 +561,7 @@ var ProxyServer = class {
|
|
|
557
561
|
}
|
|
558
562
|
servedForThisKey.add(record.recordingId);
|
|
559
563
|
console.log(
|
|
560
|
-
`[
|
|
564
|
+
`[replay serving] recordingId: ${record.recordingId}, session: ${recordingId}, body_len: ${record.response?.body?.length || 0}`
|
|
561
565
|
);
|
|
562
566
|
if (!record.response) {
|
|
563
567
|
throw new Error(
|
|
@@ -941,19 +945,27 @@ var playwrightProxy = {
|
|
|
941
945
|
* Setup before test - sets the proxy mode
|
|
942
946
|
* @param testInfo - Playwright test info object
|
|
943
947
|
* @param mode - The proxy mode to use for this test
|
|
948
|
+
* @param timeout - Optional timeout in milliseconds
|
|
944
949
|
*/
|
|
945
|
-
async before(testInfo, mode) {
|
|
950
|
+
async before(testInfo, mode, timeout) {
|
|
946
951
|
const sessionId = generateSessionId(testInfo);
|
|
947
|
-
|
|
948
|
-
await setProxyMode(mode, sessionId);
|
|
952
|
+
await setProxyMode(mode, sessionId, timeout);
|
|
949
953
|
},
|
|
950
954
|
/**
|
|
951
|
-
* Cleanup after test -
|
|
955
|
+
* Cleanup after test - resets replay session by re-entering replay mode
|
|
956
|
+
* switchToReplayMode automatically clears sequence counters
|
|
952
957
|
* @param testInfo - Playwright test info object
|
|
953
958
|
*/
|
|
954
959
|
async after(testInfo) {
|
|
955
960
|
const sessionId = generateSessionId(testInfo);
|
|
956
|
-
await setProxyMode(Modes.
|
|
961
|
+
await setProxyMode(Modes.replay, sessionId);
|
|
962
|
+
},
|
|
963
|
+
/**
|
|
964
|
+
* Global teardown - switches proxy to transparent mode
|
|
965
|
+
* Use this in Playwright's globalTeardown to ensure clean state
|
|
966
|
+
*/
|
|
967
|
+
async teardown() {
|
|
968
|
+
await setProxyMode(Modes.transparent);
|
|
957
969
|
}
|
|
958
970
|
};
|
|
959
971
|
|
|
@@ -89,19 +89,27 @@ var playwrightProxy = {
|
|
|
89
89
|
* Setup before test - sets the proxy mode
|
|
90
90
|
* @param testInfo - Playwright test info object
|
|
91
91
|
* @param mode - The proxy mode to use for this test
|
|
92
|
+
* @param timeout - Optional timeout in milliseconds
|
|
92
93
|
*/
|
|
93
|
-
async before(testInfo, mode) {
|
|
94
|
+
async before(testInfo, mode, timeout) {
|
|
94
95
|
const sessionId = generateSessionId(testInfo);
|
|
95
|
-
|
|
96
|
-
await setProxyMode(mode, sessionId);
|
|
96
|
+
await setProxyMode(mode, sessionId, timeout);
|
|
97
97
|
},
|
|
98
98
|
/**
|
|
99
|
-
* Cleanup after test -
|
|
99
|
+
* Cleanup after test - resets replay session by re-entering replay mode
|
|
100
|
+
* switchToReplayMode automatically clears sequence counters
|
|
100
101
|
* @param testInfo - Playwright test info object
|
|
101
102
|
*/
|
|
102
103
|
async after(testInfo) {
|
|
103
104
|
const sessionId = generateSessionId(testInfo);
|
|
104
|
-
await setProxyMode(Modes.
|
|
105
|
+
await setProxyMode(Modes.replay, sessionId);
|
|
106
|
+
},
|
|
107
|
+
/**
|
|
108
|
+
* Global teardown - switches proxy to transparent mode
|
|
109
|
+
* Use this in Playwright's globalTeardown to ensure clean state
|
|
110
|
+
*/
|
|
111
|
+
async teardown() {
|
|
112
|
+
await setProxyMode(Modes.transparent);
|
|
105
113
|
}
|
|
106
114
|
};
|
|
107
115
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
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-
|
|
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-nmNRt1WE.cjs';
|
|
3
3
|
import 'node:http';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
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-
|
|
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-nmNRt1WE.js';
|
|
3
3
|
import 'node:http';
|
|
@@ -87,19 +87,27 @@ var playwrightProxy = {
|
|
|
87
87
|
* Setup before test - sets the proxy mode
|
|
88
88
|
* @param testInfo - Playwright test info object
|
|
89
89
|
* @param mode - The proxy mode to use for this test
|
|
90
|
+
* @param timeout - Optional timeout in milliseconds
|
|
90
91
|
*/
|
|
91
|
-
async before(testInfo, mode) {
|
|
92
|
+
async before(testInfo, mode, timeout) {
|
|
92
93
|
const sessionId = generateSessionId(testInfo);
|
|
93
|
-
|
|
94
|
-
await setProxyMode(mode, sessionId);
|
|
94
|
+
await setProxyMode(mode, sessionId, timeout);
|
|
95
95
|
},
|
|
96
96
|
/**
|
|
97
|
-
* Cleanup after test -
|
|
97
|
+
* Cleanup after test - resets replay session by re-entering replay mode
|
|
98
|
+
* switchToReplayMode automatically clears sequence counters
|
|
98
99
|
* @param testInfo - Playwright test info object
|
|
99
100
|
*/
|
|
100
101
|
async after(testInfo) {
|
|
101
102
|
const sessionId = generateSessionId(testInfo);
|
|
102
|
-
await setProxyMode(Modes.
|
|
103
|
+
await setProxyMode(Modes.replay, sessionId);
|
|
104
|
+
},
|
|
105
|
+
/**
|
|
106
|
+
* Global teardown - switches proxy to transparent mode
|
|
107
|
+
* Use this in Playwright's globalTeardown to ensure clean state
|
|
108
|
+
*/
|
|
109
|
+
async teardown() {
|
|
110
|
+
await setProxyMode(Modes.transparent);
|
|
103
111
|
}
|
|
104
112
|
};
|
|
105
113
|
|
package/dist/proxy.js
CHANGED
|
@@ -551,7 +551,11 @@ var ProxyServer = class {
|
|
|
551
551
|
}
|
|
552
552
|
const servedForThisKey = sessionState.servedRecordingIdsByKey.get(key);
|
|
553
553
|
const host = req.headers.host || "unknown";
|
|
554
|
-
const recordsWithKey = session.recordings.filter((r) => r.key === key && r.response).toSorted((a, b) =>
|
|
554
|
+
const recordsWithKey = session.recordings.filter((r) => r.key === key && r.response).toSorted((a, b) => {
|
|
555
|
+
const aSeq = a.sequence !== void 0 ? a.sequence : a.recordingId;
|
|
556
|
+
const bSeq = b.sequence !== void 0 ? b.sequence : b.recordingId;
|
|
557
|
+
return aSeq - bSeq;
|
|
558
|
+
});
|
|
555
559
|
if (recordsWithKey.length === 0) {
|
|
556
560
|
const errorMsg = `No recording found for ${key} at ${req.method} ${host}${req.url}`;
|
|
557
561
|
console.error(`[REPLAY ERROR] ${errorMsg} (session: ${recordingId})`);
|
|
@@ -574,7 +578,7 @@ var ProxyServer = class {
|
|
|
574
578
|
}
|
|
575
579
|
const requestCount = servedForThisKey.size + 1;
|
|
576
580
|
console.log(
|
|
577
|
-
`[
|
|
581
|
+
`[replay request #${requestCount}] ${req.method} ${req.url} (session: ${recordingId}, total: ${recordsWithKey.length}, served: ${servedForThisKey.size})`
|
|
578
582
|
);
|
|
579
583
|
let record;
|
|
580
584
|
for (const rec of recordsWithKey) {
|
|
@@ -591,7 +595,7 @@ var ProxyServer = class {
|
|
|
591
595
|
}
|
|
592
596
|
servedForThisKey.add(record.recordingId);
|
|
593
597
|
console.log(
|
|
594
|
-
`[
|
|
598
|
+
`[replay serving] recordingId: ${record.recordingId}, session: ${recordingId}, body_len: ${record.response?.body?.length || 0}`
|
|
595
599
|
);
|
|
596
600
|
if (!record.response) {
|
|
597
601
|
throw new Error(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "test-proxy-recorder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "HTTP proxy server for recording and replaying network requests in testing. Works seamlessly with Playwright testing framework.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|