Bug 1034036 - Part 3: Tests that use set state should wait until window is restored to continue. r=mikedeboer

MozReview-Commit-ID: 5SZ9ePGMKF1

--HG--
extra : rebase_source : 0078e02a310374b5f54b68e17c824367547b0cc5
This commit is contained in:
Beekill95 2017-08-15 14:45:08 +07:00
parent 0f783a7dba
commit 72ce1c7a57
21 changed files with 174 additions and 123 deletions

View File

@ -11,6 +11,7 @@ const SESSION = {
add_task(async function() {
SessionStore.setBrowserState(JSON.stringify(SESSION));
await promiseWindowRestored(window);
const tab = gBrowser.tabs[1];
is(tab.getAttribute("pending"), "true", "The tab is pending restore");

View File

@ -20,6 +20,7 @@
* promiseContentDimensions alterContent
* promisePrefChangeObserved openContextMenuInFrame
* promiseAnimationFrame getCustomizableUIPanelID
* promiseWindowRestored
*/
// There are shutdown issues for which multiple rejections are left uncaught.
@ -448,3 +449,7 @@ function promisePrefChangeObserved(pref) {
resolve();
}));
}
function promiseWindowRestored(window) {
return new Promise(resolve => window.addEventListener("SSWindowRestored", resolve, {once: true}));
}

View File

@ -37,6 +37,7 @@ add_task(async function() {
// restore the window state
ss.setBrowserState(state);
await promiseWindowRestored(window);
// at this point, the cookie should be restored...
enumerator = Services.cookies.enumerator;

View File

@ -38,47 +38,49 @@ function test() {
test_state.windows[0]._closedTabs.length);
ss.setWindowState(newWin, JSON.stringify(test_state), true);
let closedTabs = SessionStore.getClosedTabData(newWin, false);
promiseWindowRestored(newWin).then(() => {
let closedTabs = SessionStore.getClosedTabData(newWin, false);
// Verify that non JSON serialized data is the same as JSON serialized data.
is(JSON.stringify(closedTabs), SessionStore.getClosedTabData(newWin),
"Non-serialized data is the same as serialized data")
// Verify that non JSON serialized data is the same as JSON serialized data.
is(JSON.stringify(closedTabs), SessionStore.getClosedTabData(newWin),
"Non-serialized data is the same as serialized data")
is(closedTabs.length, test_state.windows[0]._closedTabs.length,
"Closed tab list has the expected length");
is(countByTitle(closedTabs, FORGET),
test_state.windows[0]._closedTabs.length - remember_count,
"The correct amout of tabs are to be forgotten");
is(countByTitle(closedTabs, REMEMBER), remember_count,
"Everything is set up");
is(closedTabs.length, test_state.windows[0]._closedTabs.length,
"Closed tab list has the expected length");
is(countByTitle(closedTabs, FORGET),
test_state.windows[0]._closedTabs.length - remember_count,
"The correct amout of tabs are to be forgotten");
is(countByTitle(closedTabs, REMEMBER), remember_count,
"Everything is set up");
// All of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE.
ok(testForError(() => ss.forgetClosedTab({}, 0)),
"Invalid window for forgetClosedTab throws");
ok(testForError(() => ss.forgetClosedTab(newWin, -1)),
"Invalid tab for forgetClosedTab throws");
ok(testForError(() => ss.forgetClosedTab(newWin, test_state.windows[0]._closedTabs.length + 1)),
"Invalid tab for forgetClosedTab throws");
// All of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE.
ok(testForError(() => ss.forgetClosedTab({}, 0)),
"Invalid window for forgetClosedTab throws");
ok(testForError(() => ss.forgetClosedTab(newWin, -1)),
"Invalid tab for forgetClosedTab throws");
ok(testForError(() => ss.forgetClosedTab(newWin, test_state.windows[0]._closedTabs.length + 1)),
"Invalid tab for forgetClosedTab throws");
// Remove third tab, then first tab.
ss.forgetClosedTab(newWin, 2);
ss.forgetClosedTab(newWin, null);
// Remove third tab, then first tab.
ss.forgetClosedTab(newWin, 2);
ss.forgetClosedTab(newWin, null);
closedTabs = SessionStore.getClosedTabData(newWin, false);
closedTabs = SessionStore.getClosedTabData(newWin, false);
// Verify that non JSON serialized data is the same as JSON serialized data.
is(JSON.stringify(closedTabs), SessionStore.getClosedTabData(newWin),
"Non-serialized data is the same as serialized data")
// Verify that non JSON serialized data is the same as JSON serialized data.
is(JSON.stringify(closedTabs), SessionStore.getClosedTabData(newWin),
"Non-serialized data is the same as serialized data")
is(closedTabs.length, remember_count,
"The correct amout of tabs was removed");
is(countByTitle(closedTabs, FORGET), 0,
"All tabs specifically forgotten were indeed removed");
is(countByTitle(closedTabs, REMEMBER), remember_count,
"... and tabs not specifically forgetten weren't");
is(closedTabs.length, remember_count,
"The correct amout of tabs was removed");
is(countByTitle(closedTabs, FORGET), 0,
"All tabs specifically forgotten were indeed removed");
is(countByTitle(closedTabs, REMEMBER), remember_count,
"... and tabs not specifically forgetten weren't");
// Clean up.
gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
BrowserTestUtils.closeWindow(newWin).then(finish);
// Clean up.
gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
BrowserTestUtils.closeWindow(newWin).then(finish);
});
});
}

