@@ -2,6 +2,9 @@ import fs from 'fs'
22import { Context } from '../types.js'
33import { chromium , firefox , webkit , Browser } from '@playwright/test'
44import constants from './constants.js' ;
5+ import chalk from 'chalk' ;
6+
7+ let isPollingActive = false ;
58
69export function delDir ( dir : string ) : void {
710 if ( fs . existsSync ( dir ) ) {
@@ -200,4 +203,94 @@ export function getRenderViewportsForOptions(options: any): Array<Record<string,
200203 ...mobileRenderViewports [ constants . MOBILE_OS_IOS ] ,
201204 ...mobileRenderViewports [ constants . MOBILE_OS_ANDROID ]
202205 ] ;
206+ }
207+
208+ // Global SIGINT handler
209+ process . on ( 'SIGINT' , ( ) => {
210+ if ( isPollingActive ) {
211+ console . log ( 'Fetching results interrupted. Exiting...' ) ;
212+ isPollingActive = false ;
213+ } else {
214+ console . log ( '\nExiting gracefully...' ) ;
215+ }
216+ process . exit ( 0 ) ;
217+ } ) ;
218+
219+ // Background polling function
220+ export async function startPolling ( ctx : Context , task : any ) : Promise < void > {
221+ ctx . log . info ( 'Fetching results in progress....' ) ;
222+ isPollingActive = true ;
223+
224+ const intervalId = setInterval ( async ( ) => {
225+ if ( ! isPollingActive ) {
226+ clearInterval ( intervalId ) ;
227+ return ;
228+ }
229+
230+ try {
231+ const resp = await ctx . client . getScreenshotData ( ctx . build . id , ctx . build . baseline , ctx . log ) ;
232+
233+ if ( ! resp . build ) {
234+ ctx . log . info ( "Error: Build data is null." ) ;
235+ clearInterval ( intervalId ) ;
236+ isPollingActive = false ;
237+ }
238+
239+ fs . writeFileSync ( ctx . options . fetchResultsFileName , JSON . stringify ( resp , null , 2 ) ) ;
240+ ctx . log . debug ( `Updated results in ${ ctx . options . fetchResultsFileName } ` ) ;
241+
242+ if ( resp . build . build_status_ind === constants . BUILD_COMPLETE || resp . build . build_status_ind === constants . BUILD_ERROR ) {
243+ clearInterval ( intervalId ) ;
244+ ctx . log . info ( `Fetching results completed. Final results written to ${ ctx . options . fetchResultsFileName } ` ) ;
245+ isPollingActive = false ;
246+
247+
248+ // Evaluating Summary
249+ let totalScreenshotsWithMismatches = 0 ;
250+ let totalVariantsWithMismatches = 0 ;
251+ const totalScreenshots = Object . keys ( resp . screenshots || { } ) . length ;
252+ let totalVariants = 0 ;
253+
254+ for ( const [ screenshot , variants ] of Object . entries ( resp . screenshots || { } ) ) {
255+ let screenshotHasMismatch = false ;
256+ let variantMismatchCount = 0 ;
257+
258+ totalVariants += variants . length ; // Add to total variants count
259+
260+ for ( const variant of variants ) {
261+ if ( variant . mismatch_percentage > 0 ) {
262+ screenshotHasMismatch = true ;
263+ variantMismatchCount ++ ;
264+ }
265+ }
266+
267+ if ( screenshotHasMismatch ) {
268+ totalScreenshotsWithMismatches ++ ;
269+ totalVariantsWithMismatches += variantMismatchCount ;
270+ }
271+ }
272+
273+ // Display summary
274+ ctx . log . info (
275+ chalk . green . bold (
276+ `\nSummary of Mismatches:\n` +
277+ `${ chalk . yellow ( 'Total Variants with Mismatches:' ) } ${ chalk . white ( totalVariantsWithMismatches ) } out of ${ chalk . white ( totalVariants ) } \n` +
278+ `${ chalk . yellow ( 'Total Screenshots with Mismatches:' ) } ${ chalk . white ( totalScreenshotsWithMismatches ) } out of ${ chalk . white ( totalScreenshots ) } \n` +
279+ `${ chalk . yellow ( 'Branch Name:' ) } ${ chalk . white ( resp . build . branch ) } \n` +
280+ `${ chalk . yellow ( 'Project Name:' ) } ${ chalk . white ( resp . project . name ) } \n` +
281+ `${ chalk . yellow ( 'Build ID:' ) } ${ chalk . white ( resp . build . build_id ) } \n`
282+ )
283+ ) ;
284+ }
285+ } catch ( error : any ) {
286+ if ( error . message . includes ( 'ENOTFOUND' ) ) {
287+ ctx . log . error ( 'Error: Network error occurred while fetching build results. Please check your connection and try again.' ) ;
288+ clearInterval ( intervalId ) ;
289+ } else {
290+ ctx . log . error ( `Error fetching screenshot data: ${ error . message } ` ) ;
291+ }
292+ clearInterval ( intervalId ) ;
293+ isPollingActive = false ;
294+ }
295+ } , 5000 ) ;
203296}
0 commit comments