| 'use strict'; |
| |
| const common = require('../common'); |
| const assert = require('assert'); |
| const { |
| PerformanceObserver, |
| PerformanceEntry, |
| PerformanceResourceTiming, |
| performance: { |
| clearResourceTimings, |
| markResourceTiming, |
| }, |
| } = require('perf_hooks'); |
| |
| assert(PerformanceObserver); |
| assert(PerformanceEntry); |
| assert(PerformanceResourceTiming); |
| assert(clearResourceTimings); |
| assert(markResourceTiming); |
| |
| function createTimingInfo({ |
| startTime = 0, |
| redirectStartTime = 0, |
| redirectEndTime = 0, |
| postRedirectStartTime = 0, |
| finalServiceWorkerStartTime = 0, |
| finalNetworkRequestStartTime = 0, |
| finalNetworkResponseStartTime = 0, |
| endTime = 0, |
| encodedBodySize = 0, |
| decodedBodySize = 0, |
| finalConnectionTimingInfo = null |
| }) { |
| if (finalConnectionTimingInfo !== null) { |
| finalConnectionTimingInfo.domainLookupStartTime = |
| finalConnectionTimingInfo.domainLookupStartTime || 0; |
| finalConnectionTimingInfo.domainLookupEndTime = |
| finalConnectionTimingInfo.domainLookupEndTime || 0; |
| finalConnectionTimingInfo.connectionStartTime = |
| finalConnectionTimingInfo.connectionStartTime || 0; |
| finalConnectionTimingInfo.connectionEndTime = |
| finalConnectionTimingInfo.connectionEndTime || 0; |
| finalConnectionTimingInfo.secureConnectionStartTime = |
| finalConnectionTimingInfo.secureConnectionStartTime || 0; |
| finalConnectionTimingInfo.ALPNNegotiatedProtocol = |
| finalConnectionTimingInfo.ALPNNegotiatedProtocol || []; |
| } |
| return { |
| startTime, |
| redirectStartTime, |
| redirectEndTime, |
| postRedirectStartTime, |
| finalServiceWorkerStartTime, |
| finalNetworkRequestStartTime, |
| finalNetworkResponseStartTime, |
| endTime, |
| encodedBodySize, |
| decodedBodySize, |
| finalConnectionTimingInfo, |
| }; |
| } |
| |
| // PerformanceResourceTiming should not be initialized externally |
| { |
| assert.throws(() => new PerformanceResourceTiming(), { |
| name: 'TypeError', |
| message: 'Illegal constructor', |
| code: 'ERR_ILLEGAL_CONSTRUCTOR', |
| }); |
| } |
| |
| // Using performance.getEntries*() |
| { |
| const timingInfo = createTimingInfo({ finalConnectionTimingInfo: {} }); |
| const customGlobal = {}; |
| const requestedUrl = 'http://localhost:8080'; |
| const cacheMode = 'local'; |
| const initiatorType = 'fetch'; |
| const resource = markResourceTiming( |
| timingInfo, |
| requestedUrl, |
| initiatorType, |
| customGlobal, |
| cacheMode, |
| ); |
| |
| assert(resource instanceof PerformanceEntry); |
| assert(resource instanceof PerformanceResourceTiming); |
| |
| { |
| const entries = performance.getEntries(); |
| assert.strictEqual(entries.length, 1); |
| assert(entries[0] instanceof PerformanceResourceTiming); |
| } |
| |
| { |
| const entries = performance.getEntriesByType('resource'); |
| assert.strictEqual(entries.length, 1); |
| assert(entries[0] instanceof PerformanceResourceTiming); |
| } |
| |
| { |
| const entries = performance.getEntriesByName(resource.name); |
| assert.strictEqual(entries.length, 1); |
| assert(entries[0] instanceof PerformanceResourceTiming); |
| } |
| |
| clearResourceTimings(); |
| assert.strictEqual(performance.getEntries().length, 0); |
| } |
| |
| // Assert resource data based in timingInfo |
| |
| // default values |
| { |
| const timingInfo = createTimingInfo({ finalConnectionTimingInfo: {} }); |
| const customGlobal = {}; |
| const requestedUrl = 'http://localhost:8080'; |
| const cacheMode = 'local'; |
| const initiatorType = 'fetch'; |
| const resource = markResourceTiming( |
| timingInfo, |
| requestedUrl, |
| initiatorType, |
| customGlobal, |
| cacheMode, |
| ); |
| |
| assert(resource instanceof PerformanceEntry); |
| assert(resource instanceof PerformanceResourceTiming); |
| |
| assert.strictEqual(resource.entryType, 'resource'); |
| assert.strictEqual(resource.name, requestedUrl); |
| assert.ok(typeof resource.cacheMode === 'undefined', 'cacheMode does not have a getter'); |
| assert.strictEqual(resource.startTime, timingInfo.startTime); |
| assert.strictEqual(resource.duration, 0); |
| assert.strictEqual(resource.workerStart, 0); |
| assert.strictEqual(resource.redirectStart, 0); |
| assert.strictEqual(resource.redirectEnd, 0); |
| assert.strictEqual(resource.fetchStart, 0); |
| assert.strictEqual(resource.domainLookupStart, 0); |
| assert.strictEqual(resource.domainLookupEnd, 0); |
| assert.strictEqual(resource.connectStart, 0); |
| assert.strictEqual(resource.connectEnd, 0); |
| assert.strictEqual(resource.secureConnectionStart, 0); |
| assert.deepStrictEqual(resource.nextHopProtocol, []); |
| assert.strictEqual(resource.requestStart, 0); |
| assert.strictEqual(resource.responseStart, 0); |
| assert.strictEqual(resource.responseEnd, 0); |
| assert.strictEqual(resource.encodedBodySize, 0); |
| assert.strictEqual(resource.decodedBodySize, 0); |
| assert.strictEqual(resource.transferSize, 0); |
| assert.deepStrictEqual(resource.toJSON(), { |
| name: requestedUrl, |
| entryType: 'resource', |
| startTime: 0, |
| duration: 0, |
| initiatorType, |
| nextHopProtocol: [], |
| workerStart: 0, |
| redirectStart: 0, |
| redirectEnd: 0, |
| fetchStart: 0, |
| domainLookupStart: 0, |
| domainLookupEnd: 0, |
| connectStart: 0, |
| connectEnd: 0, |
| secureConnectionStart: 0, |
| requestStart: 0, |
| responseStart: 0, |
| responseEnd: 0, |
| transferSize: 0, |
| encodedBodySize: 0, |
| decodedBodySize: 0, |
| }); |
| |
| assert(resource instanceof PerformanceEntry); |
| assert(resource instanceof PerformanceResourceTiming); |
| |
| clearResourceTimings(); |
| const entries = performance.getEntries(); |
| assert.strictEqual(entries.length, 0); |
| } |
| |
| // custom getters math |
| { |
| const timingInfo = createTimingInfo({ |
| endTime: 100, |
| startTime: 50, |
| encodedBodySize: 150, |
| }); |
| const customGlobal = {}; |
| const requestedUrl = 'http://localhost:8080'; |
| const cacheMode = ''; |
| const initiatorType = 'fetch'; |
| const resource = markResourceTiming( |
| timingInfo, |
| requestedUrl, |
| initiatorType, |
| customGlobal, |
| cacheMode, |
| ); |
| |
| assert(resource instanceof PerformanceEntry); |
| assert(resource instanceof PerformanceResourceTiming); |
| |
| assert.strictEqual(resource.entryType, 'resource'); |
| assert.strictEqual(resource.name, requestedUrl); |
| assert.ok(typeof resource.cacheMode === 'undefined', 'cacheMode does not have a getter'); |
| assert.strictEqual(resource.startTime, timingInfo.startTime); |
| // Duration should be the timingInfo endTime - startTime |
| assert.strictEqual(resource.duration, 50); |
| // TransferSize should be encodedBodySize + 300 when cacheMode is empty |
| assert.strictEqual(resource.transferSize, 450); |
| |
| assert(resource instanceof PerformanceEntry); |
| assert(resource instanceof PerformanceResourceTiming); |
| |
| clearResourceTimings(); |
| const entries = performance.getEntries(); |
| assert.strictEqual(entries.length, 0); |
| } |
| |
| // Using PerformanceObserver |
| { |
| const obs = new PerformanceObserver(common.mustCall((list) => { |
| { |
| const entries = list.getEntries(); |
| assert.strictEqual(entries.length, 1); |
| assert(entries[0] instanceof PerformanceResourceTiming); |
| } |
| { |
| const entries = list.getEntriesByType('resource'); |
| assert.strictEqual(entries.length, 1); |
| assert(entries[0] instanceof PerformanceResourceTiming); |
| } |
| { |
| const entries = list.getEntriesByName('http://localhost:8080'); |
| assert.strictEqual(entries.length, 1); |
| assert(entries[0] instanceof PerformanceResourceTiming); |
| } |
| obs.disconnect(); |
| })); |
| obs.observe({ entryTypes: ['resource'] }); |
| |
| const timingInfo = createTimingInfo({ finalConnectionTimingInfo: {} }); |
| const customGlobal = {}; |
| const requestedUrl = 'http://localhost:8080'; |
| const cacheMode = 'local'; |
| const initiatorType = 'fetch'; |
| const resource = markResourceTiming( |
| timingInfo, |
| requestedUrl, |
| initiatorType, |
| customGlobal, |
| cacheMode, |
| ); |
| |
| assert(resource instanceof PerformanceEntry); |
| assert(resource instanceof PerformanceResourceTiming); |
| |
| clearResourceTimings(); |
| const entries = performance.getEntries(); |
| assert.strictEqual(entries.length, 0); |
| } |