UNPKG

testplane

Version:

Tests framework based on mocha and wdio

206 lines 9.14 kB
"use strict"; 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.initCommandHistory = exports.runGroup = exports.runWithoutHistory = exports.shouldPropagateFn = void 0; const debug_1 = __importDefault(require("debug")); const callstack_1 = require("./callstack"); const cmds = __importStar(require("./commands")); const utils_1 = require("./utils"); const types_1 = require("../../types"); const rrweb_1 = require("./rrweb"); const async_local_storage_1 = require("./async-local-storage"); const debug = (0, debug_1.default)("testplane:browser:history"); const shouldNotWrapCommand = (commandName) => ["addCommand", "overwriteCommand", "extendOptions", "addTag", "setMeta", "getMeta", "runStep"].includes(commandName); const shouldPropagateFn = (parentNode, currentNode) => (0, utils_1.isGroup)(parentNode) || (0, utils_1.isGroup)(currentNode); exports.shouldPropagateFn = shouldPropagateFn; const mkHistoryNode = ({ name, args, elementScope, key, overwrite, isGroup }) => { const map = { [types_1.TestStepKey.Name]: name, [types_1.TestStepKey.Args]: (0, utils_1.normalizeCommandArgs)(name, args), [types_1.TestStepKey.Scope]: cmds.createScope(elementScope ?? false), [types_1.TestStepKey.Key]: key ?? Symbol(), }; if (overwrite) { map[types_1.TestStepKey.IsOverwritten] = Boolean(overwrite); } if (isGroup) { map[types_1.TestStepKey.IsGroup] = true; } return map; }; const runWithoutHistory = async (_, fn) => { return (0, async_local_storage_1.runWithHistoryContext)({ shouldBypassHistory: true }, fn); }; exports.runWithoutHistory = runWithoutHistory; const runWithHistoryHooks = ({ session, callstack, snapshotsPromiseRef, nodeData, fn, config, }) => { nodeData.key = nodeData.key ?? Symbol(); if ((0, async_local_storage_1.getHistoryContext)()?.shouldBypassHistory) { return fn(); } return (0, utils_1.runWithHooks)({ before: () => { callstack.enter(mkHistoryNode(nodeData)); }, fn: () => { const result = fn(); if (typeof result?.then === "function") { try { const timeTravelMode = config.timeTravel.mode; const isRetry = (session.executionContext?.ctx?.attempt ?? 0) > 0; const shouldRecord = (0, utils_1.shouldRecordSnapshots)(timeTravelMode, isRetry); const isInterestingStep = !nodeData.name.startsWith("is") && !nodeData.name.startsWith("get") && !nodeData.name.startsWith("$") && !nodeData.name.startsWith("wait"); if (shouldRecord && process.send && session.executionContext?.ctx?.currentTest && isInterestingStep) { const rrwebPromise = (0, rrweb_1.installRrwebAndCollectEvents)(session, callstack) ?.then(rrwebEvents => { const rrwebEventsFiltered = (0, rrweb_1.filterEvents)(rrwebEvents); (0, rrweb_1.sendFilteredEvents)(session, rrwebEventsFiltered); }) .catch(e => { debug("An error occurred during capturing snapshots in browser: %O", e); }); snapshotsPromiseRef.current = snapshotsPromiseRef.current.then(() => rrwebPromise); } } catch (e) { debug("An error occurred during capturing snapshots in browser: %O", e); } } return result; }, after: () => { return callstack.leave(nodeData.key); }, error: () => callstack.markError(exports.shouldPropagateFn), }); }; const overwriteAddCommand = (session, callstack, snapshotsPromiseRef, config) => { session.overwriteCommand("addCommand", (origCommand, name, wrapper, elementScope) => { if (shouldNotWrapCommand(name)) { return origCommand(name, wrapper, elementScope); } function decoratedWrapper(...args) { return runWithHistoryHooks({ session, callstack, snapshotsPromiseRef, nodeData: { name, args, elementScope, overwrite: false }, fn: () => wrapper.apply(this, args), config, }); } return origCommand(name, decoratedWrapper, elementScope); }); }; const overwriteOverwriteCommand = (session, callstack, snapshotsPromiseRef, config) => { session.overwriteCommand("overwriteCommand", (origCommand, name, wrapper, elementScope) => { if (shouldNotWrapCommand(name)) { return origCommand(name, wrapper, elementScope); } function decoratedWrapper(origFn, ...args) { return runWithHistoryHooks({ session, snapshotsPromiseRef, callstack, nodeData: { name, args, elementScope, overwrite: true }, fn: () => wrapper.apply(this, [origFn, ...args]), config, }); } // eslint-disable-next-line @typescript-eslint/no-explicit-any return origCommand(name, decoratedWrapper, elementScope); }); }; const overwriteCommands = ({ session, snapshotsPromiseRef, callstack, commands, elementScope, config, }) => { commands.forEach(name => { function decoratedWrapper(origFn, ...args) { return runWithHistoryHooks({ session, snapshotsPromiseRef, callstack, nodeData: { name, args, elementScope, overwrite: false }, fn: () => origFn(...args), config, }); } // eslint-disable-next-line @typescript-eslint/no-explicit-any session.overwriteCommand(name, decoratedWrapper, elementScope); }); }; const overwriteBrowserCommands = (session, callstack, snapshotsPromiseRef, config) => overwriteCommands({ session, callstack, snapshotsPromiseRef, commands: cmds.getBrowserCommands().filter(cmd => !shouldNotWrapCommand(cmd)), elementScope: false, config, }); const overwriteElementCommands = (session, callstack, snapshotsPromiseRef, config) => overwriteCommands({ session, callstack, snapshotsPromiseRef, commands: cmds.getElementCommands(), elementScope: true, config, }); const runGroup = ({ session, callstack, snapshotsPromiseRef, config }, name, fn) => { if (!callstack) { return fn(); } return runWithHistoryHooks({ session, callstack, snapshotsPromiseRef, nodeData: { name, args: [], isGroup: true }, fn, config, }); }; exports.runGroup = runGroup; const overwriteRunStepCommand = (session, callstack, snapshotsPromiseRef, config) => { session.overwriteCommand("runStep", (origCommand, stepName, stepCb) => { return (0, exports.runGroup)({ session, snapshotsPromiseRef, callstack, config }, stepName, () => origCommand(stepName, stepCb)); }); }; const initCommandHistory = (session, config) => { const callstack = new callstack_1.Callstack(); const snapshotsPromiseRef = { current: Promise.resolve() }; overwriteAddCommand(session, callstack, snapshotsPromiseRef, config); overwriteBrowserCommands(session, callstack, snapshotsPromiseRef, config); overwriteElementCommands(session, callstack, snapshotsPromiseRef, config); overwriteOverwriteCommand(session, callstack, snapshotsPromiseRef, config); overwriteRunStepCommand(session, callstack, snapshotsPromiseRef, config); return { callstack, snapshotsPromiseRef }; }; exports.initCommandHistory = initCommandHistory; //# sourceMappingURL=index.js.map