test-proxy-recorder 0.1.0 → 0.1.2

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.
Files changed (41) hide show
  1. package/README.md +79 -172
  2. package/dist/index.cjs +597 -0
  3. package/dist/index.d.cts +88 -0
  4. package/dist/index.d.ts +88 -5
  5. package/dist/index.mjs +582 -0
  6. package/dist/playwright/index.cjs +72 -0
  7. package/dist/playwright/index.d.cts +50 -0
  8. package/dist/playwright/index.d.ts +12 -10
  9. package/dist/playwright/index.mjs +65 -0
  10. package/dist/proxy.js +555 -4
  11. package/package.json +12 -5
  12. package/dist/ProxyServer.d.ts +0 -39
  13. package/dist/ProxyServer.d.ts.map +0 -1
  14. package/dist/ProxyServer.js +0 -464
  15. package/dist/cli.d.ts +0 -8
  16. package/dist/cli.d.ts.map +0 -1
  17. package/dist/cli.js +0 -32
  18. package/dist/constants.d.ts +0 -7
  19. package/dist/constants.d.ts.map +0 -1
  20. package/dist/constants.js +0 -7
  21. package/dist/index.d.ts.map +0 -1
  22. package/dist/index.js +0 -3
  23. package/dist/playwright/index.d.ts.map +0 -1
  24. package/dist/playwright/index.js +0 -92
  25. package/dist/proxy.d.ts +0 -2
  26. package/dist/proxy.d.ts.map +0 -1
  27. package/dist/types.d.ts +0 -46
  28. package/dist/types.d.ts.map +0 -1
  29. package/dist/types.js +0 -6
  30. package/dist/utils/fileUtils.d.ts +0 -5
  31. package/dist/utils/fileUtils.d.ts.map +0 -1
  32. package/dist/utils/fileUtils.js +0 -16
  33. package/dist/utils/httpHelpers.d.ts +0 -4
  34. package/dist/utils/httpHelpers.d.ts.map +0 -1
  35. package/dist/utils/httpHelpers.js +0 -13
  36. package/dist/utils/index.d.ts +0 -4
  37. package/dist/utils/index.d.ts.map +0 -1
  38. package/dist/utils/index.js +0 -4
  39. package/dist/utils/requestKeyGenerator.d.ts +0 -3
  40. package/dist/utils/requestKeyGenerator.d.ts.map +0 -1
  41. package/dist/utils/requestKeyGenerator.js +0 -24
package/README.md CHANGED
@@ -1,18 +1,18 @@
1
1
  # test-proxy-recorder
2
2
 
