Remove browser tests - Part 1: The Tests (except for experiments)

This commit is contained in:
NTD 2018-02-03 06:00:38 -05:00 • committed by Roy Tam
commit 261374f310
1697 changed files with 0 additions and 144364 deletions

View file

@ -1,7 +0,0 @@
"use strict";
module.exports = {
"extends": [
"../../../../../testing/mochitest/browser.eslintrc.js"
]
};

View file

@ -1,15 +0,0 @@
[DEFAULT]
support-files = head.js
[browser_basic_functionality.js]
[browser_first_download_panel.js]
skip-if = os == "linux" # Bug 949434
[browser_overflow_anchor.js]
skip-if = os == "linux" # Bug 952422
[browser_confirm_unblock_download.js]
[browser_iframe_gone_mid_download.js]
[browser_indicatorDrop.js]
[browser_libraryDrop.js]
[browser_downloads_panel_block.js]
[browser_downloads_panel_footer.js]
[browser_downloads_panel_height.js]

View file

@ -1,56 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
registerCleanupFunction(function*() {
yield task_resetState();
});
/**
* Make sure the downloads panel can display items in the right order and
* contains the expected data.
*/
add_task(function* test_basic_functionality() {
// Display one of each download state.
const DownloadData = [
{ state: nsIDM.DOWNLOAD_NOTSTARTED },
{ state: nsIDM.DOWNLOAD_PAUSED },
{ state: nsIDM.DOWNLOAD_FINISHED },
{ state: nsIDM.DOWNLOAD_FAILED },
{ state: nsIDM.DOWNLOAD_CANCELED },
];
// Wait for focus first
yield promiseFocus();
// Ensure that state is reset in case previous tests didn't finish.
yield task_resetState();
// For testing purposes, show all the download items at once.
var originalCountLimit = DownloadsView.kItemCountLimit;
DownloadsView.kItemCountLimit = DownloadData.length;
registerCleanupFunction(function () {
DownloadsView.kItemCountLimit = originalCountLimit;
});
// Populate the downloads database with the data required by this test.
yield task_addDownloads(DownloadData);
// Open the user interface and wait for data to be fully loaded.
yield task_openPanel();
// Test item data and count. This also tests the ordering of the display.
let richlistbox = document.getElementById("downloadsListBox");
/* disabled for failing intermittently (bug 767828)
is(richlistbox.children.length, DownloadData.length,
"There is the correct number of richlistitems");
*/
let itemCount = richlistbox.children.length;
for (let i = 0; i < itemCount; i++) {
let element = richlistbox.children[itemCount - i - 1];
let download = DownloadsView.itemForElement(element).download;
is(DownloadsCommon.stateOfDownload(download), DownloadData[i].state,
"Download states match up");
}
});

View file

@ -1,92 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests the dialog which allows the user to unblock a downloaded file.
registerCleanupFunction(() => {});
function* assertDialogResult({ args, buttonToClick, expectedResult }) {
promiseAlertDialogOpen(buttonToClick);
is(yield DownloadsCommon.confirmUnblockDownload(args), expectedResult);
}
/**
* Tests the "unblock" dialog, for each of the possible verdicts.
*/
add_task(function* test_unblock_dialog_unblock() {
for (let verdict of [Downloads.Error.BLOCK_VERDICT_MALWARE,
Downloads.Error.BLOCK_VERDICT_POTENTIALLY_UNWANTED,
Downloads.Error.BLOCK_VERDICT_UNCOMMON]) {
let args = { verdict, window, dialogType: "unblock" };
// Test both buttons.
yield assertDialogResult({
args,
buttonToClick: "accept",
expectedResult: "unblock",
});
yield assertDialogResult({
args,
buttonToClick: "cancel",
expectedResult: "cancel",
});
}
});
/**
* Tests the "chooseUnblock" dialog for potentially unwanted downloads.
*/
add_task(function* test_chooseUnblock_dialog() {
let args = {
verdict: Downloads.Error.BLOCK_VERDICT_POTENTIALLY_UNWANTED,
window,
dialogType: "chooseUnblock",
};
// Test each of the three buttons.
yield assertDialogResult({
args,
buttonToClick: "accept",
expectedResult: "unblock",
});
yield assertDialogResult({
args,
buttonToClick: "cancel",
expectedResult: "cancel",
});
yield assertDialogResult({
args,
buttonToClick: "extra1",
expectedResult: "confirmBlock",
});
});
/**
* Tests the "chooseOpen" dialog for uncommon downloads.
*/
add_task(function* test_chooseOpen_dialog() {
let args = {
verdict: Downloads.Error.BLOCK_VERDICT_UNCOMMON,
window,
dialogType: "chooseOpen",
};
// Test each of the three buttons.
yield assertDialogResult({
args,
buttonToClick: "accept",
expectedResult: "open",
});
yield assertDialogResult({
args,
buttonToClick: "cancel",
expectedResult: "cancel",
});
yield assertDialogResult({
args,
buttonToClick: "extra1",
expectedResult: "confirmBlock",
});
});