View File

@ -57,6 +57,7 @@ add_task(async function() {
gPrefService.setIntPref("browser.sessionstore.max_tabs_undo",
test_state.windows[0]._closedTabs.length);
ss.setWindowState(newWin, JSON.stringify(test_state), true);
await promiseWindowRestored(newWin);
let closedTabs = JSON.parse(ss.getClosedTabData(newWin));
is(closedTabs.length, test_state.windows[0]._closedTabs.length,

View File

@ -22,24 +22,30 @@ function test() {
newState.windows[0].extData[uniqueKey2] = uniqueValue2;
ss.setWindowState(newWin, JSON.stringify(newState), false);
is(newWin.gBrowser.tabs.length, 2,
"original tab wasn't overwritten");
is(ss.getWindowValue(newWin, uniqueKey1), uniqueValue1,
"window value wasn't overwritten when the tabs weren't");
is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue2,
"new window value was correctly added");
promiseWindowRestored(newWin).then(() => {
is(newWin.gBrowser.tabs.length, 2,
"original tab wasn't overwritten");
is(ss.getWindowValue(newWin, uniqueKey1), uniqueValue1,
"window value wasn't overwritten when the tabs weren't");
is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue2,
"new window value was correctly added");
newState.windows[0].extData[uniqueKey2] = uniqueValue1;
ss.setWindowState(newWin, JSON.stringify(newState), true);
newState.windows[0].extData[uniqueKey2] = uniqueValue1;
ss.setWindowState(newWin, JSON.stringify(newState), true);
is(newWin.gBrowser.tabs.length, 1,
"original tabs were overwritten");
is(ss.getWindowValue(newWin, uniqueKey1), "",
"window value was cleared");
is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue1,
"window value was correctly overwritten");
promiseWindowRestored(newWin).then(() => {
is(newWin.gBrowser.tabs.length, 1,
"original tabs were overwritten");
is(ss.getWindowValue(newWin, uniqueKey1), "",
"window value was cleared");
is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue1,
"window value was correctly overwritten");
// clean up
BrowserTestUtils.closeWindow(newWin).then(finish);
// clean up
BrowserTestUtils.closeWindow(newWin).then(finish);
});
});
});
}

View File