3
+ [![npm](https://img.shields.io/npm/v/test-proxy-recorder.svg)](https://www.npmjs.com/package/test-proxy-recorder)
4
+ [![license](https://img.shields.io/github/license/asmyshlyaev177/test-proxy-recorder.svg?style=flat-square)](https://github.com/asmyshlyaev177/test-proxy-recorder/blob/master/LICENSE)
5
+
3
6
  HTTP proxy server for recording and replaying network requests in testing. Works seamlessly with Playwright and other testing frameworks.
4
7
 
5
- ### BETA VERSION, NOT STABLE FOR PRODUCTION USE
8
+ ## BETA VERSION
6
9
 
7
10
  ## Features
8
11
 
9
- - **Record Mode**: Capture HTTP/HTTPS requests and responses, including WebSocket connections
10
- - **Replay Mode**: Replay captured requests from disk without hitting real endpoints
11
- - **Transparent Mode**: Act as a simple proxy without recording or replaying
12
- - **Playwright Integration**: Built-in fixture for easy integration with Playwright tests
13
- - **WebSocket Support**: Full support for recording and replaying WebSocket connections
14
- - **Multiple Targets**: Load balance between multiple backend targets
15
- - **Timeout Control**: Automatic mode switching after configurable timeouts
12
+ - **Fast CI/CD Tests**: Record API responses once with real backend, replay them on CI/CD
13
+ - **Fast workflow**: Record real interactions with API, instead of mocking every request manually
14
+ - **Server Side Rendering**: Can record SSR requests from JS frameworks like NextJS.
15
+ - **Deterministic Tests**: Same responses every time, no flaky network issues, no need to wire up the whole Backend API for testing
16
16
 
17
17
  ## Installation
18
18
 
@@ -26,40 +26,23 @@ yarn add test-proxy-recorder
26
26
 
27
27
  ## Quick Start
28
28
 
29
- ### Standalone Usage
30
-
31
- ```typescript
32
- import { ProxyServer } from 'test-proxy-recorder';
33
-
34
- const proxy = new ProxyServer(
35
- ['http://localhost:3000'], // backend targets
36
- './recordings' // directory to store recordings
37
- );
38
-
39
- await proxy.init();
40
- const server = proxy.listen(8080);
41
- console.log('Proxy running on http://localhost:8080');
42
- ```
43
-
44
- ### With Playwright
45
-
46
- The proxy runs continuously in the background. Tests control the recording/replay mode using `playwrightProxy.before()` and `playwrightProxy.after()`:
29
+ 1. Run proxy with your backend API as a target `test-proxy-recorder --port 8100 --target http://localhost:8000 --recordings ./recordings`, here your backend on port 8000 as target, proxy on port 8100.
30
+ 2. Point your Frontend app to proxy port, 8100 as example
31
+ 3. The proxy runs continuously in the background. Tests control the recording/replay mode using `playwrightProxy.before()` and `playwrightProxy.after()`:
47
32
 
48
33
  ```typescript
49
34
  import { test } from '@playwright/test';
50
35
  import { playwrightProxy } from 'test-proxy-recorder';
51
36
 
52
- test('record API responses', async ({ page }, testInfo) => {
53
- // Set proxy to recording mode for this test
54
- await playwrightProxy.before(testInfo, 'recording');
37
+ test('Test UI with API responses', async ({ page }, testInfo) => {
38
+ // Set proxy to recording mode to record mocks, sanitized test title will be used as file name
39
+ await playwrightProxy.before(testInfo, 'record');
55
40
 
56
41
  // Make requests - they will be recorded
57
- await page.goto('http://localhost:8080/api/data');
58
-
59
- // Your test assertions here
60
- await expect(page.getByText('Data loaded')).toBeVisible();
42
+ await page.goto('/myPage');
43
+ /// ... test content ...
61
44
 
62
- // Clean up - return to transparent mode
45
+ // Save mock and return to transparent mode
63
46
  await playwrightProxy.after(testInfo);
64
47
  });
65
48
 
@@ -67,34 +50,13 @@ test('replay recorded responses', async ({ page }, testInfo) => {
67
50
  // Set proxy to replay mode - uses recording from test above
68
51
  await playwrightProxy.before(testInfo, 'replay');
69
52
 
70
- // This will use recorded responses instead of hitting the real API
71
- await page.goto('http://localhost:8080/api/data');
72
-
73
- await expect(page.getByText('Data loaded')).toBeVisible();
53
+ await page.goto('/myPage');
54
+ /// ... test content ...
74
55
 
75
56
  await playwrightProxy.after(testInfo);
76
57
  });
77
58
  ```
78
59
 
79
- You can also use standalone functions for more control:
80
-
81
- ```typescript
82
- import { test } from '@playwright/test';
83
- import { setProxyMode, generateSessionId } from 'test-proxy-recorder';
84
-
85
- test('custom proxy control', async ({ page }, testInfo) => {
86
- const sessionId = generateSessionId(testInfo);
87
-
88
- // Start recording with a 30s timeout
89
- await setProxyMode('recording', sessionId, 30000);
90
-
91
- await page.goto('http://localhost:8080/api/data');
92
-
93
- // Switch to transparent mode
94
- await setProxyMode('transparent', sessionId);
95
- });
96
- ```
97
-
98
60
  ## How It Works
99
61
 
100
62
  The proxy server runs continuously and can switch between three modes:
@@ -113,7 +75,7 @@ Replays previously recorded responses from disk instead of hitting the real API.
113
75
 
114
76
  ## Modes Control
115
77
 
116
- ### Via Playwright (Recommended)
78
+ ### Via Playwright
117
79
 
118
80
  ```typescript
119
81
  // Recording mode
@@ -129,40 +91,76 @@ await playwrightProxy.after(testInfo);
129
91
 
130
92
  ### Via HTTP Control Endpoint
131
93
 
94
+ Using curl:
95
+
132
96
  ```bash
133
97
  # Switch to record mode
134
- curl -X POST http://localhost:8080/__proxy_control__ \
98
+ curl -X POST http://localhost:8100/__control \
135
99
  -H "Content-Type: application/json" \
136
- -d '{"mode": "record", "id": "test-session-1", "timeout": 30000}'
100
+ -d '{"mode": "record", "id": "my-testfile-1", "timeout": 30000}'
137
101
 
138
102
  # Switch to replay mode
139
- curl -X POST http://localhost:8080/__proxy_control__ \
103
+ curl -X POST http://localhost:8100/__control \
140
104
  -H "Content-Type: application/json" \
141
- -d '{"mode": "replay", "id": "test-session-1"}'
105
+ -d '{"mode": "replay", "id": "my-testfile-1"}'
142
106
 
143
107
  # Switch to transparent mode
144
- curl -X POST http://localhost:8080/__proxy_control__ \
108
+ curl -X POST http://localhost:8100/__control \
145
109
  -H "Content-Type: application/json" \
146
- -d '{"mode": "transparent", "id": "test-session-1"}'
110
+ -d '{"mode": "transparent", "id": "my-testfile-1"}'
147
111
  ```
148
112
 
149
- ## CLI Usage
113
+ Using JavaScript fetch:
114
+
115
+ ```javascript
116
+ // Switch to record mode
117
+ await fetch('http://localhost:8100/__control', {
118
+ method: 'POST',
119
+ headers: {
120
+ 'Content-Type': 'application/json',
121
+ },
122
+ body: JSON.stringify({
123
+ mode: 'record',
124
+ id: 'my-testfile-1',
125
+ timeout: 30000
126
+ })
127
+ });
128
+
129
+ // Switch to replay mode
130
+ await fetch('http://localhost:8100/__control', {
131
+ method: 'POST',
132
+ headers: {
133
+ 'Content-Type': 'application/json',
134
+ },
135
+ body: JSON.stringify({
136
+ mode: 'replay',
137
+ id: 'my-testfile-1'
138
+ })
139
+ });
140
+
141
+ // Switch to transparent mode
142
+ await fetch('http://localhost:8100/__control', {
143
+ method: 'POST',
144
+ headers: {
145
+ 'Content-Type': 'application/json',
146
+ },
147
+ body: JSON.stringify({
148
+ mode: 'transparent',
149
+ })
150
+ });
151
+ ```
152
+
153
+ ## Usage
150
154
 
151
155
  ```bash
152
156
  # Start proxy server
153
- test-proxy-recorder --port 8080 --target http://localhost:3000 --recordings ./recordings
154
-
155
- # With multiple targets for load balancing
156
- test-proxy-recorder --port 8080 \
157
- --target http://localhost:3000 \
158
- --target http://localhost:3001 \
159
- --recordings ./recordings
157
+ test-proxy-recorder --port 8100 --target http://localhost:8000 --recordings ./recordings
160
158
  ```
161
159
 
162
160
  ### CLI Options
163
161
 
164
162
  - `--port, -p`: Port to listen on (default: 8080)
165
- - `--target, -t`: Backend target URL (can be specified multiple times)
163
+ - `--target, -t`: Backend target URL (can add multiple targets)
166
164
  - `--recordings, -r`: Directory to store recordings (default: ./recordings)
167
165
 
168
166
  ## API
@@ -180,13 +178,13 @@ class ProxyServer {
180
178
 
181
179
  ### Control Endpoint
182
180
 
183
- Send POST requests to `/__proxy_control__` with JSON body:
181
+ Send POST requests to `/__control` with JSON body:
184
182
 
185
183
  ```typescript
186
184
  interface ControlRequest {
187
185
  mode: 'transparent' | 'record' | 'replay';
188
- id?: string; // Required for record/replay modes
189
- timeout?: number; // Auto-switch to transparent mode after timeout (ms)
186
+ id?: string; // Will be used as file name for recordings, required for record/replay modes
187
+ timeout?: number; // Auto-switch to transparent mode after timeout (ms), default 120 seconds
190
188
  }
191
189
  ```
192
190
 
@@ -198,36 +196,11 @@ import { playwrightProxy } from 'test-proxy-recorder';
198
196
  // Main helper object for use with Playwright tests
199
197
  const playwrightProxy = {
200
198
  // Set proxy mode before test
201
- async before(testInfo: PlaywrightTestInfo, mode: 'recording' | 'replay' | 'transparent'): Promise<void>;
199
+ async before(testInfo: PlaywrightTestInfo, mode: 'record' | 'replay' | 'transparent'): Promise<void>;
202
200
 
203
201
  // Reset to transparent mode after test
204
202
  async after(testInfo: PlaywrightTestInfo): Promise<void>;
205
203
  };
206
-
207
- // Standalone functions for custom control:
208
- import {
209
- setProxyMode, // Set mode with custom session ID
210
- generateSessionId, // Generate session ID from test info
211
- startRecording, // Helper to start recording
212
- startReplay, // Helper to start replay
213
- stopProxy // Helper to stop recording/replay
214
- } from 'test-proxy-recorder';
215
- ```
216
-
217
- ### Usage Pattern
218
-
219
- ```typescript
220
- test('your test', async ({ page }, testInfo) => {
221
- // Setup: Set proxy mode at start of test
222
- await playwrightProxy.before(testInfo, 'replay');
223
-
224
- // Your test code here
225
- await page.goto('/your-page');
226
- await expect(page.getByText('Something')).toBeVisible();
227
-
228
- // Cleanup: Return to transparent mode
229
- await playwrightProxy.after(testInfo);
230
- });
231
204
  ```
232
205
 
233
206
  ## Recording Format
@@ -252,20 +225,20 @@ Each recording contains:
252
225
  1. **Start the proxy server** (runs continuously):
253
226
 
254
227
  ```bash
255
- test-proxy-recorder http://localhost:3000 --port 8080
228
+ test-proxy-recorder http://localhost:8000 --port 8100
256
229
  ```
257
230
 
258
231
  2. **Configure your app** to use the proxy:
259
232
 
260
233
  ```bash
261
- export EXTERNAL_API_URL=http://localhost:8080
234
+ export EXTERNAL_API_URL=http://localhost:8100 yarn dev
262
235
  ```
263
236
 
264
237
  3. **Record responses** (first run):
265
238
 
266
239
  ```typescript
267
240
  test('my test', async ({ page }, testInfo) => {
268
- await playwrightProxy.before(testInfo, 'recording');
241
+ await playwrightProxy.before(testInfo, 'record');
269
242
  // Test interacts with real API through proxy
270
243
  await page.goto('/my-page');
271
244
  await playwrightProxy.after(testInfo);
@@ -283,68 +256,10 @@ Each recording contains:
283
256
  });
284
257
  ```
285
258
 
286
- ## Use Cases
287
-
288
- - **Fast CI/CD Tests**: Record API responses once, replay them for instant test execution
289
- - **Deterministic Tests**: Same responses every time, no flaky network issues
290
- - **API Contract Testing**: Verify frontend handles all API scenarios
291
- - **WebSocket Testing**: Record and replay complex WebSocket message sequences
292
-
293
- ## Configuration Examples
294
-
295
- ### With Environment Variables
296
-
297
- ```typescript
298
- const proxy = new ProxyServer(
299
- [process.env.BACKEND_URL || 'http://localhost:3000'],
300
- process.env.RECORDINGS_DIR || './recordings'
301
- );
302
- ```
303
-
304
- ### Multiple Backend Targets
305
-
306
- ```typescript
307
- // Round-robin load balancing between targets
308
- const proxy = new ProxyServer(
309
- [
310
- 'http://backend-1:3000',
311
- 'http://backend-2:3000',
312
- 'http://backend-3:3000'
313
- ],
314
- './recordings'
315
- );
316
- ```
317
-
318
- ## WebSocket Support
319
-
320
- WebSocket connections are automatically detected and recorded/replayed:
321
-
322
- ```typescript
323
- test('websocket test', async ({ page }, testInfo) => {
324
- // Recording WebSocket messages
325
- await playwrightProxy.before(testInfo, 'recording');
326
-
327
- await page.goto('/websocket-page');
328
- // WebSocket connections and messages are recorded
329
-
330
- await playwrightProxy.after(testInfo);
331
- });
332
-
333
- test('websocket replay', async ({ page }, testInfo) => {
334
- // Replay WebSocket messages
335
- await playwrightProxy.before(testInfo, 'replay');
336
-
337
- await page.goto('/websocket-page');
338
- // Previously recorded WebSocket messages are replayed
339
-
340
- await playwrightProxy.after(testInfo);
341
- });
342
- ```
343
-
344
259
  ## Requirements
345
260
 
346
261
  - Node.js >= 22.0.0
347
- - For Playwright integration: @playwright/test >= 1.0.0
262
+ - @playwright/test >= 1.0.0
348
263
 
349
264
  ## License
350
265
 
@@ -353,11 +268,3 @@ MIT
353
268
  ## Contributing
354
269
 
355
270
  Contributions are welcome! Please feel free to submit a Pull Request.
356
-
357
- ## Author
358
-
359
- asmyshlyaev177
360
-
361
- ## Repository
362
-
363
- [https://github.com/asmyshlyaev177/test-proxy-recorder](https://github.com/asmyshlyaev177/test-proxy-recorder)