@@ -8,6 +8,7 @@ import assert from 'node:assert';
88import { describe , it } from 'node:test' ;
99
1010import { NetworkFormatter } from '../../src/formatters/NetworkFormatter.js' ;
11+ import type { HTTPRequest } from '../../src/third_party/index.js' ;
1112import { getMockRequest , getMockResponse } from '../utils.js' ;
1213
1314describe ( 'NetworkFormatter' , ( ) => {
@@ -145,6 +146,83 @@ describe('NetworkFormatter', () => {
145146 assert . match ( result , / s o m e t e x t / ) ;
146147 } ) ;
147148
149+ it ( 'should save bodies to file when file paths are provided' , async ( ) => {
150+ const request = {
151+ method : ( ) => 'POST' ,
152+ url : ( ) => 'http://example.com' ,
153+ headers : ( ) => ( { } ) ,
154+ hasPostData : ( ) => true ,
155+ postData : ( ) => 'request body' ,
156+ response : ( ) => ( {
157+ status : ( ) => 200 ,
158+ headers : ( ) => ( { } ) ,
159+ buffer : async ( ) => Buffer . from ( 'response body' ) ,
160+ } ) ,
161+ failure : ( ) => null ,
162+ redirectChain : ( ) => [ ] ,
163+ fetchPostData : async ( ) => undefined ,
164+ } as unknown as HTTPRequest ;
165+
166+ // Let's create a temporary file path
167+ // We are just verifying logic flow here, actual FS write might fail if we don't have permissions or path is weird,
168+ // but /tmp should be fine on the system.
169+ // However, to be safe and avoid flakiness, we might want to mock writeFile.
170+ // But since we can't easily mock it, we try to use real files.
171+ const reqPath = '/tmp/test_req_' + Date . now ( ) ;
172+ const resPath = '/tmp/test_res_' + Date . now ( ) ;
173+
174+ const formatter = await NetworkFormatter . from ( request , {
175+ fetchData : true ,
176+ requestFilePath : reqPath ,
177+ responseFilePath : resPath ,
178+ } ) ;
179+
180+ const json = formatter . toJSONDetailed ( ) as {
181+ requestBody : string ;
182+ responseBody : string ;
183+ } ;
184+ assert . strictEqual ( json . requestBody , reqPath ) ;
185+ assert . strictEqual ( json . responseBody , resPath ) ;
186+ } ) ;
187+
188+ it ( 'should not truncate large bodies when saving to file' , async ( ) => {
189+ const largeBody = 'a' . repeat ( 10005 ) ;
190+ const request = {
191+ method : ( ) => 'POST' ,
192+ url : ( ) => 'http://example.com' ,
193+ headers : ( ) => ( { } ) ,
194+ hasPostData : ( ) => true ,
195+ postData : ( ) => largeBody ,
196+ response : ( ) => ( {
197+ status : ( ) => 200 ,
198+ headers : ( ) => ( { } ) ,
199+ buffer : async ( ) => Buffer . from ( largeBody ) ,
200+ } ) ,
201+ failure : ( ) => null ,
202+ redirectChain : ( ) => [ ] ,
203+ fetchPostData : async ( ) => undefined ,
204+ } as unknown as HTTPRequest ;
205+
206+ const reqPath = '/tmp/test_req_large_' + Date . now ( ) ;
207+ const resPath = '/tmp/test_res_large_' + Date . now ( ) ;
208+
209+ await NetworkFormatter . from ( request , {
210+ fetchData : true ,
211+ requestFilePath : reqPath ,
212+ responseFilePath : resPath ,
213+ } ) ;
214+
215+ // We need to verify the file content.
216+ // Since we import fs/promises in the source, we can try to use node:fs/promises here too.
217+ // Dynamic import to avoid top-level import issues if any (though we stick to standard imports).
218+ const { readFile} = await import ( 'node:fs/promises' ) ;
219+ const reqContent = await readFile ( reqPath , 'utf8' ) ;
220+ const resContent = await readFile ( resPath , 'utf8' ) ;
221+
222+ assert . strictEqual ( reqContent , largeBody ) ;
223+ assert . strictEqual ( resContent , largeBody ) ;
224+ } ) ;
225+
148226 it ( 'handles response body' , async ( ) => {
149227 const response = getMockResponse ( ) ;
150228 response . buffer = ( ) => {
0 commit comments