Path: blob/master/lib/rammerhead/src/classes/RammerheadSession.js
5253 views
const { Session } = require('testcafe-hammerhead');1const UploadStorage = require('testcafe-hammerhead/lib/upload/storage');2const generateId = require('../util/generateId');3const StrShuffler = require('../util/StrShuffler');45// disable UploadStorage, a testcafe testing feature we do not need6const emptyFunc = () => {};7UploadStorage.prototype.copy = emptyFunc;8UploadStorage.prototype.get = emptyFunc;9UploadStorage.prototype.store = emptyFunc;1011/**12* wrapper for initializing Session with saving capabilities13*/14class RammerheadSession extends Session {15data = {};16createdAt = Date.now();17lastUsed = Date.now();18// ID used to generate the global autocomplete session.19// This must be a string containing 32 alphanumerical characters.20static autocompleteId = 'collectsearchautocompleteresults';2122/**23* @param {object} options24* @param {string} options.id25* @param {boolean} options.dontConnectToData - used when we want to connect to data later (or simply don't want to)26* @param {boolean} options.disableShuffling27* @param {string[]} options.prependScripts28*/29constructor({ id = generateId(), dontConnectToData = false, disableShuffling = false, prependScripts = [] } = {}) {30super(['blah/blah'], {31allowMultipleWindows: true,32disablePageCaching: false33});3435// necessary abstract methods for Session36this.getIframePayloadScript = async () => '';37this.getPayloadScript = async () => '';38this.getAuthCredentials = () => ({});39this.handleFileDownload = () => void 0;40this.handlePageError = () => void 0;41this.handleAttachment = () => void 0;42// this.handlePageError = (ctx, err) => {43// console.error(ctx.req.url);44// console.error(err);45// };4647// intellisense //48/**49* @type {{ host: string, hostname: string, bypassRules?: string[]; port?: string; proxyAuth?: string, authHeader?: string } | null}50*/51this.externalProxySettings = null;5253// disable http2. error handling from http2 proxy client to non-http2 user is too complicated to handle54// (status code 0, for example, will crash rammerhead)55this.isHttp2Disabled = () => true;56if (id !== RammerheadSession.autocompleteId) {57this.injectable.scripts.push(...prependScripts);58this.injectable.scripts.push('/rammer/rammerhead.js');59} else {60this.injectable.scripts.length = 0;61}6263this.id = id;64this.shuffleDict = disableShuffling ? null : StrShuffler.generateDictionary();65if (!dontConnectToData) {66this.connectHammerheadToData();67}68}69/**70* @param {boolean} dontCookie - set this to true if the store is using a more reliable approach to71* saving the cookies (like in serializeSession)72*/73connectHammerheadToData(dontCookie = false) {74this._connectObjectToHook(this, 'createdAt');75this._connectObjectToHook(this, 'lastUsed');76this._connectObjectToHook(this, 'injectable');77this._connectObjectToHook(this, 'externalProxySettings');78this._connectObjectToHook(this, 'shuffleDict');79if (!dontCookie) this._connectObjectToHook(this.cookies._cookieJar.store, 'idx', 'cookies');80}8182updateLastUsed() {83this.lastUsed = Date.now();84}85serializeSession() {86return JSON.stringify({87data: this.data,88serializedCookieJar: this.cookies.serializeJar()89});90}91// hook system and serializing are for two different store systems92static DeserializeSession(id, serializedSession) {93const parsed = JSON.parse(serializedSession);94if (!parsed.data) throw new Error('expected serializedSession to contain data object');95if (!parsed.serializedCookieJar)96throw new Error('expected serializedSession to contain serializedCookieJar object');9798const session = new RammerheadSession({ id, dontConnectToData: true });99session.data = parsed.data;100session.connectHammerheadToData(true);101session.cookies.setJar(parsed.serializedCookieJar);102return session;103}104105hasRequestEventListeners() {106// force forceProxySrcForImage to be true107// see https://github.com/DevExpress/testcafe-hammerhead/blob/a9fbf7746ff347f7bdafe1f80cf7135eeac21e34/src/session/index.ts#L180108return true;109}110/**111* @private112*/113_connectObjectToHook(obj, prop, dataProp = prop) {114const originalValue = obj[prop];115Object.defineProperty(obj, prop, {116get: () => this.data[dataProp],117set: (value) => {118this.data[dataProp] = value;119}120});121if (!(dataProp in this.data)) {122this.data[dataProp] = originalValue;123}124}125}126127module.exports = RammerheadSession;128129130