// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
/* eslint-env node */
/*
Ensure the `--firefox.preference=network.http.http3.enable:true` is
set for this test.
*/
async
function getNumLoaded(commands) {
return commands.js.run(`
let sum = 0;
document.querySelectorAll(
"#imgContainer img").forEach(e => {
sum += e.complete & e.naturalHeight != 0;
});
return sum;
`);
}
async
function waitForImgLoadEnd(
prevCount,
maxStableCount,
timeout,
commands,
context
) {
let starttime = await commands.js.run(`
return performance.now();`);
let endtime = await commands.js.run(`
return performance.now();`);
let changing =
true;
let newCount = -1;
let stableCount = 0;
while (
((await commands.js.run(`
return performance.now();`)) - starttime <
timeout) &
changing
) {
// Wait a bit before making another round
await commands.wait.byTime(100);
newCount = await getNumLoaded(commands);
context.log.debug(`${newCount}, ${prevCount}, ${stableCount}`);
// Check if we are approaching stability
if (newCount == prevCount) {
// Gather the end time now
if (stableCount == 0) {
endtime = await commands.js.run(`
return performance.now();`);
}
stableCount++;
}
else {
prevCount = newCount;
stableCount = 0;
}
if (stableCount >= maxStableCount) {
// Stability achieved
changing =
false;
}
}
return {
start: starttime,
end: endtime,
numResources: newCount,
};
}
async
function test(context, commands) {
let rootUrl =
"https://lucaspardue.com/quictilesfetch.html";
let cycles = 5;
if (
(
typeof context.options.browsertime !==
"undefined") &
(
typeof context.options.browsertime.cycles !==
"undefined")
) {
cycles = context.options.browsertime.cycles;
}
// Make firefox learn of HTTP/3 server
// XXX: Need to build an HTTP/3-specific conditioned profile
// to handle these pre-navigations.
await commands.navigate(rootUrl);
let combos = [
[100, 1],
[100, 100],
[300, 300],
];
for (let cycle = 0; cycle < cycles; cycle++) {
for (let combo = 0; combo < combos.length; combo++) {
await commands.measure.start(
"pageload");
await commands.navigate(rootUrl);
await commands.measure.stop();
let last = commands.measure.result.length - 1;
commands.measure.result[last].browserScripts.pageinfo.url =
`LucasQUIC (r=${combos[combo][0]}, p=${combos[combo][1]})`;
// Set the input fields
await commands.js.runAndWait(`
document.querySelector(
"#maxReq").setAttribute(
"value",
${combos[combo][0]}
)
`);
await commands.js.runAndWait(`
document.querySelector(
"#reqGroup").setAttribute(
"value",
${combos[combo][1]}
)
`);
// Start the test and wait for the images to finish loading
commands.click.byJs(`document.querySelector(
"button")`);
let results = await waitForImgLoadEnd(0, 40, 120000, commands, context);
commands.measure.result[last].browserScripts.pageinfo.resourceLoadTime =
results.end - results.start;
commands.measure.result[last].browserScripts.pageinfo.imagesLoaded =
results.numResources;
commands.measure.result[last].browserScripts.pageinfo.imagesMissed =
combos[combo][0] - results.numResources;
}
}
}
module.exports = {
test,
owner:
"Network Team",
name:
"lq-fetch",
component:
"netwerk",
description:
"Measures the amount of time it takes to load a set of images.",
};