platform-helpers/report-helper.js

/* global browser */
'use strict';

const showdown = require('showdown').setOption('tables', 'true');
const Moment = require('moment');
const fse = require('fs-extra');
const path = require('path');
const imagemin = require('imagemin');
const utf8 = require('utf8');
const imageminPngquant = require('imagemin-pngquant');
const rootRequire = require('rpcm-root-require');
const LoggerWrapper = rootRequire('/platform-helpers/log4js-wrapper');
const Utils = rootRequire('/platform-helpers/utils');
const logger = LoggerWrapper.getLogger();
const converter = new showdown.Converter();
rootRequire('/platform-helpers/string-extensions');

/**
 * Report helper functions. Helps add context to the generated HTML reports of the test results.
 *
 * NOTE: These methods only work inside tests!
 * @module ReportHelper
 */
class ReportHelper {
  /**
   * Logs a message within the current mocha test, with optional Markdown support (defaults to 'off').
   *
   * @public
   * @param {string} message - the message (or Markdown) to be displayed in the html-report
   * @param {boolean} [parseAsMarkdown] - if provided and true, will parse the provide message as markdown
   * @returns {string} the processed string that will be used in the report
   * @example
   *
   *  // only works inside tests!
   *  it('should log some messages', async function () {
   *    // no markdown
   *    reporterHelper.logMessage('Something important you should know!')
   *
   *    // with markdown
   *    reporterHelper.logMessage('Something **important** _you_ should know!', true)
   *  })
   */
  static logMessage = (message, parseAsMarkdown) => {
    // force to string
    if (typeof message !== 'string') message = String(message);
    try {
      if (parseAsMarkdown) {
        message = converter.makeHtml(message);
      }
    } catch (e) {
      message = `Markdown conversion issue - ${e}!\n\n${message}`;
    }
    try {
      message = utf8.decode(message);
    } catch (e) {
      // message = `Encoding issue - ${e}!\n\n${message}`
    }
    process.emit('test:log', message);
    return message;
  };

  /**
   * Takes a screenshot with optional message (including Markdown support) and adds to the active mocha test.
   *
   * Returned Promise resolves when the screenshot has been taken and compressed to reduce file size.
   *
   * @public
   * @param {string} [message] - the message (or Markdown) to be displayed in the html-report
   * @param {boolean} [parseAsMarkdown] - if provided and true, will parse the provide message as markdown
   * @example
   * describe('STEP 1 - check google.com title', () => {
   *   it('should have the right title', async function () {
   *     await browser.url('https://google.com')
   *     const title = await browser.getTitle()
   *     await reporterHelper.takeScreenshot('Page load screenshot.')
   *    chai.expect(title).to.strictlyEqual('Google')
   *   })
   * })
   */
  static takeScreenshot = async (message, parseAsMarkdown) => {
    const screenshotFolderPath = 'reports/html-reports/screenshots/';
    fse.ensureDirSync(screenshotFolderPath);
    const filepath = path.join(screenshotFolderPath, Moment().format('YYYYMMDD-HHmmss.SSS') + '.png');
    browser.saveScreenshot(filepath);
    if (message) {
      this.logMessage(message, parseAsMarkdown);
    }
    process.emit('test:screenshot', filepath);
    try {
      await imagemin([filepath], {
        destination: screenshotFolderPath, // reduce size in place
        plugins: [
          // https://openbase.io/js/imagemin-pngquant
          imageminPngquant({ quality: [0.3, 0.5] })
        ]
      });
    } catch (error) {
      logger.error('report-helper ----> Screenshot optimization error: {0}{1}'.format(Utils.getNewLine(2), error));
    }
  };
}

module.exports = ReportHelper;