@ -25,36 +25,43 @@ function test() {
"window value was set before the window was overwritten");
ss.setWindowState(newWin, JSON.stringify(newState), true);
// use newWin.setTimeout(..., 0) to mirror sss_restoreWindowFeatures
newWin.setTimeout(function() {
is(ss.getWindowValue(newWin, uniqueKey), "",
"window value was implicitly cleared");
is(newWin.windowState, newWin.STATE_MAXIMIZED,
"the window was maximized");
is(JSON.parse(ss.getClosedTabData(newWin)).length, 1,
"the closed tab was added before the window was overwritten");
delete newState.windows[0]._closedTabs;
delete newState.windows[0].sizemode;
ss.setWindowState(newWin, JSON.stringify(newState), true);
promiseWindowRestored(newWin).then(() => {
// use newWin.setTimeout(..., 0) to mirror sss_restoreWindowFeatures
newWin.setTimeout(function() {
is(JSON.parse(ss.getClosedTabData(newWin)).length, 0,
"closed tabs were implicitly cleared");
is(ss.getWindowValue(newWin, uniqueKey), "",
"window value was implicitly cleared");
is(newWin.windowState, newWin.STATE_MAXIMIZED,
"the window remains maximized");
newState.windows[0].sizemode = "normal";
"the window was maximized");
is(JSON.parse(ss.getClosedTabData(newWin)).length, 1,
"the closed tab was added before the window was overwritten");
delete newState.windows[0]._closedTabs;
delete newState.windows[0].sizemode;
ss.setWindowState(newWin, JSON.stringify(newState), true);
newWin.setTimeout(function() {
isnot(newWin.windowState, newWin.STATE_MAXIMIZED,
"the window was explicitly unmaximized");
promiseWindowRestored(newWin).then(() => {
newWin.setTimeout(function() {
is(JSON.parse(ss.getClosedTabData(newWin)).length, 0,
"closed tabs were implicitly cleared");
BrowserTestUtils.closeWindow(newWin).then(finish);
}, 0);
is(newWin.windowState, newWin.STATE_MAXIMIZED,
"the window remains maximized");
newState.windows[0].sizemode = "normal";
ss.setWindowState(newWin, JSON.stringify(newState), true);
promiseWindowRestored(newWin).then(() => {
newWin.setTimeout(function() {
isnot(newWin.windowState, newWin.STATE_MAXIMIZED,
"the window was explicitly unmaximized");
BrowserTestUtils.closeWindow(newWin).then(finish);
}, 0);
});
}, 0);
});
}, 0);
}, 0);
});
});
}

View File

@ -51,6 +51,7 @@ add_task(async function test_bug_490040() {
let win = await BrowserTestUtils.openNewBrowserWindow();
ss.setWindowState(win, JSON.stringify(state.windowState), true);
await promiseWindowRestored(win);
if (state.windowState.windows[0].tabs.length) {
await BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
}

View File

@ -85,35 +85,38 @@ function test() {
test_state._closedWindows.length);
ss.setWindowState(newWin, JSON.stringify(test_state), true);
let closedWindows = JSON.parse(ss.getClosedWindowData());
is(closedWindows.length, test_state._closedWindows.length,
"Closed window list has the expected length");
is(countByTitle(closedWindows, FORGET),
test_state._closedWindows.length - remember_count,
"The correct amount of windows are to be forgotten");
is(countByTitle(closedWindows, REMEMBER), remember_count,
"Everything is set up.");
promiseWindowRestored(newWin).then(() => {
let closedWindows = JSON.parse(ss.getClosedWindowData());
is(closedWindows.length, test_state._closedWindows.length,
"Closed window list has the expected length");
is(countByTitle(closedWindows, FORGET),
test_state._closedWindows.length - remember_count,
"The correct amount of windows are to be forgotten");
is(countByTitle(closedWindows, REMEMBER), remember_count,
"Everything is set up.");
// all of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE
ok(testForError(() => ss.forgetClosedWindow(-1)),
"Invalid window for forgetClosedWindow throws");
ok(testForError(() => ss.forgetClosedWindow(test_state._closedWindows.length + 1)),
"Invalid window for forgetClosedWindow throws");
// all of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE
ok(testForError(() => ss.forgetClosedWindow(-1)),
"Invalid window for forgetClosedWindow throws");
ok(testForError(() => ss.forgetClosedWindow(test_state._closedWindows.length + 1)),
"Invalid window for forgetClosedWindow throws");
// Remove third window, then first window
ss.forgetClosedWindow(2);
ss.forgetClosedWindow(null);
// Remove third window, then first window
ss.forgetClosedWindow(2);
ss.forgetClosedWindow(null);
closedWindows = JSON.parse(ss.getClosedWindowData());
is(closedWindows.length, remember_count,
"The correct amount of windows were removed");
is(countByTitle(closedWindows, FORGET), 0,
"All windows specifically forgotten were indeed removed");
is(countByTitle(closedWindows, REMEMBER), remember_count,
"... and windows not specifically forgetten weren't.");
closedWindows = JSON.parse(ss.getClosedWindowData());
is(closedWindows.length, remember_count,
"The correct amount of windows were removed");
is(countByTitle(closedWindows, FORGET), 0,
"All windows specifically forgotten were indeed removed");
is(countByTitle(closedWindows, REMEMBER), remember_count,
"... and windows not specifically forgetten weren't.");
// clean up
gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
BrowserTestUtils.closeWindow(newWin).then(finish);
// clean up
gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
BrowserTestUtils.closeWindow(newWin).then(finish);
});
});
}