View file

@ -1,183 +0,0 @@
"use strict";
add_task(function* mainTest() {
yield task_resetState();
let verdicts = [
Downloads.Error.BLOCK_VERDICT_UNCOMMON,
Downloads.Error.BLOCK_VERDICT_MALWARE,
Downloads.Error.BLOCK_VERDICT_POTENTIALLY_UNWANTED,
];
yield task_addDownloads(verdicts.map(v => makeDownload(v)));
// Check that the richlistitem for each download is correct.
for (let i = 0; i < verdicts.length; i++) {
yield openPanel();
// The current item is always the first one in the listbox since each
// iteration of this loop removes the item at the end.
let item = DownloadsView.richListBox.firstChild;
// Open the panel and click the item to show the subview.
EventUtils.sendMouseEvent({ type: "click" }, item);
yield promiseSubviewShown(true);
// Items are listed in newest-to-oldest order, so e.g. the first item's
// verdict is the last element in the verdicts array.
Assert.ok(DownloadsBlockedSubview.subview.getAttribute("verdict"),
verdicts[verdicts.count - i - 1]);
// Click the sliver of the main view that's still showing on the left to go
// back to it.
EventUtils.synthesizeMouse(DownloadsPanel.panel, 10, 10, {}, window);
yield promiseSubviewShown(false);
// Show the subview again.
EventUtils.sendMouseEvent({ type: "click" }, item);
yield promiseSubviewShown(true);
// Click the Open button. The download should be unblocked and then opened,
// i.e., unblockAndOpenDownload() should be called on the item. The panel
// should also be closed as a result, so wait for that too.
let unblockOpenPromise = promiseUnblockAndOpenDownloadCalled(item);
let hidePromise = promisePanelHidden();
EventUtils.synthesizeMouse(DownloadsBlockedSubview.elements.openButton,
10, 10, {}, window);
yield unblockOpenPromise;
yield hidePromise;
window.focus();
yield SimpleTest.promiseFocus(window);
// Reopen the panel and show the subview again.
yield openPanel();
EventUtils.sendMouseEvent({ type: "click" }, item);
yield promiseSubviewShown(true);
// Click the Remove button. The panel should close and the item should be
// removed from it.
EventUtils.synthesizeMouse(DownloadsBlockedSubview.elements.deleteButton,
10, 10, {}, window);
yield promisePanelHidden();
yield openPanel();
Assert.ok(!item.parentNode);
DownloadsPanel.hidePanel();
yield promisePanelHidden();
}
yield task_resetState();
});
function* openPanel() {
// This function is insane but something intermittently causes the panel to be
// closed as soon as it's opening on Linux ASAN. Maybe it would also happen
// on other build machines if the test ran often enough. Not only is the
// panel closed, it's closed while it's opening, leaving DownloadsPanel._state
// such that when you try to open the panel again, it thinks it's already
// open, but it's not. The result is that the test times out.
//
// What this does is call DownloadsPanel.showPanel over and over again until
// the panel is really open. There are a few wrinkles:
//
// (1) When panel.state is "open", check four more times (for a total of five)
// before returning to make the panel stays open.
// (2) If the panel is not open, check the _state. It should be either
// kStateUninitialized or kStateHidden. If it's not, then the panel is in the
// process of opening -- or maybe it's stuck in that process -- so reset the
// _state to kStateHidden.
// (3) If the _state is not kStateUninitialized or kStateHidden, then it may
// actually be properly opening and not stuck at all. To avoid always closing
// the panel while it's properly opening, use an exponential backoff mechanism
// for retries.
//
// If all that fails, then the test will time out, but it would have timed out
// anyway.
yield promiseFocus();
yield new Promise(resolve => {
let verifyCount = 5;
let backoff = 0;
let iBackoff = 0;
let interval = setInterval(() => {
if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") {
if (verifyCount > 0) {
verifyCount--;
} else {
clearInterval(interval);
resolve();
}
} else {
if (iBackoff < backoff) {
// Keep backing off before trying again.
iBackoff++;
} else {
// Try (or retry) opening the panel.
verifyCount = 5;
backoff = Math.max(1, 2 * backoff);
iBackoff = 0;
if (DownloadsPanel._state != DownloadsPanel.kStateUninitialized) {
DownloadsPanel._state = DownloadsPanel.kStateHidden;
}
DownloadsPanel.showPanel();
}
}
}, 100);
});
}
function promisePanelHidden() {
return new Promise(resolve => {
if (!DownloadsPanel.panel || DownloadsPanel.panel.state == "closed") {
resolve();
return;
}
DownloadsPanel.panel.addEventListener("popuphidden", function onHidden() {
DownloadsPanel.panel.removeEventListener("popuphidden", onHidden);
setTimeout(resolve, 0);
});
});
}
function makeDownload(verdict) {
return {
state: nsIDM.DOWNLOAD_DIRTY,
hasBlockedData: true,
errorObj: {
result: Components.results.NS_ERROR_FAILURE,
message: "Download blocked.",
becauseBlocked: true,
becauseBlockedByReputationCheck: true,
reputationCheckVerdict: verdict,
},
};
}
function promiseSubviewShown(shown) {
// More terribleness, but I'm tired of fighting intermittent timeouts on try.
// Just poll for the subview and wait a second before resolving the promise.
return new Promise(resolve => {
let interval = setInterval(() => {
if (shown == DownloadsBlockedSubview.view.showingSubView &&
!DownloadsBlockedSubview.view._transitioning) {
clearInterval(interval);
setTimeout(resolve, 1000);
return;
}
}, 0);
});
}
function promiseUnblockAndOpenDownloadCalled(item) {
return new Promise(resolve => {
let realFn = item._shell.unblockAndOpenDownload;
item._shell.unblockAndOpenDownload = () => {
item._shell.unblockAndOpenDownload = realFn;
resolve();
// unblockAndOpenDownload returns a promise (that's resolved when the file
// is opened).
return Promise.resolve();
};
});
}

