Skip to content

Commit

Permalink
feat: Add logging with attachments into ReportPortal
Browse files Browse the repository at this point in the history
Signed-off-by: mdolhalo <[email protected]>
  • Loading branch information
mdolhalo committed Oct 26, 2023
1 parent f86a542 commit c22e454
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 14 deletions.
23 changes: 21 additions & 2 deletions tests/e2e/specs/MochaHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { REPORTER_CONSTANTS } from '../constants/REPORTER_CONSTANTS';

const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper);
let latestWorkspace: string = '';
export let rpApi: any = undefined;

export function registerRunningWorkspace(workspaceName: string): void {
workspaceName !== '' ? Logger.debug(`with workspaceName:${workspaceName}`) : Logger.debug('delete workspace name');
Expand All @@ -38,6 +39,10 @@ export function registerRunningWorkspace(workspaceName: string): void {

exports.mochaHooks = {
beforeAll: [
function initRPApi(): any {
rpApi = require('@reportportal/agent-js-mocha/lib/publicReportingAPI.js');
},

function decorateExternalClasses(): void {
decorate(injectable(), Main);
decorate(injectable(), LocatorLoader);
Expand Down Expand Up @@ -87,6 +92,21 @@ exports.mochaHooks = {
}
}
},
async function saveReportportalAttachments(this: Mocha.Context): Promise<void> {
if (REPORTER_CONSTANTS.SAVE_RP_REPORT_DATA && this.currentTest?.state === 'failed') {
try {
const screenshot: string = await driverHelper.getDriver().takeScreenshot();
const attachment: { name: string; type: string; content: string } = {
name: 'screenshot.png',
type: 'image/png',
content: screenshot
};
rpApi.error('Screenshot on fail: ', attachment);
} catch (e) {
rpApi.error('Could not attach the screenshot');
}
}
},
// stop and remove running workspace
function deleteWorkspaceOnFailedTest(this: Mocha.Context): void {
if (this.currentTest?.state === 'failed') {
Expand All @@ -104,8 +124,7 @@ exports.mochaHooks = {
if (!BASE_TEST_CONSTANTS.TS_DEBUG_MODE && CHROME_DRIVER_CONSTANTS.TS_USE_WEB_DRIVER_FOR_TEST) {
// ensure that fired events done
await driverHelper.wait(5000);
await driverHelper.getDriver().quit();
Logger.info('Chrome driver session stopped.');
await driverHelper.quit();
}
}
]
Expand Down
6 changes: 6 additions & 0 deletions tests/e2e/utils/DriverHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -742,4 +742,10 @@ export class DriverHelper {

await this.getDriver().navigate().to(url);
}

async quit(): Promise<void> {
Logger.trace();

await this.getDriver().quit();
}
}
62 changes: 50 additions & 12 deletions tests/e2e/utils/Logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,23 @@
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
import { REPORTER_CONSTANTS } from '../constants/REPORTER_CONSTANTS';
import { rpApi } from '../specs/MochaHooks';

export abstract class Logger {
export class Logger {
/**
* uses for logging of fatal errors.
* @param text log text
* @param indentLevel log level
*/

static error(text: string = '', indentLevel: number = 1): void {
const callerInfo: string = this.getCallerInfo();
const logLevelSymbol: string = '[ERROR] ';
this.logText(indentLevel, logLevelSymbol, `${this.getFullMessage(callerInfo, text)}`);
const message: string = this.getFullMessage(callerInfo, text);
this.logText(indentLevel, logLevelSymbol, message);
if (this.sendLogMessageIntoReportPortal()) {
rpApi.error(message);
}
}

/**
Expand All @@ -32,7 +38,11 @@ export abstract class Logger {
}
const callerInfo: string = this.getCallerInfo();
const logLevelSymbol: string = '[WARN] ';
this.logText(indentLevel, logLevelSymbol, `${this.getFullMessage(callerInfo, text)}`);
const message: string = this.getFullMessage(callerInfo, text);
this.logText(indentLevel, logLevelSymbol, message);
if (this.sendLogMessageIntoReportPortal()) {
rpApi.warn(message);
}
}

/**
Expand All @@ -46,7 +56,11 @@ export abstract class Logger {
}
const callerInfo: string = this.getCallerInfo();
const logLevelSymbol: string = '• ';
this.logText(indentLevel, logLevelSymbol, `${this.getFullMessage(callerInfo, text)}`);
const message: string = this.getFullMessage(callerInfo, text);
this.logText(indentLevel, logLevelSymbol, message);
if (this.sendLogMessageIntoReportPortal()) {
rpApi.info(message);
}
}

/**
Expand All @@ -64,7 +78,11 @@ export abstract class Logger {
}
const callerInfo: string = this.getCallerInfo();
const logLevelSymbol: string = '▼ ';
this.logText(indentLevel, logLevelSymbol, `${this.getFullMessage(callerInfo, text)}`);
const message: string = this.getFullMessage(callerInfo, text);
this.logText(indentLevel, logLevelSymbol, message);
if (this.sendLogMessageIntoReportPortal()) {
rpApi.debug(message);
}
}

/**
Expand All @@ -84,13 +102,21 @@ export abstract class Logger {
}
const callerInfo: string = this.getCallerInfo();
const logLevelSymbol: string = '‣ ';
this.logText(indentLevel, logLevelSymbol, `${this.getFullMessage(callerInfo, text)}`);
const message: string = this.getFullMessage(callerInfo, text);
this.logText(indentLevel, logLevelSymbol, message);
if (this.sendLogMessageIntoReportPortal()) {
rpApi.trace(message);
}
}

private static getFullMessage(callerInfo: string, text: string): string {
return `${callerInfo}${this.separator(text, callerInfo)}${text}`;
}

private static separator(text: string, caller: string): string {
return text ? (caller ? ' - ' : '') : '';
}

private static logText(messageIndentationLevel: number, logLevelSymbol: string, text: string): void {
if (text) {
// start group for every level
Expand All @@ -107,14 +133,26 @@ export abstract class Logger {
}
}

private static getCallerInfo(): string {
const e: Error = new Error();
const stack: string[] = e.stack ? e.stack.split('\n') : [];
private static getCallerInfo(i: number = 4): string {
const stack: string[] = this.getCallStackArray();
// " at functionName ( ..." => "functionName"
return stack[3].includes('.<anonymous') ? '' : stack[3].replace(/^\s+at\s+(.+?)\s.+/g, '$1');
return stack[i].includes('.<anonymous') ? '' : stack[i].replace(/^\s+at\s+(.+?)\s.+/g, '$1');
}

private static separator(text: string, caller: string): string {
return text ? (caller ? ' - ' : '') : '';
private static getCallStackArray(): string[] {
const e: Error = new Error();
return e.stack ? e.stack.split('\n') : [];
}

private static sendLogMessageIntoReportPortal(): boolean {
return REPORTER_CONSTANTS.SAVE_RP_REPORT_DATA && !this.isRootCaller();
}

private static isRootCaller(traceLevel: number = 6): boolean {
return this.getCallStackArray()
.slice(traceLevel, traceLevel + 2)
.reduce((acc, e): boolean => {
return acc || /MochaHooks|CheReporter/.test(e);
}, false);
}
}

0 comments on commit c22e454

Please sign in to comment.