View File

@ -22,16 +22,18 @@ function test() {
promiseWindowLoaded(win).then(() => {
is(win.gURLBar.readOnly, false,
"URL bar should not be read-only before setting the state");
"URL bar should not be read-only before setting the state");
is(win.gURLBar.getAttribute("enablehistory"), "true",
"URL bar autocomplete should be enabled before setting the state");
"URL bar autocomplete should be enabled before setting the state");
ss.setWindowState(win, state, true);
is(win.gURLBar.readOnly, expected.readOnly,
"URL bar read-only state should be restored correctly");
is(win.gURLBar.getAttribute("enablehistory"), expected.enablehistory,
"URL bar autocomplete state should be restored correctly");
promiseWindowRestored(win).then(() => {
is(win.gURLBar.readOnly, expected.readOnly,
"URL bar read-only state should be restored correctly");
is(win.gURLBar.getAttribute("enablehistory"), expected.enablehistory,
"URL bar autocomplete state should be restored correctly");
BrowserTestUtils.closeWindow(win).then(callback);
BrowserTestUtils.closeWindow(win).then(callback);
});
});
}

View File

@ -28,8 +28,10 @@ function test() {
if (/NS_ERROR_MALFORMED_URI/.test(e))
gotError = true;
}
ok(!gotError, "Didn't get a malformed URI error.");
BrowserTestUtils.closeWindow(theWin).then(finish);
promiseWindowRestored(theWin).then(() => {
ok(!gotError, "Didn't get a malformed URI error.");
BrowserTestUtils.closeWindow(theWin).then(finish);
});
});
}, {once: true});
}

View File

@ -83,6 +83,7 @@ add_task(async function() {
// Set the test state.
ss.setBrowserState(JSON.stringify(state));
await promiseWindowRestored(window);
// Wait until the selected tab is restored and all others are pending.
await Promise.all(Array.map(gBrowser.tabs, tab => {

View File

@ -42,6 +42,7 @@ add_task(async function test() {
let backupState = SessionStore.getBrowserState();
SessionStore.setBrowserState(JSON.stringify(TEST_STATE));
let win = await promiseWindow;
await promiseWindowRestored(win);
// The window has now been opened. Check the state that is returned,
// this should come from the cache while the window isn't restored, yet.

View File

@ -37,12 +37,13 @@ var state = {windows: [{tabs: [{entries: [
}
]}]}]}
function test() {
add_task(async function test() {
registerCleanupFunction(function() {
ss.setBrowserState(stateBackup);
});
/* This test fails by hanging. */
ss.setBrowserState(JSON.stringify(state));
await promiseWindowRestored(window);
ok(true, "Didn't hang!");
}
});

View File

@ -24,9 +24,12 @@ function test() {
info(ex);
}
ok(!gotError, "ss.setWindowState did not throw an error");
promiseWindowRestored(window).then(() => {
ok(!gotError, "ss.setWindowState did not throw an error");
// Make sure that we reset the state. Use a full state just in case things get crazy.
let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] }]}]};
waitForBrowserState(blankState, finish);
// Make sure that we reset the state. Use a full state just in case things get crazy.
let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] }]}]};
waitForBrowserState(blankState, finish);
});
}