View file

@ -1,95 +0,0 @@
"use strict";
function *task_openDownloadsSubPanel() {
let downloadSubPanel = document.getElementById("downloadSubPanel");
let popupShownPromise = BrowserTestUtils.waitForEvent(downloadSubPanel, "popupshown");
let downloadsDropmarker = document.getElementById("downloadsFooterDropmarker");
EventUtils.synthesizeMouseAtCenter(downloadsDropmarker, {}, window);
yield popupShownPromise;
}
add_task(function* test_openDownloadsFolder() {
yield SpecialPowers.pushPrefEnv({"set": [["browser.download.showPanelDropmarker", true]]});
yield task_openPanel();
yield task_openDownloadsSubPanel();
yield new Promise(resolve => {
sinon.stub(DownloadsCommon, "showDirectory", file => {
resolve(Downloads.getPreferredDownloadsDirectory().then(downloadsPath => {
is(file.path, downloadsPath, "Check the download folder path.");
}));
});
let itemOpenDownloadsFolder =
document.getElementById("downloadsDropdownItemOpenDownloadsFolder");
EventUtils.synthesizeMouseAtCenter(itemOpenDownloadsFolder, {}, window);
});
yield task_resetState();
});
add_task(function* test_clearList() {
const kTestCases = [{
downloads: [
{ state: nsIDM.DOWNLOAD_NOTSTARTED },
{ state: nsIDM.DOWNLOAD_FINISHED },
{ state: nsIDM.DOWNLOAD_FAILED },
{ state: nsIDM.DOWNLOAD_CANCELED },
],
expectClearListShown: true,
expectedItemNumber: 0,
},{
downloads: [
{ state: nsIDM.DOWNLOAD_NOTSTARTED },
{ state: nsIDM.DOWNLOAD_FINISHED },
{ state: nsIDM.DOWNLOAD_FAILED },
{ state: nsIDM.DOWNLOAD_PAUSED },
{ state: nsIDM.DOWNLOAD_CANCELED },
],
expectClearListShown: true,
expectedItemNumber: 1,
},{
downloads: [
{ state: nsIDM.DOWNLOAD_PAUSED },
],
expectClearListShown: false,
expectedItemNumber: 1,
}];
for (let testCase of kTestCases) {
yield verify_clearList(testCase);
}
});
function *verify_clearList(testCase) {
let downloads = testCase.downloads;
yield task_addDownloads(downloads);
yield task_openPanel();
is(DownloadsView._downloads.length, downloads.length,
"Expect the number of download items");
yield task_openDownloadsSubPanel();
let itemClearList = document.getElementById("downloadsDropdownItemClearList");
let itemNumberPromise = BrowserTestUtils.waitForCondition(() => {
return DownloadsView._downloads.length === testCase.expectedItemNumber;
});
if (testCase.expectClearListShown) {
isnot("true", itemClearList.getAttribute("hidden"),
"Should show Clear Preview Panel button");
EventUtils.synthesizeMouseAtCenter(itemClearList, {}, window);
} else {
is("true", itemClearList.getAttribute("hidden"),
"Should not show Clear Preview Panel button");
}
yield itemNumberPromise;
is(DownloadsView._downloads.length, testCase.expectedItemNumber,
"Download items remained.");
yield task_resetState();
}

