forked from mirrors/gecko-dev
Differential Revision: https://phabricator.services.mozilla.com/D4552 --HG-- extra : source : 2cf17e4974823d09d0fdd1aef64e69e840b288a1 extra : intermediate-source : 4771e6948a78507aa95a56e5b324d87dc82e9009
305 lines
9.2 KiB
JavaScript
305 lines
9.2 KiB
JavaScript
"use strict";
|
|
|
|
const {TabStateFlusher} = ChromeUtils.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
|
|
|
|
// Keep this in sync with the order in Histograms.json for
|
|
// BUSY_TAB_ABANDONED
|
|
const CATEGORIES = [
|
|
"stop",
|
|
"back",
|
|
"forward",
|
|
"historyNavigation",
|
|
"reload",
|
|
"tabClosed",
|
|
"newURI",
|
|
];
|
|
|
|
const PAGE_2 = "data:text/html,<html>Page 2</html>";
|
|
|
|
/**
|
|
* This little framework helps to extract the unique things
|
|
* involved in testing each category of the BUSY_TAB_ABANDONED
|
|
* probe from all of the common things. The little framework
|
|
* in this test will take each item in PROBE_TEST, let it
|
|
* do some test preparation, then create a "busy" tab to be
|
|
* manipulated by the test. The "category" of the test will then
|
|
* be used to determine if the appropriate index in the
|
|
* histogram was bumped.
|
|
*
|
|
* Here's a more verbose breakdown of what each PROBE_TEST
|
|
* should supply:
|
|
*
|
|
* name (String):
|
|
* Human readable description of the test. This is dumped
|
|
* out via info().
|
|
*
|
|
* category (String):
|
|
* The string representation of the index that will get
|
|
* incremented in the BUSY_TAB_ABANDONED probe. This should
|
|
* be a value inside CATEGORIES.
|
|
*
|
|
* prepare (function*)
|
|
* A function that can yield Promises. This will be run once
|
|
* we have a brand new browser to deal with, and should be used by
|
|
* the PROBE_TEST to do any history preparation before the browser
|
|
* is made to appear "busy" and is tested.
|
|
*
|
|
* @param browser (<xul:browser>)
|
|
* The newly created browser that the test will use.
|
|
*
|
|
* doAction (function*)
|
|
* A function that can yield Promises. This will be run once
|
|
* the browser appears busy, and should cause the user action
|
|
* that will change the BUSY_TAB_ABANDONED probe.
|
|
*
|
|
* @param browser (<xul:browser>)
|
|
* The busy browser to perform the action on.
|
|
*/
|
|
const PROBE_TESTS = [
|
|
|
|
// Test stopping the tab
|
|
{
|
|
name: "Stopping the browser",
|
|
|
|
category: "stop",
|
|
|
|
prepare(browser) {},
|
|
|
|
doAction(browser) {
|
|
document.getElementById("Browser:Stop").doCommand();
|
|
},
|
|
},
|
|
|
|
// Test going back to a previous page
|
|
{
|
|
name: "Going back to a previous page",
|
|
|
|
category: "back",
|
|
|
|
async prepare(browser) {
|
|
BrowserTestUtils.loadURI(browser, PAGE_2);
|
|
await BrowserTestUtils.browserLoaded(browser);
|
|
},
|
|
|
|
async doAction(browser) {
|
|
let pageShow =
|
|
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
|
document.getElementById("Browser:Back").doCommand();
|
|
await pageShow;
|
|
},
|
|
},
|
|
|
|
// Test going forward to a previous page
|
|
{
|
|
name: "Going forward to the next page",
|
|
|
|
category: "forward",
|
|
|
|
async prepare(browser) {
|
|
BrowserTestUtils.loadURI(browser, PAGE_2);
|
|
await BrowserTestUtils.browserLoaded(browser);
|
|
let pageShow =
|
|
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
|
browser.goBack();
|
|
await pageShow;
|
|
},
|
|
|
|
async doAction(browser) {
|
|
let pageShow =
|
|
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
|
document.getElementById("Browser:Forward").doCommand();
|
|
await pageShow;
|
|
},
|
|
},
|
|
|
|
// Test going backwards more than one page back via gotoIndex
|
|
{
|
|
name: "Going backward to a previous page via gotoIndex",
|
|
|
|
category: "historyNavigation",
|
|
|
|
async prepare(browser) {
|
|
BrowserTestUtils.loadURI(browser, PAGE_2);
|
|
await BrowserTestUtils.browserLoaded(browser);
|
|
BrowserTestUtils.loadURI(browser, "http://example.com");
|
|
await BrowserTestUtils.browserLoaded(browser);
|
|
await TabStateFlusher.flush(browser);
|
|
},
|
|
|
|
async doAction(browser) {
|
|
let pageShow =
|
|
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
|
synthesizeHistoryNavigationToIndex(0);
|
|
await pageShow;
|
|
},
|
|
},
|
|
|
|
// Test going forwards more than one page back via gotoIndex
|
|
{
|
|
name: "Going forward to a previous page via gotoIndex",
|
|
|
|
category: "historyNavigation",
|
|
|
|
async prepare(browser) {
|
|
BrowserTestUtils.loadURI(browser, PAGE_2);
|
|
await BrowserTestUtils.browserLoaded(browser);
|
|
BrowserTestUtils.loadURI(browser, "http://example.com");
|
|
await BrowserTestUtils.browserLoaded(browser);
|
|
let pageShow =
|
|
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
|
browser.gotoIndex(0);
|
|
await pageShow;
|
|
await TabStateFlusher.flush(browser);
|
|
},
|
|
|
|
async doAction(browser) {
|
|
let pageShow =
|
|
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
|
synthesizeHistoryNavigationToIndex(2);
|
|
await pageShow;
|
|
},
|
|
},
|
|
|
|
// Test reloading the tab
|
|
{
|
|
name: "Reloading the browser",
|
|
|
|
category: "reload",
|
|
|
|
prepare(browser) {},
|
|
|
|
async doAction(browser) {
|
|
document.getElementById("Browser:Reload").doCommand();
|
|
await BrowserTestUtils.browserLoaded(browser);
|
|
},
|
|
},
|
|
|
|
// Testing closing the tab is done in its own test later on
|
|
// in this file.
|
|
|
|
// Test browsing to a new URL
|
|
{
|
|
name: "Browsing to a new URL",
|
|
|
|
category: "newURI",
|
|
|
|
prepare(browser) {},
|
|
|
|
async doAction(browser) {
|
|
openTrustedLinkIn(PAGE_2, "current");
|
|
await BrowserTestUtils.browserLoaded(browser);
|
|
},
|
|
},
|
|
];
|
|
|
|
/**
|
|
* Takes a Telemetry histogram snapshot and makes sure
|
|
* that the index for that value (as defined by CATEGORIES)
|
|
* has a count of 1, and that it's the only value that
|
|
* has been incremented.
|
|
*
|
|
* @param snapshot (Object)
|
|
* The Telemetry histogram snapshot to examine.
|
|
* @param category (String)
|
|
* The category in CATEGORIES whose index we expect to have
|
|
* been set to 1.
|
|
*/
|
|
function assertOnlyOneTypeSet(snapshot, category) {
|
|
let categoryIndex = CATEGORIES.indexOf(category);
|
|
Assert.equal(snapshot.counts[categoryIndex], 1,
|
|
`Should have seen the ${category} count increment.`);
|
|
// Use Array.prototype.reduce to sum up all of the
|
|
// snapshot.count entries
|
|
Assert.equal(snapshot.counts.reduce((a, b) => a + b), 1,
|
|
"Should only be 1 collected value.");
|
|
}
|
|
|
|
/**
|
|
* A helper function for simulating clicking on the history
|
|
* navigation popup menu that you get if you click and hold
|
|
* on the back or forward buttons when you have some browsing
|
|
* history.
|
|
*
|
|
* @param index (int)
|
|
* The index for the menuitem we want to simulate
|
|
* clicking on.
|
|
*/
|
|
function synthesizeHistoryNavigationToIndex(index) {
|
|
let popup = document.getElementById("backForwardMenu");
|
|
// I don't want to deal with popup listening - that's
|
|
// notoriously flake-y in automated tests. I'll just
|
|
// directly call the function that populates the menu.
|
|
FillHistoryMenu(popup);
|
|
Assert.ok(popup.childElementCount > 0,
|
|
"Should have some items in the back/forward menu");
|
|
let menuitem = popup.querySelector(`menuitem[index="${index}"]`);
|
|
Assert.ok(menuitem, `Should find a menuitem with index ${index}`);
|
|
// Now pretend we clicked on the right item.
|
|
let cmdEvent = new CustomEvent("command", {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
});
|
|
menuitem.dispatchEvent(cmdEvent);
|
|
}
|
|
|
|
/**
|
|
* Goes through each of the categories for the BUSY_TAB_ABANDONED
|
|
* probe, and tests that they're properly changed.
|
|
*/
|
|
add_task(async function test_probes() {
|
|
let oldCanRecord = Services.telemetry.canRecordExtended;
|
|
Services.telemetry.canRecordExtended = true;
|
|
|
|
registerCleanupFunction(() => {
|
|
Services.telemetry.canRecordExtended = oldCanRecord;
|
|
});
|
|
|
|
let histogram = Services.telemetry
|
|
.getHistogramById("BUSY_TAB_ABANDONED");
|
|
|
|
// If you want to add new tests for probes that don't involve
|
|
// the tab or window hosting the tab closing, see the documentation
|
|
// above PROBE_TESTS for how to hook into this little framework.
|
|
for (let probeTest of PROBE_TESTS) {
|
|
await BrowserTestUtils.withNewTab({
|
|
gBrowser,
|
|
url: "http://example.com",
|
|
}, async function(browser) {
|
|
let tab = gBrowser.getTabForBrowser(browser);
|
|
info(`Test: "${probeTest.name}"`);
|
|
|
|
await probeTest.prepare(browser);
|
|
// Instead of trying to fiddle with network state or
|
|
// anything, we'll just set this attribute to fool our
|
|
// telemetry probes into thinking the browser is in the
|
|
// middle of loading some resources.
|
|
tab.setAttribute("busy", true);
|
|
|
|
histogram.clear();
|
|
await probeTest.doAction(browser);
|
|
let snapshot = histogram.snapshot();
|
|
assertOnlyOneTypeSet(snapshot, probeTest.category);
|
|
});
|
|
}
|
|
|
|
// The above tests used BrowserTestUtils.withNewTab, which is
|
|
// fine for almost all categories for this probe, except for
|
|
// "tabClosed", since withNewTab closes the tab automatically
|
|
// before resolving, which doesn't work well for a tabClosed
|
|
// test in the above framework. So the tabClosed tests are
|
|
// done separately below.
|
|
|
|
histogram.clear();
|
|
// Now test that we can close a busy tab and get the tabClosed
|
|
// measurement bumped.
|
|
let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
|
|
// As above, instead of trying to fiddle with network state
|
|
// or anything, we'll just set this attribute to fool our
|
|
// telemetry probes into thinking the browser is in the
|
|
// middle of loading some resources.
|
|
newTab.setAttribute("busy", true);
|
|
|
|
BrowserTestUtils.removeTab(newTab);
|
|
let snapshot = histogram.snapshot();
|
|
assertOnlyOneTypeSet(snapshot, "tabClosed");
|
|
});
|