View File

@ -101,19 +101,22 @@ add_task(async function() {
// Now, test that we don't record history if the iframe is added dynamically
add_task(async function() {
// Start with an empty history
let blankState = JSON.stringify({
windows: [{
tabs: [{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] }],
_closedTabs: []
}],
_closedWindows: []
});
ss.setBrowserState(blankState);
let blankState = JSON.stringify({
windows: [{
tabs: [{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] }],
_closedTabs: []
}],
_closedWindows: []
});
ss.setBrowserState(blankState);
await promiseWindowRestored(window);
let testURL = getRootDirectory(gTestPath) + "browser_frame_history_index_blank.html";
let tab = BrowserTestUtils.addTab(gBrowser, testURL);
gBrowser.selectedTab = tab;
dump("Wait here\n");
await waitForLoadsInBrowser(tab.linkedBrowser, 1);
dump("Finished Wait here\n");
info("dynamic: Opening a page with an iframe containing three frames, 4 dynamic loads should take place");
let doc = tab.linkedBrowser.contentDocument;

View File

@ -37,11 +37,13 @@ add_task(async function() {
// Open a new window and restore it to an initial state.
let win = await promiseNewWindowLoaded({private: false});
SessionStore.setWindowState(win, JSON.stringify(initialState), true);
await promiseWindowRestored(win);
is(SessionStore.getClosedTabCount(win), 2, "2 closed tabs after restoring initial state");
// Restore the new state but do not overwrite existing tabs (this should
// cause the closed tabs to be merged).
SessionStore.setWindowState(win, JSON.stringify(restoreState), false);
await promiseWindowRestored(win);
// Verify the windows closed tab data is correct.
let iClosed = initialState.windows[0]._closedTabs;

View File

@ -135,6 +135,7 @@ async function runScenarios(scenarios) {
scenario.selectedTab);
SessionStore.setWindowState(win, state, true);
await promiseWindowRestored(win);
for (let i = 0; i < scenario.expectedRemoteness.length; ++i) {
let expectedRemoteness = scenario.expectedRemoteness[i];

View File

@ -135,6 +135,7 @@ add_task(async function run_test() {
// Restore window with session cookies that have no originAttributes.
ss.setWindowState(win, SESSION_DATA, true);
await promiseWindowRestored(win);
let enumerator = Services.cookies.getCookiesFromHost(TEST_HOST, {});
let cookie;
@ -155,6 +156,7 @@ add_task(async function run_test() {
// Restore window with session cookies that have originAttributes within.
ss.setWindowState(win, SESSION_DATA_OA, true);
await promiseWindowRestored(win);
enumerator = Services.cookies.getCookiesFromHost(TEST_HOST, {});
cookieCount = 0;

View File

@ -42,6 +42,7 @@ add_task(async function() {
}
ss.setWindowState(win2, JSON.stringify(winState), true);
await promiseWindowRestored(win2);
for (let i = 0; i < 4; i++) {
let browser = win2.gBrowser.tabs[i].linkedBrowser;
@ -102,6 +103,7 @@ add_task(async function() {
await TabStateFlusher.flush(win2.gBrowser.tabs[0].linkedBrowser);
ss.setWindowState(win2, JSON.stringify(winState), true);
await promiseWindowRestored(win2);
for (let i = 0; i < 2; i++) {
let browser = win2.gBrowser.tabs[i].linkedBrowser;

View File

@ -186,6 +186,10 @@ function promiseTabState(tab, state) {
return promise;
}
function promiseWindowRestored(win) {
return new Promise(resolve => win.addEventListener("SSWindowRestored", resolve, {once: true}));
}
/**
* Wait for a content -> chrome message.
*/