wdio-testrecorder-reporter
Version:
Package to record and save wdio cucumber test executions
122 lines (121 loc) • 6.26 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const reporter_1 = __importDefault(require("@wdio/reporter"));
const logger_1 = __importDefault(require("@wdio/logger"));
const uuid_1 = require("uuid");
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const remove_1 = require("fs-extra/lib/remove");
const ffmpeg_1 = __importDefault(require("@ffmpeg-installer/ffmpeg"));
const child_process_1 = require("child_process");
const log = (0, logger_1.default)('wdio-testrecorder-reporter');
const DEFAULT_VIDEO_OUTPUT_FOLDER = '../../../tmp/';
const DEFAULT_JSON_WIRE_ACTION = '../default/wdioCommand.json';
const DEFAULT_ATTACH_VIDEO_TO_CUCUMBER_REPORT = false;
const DEFAULT_REMOVE_ATTACHED_VIDEOS = false;
let testId = null;
let scenarioName = null;
let imageCapturedCount = 0;
class TestRecoder extends reporter_1.default {
constructor(options) {
super(options);
// Store video output in given path
if (!options.videoOutputPath) {
this.videoOutputPath = path_1.default.join(__dirname, DEFAULT_VIDEO_OUTPUT_FOLDER);
log.warn(`The 'videoOutputPath' was not set, it has been set to the default '${this.videoOutputPath}'`);
}
else {
this.videoOutputPath = options.videoOutputPath;
}
// Determine whether to attach video to cucumber tests
if (typeof options.attachVideoToCucumberReport === 'boolean') {
if (!options.attachVideoToCucumberReport) {
options.attachVideoToCucumberReport = DEFAULT_ATTACH_VIDEO_TO_CUCUMBER_REPORT;
}
}
else {
options.attachVideoToCucumberReport = DEFAULT_ATTACH_VIDEO_TO_CUCUMBER_REPORT;
log.warn(`'attachVideoToCucumberReport' received unsuported parameter, it has been set to the default '${DEFAULT_ATTACH_VIDEO_TO_CUCUMBER_REPORT}'`);
}
// Determine whether to attach video ahould be removed or not
if (typeof options.removeAttachedVideos === 'boolean') {
if (!options.removeAttachedVideos) {
options.removeAttachedVideos = DEFAULT_REMOVE_ATTACHED_VIDEOS;
}
}
else {
options.removeAttachedVideos = DEFAULT_REMOVE_ATTACHED_VIDEOS;
log.warn(`'removeAttachedVideos' received unsuported parameter, it has been set to the default '${DEFAULT_REMOVE_ATTACHED_VIDEOS}'`);
}
options.jsonWireCommands = DEFAULT_JSON_WIRE_ACTION;
}
onSuiteStart(suiteStats) {
const suite = JSON.parse(JSON.stringify(suiteStats));
if (suite.type === 'scenario') {
testId = (0, uuid_1.v4)();
scenarioName = suite.title;
scenarioName = scenarioName.replace(/[^a-zA-Z]/g, '_');
scenarioName = scenarioName.trim();
// initialize empty dir for storing images and videos
if (!fs_1.default.existsSync(`${this.videoOutputPath}`)) {
fs_1.default.mkdirSync(`${this.videoOutputPath}`);
}
}
}
onAfterCommand(commandArgs) {
const command = commandArgs.endpoint.substring(commandArgs.endpoint.lastIndexOf('/') + 1).trim();
const actions = JSON.parse((fs_1.default.readFileSync(path_1.default.resolve(path_1.default.join(__dirname, this.options.jsonWireCommands)))).toString());
if (actions.jsonWireActions.includes(command)) {
const videoOutputPath = path_1.default.resolve(this.videoOutputPath);
const imageName = 'img' + imageCapturedCount.toString().padStart(3, '0');
const fileName = `${videoOutputPath}/${testId}-${scenarioName}/` + imageName + '.png';
if (testId !== null && scenarioName !== null) {
if (!fs_1.default.existsSync(`${videoOutputPath}/${testId}-${scenarioName}`)) {
fs_1.default.mkdirSync(`${videoOutputPath}/${testId}-${scenarioName}`);
}
//@ts-expect-error
browser.saveScreenshot(fileName);
imageCapturedCount++;
}
}
}
onSuiteEnd(suiteStats) {
const suite = JSON.parse(JSON.stringify(suiteStats));
if (suite.type === 'scenario') {
const videoOutputPath = path_1.default.resolve(this.videoOutputPath);
const imagePath = `${videoOutputPath}/${testId}-${scenarioName}/img%03d.png`;
const videoPath = `${videoOutputPath}/videos/${testId}-${scenarioName}.mp4`;
if (!fs_1.default.existsSync(`${videoOutputPath}/videos/`)) {
fs_1.default.mkdirSync(`${videoOutputPath}/videos`);
}
if (fs_1.default.existsSync(`${videoPath}`)) {
(0, remove_1.removeSync)(`${videoPath}`);
}
try {
const command = `${ffmpeg_1.default.path} -y -r 10 -i ${imagePath} -vcodec libx264 -crf 32 -pix_fmt yuv420p -vf "scale=1200:trunc(ow/a/2)*2","setpts=3.0*PTS" ${videoPath}`;
//@ts-expect-error
(0, child_process_1.execSync)(command, { stdio: 'ignore', shell: true, windowsHide: true });
// Remove converted screenshot images
(0, remove_1.removeSync)(`${videoOutputPath}/${testId}-${scenarioName}`);
// Converts the recorded video to base64 string.
//@ts-expect-error
const base64Video = new Buffer.from(fs_1.default.readFileSync(videoPath)).toString('base64');
if (this.options.attachVideoToCucumberReport) {
//@ts-expect-error
(process.emit)('wdioCucumberJsReporter:attachment', { data: base64Video, type: 'video/mp4' });
}
if (this.options.attachVideoToCucumberReport && this.options.removeAttachedVideos) {
// Remove attached video
(0, remove_1.removeSync)(videoPath);
}
}
catch (error) {
log.error(error);
}
}
}
}
exports.default = TestRecoder;