/********************************************************************* * Copyright (c) 2019 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 '..'; @injectable() export class ScreenCatcher { constructor(@inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) { } async catchMethodScreen(methodName: string, methodIndex: number, screenshotIndex: number) { const executionScreenCastDir = `${TestConstants.TS_SELENIUM_REPORT_FOLDER}/executionScreencast`; const executionScreenCastErrorsDir = `${TestConstants.TS_SELENIUM_REPORT_FOLDER}/executionScreencastErrors`; const formattedMethodIndex: string = new Intl.NumberFormat('en-us', { minimumIntegerDigits: 3 }).format(methodIndex); const formattedScreenshotIndex: string = 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: Date = new Date(); const timeStr: string = date.toLocaleTimeString('en-us', { hour12: false }) + '.' + new Intl.NumberFormat('en-us', { minimumIntegerDigits: 3 }).format(date.getMilliseconds()); const screenshotPath: string = `${executionScreenCastDir}/${formattedMethodIndex}${formattedScreenshotIndex}--(${timeStr}): ${methodName}.png`; try { await this.catchScreen(screenshotPath); } catch (err) { if (!fs.existsSync(executionScreenCastErrorsDir)) { fs.mkdirSync(executionScreenCastErrorsDir); } let errorLogFilePath: string = screenshotPath.replace('.png', '.txt'); errorLogFilePath = errorLogFilePath.replace(executionScreenCastDir, executionScreenCastErrorsDir); await this.writeErrorLog(errorLogFilePath, err); } } async catchScreen(screenshotPath: string) { const screenshot: string = await this.driverHelper.getDriver().takeScreenshot(); const screenshotStream = fs.createWriteStream(screenshotPath); screenshotStream.write(new Buffer(screenshot, 'base64')); screenshotStream.end(); } async writeErrorLog(errorLogPath: string, err: Error) { console.log(`Failed to save screenshot, additional information in the ${errorLogPath}`); if (err.stack) { const screenshotStream = fs.createWriteStream(errorLogPath); screenshotStream.write(new Buffer(err.stack, 'utf8')); screenshotStream.end(); } } }