View file

@ -1,29 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* This test exists because we use a <panelmultiview> element and it handles
* some of the height changes for us. We need to verify that the height is
* updated correctly if downloads are removed while the panel is hidden.
*/
add_task(function* test_height_reduced_after_removal() {
yield task_addDownloads([
{ state: nsIDM.DOWNLOAD_FINISHED },
]);
yield task_openPanel();
let panel = document.getElementById("downloadsPanel");
let heightBeforeRemoval = panel.getBoundingClientRect().height;
// We want to close the panel before we remove the download from the list.
DownloadsPanel.hidePanel();
yield task_resetState();
yield task_openPanel();
let heightAfterRemoval = panel.getBoundingClientRect().height;
Assert.greater(heightBeforeRemoval, heightAfterRemoval);
yield task_resetState();
});

View file

@ -1,57 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure the downloads panel only opens automatically on the first
* download it notices. All subsequent downloads, even across sessions, should
* not open the panel automatically.
*/
add_task(function* test_first_download_panel() {
// Clear the download panel has shown preference first as this test is used to
// verify this preference's behaviour.
let oldPrefValue = Services.prefs.getBoolPref("browser.download.panel.shown");
Services.prefs.setBoolPref("browser.download.panel.shown", false);
registerCleanupFunction(function*() {
// Clean up when the test finishes.
yield task_resetState();
// Set the preference instead of clearing it afterwards to ensure the
// right value is used no matter what the default was. This ensures the
// panel doesn't appear and affect other tests.
Services.prefs.setBoolPref("browser.download.panel.shown", oldPrefValue);
});
// Ensure that state is reset in case previous tests didn't finish.
yield task_resetState();
// With this set to false, we should automatically open the panel the first
// time a download is started.
DownloadsCommon.getData(window).panelHasShownBefore = false;
let promise = promisePanelOpened();
DownloadsCommon.getData(window)._notifyDownloadEvent("start");
yield promise;
// If we got here, that means the panel opened.
DownloadsPanel.hidePanel();
ok(DownloadsCommon.getData(window).panelHasShownBefore,
"Should have recorded that the panel was opened on a download.")
// Next, make sure that if we start another download, we don't open the
// panel automatically.
let originalOnPopupShown = DownloadsPanel.onPopupShown;
DownloadsPanel.onPopupShown = function () {
originalOnPopupShown.apply(this, arguments);
ok(false, "Should not have opened the downloads panel.");
};
DownloadsCommon.getData(window)._notifyDownloadEvent("start");
// Wait 2 seconds to ensure that the panel does not open.
yield new Promise(resolve => setTimeout(resolve, 2000));
DownloadsPanel.onPopupShown = originalOnPopupShown;
});

View file

