@@ -415,7 +415,10 @@ export async function executeStep(
415415 try {
416416 // Ensure the page finished initial navigation
417417 try {
418- await page . waitForLoadState ( 'domcontentloaded' , { timeout : step . wait ?? 600000 } ) ;
418+ const currentUrl = page . url ( ) ;
419+ const isFileUrl = currentUrl . startsWith ( 'file://' ) ;
420+ const timeout = isFileUrl ? 5000 : ( step . wait ?? 600000 ) ;
421+ await page . waitForLoadState ( 'domcontentloaded' , { timeout } ) ;
419422 } catch { }
420423
421424 // Intercept responses to capture PDF even when displayed inline
@@ -523,51 +526,72 @@ export async function executeStep(
523526 // Try both approaches: wait for download event OR intercept response (unless already saved)
524527 if ( ! pdfSaved ) {
525528 try {
526- // Reload the page to trigger route interception
527- const [ response , download ] = await Promise . all ( [
528- page . reload ( { waitUntil : 'networkidle' , timeout : step . wait ?? 60000 } ) . catch ( ( ) => null ) ,
529- page . waitForEvent ( 'download' , { timeout : 5000 } ) . catch ( ( ) => null )
530- ] ) ;
531-
532- if ( download ) {
533- // If download event occurred, save it
534- await download . saveAs ( resolvedPath ) ;
535- savedPath = resolvedPath ;
536- pdfSaved = true ;
537- console . log ( ` 📄 PDF saved via download event to ${ resolvedPath } ` ) ;
538- } else if ( response ) {
539- // Check if the response itself is a PDF
540- const contentType = response . headers ( ) [ 'content-type' ] || '' ;
541- if ( contentType . includes ( 'application/pdf' ) && ! pdfSaved ) {
542- const buffer = await response . body ( ) ;
543- if ( buffer . length > 0 ) {
544- fs . writeFileSync ( resolvedPath , buffer ) ;
545- savedPath = resolvedPath ;
546- pdfSaved = true ;
547- console . log (
548- ` 📄 PDF saved via response body (${ ( buffer . length / 1024 ) . toFixed ( 2 ) } KB) to ${ resolvedPath } `
549- ) ;
550- }
551- } else {
552- // Wait a bit for route interception to capture it
553- await page . waitForTimeout ( 2000 ) ;
554- if ( interceptedData . buffer && ! pdfSaved && interceptedData . buffer . length > 0 ) {
555- fs . writeFileSync ( resolvedPath , interceptedData . buffer ) ;
556- savedPath = resolvedPath ;
557- pdfSaved = true ;
558- console . log (
559- ` 📄 PDF saved via intercepted response (${ ( interceptedData . buffer . length / 1024 ) . toFixed ( 2 ) } KB) to ${ resolvedPath } `
560- ) ;
529+ // Check if we're on a file:// URL - networkidle doesn't work well with file URLs
530+ const reloadUrl = page . url ( ) ;
531+ const isFileUrl = reloadUrl . startsWith ( 'file://' ) ;
532+ const waitUntil = isFileUrl ? 'domcontentloaded' : 'networkidle' ;
533+ const timeout = isFileUrl ? 3000 : ( step . wait ?? 60000 ) ;
534+
535+ // For file:// URLs, skip reload if no PDF URL is detected
536+ if ( isFileUrl && ! reloadUrl . includes ( '.pdf' ) ) {
537+ console . log ( ` 📄 File URL detected without PDF - skipping savePDF (use printToPDF for HTML pages)` ) ;
538+ // Still check if we intercepted anything during navigation
539+ await page . waitForTimeout ( 1000 ) ;
540+ if ( interceptedData . buffer && interceptedData . buffer . length > 0 ) {
541+ fs . writeFileSync ( resolvedPath , interceptedData . buffer ) ;
542+ savedPath = resolvedPath ;
543+ pdfSaved = true ;
544+ console . log (
545+ ` 📄 PDF saved via intercepted response (${ ( interceptedData . buffer . length / 1024 ) . toFixed ( 2 ) } KB) to ${ resolvedPath } `
546+ ) ;
547+ }
548+ } else {
549+ // Reload the page to trigger route interception
550+ const [ response , download ] = await Promise . all ( [
551+ page . reload ( { waitUntil, timeout } ) . catch ( ( ) => null ) ,
552+ page . waitForEvent ( 'download' , { timeout : 3000 } ) . catch ( ( ) => null )
553+ ] ) ;
554+
555+ if ( download ) {
556+ // If download event occurred, save it
557+ await download . saveAs ( resolvedPath ) ;
558+ savedPath = resolvedPath ;
559+ pdfSaved = true ;
560+ console . log ( ` 📄 PDF saved via download event to ${ resolvedPath } ` ) ;
561+ } else if ( response ) {
562+ // Check if the response itself is a PDF
563+ const contentType = response . headers ( ) [ 'content-type' ] || '' ;
564+ if ( contentType . includes ( 'application/pdf' ) && ! pdfSaved ) {
565+ const buffer = await response . body ( ) ;
566+ if ( buffer . length > 0 ) {
567+ fs . writeFileSync ( resolvedPath , buffer ) ;
568+ savedPath = resolvedPath ;
569+ pdfSaved = true ;
570+ console . log (
571+ ` 📄 PDF saved via response body (${ ( buffer . length / 1024 ) . toFixed ( 2 ) } KB) to ${ resolvedPath } `
572+ ) ;
573+ }
574+ } else {
575+ // Wait a bit for route interception to capture it
576+ await page . waitForTimeout ( 2000 ) ;
577+ if ( interceptedData . buffer && ! pdfSaved && interceptedData . buffer . length > 0 ) {
578+ fs . writeFileSync ( resolvedPath , interceptedData . buffer ) ;
579+ savedPath = resolvedPath ;
580+ pdfSaved = true ;
581+ console . log (
582+ ` 📄 PDF saved via intercepted response (${ ( interceptedData . buffer . length / 1024 ) . toFixed ( 2 ) } KB) to ${ resolvedPath } `
583+ ) ;
584+ }
561585 }
586+ } else if ( interceptedData . buffer && ! pdfSaved && interceptedData . buffer . length > 0 ) {
587+ // Fallback: use intercepted buffer
588+ fs . writeFileSync ( resolvedPath , interceptedData . buffer ) ;
589+ savedPath = resolvedPath ;
590+ pdfSaved = true ;
591+ console . log (
592+ ` 📄 PDF saved via intercepted response (${ ( interceptedData . buffer . length / 1024 ) . toFixed ( 2 ) } KB) to ${ resolvedPath } `
593+ ) ;
562594 }
563- } else if ( interceptedData . buffer && ! pdfSaved && interceptedData . buffer . length > 0 ) {
564- // Fallback: use intercepted buffer
565- fs . writeFileSync ( resolvedPath , interceptedData . buffer ) ;
566- savedPath = resolvedPath ;
567- pdfSaved = true ;
568- console . log (
569- ` 📄 PDF saved via intercepted response (${ ( interceptedData . buffer . length / 1024 ) . toFixed ( 2 ) } KB) to ${ resolvedPath } `
570- ) ;
571595 }
572596 } catch ( error : any ) {
573597 console . log ( ` 📄 Error during PDF save: ${ error . message } ` ) ;
0 commit comments