Backed out 10 changesets (bug 1625892) for android raptor failures. CLOSED TREE

Backed out changeset 02cb65a8e837 (bug 1625892)
Backed out changeset 95231e9159d0 (bug 1625892)
Backed out changeset 89a9f28cbf4c (bug 1625892)
Backed out changeset fe9e6463fdfc (bug 1625892)
Backed out changeset 36e8abbfb6c8 (bug 1625892)
Backed out changeset 59b42b7138e4 (bug 1625892)
Backed out changeset 40e988e1e60c (bug 1625892)
Backed out changeset 034c5165ee5f (bug 1625892)
Backed out changeset 03f735885911 (bug 1625892)
Backed out changeset 9025c0ed8a06 (bug 1625892)
This commit is contained in:
Brindusan Cristian 2020-04-04 04:02:28 +03:00
Родитель 1a3813f70b
Коммит af96555478
3 изменённых файлов: 201 добавлений и 271 удалений

Просмотреть файл

@ -4,35 +4,24 @@
// receives result from benchmark and relays onto our background runner
async function receiveMessage(event) {
function receiveMessage(event) {
raptorLog("raptor benchmark received message");
raptorLog(event.data);
// raptor benchmark message data [0] is raptor tag, [1] is benchmark
// name, and the rest is actual benchmark results that we want to fw
if (event.data[0] == "raptor-benchmark") {
await sendResult(event.data[1], event.data.slice(2));
sendResult(event.data[1], event.data.slice(2));
}
}
/**
* Send result back to background runner script
*/
async function sendResult(type, value) {
raptorLog(`sending result back to runner: ${type} ${value}`);
let response;
if (typeof browser !== "undefined") {
response = await browser.runtime.sendMessage({ type, value });
} else {
response = await new Promise(resolve => {
chrome.runtime.sendMessage({ type, value }, resolve);
});
}
if (response) {
raptorLog(`Response: ${response.text}`);
}
function sendResult(_type, _value) {
// send result back to background runner script
raptorLog(`sending result back to runner: ${_type} ${_value}`);
chrome.runtime.sendMessage({ type: _type, value: _value }, function(
response
) {
raptorLog(response.text);
});
}
function raptorLog(text, level = "info") {

Просмотреть файл

@ -51,21 +51,33 @@ var getLoadTime = false;
// performance.timing measurement used as 'starttime'
var startMeasure = "fetchStart";
async function raptorContentHandler() {
function raptorContentHandler() {
raptorLog("pageloadjs raptorContentHandler!");
// let the main raptor runner know that we (pageloadjs) is ready!
await sendPageloadReady();
sendPageloadReady();
// retrieve test settings from local ext storage
let settings;
if (typeof browser !== "undefined") {
({ settings } = await browser.storage.local.get("settings"));
// firefox, returns promise
browser.storage.local.get("settings").then(function(item) {
setup(item.settings);
});
} else {
({ settings } = await new Promise(resolve => {
chrome.storage.local.get("settings", resolve);
}));
// chrome, no promise so use callback
chrome.storage.local.get("settings", function(item) {
setup(item.settings);
});
}
setup(settings);
}
function sendPageloadReady() {
// send message to runnerjs indicating pageloadjs is ready to start getting measures
raptorLog("sending pageloadjs-ready message to runnerjs");
chrome.runtime.sendMessage({ type: "pageloadjs-ready" }, function(response) {
if (response !== undefined) {
raptorLog(`${response.text}`);
}
});
}
function setup(settings) {
@ -135,8 +147,8 @@ function measureHero() {
raptorLog(`found ${heroElementsFound.length} hero elements in the page`);
if (heroElementsFound) {
async function callbackHero(entries, observer) {
for (const entry in entries) {
function callbackHero(entries, observer) {
entries.forEach(entry => {
const heroFound = entry.target.getAttribute("elementtiming");
// mark the time now as when hero element received
perfData.mark(heroFound);
@ -150,11 +162,11 @@ function measureHero() {
);
const perfResult = perfData.getEntriesByName(resultType);
const _result = Math.round(perfResult[0].duration);
await sendResult(resultType, _result);
sendResult(resultType, _result);
perfData.clearMarks();
perfData.clearMeasures();
obs.disconnect();
}
});
}
// we want the element 100% visible on the viewport
const options = { root: null, rootMargin: "0px", threshold: [1] };
@ -174,7 +186,7 @@ function measureHero() {
}
}
async function measureFNBPaint() {
function measureFNBPaint() {
const x = window.performance.timing.timeToNonBlankPaint;
if (typeof x == "undefined") {
@ -188,7 +200,7 @@ async function measureFNBPaint() {
raptorLog("got fnbpaint");
gRetryCounter = 0;
const startTime = perfData.timing.fetchStart;
await sendResult("fnbpaint", x - startTime);
sendResult("fnbpaint", x - startTime);
} else {
gRetryCounter += 1;
if (gRetryCounter <= 10) {
@ -204,7 +216,7 @@ async function measureFNBPaint() {
}
}
async function measureDCF() {
function measureDCF() {
const x = window.performance.timing.timeToDOMContentFlushed;
if (typeof x == "undefined") {
@ -218,7 +230,7 @@ async function measureDCF() {
raptorLog(`got domContentFlushed: ${x}`);
gRetryCounter = 0;
const startTime = perfData.timing.fetchStart;
await sendResult("dcf", x - startTime);
sendResult("dcf", x - startTime);
} else {
gRetryCounter += 1;
if (gRetryCounter <= 10) {
@ -232,7 +244,7 @@ async function measureDCF() {
}
}
async function measureTTFI() {
function measureTTFI() {
const x = window.performance.timing.timeToFirstInteractive;
if (typeof x == "undefined") {
@ -246,7 +258,7 @@ async function measureTTFI() {
raptorLog(`got timeToFirstInteractive: ${x}`);
gRetryCounter = 0;
const startTime = perfData.timing.fetchStart;
await sendResult("ttfi", x - startTime);
sendResult("ttfi", x - startTime);
} else {
gRetryCounter += 1;
// NOTE: currently the gecko implementation doesn't look at network
@ -263,12 +275,12 @@ async function measureTTFI() {
} else {
// unable to get a value for TTFI - negative value will be filtered out later
raptorLog("TTFI was not available for this pageload");
await sendResult("ttfi", -1);
sendResult("ttfi", -1);
}
}
}
async function measureFCP() {
function measureFCP() {
// see https://developer.mozilla.org/en-US/docs/Web/API/PerformancePaintTiming
let result = window.performance.timing.timeToContentfulPaint;
@ -296,7 +308,7 @@ async function measureFCP() {
const startTime = perfData.timing.fetchStart;
result = result - startTime;
}
await sendResult("fcp", result);
sendResult("fcp", result);
perfData.clearMarks();
perfData.clearMeasures();
} else {
@ -314,7 +326,7 @@ async function measureFCP() {
}
}
async function measureLoadTime() {
function measureLoadTime() {
const x = window.performance.timing.loadEventStart;
if (typeof x == "undefined") {
@ -325,7 +337,7 @@ async function measureLoadTime() {
raptorLog(`got loadEventStart: ${x}`);
gRetryCounter = 0;
const startTime = perfData.timing.fetchStart;
await sendResult("loadtime", x - startTime);
sendResult("loadtime", x - startTime);
} else {
gRetryCounter += 1;
if (gRetryCounter <= 40 * (1000 / 200)) {
@ -341,44 +353,16 @@ async function measureLoadTime() {
}
}
/**
* Send message to runnerjs indicating pageloadjs is ready to start getting measures
*/
async function sendPageloadReady() {
raptorLog("sending pageloadjs-ready message to runnerjs");
let response;
if (typeof browser !== "undefined") {
response = await browser.runtime.sendMessage({ type: "pageloadjs-ready" });
} else {
response = await new Promise(resolve => {
chrome.runtime.sendMessage({ type: "pageloadjs-ready" }, resolve);
});
}
if (response) {
raptorLog(`Response: ${response.text}`);
}
}
/**
* Send result back to background runner script
*/
async function sendResult(type, value) {
raptorLog(`sending result back to runner: ${type} ${value}`);
let response;
if (typeof browser !== "undefined") {
response = await browser.runtime.sendMessage({ type, value });
} else {
response = await new Promise(resolve => {
chrome.runtime.sendMessage({ type, value }, resolve);
});
}
if (response) {
raptorLog(`Response: ${response.text}`);
}
function sendResult(_type, _value) {
// send result back to background runner script
raptorLog(`sending result back to runner: ${_type} ${_value}`);
chrome.runtime.sendMessage({ type: _type, value: _value }, function(
response
) {
if (response !== undefined) {
raptorLog(response.text);
}
});
}
function raptorLog(text, level = "info") {

Просмотреть файл

@ -29,6 +29,7 @@ var postStartupDelay;
// delay (ms) between pageload cycles
var pageCycleDelay = 1000;
var newTabDelay = 1000;
var newTabPerCycle = false;
// delay (ms) for foregrounding app
@ -48,6 +49,7 @@ var browserCycle = 0;
var pageCycles = 0;
var pageCycle = 0;
var testURL;
var testTabID = 0;
var scenarioTestTime = 60000;
var getHero = false;
var getFNBPaint = false;
@ -184,7 +186,6 @@ async function getTestSettings() {
// write options to storage that our content script needs to know
if (isGecko) {
await ext.storage.local.clear();
await ext.storage.local.set({ settings });
} else {
await new Promise(resolve => {
@ -196,10 +197,6 @@ async function getTestSettings() {
raptorLog("wrote settings to ext local storage");
}
async function sleep(delay) {
return new Promise(resolve => setTimeout(resolve, delay));
}
async function getBrowserInfo() {
if (isGecko) {
const info = await ext.runtime.getBrowserInfo();
@ -217,7 +214,7 @@ async function getBrowserInfo() {
raptorLog(`testing on ${results.browser}`);
}
async function startScenarioTimer() {
async function scenarioTimer() {
setTimeout(function() {
isScenarioPending = false;
results.measurements.scenario = [1];
@ -226,85 +223,29 @@ async function startScenarioTimer() {
await postToControlServer("status", `started scenario test timer`);
}
async function closeTab() {
// Don't close the last tab which would close the window or application
const tabs = await queryForTabs({ currentWindow: true });
if (tabs.length == 1) {
await postToControlServer("status", `Not closing last Tab: ${tabId}`);
return;
}
async function testTabCreated(tab) {
testTabID = tab.id;
await postToControlServer("status", `opened new empty tab: ${testTabID}`);
const tabId = await getCurrentTabId();
await postToControlServer("status", `closing Tab: ${tabId}`);
if (isGecko) {
await ext.tabs.remove(tabId);
} else {
await new Promise(resolve => {
ext.tabs.remove(tabId, resolve);
});
}
await postToControlServer("status", `closed tab: ${tabId}`);
// update raptor browser toolbar icon text, for a visual indicator when debugging
ext.browserAction.setTitle({ title: "Raptor RUNNING" });
}
async function getCurrentTabId() {
const tabs = await queryForTabs({ currentWindow: true, active: true });
await postToControlServer("status", "found active tab with id " + tabs[0].id);
return tabs[0].id;
async function testTabRemoved(tab) {
await postToControlServer("status", `Removed tab: ${testTabID}`);
testTabID = 0;
}
async function openTab() {
await postToControlServer("status", "openinig new tab");
async function testTabUpdated(tab) {
await postToControlServer("status", `test tab updated: ${testTabID}`);
let tab;
if (isGecko) {
tab = await ext.tabs.create({ url: "about:blank" });
} else {
tab = await new Promise(resolve => {
ext.tabs.create({ url: "about:blank" }, resolve);
});
// for benchmark or scenario type tests we can proceed directly to waitForResult;
// however for page-load tests we must first wait until we hear back from pageloaderjs
// that it has been successfully loaded in the test page and has been invoked; and
// only then start looking for measurements
if (testType != TEST_PAGE_LOAD) {
await collectResults();
}
await postToControlServer("status", `opened new empty tab: ${tab.id}`);
return tab.id;
}
async function queryForTabs(options = {}) {
let tabs;
if (isGecko) {
tabs = await ext.tabs.query(options);
} else {
tabs = await new Promise(resolve => {
ext.tabs.query(options, resolve);
});
}
return tabs;
}
/**
* Update the given tab by navigating to the test URL
*/
async function updateTab(url) {
const tabId = await getCurrentTabId();
await postToControlServer("status", `update tab ${tabId} for ${url}`);
// "null" = active tab
if (isGecko) {
await ext.tabs.update(tabId, { url });
} else {
await new Promise(resolve => {
ext.tabs.update(tabId, { url }, resolve);
});
}
await postToControlServer("status", `tab ${tabId} updated`);
}
async function collectResults() {
@ -313,47 +254,56 @@ async function collectResults() {
setTimeoutAlarm("raptor-page-timeout", pageTimeout);
// wait for pageload test result from content
await waitForResults();
await waitForResult();
// move on to next cycle (or test complete)
await nextCycle();
}
function checkForTestFinished() {
let finished = false;
async function waitForResult() {
let results = await new Promise(resolve => {
async function checkForResult() {
raptorLog("checking results...");
switch (testType) {
case TEST_BENCHMARK:
if (!isBenchmarkPending) {
resolve();
} else {
setTimeout(checkForResult, 250);
}
break;
switch (testType) {
case TEST_BENCHMARK:
finished = !isBenchmarkPending;
break;
case TEST_PAGE_LOAD:
if (
!isHeroPending &&
!isFNBPaintPending &&
!isFCPPending &&
!isDCFPending &&
!isTTFIPending &&
!isLoadTimePending
) {
finished = true;
case TEST_PAGE_LOAD:
if (
!isHeroPending &&
!isFNBPaintPending &&
!isFCPPending &&
!isDCFPending &&
!isTTFIPending &&
!isLoadTimePending
) {
raptorLog("no more results pending; resolving checkForResult");
resolve();
} else {
raptorLog("setting timeout to checkForResult again in 250ms");
setTimeout(checkForResult, 250);
}
break;
case TEST_SCENARIO:
if (!isScenarioPending) {
await cancelTimeoutAlarm("raptor-page-timeout");
await postToControlServer("status", `scenario test ended`);
resolve();
} else {
setTimeout(checkForResult, 5);
}
break;
}
break;
}
case TEST_SCENARIO:
finished = !isScenarioPending;
break;
}
return finished;
}
async function waitForResults() {
raptorLog("waiting for results...");
while (!checkForTestFinished()) {
raptorLog("results pending...");
await sleep(250);
}
checkForResult();
});
await cancelTimeoutAlarm("raptor-page-timeout");
@ -366,6 +316,8 @@ async function waitForResults() {
if (screenCapture) {
await getScreenCapture();
}
return results;
}
async function getScreenCapture() {
@ -437,7 +389,7 @@ async function nextCycle() {
);
// wait a bit to be sure the app is in foreground before starting
// new test, or finishing test
await sleep(foregroundDelay);
await new Promise(resolve => setTimeout(resolve, foregroundDelay));
}
if (pageCycle == 1) {
const text = `running ${pageCycles} pagecycles of ${testURL}`;
@ -454,65 +406,62 @@ async function nextCycle() {
`bringing app to background`
);
}
setTimeout(async () => {
await postToControlServer("status", `begin pagecycle ${pageCycle}`);
await sleep(pageCycleDelay);
switch (testType) {
case TEST_BENCHMARK:
isBenchmarkPending = true;
break;
await postToControlServer("status", `begin page cycle ${pageCycle}`);
case TEST_PAGE_LOAD:
if (getHero) {
isHeroPending = true;
pendingHeroes = Array.from(settings.measure.hero);
}
if (getFNBPaint) {
isFNBPaintPending = true;
}
if (getFCP) {
isFCPPending = true;
}
if (getDCF) {
isDCFPending = true;
}
if (getTTFI) {
isTTFIPending = true;
}
if (getLoadTime) {
isLoadTimePending = true;
}
break;
switch (testType) {
case TEST_BENCHMARK:
isBenchmarkPending = true;
break;
case TEST_SCENARIO:
isScenarioPending = true;
break;
}
case TEST_PAGE_LOAD:
if (getHero) {
isHeroPending = true;
pendingHeroes = Array.from(settings.measure.hero);
if (newTabPerCycle && testTabID != 0) {
// close previous test tab
ext.tabs.remove(testTabID);
await postToControlServer("status", `closing Tab: ${testTabID}`);
// open new tab
ext.tabs.create({ url: "about:blank" });
await postToControlServer("status", "Open new tab");
}
setTimeout(async () => {
await postToControlServer("status", `update tab: ${testTabID}`);
// update the test page - browse to our test URL
// "null" = active tab
ext.tabs.update(testTabID || null, { url: testURL }, testTabUpdated);
if (testType == TEST_SCENARIO) {
await scenarioTimer();
}
if (getFNBPaint) {
isFNBPaintPending = true;
}
if (getFCP) {
isFCPPending = true;
}
if (getDCF) {
isDCFPending = true;
}
if (getTTFI) {
isTTFIPending = true;
}
if (getLoadTime) {
isLoadTimePending = true;
}
break;
case TEST_SCENARIO:
isScenarioPending = true;
break;
}
if (newTabPerCycle) {
// close previous test tab and open a new one
await closeTab();
await openTab();
}
await updateTab(testURL);
if (testType == TEST_SCENARIO) {
await startScenarioTimer();
}
// For benchmark or scenario type tests we can proceed directly to
// waitForResult. However for page-load tests we must first wait until
// we hear back from pageloaderjs that it has been successfully loaded
// in the test page and has been invoked; and only then start looking
// for measurements.
if (testType != TEST_PAGE_LOAD) {
await collectResults();
}
await postToControlServer("status", `ended page cycle ${pageCycle}`);
}, newTabDelay);
}, pageCycleDelay);
} else {
await verifyResults();
}
@ -555,32 +504,32 @@ function setTimeoutAlarm(timeoutName, timeoutMS) {
}
async function cancelTimeoutAlarm(timeoutName) {
let cleared = false;
if (isGecko) {
cleared = await ext.alarms.clear(timeoutName);
const alarm = await ext.alarms.clear(timeoutName);
if (alarm) {
raptorLog(`cancelled raptor alarm ${timeoutName}`);
} else {
raptorLog(`failed to clear raptor alarm ${timeoutName}`, "error");
}
} else {
cleared = await new Promise(resolve => {
chrome.alarms.clear(timeoutName, resolve);
chrome.alarms.clear(timeoutName, function(wasCleared) {
if (wasCleared) {
raptorLog(`cancelled raptor alarm ${timeoutName}`);
} else {
raptorLog(`failed to clear raptor alarm ${timeoutName}`, "error");
}
});
}
if (cleared) {
raptorLog(`cancelled raptor alarm ${timeoutName}`);
} else {
raptorLog(`failed to clear raptor alarm ${timeoutName}`, "error");
}
}
function resultListener(request, sender, sendResponse) {
async function resultListener(request, sender, sendResponse) {
raptorLog(`received message from ${sender.tab.url}`);
// check if this is a message from pageloaderjs indicating it is ready to start
if (request.type == "pageloadjs-ready") {
raptorLog("received pageloadjs-ready!");
sendResponse({ text: "pageloadjs-ready-response" });
collectResults();
await collectResults();
return;
}
@ -691,16 +640,18 @@ async function postToControlServer(msgType, msgData = "") {
async function cleanUp() {
// close tab unless raptor debug-mode is enabled
if (debugMode == 1) {
raptorLog("debug-mode enabled, leaving tab open");
if (debugMode != 1) {
ext.tabs.remove(testTabID);
raptorLog(`closed tab ${testTabID}`);
} else {
await closeTab();
raptorLog("debug-mode enabled, leaving tab open");
}
if (testType == TEST_PAGE_LOAD) {
// remove listeners
ext.alarms.onAlarm.removeListener(timeoutAlarmListener);
ext.runtime.onMessage.removeListener(resultListener);
ext.tabs.onCreated.removeListener(testTabCreated);
}
raptorLog(`${testType} test finished`);
@ -731,20 +682,26 @@ async function raptorRunner() {
ext.alarms.onAlarm.addListener(timeoutAlarmListener);
ext.runtime.onMessage.addListener(resultListener);
ext.tabs.onCreated.addListener(testTabCreated);
ext.tabs.onRemoved.addListener(testTabRemoved);
// create new empty tab, which starts the test; we want to
// wait some time for the browser to settle before beginning
const text = `* pausing ${postStartupDelay /
1000} seconds to let browser settle... *`;
await postToControlServer("status", text);
await sleep(postStartupDelay);
// GeckoView doesn't support tabs
if (!isGeckoView) {
await openTab();
// GeckoView doesn't support tabs; set existing tab as blank first
if (isGeckoView) {
setTimeout(function() {
nextCycle();
}, postStartupDelay);
} else {
setTimeout(function() {
ext.tabs.create({ url: "about:blank" });
nextCycle();
}, postStartupDelay);
}
await nextCycle();
}
function raptorLog(text, level = "info") {