tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

perftest_http3_facebook_scroll.js (4634B)


      1 // This Source Code Form is subject to the terms of the Mozilla Public
      2 // License, v. 2.0. If a copy of the MPL was not distributed with this
      3 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 /* eslint-env node */
      5 
      6 /*
      7 Ensure the `--firefox.preference=network.http.http3.enable:true` is
      8 set for this test.
      9 */
     10 
     11 async function captureNetworkRequest(commands) {
     12  var capture_network_request = [];
     13  var capture_resource = await commands.js.run(`
     14    return performance.getEntriesByType("resource");
     15  `);
     16  for (var i = 0; i < capture_resource.length; i++) {
     17    capture_network_request.push(capture_resource[i].name);
     18  }
     19  return capture_network_request;
     20 }
     21 
     22 async function waitForScrollRequestsEnd(
     23  prevCount,
     24  maxStableCount,
     25  timeout,
     26  commands,
     27  context
     28 ) {
     29  let starttime = await commands.js.run(`return performance.now();`);
     30  let endtime = await commands.js.run(`return performance.now();`);
     31  let changing = true;
     32  let newCount = -1;
     33  let stableCount = 0;
     34 
     35  while (
     36    ((await commands.js.run(`return performance.now();`)) - starttime <
     37      timeout) &
     38    changing
     39  ) {
     40    // Wait a bit before making another round
     41    await commands.wait.byTime(100);
     42    newCount = (await captureNetworkRequest(commands)).length;
     43    context.log.debug(`${newCount}, ${prevCount}, ${stableCount}`);
     44 
     45    // Check if we are approaching stability
     46    if (newCount == prevCount) {
     47      // Gather the end time now
     48      if (stableCount == 0) {
     49        endtime = await commands.js.run(`return performance.now();`);
     50      }
     51      stableCount++;
     52    } else {
     53      prevCount = newCount;
     54      stableCount = 0;
     55    }
     56 
     57    if (stableCount >= maxStableCount) {
     58      // Stability achieved
     59      changing = false;
     60    }
     61  }
     62 
     63  return {
     64    start: starttime,
     65    end: endtime,
     66    numResources: newCount,
     67  };
     68 }
     69 
     70 async function test(context, commands) {
     71  let rootUrl = "https://www.facebook.com/lambofgod/";
     72  let waitTime = 1000;
     73  let numScrolls = 5;
     74 
     75  const average = arr => arr.reduce((p, c) => p + c, 0) / arr.length;
     76 
     77  if (typeof context.options.browsertime !== "undefined") {
     78    if (typeof context.options.browsertime.waitTime !== "undefined") {
     79      waitTime = context.options.browsertime.waitTime;
     80    }
     81    if (typeof context.options.browsertime.numScrolls !== "undefined") {
     82      numScrolls = context.options.browsertime.numScrolls;
     83    }
     84  }
     85 
     86  // Make firefox learn of HTTP/3 server
     87  await commands.navigate(rootUrl);
     88 
     89  let cycles = 1;
     90  for (let cycle = 0; cycle < cycles; cycle++) {
     91    // Measure the pageload
     92    await commands.measure.start("pageload");
     93    await commands.navigate(rootUrl);
     94    await commands.measure.stop();
     95 
     96    // Initial scroll to make the new user popup show
     97    await commands.js.runAndWait(
     98      `window.scrollTo({ top: 1000, behavior: 'smooth' })`
     99    );
    100    await commands.wait.byTime(1000);
    101    await commands.click.byLinkTextAndWait("Not Now");
    102 
    103    let vals = [];
    104    let badIterations = 0;
    105    for (let iteration = 0; iteration < numScrolls; iteration++) {
    106      // Clear old resources
    107      await commands.js.run(`performance.clearResourceTimings();`);
    108 
    109      // Get current resource count
    110      let currCount = (await captureNetworkRequest(commands)).length;
    111 
    112      // Scroll to a ridiculously high value for "infinite" down-scrolling
    113      commands.js.runAndWait(`
    114        window.scrollTo({ top: 100000000 })
    115      `);
    116 
    117      /*
    118      The maxStableCount of 22 was chosen as a trade-off between fast iterations
    119      and minimizing the number of bad iterations.
    120      */
    121      let newInfo = await waitForScrollRequestsEnd(
    122        currCount,
    123        22,
    124        120000,
    125        commands,
    126        context
    127      );
    128 
    129      // Gather metrics
    130      let ndiff = newInfo.numResources - currCount;
    131      let tdiff = (newInfo.end - newInfo.start) / 1000;
    132 
    133      // Check if we had a bad iteration
    134      if (ndiff == 0) {
    135        context.log.info("Bad iteration, redoing...");
    136        iteration--;
    137        badIterations++;
    138        if (badIterations == 5) {
    139          throw new Error("Too many bad scroll iterations occurred");
    140        }
    141        continue;
    142      }
    143 
    144      vals.push(ndiff / tdiff);
    145 
    146      // Wait X seconds before scrolling again
    147      await commands.wait.byTime(waitTime);
    148    }
    149 
    150    if (!vals.length) {
    151      throw new Error("No requestsPerSecond values were obtained");
    152    }
    153 
    154    commands.measure.result[0].browserScripts.pageinfo.requestsPerSecond =
    155      average(vals);
    156  }
    157 }
    158 
    159 module.exports = {
    160  test,
    161  owner: "Network Team",
    162  component: "netwerk",
    163  name: "facebook-scroll",
    164  description: "Measures the number of requests per second after a scroll.",
    165 };