function $(id) {
return document.getElementById(id);
}
// Executes command at the chrome process.
// Limited to one argument (data), which is enough for TART.
// doneCallback will be called once done and, if applicable, with the result as argument.
// Execution might finish quickly (e.g. when setting prefs) or
// take a while (e.g. when triggering the test run)
let _replyId = 1;
function chromeExec(commandName, data, doneCallback) {
let replyEvent = `tart@mozilla.org:chrome-exec-reply:${_replyId++}`;
if (doneCallback) {
addEventListener(replyEvent, e => { doneCallback(e.detail); },
{once: true});
}
function toClipboard(text) {
chromeExec("toClipboard", text);
}
function runTest(config, doneCallback) {
chromeExec("runTest", config, doneCallback);
}
// Returns a Promise that resolves when the test extension is loaded.
function waitForLoad() {
async function tryPing() {
let pingPromise = new Promise(resolve => chromeExec("ping", null, resolve));
let timeoutPromise = new Promise((resolve, reject) => setTimeout(reject, 500));
function doneTest(dispResult) {
$("hide-during-run").style.display = "block";
$("show-during-run").style.display = "none";
if (dispResult) {
// Array of test results, each element has .name and .value (test name and test result).
// Test result may also be an array of numeric values (all the intervals)
lastResults = JSON.stringify(dispResult); // for "Copy to clipboard"button
var stats = {}; // Used for average, stddev when repeat!=1 var isRepeat = false;
for (var i in dispResult) { var di = dispResult[i]; var disp = [].concat(di.value).map(function(a) { return " " + (isNaN(a) ? -1 : a.toFixed(1)); }).join(" ");
dispResult[i] = String(di.name) + ": " + disp;
if (di.name.includes(".half") || di.name.includes(".all"))
dispResult[i] = "" + dispResult[i] + "";
if (di.name.includes(".raw"))
dispResult[i] = " " + dispResult[i]; // Add space before raw results (which are the first result of an animation)
// stats:
if (!di.name.includes(".raw")) {
if (!stats[di.name]) {
stats[di.name] = [];
} else {
isRepeat = true;
}
stats[di.name].push(di.value);
}
}
var dispStats = "";
if (isRepeat) {
dispStats = "Aggregated: ";
for (var s in stats) {
if (s.includes(".half") )
dispStats += " ";
dispStats += s + " Average (" + stats[s].length + "): " + average(stats[s]).toFixed(2) + " stddev: " + stddev(stats[s]).toFixed(2) + " ";
}
let testNames = [], testResults = [];
for (let result of JSON.parse(lastResults)) {
if (!Array.isArray(result.value)) {
testNames.push(result.name);
testResults.push(result.value);
}
}
window.tpRecordTime(testResults.join(","), 0, testNames.join(","));
}
}
var config = {subtests: [], repeat: 1}; // Empty subtests interpreted as all subtests, since otherwise meaningless.
var defaultConfig = {
repeat: 1,
rest: 500,
tickle: true,
controlProfiler: true, // If true, pause the profiler when not measuring. Else just add markers.
subtests: {
simple: true,
iconDpi1: true,
iconDpi2: true,
iconFadeDpi2: true,
newtabNoPreload: true,
newtabYesPreload: true,
simple3open3closeDpiCurrent: false,
multi: false,
simpleFadeDpiCurrent: false,
iconFadeDpiCurrent: false,
lastTabFadeDpiCurrent: false,
customize: false,
},
};
var simpleInfo = "Measure open/close of a new tab of about:blank"; var iconInfo = "Measure open/close of a new empty tab with favicon and long title"; var newtabInfo = "Measure open of the standard about:newtab"; var fadeInfo = "Open a new tab, then measure Fade-out/in"; var dpi1Info = " (@DPI 1.0)"; var dpi2Info = " (@DPI 2.0)"; var dpiCurrentInfo = " (@DPI unchanged)";
var testsInfo = {
simple: simpleInfo + dpi1Info,
iconDpi1: iconInfo + dpi1Info,
iconDpi2: iconInfo + dpi2Info,
iconFadeDpi2: fadeInfo + dpi2Info,
newtabNoPreload: newtabInfo + " (without preload)",
newtabYesPreload: newtabInfo + " (with preload)",
simple3open3closeDpiCurrent: "Measure 3 tab opens and 3 tab closes" + dpiCurrentInfo,
multi: "Open 6 tabs, then measures open/close of the 7th tab (@DPI 1.0 and 2.0)",
simpleFadeDpiCurrent: fadeInfo + dpiCurrentInfo,
iconFadeDpiCurrent: fadeInfo + dpiCurrentInfo,
lastTabFadeDpiCurrent: "Focus the last tab, then measure Fade-out/in (requires to manually add a tab before testing)",
customize: "Measure (Australis) Customize-mode enter/exit",
};
function deselectAll() {
for (var test in defaultConfig.subtests) {
$("subtest-" + test).checked = false;
}
}
function updateConfig() {
config = {subtests: []};
for (var test in defaultConfig.subtests) {
if ($("subtest-" + test).checked) {
config.subtests.push(test);
}
}
// E.g. returns "world" for key "hello", "2014" for key "year", and "" for key "dummy":
// http://localhost/x.html#hello=world&x=12&year=2014
function getUriHashValue(key) { var k = String(key) + "="; var uriVars = unescape(document.location.hash).substr(1).split("&");
for (var i in uriVars) {
if (uriVars[i].indexOf(k) == 0)
return uriVars[i].substr(k.length);
}
return "";
}
// URL e.g. chrome://tart/content/tart.html#auto&tests=["simple","iconFadeDpiCurrent"]
// Note - there's no error checking for arguments parsing errors.
// Any errors will express as either javascript errors or not reading the args correctly.
// This is not an "official" part of the UI, and when used in talos, will fail early
// enough to not cause "weird" issues too late.
function updateOptionsFromUrl() { var uriTests = getUriHashValue("tests"); var tests = uriTests ? JSON.parse(uriTests) : [];
if (tests.length) {
for (var d in defaultConfig.subtests) {
$("subtest-" + d).checked = false;
for (var t in tests) {
if (tests[t] == d) {
$("subtest-" + d).checked = true;
}
}
}
}
var cp = getUriHashValue("controlProfiler");
if (cp.length)
$("controlProfiler").checked = (cp == "true");
}
function init() {
updateOptionsFromUrl();
if (document.location.hash.indexOf("#auto") == 0) {
triggerStart();
}
}
addEventListener("load", init);
</script>
</head>
<bodystyle="font-family:sans-serif;">
<h4>TART - Tab Animation Regression Tests</h4>
<div id="hide-during-run">
Visit <a href="https://wiki.mozilla.org/Performance_sheriffing/Talos/Tests#TART">talos/TART</a> for detailed info.<br/>
<ul>
<li><b>If you just opened the browser</b> - give Firefox few seconds to settle down before testing.</li>
<li><button onclick="setASAP()">Set ASAP mode</button> <button onclick="unsetASAP()">Restore default</button> (requires restart to take effect). TART runs best (and in talos) with vsync disabled - to measure maximum throughput (ASAP mode). This means the preferences layout.frame_rate = 0 and docshell.event_starvation_delay_hint = 1</li>
<li>In talos, TART runs with a single tab. If you wish to test a specific animation with several tabs open, you can do so as well by manually opening few tabs before starting the test.</li>
</ul>
Utilities:
<a href="blank.icon.html">blank with icon</a>
<a href="about:config?filter=/newtab|_rate|devP|offmain|docshell.event_starvation_delay_hint|rce-en/">about:config (already filtered with relevant prefs)</a>
<br/><br/>
<b>Configure TART</b> (CTRL-F5 to reset to talos defaults) <button type="button" onclick="deselectAll()">Deselect all tests</button><br/>
<script>
for (var test in defaultConfig.subtests) {
// eslint-disable-next-line no-unsanitized/method
document.write(' + (defaultConfig.subtests[test] ? "" : "un") + "checked>"
+ test + ""
+ ' ' + testsInfo[test] + ""
+ " ");
}
$("subtest-simple3open3closeDpiCurrent").checked = false; // Disabled by default for talos
</script>
<br/>
Repeat: <input id="repeat" type="text" size=2 value="1" onchange="updateConfig()"/> times<br/>
Delay before starting a measured animation: <input id="rest" type="text" size=4 value="500"/> ms<br/>
<input id="controlProfiler" type="checkbox" checked>Pause the profiler during animations which are <b>not</b> measured.</input><br/>
<input id="tickle" type="checkbox" checked>Accurate first recorded frame (tickle the Back button before measurements)</iinput><br/>
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.26Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.