Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

// 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 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.",
};