UNPKG

@rws-air/jestscreenshot

Version:

Jest reporter plugin to take Puppeteer screenshots on failing tests

145 lines 6.22 kB
"use strict"; 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