mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-08 08:17:31 +09:00
Remove browser tests - Part 1: The Tests (except for experiments)
This commit is contained in:
parent
fa08bd44f7
commit
261374f310
1697 changed files with 0 additions and 144364 deletions
|
|
@ -1,7 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../testing/mochitest/browser.eslintrc.js"
|
||||
]
|
||||
};
|
||||
|
|
@ -1,242 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# browser_506482.js is disabled because of frequent failures (bug 538672)
|
||||
# browser_526613.js is disabled because of frequent failures (bug 534489)
|
||||
# browser_589246.js is disabled for leaking browser windows (bug 752467)
|
||||
# browser_580512.js is disabled for leaking browser windows (bug 752467)
|
||||
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
head.js
|
||||
content.js
|
||||
content-forms.js
|
||||
browser_cookies.sjs
|
||||
browser_formdata_sample.html
|
||||
browser_formdata_xpath_sample.html
|
||||
browser_frametree_sample.html
|
||||
browser_frametree_sample_frameset.html
|
||||
browser_frame_history_index.html
|
||||
browser_frame_history_index2.html
|
||||
browser_frame_history_index_blank.html
|
||||
browser_frame_history_a.html
|
||||
browser_frame_history_b.html
|
||||
browser_frame_history_c.html
|
||||
browser_frame_history_c1.html
|
||||
browser_frame_history_c2.html
|
||||
browser_form_restore_events_sample.html
|
||||
browser_formdata_format_sample.html
|
||||
browser_pageStyle_sample.html
|
||||
browser_pageStyle_sample_nested.html
|
||||
browser_sessionHistory_slow.sjs
|
||||
browser_scrollPositions_sample.html
|
||||
browser_scrollPositions_sample_frameset.html
|
||||
browser_scrollPositions_readerModeArticle.html
|
||||
browser_sessionStorage.html
|
||||
browser_248970_b_sample.html
|
||||
browser_339445_sample.html
|
||||
browser_423132_sample.html
|
||||
browser_447951_sample.html
|
||||
browser_454908_sample.html
|
||||
browser_456342_sample.xhtml
|
||||
browser_463205_sample.html
|
||||
browser_463206_sample.html
|
||||
browser_466937_sample.html
|
||||
browser_485482_sample.html
|
||||
browser_637020_slow.sjs
|
||||
browser_662743_sample.html
|
||||
browser_739531_sample.html
|
||||
browser_911547_sample.html
|
||||
browser_911547_sample.html^headers^
|
||||
restore_redirect_http.html
|
||||
restore_redirect_http.html^headers^
|
||||
restore_redirect_js.html
|
||||
restore_redirect_target.html
|
||||
browser_1234021_page.html
|
||||
|
||||
#NB: the following are disabled
|
||||
# browser_464620_a.html
|
||||
# browser_464620_b.html
|
||||
# browser_464620_xd.html
|
||||
|
||||
|
||||
#disabled-for-intermittent-failures--bug-766044, browser_459906_empty.html
|
||||
#disabled-for-intermittent-failures--bug-766044, browser_459906_sample.html
|
||||
#disabled-for-intermittent-failures--bug-765389, browser_461743_sample.html
|
||||
|
||||
[browser_aboutPrivateBrowsing.js]
|
||||
[browser_aboutSessionRestore.js]
|
||||
[browser_async_duplicate_tab.js]
|
||||
[browser_async_flushes.js]
|
||||
run-if = e10s && crashreporter
|
||||
skip-if = debug # bug 1167933
|
||||
[browser_async_remove_tab.js]
|
||||
run-if = e10s
|
||||
skip-if = debug # bug 1211084
|
||||
[browser_attributes.js]
|
||||
[browser_backup_recovery.js]
|
||||
[browser_broadcast.js]
|
||||
[browser_capabilities.js]
|
||||
[browser_cleaner.js]
|
||||
[browser_cookies.js]
|
||||
[browser_crashedTabs.js]
|
||||
skip-if = !e10s || !crashreporter
|
||||
[browser_unrestored_crashedTabs.js]
|
||||
skip-if = !e10s || !crashreporter
|
||||
[browser_revive_crashed_bg_tabs.js]
|
||||
skip-if = !e10s || !crashreporter
|
||||
[browser_dying_cache.js]
|
||||
[browser_dynamic_frames.js]
|
||||
[browser_form_restore_events.js]
|
||||
[browser_formdata.js]
|
||||
[browser_formdata_cc.js]
|
||||
[browser_formdata_format.js]
|
||||
[browser_formdata_xpath.js]
|
||||
[browser_frametree.js]
|
||||
[browser_frame_history.js]
|
||||
[browser_global_store.js]
|
||||
[browser_history_persist.js]
|
||||
[browser_label_and_icon.js]
|
||||
[browser_merge_closed_tabs.js]
|
||||
[browser_page_title.js]
|
||||
[browser_pageStyle.js]
|
||||
[browser_pending_tabs.js]
|
||||
[browser_privatetabs.js]
|
||||
[browser_purge_shistory.js]
|
||||
skip-if = e10s # Bug 1271024
|
||||
[browser_replace_load.js]
|
||||
[browser_restore_redirect.js]
|
||||
[browser_restore_cookies_noOriginAttributes.js]
|
||||
[browser_scrollPositions.js]
|
||||
[browser_scrollPositionsReaderMode.js]
|
||||
[browser_sessionHistory.js]
|
||||
[browser_sessionStorage.js]
|
||||
[browser_sessionStorage_size.js]
|
||||
[browser_swapDocShells.js]
|
||||
[browser_switch_remoteness.js]
|
||||
run-if = e10s
|
||||
[browser_upgrade_backup.js]
|
||||
[browser_windowRestore_perwindowpb.js]
|
||||
[browser_248970_b_perwindowpb.js]
|
||||
# Disabled because of leaks.
|
||||
# Re-enabling and rewriting this test is tracked in bug 936919.
|
||||
skip-if = true
|
||||
[browser_339445.js]
|
||||
[browser_345898.js]
|
||||
[browser_350525.js]
|
||||
[browser_354894_perwindowpb.js]
|
||||
[browser_367052.js]
|
||||
[browser_393716.js]
|
||||
[browser_394759_basic.js]
|
||||
# Disabled for intermittent failures, bug 944372.
|
||||
skip-if = true
|
||||
[browser_394759_behavior.js]
|
||||
[browser_394759_perwindowpb.js]
|
||||
[browser_394759_purge.js]
|
||||
[browser_423132.js]
|
||||
[browser_447951.js]
|
||||
[browser_454908.js]
|
||||
[browser_456342.js]
|
||||
[browser_461634.js]
|
||||
[browser_463205.js]
|
||||
[browser_463206.js]
|
||||
[browser_464199.js]
|
||||
[browser_465215.js]
|
||||
[browser_465223.js]
|
||||
[browser_466937.js]
|
||||
[browser_467409-backslashplosion.js]
|
||||
[browser_477657.js]
|
||||
[browser_480893.js]
|
||||
[browser_485482.js]
|
||||
[browser_485563.js]
|
||||
[browser_490040.js]
|
||||
[browser_491168.js]
|
||||
[browser_491577.js]
|
||||
[browser_495495.js]
|
||||
[browser_500328.js]
|
||||
[browser_514751.js]
|
||||
[browser_522375.js]
|
||||
[browser_522545.js]
|
||||
[browser_524745.js]
|
||||
[browser_528776.js]
|
||||
[browser_579868.js]
|
||||
[browser_579879.js]
|
||||
skip-if = (os == 'linux' && e10s && (debug||asan)) # Bug 1234404
|
||||
[browser_581937.js]
|
||||
[browser_586147.js]
|
||||
[browser_586068-apptabs.js]
|
||||
[browser_586068-apptabs_ondemand.js]
|
||||
[browser_586068-browser_state_interrupted.js]
|
||||
[browser_586068-cascade.js]
|
||||
[browser_586068-multi_window.js]
|
||||
[browser_586068-reload.js]
|
||||
[browser_586068-select.js]
|
||||
[browser_586068-window_state.js]
|
||||
[browser_586068-window_state_override.js]
|
||||
[browser_588426.js]
|
||||
[browser_590268.js]
|
||||
[browser_590563.js]
|
||||
[browser_595601-restore_hidden.js]
|
||||
[browser_597071.js]
|
||||
skip-if = true # Needs to be rewritten as Marionette test, bug 995916
|
||||
[browser_599909.js]
|
||||
[browser_600545.js]
|
||||
[browser_601955.js]
|
||||
[browser_607016.js]
|
||||
[browser_615394-SSWindowState_events.js]
|
||||
[browser_618151.js]
|
||||
[browser_623779.js]
|
||||
[browser_624727.js]
|
||||
[browser_628270.js]
|
||||
[browser_635418.js]
|
||||
[browser_636279.js]
|
||||
[browser_637020.js]
|
||||
[browser_644409-scratchpads.js]
|
||||
[browser_645428.js]
|
||||
[browser_659591.js]
|
||||
[browser_662743.js]
|
||||
[browser_662812.js]
|
||||
[browser_665702-state_session.js]
|
||||
[browser_682507.js]
|
||||
[browser_687710.js]
|
||||
[browser_687710_2.js]
|
||||
[browser_694378.js]
|
||||
[browser_701377.js]
|
||||
[browser_705597.js]
|
||||
[browser_707862.js]
|
||||
[browser_739531.js]
|
||||
[browser_739805.js]
|
||||
[browser_819510_perwindowpb.js]
|
||||
skip-if = (os == 'win' && bits == 64) # Bug 1284312
|
||||
|
||||
# Disabled for frequent intermittent failures
|
||||
[browser_464620_a.js]
|
||||
skip-if = true
|
||||
[browser_464620_b.js]
|
||||
skip-if = true
|
||||
|
||||
# Disabled on OS X:
|
||||
[browser_625016.js]
|
||||
skip-if = os == "mac"
|
||||
|
||||
[browser_911547.js]
|
||||
[browser_send_async_message_oom.js]
|
||||
[browser_multiple_navigateAndRestore.js]
|
||||
run-if = e10s
|
||||
[browser_async_window_flushing.js]
|
||||
[browser_forget_async_closings.js]
|
||||
[browser_newtab_userTypedValue.js]
|
||||
[browser_parentProcessRestoreHash.js]
|
||||
run-if = e10s
|
||||
[browser_sessionStoreContainer.js]
|
||||
[browser_windowStateContainer.js]
|
||||
[browser_1234021.js]
|
||||
[browser_remoteness_flip_on_restore.js]
|
||||
run-if = e10s
|
||||
[browser_background_tab_crash.js]
|
||||
run-if = e10s && crashreporter
|
||||
|
||||
# Disabled on debug for frequent intermittent failures:
|
||||
[browser_undoCloseById.js]
|
||||
skip-if = debug
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const PREF = 'network.cookie.cookieBehavior';
|
||||
const PAGE_URL = 'http://mochi.test:8888/browser/' +
|
||||
'browser/components/sessionstore/test/browser_1234021_page.html';
|
||||
const BEHAVIOR_REJECT = 2;
|
||||
|
||||
add_task(function* test() {
|
||||
yield pushPrefs([PREF, BEHAVIOR_REJECT]);
|
||||
|
||||
yield BrowserTestUtils.withNewTab({
|
||||
gBrowser: gBrowser,
|
||||
url: PAGE_URL
|
||||
}, function* handler(aBrowser) {
|
||||
yield TabStateFlusher.flush(aBrowser);
|
||||
ok(true, "Flush didn't time out");
|
||||
});
|
||||
});
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<script>
|
||||
sessionStorage
|
||||
</script>
|
||||
</html>
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test (B) for Bug 248970 **/
|
||||
waitForExplicitFinish();
|
||||
|
||||
let windowsToClose = [];
|
||||
let file = Services.dirsvc.get("TmpD", Ci.nsIFile);
|
||||
let filePath = file.path;
|
||||
let fieldList = {
|
||||
"//input[@name='input']": Date.now().toString(),
|
||||
"//input[@name='spaced 1']": Math.random().toString(),
|
||||
"//input[3]": "three",
|
||||
"//input[@type='checkbox']": true,
|
||||
"//input[@name='uncheck']": false,
|
||||
"//input[@type='radio'][1]": false,
|
||||
"//input[@type='radio'][2]": true,
|
||||
"//input[@type='radio'][3]": false,
|
||||
"//select": 2,
|
||||
"//select[@multiple]": [1, 3],
|
||||
"//textarea[1]": "",
|
||||
"//textarea[2]": "Some text... " + Math.random(),
|
||||
"//textarea[3]": "Some more text\n" + new Date(),
|
||||
"//input[@type='file']": filePath
|
||||
};
|
||||
|
||||
registerCleanupFunction(function* () {
|
||||
for (let win of windowsToClose) {
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
}
|
||||
});
|
||||
|
||||
function test(aLambda) {
|
||||
try {
|
||||
return aLambda() || true;
|
||||
} catch(ex) { }
|
||||
return false;
|
||||
}
|
||||
|
||||
function getElementByXPath(aTab, aQuery) {
|
||||
let doc = aTab.linkedBrowser.contentDocument;
|
||||
let xptype = Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE;
|
||||
return doc.evaluate(aQuery, doc, null, xptype, null).singleNodeValue;
|
||||
}
|
||||
|
||||
function setFormValue(aTab, aQuery, aValue) {
|
||||
let node = getElementByXPath(aTab, aQuery);
|
||||
if (typeof aValue == "string")
|
||||
node.value = aValue;
|
||||
else if (typeof aValue == "boolean")
|
||||
node.checked = aValue;
|
||||
else if (typeof aValue == "number")
|
||||
node.selectedIndex = aValue;
|
||||
else
|
||||
Array.forEach(node.options, (aOpt, aIx) =>
|
||||
(aOpt.selected = aValue.indexOf(aIx) > -1));
|
||||
}
|
||||
|
||||
function compareFormValue(aTab, aQuery, aValue) {
|
||||
let node = getElementByXPath(aTab, aQuery);
|
||||
if (!node)
|
||||
return false;
|
||||
if (node instanceof Ci.nsIDOMHTMLInputElement)
|
||||
return aValue == (node.type == "checkbox" || node.type == "radio" ?
|
||||
node.checked : node.value);
|
||||
if (node instanceof Ci.nsIDOMHTMLTextAreaElement)
|
||||
return aValue == node.value;
|
||||
if (!node.multiple)
|
||||
return aValue == node.selectedIndex;
|
||||
return Array.every(node.options, (aOpt, aIx) =>
|
||||
(aValue.indexOf(aIx) > -1) == aOpt.selected);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Test (B) : Session data restoration between windows //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
let rootDir = getRootDirectory(gTestPath);
|
||||
const testURL = rootDir + "browser_248970_b_sample.html";
|
||||
const testURL2 = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser_248970_b_sample.html";
|
||||
|
||||
whenNewWindowLoaded({ private: false }, function(aWin) {
|
||||
windowsToClose.push(aWin);
|
||||
|
||||
// get closed tab count
|
||||
let count = ss.getClosedTabCount(aWin);
|
||||
let max_tabs_undo =
|
||||
Services.prefs.getIntPref("browser.sessionstore.max_tabs_undo");
|
||||
ok(0 <= count && count <= max_tabs_undo,
|
||||
"getClosedTabCount should return zero or at most max_tabs_undo");
|
||||
|
||||
// setup a state for tab (A) so we can check later that is restored
|
||||
let key = "key";
|
||||
let value = "Value " + Math.random();
|
||||
let state = { entries: [{ url: testURL }], extData: { key: value } };
|
||||
|
||||
// public session, add new tab: (A)
|
||||
let tab_A = aWin.gBrowser.addTab(testURL);
|
||||
ss.setTabState(tab_A, JSON.stringify(state));
|
||||
promiseBrowserLoaded(tab_A.linkedBrowser).then(() => {
|
||||
// make sure that the next closed tab will increase getClosedTabCount
|
||||
Services.prefs.setIntPref(
|
||||
"browser.sessionstore.max_tabs_undo", max_tabs_undo + 1)
|
||||
|
||||
// populate tab_A with form data
|
||||
for (let i in fieldList)
|
||||
setFormValue(tab_A, i, fieldList[i]);
|
||||
|
||||
// public session, close tab: (A)
|
||||
aWin.gBrowser.removeTab(tab_A);
|
||||
|
||||
// verify that closedTabCount increased
|
||||
ok(ss.getClosedTabCount(aWin) > count,
|
||||
"getClosedTabCount has increased after closing a tab");
|
||||
|
||||
// verify tab: (A), in undo list
|
||||
let tab_A_restored = test(() => ss.undoCloseTab(aWin, 0));
|
||||
ok(tab_A_restored, "a tab is in undo list");
|
||||
promiseTabRestored(tab_A_restored).then(() => {
|
||||
is(testURL, tab_A_restored.linkedBrowser.currentURI.spec,
|
||||
"it's the same tab that we expect");
|
||||
aWin.gBrowser.removeTab(tab_A_restored);
|
||||
|
||||
whenNewWindowLoaded({ private: true }, function(aWin) {
|
||||
windowsToClose.push(aWin);
|
||||
|
||||
// setup a state for tab (B) so we can check that its duplicated
|
||||
// properly
|
||||
let key1 = "key1";
|
||||
let value1 = "Value " + Math.random();
|
||||
let state1 = {
|
||||
entries: [{ url: testURL2 }], extData: { key1: value1 }
|
||||
};
|
||||
|
||||
let tab_B = aWin.gBrowser.addTab(testURL2);
|
||||
promiseTabState(tab_B, state1).then(() => {
|
||||
// populate tab: (B) with different form data
|
||||
for (let item in fieldList)
|
||||
setFormValue(tab_B, item, fieldList[item]);
|
||||
|
||||
// duplicate tab: (B)
|
||||
let tab_C = aWin.gBrowser.duplicateTab(tab_B);
|
||||
promiseTabRestored(tab_C).then(() => {
|
||||
// verify the correctness of the duplicated tab
|
||||
is(ss.getTabValue(tab_C, key1), value1,
|
||||
"tab successfully duplicated - correct state");
|
||||
|
||||
for (let item in fieldList)
|
||||
ok(compareFormValue(tab_C, item, fieldList[item]),
|
||||
"The value for \"" + item + "\" was correctly duplicated");
|
||||
|
||||
// private browsing session, close tab: (C) and (B)
|
||||
aWin.gBrowser.removeTab(tab_C);
|
||||
aWin.gBrowser.removeTab(tab_B);
|
||||
|
||||
finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
||||
<meta charset="utf-8">
|
||||
<title>Test for bug 248970</title>
|
||||
|
||||
<h3>Text Fields</h3>
|
||||
<input type="text" name="input">
|
||||
<input type="text" name="spaced 1">
|
||||
<input>
|
||||
|
||||
<h3>Checkboxes and Radio buttons</h3>
|
||||
<input type="checkbox" name="check"> Check 1
|
||||
<input type="checkbox" name="uncheck" checked> Check 2
|
||||
<p>
|
||||
<input type="radio" name="group" value="1"> Radio 1
|
||||
<input type="radio" name="group" value="some"> Radio 2
|
||||
<input type="radio" name="group" checked> Radio 3
|
||||
|
||||
<h3>Selects</h3>
|
||||
<select name="any">
|
||||
<option value="1"> Select 1
|
||||
<option value="some"> Select 2
|
||||
<option>Select 3
|
||||
</select>
|
||||
<select multiple="multiple">
|
||||
<option value=1> Multi-select 1
|
||||
<option value=2> Multi-select 2
|
||||
<option value=3> Multi-select 3
|
||||
<option value=4> Multi-select 4
|
||||
</select>
|
||||
|
||||
<h3>Text Areas</h3>
|
||||
<textarea name="testarea"></textarea>
|
||||
<textarea name="sized one" rows="5" cols="25"></textarea>
|
||||
<textarea></textarea>
|
||||
|
||||
<h3>File Selector</h3>
|
||||
<input type="file">
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
add_task(function* test() {
|
||||
/** Test for Bug 339445 **/
|
||||
|
||||
let testURL = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser_339445_sample.html";
|
||||
|
||||
let tab = gBrowser.addTab(testURL);
|
||||
yield promiseBrowserLoaded(tab.linkedBrowser);
|
||||
|
||||
yield ContentTask.spawn(tab.linkedBrowser, null, function() {
|
||||
let doc = content.document;
|
||||
is(doc.getElementById("storageTestItem").textContent, "PENDING",
|
||||
"sessionStorage value has been set");
|
||||
});
|
||||
|
||||
let tab2 = gBrowser.duplicateTab(tab);
|
||||
yield promiseTabRestored(tab2);
|
||||
|
||||
yield ContentTask.spawn(tab2.linkedBrowser, null, function() {
|
||||
let doc2 = content.document;
|
||||
is(doc2.getElementById("storageTestItem").textContent, "SUCCESS",
|
||||
"sessionStorage value has been duplicated");
|
||||
});
|
||||
|
||||
// clean up
|
||||
yield Promise.all([ BrowserTestUtils.removeTab(tab2),
|
||||
BrowserTestUtils.removeTab(tab) ]);
|
||||
});
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
||||
<meta charset="utf-8">
|
||||
<title>Test for bug 339445</title>
|
||||
|
||||
storageTestItem = <span id="storageTestItem">FAIL</span>
|
||||
|
||||
<!--
|
||||
storageTestItem's textContent will be one of the following:
|
||||
* FAIL : sessionStorage wasn't available
|
||||
* PENDING : the test value has been initialized on first load
|
||||
* SUCCESS : the test value was correctly retrieved
|
||||
-->
|
||||
|
||||
<script type="application/javascript">
|
||||
document.getElementById("storageTestItem").textContent =
|
||||
sessionStorage["storageTestItem"] || "PENDING";
|
||||
sessionStorage["storageTestItem"] = "SUCCESS";
|
||||
</script>
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 345898 **/
|
||||
|
||||
function test(aLambda) {
|
||||
try {
|
||||
aLambda();
|
||||
return false;
|
||||
}
|
||||
catch (ex) {
|
||||
return ex.name == "NS_ERROR_ILLEGAL_VALUE" ||
|
||||
ex.name == "NS_ERROR_FAILURE";
|
||||
}
|
||||
}
|
||||
|
||||
// all of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE
|
||||
ok(test(() => ss.getWindowState({})),
|
||||
"Invalid window for getWindowState throws");
|
||||
ok(test(() => ss.setWindowState({}, "", false)),
|
||||
"Invalid window for setWindowState throws");
|
||||
ok(test(() => ss.getTabState({})),
|
||||
"Invalid tab for getTabState throws");
|
||||
ok(test(() => ss.setTabState({}, "{}")),
|
||||
"Invalid tab state for setTabState throws");
|
||||
ok(test(() => ss.setTabState({}, JSON.stringify({ entries: [] }))),
|
||||
"Invalid tab for setTabState throws");
|
||||
ok(test(() => ss.duplicateTab({}, {})),
|
||||
"Invalid tab for duplicateTab throws");
|
||||
ok(test(() => ss.duplicateTab({}, gBrowser.selectedTab)),
|
||||
"Invalid window for duplicateTab throws");
|
||||
ok(test(() => ss.getClosedTabData({})),
|
||||
"Invalid window for getClosedTabData throws");
|
||||
ok(test(() => ss.undoCloseTab({}, 0)),
|
||||
"Invalid window for undoCloseTab throws");
|
||||
ok(test(() => ss.undoCloseTab(window, -1)),
|
||||
"Invalid index for undoCloseTab throws");
|
||||
ok(test(() => ss.getWindowValue({}, "")),
|
||||
"Invalid window for getWindowValue throws");
|
||||
ok(test(() => ss.setWindowValue({}, "", "")),
|
||||
"Invalid window for setWindowValue throws");
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
add_task(function* setup() {
|
||||
yield SpecialPowers.pushPrefEnv({
|
||||
set: [["dom.ipc.processCount", 1]]
|
||||
});
|
||||
})
|
||||
|
||||
add_task(function* () {
|
||||
/** Test for Bug 350525 **/
|
||||
|
||||
function test(aLambda) {
|
||||
try {
|
||||
return aLambda() || true;
|
||||
}
|
||||
catch (ex) { }
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// setWindowValue, et al. //
|
||||
////////////////////////////
|
||||
let key = "Unique name: " + Date.now();
|
||||
let value = "Unique value: " + Math.random();
|
||||
|
||||
// test adding
|
||||
ok(test(() => ss.setWindowValue(window, key, value)), "set a window value");
|
||||
|
||||
// test retrieving
|
||||
is(ss.getWindowValue(window, key), value, "stored window value matches original");
|
||||
|
||||
// test deleting
|
||||
ok(test(() => ss.deleteWindowValue(window, key)), "delete the window value");
|
||||
|
||||
// value should not exist post-delete
|
||||
is(ss.getWindowValue(window, key), "", "window value was deleted");
|
||||
|
||||
// test deleting a non-existent value
|
||||
ok(test(() => ss.deleteWindowValue(window, key)), "delete non-existent window value");
|
||||
|
||||
/////////////////////////
|
||||
// setTabValue, et al. //
|
||||
/////////////////////////
|
||||
key = "Unique name: " + Math.random();
|
||||
value = "Unique value: " + Date.now();
|
||||
let tab = gBrowser.addTab();
|
||||
tab.linkedBrowser.stop();
|
||||
|
||||
// test adding
|
||||
ok(test(() => ss.setTabValue(tab, key, value)), "store a tab value");
|
||||
|
||||
// test retrieving
|
||||
is(ss.getTabValue(tab, key), value, "stored tab value match original");
|
||||
|
||||
// test deleting
|
||||
ok(test(() => ss.deleteTabValue(tab, key)), "delete the tab value");
|
||||
|
||||
// value should not exist post-delete
|
||||
is(ss.getTabValue(tab, key), "", "tab value was deleted");
|
||||
|
||||
// test deleting a non-existent value
|
||||
ok(test(() => ss.deleteTabValue(tab, key)), "delete non-existent tab value");
|
||||
|
||||
// clean up
|
||||
yield promiseRemoveTab(tab);
|
||||
|
||||
/////////////////////////////////////
|
||||
// getClosedTabCount, undoCloseTab //
|
||||
/////////////////////////////////////
|
||||
|
||||
// get closed tab count
|
||||
let count = ss.getClosedTabCount(window);
|
||||
let max_tabs_undo = gPrefService.getIntPref("browser.sessionstore.max_tabs_undo");
|
||||
ok(0 <= count && count <= max_tabs_undo,
|
||||
"getClosedTabCount returns zero or at most max_tabs_undo");
|
||||
|
||||
// create a new tab
|
||||
let testURL = "about:";
|
||||
tab = gBrowser.addTab(testURL);
|
||||
yield promiseBrowserLoaded(tab.linkedBrowser);
|
||||
|
||||
// make sure that the next closed tab will increase getClosedTabCount
|
||||
gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", max_tabs_undo + 1);
|
||||
registerCleanupFunction(() => gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo"));
|
||||
|
||||
// remove tab
|
||||
yield promiseRemoveTab(tab);
|
||||
|
||||
// getClosedTabCount
|
||||
let newcount = ss.getClosedTabCount(window);
|
||||
ok(newcount > count, "after closing a tab, getClosedTabCount has been incremented");
|
||||
|
||||
// undoCloseTab
|
||||
tab = test(() => ss.undoCloseTab(window, 0));
|
||||
ok(tab, "undoCloseTab doesn't throw")
|
||||
|
||||
yield promiseTabRestored(tab);
|
||||
is(tab.linkedBrowser.currentURI.spec, testURL, "correct tab was reopened");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
|
@ -1,474 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Checks that restoring the last browser window in session is actually
|
||||
* working.
|
||||
*
|
||||
* @see https://bugzilla.mozilla.org/show_bug.cgi?id=354894
|
||||
* @note It is implicitly tested that restoring the last window works when
|
||||
* non-browser windows are around. The "Run Tests" window as well as the main
|
||||
* browser window (wherein the test code gets executed) won't be considered
|
||||
* browser windows. To achiveve this said main browser window has it's windowtype
|
||||
* attribute modified so that it's not considered a browser window any longer.
|
||||
* This is crucial, because otherwise there would be two browser windows around,
|
||||
* said main test window and the one opened by the tests, and hence the new
|
||||
* logic wouldn't be executed at all.
|
||||
* @note Mac only tests the new notifications, as restoring the last window is
|
||||
* not enabled on that platform (platform shim; the application is kept running
|
||||
* although there are no windows left)
|
||||
* @note There is a difference when closing a browser window with
|
||||
* BrowserTryToCloseWindow() as opposed to close(). The former will make
|
||||
* nsSessionStore restore a window next time it gets a chance and will post
|
||||
* notifications. The latter won't.
|
||||
*/
|
||||
|
||||
// Some urls that might be opened in tabs and/or popups
|
||||
// Do not use about:blank:
|
||||
// That one is reserved for special purposes in the tests
|
||||
const TEST_URLS = ["about:mozilla", "about:buildconfig"];
|
||||
|
||||
// Number of -request notifications to except
|
||||
// remember to adjust when adding new tests
|
||||
const NOTIFICATIONS_EXPECTED = 6;
|
||||
|
||||
// Window features of popup windows
|
||||
const POPUP_FEATURES = "toolbar=no,resizable=no,status=no";
|
||||
|
||||
// Window features of browser windows
|
||||
const CHROME_FEATURES = "chrome,all,dialog=no";
|
||||
|
||||
const IS_MAC = navigator.platform.match(/Mac/);
|
||||
|
||||
/**
|
||||
* Returns an Object with two properties:
|
||||
* open (int):
|
||||
* A count of how many non-closed navigator:browser windows there are.
|
||||
* winstates (int):
|
||||
* A count of how many windows there are in the SessionStore state.
|
||||
*/
|
||||
function getBrowserWindowsCount() {
|
||||
let open = 0;
|
||||
let e = Services.wm.getEnumerator("navigator:browser");
|
||||
while (e.hasMoreElements()) {
|
||||
if (!e.getNext().closed)
|
||||
++open;
|
||||
}
|
||||
|
||||
let winstates = JSON.parse(ss.getBrowserState()).windows.length;
|
||||
|
||||
return { open, winstates };
|
||||
}
|
||||
|
||||
add_task(function* setup() {
|
||||
// Make sure we've only got one browser window to start with
|
||||
let { open, winstates } = getBrowserWindowsCount();
|
||||
is(open, 1, "Should only be one open window");
|
||||
is(winstates, 1, "Should only be one window state in SessionStore");
|
||||
|
||||
// This test takes some time to run, and it could timeout randomly.
|
||||
// So we require a longer timeout. See bug 528219.
|
||||
requestLongerTimeout(3);
|
||||
|
||||
// Make the main test window not count as a browser window any longer
|
||||
let oldWinType = document.documentElement.getAttribute("windowtype");
|
||||
document.documentElement.setAttribute("windowtype", "navigator:testrunner");
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
document.documentElement.setAttribute("windowtype", "navigator:browser");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Sets up one of our tests by setting the right preferences, and
|
||||
* then opening up a browser window preloaded with some tabs.
|
||||
*
|
||||
* @param options (Object)
|
||||
* An object that can contain the following properties:
|
||||
*
|
||||
* private:
|
||||
* Whether or not the opened window should be private.
|
||||
*
|
||||
* denyFirst:
|
||||
* Whether or not the first window that attempts to close
|
||||
* via closeWindowForRestoration should be denied.
|
||||
*
|
||||
* @param testFunction (Function*)
|
||||
* A generator function that yields Promises to be run
|
||||
* once the test has been set up.
|
||||
*
|
||||
* @returns Promise
|
||||
* Resolves once the test has been cleaned up.
|
||||
*/
|
||||
let setupTest = Task.async(function*(options, testFunction) {
|
||||
yield pushPrefs(["browser.startup.page", 3],
|
||||
["browser.tabs.warnOnClose", false]);
|
||||
|
||||
// Observe these, and also use to count the number of hits
|
||||
let observing = {
|
||||
"browser-lastwindow-close-requested": 0,
|
||||
"browser-lastwindow-close-granted": 0
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper: Will observe and handle the notifications for us
|
||||
*/
|
||||
let hitCount = 0;
|
||||
function observer(aCancel, aTopic, aData) {
|
||||
// count so that we later may compare
|
||||
observing[aTopic]++;
|
||||
|
||||
// handle some tests
|
||||
if (options.denyFirst && ++hitCount == 1) {
|
||||
aCancel.QueryInterface(Ci.nsISupportsPRBool).data = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (let o in observing) {
|
||||
Services.obs.addObserver(observer, o, false);
|
||||
}
|
||||
|
||||
let private = options.private || false;
|
||||
let newWin = yield promiseNewWindowLoaded({ private });
|
||||
|
||||
injectTestTabs(newWin);
|
||||
|
||||
yield testFunction(newWin, observing);
|
||||
|
||||
let count = getBrowserWindowsCount();
|
||||
is(count.open, 0, "Got right number of open windows");
|
||||
is(count.winstates, 1, "Got right number of stored window states");
|
||||
|
||||
for (let o in observing) {
|
||||
Services.obs.removeObserver(observer, o);
|
||||
}
|
||||
|
||||
yield popPrefs();
|
||||
});
|
||||
|
||||
/**
|
||||
* Loads a TEST_URLS into a browser window.
|
||||
*
|
||||
* @param win (Window)
|
||||
* The browser window to load the tabs in
|
||||
*/
|
||||
function injectTestTabs(win) {
|
||||
TEST_URLS.forEach(function (url) {
|
||||
win.gBrowser.addTab(url);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to close a window via BrowserTryToCloseWindow so that
|
||||
* we get the browser-lastwindow-close-requested and
|
||||
* browser-lastwindow-close-granted observer notifications.
|
||||
*
|
||||
* @param win (Window)
|
||||
* The window to try to close
|
||||
* @returns Promise
|
||||
* Resolves to true if the window closed, or false if the window
|
||||
* was denied the ability to close.
|
||||
*/
|
||||
function closeWindowForRestoration(win) {
|
||||
return new Promise((resolve) => {
|
||||
let closePromise = BrowserTestUtils.windowClosed(win);
|
||||
win.BrowserTryToCloseWindow();
|
||||
if (!win.closed) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
closePromise.then(() => {
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal in-session restore
|
||||
*
|
||||
* @note: Non-Mac only
|
||||
*
|
||||
* Should do the following:
|
||||
* 1. Open a new browser window
|
||||
* 2. Add some tabs
|
||||
* 3. Close that window
|
||||
* 4. Opening another window
|
||||
* 5. Checks that state is restored
|
||||
*/
|
||||
add_task(function* test_open_close_normal() {
|
||||
if (IS_MAC) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield setupTest({ denyFirst: true }, function*(newWin, obs) {
|
||||
let closed = yield closeWindowForRestoration(newWin);
|
||||
ok(!closed, "First close request should have been denied");
|
||||
|
||||
closed = yield closeWindowForRestoration(newWin);
|
||||
ok(closed, "Second close request should be accepted");
|
||||
|
||||
newWin = yield promiseNewWindowLoaded();
|
||||
is(newWin.gBrowser.browsers.length, TEST_URLS.length + 2,
|
||||
"Restored window in-session with otherpopup windows around");
|
||||
|
||||
// Note that this will not result in the the browser-lastwindow-close
|
||||
// notifications firing for this other newWin.
|
||||
yield BrowserTestUtils.closeWindow(newWin);
|
||||
|
||||
// setupTest gave us a window which was denied for closing once, and then
|
||||
// closed.
|
||||
is(obs["browser-lastwindow-close-requested"], 2,
|
||||
"Got expected browser-lastwindow-close-requested notifications");
|
||||
is(obs["browser-lastwindow-close-granted"], 1,
|
||||
"Got expected browser-lastwindow-close-granted notifications");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* PrivateBrowsing in-session restore
|
||||
*
|
||||
* @note: Non-Mac only
|
||||
*
|
||||
* Should do the following:
|
||||
* 1. Open a new browser window A
|
||||
* 2. Add some tabs
|
||||
* 3. Close the window A as the last window
|
||||
* 4. Open a private browsing window B
|
||||
* 5. Make sure that B didn't restore the tabs from A
|
||||
* 6. Close private browsing window B
|
||||
* 7. Open a new window C
|
||||
* 8. Make sure that new window C has restored tabs from A
|
||||
*/
|
||||
add_task(function* test_open_close_private_browsing() {
|
||||
if (IS_MAC) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield setupTest({}, function*(newWin, obs) {
|
||||
let closed = yield closeWindowForRestoration(newWin);
|
||||
ok(closed, "Should be able to close the window");
|
||||
|
||||
newWin = yield promiseNewWindowLoaded({private: true});
|
||||
is(newWin.gBrowser.browsers.length, 1,
|
||||
"Did not restore in private browing mode");
|
||||
|
||||
closed = yield closeWindowForRestoration(newWin);
|
||||
ok(closed, "Should be able to close the window");
|
||||
|
||||
newWin = yield promiseNewWindowLoaded();
|
||||
is(newWin.gBrowser.browsers.length, TEST_URLS.length + 2,
|
||||
"Restored tabs in a new non-private window");
|
||||
|
||||
// Note that this will not result in the the browser-lastwindow-close
|
||||
// notifications firing for this other newWin.
|
||||
yield BrowserTestUtils.closeWindow(newWin);
|
||||
|
||||
// We closed two windows with closeWindowForRestoration, and both
|
||||
// should have been successful.
|
||||
is(obs["browser-lastwindow-close-requested"], 2,
|
||||
"Got expected browser-lastwindow-close-requested notifications");
|
||||
is(obs["browser-lastwindow-close-granted"], 2,
|
||||
"Got expected browser-lastwindow-close-granted notifications");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Open some popup windows to check those aren't restored, but the browser
|
||||
* window is.
|
||||
*
|
||||
* @note: Non-Mac only
|
||||
*
|
||||
* Should do the following:
|
||||
* 1. Open a new browser window
|
||||
* 2. Add some tabs
|
||||
* 3. Open some popups
|
||||
* 4. Add another tab to one popup (so that it gets stored) and close it again
|
||||
* 5. Close the browser window
|
||||
* 6. Open another browser window
|
||||
* 7. Make sure that the tabs of the closed browser window, but not the popup,
|
||||
* are restored
|
||||
*/
|
||||
add_task(function* test_open_close_window_and_popup() {
|
||||
if (IS_MAC) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield setupTest({}, function*(newWin, obs) {
|
||||
let popupPromise = BrowserTestUtils.waitForNewWindow();
|
||||
openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[0]);
|
||||
let popup = yield popupPromise;
|
||||
|
||||
let popup2Promise = BrowserTestUtils.waitForNewWindow();
|
||||
openDialog(location, "popup2", POPUP_FEATURES, TEST_URLS[1]);
|
||||
let popup2 = yield popup2Promise;
|
||||
|
||||
popup2.gBrowser.addTab(TEST_URLS[0]);
|
||||
|
||||
let closed = yield closeWindowForRestoration(newWin);
|
||||
ok(closed, "Should be able to close the window");
|
||||
|
||||
yield BrowserTestUtils.closeWindow(popup2);
|
||||
|
||||
newWin = yield promiseNewWindowLoaded();
|
||||
|
||||
is(newWin.gBrowser.browsers.length, TEST_URLS.length + 2,
|
||||
"Restored window and associated tabs in session");
|
||||
|
||||
yield BrowserTestUtils.closeWindow(popup);
|
||||
yield BrowserTestUtils.closeWindow(newWin);
|
||||
|
||||
// We closed one window with closeWindowForRestoration, and it should
|
||||
// have been successful.
|
||||
is(obs["browser-lastwindow-close-requested"], 1,
|
||||
"Got expected browser-lastwindow-close-requested notifications");
|
||||
is(obs["browser-lastwindow-close-granted"], 1,
|
||||
"Got expected browser-lastwindow-close-granted notifications");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Open some popup window to check it isn't restored. Instead nothing at all
|
||||
* should be restored
|
||||
*
|
||||
* @note: Non-Mac only
|
||||
*
|
||||
* Should do the following:
|
||||
* 1. Open a popup
|
||||
* 2. Add another tab to the popup (so that it gets stored) and close it again
|
||||
* 3. Open a window
|
||||
* 4. Check that nothing at all is restored
|
||||
* 5. Open two browser windows and close them again
|
||||
* 6. undoCloseWindow() one
|
||||
* 7. Open another browser window
|
||||
* 8. Check that nothing at all is restored
|
||||
*/
|
||||
add_task(function* test_open_close_only_popup() {
|
||||
if (IS_MAC) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield setupTest({}, function*(newWin, obs) {
|
||||
// We actually don't care about the initial window in this test.
|
||||
yield BrowserTestUtils.closeWindow(newWin);
|
||||
|
||||
// This will cause nsSessionStore to restore a window the next time it
|
||||
// gets a chance.
|
||||
let popupPromise = BrowserTestUtils.waitForNewWindow();
|
||||
openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[1]);
|
||||
let popup = yield popupPromise;
|
||||
|
||||
is(popup.gBrowser.browsers.length, 1,
|
||||
"Did not restore the popup window (1)");
|
||||
|
||||
let closed = yield closeWindowForRestoration(popup);
|
||||
ok(closed, "Should be able to close the window");
|
||||
|
||||
popupPromise = BrowserTestUtils.waitForNewWindow();
|
||||
openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[1]);
|
||||
popup = yield popupPromise;
|
||||
|
||||
popup.gBrowser.addTab(TEST_URLS[0]);
|
||||
is(popup.gBrowser.browsers.length, 2,
|
||||
"Did not restore to the popup window (2)");
|
||||
|
||||
yield BrowserTestUtils.closeWindow(popup);
|
||||
|
||||
newWin = yield promiseNewWindowLoaded();
|
||||
isnot(newWin.gBrowser.browsers.length, 2,
|
||||
"Did not restore the popup window");
|
||||
is(TEST_URLS.indexOf(newWin.gBrowser.browsers[0].currentURI.spec), -1,
|
||||
"Did not restore the popup window (2)");
|
||||
yield BrowserTestUtils.closeWindow(newWin);
|
||||
|
||||
// We closed one popup window with closeWindowForRestoration, and popup
|
||||
// windows should never fire the browser-lastwindow notifications.
|
||||
is(obs["browser-lastwindow-close-requested"], 0,
|
||||
"Got expected browser-lastwindow-close-requested notifications");
|
||||
is(obs["browser-lastwindow-close-granted"], 0,
|
||||
"Got expected browser-lastwindow-close-granted notifications");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Open some windows and do undoCloseWindow. This should prevent any
|
||||
* restoring later in the test
|
||||
*
|
||||
* @note: Non-Mac only
|
||||
*
|
||||
* Should do the following:
|
||||
* 1. Open two browser windows and close them again
|
||||
* 2. undoCloseWindow() one
|
||||
* 3. Open another browser window
|
||||
* 4. Make sure nothing at all is restored
|
||||
*/
|
||||
add_task(function* test_open_close_restore_from_popup() {
|
||||
if (IS_MAC) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield setupTest({}, function*(newWin, obs) {
|
||||
let newWin2 = yield promiseNewWindowLoaded();
|
||||
yield injectTestTabs(newWin2);
|
||||
|
||||
let closed = yield closeWindowForRestoration(newWin);
|
||||
ok(closed, "Should be able to close the window");
|
||||
closed = yield closeWindowForRestoration(newWin2);
|
||||
ok(closed, "Should be able to close the window");
|
||||
|
||||
let counts = getBrowserWindowsCount();
|
||||
is(counts.open, 0, "Got right number of open windows");
|
||||
is(counts.winstates, 1, "Got right number of window states");
|
||||
|
||||
newWin = undoCloseWindow(0);
|
||||
yield BrowserTestUtils.waitForEvent(newWin, "load");
|
||||
|
||||
// Make sure we wait until this window is restored.
|
||||
yield BrowserTestUtils.waitForEvent(newWin.gBrowser.tabContainer,
|
||||
"SSTabRestored");
|
||||
|
||||
newWin2 = yield promiseNewWindowLoaded();
|
||||
|
||||
is(newWin2.gBrowser.browsers.length, 1,
|
||||
"Did not restore, as undoCloseWindow() was last called");
|
||||
is(TEST_URLS.indexOf(newWin2.gBrowser.browsers[0].currentURI.spec), -1,
|
||||
"Did not restore, as undoCloseWindow() was last called (2)");
|
||||
|
||||
counts = getBrowserWindowsCount();
|
||||
is(counts.open, 2, "Got right number of open windows");
|
||||
is(counts.winstates, 3, "Got right number of window states");
|
||||
|
||||
yield BrowserTestUtils.closeWindow(newWin);
|
||||
yield BrowserTestUtils.closeWindow(newWin2);
|
||||
|
||||
counts = getBrowserWindowsCount();
|
||||
is(counts.open, 0, "Got right number of open windows");
|
||||
is(counts.winstates, 1, "Got right number of window states");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Test if closing can be denied on Mac.
|
||||
* @note: Mac only
|
||||
*/
|
||||
add_task(function* test_mac_notifications() {
|
||||
if (!IS_MAC) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield setupTest({ denyFirst: true }, function*(newWin, obs) {
|
||||
let closed = yield closeWindowForRestoration(newWin);
|
||||
ok(!closed, "First close attempt should be denied");
|
||||
closed = yield closeWindowForRestoration(newWin);
|
||||
ok(closed, "Second close attempt should be granted");
|
||||
|
||||
// We tried closing once, and got denied. Then we tried again and
|
||||
// succeeded. That means 2 close requests, and 1 close granted.
|
||||
is(obs["browser-lastwindow-close-requested"], 2,
|
||||
"Got expected browser-lastwindow-close-requested notifications");
|
||||
is(obs["browser-lastwindow-close-granted"], 1,
|
||||
"Got expected browser-lastwindow-close-granted notifications");
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
// make sure that the next closed tab will increase getClosedTabCount
|
||||
let max_tabs_undo = gPrefService.getIntPref("browser.sessionstore.max_tabs_undo");
|
||||
gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", max_tabs_undo + 1);
|
||||
registerCleanupFunction(() => gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo"));
|
||||
|
||||
// Empty the list of closed tabs.
|
||||
while (ss.getClosedTabCount(window)) {
|
||||
ss.forgetClosedTab(window, 0);
|
||||
}
|
||||
|
||||
// restore a blank tab
|
||||
let tab = gBrowser.addTab("about:");
|
||||
yield promiseBrowserLoaded(tab.linkedBrowser);
|
||||
|
||||
let count = yield promiseSHistoryCount(tab.linkedBrowser);
|
||||
ok(count >= 1, "the new tab does have at least one history entry");
|
||||
|
||||
yield promiseTabState(tab, {entries: []});
|
||||
|
||||
// We may have a different sessionHistory object if the tab
|
||||
// switched from non-remote to remote.
|
||||
count = yield promiseSHistoryCount(tab.linkedBrowser);
|
||||
is(count, 0, "the tab was restored without any history whatsoever");
|
||||
|
||||
yield promiseRemoveTab(tab);
|
||||
is(ss.getClosedTabCount(window), 0,
|
||||
"The closed blank tab wasn't added to Recently Closed Tabs");
|
||||
});
|
||||
|
||||
function promiseSHistoryCount(browser) {
|
||||
return ContentTask.spawn(browser, null, function* () {
|
||||
return docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory.count;
|
||||
});
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const URL = "about:config";
|
||||
|
||||
/**
|
||||
* Bug 393716 - Basic tests for getTabState(), setTabState(), and duplicateTab().
|
||||
*/
|
||||
add_task(function test_set_tabstate() {
|
||||
let key = "Unique key: " + Date.now();
|
||||
let value = "Unique value: " + Math.random();
|
||||
|
||||
// create a new tab
|
||||
let tab = gBrowser.addTab(URL);
|
||||
ss.setTabValue(tab, key, value);
|
||||
yield promiseBrowserLoaded(tab.linkedBrowser);
|
||||
|
||||
// get the tab's state
|
||||
yield TabStateFlusher.flush(tab.linkedBrowser);
|
||||
let state = ss.getTabState(tab);
|
||||
ok(state, "get the tab's state");
|
||||
|
||||
// verify the tab state's integrity
|
||||
state = JSON.parse(state);
|
||||
ok(state instanceof Object && state.entries instanceof Array && state.entries.length > 0,
|
||||
"state object seems valid");
|
||||
ok(state.entries.length == 1 && state.entries[0].url == URL,
|
||||
"Got the expected state object (test URL)");
|
||||
ok(state.extData && state.extData[key] == value,
|
||||
"Got the expected state object (test manually set tab value)");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(function test_set_tabstate_and_duplicate() {
|
||||
let key2 = "key2";
|
||||
let value2 = "Value " + Math.random();
|
||||
let value3 = "Another value: " + Date.now();
|
||||
let state = { entries: [{ url: URL }], extData: { key2: value2 } };
|
||||
|
||||
// create a new tab
|
||||
let tab = gBrowser.addTab();
|
||||
// set the tab's state
|
||||
ss.setTabState(tab, JSON.stringify(state));
|
||||
yield promiseBrowserLoaded(tab.linkedBrowser);
|
||||
|
||||
// verify the correctness of the restored tab
|
||||
ok(ss.getTabValue(tab, key2) == value2 && tab.linkedBrowser.currentURI.spec == URL,
|
||||
"the tab's state was correctly restored");
|
||||
|
||||
// add text data
|
||||
yield setInputValue(tab.linkedBrowser, {id: "textbox", value: value3});
|
||||
|
||||
// duplicate the tab
|
||||
let tab2 = ss.duplicateTab(window, tab);
|
||||
yield promiseTabRestored(tab2);
|
||||
|
||||
// verify the correctness of the duplicated tab
|
||||
ok(ss.getTabValue(tab2, key2) == value2 &&
|
||||
tab2.linkedBrowser.currentURI.spec == URL,
|
||||
"correctly duplicated the tab's state");
|
||||
let textbox = yield getInputValue(tab2.linkedBrowser, {id: "textbox"});
|
||||
is(textbox, value3, "also duplicated text data");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab2);
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URL = "data:text/html;charset=utf-8,<input%20id=txt>" +
|
||||
"<input%20type=checkbox%20id=chk>";
|
||||
|
||||
Cu.import("resource:///modules/sessionstore/SessionStore.jsm");
|
||||
|
||||
/**
|
||||
* This test ensures that closing a window is a reversible action. We will
|
||||
* close the the window, restore it and check that all data has been restored.
|
||||
* This includes window-specific data as well as form data for tabs.
|
||||
*/
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let uniqueKey = "bug 394759";
|
||||
let uniqueValue = "unik" + Date.now();
|
||||
let uniqueText = "pi != " + Math.random();
|
||||
|
||||
// Clear the list of closed windows.
|
||||
forgetClosedWindows();
|
||||
|
||||
provideWindow(function onTestURLLoaded(newWin) {
|
||||
newWin.gBrowser.addTab().linkedBrowser.stop();
|
||||
|
||||
// Mark the window with some unique data to be restored later on.
|
||||
ss.setWindowValue(newWin, uniqueKey, uniqueValue);
|
||||
let [txt, chk] = newWin.content.document.querySelectorAll("#txt, #chk");
|
||||
txt.value = uniqueText;
|
||||
|
||||
let browser = newWin.gBrowser.selectedBrowser;
|
||||
setInputChecked(browser, {id: "chk", checked: true}).then(() => {
|
||||
BrowserTestUtils.closeWindow(newWin).then(() => {
|
||||
is(ss.getClosedWindowCount(), 1,
|
||||
"The closed window was added to Recently Closed Windows");
|
||||
|
||||
let data = SessionStore.getClosedWindowData(false);
|
||||
|
||||
// Verify that non JSON serialized data is the same as JSON serialized data.
|
||||
is(JSON.stringify(data), ss.getClosedWindowData(),
|
||||
"Non-serialized data is the same as serialized data")
|
||||
|
||||
ok(data[0].title == TEST_URL && JSON.stringify(data[0]).indexOf(uniqueText) > -1,
|
||||
"The closed window data was stored correctly");
|
||||
|
||||
// Reopen the closed window and ensure its integrity.
|
||||
let newWin2 = ss.undoCloseWindow(0);
|
||||
|
||||
ok(newWin2 instanceof ChromeWindow,
|
||||
"undoCloseWindow actually returned a window");
|
||||
is(ss.getClosedWindowCount(), 0,
|
||||
"The reopened window was removed from Recently Closed Windows");
|
||||
|
||||
// SSTabRestored will fire more than once, so we need to make sure we count them.
|
||||
let restoredTabs = 0;
|
||||
let expectedTabs = data[0].tabs.length;
|
||||
newWin2.addEventListener("SSTabRestored", function sstabrestoredListener(aEvent) {
|
||||
++restoredTabs;
|
||||
info("Restored tab " + restoredTabs + "/" + expectedTabs);
|
||||
if (restoredTabs < expectedTabs) {
|
||||
return;
|
||||
}
|
||||
|
||||
is(restoredTabs, expectedTabs, "Correct number of tabs restored");
|
||||
newWin2.removeEventListener("SSTabRestored", sstabrestoredListener, true);
|
||||
|
||||
is(newWin2.gBrowser.tabs.length, 2,
|
||||
"The window correctly restored 2 tabs");
|
||||
is(newWin2.gBrowser.currentURI.spec, TEST_URL,
|
||||
"The window correctly restored the URL");
|
||||
|
||||
let [txt, chk] = newWin2.content.document.querySelectorAll("#txt, #chk");
|
||||
ok(txt.value == uniqueText && chk.checked,
|
||||
"The window correctly restored the form");
|
||||
is(ss.getWindowValue(newWin2, uniqueKey), uniqueValue,
|
||||
"The window correctly restored the data associated with it");
|
||||
|
||||
// Clean up.
|
||||
BrowserTestUtils.closeWindow(newWin2).then(finish);
|
||||
}, true);
|
||||
});
|
||||
});
|
||||
}, TEST_URL);
|
||||
}
|
||||
|
||||
function setInputChecked(browser, data) {
|
||||
return sendMessage(browser, "ss-test:setInputChecked", data);
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/**
|
||||
* Test helper function that opens a series of windows, closes them
|
||||
* and then checks the closed window data from SessionStore against
|
||||
* expected results.
|
||||
*
|
||||
* @param windowsToOpen (Array)
|
||||
* An array of Objects, where each object must define a single
|
||||
* property "isPopup" for whether or not the opened window should
|
||||
* be a popup.
|
||||
* @param expectedResults (Array)
|
||||
* An Object with two properies: mac and other, where each points
|
||||
* at yet another Object, with the following properties:
|
||||
*
|
||||
* popup (int):
|
||||
* The number of popup windows we expect to be in the closed window
|
||||
* data.
|
||||
* normal (int):
|
||||
* The number of normal windows we expect to be in the closed window
|
||||
* data.
|
||||
* @returns Promise
|
||||
*/
|
||||
function testWindows(windowsToOpen, expectedResults) {
|
||||
return Task.spawn(function*() {
|
||||
for (let winData of windowsToOpen) {
|
||||
let features = "chrome,dialog=no," +
|
||||
(winData.isPopup ? "all=no" : "all");
|
||||
let url = "http://example.com/?window=" + windowsToOpen.length;
|
||||
|
||||
let openWindowPromise = BrowserTestUtils.waitForNewWindow(true, url);
|
||||
openDialog(getBrowserURL(), "", features, url);
|
||||
let win = yield openWindowPromise;
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
}
|
||||
|
||||
let closedWindowData = JSON.parse(ss.getClosedWindowData());
|
||||
let numPopups = closedWindowData.filter(function(el, i, arr) {
|
||||
return el.isPopup;
|
||||
}).length;
|
||||
let numNormal = ss.getClosedWindowCount() - numPopups;
|
||||
// #ifdef doesn't work in browser-chrome tests, so do a simple regex on platform
|
||||
let oResults = navigator.platform.match(/Mac/) ? expectedResults.mac
|
||||
: expectedResults.other;
|
||||
is(numPopups, oResults.popup,
|
||||
"There were " + oResults.popup + " popup windows to reopen");
|
||||
is(numNormal, oResults.normal,
|
||||
"There were " + oResults.normal + " normal windows to repoen");
|
||||
});
|
||||
}
|
||||
|
||||
add_task(function* test_closed_window_states() {
|
||||
// This test takes quite some time, and timeouts frequently, so we require
|
||||
// more time to run.
|
||||
// See Bug 518970.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let windowsToOpen = [{isPopup: false},
|
||||
{isPopup: false},
|
||||
{isPopup: true},
|
||||
{isPopup: true},
|
||||
{isPopup: true}];
|
||||
let expectedResults = {mac: {popup: 3, normal: 0},
|
||||
other: {popup: 3, normal: 1}};
|
||||
|
||||
yield testWindows(windowsToOpen, expectedResults);
|
||||
|
||||
|
||||
let windowsToOpen2 = [{isPopup: false},
|
||||
{isPopup: false},
|
||||
{isPopup: false},
|
||||
{isPopup: false},
|
||||
{isPopup: false}];
|
||||
let expectedResults2 = {mac: {popup: 0, normal: 3},
|
||||
other: {popup: 0, normal: 3}};
|
||||
|
||||
yield testWindows(windowsToOpen2, expectedResults2);
|
||||
});
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TESTS = [
|
||||
{ url: "about:config",
|
||||
key: "bug 394759 Non-PB",
|
||||
value: "uniq" + r() },
|
||||
{ url: "about:mozilla",
|
||||
key: "bug 394759 PB",
|
||||
value: "uniq" + r() },
|
||||
];
|
||||
|
||||
function promiseTestOpenCloseWindow(aIsPrivate, aTest) {
|
||||
return Task.spawn(function*() {
|
||||
let win = yield BrowserTestUtils.openNewBrowserWindow({ "private": aIsPrivate });
|
||||
win.gBrowser.selectedBrowser.loadURI(aTest.url);
|
||||
yield promiseBrowserLoaded(win.gBrowser.selectedBrowser);
|
||||
yield Promise.resolve();
|
||||
// Mark the window with some unique data to be restored later on.
|
||||
ss.setWindowValue(win, aTest.key, aTest.value);
|
||||
yield TabStateFlusher.flushWindow(win);
|
||||
// Close.
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
}
|
||||
|
||||
function promiseTestOnWindow(aIsPrivate, aValue) {
|
||||
return Task.spawn(function*() {
|
||||
let win = yield BrowserTestUtils.openNewBrowserWindow({ "private": aIsPrivate });
|
||||
yield TabStateFlusher.flushWindow(win);
|
||||
let data = JSON.parse(ss.getClosedWindowData())[0];
|
||||
is(ss.getClosedWindowCount(), 1, "Check that the closed window count hasn't changed");
|
||||
ok(JSON.stringify(data).indexOf(aValue) > -1,
|
||||
"Check the closed window data was stored correctly");
|
||||
registerCleanupFunction(() => BrowserTestUtils.closeWindow(win));
|
||||
});
|
||||
}
|
||||
|
||||
add_task(function* init() {
|
||||
forgetClosedWindows();
|
||||
while (ss.getClosedTabCount(window) > 0) {
|
||||
ss.forgetClosedTab(window, 0);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* main() {
|
||||
yield promiseTestOpenCloseWindow(false, TESTS[0]);
|
||||
yield promiseTestOpenCloseWindow(true, TESTS[1]);
|
||||
yield promiseTestOnWindow(false, TESTS[0].value);
|
||||
yield promiseTestOnWindow(true, TESTS[0].value);
|
||||
});
|
||||
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/ForgetAboutSite.jsm");
|
||||
|
||||
function waitForClearHistory(aCallback) {
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(this, "browser:purge-domain-data");
|
||||
setTimeout(aCallback, 0);
|
||||
}
|
||||
};
|
||||
Services.obs.addObserver(observer, "browser:purge-domain-data", false);
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
// utility functions
|
||||
function countClosedTabsByTitle(aClosedTabList, aTitle) {
|
||||
return aClosedTabList.filter(aData => aData.title == aTitle).length;
|
||||
}
|
||||
|
||||
function countOpenTabsByTitle(aOpenTabList, aTitle) {
|
||||
return aOpenTabList.filter(aData => aData.entries.some(aEntry => aEntry.title == aTitle)).length;
|
||||
}
|
||||
|
||||
// backup old state
|
||||
let oldState = ss.getBrowserState();
|
||||
let oldState_wins = JSON.parse(oldState).windows.length;
|
||||
if (oldState_wins != 1)
|
||||
ok(false, "oldState in test_purge has " + oldState_wins + " windows instead of 1");
|
||||
|
||||
// create a new state for testing
|
||||
const REMEMBER = Date.now(), FORGET = Math.random();
|
||||
let testState = {
|
||||
windows: [ { tabs: [{ entries: [{ url: "http://example.com/" }] }], selected: 1 } ],
|
||||
_closedWindows : [
|
||||
// _closedWindows[0]
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.com/", title: REMEMBER }] },
|
||||
{ entries: [{ url: "http://mozilla.org/", title: FORGET }] }
|
||||
],
|
||||
selected: 2,
|
||||
title: "mozilla.org",
|
||||
_closedTabs: []
|
||||
},
|
||||
// _closedWindows[1]
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://mozilla.org/", title: FORGET }] },
|
||||
{ entries: [{ url: "http://example.com/", title: REMEMBER }] },
|
||||
{ entries: [{ url: "http://example.com/", title: REMEMBER }] },
|
||||
{ entries: [{ url: "http://mozilla.org/", title: FORGET }] },
|
||||
{ entries: [{ url: "http://example.com/", title: REMEMBER }] }
|
||||
],
|
||||
selected: 5,
|
||||
_closedTabs: []
|
||||
},
|
||||
// _closedWindows[2]
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.com/", title: REMEMBER }] }
|
||||
],
|
||||
selected: 1,
|
||||
_closedTabs: [
|
||||
{
|
||||
state: {
|
||||
entries: [
|
||||
{ url: "http://mozilla.org/", title: FORGET },
|
||||
{ url: "http://mozilla.org/again", title: "doesn't matter" }
|
||||
]
|
||||
},
|
||||
pos: 1,
|
||||
title: FORGET
|
||||
},
|
||||
{
|
||||
state: {
|
||||
entries: [
|
||||
{ url: "http://example.com", title: REMEMBER }
|
||||
]
|
||||
},
|
||||
title: REMEMBER
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// set browser to test state
|
||||
ss.setBrowserState(JSON.stringify(testState));
|
||||
|
||||
// purge domain & check that we purged correctly for closed windows
|
||||
ForgetAboutSite.removeDataFromDomain("mozilla.org");
|
||||
waitForClearHistory(function() {
|
||||
let closedWindowData = JSON.parse(ss.getClosedWindowData());
|
||||
|
||||
// First set of tests for _closedWindows[0] - tests basics
|
||||
let win = closedWindowData[0];
|
||||
is(win.tabs.length, 1, "1 tab was removed");
|
||||
is(countOpenTabsByTitle(win.tabs, FORGET), 0,
|
||||
"The correct tab was removed");
|
||||
is(countOpenTabsByTitle(win.tabs, REMEMBER), 1,
|
||||
"The correct tab was remembered");
|
||||
is(win.selected, 1, "Selected tab has changed");
|
||||
is(win.title, REMEMBER, "The window title was correctly updated");
|
||||
|
||||
// Test more complicated case
|
||||
win = closedWindowData[1];
|
||||
is(win.tabs.length, 3, "2 tabs were removed");
|
||||
is(countOpenTabsByTitle(win.tabs, FORGET), 0,
|
||||
"The correct tabs were removed");
|
||||
is(countOpenTabsByTitle(win.tabs, REMEMBER), 3,
|
||||
"The correct tabs were remembered");
|
||||
is(win.selected, 3, "Selected tab has changed");
|
||||
is(win.title, REMEMBER, "The window title was correctly updated");
|
||||
|
||||
// Tests handling of _closedTabs
|
||||
win = closedWindowData[2];
|
||||
is(countClosedTabsByTitle(win._closedTabs, REMEMBER), 1,
|
||||
"The correct number of tabs were removed, and the correct ones");
|
||||
is(countClosedTabsByTitle(win._closedTabs, FORGET), 0,
|
||||
"All tabs to be forgotten were indeed removed");
|
||||
|
||||
// restore pre-test state
|
||||
ss.setBrowserState(oldState);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Tests that cookies are stored and restored correctly
|
||||
* by sessionstore (bug 423132).
|
||||
*/
|
||||
add_task(function*() {
|
||||
const testURL = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser_423132_sample.html";
|
||||
|
||||
Services.cookies.removeAll();
|
||||
// make sure that sessionstore.js can be forced to be created by setting
|
||||
// the interval pref to 0
|
||||
yield SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.sessionstore.interval", 0]]
|
||||
});
|
||||
|
||||
let win = yield BrowserTestUtils.openNewBrowserWindow();
|
||||
let browser = win.gBrowser.selectedBrowser;
|
||||
browser.loadURI(testURL);
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
yield TabStateFlusher.flush(browser);
|
||||
|
||||
// get the sessionstore state for the window
|
||||
let state = ss.getWindowState(win);
|
||||
|
||||
// verify our cookie got set during pageload
|
||||
let enumerator = Services.cookies.enumerator;
|
||||
let cookie;
|
||||
let i = 0;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
|
||||
i++;
|
||||
}
|
||||
Assert.equal(i, 1, "expected one cookie");
|
||||
|
||||
// remove the cookie
|
||||
Services.cookies.removeAll();
|
||||
|
||||
// restore the window state
|
||||
ss.setWindowState(win, state, true);
|
||||
|
||||
// at this point, the cookie should be restored...
|
||||
enumerator = Services.cookies.enumerator;
|
||||
let cookie2;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
cookie2 = enumerator.getNext().QueryInterface(Ci.nsICookie);
|
||||
if (cookie.name == cookie2.name)
|
||||
break;
|
||||
}
|
||||
is(cookie.name, cookie2.name, "cookie name successfully restored");
|
||||
is(cookie.value, cookie2.value, "cookie value successfully restored");
|
||||
is(cookie.path, cookie2.path, "cookie path successfully restored");
|
||||
|
||||
// clean up
|
||||
Services.cookies.removeAll();
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script type="text/javascript">
|
||||
// generate an enormous random number...
|
||||
var r = Math.floor(Math.random() * Math.pow(2, 62)).toString();
|
||||
|
||||
// ... and use it to set a randomly named cookie
|
||||
document.cookie = r + "=value; path=/ohai";
|
||||
</script>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 447951 **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
const baseURL = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser_447951_sample.html#";
|
||||
|
||||
// Make sure the functionality added in bug 943339 doesn't affect the results
|
||||
gPrefService.setIntPref("browser.sessionstore.max_serialize_back", -1);
|
||||
gPrefService.setIntPref("browser.sessionstore.max_serialize_forward", -1);
|
||||
registerCleanupFunction(function () {
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_serialize_back");
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_serialize_forward");
|
||||
});
|
||||
|
||||
let tab = gBrowser.addTab();
|
||||
promiseBrowserLoaded(tab.linkedBrowser).then(() => {
|
||||
let tabState = { entries: [] };
|
||||
let max_entries = gPrefService.getIntPref("browser.sessionhistory.max_entries");
|
||||
for (let i = 0; i < max_entries; i++)
|
||||
tabState.entries.push({ url: baseURL + i });
|
||||
|
||||
promiseTabState(tab, tabState).then(() => {
|
||||
return TabStateFlusher.flush(tab.linkedBrowser);
|
||||
}).then(() => {
|
||||
tabState = JSON.parse(ss.getTabState(tab));
|
||||
is(tabState.entries.length, max_entries, "session history filled to the limit");
|
||||
is(tabState.entries[0].url, baseURL + 0, "... but not more");
|
||||
|
||||
// visit yet another anchor (appending it to session history)
|
||||
ContentTask.spawn(tab.linkedBrowser, null, function() {
|
||||
content.window.document.querySelector("a").click();
|
||||
}).then(flushAndCheck);
|
||||
|
||||
function flushAndCheck() {
|
||||
TabStateFlusher.flush(tab.linkedBrowser).then(check);
|
||||
}
|
||||
|
||||
function check() {
|
||||
tabState = JSON.parse(ss.getTabState(tab));
|
||||
if (tab.linkedBrowser.currentURI.spec != baseURL + "end") {
|
||||
// It may take a few passes through the event loop before we
|
||||
// get the right URL.
|
||||
executeSoon(flushAndCheck);
|
||||
return;
|
||||
}
|
||||
|
||||
is(tab.linkedBrowser.currentURI.spec, baseURL + "end",
|
||||
"the new anchor was loaded");
|
||||
is(tabState.entries[tabState.entries.length - 1].url, baseURL + "end",
|
||||
"... and ignored");
|
||||
is(tabState.entries[0].url, baseURL + 1,
|
||||
"... and the first item was removed");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Testcase for bug 447951</title>
|
||||
|
||||
<a href="#end">click me</a>
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const URL = ROOT + "browser_454908_sample.html";
|
||||
const PASS = "pwd-" + Math.random();
|
||||
|
||||
/**
|
||||
* Bug 454908 - Don't save/restore values of password fields.
|
||||
*/
|
||||
add_task(function* test_dont_save_passwords() {
|
||||
// Make sure we do save form data.
|
||||
Services.prefs.clearUserPref("browser.sessionstore.privacy_level");
|
||||
|
||||
// Add a tab with a password field.
|
||||
let tab = gBrowser.addTab(URL);
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseBrowserLoaded(browser);
|
||||
|
||||
// Fill in some values.
|
||||
let usernameValue = "User " + Math.random();
|
||||
yield setInputValue(browser, {id: "username", value: usernameValue});
|
||||
yield setInputValue(browser, {id: "passwd", value: PASS});
|
||||
|
||||
// Close and restore the tab.
|
||||
yield promiseRemoveTab(tab);
|
||||
tab = ss.undoCloseTab(window, 0);
|
||||
browser = tab.linkedBrowser;
|
||||
yield promiseTabRestored(tab);
|
||||
|
||||
// Check that password fields aren't saved/restored.
|
||||
let username = yield getInputValue(browser, {id: "username"});
|
||||
is(username, usernameValue, "username was saved/restored");
|
||||
let passwd = yield getInputValue(browser, {id: "passwd"});
|
||||
is(passwd, "", "password wasn't saved/restored");
|
||||
|
||||
// Write to disk and read our file.
|
||||
yield forceSaveState();
|
||||
yield promiseForEachSessionRestoreFile((state, key) =>
|
||||
// Ensure that we have not saved our password.
|
||||
ok(!state.includes(PASS), "password has not been written to file " + key)
|
||||
);
|
||||
|
||||
// Cleanup.
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
||||
<title>Test for bug 454908</title>
|
||||
|
||||
<h3>Dummy Login</h3>
|
||||
<form>
|
||||
<p>Username: <input type="text" id="username">
|
||||
<p>Password: <input type="password" id="passwd">
|
||||
</form>
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const URL = ROOT + "browser_456342_sample.xhtml";
|
||||
|
||||
/**
|
||||
* Bug 456342 - Restore values from non-standard input field types.
|
||||
*/
|
||||
add_task(function test_restore_nonstandard_input_values() {
|
||||
// Add tab with various non-standard input field types.
|
||||
let tab = gBrowser.addTab(URL);
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseBrowserLoaded(browser);
|
||||
|
||||
// Fill in form values.
|
||||
let expectedValue = Math.random();
|
||||
yield setFormElementValues(browser, {value: expectedValue});
|
||||
|
||||
// Remove tab and check collected form data.
|
||||
yield promiseRemoveTab(tab);
|
||||
let undoItems = JSON.parse(ss.getClosedTabData(window));
|
||||
let savedFormData = undoItems[0].state.formdata;
|
||||
|
||||
let countGood = 0, countBad = 0;
|
||||
for (let id of Object.keys(savedFormData.id)) {
|
||||
if (savedFormData.id[id] == expectedValue) {
|
||||
countGood++;
|
||||
} else {
|
||||
countBad++;
|
||||
}
|
||||
}
|
||||
|
||||
for (let exp of Object.keys(savedFormData.xpath)) {
|
||||
if (savedFormData.xpath[exp] == expectedValue) {
|
||||
countGood++;
|
||||
} else {
|
||||
countBad++;
|
||||
}
|
||||
}
|
||||
|
||||
is(countGood, 4, "Saved text for non-standard input fields");
|
||||
is(countBad, 0, "Didn't save text for ignored field types");
|
||||
});
|
||||
|
||||
function setFormElementValues(browser, data) {
|
||||
return sendMessage(browser, "ss-test:setFormElementValues", data);
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head><title>Test for bug 456342</title></head>
|
||||
|
||||
<body>
|
||||
<form>
|
||||
<h3>Non-standard <input>s</h3>
|
||||
<p>Search <input type="search" id="searchTerm"/></p>
|
||||
<p>Image Search: <input type="image search" /></p>
|
||||
<p>Autocomplete: <input type="autocomplete" name="fill-in"/></p>
|
||||
<p>Mistyped: <input type="txet" name="mistyped"/></p>
|
||||
|
||||
<h3>Ignored types</h3>
|
||||
<input type="hidden" name="hideme"/>
|
||||
<input type="HIDDEN" name="hideme2"/>
|
||||
<input type="submit" name="submit"/>
|
||||
<input type="reset" name="reset"/>
|
||||
<input type="image" name="image"/>
|
||||
<input type="button" name="button"/>
|
||||
<input type="password" name="password"/>
|
||||
<input type="PassWord" name="password2"/>
|
||||
<input type="PASSWORD" name="password3"/>
|
||||
<input autocomplete="off" name="auto1"/>
|
||||
<input type="text" autocomplete="OFF" name="auto2"/>
|
||||
<textarea autocomplete="off" name="auto3"/>
|
||||
<select autocomplete="off" name="auto4">
|
||||
<option value="1" selected="true"/>
|
||||
<option value="2"/>
|
||||
<option value="3"/>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 459906 **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
let testURL = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser_459906_sample.html";
|
||||
let uniqueValue = "<b>Unique:</b> " + Date.now();
|
||||
|
||||
var frameCount = 0;
|
||||
let tab = gBrowser.addTab(testURL);
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
// wait for all frames to load completely
|
||||
if (frameCount++ < 2)
|
||||
return;
|
||||
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
let iframes = tab.linkedBrowser.contentWindow.frames;
|
||||
iframes[1].document.body.innerHTML = uniqueValue;
|
||||
|
||||
frameCount = 0;
|
||||
let tab2 = gBrowser.duplicateTab(tab);
|
||||
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
// wait for all frames to load (and reload!) completely
|
||||
if (frameCount++ < 2)
|
||||
return;
|
||||
tab2.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
executeSoon(function() {
|
||||
let iframes = tab2.linkedBrowser.contentWindow.frames;
|
||||
if (iframes[1].document.body.innerHTML !== uniqueValue) {
|
||||
// Poll again the value, since we can't ensure to run
|
||||
// after SessionStore has injected innerHTML value.
|
||||
// See bug 521802.
|
||||
info("Polling for innerHTML value");
|
||||
setTimeout(arguments.callee, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
is(iframes[1].document.body.innerHTML, uniqueValue,
|
||||
"rich textarea's content correctly duplicated");
|
||||
|
||||
let innerDomain = null;
|
||||
try {
|
||||
innerDomain = iframes[0].document.domain;
|
||||
}
|
||||
catch (ex) { /* throws for chrome: documents */ }
|
||||
is(innerDomain, "mochi.test", "XSS exploit prevented!");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab2);
|
||||
gBrowser.removeTab(tab);
|
||||
|
||||
finish();
|
||||
});
|
||||
}, true);
|
||||
}, true);
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<title>Cross Domain File for bug 459906</title>
|
||||
|
||||
cheers from localhost
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
<!-- Testcase originally by David Bloom <bloom@google.com> -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<title>Test for bug 459906</title>
|
||||
|
||||
<body>
|
||||
<iframe src="data:text/html;charset=utf-8,not_on_localhost"></iframe>
|
||||
<iframe></iframe>
|
||||
|
||||
<script type="application/javascript">
|
||||
var loadCount = 0;
|
||||
frames[0].addEventListener("DOMContentLoaded", handleLoad, false);
|
||||
frames[1].addEventListener("DOMContentLoaded", handleLoad, false);
|
||||
function handleLoad() {
|
||||
if (++loadCount < 2)
|
||||
return;
|
||||
frames[0].removeEventListener("DOMContentLoaded", handleLoad, false);
|
||||
frames[1].removeEventListener("DOMContentLoaded", handleLoad, false);
|
||||
frames[0].document.designMode = "on";
|
||||
frames[0].document.__defineGetter__("designMode", function() {
|
||||
// inject a cross domain file ...
|
||||
var documentInjected = false;
|
||||
document.getElementsByTagName("iframe")[0].onload =
|
||||
function() { documentInjected = true; };
|
||||
frames[0].location = "browser_459906_empty.html";
|
||||
|
||||
// ... and ensure that it has time to load
|
||||
for (var c = 0; !documentInjected && c < 20; c++) {
|
||||
var r = new XMLHttpRequest();
|
||||
r.open("GET", location.href, false);
|
||||
r.overrideMimeType("text/plain");
|
||||
r.send(null);
|
||||
}
|
||||
|
||||
return "on";
|
||||
});
|
||||
|
||||
frames[1].document.designMode = "on";
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Cu.import("resource:///modules/sessionstore/SessionStore.jsm");
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 461634 **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
const REMEMBER = Date.now(), FORGET = Math.random();
|
||||
let test_state = { windows: [{ "tabs": [{ "entries": [] }], _closedTabs: [
|
||||
{ state: { entries: [{ url: "http://www.example.net/" }] }, title: FORGET },
|
||||
{ state: { entries: [{ url: "http://www.example.net/" }] }, title: REMEMBER },
|
||||
{ state: { entries: [{ url: "http://www.example.net/" }] }, title: FORGET },
|
||||
{ state: { entries: [{ url: "http://www.example.net/" }] }, title: REMEMBER },
|
||||
] }] };
|
||||
let remember_count = 2;
|
||||
|
||||
function countByTitle(aClosedTabList, aTitle) {
|
||||
return aClosedTabList.filter(aData => aData.title == aTitle).length;
|
||||
}
|
||||
|
||||
function testForError(aFunction) {
|
||||
try {
|
||||
aFunction();
|
||||
return false;
|
||||
}
|
||||
catch (ex) {
|
||||
return ex.name == "NS_ERROR_ILLEGAL_VALUE";
|
||||
}
|
||||
}
|
||||
|
||||
// Open a window and add the above closed tab list.
|
||||
let newWin = openDialog(location, "", "chrome,all,dialog=no");
|
||||
promiseWindowLoaded(newWin).then(() => {
|
||||
gPrefService.setIntPref("browser.sessionstore.max_tabs_undo",
|
||||
test_state.windows[0]._closedTabs.length);
|
||||
ss.setWindowState(newWin, JSON.stringify(test_state), true);
|
||||
|
||||
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")
|
||||
|
||||
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");
|
||||
|
||||
// Remove third tab, then first tab.
|
||||
ss.forgetClosedTab(newWin, 2);
|
||||
ss.forgetClosedTab(newWin, null);
|
||||
|
||||
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")
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 461743 **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
let testURL = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser_461743_sample.html";
|
||||
|
||||
let frameCount = 0;
|
||||
let tab = gBrowser.addTab(testURL);
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
// Wait for all frames to load completely.
|
||||
if (frameCount++ < 2)
|
||||
return;
|
||||
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
let tab2 = gBrowser.duplicateTab(tab);
|
||||
tab2.linkedBrowser.addEventListener("461743", function(aEvent) {
|
||||
tab2.linkedBrowser.removeEventListener("461743", arguments.callee, true);
|
||||
is(aEvent.data, "done", "XSS injection was attempted");
|
||||
|
||||
executeSoon(function() {
|
||||
let iframes = tab2.linkedBrowser.contentWindow.frames;
|
||||
let innerHTML = iframes[1].document.body.innerHTML;
|
||||
isnot(innerHTML, Components.utils.reportError.toString(),
|
||||
"chrome access denied!");
|
||||
|
||||
// Clean up.
|
||||
gBrowser.removeTab(tab2);
|
||||
gBrowser.removeTab(tab);
|
||||
|
||||
finish();
|
||||
});
|
||||
}, true, true);
|
||||
}, true);
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<title>Test for bug 461743</title>
|
||||
|
||||
<body>
|
||||
<iframe src="data:text/html;charset=utf-8,empty"></iframe>
|
||||
<iframe></iframe>
|
||||
|
||||
<script type="application/javascript">
|
||||
var chromeUrl = "chrome://global/content/mozilla.xhtml";
|
||||
var exploitUrl = "javascript:try { document.body.innerHTML = Components.utils.reportError; } catch (ex) { }";
|
||||
|
||||
var loadCount = 0;
|
||||
frames[0].addEventListener("DOMContentLoaded", handleLoad, false);
|
||||
frames[1].addEventListener("DOMContentLoaded", handleLoad, false);
|
||||
function handleLoad() {
|
||||
if (++loadCount < 2)
|
||||
return;
|
||||
frames[0].removeEventListener("DOMContentLoaded", handleLoad, false);
|
||||
frames[1].removeEventListener("DOMContentLoaded", handleLoad, false);
|
||||
|
||||
var flip = 0;
|
||||
MutationEvent.prototype.toString = function() {
|
||||
return flip++ == 0 ? chromeUrl : exploitUrl;
|
||||
};
|
||||
|
||||
var href = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(frames[1].location), "href").get;
|
||||
var loadChrome = { handleEvent: href };
|
||||
var loadExploit = { handleEvent: href };
|
||||
|
||||
function delay() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", location.href, false);
|
||||
xhr.send(null);
|
||||
}
|
||||
function done() {
|
||||
var event = new MessageEvent('461743', { bubbles: true, cancelable: false,
|
||||
data: "done", origin: location.href,
|
||||
source: window });
|
||||
document.dispatchEvent(event);
|
||||
frames[0].document.removeEventListener("DOMNodeInserted", loadChrome, true);
|
||||
frames[0].document.removeEventListener("DOMNodeInserted", delay, true);
|
||||
frames[0].document.removeEventListener("DOMNodeInserted", loadExploit, true);
|
||||
frames[0].document.removeEventListener("DOMNodeInserted", done, true);
|
||||
}
|
||||
|
||||
frames[0].document.addEventListener("DOMNodeInserted", loadChrome, true);
|
||||
frames[0].document.addEventListener("DOMNodeInserted", delay, true);
|
||||
frames[0].document.addEventListener("DOMNodeInserted", loadExploit, true);
|
||||
frames[0].document.addEventListener("DOMNodeInserted", done, true);
|
||||
|
||||
frames[0].document.designMode = "on";
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const URL = ROOT + "browser_463205_sample.html";
|
||||
|
||||
/**
|
||||
* Bug 463205 - Check URLs before restoring form data to make sure a malicious
|
||||
* website can't modify frame URLs and make us inject form data into the wrong
|
||||
* web pages.
|
||||
*/
|
||||
add_task(function test_check_urls_before_restoring() {
|
||||
// Add a blank tab.
|
||||
let tab = gBrowser.addTab("about:blank");
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseBrowserLoaded(browser);
|
||||
|
||||
// Restore form data with a valid URL.
|
||||
yield promiseTabState(tab, getState(URL));
|
||||
|
||||
let value = yield getInputValue(browser, {id: "text"});
|
||||
is(value, "foobar", "value was restored");
|
||||
|
||||
// Restore form data with an invalid URL.
|
||||
yield promiseTabState(tab, getState("http://example.com/"));
|
||||
|
||||
value = yield getInputValue(browser, {id: "text"});
|
||||
is(value, "", "value was not restored");
|
||||
|
||||
// Cleanup.
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
function getState(url) {
|
||||
return JSON.stringify({
|
||||
entries: [{url: URL}],
|
||||
formdata: {url: url, id: {text: "foobar"}}
|
||||
});
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>bug 463205</title>
|
||||
|
||||
<body>
|
||||
<input type="text" id="text" />
|
||||
</body>
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URL = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser_463206_sample.html";
|
||||
|
||||
add_task(function* () {
|
||||
// Add a new tab.
|
||||
let tab = gBrowser.addTab(TEST_URL);
|
||||
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
|
||||
|
||||
// "Type in" some random values.
|
||||
yield ContentTask.spawn(tab.linkedBrowser, null, function* () {
|
||||
function typeText(aTextField, aValue) {
|
||||
aTextField.value = aValue;
|
||||
|
||||
let event = aTextField.ownerDocument.createEvent("UIEvents");
|
||||
event.initUIEvent("input", true, true, aTextField.ownerGlobal, 0);
|
||||
aTextField.dispatchEvent(event);
|
||||
}
|
||||
|
||||
typeText(content.document.getElementById("out1"), Date.now());
|
||||
typeText(content.document.getElementsByName("1|#out2")[0], Math.random());
|
||||
typeText(content.frames[0].frames[1].document.getElementById("in1"), new Date());
|
||||
});
|
||||
|
||||
// Duplicate the tab.
|
||||
let tab2 = gBrowser.duplicateTab(tab);
|
||||
yield promiseTabRestored(tab2);
|
||||
|
||||
// Query a few values from the top and its child frames.
|
||||
yield ContentTask.spawn(tab2.linkedBrowser, null, function* () {
|
||||
Assert.notEqual(content.document.getElementById("out1").value,
|
||||
content.frames[1].document.getElementById("out1").value,
|
||||
"text isn't reused for frames");
|
||||
Assert.notEqual(content.document.getElementsByName("1|#out2")[0].value,
|
||||
"", "text containing | and # is correctly restored");
|
||||
Assert.equal(content.frames[1].document.getElementById("out2").value,
|
||||
"", "id prefixes can't be faked");
|
||||
// Disabled for now, Bug 588077
|
||||
//Assert.equal(content.frames[0].frames[1].document.getElementById("in1").value,
|
||||
// "", "id prefixes aren't mixed up");
|
||||
Assert.equal(content.frames[1].frames[0].document.getElementById("in1").value,
|
||||
"", "id prefixes aren't mixed up");
|
||||
});
|
||||
|
||||
// Cleanup.
|
||||
gBrowser.removeTab(tab2);
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for bug 463206</title>
|
||||
|
||||
<iframe src="data:text/html;charset=utf-8,<iframe></iframe><iframe%20src='data:text/html;charset=utf-8,<input%2520id=%2522in1%2522>'></iframe>"></iframe>
|
||||
<iframe src="data:text/html;charset=utf-8,<input%20id='out1'><input%20id='out2'><iframe%20src='data:text/html;charset=utf-8,<input%2520id=%2522in1%2522>'>"></iframe>
|
||||
|
||||
<input id="out1">
|
||||
<input name="1|#out2">
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/ForgetAboutSite.jsm");
|
||||
|
||||
function waitForClearHistory(aCallback) {
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(this, "browser:purge-domain-data");
|
||||
setTimeout(aCallback, 0);
|
||||
}
|
||||
};
|
||||
Services.obs.addObserver(observer, "browser:purge-domain-data", false);
|
||||
}
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 464199 **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
const REMEMBER = Date.now(), FORGET = Math.random();
|
||||
let test_state = { windows: [{ "tabs": [{ "entries": [] }], _closedTabs: [
|
||||
{ state: { entries: [{ url: "http://www.example.net/" }] }, title: FORGET },
|
||||
{ state: { entries: [{ url: "http://www.example.org/" }] }, title: REMEMBER },
|
||||
{ state: { entries: [{ url: "http://www.example.net/" },
|
||||
{ url: "http://www.example.org/" }] }, title: FORGET },
|
||||
{ state: { entries: [{ url: "http://example.net/" }] }, title: FORGET },
|
||||
{ state: { entries: [{ url: "http://sub.example.net/" }] }, title: FORGET },
|
||||
{ state: { entries: [{ url: "http://www.example.net:8080/" }] }, title: FORGET },
|
||||
{ state: { entries: [{ url: "about:license" }] }, title: REMEMBER },
|
||||
{ state: { entries: [{ url: "http://www.example.org/frameset",
|
||||
children: [
|
||||
{ url: "http://www.example.org/frame" },
|
||||
{ url: "http://www.example.org:8080/frame2" }
|
||||
] }] }, title: REMEMBER },
|
||||
{ state: { entries: [{ url: "http://www.example.org/frameset",
|
||||
children: [
|
||||
{ url: "http://www.example.org/frame" },
|
||||
{ url: "http://www.example.net/frame" }
|
||||
] }] }, title: FORGET },
|
||||
{ state: { entries: [{ url: "http://www.example.org/form",
|
||||
formdata: { id: { "url": "http://www.example.net/" } }
|
||||
}] }, title: REMEMBER },
|
||||
{ state: { entries: [{ url: "http://www.example.org/form" }],
|
||||
extData: { "setTabValue": "http://example.net:80" } }, title: REMEMBER }
|
||||
] }] };
|
||||
let remember_count = 5;
|
||||
|
||||
function countByTitle(aClosedTabList, aTitle) {
|
||||
return aClosedTabList.filter(aData => aData.title == aTitle).length;
|
||||
}
|
||||
|
||||
// open a window and add the above closed tab list
|
||||
let newWin = openDialog(location, "", "chrome,all,dialog=no");
|
||||
promiseWindowLoaded(newWin).then(() => {
|
||||
gPrefService.setIntPref("browser.sessionstore.max_tabs_undo",
|
||||
test_state.windows[0]._closedTabs.length);
|
||||
ss.setWindowState(newWin, JSON.stringify(test_state), true);
|
||||
|
||||
let closedTabs = JSON.parse(ss.getClosedTabData(newWin));
|
||||
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.");
|
||||
|
||||
ForgetAboutSite.removeDataFromDomain("example.net");
|
||||
waitForClearHistory(function() {
|
||||
closedTabs = JSON.parse(ss.getClosedTabData(newWin));
|
||||
is(closedTabs.length, remember_count,
|
||||
"The correct amout of tabs was removed");
|
||||
is(countByTitle(closedTabs, FORGET), 0,
|
||||
"All tabs to be forgotten were indeed removed");
|
||||
is(countByTitle(closedTabs, REMEMBER), remember_count,
|
||||
"... and tabs to be remembered weren't.");
|
||||
|
||||
// clean up
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
|
||||
BrowserTestUtils.closeWindow(newWin).then(finish);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
|
||||
|
||||
<title>Test for bug 464620 (injection on input)</title>
|
||||
|
||||
<iframe></iframe>
|
||||
<iframe onload="setup()"></iframe>
|
||||
|
||||
<script>
|
||||
var targetUrl = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser_464620_xd.html";
|
||||
var firstPass;
|
||||
|
||||
function setup() {
|
||||
if (firstPass !== undefined)
|
||||
return;
|
||||
firstPass = frames[1].location.href == "about:blank";
|
||||
if (firstPass) {
|
||||
frames[0].location = 'data:text/html;charset=utf-8,<body onload="if (parent.firstPass) parent.step();"><input id="x" oninput="parent.xss()">XXX</body>';
|
||||
}
|
||||
frames[1].location = targetUrl;
|
||||
}
|
||||
|
||||
function step() {
|
||||
var x = frames[0].document.getElementById("x");
|
||||
if (x.value == "")
|
||||
x.value = "ready";
|
||||
x.style.display = "none";
|
||||
frames[0].document.designMode = "on";
|
||||
}
|
||||
|
||||
function xss() {
|
||||
step();
|
||||
|
||||
var documentInjected = false;
|
||||
document.getElementsByTagName("iframe")[0].onload =
|
||||
function() { documentInjected = true; };
|
||||
frames[0].location = targetUrl;
|
||||
|
||||
for (var c = 0; !documentInjected && c < 20; c++) {
|
||||
var r = new XMLHttpRequest();
|
||||
r.open("GET", location.href, false);
|
||||
r.overrideMimeType("text/plain");
|
||||
r.send(null);
|
||||
}
|
||||
document.getElementById("state").textContent = "done";
|
||||
|
||||
var event = new MessageEvent('464620_a', { bubbles: true, cancelable: false,
|
||||
data: "done", origin: location.href,
|
||||
source: window });
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
</script>
|
||||
|
||||
<p id="state">pending</p>
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 464620 (injection on input) **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
let testURL = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser_464620_a.html";
|
||||
|
||||
var frameCount = 0;
|
||||
let tab = gBrowser.addTab(testURL);
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
// wait for all frames to load completely
|
||||
if (frameCount++ < 4)
|
||||
return;
|
||||
this.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
executeSoon(function() {
|
||||
frameCount = 0;
|
||||
let tab2 = gBrowser.duplicateTab(tab);
|
||||
tab2.linkedBrowser.addEventListener("464620_a", function(aEvent) {
|
||||
tab2.linkedBrowser.removeEventListener("464620_a", arguments.callee, true);
|
||||
is(aEvent.data, "done", "XSS injection was attempted");
|
||||
|
||||
// let form restoration complete and take into account the
|
||||
// setTimeout(..., 0) in sss_restoreDocument_proxy
|
||||
executeSoon(function() {
|
||||
setTimeout(function() {
|
||||
let win = tab2.linkedBrowser.contentWindow;
|
||||
isnot(win.frames[0].document.location, testURL,
|
||||
"cross domain document was loaded");
|
||||
ok(!/XXX/.test(win.frames[0].document.body.innerHTML),
|
||||
"no content was injected");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab2);
|
||||
gBrowser.removeTab(tab);
|
||||
|
||||
finish();
|
||||
}, 0);
|
||||
});
|
||||
}, true, true);
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
|
||||
|
||||
<title>Test for bug 464620 (injection on DOM node insertion)</title>
|
||||
|
||||
<iframe></iframe>
|
||||
<iframe></iframe>
|
||||
<iframe onload="setup()"></iframe>
|
||||
|
||||
<script>
|
||||
var targetUrl = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser_464620_xd.html";
|
||||
var firstPass;
|
||||
|
||||
function setup() {
|
||||
if (firstPass !== undefined)
|
||||
return;
|
||||
firstPass = frames[2].location.href == "about:blank";
|
||||
if (firstPass) {
|
||||
frames[0].location = 'data:text/html;charset=utf-8,<body onload="parent.step()">a</body>';
|
||||
frames[1].location = 'data:text/html;charset=utf-8,<body onload="document.designMode=\'on\';">XXX</body>';
|
||||
}
|
||||
frames[2].location = targetUrl;
|
||||
}
|
||||
|
||||
function step() {
|
||||
frames[0].document.designMode = "on";
|
||||
if (firstPass)
|
||||
return;
|
||||
|
||||
var body = frames[0].document.body;
|
||||
body.addEventListener("DOMNodeInserted", function() {
|
||||
body.removeEventListener("DOMNodeInserted", arguments.callee, true);
|
||||
xss();
|
||||
}, true);
|
||||
}
|
||||
|
||||
function xss() {
|
||||
var documentInjected = false;
|
||||
document.getElementsByTagName("iframe")[1].onload =
|
||||
function() { documentInjected = true; };
|
||||
frames[1].location = targetUrl;
|
||||
|
||||
for (var c = 0; !documentInjected && c < 20; c++) {
|
||||
var r = new XMLHttpRequest();
|
||||
r.open("GET", location.href, false);
|
||||
r.overrideMimeType("text/plain");
|
||||
r.send(null);
|
||||
}
|
||||
document.getElementById("state").textContent = "done";
|
||||
|
||||
var event = new MessageEvent('464620_b', { bubbles: true, cancelable: false,
|
||||
data: "done", origin: location.href,
|
||||
source: window });
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
</script>
|
||||
|
||||
<p id="state">pending</p>
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 464620 (injection on DOM node insertion) **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
let testURL = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser_464620_b.html";
|
||||
|
||||
var frameCount = 0;
|
||||
let tab = gBrowser.addTab(testURL);
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
// wait for all frames to load completely
|
||||
if (frameCount++ < 6)
|
||||
return;
|
||||
this.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
executeSoon(function() {
|
||||
frameCount = 0;
|
||||
let tab2 = gBrowser.duplicateTab(tab);
|
||||
tab2.linkedBrowser.addEventListener("464620_b", function(aEvent) {
|
||||
tab2.linkedBrowser.removeEventListener("464620_b", arguments.callee, true);
|
||||
is(aEvent.data, "done", "XSS injection was attempted");
|
||||
|
||||
// let form restoration complete and take into account the
|
||||
// setTimeout(..., 0) in sss_restoreDocument_proxy
|
||||
executeSoon(function() {
|
||||
setTimeout(function() {
|
||||
let win = tab2.linkedBrowser.contentWindow;
|
||||
isnot(win.frames[1].document.location, testURL,
|
||||
"cross domain document was loaded");
|
||||
ok(!/XXX/.test(win.frames[1].document.body.innerHTML),
|
||||
"no content was injected");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab2);
|
||||
gBrowser.removeTab(tab);
|
||||
|
||||
finish();
|
||||
}, 0);
|
||||
});
|
||||
}, true, true);
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
<title>Cross Document File for bug 464620</title>
|
||||
|
||||
<body onload="document.designMode='on';" bgcolor="red">
|
||||
This document is editable.
|
||||
</body>
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
var uniqueName = "bug 465215";
|
||||
var uniqueValue1 = "as good as unique: " + Date.now();
|
||||
var uniqueValue2 = "as good as unique: " + Math.random();
|
||||
|
||||
add_task(function* () {
|
||||
// set a unique value on a new, blank tab
|
||||
let tab1 = gBrowser.addTab("about:blank");
|
||||
yield promiseBrowserLoaded(tab1.linkedBrowser);
|
||||
ss.setTabValue(tab1, uniqueName, uniqueValue1);
|
||||
|
||||
// duplicate the tab with that value
|
||||
let tab2 = ss.duplicateTab(window, tab1);
|
||||
yield promiseTabRestored(tab2);
|
||||
is(ss.getTabValue(tab2, uniqueName), uniqueValue1, "tab value was duplicated");
|
||||
|
||||
ss.setTabValue(tab2, uniqueName, uniqueValue2);
|
||||
isnot(ss.getTabValue(tab1, uniqueName), uniqueValue2, "tab values aren't sync'd");
|
||||
|
||||
// overwrite the tab with the value which should remove it
|
||||
yield promiseTabState(tab1, {entries: []});
|
||||
is(ss.getTabValue(tab1, uniqueName), "", "tab value was cleared");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab2);
|
||||
gBrowser.removeTab(tab1);
|
||||
});
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 465223 **/
|
||||
|
||||
// test setup
|
||||
waitForExplicitFinish();
|
||||
|
||||
let uniqueKey1 = "bug 465223.1";
|
||||
let uniqueKey2 = "bug 465223.2";
|
||||
let uniqueValue1 = "unik" + Date.now();
|
||||
let uniqueValue2 = "pi != " + Math.random();
|
||||
|
||||
// open a window and set a value on it
|
||||
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
|
||||
promiseWindowLoaded(newWin).then(() => {
|
||||
ss.setWindowValue(newWin, uniqueKey1, uniqueValue1);
|
||||
|
||||
let newState = { windows: [{ tabs:[{ entries: [] }], extData: {} }] };
|
||||
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");
|
||||
|
||||
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");
|
||||
|
||||
// clean up
|
||||
BrowserTestUtils.closeWindow(newWin).then(finish);
|
||||
});
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const URL = ROOT + "browser_466937_sample.html";
|
||||
|
||||
/**
|
||||
* Bug 466937 - Prevent file stealing with sessionstore.
|
||||
*/
|
||||
add_task(function test_prevent_file_stealing() {
|
||||
// Add a tab with some file input fields.
|
||||
let tab = gBrowser.addTab(URL);
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseBrowserLoaded(browser);
|
||||
|
||||
// Generate a path to a 'secret' file.
|
||||
let file = Services.dirsvc.get("TmpD", Ci.nsIFile);
|
||||
file.append("466937_test.file");
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
|
||||
let testPath = file.path;
|
||||
|
||||
// Fill in form values.
|
||||
yield setInputValue(browser, {id: "reverse_thief", value: "/home/user/secret2"});
|
||||
yield setInputValue(browser, {id: "bystander", value: testPath});
|
||||
|
||||
// Duplicate and check form values.
|
||||
let tab2 = gBrowser.duplicateTab(tab);
|
||||
let browser2 = tab2.linkedBrowser;
|
||||
yield promiseTabRestored(tab2);
|
||||
|
||||
let thief = yield getInputValue(browser2, {id: "thief"});
|
||||
is(thief, "", "file path wasn't set to text field value");
|
||||
let reverse_thief = yield getInputValue(browser2, {id: "reverse_thief"});
|
||||
is(reverse_thief, "", "text field value wasn't set to full file path");
|
||||
let bystander = yield getInputValue(browser2, {id: "bystander"});
|
||||
is(bystander, testPath, "normal case: file path was correctly preserved");
|
||||
|
||||
// Cleanup.
|
||||
gBrowser.removeTab(tab);
|
||||
gBrowser.removeTab(tab2);
|
||||
});
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for bug 466937</title>
|
||||
|
||||
<input id="thief" value="/home/user/secret">
|
||||
<input type="file" id="reverse_thief">
|
||||
<input type="file" id="bystander">
|
||||
|
||||
<script>
|
||||
window.addEventListener("DOMContentLoaded", function() {
|
||||
window.removeEventListener("DOMContentLoaded", arguments.callee, false);
|
||||
if (!document.location.hash) {
|
||||
document.location.hash = "#ready";
|
||||
}
|
||||
else {
|
||||
document.getElementById("thief").type = "file";
|
||||
document.getElementById("reverse_thief").type = "text";
|
||||
}
|
||||
}, false);
|
||||
</script>
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test Summary:
|
||||
// 1. Open about:sessionrestore where formdata is a JS object, not a string
|
||||
// 1a. Check that #sessionData on the page is readable after JSON.parse (skipped, checking formdata is sufficient)
|
||||
// 1b. Check that there are no backslashes in the formdata
|
||||
// 1c. Check that formdata doesn't require JSON.parse
|
||||
//
|
||||
// 2. Use the current state (currently about:sessionrestore with data) and then open that in a new instance of about:sessionrestore
|
||||
// 2a. Check that there are no backslashes in the formdata
|
||||
// 2b. Check that formdata doesn't require JSON.parse
|
||||
//
|
||||
// 3. [backwards compat] Use a stringified state as formdata when opening about:sessionrestore
|
||||
// 3a. Make sure there are nodes in the tree on about:sessionrestore (skipped, checking formdata is sufficient)
|
||||
// 3b. Check that there are no backslashes in the formdata
|
||||
// 3c. Check that formdata doesn't require JSON.parse
|
||||
|
||||
const CRASH_STATE = {windows: [{tabs: [{entries: [{url: "about:mozilla" }]}]}]};
|
||||
const STATE = createEntries(CRASH_STATE);
|
||||
const STATE2 = createEntries({windows: [{tabs: [STATE]}]});
|
||||
const STATE3 = createEntries(JSON.stringify(CRASH_STATE));
|
||||
|
||||
function createEntries(sessionData) {
|
||||
return {
|
||||
entries: [{url: "about:sessionrestore"}],
|
||||
formdata: {id: {sessionData: sessionData}, url: "about:sessionrestore"}
|
||||
};
|
||||
}
|
||||
|
||||
add_task(function test_nested_about_sessionrestore() {
|
||||
// Prepare a blank tab.
|
||||
let tab = gBrowser.addTab("about:blank");
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseBrowserLoaded(browser);
|
||||
|
||||
// test 1
|
||||
yield promiseTabState(tab, STATE);
|
||||
yield checkState("test1", tab);
|
||||
|
||||
// test 2
|
||||
yield promiseTabState(tab, STATE2);
|
||||
yield checkState("test2", tab);
|
||||
|
||||
// test 3
|
||||
yield promiseTabState(tab, STATE3);
|
||||
yield checkState("test3", tab);
|
||||
|
||||
// Cleanup.
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
function* checkState(prefix, tab) {
|
||||
// Flush and query tab state.
|
||||
yield TabStateFlusher.flush(tab.linkedBrowser);
|
||||
let {formdata} = JSON.parse(ss.getTabState(tab));
|
||||
|
||||
ok(formdata.id["sessionData"], prefix + ": we have form data for about:sessionrestore");
|
||||
|
||||
let sessionData_raw = JSON.stringify(formdata.id["sessionData"]);
|
||||
ok(!/\\/.test(sessionData_raw), prefix + ": #sessionData contains no backslashes");
|
||||
info(sessionData_raw);
|
||||
|
||||
let gotError = false;
|
||||
try {
|
||||
JSON.parse(formdata.id["sessionData"]);
|
||||
} catch (e) {
|
||||
info(prefix + ": got error: " + e);
|
||||
gotError = true;
|
||||
}
|
||||
ok(gotError, prefix + ": attempting to JSON.parse form data threw error");
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 477657 **/
|
||||
waitForExplicitFinish();
|
||||
|
||||
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
|
||||
promiseWindowLoaded(newWin).then(() => {
|
||||
let newState = { windows: [{
|
||||
tabs: [{ entries: [] }],
|
||||
_closedTabs: [{
|
||||
state: { entries: [{ url: "about:" }]},
|
||||
title: "About:"
|
||||
}],
|
||||
sizemode: "maximized"
|
||||
}] };
|
||||
|
||||
let uniqueKey = "bug 477657";
|
||||
let uniqueValue = "unik" + Date.now();
|
||||
|
||||
ss.setWindowValue(newWin, uniqueKey, uniqueValue);
|
||||
is(ss.getWindowValue(newWin, uniqueKey), uniqueValue,
|
||||
"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);
|
||||
|
||||
newWin.setTimeout(function() {
|
||||
is(JSON.parse(ss.getClosedTabData(newWin)).length, 0,
|
||||
"closed tabs were implicitly cleared");
|
||||
|
||||
is(newWin.windowState, newWin.STATE_MAXIMIZED,
|
||||
"the window remains maximized");
|
||||
newState.windows[0].sizemode = "normal";
|
||||
ss.setWindowState(newWin, JSON.stringify(newState), true);
|
||||
|
||||
newWin.setTimeout(function() {
|
||||
isnot(newWin.windowState, newWin.STATE_MAXIMIZED,
|
||||
"the window was explicitly unmaximized");
|
||||
|
||||
BrowserTestUtils.closeWindow(newWin).then(finish);
|
||||
}, 0);
|
||||
}, 0);
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Tests that we get sent to the right page when the user clicks
|
||||
* the "Close" button in about:sessionrestore
|
||||
*/
|
||||
add_task(function*() {
|
||||
yield SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["browser.startup.page", 0],
|
||||
]
|
||||
});
|
||||
|
||||
let tab = gBrowser.addTab("about:sessionrestore");
|
||||
gBrowser.selectedTab = tab;
|
||||
let browser = tab.linkedBrowser;
|
||||
yield BrowserTestUtils.browserLoaded(browser, false, "about:sessionrestore");
|
||||
|
||||
let doc = browser.contentDocument;
|
||||
|
||||
// Click on the "Close" button after about:sessionrestore is loaded.
|
||||
doc.getElementById("errorCancel").click();
|
||||
|
||||
yield BrowserTestUtils.browserLoaded(browser, false, "about:blank");
|
||||
|
||||
// Test that starting a new session loads the homepage (set to http://mochi.test:8888)
|
||||
// if Firefox is configured to display a homepage at startup (browser.startup.page = 1)
|
||||
let homepage = "http://mochi.test:8888/";
|
||||
yield SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["browser.startup.homepage", homepage],
|
||||
["browser.startup.page", 1],
|
||||
]
|
||||
});
|
||||
|
||||
browser.loadURI("about:sessionrestore");
|
||||
yield BrowserTestUtils.browserLoaded(browser, false, "about:sessionrestore");
|
||||
doc = browser.contentDocument;
|
||||
|
||||
// Click on the "Close" button after about:sessionrestore is loaded.
|
||||
doc.getElementById("errorCancel").click();
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
is(browser.currentURI.spec, homepage, "loaded page is the homepage");
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const URL = ROOT + "browser_485482_sample.html";
|
||||
|
||||
/**
|
||||
* Bug 485482 - Make sure that we produce valid XPath expressions even for very
|
||||
* weird HTML documents.
|
||||
*/
|
||||
add_task(function test_xpath_exp_for_strange_documents() {
|
||||
// Load a page with weird tag names.
|
||||
let tab = gBrowser.addTab(URL);
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseBrowserLoaded(browser);
|
||||
|
||||
// Fill in some values.
|
||||
let uniqueValue = Math.random();
|
||||
yield setInputValue(browser, {selector: "input[type=text]", value: uniqueValue});
|
||||
yield setInputChecked(browser, {selector: "input[type=checkbox]", checked: true});
|
||||
|
||||
// Duplicate the tab.
|
||||
let tab2 = gBrowser.duplicateTab(tab);
|
||||
let browser2 = tab2.linkedBrowser;
|
||||
yield promiseTabRestored(tab2);
|
||||
|
||||
// Check that we generated valid XPath expressions to restore form values.
|
||||
let text = yield getInputValue(browser2, {selector: "input[type=text]"});
|
||||
is(text, uniqueValue, "generated XPath expression was valid");
|
||||
let checkbox = yield getInputChecked(browser2, {selector: "input[type=checkbox]"});
|
||||
ok(checkbox, "generated XPath expression was valid");
|
||||
|
||||
// Cleanup.
|
||||
gBrowser.removeTab(tab2);
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test for bug 485482</title>
|
||||
|
||||
<bad=name>
|
||||
<input type="text">
|
||||
</bad=name>
|
||||
|
||||
<worse=name>
|
||||
<l0c@l+na~e"'§>
|
||||
<input type="checkbox" name="check"> Check
|
||||
</l0c@l+na~e"'§>
|
||||
</worse=name>
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 485563 **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
let uniqueValue = Math.random() + "\u2028Second line\u2029Second paragraph\u2027";
|
||||
|
||||
let tab = gBrowser.addTab();
|
||||
promiseBrowserLoaded(tab.linkedBrowser).then(() => {
|
||||
ss.setTabValue(tab, "bug485563", uniqueValue);
|
||||
let tabState = JSON.parse(ss.getTabState(tab));
|
||||
is(tabState.extData["bug485563"], uniqueValue,
|
||||
"unicode line separator wasn't over-encoded");
|
||||
ss.deleteTabValue(tab, "bug485563");
|
||||
ss.setTabState(tab, JSON.stringify(tabState));
|
||||
is(ss.getTabValue(tab, "bug485563"), uniqueValue,
|
||||
"unicode line separator was correctly preserved");
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Only windows with open tabs are restorable. Windows where a lone tab is
|
||||
// detached may have _closedTabs, but is left with just an empty tab.
|
||||
const STATES = [{
|
||||
shouldBeAdded: true,
|
||||
windowState: {
|
||||
windows: [{
|
||||
tabs: [{ entries: [{ url: "http://example.com", title: "example.com" }] }],
|
||||
selected: 1,
|
||||
_closedTabs: []
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
shouldBeAdded: false,
|
||||
windowState: {
|
||||
windows: [{
|
||||
tabs: [{ entries: [] }],
|
||||
_closedTabs: []
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
shouldBeAdded: false,
|
||||
windowState: {
|
||||
windows: [{
|
||||
tabs: [{ entries: [] }],
|
||||
_closedTabs: [{ state: { entries: [{ url: "http://example.com", index: 1 }] } }]
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
shouldBeAdded: false,
|
||||
windowState: {
|
||||
windows: [{
|
||||
tabs: [{ entries: [] }],
|
||||
_closedTabs: [],
|
||||
extData: { keyname: "pi != " + Math.random() }
|
||||
}]
|
||||
}
|
||||
}];
|
||||
|
||||
add_task(function* test_bug_490040() {
|
||||
for (let state of STATES) {
|
||||
// Ensure we can store the window if needed.
|
||||
let startingClosedWindowCount = ss.getClosedWindowCount();
|
||||
yield pushPrefs(["browser.sessionstore.max_windows_undo",
|
||||
startingClosedWindowCount + 1]);
|
||||
|
||||
let curClosedWindowCount = ss.getClosedWindowCount();
|
||||
let win = yield BrowserTestUtils.openNewBrowserWindow();
|
||||
|
||||
ss.setWindowState(win, JSON.stringify(state.windowState), true);
|
||||
if (state.windowState.windows[0].tabs.length) {
|
||||
yield BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
|
||||
}
|
||||
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
|
||||
is(ss.getClosedWindowCount(),
|
||||
curClosedWindowCount + (state.shouldBeAdded ? 1 : 0),
|
||||
"That window should " + (state.shouldBeAdded ? "" : "not ") +
|
||||
"be restorable");
|
||||
}
|
||||
});
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const REFERRER1 = "http://example.org/?" + Date.now();
|
||||
const REFERRER2 = "http://example.org/?" + Math.random();
|
||||
|
||||
add_task(function* () {
|
||||
function* checkDocumentReferrer(referrer, msg) {
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, { referrer, msg }, function* (args) {
|
||||
Assert.equal(content.document.referrer, args.referrer, args.msg);
|
||||
});
|
||||
}
|
||||
|
||||
// Add a new tab.
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseBrowserLoaded(browser);
|
||||
|
||||
// Load a new URI with a specific referrer.
|
||||
let referrerURI = Services.io.newURI(REFERRER1, null, null);
|
||||
browser.loadURI("http://example.org", referrerURI, null);
|
||||
yield promiseBrowserLoaded(browser);
|
||||
|
||||
yield TabStateFlusher.flush(browser);
|
||||
let tabState = JSON.parse(ss.getTabState(tab));
|
||||
is(tabState.entries[0].referrer, REFERRER1,
|
||||
"Referrer retrieved via getTabState matches referrer set via loadURI.");
|
||||
|
||||
tabState.entries[0].referrer = REFERRER2;
|
||||
yield promiseTabState(tab, tabState);
|
||||
|
||||
yield checkDocumentReferrer(REFERRER2,
|
||||
"document.referrer matches referrer set via setTabState.");
|
||||
gBrowser.removeCurrentTab();
|
||||
|
||||
// Restore the closed tab.
|
||||
tab = ss.undoCloseTab(window, 0);
|
||||
yield promiseTabRestored(tab);
|
||||
|
||||
yield checkDocumentReferrer(REFERRER2,
|
||||
"document.referrer is still correct after closing and reopening the tab.");
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 491577 **/
|
||||
|
||||
// test setup
|
||||
waitForExplicitFinish();
|
||||
|
||||
const REMEMBER = Date.now(), FORGET = Math.random();
|
||||
let test_state = {
|
||||
windows: [ { tabs: [{ entries: [{ url: "http://example.com/" }] }], selected: 1 } ],
|
||||
_closedWindows : [
|
||||
// _closedWindows[0]
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.com/", title: "title" }] },
|
||||
{ entries: [{ url: "http://mozilla.org/", title: "title" }] }
|
||||
],
|
||||
selected: 2,
|
||||
title: FORGET,
|
||||
_closedTabs: []
|
||||
},
|
||||
// _closedWindows[1]
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://mozilla.org/", title: "title" }] },
|
||||
{ entries: [{ url: "http://example.com/", title: "title" }] },
|
||||
{ entries: [{ url: "http://mozilla.org/", title: "title" }] },
|
||||
],
|
||||
selected: 3,
|
||||
title: REMEMBER,
|
||||
_closedTabs: []
|
||||
},
|
||||
// _closedWindows[2]
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.com/", title: "title" }] }
|
||||
],
|
||||
selected: 1,
|
||||
title: FORGET,
|
||||
_closedTabs: [
|
||||
{
|
||||
state: {
|
||||
entries: [
|
||||
{ url: "http://mozilla.org/", title: "title" },
|
||||
{ url: "http://mozilla.org/again", title: "title" }
|
||||
]
|
||||
},
|
||||
pos: 1,
|
||||
title: "title"
|
||||
},
|
||||
{
|
||||
state: {
|
||||
entries: [
|
||||
{ url: "http://example.com", title: "title" }
|
||||
]
|
||||
},
|
||||
title: "title"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
let remember_count = 1;
|
||||
|
||||
function countByTitle(aClosedWindowList, aTitle) {
|
||||
return aClosedWindowList.filter(aData => aData.title == aTitle).length;
|
||||
}
|
||||
|
||||
function testForError(aFunction) {
|
||||
try {
|
||||
aFunction();
|
||||
return false;
|
||||
}
|
||||
catch (ex) {
|
||||
return ex.name == "NS_ERROR_ILLEGAL_VALUE";
|
||||
}
|
||||
}
|
||||
|
||||
// open a window and add the above closed window list
|
||||
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
|
||||
promiseWindowLoaded(newWin).then(() => {
|
||||
gPrefService.setIntPref("browser.sessionstore.max_windows_undo",
|
||||
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.");
|
||||
|
||||
// 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);
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 495495 **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no,toolbar=yes");
|
||||
promiseWindowLoaded(newWin).then(() => {
|
||||
let state1 = ss.getWindowState(newWin);
|
||||
BrowserTestUtils.closeWindow(newWin).then(() => {
|
||||
|
||||
newWin = openDialog(location, "_blank",
|
||||
"chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar=no,location,personal,directories,dialog=no");
|
||||
promiseWindowLoaded(newWin).then(() => {
|
||||
let state2 = ss.getWindowState(newWin);
|
||||
|
||||
function testState(state, expected, callback) {
|
||||
let win = openDialog(location, "_blank", "chrome,all,dialog=no");
|
||||
promiseWindowLoaded(win).then(() => {
|
||||
|
||||
is(win.gURLBar.readOnly, false,
|
||||
"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");
|
||||
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");
|
||||
|
||||
BrowserTestUtils.closeWindow(win).then(callback);
|
||||
});
|
||||
}
|
||||
|
||||
BrowserTestUtils.closeWindow(newWin).then(() => {
|
||||
testState(state1, {readOnly: false, enablehistory: "true"}, function() {
|
||||
testState(state2, {readOnly: true, enablehistory: "false"}, finish);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
let checkState = Task.async(function*(browser) {
|
||||
// Go back and then forward, and make sure that the state objects received
|
||||
// from the popState event are as we expect them to be.
|
||||
//
|
||||
// We also add a node to the document's body when after going back and make
|
||||
// sure it's still there after we go forward -- this is to test that the two
|
||||
// history entries correspond to the same document.
|
||||
|
||||
let deferred = {};
|
||||
deferred.promise = new Promise(resolve => deferred.resolve = resolve);
|
||||
|
||||
let popStateCount = 0;
|
||||
|
||||
browser.addEventListener("popstate", function(aEvent) {
|
||||
if (popStateCount == 0) {
|
||||
popStateCount++;
|
||||
|
||||
ok(aEvent.state, "Event should have a state property.");
|
||||
|
||||
ContentTask.spawn(browser, null, function() {
|
||||
is(content.testState, "foo",
|
||||
"testState after going back");
|
||||
is(JSON.stringify(content.history.state), JSON.stringify({obj1:1}),
|
||||
"first popstate object.");
|
||||
|
||||
// Add a node with id "new-elem" to the document.
|
||||
let doc = content.document;
|
||||
ok(!doc.getElementById("new-elem"),
|
||||
"doc shouldn't contain new-elem before we add it.");
|
||||
let elem = doc.createElement("div");
|
||||
elem.id = "new-elem";
|
||||
doc.body.appendChild(elem);
|
||||
}).then(() => {
|
||||
browser.goForward();
|
||||
});
|
||||
} else if (popStateCount == 1) {
|
||||
popStateCount++;
|
||||
// When content fires a PopStateEvent and we observe it from a chrome event
|
||||
// listener (as we do here, and, thankfully, nowhere else in the tree), the
|
||||
// state object will be a cross-compartment wrapper to an object that was
|
||||
// deserialized in the content scope. And in this case, since RegExps are
|
||||
// not currently Xrayable (see bug 1014991), trying to pull |obj3| (a RegExp)
|
||||
// off of an Xrayed Object won't work. So we need to waive.
|
||||
ContentTask.spawn(browser, aEvent.state, function(state) {
|
||||
Assert.equal(Cu.waiveXrays(state).obj3.toString(),
|
||||
"/^a$/", "second popstate object.");
|
||||
|
||||
// Make sure that the new-elem node is present in the document. If it's
|
||||
// not, then this history entry has a different doc identifier than the
|
||||
// previous entry, which is bad.
|
||||
let doc = content.document;
|
||||
let newElem = doc.getElementById("new-elem");
|
||||
ok(newElem, "doc should contain new-elem.");
|
||||
newElem.parentNode.removeChild(newElem);
|
||||
ok(!doc.getElementById("new-elem"), "new-elem should be removed.");
|
||||
}).then(() => {
|
||||
browser.removeEventListener("popstate", arguments.callee, true);
|
||||
deferred.resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Set some state in the page's window. When we go back(), the page should
|
||||
// be retrieved from bfcache, and this state should still be there.
|
||||
yield ContentTask.spawn(browser, null, function() {
|
||||
content.testState = "foo";
|
||||
});
|
||||
|
||||
// Now go back. This should trigger the popstate event handler above.
|
||||
browser.goBack();
|
||||
|
||||
yield deferred.promise;
|
||||
});
|
||||
|
||||
add_task(function* test() {
|
||||
// Tests session restore functionality of history.pushState and
|
||||
// history.replaceState(). (Bug 500328)
|
||||
|
||||
// We open a new blank window, let it load, and then load in
|
||||
// http://example.com. We need to load the blank window first, otherwise the
|
||||
// docshell gets confused and doesn't have a current history entry.
|
||||
let state;
|
||||
yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, function* (browser) {
|
||||
BrowserTestUtils.loadURI(browser, "http://example.com");
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// After these push/replaceState calls, the window should have three
|
||||
// history entries:
|
||||
// testURL (state object: null) <-- oldest
|
||||
// testURL (state object: {obj1:1})
|
||||
// testURL?page2 (state object: {obj3:/^a$/}) <-- newest
|
||||
function contentTest() {
|
||||
let history = content.window.history;
|
||||
history.pushState({obj1:1}, "title-obj1");
|
||||
history.pushState({obj2:2}, "title-obj2", "?page2");
|
||||
history.replaceState({obj3:/^a$/}, "title-obj3");
|
||||
}
|
||||
yield ContentTask.spawn(browser, null, contentTest);
|
||||
yield TabStateFlusher.flush(browser);
|
||||
|
||||
state = ss.getTabState(gBrowser.getTabForBrowser(browser));
|
||||
});
|
||||
|
||||
// Restore the state into a new tab. Things don't work well when we
|
||||
// restore into the old tab, but that's not a real use case anyway.
|
||||
yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, function* (browser) {
|
||||
let tab2 = gBrowser.getTabForBrowser(browser);
|
||||
|
||||
let tabRestoredPromise = promiseTabRestored(tab2);
|
||||
ss.setTabState(tab2, state, true);
|
||||
|
||||
// Run checkState() once the tab finishes loading its restored state.
|
||||
yield tabRestoredPromise;
|
||||
yield checkState(browser);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 506482 **/
|
||||
|
||||
// test setup
|
||||
waitForExplicitFinish();
|
||||
|
||||
// read the sessionstore.js mtime (picked from browser_248970_a.js)
|
||||
let profilePath = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).
|
||||
get("ProfD", Ci.nsIFile);
|
||||
function getSessionstoreFile() {
|
||||
let sessionStoreJS = profilePath.clone();
|
||||
sessionStoreJS.append("sessionstore.js");
|
||||
return sessionStoreJS;
|
||||
}
|
||||
function getSessionstorejsModificationTime() {
|
||||
let file = getSessionstoreFile();
|
||||
if (file.exists())
|
||||
return file.lastModifiedTime;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// delete existing sessionstore.js, to make sure we're not reading
|
||||
// the mtime of an old one initially.
|
||||
let sessionStoreJS = getSessionstoreFile();
|
||||
if (sessionStoreJS.exists())
|
||||
sessionStoreJS.remove(false);
|
||||
|
||||
// test content URL
|
||||
const TEST_URL = "data:text/html;charset=utf-8,"
|
||||
+ "<body style='width: 100000px; height: 100000px;'><p>top</p></body>"
|
||||
|
||||
// preferences that we use
|
||||
const PREF_INTERVAL = "browser.sessionstore.interval";
|
||||
|
||||
// make sure sessionstore.js is saved ASAP on all events
|
||||
gPrefService.setIntPref(PREF_INTERVAL, 0);
|
||||
|
||||
// get the initial sessionstore.js mtime (-1 if it doesn't exist yet)
|
||||
let mtime0 = getSessionstorejsModificationTime();
|
||||
|
||||
// create and select a first tab
|
||||
let tab = gBrowser.addTab(TEST_URL);
|
||||
promiseBrowserLoaded(tab.linkedBrowser).then(() => {
|
||||
// step1: the above has triggered some saveStateDelayed(), sleep until
|
||||
// it's done, and get the initial sessionstore.js mtime
|
||||
setTimeout(function step1(e) {
|
||||
let mtime1 = getSessionstorejsModificationTime();
|
||||
isnot(mtime1, mtime0, "initial sessionstore.js update");
|
||||
|
||||
// step2: test sessionstore.js is not updated on tab selection
|
||||
// or content scrolling
|
||||
gBrowser.selectedTab = tab;
|
||||
tab.linkedBrowser.contentWindow.scrollTo(1100, 1200);
|
||||
setTimeout(function step2(e) {
|
||||
let mtime2 = getSessionstorejsModificationTime();
|
||||
is(mtime2, mtime1,
|
||||
"tab selection and scrolling: sessionstore.js not updated");
|
||||
|
||||
// ok, done, cleanup and finish
|
||||
if (gPrefService.prefHasUserValue(PREF_INTERVAL))
|
||||
gPrefService.clearUserPref(PREF_INTERVAL);
|
||||
gBrowser.removeTab(tab);
|
||||
finish();
|
||||
}, 3500); // end of sleep after tab selection and scrolling
|
||||
}, 3500); // end of sleep after initial saveStateDelayed()
|
||||
});
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 514751 (Wallpaper) **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
let state = {
|
||||
windows: [{
|
||||
tabs: [{
|
||||
entries: [
|
||||
{ url: "about:mozilla", title: "Mozilla" },
|
||||
{}
|
||||
]
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
var theWin = openDialog(location, "", "chrome,all,dialog=no");
|
||||
theWin.addEventListener("load", function () {
|
||||
theWin.removeEventListener("load", arguments.callee, false);
|
||||
|
||||
executeSoon(function () {
|
||||
var gotError = false;
|
||||
try {
|
||||
ss.setWindowState(theWin, JSON.stringify(state), true);
|
||||
} catch (e) {
|
||||
if (/NS_ERROR_MALFORMED_URI/.test(e))
|
||||
gotError = true;
|
||||
}
|
||||
ok(!gotError, "Didn't get a malformed URI error.");
|
||||
BrowserTestUtils.closeWindow(theWin).then(finish);
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
function test() {
|
||||
var startup_info = Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(Components.interfaces.nsIAppStartup).getStartupInfo();
|
||||
// No .process info on mac
|
||||
|
||||
// Check if we encountered a telemetry error for the the process creation
|
||||
// timestamp and turn the first test into a known failure.
|
||||
var telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
|
||||
var snapshot = telemetry.getHistogramById("STARTUP_MEASUREMENT_ERRORS")
|
||||
.snapshot();
|
||||
|
||||
if (snapshot.counts[0] == 0)
|
||||
ok(startup_info.process <= startup_info.main, "process created before main is run " + uneval(startup_info));
|
||||
else
|
||||
todo(false, "An error occurred while recording the process creation timestamp, skipping this test");
|
||||
|
||||
// on linux firstPaint can happen after everything is loaded (especially with remote X)
|
||||
if (startup_info.firstPaint)
|
||||
ok(startup_info.main <= startup_info.firstPaint, "main ran before first paint " + uneval(startup_info));
|
||||
|
||||
ok(startup_info.main < startup_info.sessionRestored, "Session restored after main " + uneval(startup_info));
|
||||
}
|
||||
|
|
@ -1,269 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 522545 **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(4);
|
||||
|
||||
// This tests the following use case:
|
||||
// User opens a new tab which gets focus. The user types something into the
|
||||
// address bar, then crashes or quits.
|
||||
function test_newTabFocused() {
|
||||
let state = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: "about:mozilla" }] },
|
||||
{ entries: [], userTypedValue: "example.com", userTypedClear: 0 }
|
||||
],
|
||||
selected: 2
|
||||
}]
|
||||
};
|
||||
|
||||
waitForBrowserState(state, function() {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
is(browser.currentURI.spec, "about:blank",
|
||||
"No history entries still sets currentURI to about:blank");
|
||||
is(browser.userTypedValue, "example.com",
|
||||
"userTypedValue was correctly restored");
|
||||
ok(!browser.didStartLoadSinceLastUserTyping(),
|
||||
"We still know that no load is ongoing");
|
||||
is(gURLBar.value, "example.com",
|
||||
"Address bar's value correctly restored");
|
||||
// Change tabs to make sure address bar value gets updated
|
||||
gBrowser.selectedTab = gBrowser.tabContainer.getItemAtIndex(0);
|
||||
is(gURLBar.value, "about:mozilla",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
});
|
||||
}
|
||||
|
||||
// This tests the following use case:
|
||||
// User opens a new tab which gets focus. The user types something into the
|
||||
// address bar, switches back to the first tab, then crashes or quits.
|
||||
function test_newTabNotFocused() {
|
||||
let state = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: "about:mozilla" }] },
|
||||
{ entries: [], userTypedValue: "example.org", userTypedClear: 0 }
|
||||
],
|
||||
selected: 1
|
||||
}]
|
||||
};
|
||||
|
||||
waitForBrowserState(state, function() {
|
||||
let browser = gBrowser.getBrowserAtIndex(1);
|
||||
is(browser.currentURI.spec, "about:blank",
|
||||
"No history entries still sets currentURI to about:blank");
|
||||
is(browser.userTypedValue, "example.org",
|
||||
"userTypedValue was correctly restored");
|
||||
ok(!browser.didStartLoadSinceLastUserTyping(),
|
||||
"We still know that no load is ongoing");
|
||||
is(gURLBar.value, "about:mozilla",
|
||||
"Address bar's value correctly restored");
|
||||
// Change tabs to make sure address bar value gets updated
|
||||
gBrowser.selectedTab = gBrowser.tabContainer.getItemAtIndex(1);
|
||||
is(gURLBar.value, "example.org",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
});
|
||||
}
|
||||
|
||||
// This tests the following use case:
|
||||
// User is in a tab with session history, then types something in the
|
||||
// address bar, then crashes or quits.
|
||||
function test_existingSHEnd_noClear() {
|
||||
let state = {
|
||||
windows: [{
|
||||
tabs: [{
|
||||
entries: [{ url: "about:mozilla" }, { url: "about:config" }],
|
||||
index: 2,
|
||||
userTypedValue: "example.com",
|
||||
userTypedClear: 0
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
waitForBrowserState(state, function() {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
is(browser.currentURI.spec, "about:config",
|
||||
"browser.currentURI set to current entry in SH");
|
||||
is(browser.userTypedValue, "example.com",
|
||||
"userTypedValue was correctly restored");
|
||||
ok(!browser.didStartLoadSinceLastUserTyping(),
|
||||
"We still know that no load is ongoing");
|
||||
is(gURLBar.value, "example.com",
|
||||
"Address bar's value correctly restored to userTypedValue");
|
||||
runNextTest();
|
||||
});
|
||||
}
|
||||
|
||||
// This tests the following use case:
|
||||
// User is in a tab with session history, presses back at some point, then
|
||||
// types something in the address bar, then crashes or quits.
|
||||
function test_existingSHMiddle_noClear() {
|
||||
let state = {
|
||||
windows: [{
|
||||
tabs: [{
|
||||
entries: [{ url: "about:mozilla" }, { url: "about:config" }],
|
||||
index: 1,
|
||||
userTypedValue: "example.org",
|
||||
userTypedClear: 0
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
waitForBrowserState(state, function() {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
is(browser.currentURI.spec, "about:mozilla",
|
||||
"browser.currentURI set to current entry in SH");
|
||||
is(browser.userTypedValue, "example.org",
|
||||
"userTypedValue was correctly restored");
|
||||
ok(!browser.didStartLoadSinceLastUserTyping(),
|
||||
"We still know that no load is ongoing");
|
||||
is(gURLBar.value, "example.org",
|
||||
"Address bar's value correctly restored to userTypedValue");
|
||||
runNextTest();
|
||||
});
|
||||
}
|
||||
|
||||
// This test simulates lots of tabs opening at once and then quitting/crashing.
|
||||
function test_getBrowserState_lotsOfTabsOpening() {
|
||||
gBrowser.stop();
|
||||
|
||||
let uris = [];
|
||||
for (let i = 0; i < 25; i++)
|
||||
uris.push("http://example.com/" + i);
|
||||
|
||||
// We're waiting for the first location change, which should indicate
|
||||
// one of the tabs has loaded and the others haven't. So one should
|
||||
// be in a non-userTypedValue case, while others should still have
|
||||
// userTypedValue and userTypedClear set.
|
||||
gBrowser.addTabsProgressListener({
|
||||
onLocationChange: function (aBrowser) {
|
||||
if (uris.indexOf(aBrowser.currentURI.spec) > -1) {
|
||||
gBrowser.removeTabsProgressListener(this);
|
||||
firstLocationChange();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function firstLocationChange() {
|
||||
let state = JSON.parse(ss.getBrowserState());
|
||||
let hasUTV = state.windows[0].tabs.some(function(aTab) {
|
||||
return aTab.userTypedValue && aTab.userTypedClear && !aTab.entries.length;
|
||||
});
|
||||
|
||||
ok(hasUTV, "At least one tab has a userTypedValue with userTypedClear with no loaded URL");
|
||||
|
||||
BrowserTestUtils.waitForMessage(gBrowser.selectedBrowser.messageManager, "SessionStore:update").then(firstLoad);
|
||||
}
|
||||
|
||||
function firstLoad() {
|
||||
let state = JSON.parse(ss.getTabState(gBrowser.selectedTab));
|
||||
let hasSH = !("userTypedValue" in state) && state.entries[0].url;
|
||||
ok(hasSH, "The selected tab has its entry in SH");
|
||||
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
gBrowser.loadTabs(uris);
|
||||
}
|
||||
|
||||
// This simulates setting a userTypedValue and ensures that just typing in the
|
||||
// URL bar doesn't set userTypedClear as well.
|
||||
function test_getBrowserState_userTypedValue() {
|
||||
let state = {
|
||||
windows: [{
|
||||
tabs: [{ entries: [] }]
|
||||
}]
|
||||
};
|
||||
|
||||
waitForBrowserState(state, function() {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
// Make sure this tab isn't loading and state is clear before we test.
|
||||
is(browser.userTypedValue, null, "userTypedValue is empty to start");
|
||||
ok(!browser.didStartLoadSinceLastUserTyping(),
|
||||
"Initially, no load should be ongoing");
|
||||
|
||||
let inputText = "example.org";
|
||||
gURLBar.focus();
|
||||
gURLBar.value = inputText.slice(0, -1);
|
||||
EventUtils.synthesizeKey(inputText.slice(-1) , {});
|
||||
|
||||
executeSoon(function () {
|
||||
is(browser.userTypedValue, "example.org",
|
||||
"userTypedValue was set when changing URLBar value");
|
||||
ok(!browser.didStartLoadSinceLastUserTyping(),
|
||||
"No load started since changing URLBar value");
|
||||
|
||||
// Now make sure ss gets these values too
|
||||
let newState = JSON.parse(ss.getBrowserState());
|
||||
is(newState.windows[0].tabs[0].userTypedValue, "example.org",
|
||||
"sessionstore got correct userTypedValue");
|
||||
is(newState.windows[0].tabs[0].userTypedClear, 0,
|
||||
"sessionstore got correct userTypedClear");
|
||||
runNextTest();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// test_getBrowserState_lotsOfTabsOpening tested userTypedClear in a few cases,
|
||||
// but not necessarily any that had legitimate URIs in the state of loading
|
||||
// (eg, "http://example.com"), so this test will cover that case.
|
||||
function test_userTypedClearLoadURI() {
|
||||
let state = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [], userTypedValue: "http://example.com", userTypedClear: 2 }
|
||||
]
|
||||
}]
|
||||
};
|
||||
|
||||
waitForBrowserState(state, function() {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
is(browser.currentURI.spec, "http://example.com/",
|
||||
"userTypedClear=2 caused userTypedValue to be loaded");
|
||||
is(browser.userTypedValue, null,
|
||||
"userTypedValue was null after loading a URI");
|
||||
ok(!browser.didStartLoadSinceLastUserTyping(),
|
||||
"We should have reset the load state when the tab loaded");
|
||||
is(gURLBar.textValue, gURLBar.trimValue("http://example.com/"),
|
||||
"Address bar's value set after loading URI");
|
||||
runNextTest();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
let tests = [test_newTabFocused, test_newTabNotFocused,
|
||||
test_existingSHEnd_noClear, test_existingSHMiddle_noClear,
|
||||
test_getBrowserState_lotsOfTabsOpening,
|
||||
test_getBrowserState_userTypedValue, test_userTypedClearLoadURI];
|
||||
let originalState = JSON.parse(ss.getBrowserState());
|
||||
let state = {
|
||||
windows: [{
|
||||
tabs: [{ entries: [{ url: "about:blank" }] }]
|
||||
}]
|
||||
};
|
||||
function runNextTest() {
|
||||
if (tests.length) {
|
||||
waitForBrowserState(state, function() {
|
||||
gBrowser.selectedBrowser.userTypedValue = null;
|
||||
URLBarSetURI();
|
||||
(tests.shift())();
|
||||
});
|
||||
} else {
|
||||
waitForBrowserState(originalState, function() {
|
||||
gBrowser.selectedBrowser.userTypedValue = null;
|
||||
URLBarSetURI();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Run the tests!
|
||||
runNextTest();
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 524745 **/
|
||||
|
||||
let uniqKey = "bug524745";
|
||||
let uniqVal = Date.now().toString();
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
whenNewWindowLoaded({ private: false }, function (window_B) {
|
||||
waitForFocus(function() {
|
||||
// Add identifying information to window_B
|
||||
ss.setWindowValue(window_B, uniqKey, uniqVal);
|
||||
let state = JSON.parse(ss.getBrowserState());
|
||||
let selectedWindow = state.windows[state.selectedWindow - 1];
|
||||
is(selectedWindow.extData && selectedWindow.extData[uniqKey], uniqVal,
|
||||
"selectedWindow is window_B");
|
||||
|
||||
// Now minimize window_B. The selected window shouldn't have the secret data
|
||||
window_B.minimize();
|
||||
waitForFocus(function() {
|
||||
state = JSON.parse(ss.getBrowserState());
|
||||
selectedWindow = state.windows[state.selectedWindow - 1];
|
||||
ok(!selectedWindow.extData || !selectedWindow.extData[uniqKey],
|
||||
"selectedWindow is not window_B after minimizing it");
|
||||
|
||||
// Now minimize the last open window (assumes no other tests left windows open)
|
||||
window.minimize();
|
||||
state = JSON.parse(ss.getBrowserState());
|
||||
is(state.selectedWindow, 0,
|
||||
"selectedWindow should be 0 when all windows are minimized");
|
||||
|
||||
// Cleanup
|
||||
window.restore();
|
||||
BrowserTestUtils.closeWindow(window_B).then(finish);
|
||||
});
|
||||
}, window_B);
|
||||
});
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 526613 **/
|
||||
|
||||
// test setup
|
||||
waitForExplicitFinish();
|
||||
|
||||
function browserWindowsCount(expected) {
|
||||
let count = 0;
|
||||
let e = Services.wm.getEnumerator("navigator:browser");
|
||||
while (e.hasMoreElements()) {
|
||||
if (!e.getNext().closed)
|
||||
++count;
|
||||
}
|
||||
is(count, expected,
|
||||
"number of open browser windows according to nsIWindowMediator");
|
||||
let state = ss.getBrowserState();
|
||||
info(state);
|
||||
is(JSON.parse(state).windows.length, expected,
|
||||
"number of open browser windows according to getBrowserState");
|
||||
}
|
||||
|
||||
browserWindowsCount(1);
|
||||
|
||||
// backup old state
|
||||
let oldState = ss.getBrowserState();
|
||||
// create a new state for testing
|
||||
let testState = {
|
||||
windows: [
|
||||
{ tabs: [{ entries: [{ url: "http://example.com/" }] }], selected: 1 },
|
||||
{ tabs: [{ entries: [{ url: "about:mozilla" }] }], selected: 1 },
|
||||
],
|
||||
// make sure the first window is focused, otherwise when restoring the
|
||||
// old state, the first window is closed and the test harness gets unloaded
|
||||
selectedWindow: 1
|
||||
};
|
||||
|
||||
let pass = 1;
|
||||
function observer(aSubject, aTopic, aData) {
|
||||
is(aTopic, "sessionstore-browser-state-restored",
|
||||
"The sessionstore-browser-state-restored notification was observed");
|
||||
|
||||
if (pass++ == 1) {
|
||||
browserWindowsCount(2);
|
||||
|
||||
// let the first window be focused (see above)
|
||||
function pollMostRecentWindow() {
|
||||
if (Services.wm.getMostRecentWindow("navigator:browser") == window) {
|
||||
ss.setBrowserState(oldState);
|
||||
} else {
|
||||
info("waiting for the current window to become active");
|
||||
setTimeout(pollMostRecentWindow, 0);
|
||||
window.focus(); //XXX Why is this needed?
|
||||
}
|
||||
}
|
||||
pollMostRecentWindow();
|
||||
}
|
||||
else {
|
||||
browserWindowsCount(1);
|
||||
ok(!window.closed, "Restoring the old state should have left this window open");
|
||||
Services.obs.removeObserver(observer, "sessionstore-browser-state-restored");
|
||||
finish();
|
||||
}
|
||||
}
|
||||
Services.obs.addObserver(observer, "sessionstore-browser-state-restored", false);
|
||||
|
||||
// set browser to test state
|
||||
ss.setBrowserState(JSON.stringify(testState));
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
function browserWindowsCount(expected) {
|
||||
var count = 0;
|
||||
var e = Services.wm.getEnumerator("navigator:browser");
|
||||
while (e.hasMoreElements()) {
|
||||
if (!e.getNext().closed)
|
||||
++count;
|
||||
}
|
||||
is(count, expected,
|
||||
"number of open browser windows according to nsIWindowMediator");
|
||||
is(JSON.parse(ss.getBrowserState()).windows.length, expected,
|
||||
"number of open browser windows according to getBrowserState");
|
||||
}
|
||||
|
||||
add_task(function() {
|
||||
browserWindowsCount(1);
|
||||
|
||||
let win = yield BrowserTestUtils.openNewBrowserWindow();
|
||||
browserWindowsCount(2);
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
browserWindowsCount(1);
|
||||
});
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let tab1 = gBrowser.addTab("about:rights");
|
||||
let tab2 = gBrowser.addTab("about:mozilla");
|
||||
|
||||
promiseBrowserLoaded(tab1.linkedBrowser).then(() => {
|
||||
// Tell the session storer that the tab is pinned
|
||||
let newTabState = '{"entries":[{"url":"about:rights"}],"pinned":true,"userTypedValue":"Hello World!"}';
|
||||
ss.setTabState(tab1, newTabState);
|
||||
|
||||
// Undo pinning
|
||||
gBrowser.unpinTab(tab1);
|
||||
|
||||
// Close and restore tab
|
||||
gBrowser.removeTab(tab1);
|
||||
let savedState = JSON.parse(ss.getClosedTabData(window))[0].state;
|
||||
isnot(savedState.pinned, true, "Pinned should not be true");
|
||||
tab1 = ss.undoCloseTab(window, 0);
|
||||
|
||||
isnot(tab1.pinned, true, "Should not be pinned");
|
||||
gBrowser.removeTab(tab1);
|
||||
gBrowser.removeTab(tab2);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
let tab1 = gBrowser.addTab("data:text/plain;charset=utf-8,foo");
|
||||
gBrowser.pinTab(tab1);
|
||||
|
||||
yield promiseBrowserLoaded(tab1.linkedBrowser);
|
||||
let tab2 = gBrowser.addTab();
|
||||
gBrowser.pinTab(tab2);
|
||||
|
||||
is(Array.indexOf(gBrowser.tabs, tab1), 0, "pinned tab 1 is at the first position");
|
||||
yield promiseRemoveTab(tab1);
|
||||
|
||||
tab1 = undoCloseTab();
|
||||
ok(tab1.pinned, "pinned tab 1 has been restored as a pinned tab");
|
||||
is(Array.indexOf(gBrowser.tabs, tab1), 0, "pinned tab 1 has been restored to the first position");
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab1);
|
||||
yield BrowserTestUtils.removeTab(tab2);
|
||||
});
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const URIS_PINNED = ["about:license", "about:about"];
|
||||
const URIS_NORMAL_A = ["about:mozilla"];
|
||||
const URIS_NORMAL_B = ["about:buildconfig"];
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
isnot(Services.prefs.getIntPref("browser.startup.page"), 3,
|
||||
"pref to save session must not be set for this test");
|
||||
ok(!Services.prefs.getBoolPref("browser.sessionstore.resume_session_once"),
|
||||
"pref to save session once must not be set for this test");
|
||||
|
||||
document.documentElement.setAttribute("windowtype", "navigator:browsertestdummy");
|
||||
|
||||
openWinWithCb(closeFirstWin, URIS_PINNED.concat(URIS_NORMAL_A));
|
||||
}
|
||||
|
||||
function closeFirstWin(win) {
|
||||
win.gBrowser.pinTab(win.gBrowser.tabs[0]);
|
||||
win.gBrowser.pinTab(win.gBrowser.tabs[1]);
|
||||
|
||||
let winClosed = BrowserTestUtils.windowClosed(win);
|
||||
// We need to call BrowserTryToCloseWindow in order to trigger
|
||||
// the machinery that chooses whether or not to save the session
|
||||
// for the last window.
|
||||
win.BrowserTryToCloseWindow();
|
||||
ok(win.closed, "window closed");
|
||||
|
||||
winClosed.then(() => {
|
||||
openWinWithCb(checkSecondWin, URIS_NORMAL_B, URIS_PINNED.concat(URIS_NORMAL_B));
|
||||
});
|
||||
}
|
||||
|
||||
function checkSecondWin(win) {
|
||||
is(win.gBrowser.browsers[0].currentURI.spec, URIS_PINNED[0], "first pinned tab restored");
|
||||
is(win.gBrowser.browsers[1].currentURI.spec, URIS_PINNED[1], "second pinned tab restored");
|
||||
ok(win.gBrowser.tabs[0].pinned, "first pinned tab is still pinned");
|
||||
ok(win.gBrowser.tabs[1].pinned, "second pinned tab is still pinned");
|
||||
|
||||
BrowserTestUtils.closeWindow(win).then(() => {
|
||||
// cleanup
|
||||
document.documentElement.setAttribute("windowtype", "navigator:browser");
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function openWinWithCb(cb, argURIs, expectedURIs) {
|
||||
if (!expectedURIs)
|
||||
expectedURIs = argURIs;
|
||||
|
||||
var win = openDialog(getBrowserURL(), "_blank",
|
||||
"chrome,all,dialog=no", argURIs.join("|"));
|
||||
|
||||
win.addEventListener("load", function () {
|
||||
win.removeEventListener("load", arguments.callee, false);
|
||||
info("the window loaded");
|
||||
|
||||
var expectedLoads = expectedURIs.length;
|
||||
|
||||
win.gBrowser.addTabsProgressListener({
|
||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
if (aRequest &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
||||
expectedURIs.indexOf(aRequest.QueryInterface(Ci.nsIChannel).originalURI.spec) > -1 &&
|
||||
--expectedLoads <= 0) {
|
||||
win.gBrowser.removeTabsProgressListener(this);
|
||||
info("all tabs loaded");
|
||||
is(win.gBrowser.tabs.length, expectedURIs.length, "didn't load any unexpected tabs");
|
||||
executeSoon(function () {
|
||||
cb(win);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// Tests that an about:blank tab with no history will not be saved into
|
||||
// session store and thus, it will not show up in Recently Closed Tabs.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
let tab = gBrowser.addTab("about:blank");
|
||||
yield promiseBrowserLoaded(tab.linkedBrowser);
|
||||
|
||||
is(tab.linkedBrowser.currentURI.spec, "about:blank",
|
||||
"we will be removing an about:blank tab");
|
||||
|
||||
let r = `rand-${Math.random()}`;
|
||||
ss.setTabValue(tab, "foobar", r);
|
||||
|
||||
yield promiseRemoveTab(tab);
|
||||
let closedTabData = ss.getClosedTabData(window);
|
||||
ok(!closedTabData.includes(r), "tab not stored in _closedTabs");
|
||||
});
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
|
||||
|
||||
add_task(function* test() {
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
|
||||
});
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org/#1" }], extData: { "uniq": r() }, pinned: true },
|
||||
{ entries: [{ url: "http://example.org/#2" }], extData: { "uniq": r() }, pinned: true },
|
||||
{ entries: [{ url: "http://example.org/#3" }], extData: { "uniq": r() }, pinned: true },
|
||||
{ entries: [{ url: "http://example.org/#4" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#5" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#6" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#7" }], extData: { "uniq": r() } },
|
||||
], selected: 5 }] };
|
||||
|
||||
let loadCount = 0;
|
||||
let promiseRestoringTabs = new Promise(resolve => {
|
||||
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
|
||||
loadCount++;
|
||||
|
||||
// We'll make sure that the loads we get come from pinned tabs or the
|
||||
// the selected tab.
|
||||
|
||||
// get the tab
|
||||
let tab;
|
||||
for (let i = 0; i < window.gBrowser.tabs.length; i++) {
|
||||
if (!tab && window.gBrowser.tabs[i].linkedBrowser == aBrowser)
|
||||
tab = window.gBrowser.tabs[i];
|
||||
}
|
||||
|
||||
ok(tab.pinned || tab.selected,
|
||||
"load came from pinned or selected tab");
|
||||
|
||||
// We should get 4 loads: 3 app tabs + 1 normal selected tab
|
||||
if (loadCount < 4)
|
||||
return;
|
||||
|
||||
gProgressListener.unsetCallback();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let backupState = ss.getBrowserState();
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
yield promiseRestoringTabs;
|
||||
|
||||
// Cleanup.
|
||||
yield promiseBrowserState(backupState);
|
||||
});
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
|
||||
const PREF_RESTORE_PINNED_TABS_ON_DEMAND = "browser.sessionstore.restore_pinned_tabs_on_demand";
|
||||
|
||||
add_task(function* test() {
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_PINNED_TABS_ON_DEMAND, true);
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_PINNED_TABS_ON_DEMAND);
|
||||
});
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org/#1" }], extData: { "uniq": r() }, pinned: true },
|
||||
{ entries: [{ url: "http://example.org/#2" }], extData: { "uniq": r() }, pinned: true },
|
||||
{ entries: [{ url: "http://example.org/#3" }], extData: { "uniq": r() }, pinned: true },
|
||||
{ entries: [{ url: "http://example.org/#4" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#5" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#6" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#7" }], extData: { "uniq": r() } },
|
||||
], selected: 5 }] };
|
||||
|
||||
let promiseRestoringTabs = new Promise(resolve => {
|
||||
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
|
||||
// get the tab
|
||||
let tab;
|
||||
for (let i = 0; i < window.gBrowser.tabs.length; i++) {
|
||||
if (!tab && window.gBrowser.tabs[i].linkedBrowser == aBrowser)
|
||||
tab = window.gBrowser.tabs[i];
|
||||
}
|
||||
|
||||
// Check that the load only comes from the selected tab.
|
||||
ok(tab.selected, "load came from selected tab");
|
||||
is(aNeedRestore, 6, "six tabs left to restore");
|
||||
is(aRestoring, 1, "one tab is restoring");
|
||||
is(aRestored, 0, "no tabs have been restored, yet");
|
||||
|
||||
gProgressListener.unsetCallback();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let backupState = ss.getBrowserState();
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
yield promiseRestoringTabs;
|
||||
|
||||
// Cleanup.
|
||||
yield promiseBrowserState(backupState);
|
||||
});
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
add_task(function* test() {
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
|
||||
});
|
||||
|
||||
// The first state will be loaded using setBrowserState, followed by the 2nd
|
||||
// state also being loaded using setBrowserState, interrupting the first restore.
|
||||
let state1 = { windows: [
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.org#1" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org#2" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org#3" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org#4" }], extData: { "uniq": r() } }
|
||||
],
|
||||
selected: 1
|
||||
},
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.com#1" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#2" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#3" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#4" }], extData: { "uniq": r() } },
|
||||
],
|
||||
selected: 3
|
||||
}
|
||||
] };
|
||||
let state2 = { windows: [
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.org#5" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org#6" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org#7" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org#8" }], extData: { "uniq": r() } }
|
||||
],
|
||||
selected: 3
|
||||
},
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.com#5" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#6" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#7" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#8" }], extData: { "uniq": r() } },
|
||||
],
|
||||
selected: 1
|
||||
}
|
||||
] };
|
||||
|
||||
// interruptedAfter will be set after the selected tab from each window have loaded.
|
||||
let interruptedAfter = 0;
|
||||
let loadedWindow1 = false;
|
||||
let loadedWindow2 = false;
|
||||
let numTabs = state2.windows[0].tabs.length + state2.windows[1].tabs.length;
|
||||
|
||||
let loadCount = 0;
|
||||
let promiseRestoringTabs = new Promise(resolve => {
|
||||
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
|
||||
loadCount++;
|
||||
|
||||
if (aBrowser.currentURI.spec == state1.windows[0].tabs[2].entries[0].url)
|
||||
loadedWindow1 = true;
|
||||
if (aBrowser.currentURI.spec == state1.windows[1].tabs[0].entries[0].url)
|
||||
loadedWindow2 = true;
|
||||
|
||||
if (!interruptedAfter && loadedWindow1 && loadedWindow2) {
|
||||
interruptedAfter = loadCount;
|
||||
ss.setBrowserState(JSON.stringify(state2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (loadCount < numTabs + interruptedAfter)
|
||||
return;
|
||||
|
||||
// We don't actually care about load order in this test, just that they all
|
||||
// do load.
|
||||
is(loadCount, numTabs + interruptedAfter, "all tabs were restored");
|
||||
is(aNeedRestore, 0, "there are no tabs left needing restore");
|
||||
|
||||
// Remove the progress listener.
|
||||
gProgressListener.unsetCallback();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
// We also want to catch the extra windows (there should be 2), so we need to observe domwindowopened
|
||||
Services.ww.registerNotification(function observer(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowopened") {
|
||||
let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad);
|
||||
Services.ww.unregisterNotification(observer);
|
||||
win.gBrowser.addTabsProgressListener(gProgressListener);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
let backupState = ss.getBrowserState();
|
||||
ss.setBrowserState(JSON.stringify(state1));
|
||||
yield promiseRestoringTabs;
|
||||
|
||||
// Cleanup.
|
||||
yield promiseAllButPrimaryWindowClosed();
|
||||
yield promiseBrowserState(backupState);
|
||||
});
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
|
||||
|
||||
add_task(function* test() {
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
|
||||
});
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.com" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com" }], extData: { "uniq": r() } }
|
||||
] }] };
|
||||
|
||||
let expectedCounts = [
|
||||
[3, 3, 0],
|
||||
[2, 3, 1],
|
||||
[1, 3, 2],
|
||||
[0, 3, 3],
|
||||
[0, 2, 4],
|
||||
[0, 1, 5]
|
||||
];
|
||||
|
||||
let loadCount = 0;
|
||||
let promiseRestoringTabs = new Promise(resolve => {
|
||||
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
|
||||
loadCount++;
|
||||
let expected = expectedCounts[loadCount - 1];
|
||||
|
||||
is(aNeedRestore, expected[0], "load " + loadCount + " - # tabs that need to be restored");
|
||||
is(aRestoring, expected[1], "load " + loadCount + " - # tabs that are restoring");
|
||||
is(aRestored, expected[2], "load " + loadCount + " - # tabs that has been restored");
|
||||
|
||||
if (loadCount == state.windows[0].tabs.length) {
|
||||
gProgressListener.unsetCallback();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let backupState = ss.getBrowserState();
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
yield promiseRestoringTabs;
|
||||
|
||||
// Cleanup.
|
||||
yield promiseBrowserState(backupState);
|
||||
});
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
|
||||
|
||||
add_task(function* test() {
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
|
||||
});
|
||||
|
||||
// The first window will be put into the already open window and the second
|
||||
// window will be opened with _openWindowWithState, which is the source of the problem.
|
||||
let state = { windows: [
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.org#0" }], extData: { "uniq": r() } }
|
||||
],
|
||||
selected: 1
|
||||
},
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.com#1" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#2" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#3" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#4" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#5" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#6" }], extData: { "uniq": r() } }
|
||||
],
|
||||
selected: 4
|
||||
}
|
||||
] };
|
||||
let numTabs = state.windows[0].tabs.length + state.windows[1].tabs.length;
|
||||
|
||||
let loadCount = 0;
|
||||
let promiseRestoringTabs = new Promise(resolve => {
|
||||
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
|
||||
if (++loadCount == numTabs) {
|
||||
// We don't actually care about load order in this test, just that they all
|
||||
// do load.
|
||||
is(loadCount, numTabs, "all tabs were restored");
|
||||
is(aNeedRestore, 0, "there are no tabs left needing restore");
|
||||
|
||||
gProgressListener.unsetCallback();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// We also want to catch the 2nd window, so we need to observe domwindowopened
|
||||
Services.ww.registerNotification(function observer(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowopened") {
|
||||
let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad);
|
||||
Services.ww.unregisterNotification(observer);
|
||||
win.gBrowser.addTabsProgressListener(gProgressListener);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
let backupState = ss.getBrowserState();
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
yield promiseRestoringTabs;
|
||||
|
||||
// Cleanup.
|
||||
yield promiseAllButPrimaryWindowClosed();
|
||||
yield promiseBrowserState(backupState);
|
||||
});
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
|
||||
|
||||
add_task(function* test() {
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
|
||||
});
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org/#1" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#2" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#3" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#4" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#5" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#6" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#7" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#8" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#9" }], extData: { "uniq": r() } },
|
||||
], selected: 1 }] };
|
||||
|
||||
let loadCount = 0;
|
||||
let promiseRestoringTabs = new Promise(resolve => {
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", function onRestored(event) {
|
||||
let tab = event.target;
|
||||
let browser = tab.linkedBrowser;
|
||||
let tabData = state.windows[0].tabs[loadCount++];
|
||||
|
||||
// double check that this tab was the right one
|
||||
is(browser.currentURI.spec, tabData.entries[0].url,
|
||||
"load " + loadCount + " - browser loaded correct url");
|
||||
is(ss.getTabValue(tab, "uniq"), tabData.extData.uniq,
|
||||
"load " + loadCount + " - correct tab was restored");
|
||||
|
||||
if (loadCount == state.windows[0].tabs.length) {
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onRestored);
|
||||
resolve();
|
||||
} else {
|
||||
// reload the next tab
|
||||
gBrowser.browsers[loadCount].reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let backupState = ss.getBrowserState();
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
yield promiseRestoringTabs;
|
||||
|
||||
// Cleanup.
|
||||
yield promiseBrowserState(backupState);
|
||||
});
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
|
||||
|
||||
add_task(function* test() {
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
|
||||
});
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org" }], extData: { "uniq": r() } }
|
||||
], selected: 1 }] };
|
||||
|
||||
let expectedCounts = [
|
||||
[5, 1, 0],
|
||||
[4, 1, 1],
|
||||
[3, 1, 2],
|
||||
[2, 1, 3],
|
||||
[1, 1, 4],
|
||||
[0, 1, 5]
|
||||
];
|
||||
let tabOrder = [0, 5, 1, 4, 3, 2];
|
||||
|
||||
let loadCount = 0;
|
||||
let promiseRestoringTabs = new Promise(resolve => {
|
||||
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
|
||||
loadCount++;
|
||||
let expected = expectedCounts[loadCount - 1];
|
||||
|
||||
is(aNeedRestore, expected[0], "load " + loadCount + " - # tabs that need to be restored");
|
||||
is(aRestoring, expected[1], "load " + loadCount + " - # tabs that are restoring");
|
||||
is(aRestored, expected[2], "load " + loadCount + " - # tabs that has been restored");
|
||||
|
||||
if (loadCount < state.windows[0].tabs.length) {
|
||||
// double check that this tab was the right one
|
||||
let expectedData = state.windows[0].tabs[tabOrder[loadCount - 1]].extData.uniq;
|
||||
let tab;
|
||||
for (let i = 0; i < window.gBrowser.tabs.length; i++) {
|
||||
if (!tab && window.gBrowser.tabs[i].linkedBrowser == aBrowser)
|
||||
tab = window.gBrowser.tabs[i];
|
||||
}
|
||||
|
||||
is(ss.getTabValue(tab, "uniq"), expectedData,
|
||||
"load " + loadCount + " - correct tab was restored");
|
||||
|
||||
// select the next tab
|
||||
window.gBrowser.selectTabAtIndex(tabOrder[loadCount]);
|
||||
} else {
|
||||
gProgressListener.unsetCallback();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let backupState = ss.getBrowserState();
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
yield promiseRestoringTabs;
|
||||
|
||||
// Cleanup.
|
||||
yield promiseBrowserState(backupState);
|
||||
});
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
|
||||
|
||||
add_task(function* test() {
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
|
||||
});
|
||||
|
||||
// We'll use 2 states so that we can make sure calling setWindowState doesn't
|
||||
// wipe out currently restoring data.
|
||||
let state1 = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.com#1" }] },
|
||||
{ entries: [{ url: "http://example.com#2" }] },
|
||||
{ entries: [{ url: "http://example.com#3" }] },
|
||||
{ entries: [{ url: "http://example.com#4" }] },
|
||||
{ entries: [{ url: "http://example.com#5" }] },
|
||||
] }] };
|
||||
let state2 = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org#1" }] },
|
||||
{ entries: [{ url: "http://example.org#2" }] },
|
||||
{ entries: [{ url: "http://example.org#3" }] },
|
||||
{ entries: [{ url: "http://example.org#4" }] },
|
||||
{ entries: [{ url: "http://example.org#5" }] }
|
||||
] }] };
|
||||
let numTabs = state1.windows[0].tabs.length + state2.windows[0].tabs.length;
|
||||
|
||||
let loadCount = 0;
|
||||
let promiseRestoringTabs = new Promise(resolve => {
|
||||
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
|
||||
// When loadCount == 2, we'll also restore state2 into the window
|
||||
if (++loadCount == 2) {
|
||||
ss.setWindowState(window, JSON.stringify(state2), false);
|
||||
}
|
||||
|
||||
if (loadCount < numTabs) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't actually care about load order in this test, just that they all
|
||||
// do load.
|
||||
is(loadCount, numTabs, "test_setWindowStateNoOverwrite: all tabs were restored");
|
||||
is(aNeedRestore, 0, "there are no tabs left needing restore");
|
||||
|
||||
gProgressListener.unsetCallback();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let backupState = ss.getBrowserState();
|
||||
ss.setWindowState(window, JSON.stringify(state1), true);
|
||||
yield promiseRestoringTabs;
|
||||
|
||||
// Cleanup.
|
||||
yield promiseBrowserState(backupState);
|
||||
});
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
|
||||
|
||||
add_task(function* test() {
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
|
||||
});
|
||||
|
||||
// We'll use 2 states so that we can make sure calling setWindowState doesn't
|
||||
// wipe out currently restoring data.
|
||||
let state1 = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.com#1" }] },
|
||||
{ entries: [{ url: "http://example.com#2" }] },
|
||||
{ entries: [{ url: "http://example.com#3" }] },
|
||||
{ entries: [{ url: "http://example.com#4" }] },
|
||||
{ entries: [{ url: "http://example.com#5" }] },
|
||||
] }] };
|
||||
let state2 = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org#1" }] },
|
||||
{ entries: [{ url: "http://example.org#2" }] },
|
||||
{ entries: [{ url: "http://example.org#3" }] },
|
||||
{ entries: [{ url: "http://example.org#4" }] },
|
||||
{ entries: [{ url: "http://example.org#5" }] }
|
||||
] }] };
|
||||
let numTabs = 2 + state2.windows[0].tabs.length;
|
||||
|
||||
let loadCount = 0;
|
||||
let promiseRestoringTabs = new Promise(resolve => {
|
||||
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
|
||||
// When loadCount == 2, we'll also restore state2 into the window
|
||||
if (++loadCount == 2) {
|
||||
executeSoon(() => ss.setWindowState(window, JSON.stringify(state2), true));
|
||||
}
|
||||
|
||||
if (loadCount < numTabs) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't actually care about load order in this test, just that they all
|
||||
// do load.
|
||||
is(loadCount, numTabs, "all tabs were restored");
|
||||
is(aNeedRestore, 0, "there are no tabs left needing restore");
|
||||
|
||||
gProgressListener.unsetCallback();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let backupState = ss.getBrowserState();
|
||||
ss.setWindowState(window, JSON.stringify(state1), true);
|
||||
yield promiseRestoringTabs;
|
||||
|
||||
// Cleanup.
|
||||
yield promiseBrowserState(backupState);
|
||||
});
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function observeOneRestore(callback) {
|
||||
let topic = "sessionstore-browser-state-restored";
|
||||
Services.obs.addObserver(function onRestore() {
|
||||
Services.obs.removeObserver(onRestore, topic);
|
||||
callback();
|
||||
}, topic, false);
|
||||
};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// There should be one tab when we start the test
|
||||
let [origTab] = gBrowser.visibleTabs;
|
||||
let hiddenTab = gBrowser.addTab();
|
||||
|
||||
is(gBrowser.visibleTabs.length, 2, "should have 2 tabs before hiding");
|
||||
gBrowser.showOnlyTheseTabs([origTab]);
|
||||
is(gBrowser.visibleTabs.length, 1, "only 1 after hiding");
|
||||
ok(hiddenTab.hidden, "sanity check that it's hidden");
|
||||
|
||||
let extraTab = gBrowser.addTab();
|
||||
let state = ss.getBrowserState();
|
||||
let stateObj = JSON.parse(state);
|
||||
let tabs = stateObj.windows[0].tabs;
|
||||
is(tabs.length, 3, "just checking that browser state is correct");
|
||||
ok(!tabs[0].hidden, "first tab is visible");
|
||||
ok(tabs[1].hidden, "second is hidden");
|
||||
ok(!tabs[2].hidden, "third is visible");
|
||||
|
||||
// Make the third tab hidden and then restore the modified state object
|
||||
tabs[2].hidden = true;
|
||||
|
||||
observeOneRestore(function() {
|
||||
let testWindow = Services.wm.getEnumerator("navigator:browser").getNext();
|
||||
is(testWindow.gBrowser.visibleTabs.length, 1, "only restored 1 visible tab");
|
||||
let tabs = testWindow.gBrowser.tabs;
|
||||
ok(!tabs[0].hidden, "first is still visible");
|
||||
ok(tabs[1].hidden, "second tab is still hidden");
|
||||
ok(tabs[2].hidden, "third tab is now hidden");
|
||||
|
||||
// Restore the original state and clean up now that we're done
|
||||
gBrowser.removeTab(hiddenTab);
|
||||
gBrowser.removeTab(extraTab);
|
||||
|
||||
finish();
|
||||
});
|
||||
ss.setBrowserState(JSON.stringify(stateObj));
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let state = { windows: [{ tabs: [
|
||||
{entries: [{url: "about:mozilla"}], hidden: true},
|
||||
{entries: [{url: "about:rights"}], hidden: true}
|
||||
] }] };
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
newWindowWithState(state, function (win) {
|
||||
registerCleanupFunction(() => BrowserTestUtils.closeWindow(win));
|
||||
|
||||
is(win.gBrowser.tabs.length, 2, "two tabs were restored");
|
||||
is(win.gBrowser.visibleTabs.length, 1, "one tab is visible");
|
||||
|
||||
let tab = win.gBrowser.visibleTabs[0];
|
||||
is(tab.linkedBrowser.currentURI.spec, "about:mozilla", "visible tab is about:mozilla");
|
||||
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function newWindowWithState(state, callback) {
|
||||
let opts = "chrome,all,dialog=no,height=800,width=800";
|
||||
let win = window.openDialog(getBrowserURL(), "_blank", opts);
|
||||
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
|
||||
executeSoon(function () {
|
||||
win.addEventListener("SSWindowStateReady", function onReady() {
|
||||
win.removeEventListener("SSWindowStateReady", onReady, false);
|
||||
promiseTabRestored(win.gBrowser.tabs[0]).then(() => callback(win));
|
||||
}, false);
|
||||
|
||||
ss.setWindowState(win, JSON.stringify(state), true);
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
|
@ -1,242 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Mirrors WINDOW_ATTRIBUTES IN nsSessionStore.js
|
||||
const WINDOW_ATTRIBUTES = ["width", "height", "screenX", "screenY", "sizemode"];
|
||||
|
||||
var stateBackup = ss.getBrowserState();
|
||||
|
||||
var originalWarnOnClose = gPrefService.getBoolPref("browser.tabs.warnOnClose");
|
||||
var originalStartupPage = gPrefService.getIntPref("browser.startup.page");
|
||||
var originalWindowType = document.documentElement.getAttribute("windowtype");
|
||||
|
||||
var gotLastWindowClosedTopic = false;
|
||||
var shouldPinTab = false;
|
||||
var shouldOpenTabs = false;
|
||||
var shouldCloseTab = false;
|
||||
var testNum = 0;
|
||||
var afterTestCallback;
|
||||
|
||||
// Set state so we know the closed windows content
|
||||
var testState = {
|
||||
windows: [
|
||||
{ tabs: [{ entries: [{ url: "http://example.org" }] }] }
|
||||
],
|
||||
_closedWindows: []
|
||||
};
|
||||
|
||||
// We'll push a set of conditions and callbacks into this array
|
||||
// Ideally we would also test win/linux under a complete set of conditions, but
|
||||
// the tests for osx mirror the other set of conditions possible on win/linux.
|
||||
var tests = [];
|
||||
|
||||
// the third & fourth test share a condition check, keep it DRY
|
||||
function checkOSX34Generator(num) {
|
||||
return function(aPreviousState, aCurState) {
|
||||
// In here, we should have restored the pinned tab, so only the unpinned tab
|
||||
// should be in aCurState. So let's shape our expectations.
|
||||
let expectedState = JSON.parse(aPreviousState);
|
||||
expectedState[0].tabs.shift();
|
||||
// size attributes are stripped out in _prepDataForDeferredRestore in nsSessionStore.
|
||||
// This isn't the best approach, but neither is comparing JSON strings
|
||||
WINDOW_ATTRIBUTES.forEach(attr => delete expectedState[0][attr]);
|
||||
|
||||
is(aCurState, JSON.stringify(expectedState),
|
||||
"test #" + num + ": closedWindowState is as expected");
|
||||
};
|
||||
}
|
||||
function checkNoWindowsGenerator(num) {
|
||||
return function(aPreviousState, aCurState) {
|
||||
is(aCurState, "[]", "test #" + num + ": there should be no closedWindowsLeft");
|
||||
};
|
||||
}
|
||||
|
||||
// The first test has 0 pinned tabs and 1 unpinned tab
|
||||
tests.push({
|
||||
pinned: false,
|
||||
extra: false,
|
||||
close: false,
|
||||
checkWinLin: checkNoWindowsGenerator(1),
|
||||
checkOSX: function(aPreviousState, aCurState) {
|
||||
is(aCurState, aPreviousState, "test #1: closed window state is unchanged");
|
||||
}
|
||||
});
|
||||
|
||||
// The second test has 1 pinned tab and 0 unpinned tabs.
|
||||
tests.push({
|
||||
pinned: true,
|
||||
extra: false,
|
||||
close: false,
|
||||
checkWinLin: checkNoWindowsGenerator(2),
|
||||
checkOSX: checkNoWindowsGenerator(2)
|
||||
});
|
||||
|
||||
// The third test has 1 pinned tab and 2 unpinned tabs.
|
||||
tests.push({
|
||||
pinned: true,
|
||||
extra: true,
|
||||
close: false,
|
||||
checkWinLin: checkNoWindowsGenerator(3),
|
||||
checkOSX: checkOSX34Generator(3)
|
||||
});
|
||||
|
||||
// The fourth test has 1 pinned tab, 2 unpinned tabs, and closes one unpinned tab.
|
||||
tests.push({
|
||||
pinned: true,
|
||||
extra: true,
|
||||
close: "one",
|
||||
checkWinLin: checkNoWindowsGenerator(4),
|
||||
checkOSX: checkOSX34Generator(4)
|
||||
});
|
||||
|
||||
// The fifth test has 1 pinned tab, 2 unpinned tabs, and closes both unpinned tabs.
|
||||
tests.push({
|
||||
pinned: true,
|
||||
extra: true,
|
||||
close: "both",
|
||||
checkWinLin: checkNoWindowsGenerator(5),
|
||||
checkOSX: checkNoWindowsGenerator(5)
|
||||
});
|
||||
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 589246 - Closed window state getting corrupted when closing
|
||||
and reopening last browser window without exiting browser **/
|
||||
waitForExplicitFinish();
|
||||
// windows opening & closing, so extending the timeout
|
||||
requestLongerTimeout(2);
|
||||
|
||||
// We don't want the quit dialog pref
|
||||
gPrefService.setBoolPref("browser.tabs.warnOnClose", false);
|
||||
// Ensure that we would restore the session (important for Windows)
|
||||
gPrefService.setIntPref("browser.startup.page", 3);
|
||||
|
||||
runNextTestOrFinish();
|
||||
}
|
||||
|
||||
function runNextTestOrFinish() {
|
||||
if (tests.length) {
|
||||
setupForTest(tests.shift())
|
||||
}
|
||||
else {
|
||||
// some state is cleaned up at the end of each test, but not all
|
||||
["browser.tabs.warnOnClose", "browser.startup.page"].forEach(function(p) {
|
||||
if (gPrefService.prefHasUserValue(p))
|
||||
gPrefService.clearUserPref(p);
|
||||
});
|
||||
|
||||
ss.setBrowserState(stateBackup);
|
||||
executeSoon(finish);
|
||||
}
|
||||
}
|
||||
|
||||
function setupForTest(aConditions) {
|
||||
// reset some checks
|
||||
gotLastWindowClosedTopic = false;
|
||||
shouldPinTab = aConditions.pinned;
|
||||
shouldOpenTabs = aConditions.extra;
|
||||
shouldCloseTab = aConditions.close;
|
||||
testNum++;
|
||||
|
||||
// set our test callback
|
||||
afterTestCallback = /Mac/.test(navigator.platform) ? aConditions.checkOSX
|
||||
: aConditions.checkWinLin;
|
||||
|
||||
// Add observers
|
||||
Services.obs.addObserver(onLastWindowClosed, "browser-lastwindow-close-granted", false);
|
||||
|
||||
// Set the state
|
||||
Services.obs.addObserver(onStateRestored, "sessionstore-browser-state-restored", false);
|
||||
ss.setBrowserState(JSON.stringify(testState));
|
||||
}
|
||||
|
||||
function onStateRestored(aSubject, aTopic, aData) {
|
||||
info("test #" + testNum + ": onStateRestored");
|
||||
Services.obs.removeObserver(onStateRestored, "sessionstore-browser-state-restored");
|
||||
|
||||
// change this window's windowtype so that closing a new window will trigger
|
||||
// browser-lastwindow-close-granted.
|
||||
document.documentElement.setAttribute("windowtype", "navigator:testrunner");
|
||||
|
||||
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "http://example.com");
|
||||
newWin.addEventListener("load", function(aEvent) {
|
||||
newWin.removeEventListener("load", arguments.callee, false);
|
||||
|
||||
promiseBrowserLoaded(newWin.gBrowser.selectedBrowser).then(() => {
|
||||
// pin this tab
|
||||
if (shouldPinTab)
|
||||
newWin.gBrowser.pinTab(newWin.gBrowser.selectedTab);
|
||||
|
||||
newWin.addEventListener("unload", function () {
|
||||
newWin.removeEventListener("unload", arguments.callee, false);
|
||||
onWindowUnloaded();
|
||||
}, false);
|
||||
// Open a new tab as well. On Windows/Linux this will be restored when the
|
||||
// new window is opened below (in onWindowUnloaded). On OS X we'll just
|
||||
// restore the pinned tabs, leaving the unpinned tab in the closedWindowsData.
|
||||
if (shouldOpenTabs) {
|
||||
let newTab = newWin.gBrowser.addTab("about:config");
|
||||
let newTab2 = newWin.gBrowser.addTab("about:buildconfig");
|
||||
|
||||
newTab.linkedBrowser.addEventListener("load", function() {
|
||||
newTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
if (shouldCloseTab == "one") {
|
||||
newWin.gBrowser.removeTab(newTab2);
|
||||
}
|
||||
else if (shouldCloseTab == "both") {
|
||||
newWin.gBrowser.removeTab(newTab);
|
||||
newWin.gBrowser.removeTab(newTab2);
|
||||
}
|
||||
newWin.BrowserTryToCloseWindow();
|
||||
}, true);
|
||||
}
|
||||
else {
|
||||
newWin.BrowserTryToCloseWindow();
|
||||
}
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
// This will be called before the window is actually closed
|
||||
function onLastWindowClosed(aSubject, aTopic, aData) {
|
||||
info("test #" + testNum + ": onLastWindowClosed");
|
||||
Services.obs.removeObserver(onLastWindowClosed, "browser-lastwindow-close-granted");
|
||||
gotLastWindowClosedTopic = true;
|
||||
}
|
||||
|
||||
// This is the unload event listener on the new window (from onStateRestored).
|
||||
// Unload is fired after the window is closed, so sessionstore has already
|
||||
// updated _closedWindows (which is important). We'll open a new window here
|
||||
// which should actually trigger the bug.
|
||||
function onWindowUnloaded() {
|
||||
info("test #" + testNum + ": onWindowClosed");
|
||||
ok(gotLastWindowClosedTopic, "test #" + testNum + ": browser-lastwindow-close-granted was notified prior");
|
||||
|
||||
let previousClosedWindowData = ss.getClosedWindowData();
|
||||
|
||||
// Now we want to open a new window
|
||||
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "about:mozilla");
|
||||
newWin.addEventListener("load", function(aEvent) {
|
||||
newWin.removeEventListener("load", arguments.callee, false);
|
||||
|
||||
newWin.gBrowser.selectedBrowser.addEventListener("load", function () {
|
||||
newWin.gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
// Good enough for checking the state
|
||||
afterTestCallback(previousClosedWindowData, ss.getClosedWindowData());
|
||||
afterTestCleanup(newWin);
|
||||
}, true);
|
||||
|
||||
}, false);
|
||||
}
|
||||
|
||||
function afterTestCleanup(aNewWin) {
|
||||
executeSoon(function() {
|
||||
BrowserTestUtils.closeWindow(aNewWin).then(() => {
|
||||
document.documentElement.setAttribute("windowtype", originalWindowType);
|
||||
runNextTestOrFinish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const NUM_TABS = 12;
|
||||
|
||||
var stateBackup = ss.getBrowserState();
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 590268 - Provide access to sessionstore tab data sooner **/
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let startedTest = false;
|
||||
|
||||
// wasLoaded will be used to keep track of tabs that have already had SSTabRestoring
|
||||
// fired for them.
|
||||
let wasLoaded = { };
|
||||
let restoringTabsCount = 0;
|
||||
let restoredTabsCount = 0;
|
||||
let uniq2 = { };
|
||||
let uniq2Count = 0;
|
||||
let state = { windows: [{ tabs: [] }] };
|
||||
// We're going to put a bunch of tabs into this state
|
||||
for (let i = 0; i < NUM_TABS; i++) {
|
||||
let uniq = r();
|
||||
let tabData = {
|
||||
entries: [{ url: "http://example.com/#" + i }],
|
||||
extData: { "uniq": uniq, "baz": "qux" }
|
||||
};
|
||||
state.windows[0].tabs.push(tabData);
|
||||
wasLoaded[uniq] = false;
|
||||
}
|
||||
|
||||
|
||||
function onSSTabRestoring(aEvent) {
|
||||
restoringTabsCount++;
|
||||
let uniq = ss.getTabValue(aEvent.originalTarget, "uniq");
|
||||
wasLoaded[uniq] = true;
|
||||
|
||||
is(ss.getTabValue(aEvent.originalTarget, "foo"), "",
|
||||
"There is no value for 'foo'");
|
||||
|
||||
// On the first SSTabRestoring we're going to run the the real test.
|
||||
// We'll keep this listener around so we can keep marking tabs as restored.
|
||||
if (restoringTabsCount == 1)
|
||||
onFirstSSTabRestoring();
|
||||
else if (restoringTabsCount == NUM_TABS)
|
||||
onLastSSTabRestoring();
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
if (++restoredTabsCount < NUM_TABS)
|
||||
return;
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function onTabOpen(aEvent) {
|
||||
// To test bug 614708, we'll just set a value on the tab here. This value
|
||||
// would previously cause us to not recognize the values in extData until
|
||||
// much later. So testing "uniq" failed.
|
||||
ss.setTabValue(aEvent.originalTarget, "foo", "bar");
|
||||
}
|
||||
|
||||
// This does the actual testing. SSTabRestoring should be firing on tabs from
|
||||
// left to right, so we're going to start with the rightmost tab.
|
||||
function onFirstSSTabRestoring() {
|
||||
info("onFirstSSTabRestoring...");
|
||||
for (let i = gBrowser.tabs.length - 1; i >= 0; i--) {
|
||||
let tab = gBrowser.tabs[i];
|
||||
let actualUniq = ss.getTabValue(tab, "uniq");
|
||||
let expectedUniq = state.windows[0].tabs[i].extData["uniq"];
|
||||
|
||||
if (wasLoaded[actualUniq]) {
|
||||
info("tab " + i + ": already restored");
|
||||
continue;
|
||||
}
|
||||
is(actualUniq, expectedUniq, "tab " + i + ": extData was correct");
|
||||
|
||||
// Now we're going to set a piece of data back on the tab so it can be read
|
||||
// to test setting a value "early".
|
||||
uniq2[actualUniq] = r();
|
||||
ss.setTabValue(tab, "uniq2", uniq2[actualUniq]);
|
||||
|
||||
// Delete the value we have for "baz". This tests that deleteTabValue
|
||||
// will delete "early access" values (c.f. bug 617175). If this doesn't throw
|
||||
// then the test is successful.
|
||||
try {
|
||||
ss.deleteTabValue(tab, "baz");
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "no error calling deleteTabValue - " + e);
|
||||
}
|
||||
|
||||
// This will be used in the final comparison to make sure we checked the
|
||||
// same number as we set.
|
||||
uniq2Count++;
|
||||
}
|
||||
}
|
||||
|
||||
function onLastSSTabRestoring() {
|
||||
let checked = 0;
|
||||
for (let i = 0; i < gBrowser.tabs.length; i++) {
|
||||
let tab = gBrowser.tabs[i];
|
||||
let uniq = ss.getTabValue(tab, "uniq");
|
||||
|
||||
// Look to see if we set a uniq2 value for this uniq value
|
||||
if (uniq in uniq2) {
|
||||
is(ss.getTabValue(tab, "uniq2"), uniq2[uniq], "tab " + i + " has correct uniq2 value");
|
||||
checked++;
|
||||
}
|
||||
}
|
||||
ok(uniq2Count > 0, "at least 1 tab properly checked 'early access'");
|
||||
is(checked, uniq2Count, "checked the same number of uniq2 as we set");
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
// remove the event listener and clean up before finishing
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestoring", onSSTabRestoring, false);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, true);
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, false);
|
||||
// Put this in an executeSoon because we still haven't called restoreNextTab
|
||||
// in sessionstore for the last tab (we'll call it after this). We end up
|
||||
// trying to restore the tab (since we then add a closed tab to the array).
|
||||
executeSoon(function() {
|
||||
ss.setBrowserState(stateBackup);
|
||||
executeSoon(finish);
|
||||
});
|
||||
}
|
||||
|
||||
// Add the event listeners
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestoring", onSSTabRestoring, false);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, true);
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, false);
|
||||
// Restore state
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let sessionData = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: "about:mozilla" }], hidden: true },
|
||||
{ entries: [{ url: "about:blank" }], hidden: false }
|
||||
]
|
||||
}]
|
||||
};
|
||||
let url = "about:sessionrestore";
|
||||
let formdata = {id: {sessionData}, url};
|
||||
let state = { windows: [{ tabs: [{ entries: [{url}], formdata }] }] };
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
newWindowWithState(state, function (win) {
|
||||
registerCleanupFunction(() => BrowserTestUtils.closeWindow(win));
|
||||
|
||||
is(gBrowser.tabs.length, 1, "The total number of tabs should be 1");
|
||||
is(gBrowser.visibleTabs.length, 1, "The total number of visible tabs should be 1");
|
||||
|
||||
executeSoon(function () {
|
||||
waitForFocus(function () {
|
||||
middleClickTest(win);
|
||||
finish();
|
||||
}, win);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function middleClickTest(win) {
|
||||
let browser = win.gBrowser.selectedBrowser;
|
||||
let tree = browser.contentDocument.getElementById("tabList");
|
||||
is(tree.view.rowCount, 3, "There should be three items");
|
||||
|
||||
// click on the first tab item
|
||||
var rect = tree.treeBoxObject.getCoordsForCellItem(1, tree.columns[1], "text");
|
||||
EventUtils.synthesizeMouse(tree.body, rect.x, rect.y, { button: 1 },
|
||||
browser.contentWindow);
|
||||
// click on the second tab item
|
||||
rect = tree.treeBoxObject.getCoordsForCellItem(2, tree.columns[1], "text");
|
||||
EventUtils.synthesizeMouse(tree.body, rect.x, rect.y, { button: 1 },
|
||||
browser.contentWindow);
|
||||
|
||||
is(win.gBrowser.tabs.length, 3,
|
||||
"The total number of tabs should be 3 after restoring 2 tabs by middle click.");
|
||||
is(win.gBrowser.visibleTabs.length, 3,
|
||||
"The total number of visible tabs should be 3 after restoring 2 tabs by middle click");
|
||||
}
|
||||
|
||||
function newWindowWithState(state, callback) {
|
||||
let opts = "chrome,all,dialog=no,height=800,width=800";
|
||||
let win = window.openDialog(getBrowserURL(), "_blank", opts);
|
||||
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
|
||||
let tab = win.gBrowser.selectedTab;
|
||||
|
||||
// The form data will be restored before SSTabRestored, so we want to listen
|
||||
// for that on the currently selected tab (it will be reused)
|
||||
tab.addEventListener("SSTabRestored", function onRestored() {
|
||||
tab.removeEventListener("SSTabRestored", onRestored, true);
|
||||
callback(win);
|
||||
}, true);
|
||||
|
||||
executeSoon(function () {
|
||||
ss.setWindowState(win, JSON.stringify(state), true);
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
var state = {windows:[{tabs:[
|
||||
{entries:[{url:"http://example.com#1"}]},
|
||||
{entries:[{url:"http://example.com#2"}]},
|
||||
{entries:[{url:"http://example.com#3"}]},
|
||||
{entries:[{url:"http://example.com#4"}]},
|
||||
{entries:[{url:"http://example.com#5"}], hidden: true},
|
||||
{entries:[{url:"http://example.com#6"}], hidden: true},
|
||||
{entries:[{url:"http://example.com#7"}], hidden: true},
|
||||
{entries:[{url:"http://example.com#8"}], hidden: true}
|
||||
]}]};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(2);
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs");
|
||||
});
|
||||
|
||||
// First stage: restoreHiddenTabs = true
|
||||
// Second stage: restoreHiddenTabs = false
|
||||
test_loadTabs(true, function () {
|
||||
test_loadTabs(false, finish);
|
||||
});
|
||||
}
|
||||
|
||||
function test_loadTabs(restoreHiddenTabs, callback) {
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_hidden_tabs", restoreHiddenTabs);
|
||||
|
||||
let expectedTabs = restoreHiddenTabs ? 8 : 4;
|
||||
let firstProgress = true;
|
||||
|
||||
newWindowWithState(state, function (win, needsRestore, isRestoring) {
|
||||
if (firstProgress) {
|
||||
firstProgress = false;
|
||||
is(isRestoring, 3, "restoring 3 tabs concurrently");
|
||||
} else {
|
||||
ok(isRestoring < 4, "restoring max. 3 tabs concurrently");
|
||||
}
|
||||
|
||||
// We're explicity checking for (isRestoring == 1) here because the test
|
||||
// progress listener is called before the session store one. So when we're
|
||||
// called with one tab left to restore we know that the last tab has
|
||||
// finished restoring and will soon be handled by the SS listener.
|
||||
let tabsNeedingRestore = win.gBrowser.tabs.length - needsRestore;
|
||||
if (isRestoring == 1 && tabsNeedingRestore == expectedTabs) {
|
||||
is(win.gBrowser.visibleTabs.length, 4, "only 4 visible tabs");
|
||||
|
||||
TabsProgressListener.uninit();
|
||||
executeSoon(callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var TabsProgressListener = {
|
||||
init: function (win) {
|
||||
this.window = win;
|
||||
Services.obs.addObserver(this, "sessionstore-debug-tab-restored", false);
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
Services.obs.removeObserver(this, "sessionstore-debug-tab-restored");
|
||||
|
||||
delete this.window;
|
||||
delete this.callback;
|
||||
},
|
||||
|
||||
setCallback: function (callback) {
|
||||
this.callback = callback;
|
||||
},
|
||||
|
||||
observe: function (browser) {
|
||||
TabsProgressListener.onRestored(browser);
|
||||
},
|
||||
|
||||
onRestored: function (browser) {
|
||||
if (this.callback && browser.__SS_restoreState == TAB_STATE_RESTORING)
|
||||
this.callback.apply(null, [this.window].concat(this.countTabs()));
|
||||
},
|
||||
|
||||
countTabs: function () {
|
||||
let needsRestore = 0, isRestoring = 0;
|
||||
|
||||
for (let i = 0; i < this.window.gBrowser.tabs.length; i++) {
|
||||
let browser = this.window.gBrowser.tabs[i].linkedBrowser;
|
||||
if (browser.__SS_restoreState == TAB_STATE_RESTORING)
|
||||
isRestoring++;
|
||||
else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
|
||||
needsRestore++;
|
||||
}
|
||||
|
||||
return [needsRestore, isRestoring];
|
||||
}
|
||||
}
|
||||
|
||||
// ----------
|
||||
function newWindowWithState(state, callback) {
|
||||
let opts = "chrome,all,dialog=no,height=800,width=800";
|
||||
let win = window.openDialog(getBrowserURL(), "_blank", opts);
|
||||
|
||||
registerCleanupFunction(() => BrowserTestUtils.closeWindow(win));
|
||||
|
||||
whenWindowLoaded(win, function onWindowLoaded(aWin) {
|
||||
TabsProgressListener.init(aWin);
|
||||
TabsProgressListener.setCallback(callback);
|
||||
|
||||
ss.setWindowState(aWin, JSON.stringify(state), true);
|
||||
});
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 597071 - Closed windows should only be resurrected when there is a single
|
||||
* popup window
|
||||
*/
|
||||
add_task(function test_close_last_nonpopup_window() {
|
||||
// Purge the list of closed windows.
|
||||
forgetClosedWindows();
|
||||
|
||||
let oldState = ss.getWindowState(window);
|
||||
|
||||
let popupState = {windows: [
|
||||
{tabs: [{entries: []}], isPopup: true, hidden: "toolbar"}
|
||||
]};
|
||||
|
||||
// Set this window to be a popup.
|
||||
ss.setWindowState(window, JSON.stringify(popupState), true);
|
||||
|
||||
// Open a new window with a tab.
|
||||
let win = yield BrowserTestUtils.openNewBrowserWindow({private: false});
|
||||
let tab = win.gBrowser.addTab("http://example.com/");
|
||||
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
|
||||
|
||||
// Make sure sessionstore sees this window.
|
||||
let state = JSON.parse(ss.getBrowserState());
|
||||
is(state.windows.length, 2, "sessionstore knows about this window");
|
||||
|
||||
// Closed the window and check the closed window count.
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
is(ss.getClosedWindowCount(), 1, "correct closed window count");
|
||||
|
||||
// Cleanup.
|
||||
ss.setWindowState(window, oldState, true);
|
||||
});
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var stateBackup = ss.getBrowserState();
|
||||
|
||||
function cleanup() {
|
||||
// Reset the pref
|
||||
try {
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
|
||||
} catch (e) {}
|
||||
ss.setBrowserState(stateBackup);
|
||||
executeSoon(finish);
|
||||
}
|
||||
|
||||
function test() {
|
||||
/** Bug 599909 - to-be-reloaded tabs don't show up in switch-to-tab **/
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Set the pref to true so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org/#1" }] },
|
||||
{ entries: [{ url: "http://example.org/#2" }] },
|
||||
{ entries: [{ url: "http://example.org/#3" }] },
|
||||
{ entries: [{ url: "http://example.org/#4" }] }
|
||||
], selected: 1 }] };
|
||||
|
||||
let tabsForEnsure = {};
|
||||
state.windows[0].tabs.forEach(function(tab) {
|
||||
tabsForEnsure[tab.entries[0].url] = 1;
|
||||
});
|
||||
|
||||
let tabsRestoring = 0;
|
||||
let tabsRestored = 0;
|
||||
|
||||
function handleEvent(aEvent) {
|
||||
if (aEvent.type == "SSTabRestoring")
|
||||
tabsRestoring++;
|
||||
else
|
||||
tabsRestored++;
|
||||
|
||||
if (tabsRestoring < state.windows[0].tabs.length ||
|
||||
tabsRestored < 1)
|
||||
return;
|
||||
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestoring", handleEvent, true);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", handleEvent, true);
|
||||
executeSoon(function() {
|
||||
checkAutocompleteResults(tabsForEnsure, cleanup);
|
||||
});
|
||||
}
|
||||
|
||||
// currentURI is set before SSTabRestoring is fired, so we can sucessfully check
|
||||
// after that has fired for all tabs. Since 1 tab will be restored though, we
|
||||
// also need to wait for 1 SSTabRestored since currentURI will be set, unset, then set.
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestoring", handleEvent, true);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", handleEvent, true);
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
}
|
||||
|
||||
// The following was taken from browser/base/content/test/general/browser_tabMatchesInAwesomebar.js
|
||||
// so that we could do the same sort of checking.
|
||||
var gController = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
function checkAutocompleteResults(aExpected, aCallback) {
|
||||
gController.input = {
|
||||
timeout: 10,
|
||||
textValue: "",
|
||||
searches: ["unifiedcomplete"],
|
||||
searchParam: "enable-actions",
|
||||
popupOpen: false,
|
||||
minResultsForPopup: 0,
|
||||
invalidate: function() {},
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
get popup() { return this; },
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function ()
|
||||
{
|
||||
info("Found " + gController.matchCount + " matches.");
|
||||
// Check to see the expected uris and titles match up (in any order)
|
||||
for (let i = 0; i < gController.matchCount; i++) {
|
||||
if (gController.getStyleAt(i).includes("heuristic")) {
|
||||
info("Skip heuristic match");
|
||||
continue;
|
||||
}
|
||||
let action = gURLBar.popup.input._parseActionUrl(gController.getValueAt(i));
|
||||
let uri = action.params.url;
|
||||
|
||||
info("Search for '" + uri + "' in open tabs.");
|
||||
ok(uri in aExpected, "Registered open page found in autocomplete.");
|
||||
// Remove the found entry from expected results.
|
||||
delete aExpected[uri];
|
||||
}
|
||||
|
||||
// Make sure there is no reported open page that is not open.
|
||||
for (let entry in aExpected) {
|
||||
ok(false, "'" + entry + "' not found in autocomplete.");
|
||||
}
|
||||
|
||||
executeSoon(aCallback);
|
||||
},
|
||||
setSelectedIndex: function() {},
|
||||
get searchCount() { return this.searches.length; },
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIAutoCompleteInput,
|
||||
Ci.nsIAutoCompletePopup,
|
||||
])
|
||||
};
|
||||
|
||||
info("Searching open pages.");
|
||||
gController.startSearch(Services.prefs.getCharPref("browser.urlbar.restrict.openpage"));
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
var stateBackup = JSON.parse(ss.getBrowserState());
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 600545 **/
|
||||
waitForExplicitFinish();
|
||||
testBug600545();
|
||||
}
|
||||
|
||||
function testBug600545() {
|
||||
// Set the pref to false to cause non-app tabs to be stripped out on a save
|
||||
Services.prefs.setBoolPref("browser.sessionstore.resume_from_crash", false);
|
||||
Services.prefs.setIntPref("browser.sessionstore.interval", 2000);
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref("browser.sessionstore.resume_from_crash");
|
||||
Services.prefs.clearUserPref("browser.sessionstore.interval");
|
||||
});
|
||||
|
||||
// This tests the following use case: When multiple windows are open
|
||||
// and browser.sessionstore.resume_from_crash preference is false,
|
||||
// tab session data for non-active window is stripped for non-pinned
|
||||
// tabs. This occurs after "sessionstore-state-write-complete"
|
||||
// fires which will only fire in this case if there is at least one
|
||||
// pinned tab.
|
||||
let state = { windows: [
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.org#0" }], pinned:true },
|
||||
{ entries: [{ url: "http://example.com#1" }] },
|
||||
{ entries: [{ url: "http://example.com#2" }] },
|
||||
],
|
||||
selected: 2
|
||||
},
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.com#3" }] },
|
||||
{ entries: [{ url: "http://example.com#4" }] },
|
||||
{ entries: [{ url: "http://example.com#5" }] },
|
||||
{ entries: [{ url: "http://example.com#6" }] }
|
||||
],
|
||||
selected: 3
|
||||
}
|
||||
] };
|
||||
|
||||
waitForBrowserState(state, function() {
|
||||
// Need to wait for SessionStore's saveState function to be called
|
||||
// so that non-pinned tabs will be stripped from non-active window
|
||||
waitForSaveState(function () {
|
||||
let expectedNumberOfTabs = getStateTabCount(state);
|
||||
let retrievedState = JSON.parse(ss.getBrowserState());
|
||||
let actualNumberOfTabs = getStateTabCount(retrievedState);
|
||||
|
||||
is(actualNumberOfTabs, expectedNumberOfTabs,
|
||||
"Number of tabs in retreived session data, matches number of tabs set.");
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function done() {
|
||||
// Enumerate windows and close everything but our primary window. We can't
|
||||
// use waitForFocus() because apparently it's buggy. See bug 599253.
|
||||
let windowsEnum = Services.wm.getEnumerator("navigator:browser");
|
||||
let closeWinPromises = [];
|
||||
while (windowsEnum.hasMoreElements()) {
|
||||
let currentWindow = windowsEnum.getNext();
|
||||
if (currentWindow != window)
|
||||
closeWinPromises.push(BrowserTestUtils.closeWindow(currentWindow));
|
||||
}
|
||||
|
||||
Promise.all(closeWinPromises).then(() => {
|
||||
waitForBrowserState(stateBackup, finish);
|
||||
});
|
||||
}
|
||||
|
||||
// Count up the number of tabs in the state data
|
||||
function getStateTabCount(aState) {
|
||||
let tabCount = 0;
|
||||
for (let i in aState.windows)
|
||||
tabCount += aState.windows[i].tabs.length;
|
||||
return tabCount;
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This tests that pinning/unpinning a tab, on its own, eventually triggers a
|
||||
// session store.
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
// We speed up the interval between session saves to ensure that the test
|
||||
// runs quickly.
|
||||
Services.prefs.setIntPref("browser.sessionstore.interval", 2000);
|
||||
|
||||
// Loading a tab causes a save state and this is meant to catch that event.
|
||||
waitForSaveState(testBug601955_1);
|
||||
|
||||
// Assumption: Only one window is open and it has one tab open.
|
||||
gBrowser.addTab("about:mozilla");
|
||||
}
|
||||
|
||||
function testBug601955_1() {
|
||||
// Because pinned tabs are at the front of |gBrowser.tabs|, pinning tabs
|
||||
// re-arranges the |tabs| array.
|
||||
ok(!gBrowser.tabs[0].pinned, "first tab should not be pinned yet");
|
||||
ok(!gBrowser.tabs[1].pinned, "second tab should not be pinned yet");
|
||||
|
||||
waitForSaveState(testBug601955_2);
|
||||
gBrowser.pinTab(gBrowser.tabs[0]);
|
||||
}
|
||||
|
||||
function testBug601955_2() {
|
||||
let state = JSON.parse(ss.getBrowserState());
|
||||
ok(state.windows[0].tabs[0].pinned, "first tab should be pinned by now");
|
||||
ok(!state.windows[0].tabs[1].pinned, "second tab should still not be pinned");
|
||||
|
||||
waitForSaveState(testBug601955_3);
|
||||
gBrowser.unpinTab(window.gBrowser.tabs[0]);
|
||||
}
|
||||
|
||||
function testBug601955_3() {
|
||||
let state = JSON.parse(ss.getBrowserState());
|
||||
ok(!state.windows[0].tabs[0].pinned, "first tab should not be pinned");
|
||||
ok(!state.windows[0].tabs[1].pinned, "second tab should not be pinned");
|
||||
|
||||
done();
|
||||
}
|
||||
|
||||
function done() {
|
||||
gBrowser.removeTab(window.gBrowser.tabs[1]);
|
||||
|
||||
Services.prefs.clearUserPref("browser.sessionstore.interval");
|
||||
|
||||
executeSoon(finish);
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
var stateBackup = ss.getBrowserState();
|
||||
|
||||
add_task(function* () {
|
||||
/** Bug 607016 - If a tab is never restored, attributes (eg. hidden) aren't updated correctly **/
|
||||
ignoreAllUncaughtExceptions();
|
||||
|
||||
// Set the pref to true so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org#1" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org#2" }], extData: { "uniq": r() } }, // overwriting
|
||||
{ entries: [{ url: "http://example.org#3" }], extData: { "uniq": r() } }, // hiding
|
||||
{ entries: [{ url: "http://example.org#4" }], extData: { "uniq": r() } }, // adding
|
||||
{ entries: [{ url: "http://example.org#5" }], extData: { "uniq": r() } }, // deleting
|
||||
{ entries: [{ url: "http://example.org#6" }] } // creating
|
||||
], selected: 1 }] };
|
||||
|
||||
function* progressCallback() {
|
||||
let curState = JSON.parse(ss.getBrowserState());
|
||||
for (let i = 0; i < curState.windows[0].tabs.length; i++) {
|
||||
let tabState = state.windows[0].tabs[i];
|
||||
let tabCurState = curState.windows[0].tabs[i];
|
||||
if (tabState.extData) {
|
||||
is(tabCurState.extData["uniq"], tabState.extData["uniq"],
|
||||
"sanity check that tab has correct extData");
|
||||
}
|
||||
else {
|
||||
// We aren't expecting there to be any data on extData, but panorama
|
||||
// may be setting something, so we need to make sure that if we do have
|
||||
// data, we just don't have anything for "uniq".
|
||||
ok(!("extData" in tabCurState) || !("uniq" in tabCurState.extData),
|
||||
"sanity check that tab doesn't have extData or extData doesn't have 'uniq'");
|
||||
}
|
||||
}
|
||||
|
||||
// Now we'll set a new unique value on 1 of the tabs
|
||||
let newUniq = r();
|
||||
ss.setTabValue(gBrowser.tabs[1], "uniq", newUniq);
|
||||
let tabState = JSON.parse(ss.getTabState(gBrowser.tabs[1]));
|
||||
is(tabState.extData.uniq, newUniq,
|
||||
"(overwriting) new data is stored in extData");
|
||||
|
||||
// hide the next tab before closing it
|
||||
gBrowser.hideTab(gBrowser.tabs[2]);
|
||||
tabState = JSON.parse(ss.getTabState(gBrowser.tabs[2]));
|
||||
ok(tabState.hidden, "(hiding) tab data has hidden == true");
|
||||
|
||||
// set data that's not in a conflicting key
|
||||
let stillUniq = r();
|
||||
ss.setTabValue(gBrowser.tabs[3], "stillUniq", stillUniq);
|
||||
tabState = JSON.parse(ss.getTabState(gBrowser.tabs[3]));
|
||||
is(tabState.extData.stillUniq, stillUniq,
|
||||
"(adding) new data is stored in extData");
|
||||
|
||||
// remove the uniq value and make sure it's not there in the closed data
|
||||
ss.deleteTabValue(gBrowser.tabs[4], "uniq");
|
||||
tabState = JSON.parse(ss.getTabState(gBrowser.tabs[4]));
|
||||
// Since Panorama might have put data in, first check if there is extData.
|
||||
// If there is explicitly check that "uniq" isn't in it. Otherwise, we're ok
|
||||
if ("extData" in tabState) {
|
||||
ok(!("uniq" in tabState.extData),
|
||||
"(deleting) uniq not in existing extData");
|
||||
}
|
||||
else {
|
||||
ok(true, "(deleting) no data is stored in extData");
|
||||
}
|
||||
|
||||
// set unique data on the tab that never had any set, make sure that's saved
|
||||
let newUniq2 = r();
|
||||
ss.setTabValue(gBrowser.tabs[5], "uniq", newUniq2);
|
||||
tabState = JSON.parse(ss.getTabState(gBrowser.tabs[5]));
|
||||
is(tabState.extData.uniq, newUniq2,
|
||||
"(creating) new data is stored in extData where there was none");
|
||||
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
yield promiseRemoveTab(gBrowser.tabs[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the test state.
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
|
||||
// Wait until the selected tab is restored and all others are pending.
|
||||
yield Promise.all(Array.map(gBrowser.tabs, tab => {
|
||||
return (tab == gBrowser.selectedTab) ?
|
||||
promiseTabRestored(tab) : promiseTabRestoring(tab)
|
||||
}));
|
||||
|
||||
// Kick off the actual tests.
|
||||
yield progressCallback();
|
||||
|
||||
// Cleanup.
|
||||
yield promiseBrowserState(stateBackup);
|
||||
});
|
||||
|
|
@ -1,361 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const stateBackup = JSON.parse(ss.getBrowserState());
|
||||
const testState = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: "about:blank" }] },
|
||||
{ entries: [{ url: "about:rights" }] }
|
||||
]
|
||||
}]
|
||||
};
|
||||
const lameMultiWindowState = { windows: [
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.org#1" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org#2" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org#3" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org#4" }], extData: { "uniq": r() } }
|
||||
],
|
||||
selected: 1
|
||||
},
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.com#1" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#2" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#3" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com#4" }], extData: { "uniq": r() } },
|
||||
],
|
||||
selected: 3
|
||||
}
|
||||
] };
|
||||
|
||||
|
||||
function getOuterWindowID(aWindow) {
|
||||
return aWindow.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
|
||||
}
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 615394 - Session Restore should notify when it is beginning and ending a restore **/
|
||||
waitForExplicitFinish();
|
||||
// Preemptively extend the timeout to prevent [orange]
|
||||
requestLongerTimeout(4);
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
|
||||
var tests = [
|
||||
test_setTabState,
|
||||
test_duplicateTab,
|
||||
test_undoCloseTab,
|
||||
test_setWindowState,
|
||||
test_setBrowserState,
|
||||
test_undoCloseWindow
|
||||
];
|
||||
function runNextTest() {
|
||||
// set an empty state & run the next test, or finish
|
||||
if (tests.length) {
|
||||
// Enumerate windows and close everything but our primary window. We can't
|
||||
// use waitForFocus() because apparently it's buggy. See bug 599253.
|
||||
var windowsEnum = Services.wm.getEnumerator("navigator:browser");
|
||||
let closeWinPromises = [];
|
||||
while (windowsEnum.hasMoreElements()) {
|
||||
var currentWindow = windowsEnum.getNext();
|
||||
if (currentWindow != window) {
|
||||
closeWinPromises.push(BrowserTestUtils.closeWindow(currentWindow));
|
||||
}
|
||||
}
|
||||
|
||||
Promise.all(closeWinPromises).then(() => {
|
||||
let currentTest = tests.shift();
|
||||
info("prepping for " + currentTest.name);
|
||||
waitForBrowserState(testState, currentTest);
|
||||
});
|
||||
}
|
||||
else {
|
||||
waitForBrowserState(stateBackup, finish);
|
||||
}
|
||||
}
|
||||
|
||||
/** ACTUAL TESTS **/
|
||||
|
||||
function test_setTabState() {
|
||||
let tab = gBrowser.tabs[1];
|
||||
let newTabState = JSON.stringify({ entries: [{ url: "http://example.org" }], extData: { foo: "bar" } });
|
||||
let busyEventCount = 0;
|
||||
let readyEventCount = 0;
|
||||
|
||||
function onSSWindowStateBusy(aEvent) {
|
||||
busyEventCount++;
|
||||
}
|
||||
|
||||
function onSSWindowStateReady(aEvent) {
|
||||
readyEventCount++;
|
||||
is(ss.getTabValue(tab, "foo"), "bar");
|
||||
ss.setTabValue(tab, "baz", "qux");
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(ss.getTabValue(tab, "baz"), "qux");
|
||||
is(tab.linkedBrowser.currentURI.spec, "http://example.org/");
|
||||
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
ss.setTabState(tab, newTabState);
|
||||
}
|
||||
|
||||
|
||||
function test_duplicateTab() {
|
||||
let tab = gBrowser.tabs[1];
|
||||
let busyEventCount = 0;
|
||||
let readyEventCount = 0;
|
||||
let newTab;
|
||||
|
||||
// We'll look to make sure this value is on the duplicated tab
|
||||
ss.setTabValue(tab, "foo", "bar");
|
||||
|
||||
function onSSWindowStateBusy(aEvent) {
|
||||
busyEventCount++;
|
||||
}
|
||||
|
||||
function onSSWindowStateReady(aEvent) {
|
||||
newTab = gBrowser.tabs[2];
|
||||
readyEventCount++;
|
||||
is(ss.getTabValue(newTab, "foo"), "bar");
|
||||
ss.setTabValue(newTab, "baz", "qux");
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(ss.getTabValue(newTab, "baz"), "qux");
|
||||
is(newTab.linkedBrowser.currentURI.spec, "about:rights");
|
||||
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
|
||||
newTab = ss.duplicateTab(window, tab);
|
||||
}
|
||||
|
||||
|
||||
function test_undoCloseTab() {
|
||||
let tab = gBrowser.tabs[1],
|
||||
busyEventCount = 0,
|
||||
readyEventCount = 0,
|
||||
reopenedTab;
|
||||
|
||||
ss.setTabValue(tab, "foo", "bar");
|
||||
|
||||
function onSSWindowStateBusy(aEvent) {
|
||||
busyEventCount++;
|
||||
}
|
||||
|
||||
function onSSWindowStateReady(aEvent) {
|
||||
reopenedTab = gBrowser.tabs[1];
|
||||
readyEventCount++;
|
||||
is(ss.getTabValue(reopenedTab, "foo"), "bar");
|
||||
ss.setTabValue(reopenedTab, "baz", "qux");
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(ss.getTabValue(reopenedTab, "baz"), "qux");
|
||||
is(reopenedTab.linkedBrowser.currentURI.spec, "about:rights");
|
||||
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
reopenedTab = ss.undoCloseTab(window, 0);
|
||||
}
|
||||
|
||||
|
||||
function test_setWindowState() {
|
||||
let testState = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: "about:mozilla" }], extData: { "foo": "bar" } },
|
||||
{ entries: [{ url: "http://example.org" }], extData: { "baz": "qux" } }
|
||||
]
|
||||
}]
|
||||
};
|
||||
|
||||
let busyEventCount = 0,
|
||||
readyEventCount = 0,
|
||||
tabRestoredCount = 0;
|
||||
|
||||
function onSSWindowStateBusy(aEvent) {
|
||||
busyEventCount++;
|
||||
}
|
||||
|
||||
function onSSWindowStateReady(aEvent) {
|
||||
readyEventCount++;
|
||||
is(ss.getTabValue(gBrowser.tabs[0], "foo"), "bar");
|
||||
is(ss.getTabValue(gBrowser.tabs[1], "baz"), "qux");
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
if (++tabRestoredCount < 2)
|
||||
return;
|
||||
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(gBrowser.tabs[0].linkedBrowser.currentURI.spec, "about:mozilla");
|
||||
is(gBrowser.tabs[1].linkedBrowser.currentURI.spec, "http://example.org/");
|
||||
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
|
||||
ss.setWindowState(window, JSON.stringify(testState), true);
|
||||
}
|
||||
|
||||
|
||||
function test_setBrowserState() {
|
||||
// We'll track events per window so we are sure that they are each happening once
|
||||
// pre window.
|
||||
let windowEvents = {};
|
||||
windowEvents[getOuterWindowID(window)] = { busyEventCount: 0, readyEventCount: 0 };
|
||||
|
||||
// waitForBrowserState does it's own observing for windows, but doesn't attach
|
||||
// the listeners we want here, so do it ourselves.
|
||||
let newWindow;
|
||||
function windowObserver(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowopened") {
|
||||
newWindow = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
newWindow.addEventListener("load", function() {
|
||||
newWindow.removeEventListener("load", arguments.callee, false);
|
||||
|
||||
Services.ww.unregisterNotification(windowObserver);
|
||||
|
||||
windowEvents[getOuterWindowID(newWindow)] = { busyEventCount: 0, readyEventCount: 0 };
|
||||
|
||||
newWindow.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
newWindow.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
|
||||
function onSSWindowStateBusy(aEvent) {
|
||||
windowEvents[getOuterWindowID(aEvent.originalTarget)].busyEventCount++;
|
||||
}
|
||||
|
||||
function onSSWindowStateReady(aEvent) {
|
||||
windowEvents[getOuterWindowID(aEvent.originalTarget)].readyEventCount++;
|
||||
}
|
||||
|
||||
window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
Services.ww.registerNotification(windowObserver);
|
||||
|
||||
waitForBrowserState(lameMultiWindowState, function() {
|
||||
let checkedWindows = 0;
|
||||
for (let id of Object.keys(windowEvents)) {
|
||||
let winEvents = windowEvents[id];
|
||||
is(winEvents.busyEventCount, 1,
|
||||
"[test_setBrowserState] window" + id + " busy event count correct");
|
||||
is(winEvents.readyEventCount, 1,
|
||||
"[test_setBrowserState] window" + id + " ready event count correct");
|
||||
checkedWindows++;
|
||||
}
|
||||
is(checkedWindows, 2,
|
||||
"[test_setBrowserState] checked 2 windows");
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
newWindow.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
newWindow.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
runNextTest();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function test_undoCloseWindow() {
|
||||
let newWindow, reopenedWindow;
|
||||
|
||||
function firstWindowObserver(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowopened") {
|
||||
newWindow = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
Services.ww.unregisterNotification(firstWindowObserver);
|
||||
}
|
||||
}
|
||||
Services.ww.registerNotification(firstWindowObserver);
|
||||
|
||||
waitForBrowserState(lameMultiWindowState, function() {
|
||||
// Close the window which isn't window
|
||||
BrowserTestUtils.closeWindow(newWindow).then(() => {
|
||||
// Now give it time to close
|
||||
reopenedWindow = ss.undoCloseWindow(0);
|
||||
reopenedWindow.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
reopenedWindow.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
|
||||
reopenedWindow.addEventListener("load", function() {
|
||||
reopenedWindow.removeEventListener("load", arguments.callee, false);
|
||||
|
||||
reopenedWindow.gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
|
||||
let busyEventCount = 0,
|
||||
readyEventCount = 0,
|
||||
tabRestoredCount = 0;
|
||||
// These will listen to the reopened closed window...
|
||||
function onSSWindowStateBusy(aEvent) {
|
||||
busyEventCount++;
|
||||
}
|
||||
|
||||
function onSSWindowStateReady(aEvent) {
|
||||
readyEventCount++;
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
if (++tabRestoredCount < 4)
|
||||
return;
|
||||
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
|
||||
reopenedWindow.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
|
||||
reopenedWindow.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
|
||||
reopenedWindow.gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
|
||||
BrowserTestUtils.closeWindow(reopenedWindow).then(runNextTest);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const stateBackup = ss.getBrowserState();
|
||||
const testState = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: "about:blank" }] },
|
||||
{ entries: [{ url: "about:mozilla" }] }
|
||||
]
|
||||
}]
|
||||
};
|
||||
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 618151 - Overwriting state can lead to unrestored tabs **/
|
||||
waitForExplicitFinish();
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
// Just a subset of tests from bug 615394 that causes a timeout.
|
||||
var tests = [test_setup, test_hang];
|
||||
function runNextTest() {
|
||||
// set an empty state & run the next test, or finish
|
||||
if (tests.length) {
|
||||
// Enumerate windows and close everything but our primary window. We can't
|
||||
// use waitForFocus() because apparently it's buggy. See bug 599253.
|
||||
var windowsEnum = Services.wm.getEnumerator("navigator:browser");
|
||||
let closeWinPromises = [];
|
||||
while (windowsEnum.hasMoreElements()) {
|
||||
var currentWindow = windowsEnum.getNext();
|
||||
if (currentWindow != window) {
|
||||
closeWinPromises.push(BrowserTestUtils.closeWindow(currentWindow));
|
||||
}
|
||||
}
|
||||
|
||||
Promise.all(closeWinPromises).then(() => {
|
||||
let currentTest = tests.shift();
|
||||
info("running " + currentTest.name);
|
||||
waitForBrowserState(testState, currentTest);
|
||||
});
|
||||
}
|
||||
else {
|
||||
ss.setBrowserState(stateBackup);
|
||||
executeSoon(finish);
|
||||
}
|
||||
}
|
||||
|
||||
function test_setup() {
|
||||
function onSSTabRestored(aEvent) {
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
|
||||
ss.setTabState(gBrowser.tabs[1], JSON.stringify({
|
||||
entries: [{ url: "http://example.org" }],
|
||||
extData: { foo: "bar" } }));
|
||||
}
|
||||
|
||||
function test_hang() {
|
||||
ok(true, "test didn't time out");
|
||||
runNextTest();
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
gBrowser.pinTab(gBrowser.selectedTab);
|
||||
|
||||
let newTab = gBrowser.duplicateTab(gBrowser.selectedTab);
|
||||
yield promiseTabRestored(newTab);
|
||||
|
||||
ok(!newTab.pinned, "duplicating a pinned tab creates unpinned tab");
|
||||
yield promiseRemoveTab(newTab);
|
||||
|
||||
gBrowser.unpinTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
var TEST_STATE = { windows: [{ tabs: [{ url: "about:blank" }] }] };
|
||||
|
||||
add_task(function* () {
|
||||
function assertNumberOfTabs(num, msg) {
|
||||
is(gBrowser.tabs.length, num, msg);
|
||||
}
|
||||
|
||||
function assertNumberOfPinnedTabs(num, msg) {
|
||||
is(gBrowser._numPinnedTabs, num, msg);
|
||||
}
|
||||
|
||||
// check prerequisites
|
||||
assertNumberOfTabs(1, "we start off with one tab");
|
||||
assertNumberOfPinnedTabs(0, "no pinned tabs so far");
|
||||
|
||||
// setup
|
||||
gBrowser.addTab("about:blank");
|
||||
assertNumberOfTabs(2, "there are two tabs, now");
|
||||
|
||||
let [tab1, tab2] = gBrowser.tabs;
|
||||
let linkedBrowser = tab1.linkedBrowser;
|
||||
gBrowser.pinTab(tab1);
|
||||
gBrowser.pinTab(tab2);
|
||||
assertNumberOfPinnedTabs(2, "both tabs are now pinned");
|
||||
|
||||
// run the test
|
||||
yield promiseBrowserState(TEST_STATE);
|
||||
|
||||
assertNumberOfTabs(1, "one tab left after setBrowserState()");
|
||||
assertNumberOfPinnedTabs(0, "there are no pinned tabs");
|
||||
is(gBrowser.tabs[0].linkedBrowser, linkedBrowser, "first tab's browser got re-used");
|
||||
});
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
add_task(function* setup() {
|
||||
/** Test for Bug 625016 - Restore windows closed in succession to quit (non-OSX only) **/
|
||||
|
||||
// We'll test this by opening a new window, waiting for the save
|
||||
// event, then closing that window. We'll observe the
|
||||
// "sessionstore-state-write-complete" notification and check that
|
||||
// the state contains no _closedWindows. We'll then add a new tab
|
||||
// and make sure that the state following that was reset and the
|
||||
// closed window is now in _closedWindows.
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
yield forceSaveState();
|
||||
|
||||
// We'll clear all closed windows to make sure our state is clean
|
||||
// forgetClosedWindow doesn't trigger a delayed save
|
||||
forgetClosedWindows();
|
||||
is(ss.getClosedWindowCount(), 0, "starting with no closed windows");
|
||||
});
|
||||
|
||||
add_task(function* new_window() {
|
||||
let newWin;
|
||||
try {
|
||||
newWin = yield promiseNewWindowLoaded();
|
||||
let tab = newWin.gBrowser.addTab("http://example.com/browser_625016.js?" + Math.random());
|
||||
yield promiseBrowserLoaded(tab.linkedBrowser);
|
||||
|
||||
// Double check that we have no closed windows
|
||||
is(ss.getClosedWindowCount(), 0, "no closed windows on first save");
|
||||
|
||||
yield BrowserTestUtils.closeWindow(newWin);
|
||||
newWin = null;
|
||||
|
||||
let state = JSON.parse((yield promiseRecoveryFileContents()));
|
||||
is(state.windows.length, 2,
|
||||
"observe1: 2 windows in data written to disk");
|
||||
is(state._closedWindows.length, 0,
|
||||
"observe1: no closed windows in data written to disk");
|
||||
|
||||
// The API still treats the closed window as closed, so ensure that window is there
|
||||
is(ss.getClosedWindowCount(), 1,
|
||||
"observe1: 1 closed window according to API");
|
||||
} finally {
|
||||
if (newWin) {
|
||||
yield BrowserTestUtils.closeWindow(newWin);
|
||||
}
|
||||
yield forceSaveState();
|
||||
}
|
||||
});
|
||||
|
||||
// We'll open a tab, which should trigger another state save which would wipe
|
||||
// the _shouldRestore attribute from the closed window
|
||||
add_task(function* new_tab() {
|
||||
let newTab;
|
||||
try {
|
||||
newTab = gBrowser.addTab("about:mozilla");
|
||||
|
||||
let state = JSON.parse((yield promiseRecoveryFileContents()));
|
||||
is(state.windows.length, 1,
|
||||
"observe2: 1 window in data being written to disk");
|
||||
is(state._closedWindows.length, 1,
|
||||
"observe2: 1 closed window in data being written to disk");
|
||||
|
||||
// The API still treats the closed window as closed, so ensure that window is there
|
||||
is(ss.getClosedWindowCount(), 1,
|
||||
"observe2: 1 closed window according to API");
|
||||
} finally {
|
||||
gBrowser.removeTab(newTab);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
add_task(function* done() {
|
||||
// The API still represents the closed window as closed, so we can clear it
|
||||
// with the API, but just to make sure...
|
||||
// is(ss.getClosedWindowCount(), 1, "1 closed window according to API");
|
||||
forgetClosedWindows();
|
||||
Services.prefs.clearUserPref("browser.sessionstore.interval");
|
||||
});
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let assertNumberOfTabs = function (num, msg) {
|
||||
is(gBrowser.tabs.length, num, msg);
|
||||
}
|
||||
|
||||
let assertNumberOfVisibleTabs = function (num, msg) {
|
||||
is(gBrowser.visibleTabs.length, num, msg);
|
||||
}
|
||||
|
||||
let assertNumberOfPinnedTabs = function (num, msg) {
|
||||
is(gBrowser._numPinnedTabs, num, msg);
|
||||
}
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
// check prerequisites
|
||||
assertNumberOfTabs(1, "we start off with one tab");
|
||||
|
||||
// setup
|
||||
let tab = gBrowser.addTab("about:mozilla");
|
||||
|
||||
whenTabIsLoaded(tab, function () {
|
||||
// hide the newly created tab
|
||||
assertNumberOfVisibleTabs(2, "there are two visible tabs");
|
||||
gBrowser.showOnlyTheseTabs([gBrowser.tabs[0]]);
|
||||
assertNumberOfVisibleTabs(1, "there is one visible tab");
|
||||
ok(tab.hidden, "newly created tab is now hidden");
|
||||
|
||||
// close and restore hidden tab
|
||||
promiseRemoveTab(tab).then(() => {
|
||||
tab = ss.undoCloseTab(window, 0);
|
||||
|
||||
// check that everything was restored correctly, clean up and finish
|
||||
whenTabIsLoaded(tab, function () {
|
||||
is(tab.linkedBrowser.currentURI.spec, "about:mozilla", "restored tab has correct url");
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function whenTabIsLoaded(tab, callback) {
|
||||
tab.linkedBrowser.addEventListener("load", function onLoad() {
|
||||
tab.linkedBrowser.removeEventListener("load", onLoad, true);
|
||||
callback();
|
||||
}, true);
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This tests that hiding/showing a tab, on its own, eventually triggers a
|
||||
// session store.
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// We speed up the interval between session saves to ensure that the test
|
||||
// runs quickly.
|
||||
Services.prefs.setIntPref("browser.sessionstore.interval", 2000);
|
||||
|
||||
// Loading a tab causes a save state and this is meant to catch that event.
|
||||
waitForSaveState(testBug635418_1);
|
||||
|
||||
// Assumption: Only one window is open and it has one tab open.
|
||||
gBrowser.addTab("about:mozilla");
|
||||
}
|
||||
|
||||
function testBug635418_1() {
|
||||
ok(!gBrowser.tabs[0].hidden, "first tab should not be hidden");
|
||||
ok(!gBrowser.tabs[1].hidden, "second tab should not be hidden");
|
||||
|
||||
waitForSaveState(testBug635418_2);
|
||||
|
||||
// We can't hide the selected tab, so hide the new one
|
||||
gBrowser.hideTab(gBrowser.tabs[1]);
|
||||
}
|
||||
|
||||
function testBug635418_2() {
|
||||
let state = JSON.parse(ss.getBrowserState());
|
||||
ok(!state.windows[0].tabs[0].hidden, "first tab should still not be hidden");
|
||||
ok(state.windows[0].tabs[1].hidden, "second tab should be hidden by now");
|
||||
|
||||
waitForSaveState(testBug635418_3);
|
||||
gBrowser.showTab(gBrowser.tabs[1]);
|
||||
}
|
||||
|
||||
function testBug635418_3() {
|
||||
let state = JSON.parse(ss.getBrowserState());
|
||||
ok(!state.windows[0].tabs[0].hidden, "first tab should still still not be hidden");
|
||||
ok(!state.windows[0].tabs[1].hidden, "second tab should not be hidden again");
|
||||
|
||||
done();
|
||||
}
|
||||
|
||||
function done() {
|
||||
gBrowser.removeTab(window.gBrowser.tabs[1]);
|
||||
|
||||
Services.prefs.clearUserPref("browser.sessionstore.interval");
|
||||
|
||||
executeSoon(finish);
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
var stateBackup = ss.getBrowserState();
|
||||
|
||||
var statePinned = {windows:[{tabs:[
|
||||
{entries:[{url:"http://example.com#1"}], pinned: true}
|
||||
]}]};
|
||||
|
||||
var state = {windows:[{tabs:[
|
||||
{entries:[{url:"http://example.com#1"}]},
|
||||
{entries:[{url:"http://example.com#2"}]},
|
||||
{entries:[{url:"http://example.com#3"}]},
|
||||
{entries:[{url:"http://example.com#4"}]},
|
||||
]}]};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
TabsProgressListener.uninit();
|
||||
ss.setBrowserState(stateBackup);
|
||||
});
|
||||
|
||||
|
||||
TabsProgressListener.init();
|
||||
|
||||
window.addEventListener("SSWindowStateReady", function onReady() {
|
||||
window.removeEventListener("SSWindowStateReady", onReady, false);
|
||||
|
||||
let firstProgress = true;
|
||||
|
||||
TabsProgressListener.setCallback(function (needsRestore, isRestoring) {
|
||||
if (firstProgress) {
|
||||
firstProgress = false;
|
||||
is(isRestoring, 3, "restoring 3 tabs concurrently");
|
||||
} else {
|
||||
ok(isRestoring <= 3, "restoring max. 2 tabs concurrently");
|
||||
}
|
||||
|
||||
if (0 == needsRestore) {
|
||||
TabsProgressListener.unsetCallback();
|
||||
waitForFocus(finish);
|
||||
}
|
||||
});
|
||||
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
}, false);
|
||||
|
||||
ss.setBrowserState(JSON.stringify(statePinned));
|
||||
}
|
||||
|
||||
function countTabs() {
|
||||
let needsRestore = 0, isRestoring = 0;
|
||||
let windowsEnum = Services.wm.getEnumerator("navigator:browser");
|
||||
|
||||
while (windowsEnum.hasMoreElements()) {
|
||||
let window = windowsEnum.getNext();
|
||||
if (window.closed)
|
||||
continue;
|
||||
|
||||
for (let i = 0; i < window.gBrowser.tabs.length; i++) {
|
||||
let browser = window.gBrowser.tabs[i].linkedBrowser;
|
||||
if (browser.__SS_restoreState == TAB_STATE_RESTORING)
|
||||
isRestoring++;
|
||||
else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
|
||||
needsRestore++;
|
||||
}
|
||||
}
|
||||
|
||||
return [needsRestore, isRestoring];
|
||||
}
|
||||
|
||||
var TabsProgressListener = {
|
||||
init: function () {
|
||||
Services.obs.addObserver(this, "sessionstore-debug-tab-restored", false);
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
Services.obs.removeObserver(this, "sessionstore-debug-tab-restored");
|
||||
this.unsetCallback();
|
||||
},
|
||||
|
||||
setCallback: function (callback) {
|
||||
this.callback = callback;
|
||||
},
|
||||
|
||||
unsetCallback: function () {
|
||||
delete this.callback;
|
||||
},
|
||||
|
||||
observe: function (browser, topic, data) {
|
||||
TabsProgressListener.onRestored(browser);
|
||||
},
|
||||
|
||||
onRestored: function (browser) {
|
||||
if (this.callback && browser.__SS_restoreState == TAB_STATE_RESTORING) {
|
||||
this.callback.apply(null, countTabs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const TEST_URL = "http://mochi.test:8888/browser/browser/components/" +
|
||||
"sessionstore/test/browser_637020_slow.sjs";
|
||||
|
||||
const TEST_STATE = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: "about:mozilla" }] },
|
||||
{ entries: [{ url: "about:robots" }] }
|
||||
]
|
||||
}, {
|
||||
tabs: [
|
||||
{ entries: [{ url: TEST_URL }] },
|
||||
{ entries: [{ url: TEST_URL }] }
|
||||
]
|
||||
}]
|
||||
};
|
||||
|
||||
/**
|
||||
* This test ensures that windows that have just been restored will be marked
|
||||
* as dirty, otherwise _getCurrentState() might ignore them when collecting
|
||||
* state for the first time and we'd just save them as empty objects.
|
||||
*
|
||||
* The dirty state acts as a cache to not collect data from all windows all the
|
||||
* time, so at the beginning, each window must be dirty so that we collect
|
||||
* their state at least once.
|
||||
*/
|
||||
|
||||
add_task(function* test() {
|
||||
// Wait until the new window has been opened.
|
||||
let promiseWindow = new Promise(resolve => {
|
||||
Services.obs.addObserver(function onOpened(subject) {
|
||||
Services.obs.removeObserver(onOpened, "domwindowopened");
|
||||
resolve(subject);
|
||||
}, "domwindowopened", false);
|
||||
});
|
||||
|
||||
// Set the new browser state that will
|
||||
// restore a window with two slowly loading tabs.
|
||||
let backupState = SessionStore.getBrowserState();
|
||||
SessionStore.setBrowserState(JSON.stringify(TEST_STATE));
|
||||
let win = yield promiseWindow;
|
||||
|
||||
// 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.
|
||||
info("the window has been opened");
|
||||
checkWindows();
|
||||
|
||||
// The history has now been restored and the tabs are loading. The data must
|
||||
// now come from the window, if it's correctly been marked as dirty before.
|
||||
yield new Promise(resolve => whenDelayedStartupFinished(win, resolve));
|
||||
info("the delayed startup has finished");
|
||||
checkWindows();
|
||||
|
||||
// Cleanup.
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
yield promiseBrowserState(backupState);
|
||||
});
|
||||
|
||||
function checkWindows() {
|
||||
let state = JSON.parse(SessionStore.getBrowserState());
|
||||
is(state.windows[0].tabs.length, 2, "first window has two tabs");
|
||||
is(state.windows[1].tabs.length, 2, "second window has two tabs");
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
const DELAY_MS = "2000";
|
||||
|
||||
let timer;
|
||||
|
||||
function handleRequest(req, resp) {
|
||||
resp.processAsync();
|
||||
resp.setHeader("Cache-Control", "no-cache", false);
|
||||
resp.setHeader("Content-Type", "text/html;charset=utf-8", false);
|
||||
|
||||
timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.init(() => {
|
||||
resp.write("hi");
|
||||
resp.finish();
|
||||
}, DELAY_MS, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const testState = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: "about:blank" }] },
|
||||
]
|
||||
}],
|
||||
scratchpads: [
|
||||
{ text: "text1", executionContext: 1 },
|
||||
{ text: "", executionContext: 2, filename: "test.js" }
|
||||
]
|
||||
};
|
||||
|
||||
// only finish() when correct number of windows opened
|
||||
var restored = [];
|
||||
function addState(state) {
|
||||
restored.push(state);
|
||||
|
||||
if (restored.length == testState.scratchpads.length) {
|
||||
ok(statesMatch(restored, testState.scratchpads),
|
||||
"Two scratchpad windows restored");
|
||||
|
||||
Services.ww.unregisterNotification(windowObserver);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.ww.registerNotification(windowObserver);
|
||||
|
||||
ss.setBrowserState(JSON.stringify(testState));
|
||||
}
|
||||
|
||||
function windowObserver(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowopened") {
|
||||
let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
|
||||
if (win.Scratchpad) {
|
||||
win.Scratchpad.addObserver({
|
||||
onReady: function() {
|
||||
win.Scratchpad.removeObserver(this);
|
||||
|
||||
let state = win.Scratchpad.getState();
|
||||
BrowserTestUtils.closeWindow(win).then(() => {
|
||||
addState(state);
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
|
||||
function statesMatch(restored, states) {
|
||||
return states.every(function(state) {
|
||||
return restored.some(function(restoredState) {
|
||||
return state.filename == restoredState.filename &&
|
||||
state.text == restoredState.text &&
|
||||
state.executionContext == restoredState.executionContext;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const NOTIFICATION = "sessionstore-browser-state-restored";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
function observe(subject, topic, data) {
|
||||
if (NOTIFICATION == topic) {
|
||||
finish();
|
||||
ok(true, "TOPIC received");
|
||||
}
|
||||
}
|
||||
|
||||
Services.obs.addObserver(observe, NOTIFICATION, false);
|
||||
registerCleanupFunction(function () {
|
||||
Services.obs.removeObserver(observe, NOTIFICATION);
|
||||
});
|
||||
|
||||
ss.setBrowserState(JSON.stringify({ windows: [] }));
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let eventReceived = false;
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
ok(eventReceived, "SSWindowClosing event received");
|
||||
});
|
||||
|
||||
newWindow(function (win) {
|
||||
win.addEventListener("SSWindowClosing", function onWindowClosing() {
|
||||
win.removeEventListener("SSWindowClosing", onWindowClosing, false);
|
||||
eventReceived = true;
|
||||
}, false);
|
||||
|
||||
BrowserTestUtils.closeWindow(win).then(() => {
|
||||
waitForFocus(finish);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function newWindow(callback) {
|
||||
let opts = "chrome,all,dialog=no,height=800,width=800";
|
||||
let win = window.openDialog(getBrowserURL(), "_blank", opts);
|
||||
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
executeSoon(() => callback(win));
|
||||
}, false);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue