UNPKG

@assurka/cypress

Version:

Assurka Cypress Plugin

353 lines 17.3 kB
"use strict"; /// <reference types="cypress" /> var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.assurka = void 0; /** * @type {Cypress.PluginConfig} */ var fs_extra_1 = __importDefault(require("fs-extra")); var del_1 = __importDefault(require("del")); var lodash_1 = __importDefault(require("lodash")); var node_fetch_1 = __importStar(require("node-fetch")); var git_last_commit_1 = require("git-last-commit"); var form_data_1 = __importDefault(require("form-data")); var assurka = function (on, config, assurkaConfig) { // console.log("config", config); on("before:run", function (details) { return __awaiter(void 0, void 0, void 0, function () { var tokenResponse, commit, payload, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: // console.log("before:run", details); // reset any config's assurkaConfig.testSpecs = []; assurkaConfig.testRun = null; if (!!assurkaConfig.token) return [3 /*break*/, 4]; return [4 /*yield*/, api("auth/api", "POST", { id: assurkaConfig.projectId, secret: assurkaConfig.secret, })]; case 1: tokenResponse = _b.sent(); assurkaConfig.token = tokenResponse.token; return [4 /*yield*/, getGitCommit(details.config.projectRoot)]; case 2: commit = _b.sent(); payload = details; delete details.specs; _a = assurkaConfig; return [4 /*yield*/, api("test-run/".concat(assurkaConfig.testPlanId, "/create"), "POST", __assign(__assign({}, payload), { commit: commit, platform: "cypress" }))]; case 3: _a.testRun = _b.sent(); _b.label = 4; case 4: return [2 /*return*/]; } }); }); }); on("after:run", function (results) { return __awaiter(void 0, void 0, void 0, function () { var testRunPayload; return __generator(this, function (_a) { switch (_a.label) { case 0: console.log("after:run", results); if (!results) return [3 /*break*/, 3]; testRunPayload = { duration: results.totalDuration, status: results.status, browserName: results.browserName, browserVersion: results.browserVersion, cypressVersion: results.cypressVersion, osName: results.osName, osVersion: results.osVersion, endedTestsAt: results.endedTestsAt, startedTestsAt: results.startedTestsAt, numFailedTests: results.totalFailed, numPassedTests: results.totalPassed, numPendingTests: results.totalPending, numSkippedTest: results.totalSkipped, numTestSuites: results.totalSuites, numTotalTests: results.totalTests, }; //update the test run return [4 /*yield*/, api("test-run/".concat(assurkaConfig.testPlanId, "/update/").concat(assurkaConfig.testRun.id), "PATCH", testRunPayload)]; case 1: //update the test run _a.sent(); //update the test plan return [4 /*yield*/, api("test-run/".concat(assurkaConfig.projectId, "/update/").concat(assurkaConfig.testPlan), "PATCH", testRunPayload)]; case 2: //update the test plan _a.sent(); // results will be undefined in interactive mode console.log(results.totalPassed, "out of", results.totalTests, "passed"); _a.label = 3; case 3: return [2 /*return*/]; } }); }); }); on("before:spec", function (spec) { return __awaiter(void 0, void 0, void 0, function () { var testSpec; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, api("test-spec/".concat(assurkaConfig.testRun.id, "/create"), "POST", { name: spec.name, testRunId: assurkaConfig.testRun.id, })]; case 1: testSpec = _a.sent(); assurkaConfig.testSpecs.push(testSpec); return [2 /*return*/]; } }); }); }); on("after:spec", function (spec, results) { return __awaiter(void 0, void 0, void 0, function () { var testSpec, screenshots, _i, _a, screenshot, result, video, videoResponse, specPayload, index, test_1, testPayload, failures; return __generator(this, function (_b) { switch (_b.label) { case 0: testSpec = assurkaConfig.testSpecs.find(function (f) { return f.name === spec.name; }); if (!results) return [3 /*break*/, 12]; screenshots = []; if (!(results && results.screenshots)) return [3 /*break*/, 4]; _i = 0, _a = results.screenshots; _b.label = 1; case 1: if (!(_i < _a.length)) return [3 /*break*/, 4]; screenshot = _a[_i]; return [4 /*yield*/, upload(screenshot.path)]; case 2: result = _b.sent(); screenshots.push(result.filename); _b.label = 3; case 3: _i++; return [3 /*break*/, 1]; case 4: video = undefined; if (!(results && results.video)) return [3 /*break*/, 6]; return [4 /*yield*/, upload(results.video)]; case 5: videoResponse = _b.sent(); if (videoResponse && videoResponse.filename) { video = videoResponse.filename; } _b.label = 6; case 6: specPayload = { numPassingTests: results.stats.passes, numPendingTests: results.stats.pending, numFailingTests: results.stats.failures, duration: results.stats.wallClockDuration, runtime: results.stats.wallClockDuration, screenshots: screenshots, video: video, testRunId: assurkaConfig.testRun.id, }; if (results.video) { } return [4 /*yield*/, api("test-spec/".concat(assurkaConfig.testRun.id, "/update/").concat(testSpec.id), "PATCH", specPayload)]; case 7: _b.sent(); index = 0; _b.label = 8; case 8: if (!(index < results.tests.length)) return [3 /*break*/, 11]; test_1 = results.tests[index]; testPayload = { title: test_1.title[test_1.title.length - 1], ancestorTitles: test_1.title, status: test_1.state, attempts: test_1.attempts, body: test_1.body, displayError: test_1.displayError, testSpecId: testSpec.id, testRunId: assurkaConfig.testRun.id, position: index, }; return [4 /*yield*/, api("test-case/".concat(testSpec.id, "/create"), "POST", testPayload)]; case 9: _b.sent(); _b.label = 10; case 10: index++; return [3 /*break*/, 8]; case 11: // delete the recorded video if the spec passed if (results && results.stats.failures === 0 && results.video) { // `del()` returns a promise, so it's important to return it to ensure // deleting the video is finished before moving on return [2 /*return*/, (0, del_1.default)(results.video)]; } // delete the recorded video if no tests retried if (results && results.video) { failures = lodash_1.default.some(results.tests, function (test) { return lodash_1.default.some(test.attempts, { state: "failed" }); }); if (!failures) { // delete the video if the spec passed and no tests retried return [2 /*return*/, (0, del_1.default)(results.video)]; } } _b.label = 12; case 12: return [2 /*return*/]; } }); }); }); on("after:screenshot", function (details) { //console.log("after:screenshot", details); }); on("before:browser:launch", function (browser, launchOptions) { // console.log("before:browser:launch", browser, launchOptions); if (browser.name === "chrome" && browser.isHeadless) { // fullPage screenshot size is 1400x1200 on non-retina screens // and 2800x2400 on retina screens launchOptions.args.push("--window-size=1400,1200"); // force screen to be non-retina (1400x1200 size) launchOptions.args.push("--force-device-scale-factor=1"); } if (browser.name === "electron" && browser.isHeadless) { // fullPage screenshot size is 1400x1200 launchOptions.preferences.width = 1400; launchOptions.preferences.height = 1200; } if (browser.name === "firefox" && browser.isHeadless) { // menubars take up height on the screen // so fullPage screenshot size is 1400x1126 launchOptions.args.push("--width=1400"); launchOptions.args.push("--height=1200"); } return launchOptions; }); /** *Sends results to the Assurka API * @param {string} url - the url * @param {string} method - the api method * @param {*} body - the api body * @memberof AssurkaCustomReporter */ var api = function (url, method, body) { return __awaiter(void 0, void 0, void 0, function () { var headers; return __generator(this, function (_a) { headers = new node_fetch_1.Headers({ "Content-Type": "application/json" }); if (assurkaConfig.token) { headers.append("Authorization", "Bearer " + assurkaConfig.token); } return [2 /*return*/, (0, node_fetch_1.default)("".concat(assurkaConfig.host, "/").concat(url), { method: method, headers: headers, body: JSON.stringify(body), }).then(function (response) { if (!response.ok) { return null; } return response.json(); })]; }); }); }; var upload = function (filePath) { return __awaiter(void 0, void 0, void 0, function () { var form, fileStream, options; return __generator(this, function (_a) { form = new form_data_1.default(); fileStream = fs_extra_1.default.createReadStream(filePath); form.append("file", fileStream); options = { method: "POST", credentials: "include", body: form, }; return [2 /*return*/, (0, node_fetch_1.default)("".concat(assurkaConfig.host, "/file/upload"), __assign({}, options)).then(function (response) { if (!response.ok) { console.warn(response.statusText); return null; } return response.json(); })]; }); }); }; var getGitCommit = function (path) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, new Promise(function (res, _rej) { (0, git_last_commit_1.getLastCommit)(function (err, commit) { if (err) return res(null); return res(commit); }, { dst: path }); })]; }); }); }; }; exports.assurka = assurka; //# sourceMappingURL=index.js.map