From 156277940a95dcadf5a8518c872734bbab21edef Mon Sep 17 00:00:00 2001 From: Dorel Luca Date: Wed, 6 Mar 2019 22:37:22 +0200 Subject: [PATCH] Backed out 2 changesets (bug 1525395) for Devtools failures in devtools/client/scratchpad/test/browser_scratchpad_recent_files.js Backed out changeset 19d2e4ea75cf (bug 1525395) Backed out changeset af3e74a36fec (bug 1525395) --HG-- extra : rebase_source : db36751a03f54c9e1d3acd6f8d3a49f3f06faed8 --- devtools/client/scratchpad/scratchpad.js | 69 +++--- .../test/browser_scratchpad_recent_files.js | 222 ++++++++++++------ 2 files changed, 180 insertions(+), 111 deletions(-) diff --git a/devtools/client/scratchpad/scratchpad.js b/devtools/client/scratchpad/scratchpad.js index fd4bc46957db..40e05a8454be 100644 --- a/devtools/client/scratchpad/scratchpad.js +++ b/devtools/client/scratchpad/scratchpad.js @@ -1087,30 +1087,18 @@ var Scratchpad = { /** * Open a file to edit in the Scratchpad. * - * * @param integer aIndex * Optional integer: clicked menuitem in the 'Open Recent'-menu. - * If omitted, prompt the user to pick a file to open. - * - * @return Promise - * A Promise that resolves to undefined when the file is opened. The - * promise is rejected instead if the user cancels the file picker - * dialog, or if the file can't be opened. */ - openFile(aIndex) { - return new Promise((resolve, reject) => { - const promptCallback = aFile => { - this.promptSave((aCloseFile, aSaved, aStatus) => { - let shouldOpen = aCloseFile; - if (aSaved && !Components.isSuccessCode(aStatus)) { - shouldOpen = false; - } - - if (!shouldOpen) { - reject(new Error("cancelled")); - return; - } + openFile: function SP_openFile(aIndex) { + const promptCallback = aFile => { + this.promptSave((aCloseFile, aSaved, aStatus) => { + let shouldOpen = aCloseFile; + if (aSaved && !Components.isSuccessCode(aStatus)) { + shouldOpen = false; + } + if (shouldOpen) { let file; if (aFile) { file = aFile; @@ -1130,32 +1118,29 @@ var Scratchpad = { null); this.clearFiles(aIndex, 1); - reject(new Error("file-no-longer-exists")); return; } - this.importFromFile(file, false).then(_ => resolve(), reject); - }); - }; + this.importFromFile(file, false); + } + }); + }; - if (aIndex > -1) { - promptCallback(); - } else { - const fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); - fp.init(window, this.strings.GetStringFromName("openFile.title"), - Ci.nsIFilePicker.modeOpen); - fp.defaultString = ""; - fp.appendFilter("JavaScript Files", "*.js; *.jsm; *.json"); - fp.appendFilter("All Files", "*.*"); - fp.open(aResult => { - if (aResult == Ci.nsIFilePicker.returnCancel) { - reject(new Error("cancelled")); - } else { - promptCallback(fp.file); - } - }); - } - }); + if (aIndex > -1) { + promptCallback(); + } else { + const fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); + fp.init(window, this.strings.GetStringFromName("openFile.title"), + Ci.nsIFilePicker.modeOpen); + fp.defaultString = ""; + fp.appendFilter("JavaScript Files", "*.js; *.jsm; *.json"); + fp.appendFilter("All Files", "*.*"); + fp.open(aResult => { + if (aResult != Ci.nsIFilePicker.returnCancel) { + promptCallback(fp.file); + } + }); + } }, /** diff --git a/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js b/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js index 76e79a96f47e..c9685d48c3df 100644 --- a/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js +++ b/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js @@ -32,20 +32,17 @@ var gFileContent02 = "hello.world.02('bug651942');"; var gFileContent03 = "hello.world.03('bug651942');"; var gFileContent04 = "hello.world.04('bug651942');"; -// Return a promise that will be resolved after one event loop turn. -function snooze() { - return new Promise(resolve => setTimeout(resolve, 0)); -} - -async function testAddedToRecent() { +async function startTest() { gScratchpad = gScratchpadWindow.Scratchpad; gFile01 = await createAndLoadTemporaryFile(gFileName01, gFileContent01); gFile02 = await createAndLoadTemporaryFile(gFileName02, gFileContent02); gFile03 = await createAndLoadTemporaryFile(gFileName03, gFileContent03); +} - // Test to see if the files we just created have been added to the list of - // recent files. +// Test to see if the three files we created in the 'startTest()'-method have +// been added to the list of recent files. +async function testAddedToRecent() { lists.recentFiles01 = gScratchpad.getRecentFiles(); is(lists.recentFiles01.length, 3, @@ -53,9 +50,11 @@ async function testAddedToRecent() { // Create a 4th file, this should clear the oldest file. gFile04 = await createAndLoadTemporaryFile(gFileName04, gFileContent04); +} - // Test to see if the oldest recent file was removed, - // and that the other files were reordered successfully. +// We have opened a 4th file. Test to see if the oldest recent file was removed, +// and that the other files were reordered successfully. +function testOverwriteRecent() { lists.recentFiles02 = gScratchpad.getRecentFiles(); is(lists.recentFiles02[0], lists.recentFiles01[1], @@ -66,10 +65,12 @@ async function testAddedToRecent() { "File04: was added successfully."); // Open the oldest recent file. - await gScratchpad.openFile(0); + gScratchpad.openFile(0); +} - // Test to see if it is now the most recent file, and that the other files - // were reordered successfully. +// We have opened the "oldest"-recent file. Test to see if it is now the most +// recent file, and that the other files were reordered successfully. +function testOpenOldestRecent() { lists.recentFiles03 = gScratchpad.getRecentFiles(); is(lists.recentFiles02[0], lists.recentFiles03[2], @@ -78,34 +79,24 @@ async function testAddedToRecent() { "File03 was reordered successfully in the 'recent files'-list."); is(lists.recentFiles02[2], lists.recentFiles03[1], "File02 was reordered successfully in the 'recent files'-list."); + + Services.prefs.setIntPref("devtools.scratchpad.recentFilesMax", 0); } -async function testHideMenu() { - Services.prefs.setIntPref("devtools.scratchpad.recentFilesMax", 0); - - // Give the Scratchpad UI time to react to the pref change, via its observer. - // This is a race condition; to fix it, Scratchpad would need to give us some - // indication that it was finished responding to a pref update - perhaps by - // emitting an event. - await snooze(); - - // The "devtools.scratchpad.recentFilesMax"-preference was set to zero (0). - // This should disable the "Open Recent"-menu by hiding it (this should not - // remove any files from the list). Test to see if it's been hidden. +// The "devtools.scratchpad.recentFilesMax"-preference was set to zero (0). +// This should disable the "Open Recent"-menu by hiding it (this should not +// remove any files from the list). Test to see if it's been hidden. +function testHideMenu() { const menu = gScratchpadWindow.document.getElementById("sp-open_recent-menu"); ok(menu.hasAttribute("hidden"), "The menu was hidden successfully."); + + Services.prefs.setIntPref("devtools.scratchpad.recentFilesMax", 2); } -async function testEnableMenu() { - Services.prefs.setIntPref("devtools.scratchpad.recentFilesMax", 2); - - // Give the Scratchpad UI time to react to the pref change. This is a race - // condition; see the comment in testHideMenu. - await snooze(); - - // We have set the recentFilesMax pref to a nonzero value. This enables the - // feature, removes the oldest files, rebuilds the menu and removes the - // "hidden"-attribute from it. Test to see if this works. +// We have set the recentFilesMax-pref to one (1), this enables the feature, +// removes the two oldest files, rebuilds the menu and removes the +// "hidden"-attribute from it. Test to see if this works. +function testChangedMaxRecent() { const menu = gScratchpadWindow.document.getElementById("sp-open_recent-menu"); ok(!menu.hasAttribute("hidden"), "The menu is visible. \\o/"); @@ -126,24 +117,30 @@ async function testEnableMenu() { is(correctMenuItem, true, "Two recent files were successfully removed from the 'Open Recent'-menu"); -} -async function testOpenDeletedFile() { // We now remove one file from the harddrive and use the recent-menuitem for // it to make sure the user is notified that the file no longer exists. // This is tested in testOpenDeletedFile(). gFile04.remove(false); - // Make sure the file has been deleted before continuing. - while (gFile04.exists()) { - await snooze(); + // Make sure the file has been deleted before continuing to avoid + // intermittent oranges. + waitForFileDeletion(); +} + +function waitForFileDeletion() { + if (gFile04.exists()) { + executeSoon(waitForFileDeletion); + return; } + gFile04 = null; + gScratchpad.openFile(0); +} - // By now we should have two recent files stored in the list but one of the - // files should be missing on the harddrive. - await gScratchpad.openFile(0); - +// By now we should have two recent files stored in the list but one of the +// files should be missing on the harddrive. +function testOpenDeletedFile() { const doc = gScratchpadWindow.document; const popup = doc.getElementById("sp-menu-open_recentPopup"); @@ -158,19 +155,13 @@ async function testOpenDeletedFile() { is(gScratchpad.notificationBox.currentNotification.messageText.textContent, gScratchpad.strings.GetStringFromName("fileNoLongerExists.notification"), "The notification label is correct."); + + gScratchpad.clearRecentFiles(); } -async function testClearAll() { - gScratchpad.clearRecentFiles(); - - // Give the UI time to react to the recent files being cleared out. This is a - // race condition. The clearRecentFiles method works asynchronously, but - // there is no way to wait for it to finish. A single event loop turn should - // be good enough. - await snooze(); - - // We have cleared the last file. Test to see if the last file was removed, - // the menu is empty and was disabled successfully. +// We have cleared the last file. Test to see if the last file was removed, +// the menu is empty and was disabled successfully. +function testClearedAll() { const doc = gScratchpadWindow.document; const menu = doc.getElementById("sp-open_recent-menu"); const popup = doc.getElementById("sp-menu-open_recentPopup"); @@ -180,6 +171,8 @@ async function testClearAll() { is(popup.children.length, 0, "All menuitems removed successfully."); ok(menu.hasAttribute("disabled"), "No files in the menu, it was disabled successfully."); + + finishTest(); } async function createAndLoadTemporaryFile(aFileName, aFileContent) { @@ -219,33 +212,124 @@ function checkIfMenuIsPopulated() { } } -async function test() { +/** + * The PreferenceObserver listens for preference changes while Scratchpad is + * running. + */ +var PreferenceObserver = { + _initialized: false, + + _timesFired: 0, + set timesFired(aNewValue) { + this._timesFired = aNewValue; + }, + get timesFired() { + return this._timesFired; + }, + + init: function PO_init() { + if (this._initialized) { + return; + } + + this.branch = Services.prefs.getBranch("devtools.scratchpad."); + this.branch.addObserver("", this); + this._initialized = true; + }, + + async observe(message, topic, data) { + if (topic != "nsPref:changed") { + return; + } + + if (this._inProgress) { + await this._inProgress; + } + + this._inProgress = new Promise(async resolve => { + info(`Times fired: ${this.timesFired}`); + switch (this.timesFired) { + case 0: + this.timesFired = 1; + break; + case 1: + this.timesFired = 2; + break; + case 2: + this.timesFired = 3; + await testAddedToRecent(); + break; + case 3: + this.timesFired = 4; + testOverwriteRecent(); + break; + case 4: + this.timesFired = 5; + testOpenOldestRecent(); + break; + case 5: + this.timesFired = 6; + testHideMenu(); + break; + case 6: + this.timesFired = 7; + testChangedMaxRecent(); + break; + case 7: + this.timesFired = 8; + testOpenDeletedFile(); + break; + case 8: + this.timesFired = 9; + testClearedAll(); + break; + } + + this._inProgress = null; + resolve(); + }); + }, + + uninit: function PO_uninit() { + this.branch.removeObserver("", this); + }, +}; + +function test() { waitForExplicitFinish(); registerCleanupFunction(function() { gFile01.remove(false); + gFile01 = null; gFile02.remove(false); + gFile02 = null; gFile03.remove(false); - // If all tests passed, gFile04 was already removed, but just in case: - if (gFile04) { - gFile04.remove(false); - } + gFile03 = null; + // gFile04 was removed earlier. + lists.recentFiles01 = null; + lists.recentFiles02 = null; + lists.recentFiles03 = null; + lists.recentFiles04 = null; + gScratchpad = null; + + PreferenceObserver.uninit(); Services.prefs.clearUserPref("devtools.scratchpad.recentFilesMax"); }); Services.prefs.setIntPref("devtools.scratchpad.recentFilesMax", 3); + // Initiate the preference observer after we have set the temporary recent + // files max for this test. + PreferenceObserver.init(); + gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); - const loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() { + openScratchpad(startTest); + }); + BrowserTestUtils.loadURI(gBrowser, "data:text/html,

test recent files in Scratchpad"); - await loaded; - await new Promise(openScratchpad); - - await testAddedToRecent(); - await testHideMenu(); - await testEnableMenu(); - await testOpenDeletedFile(); - await testClearAll(); +} +function finishTest() { finish(); }