/*********************************************************************
 * Copyright (c) 2021 Red Hat, Inc.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 **********************************************************************/ import * as fs from 'fs' ; import { injectable , inject } from 'inversify' ; import { CLASSES } from '../inversify.types' ; import { DriverHelper } from './DriverHelper' ; import { TestConstants } from '..' ; import { Sanitizer } from './Sanitizer' ; import { error } from 'selenium-webdriver' ; @ injectable ( ) export class ScreenCatcher { constructor ( @ inject ( CLASSES . DriverHelper ) private readonly driverHelper , @ inject ( CLASSES . Sanitizer ) private readonly sanitizer ) { } async catchMethodScreen ( methodName , methodIndex , screenshotIndex ) { const executionScreenCastDir = `${ TestConstants . TS_SELENIUM_REPORT_FOLDER }/executionScreencast` ; const executionScreenCastErrorsDir = `${ TestConstants . TS_SELENIUM_REPORT_FOLDER }/executionScreencastErrors` ; const formattedMethodIndex = new Intl . NumberFormat ( 'en-us' , { minimumIntegerDigits : 3 } ) . format ( methodIndex ) ; const formattedScreenshotIndex = new Intl . NumberFormat ( 'en-us' , { minimumIntegerDigits : 5 } ) . format ( screenshotIndex ) . replace ( /,/g , '' ) ; if ( ! fs . existsSync ( TestConstants . TS_SELENIUM_REPORT_FOLDER ) ) { fs . mkdirSync ( TestConstants . TS_SELENIUM_REPORT_FOLDER ) ; } if ( ! fs . existsSync ( executionScreenCastDir ) ) { fs . mkdirSync ( executionScreenCastDir ) ; } const date = new Date ( ) ; const timeStr = date . toLocaleTimeString ( 'en-us' , { hour12 : false } ) + '.' + new Intl . NumberFormat ( 'en-us' , { minimumIntegerDigits : 3 } ) . format ( date . getMilliseconds ( ) ) ; const screenshotPath = `${ executionScreenCastDir }/${ formattedMethodIndex }-${ formattedScreenshotIndex }--(${ this . sanitizer . sanitize ( timeStr ) })_${ this . sanitizer . sanitize ( methodName ) }.png` ; try { await this . catchScreen ( screenshotPath ) ; } catch ( err ) { if ( ! fs . existsSync ( executionScreenCastErrorsDir ) ) { fs . mkdirSync ( executionScreenCastErrorsDir ) ; } let errorLogFilePath = screenshotPath . replace ( '.png' , '.txt' ) ; errorLogFilePath = errorLogFilePath . replace ( executionScreenCastDir , executionScreenCastErrorsDir ) ; if ( err instanceof error . IError ) { await this . writeErrorLog ( errorLogFilePath , err ) ; } } } async catchScreen ( screenshotPath ) { const screenshot = await this . driverHelper . getDriver ( ) . takeScreenshot ( ) ; const screenshotStream = fs . createWriteStream ( screenshotPath ) ; screenshotStream . write ( Buffer . from ( screenshot , 'base64' ) ) ; screenshotStream . end ( ) ; } async writeErrorLog ( errorLogPath , err ) { console . log ( `Failed to save screenshot, additional information in the ${ errorLogPath }` ) ; if ( err . stack ) { const screenshotStream = fs . createWriteStream ( errorLogPath ) ; screenshotStream . write ( Buffer . from ( err . stack , 'utf8' ) ) ; screenshotStream . end ( ) ; } } }