@rws-air/jestscreenshot
Version:
Jest reporter plugin to take Puppeteer screenshots on failing tests
145 lines • 6.22 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.JestScreenshot = exports.JestScreenshotError = void 0;
const form_data_1 = __importDefault(require("form-data"));
const fs_nextra_1 = require("fs-nextra");
const moment_1 = __importDefault(require("moment"));
const node_fetch_1 = __importDefault(require("node-fetch"));
const path_1 = __importDefault(require("path"));
class JestScreenshotError extends Error {
/**
* Constructs a new JestScreenshotError
* @param message Message to append to standard message for JestScreenshotError
*/
constructor(message) {
super();
this.message = `Failed to create JestScreenshot Reporter.\n${message}`;
}
}
exports.JestScreenshotError = JestScreenshotError;
/**
* The main class of JestScreenshot that should be initialized with config
*
* @remarks Jest reporter plugin to take Puppeteer screenshots on failing tests
*
* @param page The Puppeteer page object to screenshot
* @param dirName The directory to create a "screenshots" folder in
* @param testName An optional name of the script that is currently being ran
* @param slackUpload Optionally upload screenshots to slack after making them.
*
* Requires you pass a token to the slackToken option, or set the SLACK_WEBTOKEN environment variable
* @param slackToken Token to use when uploading to slack. Required when you pass slackUpload=true
*
* Optionally you can also pass this through the environment variable "SLACK_WEBTOKEN".
*
* This environment variable will take priority over passing it as option
*
* @param slackChannels Channels to send the Slack upload to
*
* Should be an array of Slack channel IDs
*
* Only used when slackUpload is set to true
*/
class JestScreenshot {
/**
* Constructs a new JestScreenshot
* @param options The options to pass to the instance of JestScreenshot
*/
constructor(options) {
this.shouldUploadToSlack = false;
this.slackToken = '';
this.slackChannels = [];
if (!Reflect.has(options, 'page')) {
throw new JestScreenshotError('You should pass page to screenshot to options (page)!!');
}
if (!Reflect.has(options, 'dirName')) {
throw new JestScreenshotError('You should pass the name of the directory to save images to the options (dirName)!!');
}
this.page = options.page;
this.dirName = `${options.dirName}/screenshots`;
this.testName = options.testName && 'testName' in options ? options.testName : 'jest-test';
this.shouldUploadToSlack = options.slackUpload && 'slackUpload' in options ? options.slackUpload : false;
if (this.shouldUploadToSlack) {
if (process.env.SLACK_WEBTOKEN) {
this.slackToken = process.env.SLACK_WEBTOKEN;
}
else {
this.slackToken = options.slackToken;
}
if (!this.slackToken)
throw new JestScreenshotError('When you want to upload to slack you should either provide the slackToken option or an environment variable called "SLACK_WEBTOKEN"');
if (!Reflect.has(options, 'slackChannels')) {
throw new JestScreenshotError('When you want to upload to slack you provide an array of channels to post the screenshot in through the "slackChannels" options');
}
this.slackChannels = options.slackChannels;
if (!this.slackChannels || !this.slackChannels.length) {
throw new JestScreenshotError('Failed to set the Slack channels, please verify your slackChannels option');
}
}
}
/**
* Sets up the JestScreenshot reporter
*
* @returns JestScreenshot reporter will have been initialiazed as a side effect for this test suite
*/
async setup() {
try {
await fs_nextra_1.mkdirp(this.dirName);
}
catch {
throw new Error('Failed to create screenshots directory, maybe check your permissions?');
}
await this.takeScreenshot();
}
/**
* Takes a screenshot of the current page
* @returns Either returns the response from Slack or the screenshot as a Buffer
*/
async takeScreenshot() {
const fileName = `${this.testName}-${moment_1.default().format('YYYY-MM-DD[_]HH.mm.ss')}.png`;
const filePath = path_1.default.join(this.dirName, fileName);
const screenshot = await this.page.screenshot({ path: filePath });
if (this.shouldUploadToSlack)
return this.uploadToSlack(screenshot, fileName.slice(0, -4));
return screenshot;
}
/**
* Uploads screenshots to Slack using the provided token
*
* @param screenshot base64 representation of the screenshot to upload
* @returns {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise | Promise} of the SlackResponse
*/
async uploadToSlack(screenshot, fileName) {
var _a;
const apiUrl = 'https://slack.com/api';
const apiMethod = `${apiUrl}/files.upload`;
const form = new form_data_1.default();
form.append('token', this.slackToken);
form.append('channels', ((_a = this.slackChannels) === null || _a === void 0 ? void 0 : _a.join(',')) || [].join(','));
form.append('file', screenshot, {
contentType: 'image/png',
filename: fileName
});
form.append('filename', fileName);
form.append('title', fileName);
form.append('filetype', 'png');
try {
const request = await node_fetch_1.default(apiMethod, {
method: 'POST',
body: form
});
const data = (await request.json());
return data;
}
catch (err) {
throw new Error(err);
}
}
}
exports.JestScreenshot = JestScreenshot;
exports.default = JestScreenshot;
module.exports = JestScreenshot;
//# sourceMappingURL=index.js.map