@@ -102,6 +102,42 @@ function createPageDownloadWaiter(page: Page, timeoutMs: number) {
102102 } ;
103103}
104104
105+ type DownloadPayload = {
106+ url ?: ( ) => string ;
107+ suggestedFilename ?: ( ) => string ;
108+ saveAs ?: ( outPath : string ) => Promise < void > ;
109+ } ;
110+
111+ async function saveDownloadPayload ( download : DownloadPayload , outPath : string ) {
112+ const suggested = download . suggestedFilename ?.( ) || "download.bin" ;
113+ const resolvedOutPath = outPath ?. trim ( ) || buildTempDownloadPath ( suggested ) ;
114+ await fs . mkdir ( path . dirname ( resolvedOutPath ) , { recursive : true } ) ;
115+ await download . saveAs ?.( resolvedOutPath ) ;
116+ return {
117+ url : download . url ?.( ) || "" ,
118+ suggestedFilename : suggested ,
119+ path : path . resolve ( resolvedOutPath ) ,
120+ } ;
121+ }
122+
123+ async function awaitDownloadPayload ( params : {
124+ waiter : ReturnType < typeof createPageDownloadWaiter > ;
125+ state : ReturnType < typeof ensurePageState > ;
126+ armId : number ;
127+ outPath ?: string ;
128+ } ) {
129+ try {
130+ const download = ( await params . waiter . promise ) as DownloadPayload ;
131+ if ( params . state . armIdDownload !== params . armId ) {
132+ throw new Error ( "Download was superseded by another waiter" ) ;
133+ }
134+ return await saveDownloadPayload ( download , params . outPath ?? "" ) ;
135+ } catch ( err ) {
136+ params . waiter . cancel ( ) ;
137+ throw err ;
138+ }
139+ }
140+
105141export async function armFileUploadViaPlaywright ( opts : {
106142 cdpUrl : string ;
107143 targetId ?: string ;
@@ -200,28 +236,7 @@ export async function waitForDownloadViaPlaywright(opts: {
200236 const armId = state . armIdDownload ;
201237
202238 const waiter = createPageDownloadWaiter ( page , timeout ) ;
203- try {
204- const download = ( await waiter . promise ) as {
205- url ?: ( ) => string ;
206- suggestedFilename ?: ( ) => string ;
207- saveAs ?: ( outPath : string ) => Promise < void > ;
208- } ;
209- if ( state . armIdDownload !== armId ) {
210- throw new Error ( "Download was superseded by another waiter" ) ;
211- }
212- const suggested = download . suggestedFilename ?.( ) || "download.bin" ;
213- const outPath = opts . path ?. trim ( ) || buildTempDownloadPath ( suggested ) ;
214- await fs . mkdir ( path . dirname ( outPath ) , { recursive : true } ) ;
215- await download . saveAs ?.( outPath ) ;
216- return {
217- url : download . url ?.( ) || "" ,
218- suggestedFilename : suggested ,
219- path : path . resolve ( outPath ) ,
220- } ;
221- } catch ( err ) {
222- waiter . cancel ( ) ;
223- throw err ;
224- }
239+ return await awaitDownloadPayload ( { waiter, state, armId, outPath : opts . path } ) ;
225240}
226241
227242export async function downloadViaPlaywright ( opts : {
@@ -257,23 +272,7 @@ export async function downloadViaPlaywright(opts: {
257272 } catch ( err ) {
258273 throw toAIFriendlyError ( err , ref ) ;
259274 }
260-
261- const download = ( await waiter . promise ) as {
262- url ?: ( ) => string ;
263- suggestedFilename ?: ( ) => string ;
264- saveAs ?: ( outPath : string ) => Promise < void > ;
265- } ;
266- if ( state . armIdDownload !== armId ) {
267- throw new Error ( "Download was superseded by another waiter" ) ;
268- }
269- const suggested = download . suggestedFilename ?.( ) || "download.bin" ;
270- await fs . mkdir ( path . dirname ( outPath ) , { recursive : true } ) ;
271- await download . saveAs ?.( outPath ) ;
272- return {
273- url : download . url ?.( ) || "" ,
274- suggestedFilename : suggested ,
275- path : path . resolve ( outPath ) ,
276- } ;
275+ return await awaitDownloadPayload ( { waiter, state, armId, outPath } ) ;
277276 } catch ( err ) {
278277 waiter . cancel ( ) ;
279278 throw err ;
0 commit comments