@ -1,62 +0,0 @@
const SAVE_PER_SITE_PREF = "browser.download.lastDir.savePerSite";
function test_deleted_iframe(perSitePref, windowOptions={}) {
return function*() {
Services.prefs.setBoolPref(SAVE_PER_SITE_PREF, perSitePref);
let {DownloadLastDir} = Cu.import("resource://gre/modules/DownloadLastDir.jsm", {});
let win = yield promiseOpenAndLoadWindow(windowOptions);
let tab = win.gBrowser.addTab();
yield promiseTabLoadEvent(tab, "about:mozilla");
let doc = tab.linkedBrowser.contentDocument;
let iframe = doc.createElement("iframe");
doc.body.appendChild(iframe);
ok(iframe.contentWindow, "iframe should have a window");
let gDownloadLastDir = new DownloadLastDir(iframe.contentWindow);
let cw = iframe.contentWindow;
let promiseIframeWindowGone = new Promise((resolve, reject) => {
Services.obs.addObserver(function obs(subject, topic) {
if (subject == cw) {
Services.obs.removeObserver(obs, topic);
resolve();
}
}, "dom-window-destroyed", false);
});
iframe.remove();
yield promiseIframeWindowGone;
cw = null;
ok(!iframe.contentWindow, "Managed to destroy iframe");
let someDir = "blah";
try {
someDir = yield new Promise((resolve, reject) => {
gDownloadLastDir.getFileAsync("http://www.mozilla.org/", function(dir) {
resolve(dir);
});
});
} catch (ex) {
ok(false, "Got an exception trying to get the directory where things should be saved.");
Cu.reportError(ex);
}
// NB: someDir can legitimately be null here when set, hence the 'blah' workaround:
isnot(someDir, "blah", "Should get a file even after the window was destroyed.");
try {
gDownloadLastDir.setFile("http://www.mozilla.org/", null);
} catch (ex) {
ok(false, "Got an exception trying to set the directory where things should be saved.");
Cu.reportError(ex);
}
yield promiseWindowClosed(win);
Services.prefs.clearUserPref(SAVE_PER_SITE_PREF);
};
}
add_task(test_deleted_iframe(false));
add_task(test_deleted_iframe(false));
add_task(test_deleted_iframe(true, {private: true}));
add_task(test_deleted_iframe(true, {private: true}));

View file

@ -1,67 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
XPCOMUtils.defineLazyModuleGetter(this, "HttpServer",
"resource://testing-common/httpd.js");
registerCleanupFunction(function*() {
yield task_resetState();
yield task_clearHistory();
});
add_task(function* test_indicatorDrop() {
let downloadButton = document.getElementById("downloads-button");
ok(downloadButton, "download button present");
let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader);
let EventUtils = {};
scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
function* task_drop(urls) {
let dragData = [[{type: "text/plain", data: urls.join("\n")}]];
let list = yield Downloads.getList(Downloads.ALL);
let added = new Set();
let succeeded = new Set();
yield new Promise(function(resolve) {
let view = {
onDownloadAdded: function(download) {
added.add(download.source.url);
},
onDownloadChanged: function(download) {
if (!added.has(download.source.url))
return;
if (!download.succeeded)
return;
succeeded.add(download.source.url);
if (succeeded.size == urls.length) {
list.removeView(view).then(resolve);
}
}
};
list.addView(view).then(function() {
EventUtils.synthesizeDrop(downloadButton, downloadButton, dragData, "link", window);
});
});
for (let url of urls) {
ok(added.has(url), url + " is added to download");
}
}
// Ensure that state is reset in case previous tests didn't finish.
yield task_resetState();
yield setDownloadDir();
startServer();
yield* task_drop([httpUrl("file1.txt")]);
yield* task_drop([httpUrl("file1.txt"),
httpUrl("file2.txt"),
httpUrl("file3.txt")]);
});

View file

@ -1,72 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
XPCOMUtils.defineLazyModuleGetter(this, "HttpServer",
"resource://testing-common/httpd.js");
registerCleanupFunction(function*() {
yield task_resetState();
yield task_clearHistory();
});
add_task(function* test_indicatorDrop() {
let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader);
let EventUtils = {};
scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
function task_drop(win, urls) {
let dragData = [[{type: "text/plain", data: urls.join("\n")}]];
let listBox = win.document.getElementById("downloadsRichListBox");
ok(listBox, "download list box present");
let list = yield Downloads.getList(Downloads.ALL);
let added = new Set();
let succeeded = new Set();
yield new Promise(function(resolve) {
let view = {
onDownloadAdded: function(download) {
added.add(download.source.url);
},
onDownloadChanged: function(download) {
if (!added.has(download.source.url))
return;
if (!download.succeeded)
return;
succeeded.add(download.source.url);
if (succeeded.size == urls.length) {
list.removeView(view).then(resolve);
}
}
};
list.addView(view).then(function() {
EventUtils.synthesizeDrop(listBox, listBox, dragData, "link", win);
});
});
for (let url of urls) {
ok(added.has(url), url + " is added to download");
}
}
// Ensure that state is reset in case previous tests didn't finish.
yield task_resetState();
setDownloadDir();
startServer();
let win = yield openLibrary("Downloads");
registerCleanupFunction(function() {
win.close();
});
yield* task_drop(win, [httpUrl("file1.txt")]);
yield* task_drop(win, [httpUrl("file1.txt"),
httpUrl("file2.txt"),
httpUrl("file3.txt")]);
});

