11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ciconst util = require('util');
61cb0ef41Sopenharmony_ciconst {
71cb0ef41Sopenharmony_ci  PerformanceObserver,
81cb0ef41Sopenharmony_ci  PerformanceEntry,
91cb0ef41Sopenharmony_ci  PerformanceResourceTiming,
101cb0ef41Sopenharmony_ci  performance: {
111cb0ef41Sopenharmony_ci    clearResourceTimings,
121cb0ef41Sopenharmony_ci    markResourceTiming,
131cb0ef41Sopenharmony_ci  },
141cb0ef41Sopenharmony_ci} = require('perf_hooks');
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ciassert(PerformanceObserver);
171cb0ef41Sopenharmony_ciassert(PerformanceEntry);
181cb0ef41Sopenharmony_ciassert.throws(() => new PerformanceEntry(), { code: 'ERR_ILLEGAL_CONSTRUCTOR' });
191cb0ef41Sopenharmony_ciassert(PerformanceResourceTiming);
201cb0ef41Sopenharmony_ciassert(clearResourceTimings);
211cb0ef41Sopenharmony_ciassert(markResourceTiming);
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_cifunction createTimingInfo({
241cb0ef41Sopenharmony_ci  startTime = 0,
251cb0ef41Sopenharmony_ci  redirectStartTime = 0,
261cb0ef41Sopenharmony_ci  redirectEndTime = 0,
271cb0ef41Sopenharmony_ci  postRedirectStartTime = 0,
281cb0ef41Sopenharmony_ci  finalServiceWorkerStartTime = 0,
291cb0ef41Sopenharmony_ci  finalNetworkRequestStartTime = 0,
301cb0ef41Sopenharmony_ci  finalNetworkResponseStartTime = 0,
311cb0ef41Sopenharmony_ci  endTime = 0,
321cb0ef41Sopenharmony_ci  encodedBodySize = 0,
331cb0ef41Sopenharmony_ci  decodedBodySize = 0,
341cb0ef41Sopenharmony_ci  finalConnectionTimingInfo = null
351cb0ef41Sopenharmony_ci}) {
361cb0ef41Sopenharmony_ci  if (finalConnectionTimingInfo !== null) {
371cb0ef41Sopenharmony_ci    finalConnectionTimingInfo.domainLookupStartTime =
381cb0ef41Sopenharmony_ci        finalConnectionTimingInfo.domainLookupStartTime || 0;
391cb0ef41Sopenharmony_ci    finalConnectionTimingInfo.domainLookupEndTime =
401cb0ef41Sopenharmony_ci        finalConnectionTimingInfo.domainLookupEndTime || 0;
411cb0ef41Sopenharmony_ci    finalConnectionTimingInfo.connectionStartTime =
421cb0ef41Sopenharmony_ci        finalConnectionTimingInfo.connectionStartTime || 0;
431cb0ef41Sopenharmony_ci    finalConnectionTimingInfo.connectionEndTime =
441cb0ef41Sopenharmony_ci        finalConnectionTimingInfo.connectionEndTime || 0;
451cb0ef41Sopenharmony_ci    finalConnectionTimingInfo.secureConnectionStartTime =
461cb0ef41Sopenharmony_ci        finalConnectionTimingInfo.secureConnectionStartTime || 0;
471cb0ef41Sopenharmony_ci    finalConnectionTimingInfo.ALPNNegotiatedProtocol =
481cb0ef41Sopenharmony_ci        finalConnectionTimingInfo.ALPNNegotiatedProtocol || [];
491cb0ef41Sopenharmony_ci  }
501cb0ef41Sopenharmony_ci  return {
511cb0ef41Sopenharmony_ci    startTime,
521cb0ef41Sopenharmony_ci    redirectStartTime,
531cb0ef41Sopenharmony_ci    redirectEndTime,
541cb0ef41Sopenharmony_ci    postRedirectStartTime,
551cb0ef41Sopenharmony_ci    finalServiceWorkerStartTime,
561cb0ef41Sopenharmony_ci    finalNetworkRequestStartTime,
571cb0ef41Sopenharmony_ci    finalNetworkResponseStartTime,
581cb0ef41Sopenharmony_ci    endTime,
591cb0ef41Sopenharmony_ci    encodedBodySize,
601cb0ef41Sopenharmony_ci    decodedBodySize,
611cb0ef41Sopenharmony_ci    finalConnectionTimingInfo,
621cb0ef41Sopenharmony_ci  };
631cb0ef41Sopenharmony_ci}
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci// PerformanceResourceTiming should not be initialized externally
661cb0ef41Sopenharmony_ci{
671cb0ef41Sopenharmony_ci  assert.throws(() => new PerformanceResourceTiming(), {
681cb0ef41Sopenharmony_ci    name: 'TypeError',
691cb0ef41Sopenharmony_ci    message: 'Illegal constructor',
701cb0ef41Sopenharmony_ci    code: 'ERR_ILLEGAL_CONSTRUCTOR',
711cb0ef41Sopenharmony_ci  });
721cb0ef41Sopenharmony_ci}
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci// Using performance.getEntries*()
751cb0ef41Sopenharmony_ci{
761cb0ef41Sopenharmony_ci  const timingInfo = createTimingInfo({ finalConnectionTimingInfo: {} });
771cb0ef41Sopenharmony_ci  const customGlobal = {};
781cb0ef41Sopenharmony_ci  const requestedUrl = 'http://localhost:8080';
791cb0ef41Sopenharmony_ci  const cacheMode = 'local';
801cb0ef41Sopenharmony_ci  const initiatorType = 'fetch';
811cb0ef41Sopenharmony_ci  const resource = markResourceTiming(
821cb0ef41Sopenharmony_ci    timingInfo,
831cb0ef41Sopenharmony_ci    requestedUrl,
841cb0ef41Sopenharmony_ci    initiatorType,
851cb0ef41Sopenharmony_ci    customGlobal,
861cb0ef41Sopenharmony_ci    cacheMode,
871cb0ef41Sopenharmony_ci  );
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceEntry);
901cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceResourceTiming);
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  {
931cb0ef41Sopenharmony_ci    const entries = performance.getEntries();
941cb0ef41Sopenharmony_ci    assert.strictEqual(entries.length, 1);
951cb0ef41Sopenharmony_ci    assert(entries[0] instanceof PerformanceResourceTiming);
961cb0ef41Sopenharmony_ci  }
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci  {
991cb0ef41Sopenharmony_ci    const entries = performance.getEntriesByType('resource');
1001cb0ef41Sopenharmony_ci    assert.strictEqual(entries.length, 1);
1011cb0ef41Sopenharmony_ci    assert(entries[0] instanceof PerformanceResourceTiming);
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  {
1051cb0ef41Sopenharmony_ci    const entries = performance.getEntriesByName(resource.name);
1061cb0ef41Sopenharmony_ci    assert.strictEqual(entries.length, 1);
1071cb0ef41Sopenharmony_ci    assert(entries[0] instanceof PerformanceResourceTiming);
1081cb0ef41Sopenharmony_ci  }
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  clearResourceTimings();
1111cb0ef41Sopenharmony_ci  assert.strictEqual(performance.getEntries().length, 0);
1121cb0ef41Sopenharmony_ci}
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci// Assert resource data based in timingInfo
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci// default values
1171cb0ef41Sopenharmony_ci{
1181cb0ef41Sopenharmony_ci  const timingInfo = createTimingInfo({ finalConnectionTimingInfo: {} });
1191cb0ef41Sopenharmony_ci  const customGlobal = {};
1201cb0ef41Sopenharmony_ci  const requestedUrl = 'http://localhost:8080';
1211cb0ef41Sopenharmony_ci  const cacheMode = 'local';
1221cb0ef41Sopenharmony_ci  const initiatorType = 'fetch';
1231cb0ef41Sopenharmony_ci  const resource = markResourceTiming(
1241cb0ef41Sopenharmony_ci    timingInfo,
1251cb0ef41Sopenharmony_ci    requestedUrl,
1261cb0ef41Sopenharmony_ci    initiatorType,
1271cb0ef41Sopenharmony_ci    customGlobal,
1281cb0ef41Sopenharmony_ci    cacheMode,
1291cb0ef41Sopenharmony_ci  );
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceEntry);
1321cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceResourceTiming);
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  assert.strictEqual(resource.entryType, 'resource');
1351cb0ef41Sopenharmony_ci  assert.strictEqual(resource.name, requestedUrl);
1361cb0ef41Sopenharmony_ci  assert.ok(typeof resource.cacheMode === 'undefined', 'cacheMode does not have a getter');
1371cb0ef41Sopenharmony_ci  assert.strictEqual(resource.startTime, timingInfo.startTime);
1381cb0ef41Sopenharmony_ci  assert.strictEqual(resource.duration, 0);
1391cb0ef41Sopenharmony_ci  assert.strictEqual(resource.initiatorType, initiatorType);
1401cb0ef41Sopenharmony_ci  assert.strictEqual(resource.workerStart, 0);
1411cb0ef41Sopenharmony_ci  assert.strictEqual(resource.redirectStart, 0);
1421cb0ef41Sopenharmony_ci  assert.strictEqual(resource.redirectEnd, 0);
1431cb0ef41Sopenharmony_ci  assert.strictEqual(resource.fetchStart, 0);
1441cb0ef41Sopenharmony_ci  assert.strictEqual(resource.domainLookupStart, 0);
1451cb0ef41Sopenharmony_ci  assert.strictEqual(resource.domainLookupEnd, 0);
1461cb0ef41Sopenharmony_ci  assert.strictEqual(resource.connectStart, 0);
1471cb0ef41Sopenharmony_ci  assert.strictEqual(resource.connectEnd, 0);
1481cb0ef41Sopenharmony_ci  assert.strictEqual(resource.secureConnectionStart, 0);
1491cb0ef41Sopenharmony_ci  assert.deepStrictEqual(resource.nextHopProtocol, []);
1501cb0ef41Sopenharmony_ci  assert.strictEqual(resource.requestStart, 0);
1511cb0ef41Sopenharmony_ci  assert.strictEqual(resource.responseStart, 0);
1521cb0ef41Sopenharmony_ci  assert.strictEqual(resource.responseEnd, 0);
1531cb0ef41Sopenharmony_ci  assert.strictEqual(resource.encodedBodySize, 0);
1541cb0ef41Sopenharmony_ci  assert.strictEqual(resource.decodedBodySize, 0);
1551cb0ef41Sopenharmony_ci  assert.strictEqual(resource.transferSize, 0);
1561cb0ef41Sopenharmony_ci  assert.deepStrictEqual(resource.toJSON(), {
1571cb0ef41Sopenharmony_ci    name: requestedUrl,
1581cb0ef41Sopenharmony_ci    entryType: 'resource',
1591cb0ef41Sopenharmony_ci    startTime: 0,
1601cb0ef41Sopenharmony_ci    duration: 0,
1611cb0ef41Sopenharmony_ci    initiatorType,
1621cb0ef41Sopenharmony_ci    nextHopProtocol: [],
1631cb0ef41Sopenharmony_ci    workerStart: 0,
1641cb0ef41Sopenharmony_ci    redirectStart: 0,
1651cb0ef41Sopenharmony_ci    redirectEnd: 0,
1661cb0ef41Sopenharmony_ci    fetchStart: 0,
1671cb0ef41Sopenharmony_ci    domainLookupStart: 0,
1681cb0ef41Sopenharmony_ci    domainLookupEnd: 0,
1691cb0ef41Sopenharmony_ci    connectStart: 0,
1701cb0ef41Sopenharmony_ci    connectEnd: 0,
1711cb0ef41Sopenharmony_ci    secureConnectionStart: 0,
1721cb0ef41Sopenharmony_ci    requestStart: 0,
1731cb0ef41Sopenharmony_ci    responseStart: 0,
1741cb0ef41Sopenharmony_ci    responseEnd: 0,
1751cb0ef41Sopenharmony_ci    transferSize: 0,
1761cb0ef41Sopenharmony_ci    encodedBodySize: 0,
1771cb0ef41Sopenharmony_ci    decodedBodySize: 0,
1781cb0ef41Sopenharmony_ci  });
1791cb0ef41Sopenharmony_ci  assert.strictEqual(util.inspect(performance.getEntries()), `[
1801cb0ef41Sopenharmony_ci  PerformanceResourceTiming {
1811cb0ef41Sopenharmony_ci    name: 'http://localhost:8080',
1821cb0ef41Sopenharmony_ci    entryType: 'resource',
1831cb0ef41Sopenharmony_ci    startTime: 0,
1841cb0ef41Sopenharmony_ci    duration: 0,
1851cb0ef41Sopenharmony_ci    initiatorType: 'fetch',
1861cb0ef41Sopenharmony_ci    nextHopProtocol: [],
1871cb0ef41Sopenharmony_ci    workerStart: 0,
1881cb0ef41Sopenharmony_ci    redirectStart: 0,
1891cb0ef41Sopenharmony_ci    redirectEnd: 0,
1901cb0ef41Sopenharmony_ci    fetchStart: 0,
1911cb0ef41Sopenharmony_ci    domainLookupStart: 0,
1921cb0ef41Sopenharmony_ci    domainLookupEnd: 0,
1931cb0ef41Sopenharmony_ci    connectStart: 0,
1941cb0ef41Sopenharmony_ci    connectEnd: 0,
1951cb0ef41Sopenharmony_ci    secureConnectionStart: 0,
1961cb0ef41Sopenharmony_ci    requestStart: 0,
1971cb0ef41Sopenharmony_ci    responseStart: 0,
1981cb0ef41Sopenharmony_ci    responseEnd: 0,
1991cb0ef41Sopenharmony_ci    transferSize: 0,
2001cb0ef41Sopenharmony_ci    encodedBodySize: 0,
2011cb0ef41Sopenharmony_ci    decodedBodySize: 0
2021cb0ef41Sopenharmony_ci  }
2031cb0ef41Sopenharmony_ci]`);
2041cb0ef41Sopenharmony_ci  assert.strictEqual(util.inspect(resource), `PerformanceResourceTiming {
2051cb0ef41Sopenharmony_ci  name: 'http://localhost:8080',
2061cb0ef41Sopenharmony_ci  entryType: 'resource',
2071cb0ef41Sopenharmony_ci  startTime: 0,
2081cb0ef41Sopenharmony_ci  duration: 0,
2091cb0ef41Sopenharmony_ci  initiatorType: 'fetch',
2101cb0ef41Sopenharmony_ci  nextHopProtocol: [],
2111cb0ef41Sopenharmony_ci  workerStart: 0,
2121cb0ef41Sopenharmony_ci  redirectStart: 0,
2131cb0ef41Sopenharmony_ci  redirectEnd: 0,
2141cb0ef41Sopenharmony_ci  fetchStart: 0,
2151cb0ef41Sopenharmony_ci  domainLookupStart: 0,
2161cb0ef41Sopenharmony_ci  domainLookupEnd: 0,
2171cb0ef41Sopenharmony_ci  connectStart: 0,
2181cb0ef41Sopenharmony_ci  connectEnd: 0,
2191cb0ef41Sopenharmony_ci  secureConnectionStart: 0,
2201cb0ef41Sopenharmony_ci  requestStart: 0,
2211cb0ef41Sopenharmony_ci  responseStart: 0,
2221cb0ef41Sopenharmony_ci  responseEnd: 0,
2231cb0ef41Sopenharmony_ci  transferSize: 0,
2241cb0ef41Sopenharmony_ci  encodedBodySize: 0,
2251cb0ef41Sopenharmony_ci  decodedBodySize: 0
2261cb0ef41Sopenharmony_ci}`);
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceEntry);
2291cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceResourceTiming);
2301cb0ef41Sopenharmony_ci
2311cb0ef41Sopenharmony_ci  clearResourceTimings();
2321cb0ef41Sopenharmony_ci  const entries = performance.getEntries();
2331cb0ef41Sopenharmony_ci  assert.strictEqual(entries.length, 0);
2341cb0ef41Sopenharmony_ci}
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci// custom getters math
2371cb0ef41Sopenharmony_ci{
2381cb0ef41Sopenharmony_ci  const timingInfo = createTimingInfo({
2391cb0ef41Sopenharmony_ci    endTime: 100,
2401cb0ef41Sopenharmony_ci    startTime: 50,
2411cb0ef41Sopenharmony_ci    encodedBodySize: 150,
2421cb0ef41Sopenharmony_ci  });
2431cb0ef41Sopenharmony_ci  const customGlobal = {};
2441cb0ef41Sopenharmony_ci  const requestedUrl = 'http://localhost:8080';
2451cb0ef41Sopenharmony_ci  const cacheMode = '';
2461cb0ef41Sopenharmony_ci  const initiatorType = 'fetch';
2471cb0ef41Sopenharmony_ci  const resource = markResourceTiming(
2481cb0ef41Sopenharmony_ci    timingInfo,
2491cb0ef41Sopenharmony_ci    requestedUrl,
2501cb0ef41Sopenharmony_ci    initiatorType,
2511cb0ef41Sopenharmony_ci    customGlobal,
2521cb0ef41Sopenharmony_ci    cacheMode,
2531cb0ef41Sopenharmony_ci  );
2541cb0ef41Sopenharmony_ci
2551cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceEntry);
2561cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceResourceTiming);
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci  assert.strictEqual(resource.entryType, 'resource');
2591cb0ef41Sopenharmony_ci  assert.strictEqual(resource.name, requestedUrl);
2601cb0ef41Sopenharmony_ci  assert.ok(typeof resource.cacheMode === 'undefined', 'cacheMode does not have a getter');
2611cb0ef41Sopenharmony_ci  assert.strictEqual(resource.startTime, timingInfo.startTime);
2621cb0ef41Sopenharmony_ci  // Duration should be the timingInfo endTime - startTime
2631cb0ef41Sopenharmony_ci  assert.strictEqual(resource.duration, 50);
2641cb0ef41Sopenharmony_ci  // TransferSize should be encodedBodySize + 300 when cacheMode is empty
2651cb0ef41Sopenharmony_ci  assert.strictEqual(resource.transferSize, 450);
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceEntry);
2681cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceResourceTiming);
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci  clearResourceTimings();
2711cb0ef41Sopenharmony_ci  const entries = performance.getEntries();
2721cb0ef41Sopenharmony_ci  assert.strictEqual(entries.length, 0);
2731cb0ef41Sopenharmony_ci}
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci// Using PerformanceObserver
2761cb0ef41Sopenharmony_ci{
2771cb0ef41Sopenharmony_ci  const obs = new PerformanceObserver(common.mustCall((list) => {
2781cb0ef41Sopenharmony_ci    {
2791cb0ef41Sopenharmony_ci      const entries = list.getEntries();
2801cb0ef41Sopenharmony_ci      assert.strictEqual(entries.length, 1);
2811cb0ef41Sopenharmony_ci      assert(entries[0] instanceof PerformanceResourceTiming);
2821cb0ef41Sopenharmony_ci    }
2831cb0ef41Sopenharmony_ci    {
2841cb0ef41Sopenharmony_ci      const entries = list.getEntriesByType('resource');
2851cb0ef41Sopenharmony_ci      assert.strictEqual(entries.length, 1);
2861cb0ef41Sopenharmony_ci      assert(entries[0] instanceof PerformanceResourceTiming);
2871cb0ef41Sopenharmony_ci    }
2881cb0ef41Sopenharmony_ci    {
2891cb0ef41Sopenharmony_ci      const entries = list.getEntriesByName('http://localhost:8080');
2901cb0ef41Sopenharmony_ci      assert.strictEqual(entries.length, 1);
2911cb0ef41Sopenharmony_ci      assert(entries[0] instanceof PerformanceResourceTiming);
2921cb0ef41Sopenharmony_ci    }
2931cb0ef41Sopenharmony_ci    obs.disconnect();
2941cb0ef41Sopenharmony_ci  }));
2951cb0ef41Sopenharmony_ci  obs.observe({ entryTypes: ['resource'] });
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci  const timingInfo = createTimingInfo({ finalConnectionTimingInfo: {} });
2981cb0ef41Sopenharmony_ci  const customGlobal = {};
2991cb0ef41Sopenharmony_ci  const requestedUrl = 'http://localhost:8080';
3001cb0ef41Sopenharmony_ci  const cacheMode = 'local';
3011cb0ef41Sopenharmony_ci  const initiatorType = 'fetch';
3021cb0ef41Sopenharmony_ci  const resource = markResourceTiming(
3031cb0ef41Sopenharmony_ci    timingInfo,
3041cb0ef41Sopenharmony_ci    requestedUrl,
3051cb0ef41Sopenharmony_ci    initiatorType,
3061cb0ef41Sopenharmony_ci    customGlobal,
3071cb0ef41Sopenharmony_ci    cacheMode,
3081cb0ef41Sopenharmony_ci  );
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceEntry);
3111cb0ef41Sopenharmony_ci  assert(resource instanceof PerformanceResourceTiming);
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ci  clearResourceTimings();
3141cb0ef41Sopenharmony_ci  const entries = performance.getEntries();
3151cb0ef41Sopenharmony_ci  assert.strictEqual(entries.length, 0);
3161cb0ef41Sopenharmony_ci}
317