Best JavaScript code snippet using playwright-internal
index.spec.js
Source:index.spec.js
...184 cookies: {cookie1: 1, cookie2: 2, cookie3: 'three'},185 getHeaders: () => ({header1: 1, header2: 2, header3: 'three', 'content-encoding': 'gzip'})186 };187 mockRes.get = () => 'application/json';188 actualEntry = await proxy.createHarEntry(new Date('2017-07-25T21:03:55.962Z').toISOString(), mockReq, mockRes, '{"Response": 42}');189 assert.deepStrictEqual(actualEntry, expectedEntry, 'Generate a Valid HAR entry that filters out content-encoding response header');190 assert.deepStrictEqual(actualEntry.response.content.encoding, 'utf8', 'utf8 encode the response body if the mime type is application/json format');191 mockRes.get = () => 'text/plain';192 actualEntry = await proxy.createHarEntry(new Date('2017-07-25T21:03:55.962Z').toISOString(), mockReq, mockRes, '{"Response": 42}');193 assert.deepStrictEqual(actualEntry.response.content.encoding, 'utf8', 'utf8 encode the response body if the mime type is plain/text format');194 mockRes.get = () => 'obscure_mimetype';195 actualEntry = await proxy.createHarEntry(new Date('2017-07-25T21:03:55.962Z').toISOString(), mockReq, mockRes, '{"Response": 42}');196 assert.deepStrictEqual(actualEntry.response.content.encoding, 'base64', 'base64 encode the response body if the mimetype is not a text format');197 mockRes.get = () => 'text/plain';198 mockRes.getHeaders = () => ({'content-encoding': 'br'});199 actualEntry = await proxy.createHarEntry(new Date('2017-07-25T21:03:55.962Z').toISOString(), mockReq, mockRes, zlib.brotliCompressSync('hello there!'));200 assert.deepStrictEqual(actualEntry.response.content.text, 'hello there!','utf8 encode the response body with brotli compression');201 });202 });203 describe('Express Routes', () => {204 let mockApp = express();205 let mockRemoteServer, proxy;206 let mockJson, mockText;207 before(() => {208 mockJson = {a: 1, b: 'Some Value'};209 mockText = '<div>My Div</div>';210 mockRemoteServer = mockApp.listen(mockServerPort);211 mockApp.use('/test', (req, res) => res.json(mockJson));212 mockApp.use('/excluded1', (req, res) => res.send(mockText));213 mockApp.use('/excluded2', (req, res) => res.send(mockText));...
harTracer.js
Source:harTracer.js
...109 this._barrierPromises.add(race);110 }111 _onAPIRequest(event) {112 var _event$postData;113 const harEntry = createHarEntry(event.method, event.url, '', '');114 harEntry.request.cookies = event.cookies;115 harEntry.request.headers = Object.entries(event.headers).map(([name, value]) => ({116 name,117 value118 }));119 harEntry.request.postData = postDataForBuffer(event.postData || null, event.headers['content-type'], this._options.content);120 harEntry.request.bodySize = ((_event$postData = event.postData) === null || _event$postData === void 0 ? void 0 : _event$postData.length) || 0;121 event[this._entrySymbol] = harEntry;122 if (this._started) this._delegate.onEntryStarted(harEntry);123 }124 _onAPIRequestFinished(event) {125 const harEntry = this._entryForRequest(event.requestEvent);126 if (!harEntry) return;127 harEntry.response.status = event.statusCode;128 harEntry.response.statusText = event.statusMessage;129 harEntry.response.httpVersion = event.httpVersion;130 harEntry.response.redirectURL = event.headers.location || '';131 for (let i = 0; i < event.rawHeaders.length; i += 2) {132 harEntry.response.headers.push({133 name: event.rawHeaders[i],134 value: event.rawHeaders[i + 1]135 });136 }137 harEntry.response.cookies = event.cookies.map(c => {138 return { ...c,139 expires: c.expires === -1 ? undefined : new Date(c.expires)140 };141 });142 const content = harEntry.response.content;143 const contentType = event.headers['content-type'];144 if (contentType) content.mimeType = contentType;145 this._storeResponseContent(event.body, content);146 if (this._started) this._delegate.onEntryFinished(harEntry);147 }148 _onRequest(request) {149 const page = request.frame()._page;150 const url = network.parsedURL(request.url());151 if (!url) return;152 const pageEntry = this._ensurePageEntry(page);153 const harEntry = createHarEntry(request.method(), url, request.guid, request.frame().guid);154 harEntry.pageref = pageEntry.id;155 harEntry.request.postData = postDataForRequest(request, this._options.content);156 harEntry.request.bodySize = request.bodySize();157 if (request.redirectedFrom()) {158 const fromEntry = this._entryForRequest(request.redirectedFrom());159 if (fromEntry) fromEntry.response.redirectURL = request.url();160 }161 request[this._entrySymbol] = harEntry;162 if (this._started) this._delegate.onEntryStarted(harEntry);163 }164 async _onRequestFinished(request, response) {165 if (!response) return;166 const page = request.frame()._page;167 const harEntry = this._entryForRequest(request);168 if (!harEntry) return;169 const httpVersion = response.httpVersion();170 harEntry.request.httpVersion = httpVersion;171 harEntry.response.httpVersion = httpVersion;172 const compressionCalculationBarrier = {173 _encodedBodySize: -1,174 _decodedBodySize: -1,175 barrier: new _async.ManualPromise(),176 _check: function () {177 if (this._encodedBodySize !== -1 && this._decodedBodySize !== -1) {178 harEntry.response.content.compression = Math.max(0, this._decodedBodySize - this._encodedBodySize);179 this.barrier.resolve();180 }181 },182 setEncodedBodySize: function (encodedBodySize) {183 this._encodedBodySize = encodedBodySize;184 this._check();185 },186 setDecodedBodySize: function (decodedBodySize) {187 this._decodedBodySize = decodedBodySize;188 this._check();189 }190 };191 this._addBarrier(page, compressionCalculationBarrier.barrier);192 const promise = response.body().then(buffer => {193 if (this._options.skipScripts && request.resourceType() === 'script') {194 compressionCalculationBarrier.setDecodedBodySize(0);195 return;196 }197 const content = harEntry.response.content;198 compressionCalculationBarrier.setDecodedBodySize(buffer.length);199 this._storeResponseContent(buffer, content);200 }).catch(() => {201 compressionCalculationBarrier.setDecodedBodySize(0);202 }).then(() => {203 const postData = response.request().postDataBuffer();204 if (postData && harEntry.request.postData && this._options.content === 'sha1') {205 harEntry.request.postData._sha1 = (0, _utils.calculateSha1)(postData) + '.' + (mime.getExtension(harEntry.request.postData.mimeType) || 'dat');206 if (this._started) this._delegate.onContentBlob(harEntry.request.postData._sha1, postData);207 }208 if (this._started) this._delegate.onEntryFinished(harEntry);209 });210 this._addBarrier(page, promise);211 this._addBarrier(page, response.sizes().then(sizes => {212 harEntry.response.bodySize = sizes.responseBodySize;213 harEntry.response.headersSize = sizes.responseHeadersSize; // Fallback for WebKit by calculating it manually214 harEntry.response._transferSize = response.request().responseSize.transferSize || sizes.responseHeadersSize + sizes.responseBodySize;215 harEntry.request.headersSize = sizes.requestHeadersSize;216 compressionCalculationBarrier.setEncodedBodySize(sizes.responseBodySize);217 }));218 }219 async _onRequestFailed(request) {220 const harEntry = this._entryForRequest(request);221 if (!harEntry) return;222 if (request._failureText !== null) harEntry.response._failureText = request._failureText;223 if (this._started) this._delegate.onEntryFinished(harEntry);224 }225 _storeResponseContent(buffer, content) {226 if (!buffer) {227 content.size = 0;228 return;229 }230 content.size = buffer.length;231 if (this._options.content === 'embedded') {232 content.text = buffer.toString('base64');233 content.encoding = 'base64';234 } else if (this._options.content === 'sha1') {235 content._sha1 = (0, _utils.calculateSha1)(buffer) + '.' + (mime.getExtension(content.mimeType) || 'dat');236 if (this._started) this._delegate.onContentBlob(content._sha1, buffer);237 }238 }239 _onResponse(response) {240 const page = response.frame()._page;241 const pageEntry = this._ensurePageEntry(page);242 const harEntry = this._entryForRequest(response.request());243 if (!harEntry) return;244 const request = response.request();245 harEntry.request.postData = postDataForRequest(request, this._options.content);246 harEntry.response = {247 status: response.status(),248 statusText: response.statusText(),249 httpVersion: response.httpVersion(),250 // These are bad values that will be overwritten bellow.251 cookies: [],252 headers: [],253 content: {254 size: -1,255 mimeType: 'x-unknown'256 },257 headersSize: -1,258 bodySize: -1,259 redirectURL: '',260 _transferSize: -1261 };262 const timing = response.timing();263 if (pageEntry.startedDateTime.valueOf() > timing.startTime) pageEntry.startedDateTime = new Date(timing.startTime);264 const dns = timing.domainLookupEnd !== -1 ? _helper.helper.millisToRoundishMillis(timing.domainLookupEnd - timing.domainLookupStart) : -1;265 const connect = timing.connectEnd !== -1 ? _helper.helper.millisToRoundishMillis(timing.connectEnd - timing.connectStart) : -1;266 const ssl = timing.connectEnd !== -1 ? _helper.helper.millisToRoundishMillis(timing.connectEnd - timing.secureConnectionStart) : -1;267 const wait = timing.responseStart !== -1 ? _helper.helper.millisToRoundishMillis(timing.responseStart - timing.requestStart) : -1;268 const receive = response.request()._responseEndTiming !== -1 ? _helper.helper.millisToRoundishMillis(response.request()._responseEndTiming - timing.responseStart) : -1;269 harEntry.timings = {270 dns,271 connect,272 ssl,273 send: 0,274 wait,275 receive276 };277 harEntry.time = [dns, connect, ssl, wait, receive].reduce((pre, cur) => cur > 0 ? cur + pre : pre, 0);278 this._addBarrier(page, response.serverAddr().then(server => {279 if (server !== null && server !== void 0 && server.ipAddress) harEntry.serverIPAddress = server.ipAddress;280 if (server !== null && server !== void 0 && server.port) harEntry._serverPort = server.port;281 }));282 this._addBarrier(page, response.securityDetails().then(details => {283 if (details) harEntry._securityDetails = details;284 }));285 this._addBarrier(page, request.rawRequestHeaders().then(headers => {286 for (const header of headers.filter(header => header.name.toLowerCase() === 'cookie')) harEntry.request.cookies.push(...header.value.split(';').map(parseCookie));287 harEntry.request.headers = headers;288 }));289 this._addBarrier(page, response.rawResponseHeaders().then(headers => {290 for (const header of headers.filter(header => header.name.toLowerCase() === 'set-cookie')) harEntry.response.cookies.push(parseCookie(header.value));291 harEntry.response.headers = headers;292 const contentType = headers.find(header => header.name.toLowerCase() === 'content-type');293 if (contentType) harEntry.response.content.mimeType = contentType.value;294 }));295 }296 async flush() {297 await Promise.all(this._barrierPromises);298 }299 stop() {300 this._started = false;301 _eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);302 this._barrierPromises.clear();303 const log = {304 version: '1.2',305 creator: {306 name: 'Playwright',307 version: require('../../../../package.json')['version']308 },309 browser: {310 name: this._context._browser.options.name,311 version: this._context._browser.version()312 },313 pages: Array.from(this._pageEntries.values()),314 entries: []315 };316 for (const pageEntry of log.pages) {317 if (pageEntry.pageTimings.onContentLoad >= 0) pageEntry.pageTimings.onContentLoad -= pageEntry.startedDateTime.valueOf();else pageEntry.pageTimings.onContentLoad = -1;318 if (pageEntry.pageTimings.onLoad >= 0) pageEntry.pageTimings.onLoad -= pageEntry.startedDateTime.valueOf();else pageEntry.pageTimings.onLoad = -1;319 }320 this._pageEntries.clear();321 return log;322 }323}324exports.HarTracer = HarTracer;325function createHarEntry(method, url, requestref, frameref) {326 const harEntry = {327 _requestref: requestref,328 _frameref: frameref,329 _monotonicTime: (0, _utils.monotonicTime)(),330 startedDateTime: new Date(),331 time: -1,332 request: {333 method: method,334 url: url.toString(),335 httpVersion: FALLBACK_HTTP_VERSION,336 cookies: [],337 headers: [],338 queryString: [...url.searchParams].map(e => ({339 name: e[0],...
index.mjs
Source:index.mjs
...121 * @param {Object} res - An express ServerResponse response122 * @param {Buffer} data - An express response body (the content buffer)123 * @returns {Object} A HAR entry object124 */125 async createHarEntry(startedDateTime, req, res, data) {126 let reqMimeType = req.get('Content-Type');127 let resMimeType = res.get('Content-Type') || 'text/plain';128 let encoding = (/^text\/|^application\/(javascript|json)/).test(resMimeType) ? 'utf8' : 'base64';129 let entry = {130 request: {131 startedDateTime: startedDateTime,132 method: req.method.toUpperCase(),133 url: req.url,134 cookies: this.convertToNameValueList(req.cookies),135 headers: this.convertToNameValueList(req.headers),136 queryString: this.convertToNameValueList(req.query),137 headersSize: -1,138 bodySize: -1139 },140 response: {141 status: res.statusCode,142 statusText: res.statusMessage,143 cookies: this.convertToNameValueList(res.cookies),144 headers: this.convertToNameValueList(res.getHeaders()).filter(header => header.name.toLowerCase() !== 'content-encoding'), // Not compressed145 content: {146 size: -1,147 mimeType: resMimeType,148 // Workaround for http-express-proxy not handling brotli encoding. TODO: remove this code when HEP fixes this149 text: (res.getHeaders()['content-encoding'] || '').toLowerCase() == 'br' ?150 (await brotliDecompress(data)).toString(encoding) :151 data.toString(encoding),152 encoding: encoding153 },154 headersSize: -1,155 bodySize: -1156 }157 };158 // Add the request body if it exists159 if (req.body && req.body.length > 0) {160 entry.request.postData = {161 mimeType: reqMimeType,162 text: req.body.toString(encoding)163 };164 }165 return entry;166 }167 /**168 * Check to see if the pieces of a request are excluded. This checks only the method and the uri. It uses the list169 * of regExp matchers to test170 * @param {string} method - e.g. GET, POST, PUT, etc.171 * @param {string} uri - e.g. http://www.api.com/rest/accounts172 * @returns {boolean} Whether the test is true for some matcher173 */174 isRouteExcluded(method, uri) {175 return this.options.excludedRouteMatchers.some(regExp => regExp.test(`${method} ${uri}`))176 }177 /**178 * Check to see if the status of a response is excluded. It uses the list of regExp matchers to test179 * @param {number} status - e.g. 404, 503, etc.180 * @returns {boolean} Whether the test is true for some matcher181 */182 isStatusExcluded(status) {183 return this.options.excludedStatusMatchers.some(regExp => regExp.test(status))184 }185 /**186 * Add express routes for each entry in a harObject. The harObject would have been read in from a har file at some point187 * @param {Object} harObject - A standard HAR file object that contains a collection of entries188 * @returns {JsonCachingProxy}189 */190 addHarEntriesToCache(harObject) {191 if (harObject) {192 harObject.log.entries.forEach(entry => {193 let { key, hash } = this.genKeyFromHarReq(entry.request);194 if (this.isRouteExcluded(entry.request.method, entry.request.url)) {195 this.log(chalk.red('Excluded from Cache', chalk.bold(entry.request.method, entry.request.url)));196 return;197 }198 if (this.isStatusExcluded(entry.response.status)) {199 this.log(chalk.red('Excluded from Cache', chalk.bold(entry.request.method, entry.request.url, `\tStatus: ${entry.response.status}`)));200 return;201 }202 // Only cache things that have content. Some times HAR files generated elsewhere will be missing this parameter203 if (entry.response.content.text) {204 let mimeType = entry.response.content.mimeType;205 if (entry.response.headers && (this.options.cacheEverything || !this.options.cacheEverything && mimeType && mimeType.indexOf('application/json') >= 0)) {206 // Remove content-encoding. gzip compression won't be used207 entry.response.headers = entry.response.headers.filter(header => header.name.toLowerCase() !== 'content-encoding');208 this.routeCache[key] = entry;209 this.log(chalk.yellow('Saved to Cache', hash, chalk.bold(entry.request.method, entry.request.url)));210 }211 }212 });213 }214 return this;215 }216 /**217 * Add the admin express routes for controlling the proxy server through a browser. Allows one to make GET requests to clear218 * the cache, disable/enable playback/recording, and generate a har file of the cache to download for later use.219 * @returns {JsonCachingProxy}220 */221 addAdminRoutes() {222 // These are not really restful because the GET is changing state. But it's easier to use in a browser223 this.app.get(`/${this.options.commandPrefix}/playback`, (req, res) => {224 this.options.dataPlayback = typeof req.query.enabled !== 'undefined' ? req.query.enabled === 'true'.toLowerCase() : this.options.dataPlayback;225 this.log(chalk.blue(`Replay from cache: ${this.options.dataPlayback}`));226 res.send(`Replay from cache: ${this.options.dataPlayback}`);227 });228 this.app.get(`/${this.options.commandPrefix}/record`, (req, res) => {229 this.options.dataRecord = typeof req.query.enabled !== 'undefined' ? req.query.enabled === 'true'.toLowerCase() : this.options.dataRecord;230 this.log(chalk.blue('Saving to cache: ' + this.options.dataRecord));231 res.send(`Saving to cache: ${this.options.dataRecord}`);232 });233 this.app.get(`/${this.options.commandPrefix}/clear`, (req, res) => {234 this.routeCache = {};235 this.log(chalk.blue('Cleared cache'));236 res.send('Cleared cache');237 });238 this.app.get(`/${this.options.commandPrefix}/har`, (req, res) => {239 this.log(chalk.blue('Generating har file'));240 let har = {241 log: {242 version: "1.2",243 creator: {244 name: npmPackage.name,245 version: npmPackage.version246 },247 entries: []248 }249 };250 Object.keys(this.routeCache).forEach(key => har.log.entries.push(this.routeCache[key]));251 res.setHeader('Content-disposition', 'attachment; filename=json-caching-proxy.har');252 res.setHeader('Content-type', 'application/json');253 res.json(har);254 });255 return this;256 }257 /**258 * Add user supplied middleware routes to express in order to handle special cases (browser-sync middleware options)259 * @param {Object[]} middlewareList - A list of route/handler pairs260 * @returns {JsonCachingProxy}261 */262 addMiddleWareRoutes(middlewareList) {263 middlewareList.forEach(mw => {264 if (mw.route) {265 this.app.use(mw.route, mw.handle);266 } else {267 this.app.use(mw.handle);268 }269 });270 return this;271 }272 /**273 * Add Request body parsing into bodyParser if there is actual body content274 * @returns {JsonCachingProxy}275 */276 addBodyParser() {277 this.app.use(bodyParser.raw({ type: '*/*', limit: '100mb' }));278 // Remove the body if there is no body content. Some sites check for malformed requests279 this.app.use((req, res, next) => {280 if (!req.headers['content-length']) {281 delete req.body;282 }283 next();284 });285 return this;286 }287 /**288 * An express route that reads from the cache if possible for any routes persisted in cache memory289 * @returns {JsonCachingProxy}290 */291 addCachingRoute() {292 this.app.use('/', (req, res, next) => {293 if (!this.options.dataPlayback) {294 next();295 } else {296 let { key, hash } = this.genKeyFromExpressReq(req);297 let entry = this.routeCache[key];298 if (!(entry && entry.response && entry.response.content)) {299 next();300 } else {301 let response = entry.response;302 let headerList = response.headers || [];303 let text = response.content.text || '';304 let encoding = response.content.encoding || 'utf8';305 headerList.forEach(function (header) {306 res.set(header.name, header.value);307 });308 // Use our header identifier to signal that this response is cached309 res.set(this.options.proxyHeaderIdentifier, true);310 if (text.length === 0) {311 res.sendStatus(response.status);312 } else {313 if (encoding === 'base64') {314 let bin = new Buffer(text, 'base64');315 res.writeHead(response.status, {316 'Content-Type': response.content.mimeType,317 'Content-Length': bin.length318 });319 res.end(bin);320 } else {321 res.status(response.status);322 res.type(response.content.mimeType);323 res.send(text);324 }325 }326 this.log(chalk.green('Reading From Cache', hash, chalk.bold(entry.request.method, entry.request.url)));327 }328 }329 });330 return this;331 }332 /**333 * Add the proxy route that makes the actual request to the target server and cache the response when it comes back.334 * Modifies locations on redirects.335 * @returns {JsonCachingProxy}336 */337 async addProxyRoute() {338 this.app.use('/', proxy(this.options.remoteServerUrl, {339 userResDecorator: async (rsp, rspData, req, res) => {340 let headers = res.getHeaders();341 // Handle Redirects by modifying the location property of the response header342 let location = res.get('location');343 if (location) {344 res.location(urlUtil.parse(location).path);345 }346 if (this.options.overrideCors && this.options.overrideCors !== '*') {347 res.header('access-control-allow-origin', this.options.overrideCors);348 }349 if (this.options.deleteCookieDomain && headers['set-cookie']) {350 res.header('set-cookie', this.removeCookiesDomain(headers['set-cookie'] || []));351 }352 if (this.isRouteExcluded(req.method, req.url)) {353 this.log(chalk.red('Exclude Proxied Resource', chalk.bold(req.method, req.url)));354 } else if (this.isStatusExcluded(res.statusCode)) {355 this.log(chalk.red('Exclude Proxied Resource', chalk.bold(req.method, req.url, `\tStatus: ${res.statusCode}`)));356 } else {357 let mimeType = headers['content-type'];358 if (this.options.dataRecord && (this.options.cacheEverything || !this.options.cacheEverything && mimeType && mimeType.indexOf('application/json') >= 0)) {359 let { key, hash } = this.genKeyFromExpressReq(req);360 let entry = await this.createHarEntry(new Date().toISOString(), req, res, rspData);361 this.routeCache[key] = entry;362 this.log(chalk.yellow('Saved to Cache', hash, chalk.bold(entry.request.method, entry.request.url)));363 } else {364 this.log(chalk.gray('Proxied Resource', chalk.bold(req.method, req.url)));365 }366 }367 return rspData;368 }369 }));370 return this;371 }372 /**373 * Start the server and generate any log output if needed374 * @param {Function} callback fn executed after the server has started...
server.js
Source:server.js
...25 }26 // Write this request/response pair to a har file27 const harFilePath = path.join(app.tapeDir, `${scenarioName}.har`);28 const har = harUtil.readHarFile(harFilePath);29 const harEntry = harUtil.createHarEntry({responseBody, req, res});30 har.log.entries.push(harEntry);31 fs.ensureDirSync(app.tapeDir);32 fs.writeFileSync(harFilePath, JSON.stringify(har, null, 2));33 })34 .pipe(res);35};36server.playbackProxy = ({app, scenarioName, req, res}) => {37 const scenarioEntries = app.scenarioEntriesMap[scenarioName];38 if (!scenarioEntries) {39 return util.sendError(res, `no record for a scenario named ${scenarioName}`, 404);40 }41 // Pull the next response out of the scenario collection42 const nextEntry = scenarioEntries.shift();43 if (!nextEntry) {...
harObectCreator.js
Source:harObectCreator.js
1"use strict";2Object.defineProperty(exports, "__esModule", { value: true });3exports.createHarResponse = exports.createHarRequest = exports.createHarEntry = exports.createHar = exports.createRequestHarObject = void 0;4const createHarHeaders = (request_headers_obj) => {5 // convert headers obj to haar format6 const headers = [];7 if (request_headers_obj) {8 for (const key in request_headers_obj) {9 headers.push({10 name: key,11 value: request_headers_obj[key],12 });13 }14 }15 return headers;16};17const createHarQueryStrings = (path) => {18 // TODO -> http://www.softwareishard.com/blog/har-12-spec/#queryString19 return [];20};21const getContentType = (headers) => {22 let contentType = null;23 if (headers) {24 headers.forEach((item) => {25 if (item.name === "content-type") {26 contentType = item.value;27 }28 });29 }30 return contentType;31};32const buildHarPostParams = (contentType, body) => {33 if (contentType === "application/x-www-form-urlencoded") {34 return body35 .split("&") // Split by separators36 .map((keyValue) => {37 const [key, value] = keyValue.split("=");38 return {39 name: key,40 value,41 };42 });43 }44 else {45 // FormData has its own format46 // TODO Complete form data case -> where file is uploaded47 return {48 name: contentType,49 value: body,50 };51 }52};53const createHarPostData = (body, headers) => {54 // http://www.softwareishard.com/blog/har-12-spec/#postData55 if (!body) {56 return undefined;57 }58 const contentType = getContentType(headers);59 // if (!contentType) {60 // return undefined;61 // }62 // // console.log("contentType and Body", { contentType, body }, typeof body);63 // if (64 // ["application/x-www-form-urlencoded", "multipart/form-data"].includes(65 // contentType66 // )67 // ) {68 // return {69 // mimeType: contentType,70 // params: buildHarPostParams(contentType, body),71 // };72 // }73 return {74 mimeType: contentType,75 text: body,76 };77};78// create standard request har object: http://www.softwareishard.com/blog/har-12-spec/#request79// URL: https://github.com/hoppscotch/hoppscotch/blob/75ab7fdb00c0129ad42d45165bd3ad0af1faca2e/packages/hoppscotch-app/helpers/new-codegen/har.ts#L2680const createRequestHarObject = (requestHarObject, proxyToServerRequestOptions) => {81 const { method, host, path, body, headers, agent, } = proxyToServerRequestOptions;82 return {83 bodySize: -1,84 headersSize: -1,85 httpVersion: "HTTP/1.1",86 cookies: [],87 headers: requestHarObject.headers || createHarHeaders(headers),88 method: requestHarObject.method || method,89 queryString: requestHarObject.queryString || createHarQueryStrings(path),90 url: requestHarObject.url || ((agent === null || agent === void 0 ? void 0 : agent.protocol) || "http:") + "//" + host + path,91 postData: requestHarObject.postData ||92 createHarPostData(body, requestHarObject.headers),93 };94};95exports.createRequestHarObject = createRequestHarObject;96const createHar = (requestHeaders, method, protocol, host, path, requestBody, responseStatusCode, response, responseHeaders) => {97 return {98 "log": {99 "version": "1.2",100 "creator": {},101 "browser": {},102 "pages": [],103 "entries": [(0, exports.createHarEntry)(requestHeaders, method, protocol, host, path, requestBody, responseStatusCode, response, responseHeaders)],104 "comment": ""105 }106 };107};108exports.createHar = createHar;109const createHarEntry = (requestHeaders, method, protocol, host, path, requestBody, responseStatusCode, response, responseHeaders) => {110 return {111 // "pageref": "page_0",112 "startedDateTime": new Date().toISOString(),113 // "time": 50,114 "request": (0, exports.createHarRequest)(requestHeaders, method, protocol, host, path, requestBody),115 "response": (0, exports.createHarResponse)(responseStatusCode, response, responseHeaders),116 "cache": {},117 "timings": {},118 // "serverIPAddress": "10.0.0.1",119 // "connection": "52492",120 "comment": ""121 };122};123exports.createHarEntry = createHarEntry;124const createHarRequest = (requestHeaders, method, protocol, host, path, requestBody) => {125 return {126 bodySize: -1,127 headersSize: -1,128 httpVersion: "HTTP/1.1",129 cookies: [],130 headers: createHarHeaders(requestHeaders),131 method: method,132 queryString: createHarQueryStrings(path),133 url: protocol + "://" + host + path,134 postData: createHarPostData(requestBody, createHarHeaders(requestHeaders)),135 };136};137exports.createHarRequest = createHarRequest;138const createHarResponse = (responseStatusCode, response, responseHeaders) => {139 return {140 "status": responseStatusCode,141 // "statusText": "OK",142 "httpVersion": "HTTP/1.1",143 "cookies": [],144 "headers": createHarHeaders(responseHeaders),145 "content": {146 "size": 33,147 "compression": 0,148 "mimeType": (responseHeaders && responseHeaders["content-type"]),149 "text": response,150 "comment": ""151 },152 // "redirectURL": "",153 "headersSize": -1,154 "bodySize": -1,155 "comment": ""156 };157};...
harUtil.js
Source:harUtil.js
1const fs = require('fs-extra');2const path = require('path');3const { URL } = require('url');4const querystring = require('querystring');5const stringify = require('json-stable-stringify');6const packageJson = require('../package.json');7const harUtil = module.exports;8const proxyTarget = 'https://test.example.com';9// Fetch the har for a scenario10harUtil.readHarFile = harFilePath => {11 // Return the har if we have one12 if (fs.existsSync(harFilePath)) {13 return fs.readJsonSync(harFilePath);14 }15 // Return a default har16 return {17 log: {18 version: 1.2,19 creator: {20 name: 'okta-sdk-test-server',21 version: packageJson.version22 },23 entries: []24 }25 };26};27harUtil.normalizeQueryString = url => {28 let missingDomain;29 if (url[0] === '/') {30 missingDomain = proxyTarget;31 }32 const newUrl = new URL(url, missingDomain);33 const query = newUrl.search.slice(1);34 if (query) {35 const parsed = querystring.parse(query);36 const sortedObj = JSON.parse(stringify(parsed));37 newUrl.search = querystring.stringify(sortedObj);38 }39 return newUrl.href;40};41// Ensure all the requests are consistent42harUtil.normalizeRequest = (req) => {43 // Purposefully exclude the authorization header to avoid44 // api tokens in the har output45 req.headers = {46 accept: req.headers.accept,47 'content-type': req.headers['content-type']48 };49 // Normalize the query params50 req.url = harUtil.normalizeQueryString(req.url);51 // Some libraries change spacing or ordering of json data52 // default to an empty string53 req.data = (req.data) ? stringify(JSON.parse(req.data)) : '';54 req.body = req.body || '';55};56harUtil.normalizeHarRequest = harRequest => {57 if (!harRequest.postData.text) {58 harRequest.postData.text = '';59 }60 harRequest.url = harUtil.normalizeQueryString(harRequest.url);61};62harUtil.createHarEntry = ({responseBody, req, res}) => {63 harUtil.normalizeRequest(req);64 // Build the request portion65 const request = {66 method: req.method.toUpperCase(),67 url: proxyTarget + req.url,68 headers: Object.entries(req.headers).map(([headerName, header]) => {69 return {70 name: headerName,71 value: header72 };73 }),74 queryString: (function () {75 const aggregate = [];76 const parsedUrl = new URL(proxyTarget + req.url);77 for (const [queryName, query] of parsedUrl.searchParams.entries()) {78 aggregate.push({79 name: queryName,80 value: query81 });82 }83 return aggregate;84 }()),85 postData: {86 text: req.body || ''87 }88 };89 // Build the response portion90 const response = {91 status: res.statusCode,92 statusText: res.statusMessage,93 headers: ['content-type', 'link']94 .map(headerName => {95 return {96 name: headerName,97 value: res.getHeader(headerName)98 };99 })100 .filter(header => !!header.value),101 content: {102 mimeType: res.getHeader('content-type'),103 text: responseBody104 }105 };106 return {107 request,108 response109 };110};111harUtil.loadHarFromFile = scenarioFileName => {112 const scenarioName = path.basename(scenarioFileName, '.har');113 const scenario = fs.readJsonSync(scenarioFileName);114 return [scenarioName, scenario.log.entries];...
harUtil-spec.js
Source:harUtil-spec.js
1describe('harUtil', () => {2 describe('readHarFile', () => {3 it('returns a har if a file exists');4 it('returns a default har if a file does not exist');5 });6 describe('normalizeRequest', () => {7 it('creates a har for new requests');8 });9 describe('createHarEntry', () => {10 it('plays back a har if it matches');11 });...
Using AI Code Generation
1const playwright = require('playwright');2(async () => {3 const browser = await playwright.chromium.launch({ headless: false });4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.close();7 await context.close();8 await browser.close();9})();
Using AI Code Generation
1const { createHarEntry } = require('@playwright/test/lib/har');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 console.log(harEntry);8 await browser.close();9})();10{11 request: {12 {13 value: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'14 },15 {16 },17 {18 value: 'en-US,en;q=0.9'19 },20 {21 value: '" Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"'22 },23 {24 },25 {26 },27 {28 },29 {30 },31 {32 },33 {34 },35 {36 value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'37 }
Using AI Code Generation
1const { createHarEntry } = require('playwright/lib/server/chromium/crNetworkManager');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 console.log(JSON.stringify(harEntry, null, 2));8 await browser.close();9})();10{11 "request": {12 {13 "value": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"14 },15 {16 },17 {18 "value": "en-US,en;q=0.5"19 },20 {21 },22 {23 },24 {25 },26 {27 "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.0 Safari/537.36"28 }29 "postData": {},30 },31 "response": {32 {33 },34 {
Using AI Code Generation
1const { createHarEntry } = require('playwright-core/lib/server/supplements/har/harTracer');2const { createHar } = require('playwright-core/lib/server/supplements/har/har');3const entry = createHarEntry({4 headers: {},5 postData: {},6 responseHeaders: {},7 responseContent: {},8 timings: {9 }10});11const har = createHar({12 log: {13 creator: {14 },15 }16});17console.log(JSON.stringify(har));18const { createHar } = require('playwright-core/lib/server/supplements/har/har');19const har = createHar({20 log: {21 creator: {22 },23 }24});25console.log(JSON.stringify(har));26const { createHar } = require('playwright-core/lib/server/supplements/har/har');27const har = createHar({28 log: {29 creator: {30 },31 }32});33console.log(JSON.stringify(har));34const { createHar } = require('playwright-core/lib/server/supplements/har/har');35const har = createHar({36 log: {37 creator: {
Using AI Code Generation
1const { createHarEntry } = require('playwright/lib/server/har');2const harEntry = await createHarEntry(page, {3});4console.log(harEntry);5const { createHarEntry } = require('puppeteer/lib/cjs/puppeteer/common/NetworkManager');6const harEntry = await createHarEntry(page, {7});8console.log(harEntry);9const { createHarEntry } = require('playwright-chromium/lib/server/har');10const harEntry = await createHarEntry(page, {11});12console.log(harEntry);13const { createHarEntry } = require('playwright-firefox/lib/server/har');14const harEntry = await createHarEntry(page, {15});16console.log(harEntry);17const { createHarEntry } = require('playwright-webkit/lib/server/har');18const harEntry = await createHarEntry(page, {
Using AI Code Generation
1const { createHarEntry } = require('playwright/lib/utils/har');2const harEntry = createHarEntry({3 headers: {4 },5 postData: {6 text: '{"foo":"bar"}',7 },8 response: {9 headers: {10 },11 content: {12 },13 },14 startedDateTime: new Date(),15});16console.log(harEntry);17{18 request: {19 {20 },21 postData: {22 text: '{"foo":"bar"}',23 },24 },25 response: {26 {27 },28 content: {29 },30 },31 cache: {},32 timings: {33 },34 _initiator: {35 stack: {36 {
Using AI Code Generation
1const { createHarEntry } = require('playwright-core/lib/server/network');2console.log(harEntry);3const { createHarEntry } = require('playwright-core/lib/server/network');4console.log(harEntry);5const { createHarEntry } = require('playwright-core/lib/server/network');6console.log(harEntry);7const { createHarEntry } = require('playwright-core/lib/server/network');8console.log(harEntry);9const { createHarEntry } = require('playwright-core/lib/server/network');10console.log(harEntry);11const { createHarEntry } = require('playwright-core/lib/server/network');12console.log(harEntry);13const { createHarEntry } = require('playwright-core/lib/server/network');14console.log(harEntry);15const { createHarEntry } = require('playwright-core/lib/server/network');16console.log(harEntry);17const { createHarEntry } = require('playwright-core/lib/server/network');18console.log(harEntry);19const {
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!