View file

@ -1,115 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
registerCleanupFunction(function*() {
// Clean up when the test finishes.
yield task_resetState();
});
/**
* Make sure the downloads button and indicator overflows into the nav-bar
* chevron properly, and then when those buttons are clicked in the overflow
* panel that the downloads panel anchors to the chevron.
*/
add_task(function* test_overflow_anchor() {
// Ensure that state is reset in case previous tests didn't finish.
yield task_resetState();
// Record the original width of the window so we can put it back when
// this test finishes.
let oldWidth = window.outerWidth;
// The downloads button should not be overflowed to begin with.
let button = CustomizableUI.getWidget("downloads-button")
.forWindow(window);
ok(!button.overflowed, "Downloads button should not be overflowed.");
// Hack - we lock the size of the default flex-y items in the nav-bar,
// namely, the URL and search inputs. That way we can resize the
// window without worrying about them flexing.
const kFlexyItems = ["urlbar-container", "search-container"];
registerCleanupFunction(() => unlockWidth(kFlexyItems));
lockWidth(kFlexyItems);
// Resize the window to half of its original size. That should
// be enough to overflow the downloads button.
window.resizeTo(oldWidth / 2, window.outerHeight);
yield waitForOverflowed(button, true);
let promise = promisePanelOpened();
button.node.doCommand();
yield promise;
let panel = DownloadsPanel.panel;
let chevron = document.getElementById("nav-bar-overflow-button");
is(panel.anchorNode, chevron, "Panel should be anchored to the chevron.");
DownloadsPanel.hidePanel();
// Unlock the widths on the flex-y items.
unlockWidth(kFlexyItems);
// Put the window back to its original dimensions.
window.resizeTo(oldWidth, window.outerHeight);
// The downloads button should eventually be un-overflowed.
yield waitForOverflowed(button, false);
// Now try opening the panel again.
promise = promisePanelOpened();
button.node.doCommand();
yield promise;
is(panel.anchorNode.id, "downloads-indicator-anchor");
DownloadsPanel.hidePanel();
});
/**
* For some node IDs, finds the nodes and sets their min-width's to their
* current width, preventing them from flex-shrinking.
*
* @param aItemIDs an array of item IDs to set min-width on.
*/
function lockWidth(aItemIDs) {
for (let itemID of aItemIDs) {
let item = document.getElementById(itemID);
let curWidth = item.getBoundingClientRect().width + "px";
item.style.minWidth = curWidth;
}
}
/**
* Clears the min-width's set on a set of IDs by lockWidth.
*
* @param aItemIDs an array of ItemIDs to remove min-width on.
*/
function unlockWidth(aItemIDs) {
for (let itemID of aItemIDs) {
let item = document.getElementById(itemID);
item.style.minWidth = "";
}
}
/**
* Waits for a node to enter or exit the overflowed state.
*
* @param aItem the node to wait for.
* @param aIsOverflowed if we're waiting for the item to be overflowed.
*/
function waitForOverflowed(aItem, aIsOverflowed) {
let deferOverflow = Promise.defer();
if (aItem.overflowed == aIsOverflowed) {
return deferOverflow.resolve();
}
let observer = new MutationObserver(function(aMutations) {
if (aItem.overflowed == aIsOverflowed) {
observer.disconnect();
deferOverflow.resolve();
}
});
observer.observe(aItem.node, {attributes: true});
return deferOverflow.promise;
}

View file

