@@ -17,6 +17,7 @@ async function captureScreenshotsForConfig(
1717 ctx . log . debug ( `*** urlConfig ${ JSON . stringify ( urlConfig ) } ` ) ;
1818
1919 let { name, url, waitForTimeout, execute, pageEvent, userAgent} = urlConfig ;
20+ let beforeNavigationScript = execute ?. beforeNavigation ;
2021 let afterNavigationScript = execute ?. afterNavigation ;
2122 let beforeSnapshotScript = execute ?. beforeSnapshot ;
2223 let waitUntilEvent = pageEvent || process . env . SMARTUI_PAGE_WAIT_UNTIL_EVENT || 'load' ;
@@ -28,6 +29,77 @@ async function captureScreenshotsForConfig(
2829 let contextOptions : Record < string , any > = {
2930 ignoreHTTPSErrors : ctx . config . ignoreHTTPSErrors
3031 } ;
32+
33+
34+
35+ // Resolve proxy/tunnel/geolocation-proxy from global config
36+ try {
37+ if ( ctx . config . tunnel && ctx . config . tunnel . tunnelName ) {
38+ if ( ctx . tunnelDetails && ctx . tunnelDetails . tunnelPort != - 1 && ctx . tunnelDetails . tunnelHost ) {
39+ const tunnelServer = `http://${ ctx . tunnelDetails . tunnelHost } :${ ctx . tunnelDetails . tunnelPort } ` ;
40+ ctx . log . info ( `URL Capture :: Using tunnel address: ${ tunnelServer } ` ) ;
41+ contextOptions . proxy = { server : tunnelServer } ;
42+ } else {
43+ let tunnelResp = await ctx . client . getTunnelDetails ( ctx , ctx . log ) ;
44+ ctx . log . debug ( `Tunnel Response: ${ JSON . stringify ( tunnelResp ) } ` )
45+ if ( tunnelResp && tunnelResp . data && tunnelResp . data . host && tunnelResp . data . port ) {
46+ ctx . tunnelDetails = {
47+ tunnelHost : tunnelResp . data . host ,
48+ tunnelPort : tunnelResp . data . port ,
49+ tunnelName : tunnelResp . data . tunnel_name
50+ } as any ;
51+ const tunnelServer = `http://${ ctx . tunnelDetails . tunnelHost } :${ ctx . tunnelDetails . tunnelPort } ` ;
52+ ctx . log . info ( `URL Capture :: Using tunnel address: ${ tunnelServer } ` ) ;
53+ contextOptions . proxy = { server : tunnelServer } ;
54+ } else if ( tunnelResp && tunnelResp . error ) {
55+ if ( tunnelResp . error . message ) {
56+ ctx . log . warn ( `Error while fetching tunnel details: ${ tunnelResp . error . message } ` )
57+ }
58+ }
59+ }
60+ } else if ( ctx . config . geolocation && ctx . config . geolocation !== '' ) {
61+ // Use cached geolocation proxy if available for the same geolocation key
62+ if ( ctx . geolocationData && ctx . geolocationData . proxy && ctx . geolocationData . username && ctx . geolocationData . password && ctx . geolocationData . geoCode === ctx . config . geolocation ) {
63+ ctx . log . info ( `URL Capture :: Using cached geolocation proxy for ${ ctx . config . geolocation } ` ) ;
64+ contextOptions . proxy = {
65+ server : ctx . geolocationData . proxy ,
66+ username : ctx . geolocationData . username ,
67+ password : ctx . geolocationData . password
68+ } ;
69+ } else {
70+ const geoResp = await ctx . client . getGeolocationProxy ( ctx . config . geolocation , ctx . log ) ;
71+ ctx . log . debug ( `Geolocation proxy response: ${ JSON . stringify ( geoResp ) } ` ) ;
72+ if ( geoResp && geoResp . data && geoResp . data . proxy && geoResp . data . username && geoResp . data . password ) {
73+ ctx . log . info ( `URL Capture :: Using geolocation proxy for ${ ctx . config . geolocation } ` ) ;
74+ ctx . geolocationData = {
75+ proxy : geoResp . data . proxy ,
76+ username : geoResp . data . username ,
77+ password : geoResp . data . password ,
78+ geoCode : ctx . config . geolocation
79+ } as any ;
80+ contextOptions . proxy = {
81+ server : geoResp . data . proxy ,
82+ username : geoResp . data . username ,
83+ password : geoResp . data . password
84+ } ;
85+ } else {
86+ ctx . log . warn ( `Geolocation proxy not available for '${ ctx . config . geolocation } ', falling back if dedicatedProxyURL present` ) ;
87+ if ( ctx . config . dedicatedProxyURL && ctx . config . dedicatedProxyURL !== '' ) {
88+ ctx . log . info ( `URL Capture :: Using dedicated proxy: ${ ctx . config . dedicatedProxyURL } ` ) ;
89+ contextOptions . proxy = { server : ctx . config . dedicatedProxyURL } ;
90+ }
91+ }
92+ }
93+ } else if ( ctx . config . dedicatedProxyURL && ctx . config . dedicatedProxyURL !== '' ) {
94+ ctx . log . info ( `URL Capture :: Using dedicated proxy: ${ ctx . config . dedicatedProxyURL } ` ) ;
95+ contextOptions . proxy = { server : ctx . config . dedicatedProxyURL } ;
96+ }
97+
98+ // Note: when using IP-based geolocation via proxy, browser geolocation permission is not required
99+
100+ } catch ( e ) {
101+ ctx . log . debug ( `Failed resolving tunnel/proxy details: ${ e } ` ) ;
102+ }
31103 let page : Page ;
32104 if ( browserName == constants . CHROME ) contextOptions . userAgent = constants . CHROME_USER_AGENT ;
33105 else if ( browserName == constants . FIREFOX ) contextOptions . userAgent = constants . FIREFOX_USER_AGENT ;
@@ -46,6 +118,16 @@ async function captureScreenshotsForConfig(
46118 const browser = browsers [ browserName ] ;
47119 context = await browser ?. newContext ( contextOptions ) ;
48120 page = await context ?. newPage ( ) ;
121+
122+ if ( beforeNavigationScript && beforeNavigationScript !== "" ) {
123+ const wrappedScript = new Function ( 'page' , `
124+ return (async () => {
125+ ${ beforeNavigationScript }
126+ })();
127+ ` ) ;
128+ ctx . log . debug ( `Executing before navigation script: ${ wrappedScript } ` ) ;
129+ await wrappedScript ( page ) ;
130+ }
49131 const headersObject : Record < string , string > = { } ;
50132 if ( ctx . config . requestHeaders && Array . isArray ( ctx . config . requestHeaders ) ) {
51133 ctx . config . requestHeaders . forEach ( ( headerObj ) => {
@@ -62,6 +144,12 @@ async function captureScreenshotsForConfig(
62144 } ) ;
63145 }
64146
147+ if ( ctx . config . basicAuthorization ) {
148+ ctx . log . debug ( `Adding basic authorization to the headers for root url` ) ;
149+ let token = Buffer . from ( `${ ctx . config . basicAuthorization . username } :${ ctx . config . basicAuthorization . password } ` ) . toString ( 'base64' ) ;
150+ headersObject [ 'Authorization' ] = `Basic ${ token } ` ;
151+ }
152+
65153 ctx . log . debug ( `Combined headers: ${ JSON . stringify ( headersObject ) } ` ) ;
66154 if ( Object . keys ( headersObject ) . length > 0 ) {
67155 await page . setExtraHTTPHeaders ( headersObject ) ;
0 commit comments