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/.
7 Ensure the `--firefox.preference=network.http.http3.enable:true` is
11 async function getNumImagesLoaded(elementSelector, commands) {
12 return commands.js.run(`
14 document.querySelectorAll(${elementSelector}).forEach(e => {
15 sum += e.complete & e.naturalHeight != 0;
21 async function waitForImgLoadEnd(
31 let starttime = await commands.js.run(`return performance.now();`);
32 let endtime = await commands.js.run(`return performance.now();`);
38 ((await commands.js.run(`return performance.now();`)) - starttime <
42 // Wait a bit before making another round
43 await commands.wait.byTime(iterationDelay);
44 newCount = await counter(elementSelector, commands);
45 context.log.debug(`${newCount}, ${prevCount}, ${stableCount}`);
47 // Check if we are approaching stability
48 if (newCount == prevCount) {
49 // Gather the end time now
50 if (stableCount == 0) {
51 endtime = await commands.js.run(`return performance.now();`);
59 if (stableCount >= maxStableCount) {
68 numResources: newCount,
72 async function test(context, commands) {
73 let rootUrl = "https://www.google.com/search?q=kittens&tbm=isch";
77 const average = arr => arr.reduce((p, c) => p + c, 0) / arr.length;
79 if (typeof context.options.browsertime !== "undefined") {
80 if (typeof context.options.browsertime.waitTime !== "undefined") {
81 waitTime = context.options.browsertime.waitTime;
83 if (typeof context.options.browsertime.numScrolls !== "undefined") {
84 numScrolls = context.options.browsertime.numScrolls;
88 // Make firefox learn of HTTP/3 server
89 await commands.navigate(rootUrl);
92 for (let cycle = 0; cycle < cycles; cycle++) {
93 // Measure the pageload
94 await commands.measure.start("pageload");
95 await commands.navigate(rootUrl);
96 await commands.measure.stop();
98 async function getHeight() {
99 return commands.js.run(`return document.body.scrollHeight;`);
103 let badIterations = 0;
105 for (let iteration = 0; iteration < numScrolls; iteration++) {
106 // Get current image count
107 let currCount = await getNumImagesLoaded(`".isv-r img"`, commands);
108 prevHeight = await getHeight();
110 // Scroll to a ridiculously high value for "infinite" down-scrolling
111 commands.js.runAndWait(`
112 window.scrollTo({ top: 100000000 })
116 The maxStableCount of 22 was chosen as a trade-off between fast iterations
117 and minimizing the number of bad iterations.
119 let results = await waitForImgLoadEnd(
131 let ndiff = results.numResources - currCount;
132 let tdiff = (results.end - results.start) / 1000;
134 // Check if we had a bad iteration
136 // Check if the end of the search results was reached
137 if (prevHeight == (await getHeight())) {
138 context.log.info("Reached end of page.");
141 context.log.info("Bad iteration, redoing...");
144 if (badIterations == 5) {
145 throw new Error("Too many bad scroll iterations occurred");
150 context.log.info(`${ndiff}, ${tdiff}`);
151 vals.push(ndiff / tdiff);
153 // Wait X seconds before scrolling again
154 await commands.wait.byTime(waitTime);
158 throw new Error("No requestsPerSecond values were obtained");
161 commands.measure.result[0].browserScripts.pageinfo.imagesPerSecond =
164 // Test clicking and and opening an image
165 await commands.wait.byTime(waitTime);
166 commands.click.byJs(`
167 const links = document.querySelectorAll(".islib"); links[links.length-1]
169 let results = await waitForImgLoadEnd(
179 commands.measure.result[0].browserScripts.pageinfo.imageLoadTime =
180 results.end - results.start;
186 owner: "Network Team",
187 component: "netwerk",
189 description: "Measures the number of images per second after a scroll.",