@ -1,300 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Provides infrastructure for automated download components tests.
*/
////////////////////////////////////////////////////////////////////////////////
//// Globals
XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
"resource://gre/modules/Downloads.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
"resource:///modules/DownloadsCommon.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/Promise.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
const nsIDM = Ci.nsIDownloadManager;
var gTestTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]);
gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
// Load mocking/stubbing library, sinon
// docs: http://sinonjs.org/docs/
Services.scriptloader.loadSubScript("resource://testing-common/sinon-1.16.1.js");
registerCleanupFunction(function () {
gTestTargetFile.remove(false);
delete window.sinon;
delete window.setImmediate;
delete window.clearImmediate;
});
////////////////////////////////////////////////////////////////////////////////
//// Asynchronous support subroutines
function promiseOpenAndLoadWindow(aOptions)
{
return new Promise((resolve, reject) => {
let win = OpenBrowserWindow(aOptions);
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad);
resolve(win);
});
});
}
/**
* Waits for a load (or custom) event to finish in a given tab. If provided
* load an uri into the tab.
*
* @param tab
* The tab to load into.
* @param [optional] url
* The url to load, or the current url.
* @param [optional] event
* The load event type to wait for. Defaults to "load".
* @return {Promise} resolved when the event is handled.
* @resolves to the received event
* @rejects if a valid load event is not received within a meaningful interval
*/
function promiseTabLoadEvent(tab, url, eventType="load")
{
let deferred = Promise.defer();
info("Wait tab event: " + eventType);
function handle(event) {
if (event.originalTarget != tab.linkedBrowser.contentDocument ||
event.target.location.href == "about:blank" ||
(url && event.target.location.href != url)) {
info("Skipping spurious '" + eventType + "'' event" +
" for " + event.target.location.href);
return;
}
// Remove reference to tab from the cleanup function:
realCleanup = () => {};
tab.linkedBrowser.removeEventListener(eventType, handle, true);
info("Tab event received: " + eventType);
deferred.resolve(event);
}
// Juggle a bit to avoid leaks:
let realCleanup = () => tab.linkedBrowser.removeEventListener(eventType, handle, true);
registerCleanupFunction(() => realCleanup());
tab.linkedBrowser.addEventListener(eventType, handle, true, true);
if (url)
tab.linkedBrowser.loadURI(url);
return deferred.promise;
}
function promiseWindowClosed(win)
{
let promise = new Promise((resolve, reject) => {
Services.obs.addObserver(function obs(subject, topic) {
if (subject == win) {
Services.obs.removeObserver(obs, topic);
resolve();
}
}, "domwindowclosed", false);
});
win.close();
return promise;
}
function promiseFocus()
{
let deferred = Promise.defer();
waitForFocus(deferred.resolve);
return deferred.promise;
}
function promisePanelOpened()
{
let deferred = Promise.defer();
if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") {
return deferred.resolve();
}
// Hook to wait until the panel is shown.
let originalOnPopupShown = DownloadsPanel.onPopupShown;
DownloadsPanel.onPopupShown = function () {
DownloadsPanel.onPopupShown = originalOnPopupShown;
originalOnPopupShown.apply(this, arguments);
// Defer to the next tick of the event loop so that we don't continue
// processing during the DOM event handler itself.
setTimeout(deferred.resolve, 0);
};
return deferred.promise;
}
function* task_resetState()
{
// Remove all downloads.
let publicList = yield Downloads.getList(Downloads.PUBLIC);
let downloads = yield publicList.getAll();
for (let download of downloads) {
publicList.remove(download);
yield download.finalize(true);
}
DownloadsPanel.hidePanel();
yield promiseFocus();
}
function* task_addDownloads(aItems)
{
let startTimeMs = Date.now();
let publicList = yield Downloads.getList(Downloads.PUBLIC);
for (let item of aItems) {
let download = {
source: {
url: "http://www.example.com/test-download.txt",
},
target: {
path: gTestTargetFile.path,
},
succeeded: item.state == nsIDM.DOWNLOAD_FINISHED,
canceled: item.state == nsIDM.DOWNLOAD_CANCELED ||
item.state == nsIDM.DOWNLOAD_PAUSED,
error: item.state == nsIDM.DOWNLOAD_FAILED ? new Error("Failed.") : null,
hasPartialData: item.state == nsIDM.DOWNLOAD_PAUSED,
hasBlockedData: item.hasBlockedData || false,
startTime: new Date(startTimeMs++),
};
// `"errorObj" in download` must be false when there's no error.
if (item.errorObj) {
download.errorObj = item.errorObj;
}
yield publicList.add(yield Downloads.createDownload(download));
}
}
function* task_openPanel()
{
yield promiseFocus();
let promise = promisePanelOpened();
DownloadsPanel.showPanel();
yield promise;
}
function* setDownloadDir() {
let tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
tmpDir.append("testsavedir");
if (!tmpDir.exists()) {
tmpDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
registerCleanupFunction(function () {
try {
tmpDir.remove(true);
} catch (e) {
// On Windows debug build this may fail.
}
});
}
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [
["browser.download.folderList", 2],
["browser.download.dir", tmpDir, Ci.nsIFile],
]}, resolve);
});
}
let gHttpServer = null;
function startServer() {
gHttpServer = new HttpServer();
gHttpServer.start(-1);
registerCleanupFunction(function*() {
yield new Promise(function(resolve) {
gHttpServer.stop(resolve);
});
});
gHttpServer.registerPathHandler("/file1.txt", (request, response) => {
response.setStatusLine(null, 200, "OK");
response.write("file1");
response.processAsync();
response.finish();
});
gHttpServer.registerPathHandler("/file2.txt", (request, response) => {
response.setStatusLine(null, 200, "OK");
response.write("file2");
response.processAsync();
response.finish();
});
gHttpServer.registerPathHandler("/file3.txt", (request, response) => {
response.setStatusLine(null, 200, "OK");
response.write("file3");
response.processAsync();
response.finish();
});
}
function httpUrl(aFileName) {
return "http://localhost:" + gHttpServer.identity.primaryPort + "/" +
aFileName;
}
function task_clearHistory() {
return new Promise(function(resolve) {
Services.obs.addObserver(function observeCH(aSubject, aTopic, aData) {
Services.obs.removeObserver(observeCH, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
resolve();
}, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
PlacesUtils.history.clear();
});
}
function openLibrary(aLeftPaneRoot) {
let library = window.openDialog("chrome://browser/content/places/places.xul",
"", "chrome,toolbar=yes,dialog=no,resizable",
aLeftPaneRoot);
return new Promise(resolve => {
waitForFocus(resolve, library);
});
}
function promiseAlertDialogOpen(buttonAction) {
return new Promise(resolve => {
Services.ww.registerNotification(function onOpen(subj, topic, data) {
if (topic == "domwindowopened" && subj instanceof Ci.nsIDOMWindow) {
// The test listens for the "load" event which guarantees that the alert
// class has already been added (it is added when "DOMContentLoaded" is
// fired).
subj.addEventListener("load", function onLoad() {
subj.removeEventListener("load", onLoad);
if (subj.document.documentURI ==
"chrome://global/content/commonDialog.xul") {
Services.ww.unregisterNotification(onOpen);
let dialog = subj.document.getElementById("commonDialog");
ok(dialog.classList.contains("alert-dialog"),
"The dialog element should contain an alert class.");
let doc = subj.document.documentElement;
doc.getButton(buttonAction).click();
resolve();
}
});
}
});
});
}

View file

@ -1,7 +0,0 @@
"use strict";
module.exports = {
"extends": [
"../../../../../testing/xpcshell/xpcshell.eslintrc.js"
]
};

View file

@ -1,18 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Provides infrastructure for automated download components tests.
*/
////////////////////////////////////////////////////////////////////////////////
//// Globals
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cu = Components.utils;
var Cr = Components.results;
Cu.import("resource:///modules/DownloadsCommon.jsm");

View file

@ -1,37 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests for the functions located directly in the "DownloadsCommon" object.
*/
function testFormatTimeLeft(aSeconds, aExpectedValue, aExpectedUnitString)
{
let expected = "";
if (aExpectedValue) {
// Format the expected result based on the current language.
expected = DownloadsCommon.strings[aExpectedUnitString](aExpectedValue);
}
do_check_eq(DownloadsCommon.formatTimeLeft(aSeconds), expected);
}
function run_test()
{
testFormatTimeLeft( 0, "", "");
testFormatTimeLeft( 1, "1", "shortTimeLeftSeconds");
testFormatTimeLeft( 29, "29", "shortTimeLeftSeconds");
testFormatTimeLeft( 30, "30", "shortTimeLeftSeconds");
testFormatTimeLeft( 31, "1", "shortTimeLeftMinutes");
testFormatTimeLeft( 60, "1", "shortTimeLeftMinutes");
testFormatTimeLeft( 89, "1", "shortTimeLeftMinutes");
testFormatTimeLeft( 90, "2", "shortTimeLeftMinutes");
testFormatTimeLeft( 91, "2", "shortTimeLeftMinutes");
testFormatTimeLeft( 3600, "1", "shortTimeLeftHours");
testFormatTimeLeft( 86400, "24", "shortTimeLeftHours");
testFormatTimeLeft( 169200, "47", "shortTimeLeftHours");
testFormatTimeLeft( 172800, "2", "shortTimeLeftDays");
testFormatTimeLeft(8553600, "99", "shortTimeLeftDays");
testFormatTimeLeft(8640000, "99", "shortTimeLeftDays");
}

View file

@ -1,7 +0,0 @@
[DEFAULT]
head = head.js
tail =
firefox-appdir = browser
skip-if = toolkit == 'android'
[test_DownloadsCommon.js]