diff options
Diffstat (limited to 'docshell/test/navigation')
119 files changed, 5046 insertions, 0 deletions
diff --git a/docshell/test/navigation/.eslintrc.js b/docshell/test/navigation/.eslintrc.js new file mode 100644 index 0000000000..af3d7f7c7f --- /dev/null +++ b/docshell/test/navigation/.eslintrc.js @@ -0,0 +1,11 @@ +"use strict"; + +module.exports = { + extends: ["plugin:mozilla/browser-test", "plugin:mozilla/mochitest-test"], + + plugins: ["no-unsanitized"], + + rules: { + "no-unsanitized/method": "off", + }, +}; diff --git a/docshell/test/navigation/NavigationUtils.js b/docshell/test/navigation/NavigationUtils.js new file mode 100644 index 0000000000..4d9d40a3c6 --- /dev/null +++ b/docshell/test/navigation/NavigationUtils.js @@ -0,0 +1,203 @@ +/* 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/. */ + +// ///////////////////////////////////////////////////////////////////////// +// +// Utilities for navigation tests +// +// ///////////////////////////////////////////////////////////////////////// + +var body = "This frame was navigated."; +var target_url = "navigation_target_url.html"; + +var popup_body = "This is a popup"; +var target_popup_url = "navigation_target_popup_url.html"; + +// ///////////////////////////////////////////////////////////////////////// +// Functions that navigate frames +// ///////////////////////////////////////////////////////////////////////// + +function navigateByLocation(wnd) { + try { + wnd.location = target_url; + } catch (ex) { + // We need to keep our finished frames count consistent. + // Oddly, this ends up simulating the behavior of IE7. + window.open(target_url, "_blank", "width=10,height=10"); + } +} + +function navigateByOpen(name) { + window.open(target_url, name, "width=10,height=10"); +} + +function navigateByForm(name) { + var form = document.createElement("form"); + form.action = target_url; + form.method = "POST"; + form.target = name; + document.body.appendChild(form); + form.submit(); +} + +var hyperlink_count = 0; + +async function navigateByHyperlink(name) { + var link = document.createElement("a"); + link.href = target_url; + link.target = name; + link.id = "navigation_hyperlink_" + hyperlink_count++; + document.body.appendChild(link); + await sendMouseEvent({ type: "click" }, link.id); +} + +// ///////////////////////////////////////////////////////////////////////// +// Functions that call into Mochitest framework +// ///////////////////////////////////////////////////////////////////////// + +async function isNavigated(wnd, message) { + var result = null; + try { + result = await SpecialPowers.spawn(wnd, [], () => + this.content.document.body.innerHTML.trim() + ); + } catch (ex) { + result = ex; + } + is(result, body, message); +} + +function isBlank(wnd, message) { + var result = null; + try { + result = wnd.document.body.innerHTML.trim(); + } catch (ex) { + result = ex; + } + is(result, "This is a blank document.", message); +} + +function isAccessible(wnd, message) { + try { + wnd.document.body.innerHTML; + ok(true, message); + } catch (ex) { + ok(false, message); + } +} + +function isInaccessible(wnd, message) { + try { + wnd.document.body.innerHTML; + ok(false, message); + } catch (ex) { + ok(true, message); + } +} + +function delay(msec) { + return new Promise(resolve => setTimeout(resolve, msec)); +} + +// ///////////////////////////////////////////////////////////////////////// +// Functions that uses SpecialPowers.spawn +// ///////////////////////////////////////////////////////////////////////// + +async function waitForFinishedFrames(numFrames) { + SimpleTest.requestFlakyTimeout("Polling"); + + var finishedWindows = new Set(); + + async function searchForFinishedFrames(win) { + try { + let { href, bodyText, readyState } = await SpecialPowers.spawn( + win, + [], + () => { + return { + href: this.content.location.href, + bodyText: + this.content.document.body && + this.content.document.body.textContent.trim(), + readyState: this.content.document.readyState, + }; + } + ); + + if ( + (href.endsWith(target_url) || href.endsWith(target_popup_url)) && + (bodyText == body || bodyText == popup_body) && + readyState == "complete" + ) { + finishedWindows.add(SpecialPowers.getBrowsingContextID(win)); + } + } catch (e) { + // This may throw if a frame is not fully initialized, in which + // case we'll handle it in a later iteration. + } + + for (let i = 0; i < win.frames.length; i++) { + await searchForFinishedFrames(win.frames[i]); + } + } + + while (finishedWindows.size < numFrames) { + await delay(500); + + for (let win of SpecialPowers.getGroupTopLevelWindows(window)) { + win = SpecialPowers.unwrap(win); + await searchForFinishedFrames(win); + } + } + + if (finishedWindows.size > numFrames) { + throw new Error("Too many frames loaded."); + } +} + +async function getFramesByName(name) { + let results = []; + for (let win of SpecialPowers.getGroupTopLevelWindows(window)) { + win = SpecialPowers.unwrap(win); + if ( + (await SpecialPowers.spawn(win, [], () => this.content.name)) === name + ) { + results.push(win); + } + } + + return results; +} + +async function cleanupWindows() { + for (let win of SpecialPowers.getGroupTopLevelWindows(window)) { + win = SpecialPowers.unwrap(win); + if (win.closed) { + continue; + } + + let href = ""; + try { + href = await SpecialPowers.spawn( + win, + [], + () => + this.content && this.content.location && this.content.location.href + ); + } catch (error) { + // SpecialPowers.spawn(win, ...) throws if win is closed. We did + // our best to not call it on a closed window, but races happen. + if (!win.closed) { + throw error; + } + } + + if ( + href && + (href.endsWith(target_url) || href.endsWith(target_popup_url)) + ) { + win.close(); + } + } +} diff --git a/docshell/test/navigation/blank.html b/docshell/test/navigation/blank.html new file mode 100644 index 0000000000..5360333f1d --- /dev/null +++ b/docshell/test/navigation/blank.html @@ -0,0 +1 @@ +<html><body>This is a blank document.</body></html>
\ No newline at end of file diff --git a/docshell/test/navigation/bluebox_bug430723.html b/docshell/test/navigation/bluebox_bug430723.html new file mode 100644 index 0000000000..5dcc533562 --- /dev/null +++ b/docshell/test/navigation/bluebox_bug430723.html @@ -0,0 +1,6 @@ +<html><head> +<script> window.addEventListener("pageshow", function() { opener.nextTest(); }); </script> +</head><body> +<div style="position:absolute; left:0px; top:0px; width:50%; height:150%; background-color:blue"> +<p>This is a very tall blue box.</p> +</div></body></html> diff --git a/docshell/test/navigation/browser.ini b/docshell/test/navigation/browser.ini new file mode 100644 index 0000000000..f5b7f427df --- /dev/null +++ b/docshell/test/navigation/browser.ini @@ -0,0 +1,15 @@ +[DEFAULT] +support-files = + bug343515_pg1.html + bug343515_pg2.html + bug343515_pg3.html + bug343515_pg3_1.html + bug343515_pg3_1_1.html + bug343515_pg3_2.html + +[browser_test_bfcache_eviction.js] +skip-if = fission # bug 1665165 +[browser_bug343515.js] +[browser_test-content-chromeflags.js] +tags = openwindow +[browser_ghistorymaxsize_is_0.js] diff --git a/docshell/test/navigation/browser_bug343515.js b/docshell/test/navigation/browser_bug343515.js new file mode 100644 index 0000000000..35acf9a6b5 --- /dev/null +++ b/docshell/test/navigation/browser_bug343515.js @@ -0,0 +1,267 @@ +// Test for bug 343515 - Need API for tabbrowsers to tell docshells they're visible/hidden + +// Globals +var testPath = "http://mochi.test:8888/browser/docshell/test/navigation/"; +var ctx = {}; + +add_task(async function() { + // Step 1. + + // Get a handle on the initial tab + ctx.tab0 = gBrowser.selectedTab; + ctx.tab0Browser = gBrowser.getBrowserForTab(ctx.tab0); + + await BrowserTestUtils.waitForCondition( + () => ctx.tab0Browser.docShellIsActive, + "Timed out waiting for initial tab to be active." + ); + + // Open a New Tab + ctx.tab1 = BrowserTestUtils.addTab(gBrowser, testPath + "bug343515_pg1.html"); + ctx.tab1Browser = gBrowser.getBrowserForTab(ctx.tab1); + await BrowserTestUtils.browserLoaded(ctx.tab1Browser); + + // Step 2. + is( + testPath + "bug343515_pg1.html", + ctx.tab1Browser.currentURI.spec, + "Got expected tab 1 url in step 2" + ); + + // Our current tab should still be active + ok(ctx.tab0Browser.docShellIsActive, "Tab 0 should still be active"); + ok(!ctx.tab1Browser.docShellIsActive, "Tab 1 should not be active"); + + // Switch to tab 1 + await BrowserTestUtils.switchTab(gBrowser, ctx.tab1); + + // Tab 1 should now be active + ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); + ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active"); + + // Open another tab + ctx.tab2 = BrowserTestUtils.addTab(gBrowser, testPath + "bug343515_pg2.html"); + ctx.tab2Browser = gBrowser.getBrowserForTab(ctx.tab2); + + await BrowserTestUtils.browserLoaded(ctx.tab2Browser); + + // Step 3. + is( + testPath + "bug343515_pg2.html", + ctx.tab2Browser.currentURI.spec, + "Got expected tab 2 url in step 3" + ); + + // Tab 0 should be inactive, Tab 1 should be active + ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); + ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active"); + + // Tab 2's window _and_ its iframes should be inactive + ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive"); + + await SpecialPowers.spawn(ctx.tab2Browser, [], async function() { + Assert.equal(content.frames.length, 2, "Tab 2 should have 2 iframes"); + for (var i = 0; i < content.frames.length; i++) { + info("step 3, frame " + i + " info: " + content.frames[i].location); + let bc = content.frames[i].browsingContext; + Assert.ok(!bc.isActive, `Tab2 iframe ${i} should be inactive`); + } + }); + + // Navigate tab 2 to a different page + BrowserTestUtils.loadURI(ctx.tab2Browser, testPath + "bug343515_pg3.html"); + + await BrowserTestUtils.browserLoaded(ctx.tab2Browser); + + // Step 4. + + async function checkTab2Active(outerExpected) { + await SpecialPowers.spawn(ctx.tab2Browser, [outerExpected], async function( + expected + ) { + function isActive(aWindow) { + var docshell = aWindow.docShell; + info(`checking ${docshell.browsingContext.id}`); + return docshell.browsingContext.isActive; + } + + let active = expected ? "active" : "inactive"; + Assert.equal(content.frames.length, 2, "Tab 2 should have 2 iframes"); + for (var i = 0; i < content.frames.length; i++) { + info("step 4, frame " + i + " info: " + content.frames[i].location); + } + Assert.equal( + content.frames[0].frames.length, + 1, + "Tab 2 iframe 0 should have 1 iframes" + ); + Assert.equal( + isActive(content.frames[0]), + expected, + `Tab2 iframe 0 should be ${active}` + ); + Assert.equal( + isActive(content.frames[0].frames[0]), + expected, + `Tab2 iframe 0 subiframe 0 should be ${active}` + ); + Assert.equal( + isActive(content.frames[1]), + expected, + `Tab2 iframe 1 should be ${active}` + ); + }); + } + + is( + testPath + "bug343515_pg3.html", + ctx.tab2Browser.currentURI.spec, + "Got expected tab 2 url in step 4" + ); + + // Tab 0 should be inactive, Tab 1 should be active + ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); + ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active"); + + // Tab2 and all descendants should be inactive + await checkTab2Active(false); + + // Switch to Tab 2 + await BrowserTestUtils.switchTab(gBrowser, ctx.tab2); + + // Check everything + ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); + ok(!ctx.tab1Browser.docShellIsActive, "Tab 1 should be inactive"); + ok(ctx.tab2Browser.docShellIsActive, "Tab 2 should be active"); + + await checkTab2Active(true); + + // Go back + let backDone = BrowserTestUtils.waitForContentEvent( + ctx.tab2Browser, + "pageshow" + ); + ctx.tab2Browser.goBack(); + await backDone; + + // Step 5. + + // Check everything + ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); + ok(!ctx.tab1Browser.docShellIsActive, "Tab 1 should be inactive"); + ok(ctx.tab2Browser.docShellIsActive, "Tab 2 should be active"); + is( + testPath + "bug343515_pg2.html", + ctx.tab2Browser.currentURI.spec, + "Got expected tab 2 url in step 5" + ); + + await SpecialPowers.spawn(ctx.tab2Browser, [], async function() { + for (var i = 0; i < content.frames.length; i++) { + let bc = content.frames[i].browsingContext; + Assert.ok(bc.isActive, `Tab2 iframe ${i} should be active`); + } + }); + + // Switch to tab 1 + await BrowserTestUtils.switchTab(gBrowser, ctx.tab1); + + // Navigate to page 3 + BrowserTestUtils.loadURI(ctx.tab1Browser, testPath + "bug343515_pg3.html"); + + await BrowserTestUtils.browserLoaded(ctx.tab1Browser); + + // Step 6. + + // Check everything + ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); + ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active"); + is( + testPath + "bug343515_pg3.html", + ctx.tab1Browser.currentURI.spec, + "Got expected tab 1 url in step 6" + ); + + await SpecialPowers.spawn(ctx.tab1Browser, [], async function() { + function isActive(aWindow) { + var docshell = aWindow.docShell; + info(`checking ${docshell.browsingContext.id}`); + return docshell.browsingContext.isActive; + } + + Assert.ok(isActive(content.frames[0]), "Tab1 iframe 0 should be active"); + Assert.ok( + isActive(content.frames[0].frames[0]), + "Tab1 iframe 0 subiframe 0 should be active" + ); + Assert.ok(isActive(content.frames[1]), "Tab1 iframe 1 should be active"); + }); + + ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive"); + + await SpecialPowers.spawn(ctx.tab2Browser, [], async function() { + for (var i = 0; i < content.frames.length; i++) { + let bc = content.frames[i].browsingContext; + Assert.ok(!bc.isActive, `Tab2 iframe ${i} should be inactive`); + } + }); + + // Go forward on tab 2 + let forwardDone = BrowserTestUtils.waitForContentEvent( + ctx.tab2Browser, + "pageshow" + ); + ctx.tab2Browser.goForward(); + await forwardDone; + + // Step 7. + + async function checkBrowser(browser, outerTabNum, outerActive) { + let data = { tabNum: outerTabNum, active: outerActive }; + await SpecialPowers.spawn(browser, [data], async function({ + tabNum, + active, + }) { + function isActive(aWindow) { + var docshell = aWindow.docShell; + info(`checking ${docshell.browsingContext.id}`); + return docshell.browsingContext.isActive; + } + + let activestr = active ? "active" : "inactive"; + Assert.equal( + isActive(content.frames[0]), + active, + `Tab${tabNum} iframe 0 should be ${activestr}` + ); + Assert.equal( + isActive(content.frames[0].frames[0]), + active, + `Tab${tabNum} iframe 0 subiframe 0 should be ${activestr}` + ); + Assert.equal( + isActive(content.frames[1]), + active, + `Tab${tabNum} iframe 1 should be ${activestr}` + ); + }); + } + + // Check everything + ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); + ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active"); + is( + testPath + "bug343515_pg3.html", + ctx.tab2Browser.currentURI.spec, + "Got expected tab 2 url in step 7" + ); + + await checkBrowser(ctx.tab1Browser, 1, true); + + ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive"); + await checkBrowser(ctx.tab2Browser, 2, false); + + // Close the tabs we made + BrowserTestUtils.removeTab(ctx.tab1); + BrowserTestUtils.removeTab(ctx.tab2); +}); diff --git a/docshell/test/navigation/browser_ghistorymaxsize_is_0.js b/docshell/test/navigation/browser_ghistorymaxsize_is_0.js new file mode 100644 index 0000000000..4034f63bd9 --- /dev/null +++ b/docshell/test/navigation/browser_ghistorymaxsize_is_0.js @@ -0,0 +1,81 @@ +add_task(async function() { + // The urls don't really matter as long as they are of the same origin + var URL = + "http://mochi.test:8888/browser/docshell/test/navigation/bug343515_pg1.html"; + var URL2 = + "http://mochi.test:8888/browser/docshell/test/navigation/bug343515_pg3_1.html"; + + // We want to test a specific code path that leads to this call + // https://searchfox.org/mozilla-central/rev/e7c61f4a68b974d5fecd216dc7407b631a24eb8f/docshell/base/nsDocShell.cpp#10795 + // when gHistoryMaxSize is 0 and mIndex and mRequestedIndex are -1 + + // 1. Navigate to URL + await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, async function( + browser + ) { + // At this point, we haven't set gHistoryMaxSize to 0, and it is still 50 (default value). + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + let sh = browser.browsingContext.sessionHistory; + is( + sh.count, + 1, + "We should have entry in session history because we haven't changed gHistoryMaxSize to be 0 yet" + ); + is( + sh.index, + 0, + "Shistory's current index should be 0 because we haven't purged history yet" + ); + } else { + await ContentTask.spawn(browser, null, () => { + var sh = content.window.docShell.QueryInterface(Ci.nsIWebNavigation) + .sessionHistory.legacySHistory; + is( + sh.count, + 1, + "We should have entry in session history because we haven't changed gHistoryMaxSize to be 0 yet" + ); + is( + sh.index, + 0, + "Shistory's current index should be 0 because we haven't purged history yet" + ); + }); + } + + var loadPromise = BrowserTestUtils.browserLoaded(browser, false, URL2); + // If we set the pref at the beginning of this page, then when we launch a child process + // to navigate to URL in Step 1, because of + // https://searchfox.org/mozilla-central/rev/e7c61f4a68b974d5fecd216dc7407b631a24eb8f/docshell/shistory/nsSHistory.cpp#308-312 + // this pref will be set to the default value (currently 50). Setting this pref after the child process launches + // is a robust way to make sure it stays 0 + await SpecialPowers.pushPrefEnv({ + set: [["browser.sessionhistory.max_entries", 0]], + }); + // 2. Navigate to URL2 + // We are navigating to a page with the same origin so that we will stay in the same process + BrowserTestUtils.loadURI(browser, URL2); + await loadPromise; + + // 3. Reload the browser with specific flags so that we end up here + // https://searchfox.org/mozilla-central/rev/e7c61f4a68b974d5fecd216dc7407b631a24eb8f/docshell/base/nsDocShell.cpp#10795 + var promise = BrowserTestUtils.browserLoaded(browser); + browser.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE); + await promise; + + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + let sh = browser.browsingContext.sessionHistory; + is(sh.count, 0, "We should not save any entries in session history"); + is(sh.index, -1); + is(sh.requestedIndex, -1); + } else { + await ContentTask.spawn(browser, null, () => { + var sh = content.window.docShell.QueryInterface(Ci.nsIWebNavigation) + .sessionHistory.legacySHistory; + is(sh.count, 0, "We should not save any entries in session history"); + is(sh.index, -1); + is(sh.requestedIndex, -1); + }); + } + }); +}); diff --git a/docshell/test/navigation/browser_test-content-chromeflags.js b/docshell/test/navigation/browser_test-content-chromeflags.js new file mode 100644 index 0000000000..af527b2dbc --- /dev/null +++ b/docshell/test/navigation/browser_test-content-chromeflags.js @@ -0,0 +1,57 @@ +const TEST_PAGE = `data:text/html,<html><body><a href="about:blank" target="_blank">Test</a></body></html>`; +const { + CHROME_ALL, + CHROME_REMOTE_WINDOW, + CHROME_FISSION_WINDOW, +} = Ci.nsIWebBrowserChrome; + +/** + * Tests that when we open new browser windows from content they + * get the full browser chrome. + */ +add_task(async function() { + // Make sure that the window.open call will open a new + // window instead of a new tab. + await new Promise(resolve => { + SpecialPowers.pushPrefEnv( + { + set: [["browser.link.open_newwindow", 2]], + }, + resolve + ); + }); + + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: TEST_PAGE, + }, + async function(browser) { + let openedPromise = BrowserTestUtils.waitForNewWindow(); + BrowserTestUtils.synthesizeMouse("a", 0, 0, {}, browser); + let win = await openedPromise; + + let chromeFlags = win.docShell.treeOwner + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIAppWindow).chromeFlags; + + let expected = CHROME_ALL; + + // In the multi-process tab case, the new window will have the + // CHROME_REMOTE_WINDOW flag set. + if (gMultiProcessBrowser) { + expected |= CHROME_REMOTE_WINDOW; + } + + // In the multi-process subframe case, the new window will have the + // CHROME_FISSION_WINDOW flag set. + if (gFissionBrowser) { + expected |= CHROME_FISSION_WINDOW; + } + + is(chromeFlags, expected, "Window should have opened with all chrome"); + + await BrowserTestUtils.closeWindow(win); + } + ); +}); diff --git a/docshell/test/navigation/browser_test_bfcache_eviction.js b/docshell/test/navigation/browser_test_bfcache_eviction.js new file mode 100644 index 0000000000..70cb258b7c --- /dev/null +++ b/docshell/test/navigation/browser_test_bfcache_eviction.js @@ -0,0 +1,96 @@ +add_task(async function() { + // We don't want the number of total viewers to be calculated by the available size + // for this test case. Instead, fix the number of viewers. + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.sessionhistory.max_total_viewers", 3], + ["docshell.shistory.testing.bfevict", true], + ], + }); + + // 1. Open a tab + var testPage = + "data:text/html,<html id='html1'><body id='body1'>First tab ever opened</body></html>"; + await BrowserTestUtils.withNewTab({ gBrowser, url: testPage }, async function( + browser + ) { + let testDone = {}; + if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) { + // 2. Add a promise that will be resolved when the 'content viewer evicted' event goes off + testDone.promise = SpecialPowers.spawn(browser, [], async function() { + return new Promise(resolve => { + let webNavigation = content.docShell.QueryInterface( + Ci.nsIWebNavigation + ); + let { legacySHistory } = webNavigation.sessionHistory; + // 3. Register a session history listener to listen for a 'content viewer evicted' event. + let historyListener = { + OnContentViewerEvicted() { + ok( + true, + "History listener got called after a content viewer was evicted" + ); + legacySHistory.removeSHistoryListener(historyListener); + // 6. Resolve the promise when we got our 'content viewer evicted' event + resolve(); + }, + QueryInterface: ChromeUtils.generateQI([ + "nsISHistoryListener", + "nsISupportsWeakReference", + ]), + }; + legacySHistory.addSHistoryListener(historyListener); + // Keep the weak shistory listener alive + content._testListener = historyListener; + }); + }); + } else { + // 2. Add a promise that will be resolved when the 'content viewer evicted' event goes off + testDone.promise = new Promise(resolve => { + testDone.resolve = resolve; + }); + let shistory = browser.browsingContext.sessionHistory; + // 3. Register a session history listener to listen for a 'content viewer evicted' event. + let historyListener = { + OnContentViewerEvicted() { + ok( + true, + "History listener got called after a content viewer was evicted" + ); + shistory.removeSHistoryListener(historyListener); + delete window._testListener; + // 6. Resolve the promise when we got our 'content viewer evicted' event + testDone.resolve(); + }, + QueryInterface: ChromeUtils.generateQI([ + "nsISHistoryListener", + "nsISupportsWeakReference", + ]), + }; + shistory.addSHistoryListener(historyListener); + // Keep the weak shistory listener alive + window._testListener = historyListener; + } + + // 4. Open a second tab + testPage = `data:text/html,<html id='html1'><body id='body1'>I am a second tab!</body></html>`; + let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, testPage); + + // 5. Navigate the first tab to 4 different pages. + // We should get 1 content viewer evicted because it will be outside of the range. + // If we have the following pages in our session history: P1 P2 P3 P4 P5 + // and we are currently at P5, then P1 is outside of the range + // (it is more than 3 entries away from current entry) and thus will be evicted. + for (var i = 0; i < 4; i++) { + testPage = `data:text/html,<html id='html1'><body id='body1'>${i}</body></html>`; + let pagePromise = BrowserTestUtils.browserLoaded(browser); + BrowserTestUtils.loadURI(browser, testPage); + await pagePromise; + } + // 7. Wait for 'content viewer evicted' event to go off + await testDone.promise; + + // 8. Close the second tab + BrowserTestUtils.removeTab(tab2); + }); +}); diff --git a/docshell/test/navigation/bug343515_pg1.html b/docshell/test/navigation/bug343515_pg1.html new file mode 100644 index 0000000000..a8337c7f70 --- /dev/null +++ b/docshell/test/navigation/bug343515_pg1.html @@ -0,0 +1,5 @@ +<html> + <head><meta charset="UTF-8"/></head> + <body>Page 1 + </body> +</html> diff --git a/docshell/test/navigation/bug343515_pg2.html b/docshell/test/navigation/bug343515_pg2.html new file mode 100644 index 0000000000..c5f5665de5 --- /dev/null +++ b/docshell/test/navigation/bug343515_pg2.html @@ -0,0 +1,7 @@ +<html> + <head><meta charset="UTF-8"/></head> + <body>Page 2 + <iframe src="data:text/html;charset=UTF8,<html><head></head><body>pg2 iframe 0</body></html>"></iframe> + <iframe src="data:text/html;charset=UTF8,<html><head></head><body>pg2 iframe 1</body></html>"></iframe> + </body> +</html> diff --git a/docshell/test/navigation/bug343515_pg3.html b/docshell/test/navigation/bug343515_pg3.html new file mode 100644 index 0000000000..fdc79fbf7a --- /dev/null +++ b/docshell/test/navigation/bug343515_pg3.html @@ -0,0 +1,7 @@ +<html> + <head><meta charset="UTF-8"/></head> + <body>Page 3 + <iframe src="bug343515_pg3_1.html"></iframe> + <iframe src="bug343515_pg3_2.html"></iframe> + </body> +</html> diff --git a/docshell/test/navigation/bug343515_pg3_1.html b/docshell/test/navigation/bug343515_pg3_1.html new file mode 100644 index 0000000000..254164c9f0 --- /dev/null +++ b/docshell/test/navigation/bug343515_pg3_1.html @@ -0,0 +1,6 @@ +<html> + <head><meta charset="UTF-8"/></head> + <body>pg3 - iframe 0 + <iframe src="bug343515_pg3_1_1.html"></iframe> + </body> +</html> diff --git a/docshell/test/navigation/bug343515_pg3_1_1.html b/docshell/test/navigation/bug343515_pg3_1_1.html new file mode 100644 index 0000000000..be05b74888 --- /dev/null +++ b/docshell/test/navigation/bug343515_pg3_1_1.html @@ -0,0 +1 @@ +<html><head><meta charset="UTF-8"/></head><body>How far does the rabbit hole go?</body></html> diff --git a/docshell/test/navigation/bug343515_pg3_2.html b/docshell/test/navigation/bug343515_pg3_2.html new file mode 100644 index 0000000000..7655eb526d --- /dev/null +++ b/docshell/test/navigation/bug343515_pg3_2.html @@ -0,0 +1 @@ +<html><head><meta charset="UTF-8"/></head><body>pg3 iframe 1</body></html> diff --git a/docshell/test/navigation/file_bug1300461.html b/docshell/test/navigation/file_bug1300461.html new file mode 100644 index 0000000000..d7abe8be90 --- /dev/null +++ b/docshell/test/navigation/file_bug1300461.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <title>Bug 1300461</title> + </head> + <body onload="test();"> + <script> + /** + * Bug 1300461 identifies that if a history entry was not bfcached, and + * a http redirection happens when navigating to that entry, the history + * index would mess up. + * + * The test case emulates the circumstance by the following steps + * 1) Navigate to file_bug1300461_back.html which is not bf-cachable. + * 2) In file_bug1300461_back.html, replace its own history state to + * file_bug1300461_redirect.html. + * 3) Back, and then forward. Since the document is not in bfcache, it + * tries to load file_bug1300461_redirect.html directly. + * 4) file_bug1300461_redirect.html redirects UA to + * file_bug1300461_back.html through HTTP 301 header. + * + * We verify the history index, canGoBack, canGoForward, etc. keep correct + * in this process. + */ + let Ci = SpecialPowers.Ci; + let webNav = SpecialPowers.wrap(window) + .docShell + .QueryInterface(Ci.nsIWebNavigation); + let shistory = webNav.sessionHistory; + let testSteps = [ + function() { + opener.is(shistory.count, 1, "check history length"); + opener.is(shistory.index, 0, "check history index"); + opener.ok(!webNav.canGoForward, "check canGoForward"); + setTimeout(() => window.location = "file_bug1300461_back.html", 0); + }, + function() { + opener.is(shistory.count, 2, "check history length"); + opener.is(shistory.index, 0, "check history index"); + opener.ok(webNav.canGoForward, "check canGoForward"); + window.history.forward(); + }, + function() { + opener.is(shistory.count, 2, "check history length"); + opener.is(shistory.index, 0, "check history index"); + opener.ok(webNav.canGoForward, "check canGoForward"); + opener.info("file_bug1300461.html tests finished"); + opener.finishTest(); + }, + ]; + + function test() { + if (opener) { + opener.info("file_bug1300461.html test " + opener.testCount); + testSteps[opener.testCount++](); + } + } + </script> + </body> +</html> diff --git a/docshell/test/navigation/file_bug1300461_back.html b/docshell/test/navigation/file_bug1300461_back.html new file mode 100644 index 0000000000..ea014cce34 --- /dev/null +++ b/docshell/test/navigation/file_bug1300461_back.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <title>Bug 1300461</title> + </head> + <!-- The empty unload handler is to prevent bfcache. --> + <body onload="test();" onunload=""> + <script> + let Ci = SpecialPowers.Ci; + let webNav = SpecialPowers.wrap(window) + .docShell + .QueryInterface(Ci.nsIWebNavigation); + let shistory = webNav.sessionHistory; + async function test() { + if (opener) { + opener.info("file_bug1300461_back.html"); + opener.is(shistory.count, 2, "check history length"); + opener.is(shistory.index, 1, "check history index"); + if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) { + opener.is(shistory.legacySHistory.requestedIndex, -1, "check requestedIndex"); + } else { + let index = await opener.getSHRequestedIndex(); + opener.is(index, -1, "check requestedIndex"); + } + + opener.ok(webNav.canGoBack, "check canGoBack"); + if (opener.testCount == 1) { + opener.info("replaceState to redirect.html"); + window.history.replaceState({}, "", "file_bug1300461_redirect.html"); + } + window.history.back(); + } + } + </script> + </body> +</html> diff --git a/docshell/test/navigation/file_bug1300461_redirect.html b/docshell/test/navigation/file_bug1300461_redirect.html new file mode 100644 index 0000000000..979530c5cf --- /dev/null +++ b/docshell/test/navigation/file_bug1300461_redirect.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <title>Bug 1300461</title> + </head> + <body> + Redirect to file_bug1300461_back.html. + </body> +</html> diff --git a/docshell/test/navigation/file_bug1300461_redirect.html^headers^ b/docshell/test/navigation/file_bug1300461_redirect.html^headers^ new file mode 100644 index 0000000000..241b891826 --- /dev/null +++ b/docshell/test/navigation/file_bug1300461_redirect.html^headers^ @@ -0,0 +1,2 @@ +HTTP 301 Moved Permanently +Location: file_bug1300461_back.html diff --git a/docshell/test/navigation/file_bug1326251.html b/docshell/test/navigation/file_bug1326251.html new file mode 100644 index 0000000000..f252df98bf --- /dev/null +++ b/docshell/test/navigation/file_bug1326251.html @@ -0,0 +1,190 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Bug 1326251</title> + <script> + const BASE_URL = "http://mochi.test:8888/tests/docshell/test/navigation/"; + let testSteps = [ + async function() { + // Test 1: Create dynamic iframe with bfcache enabled. + // Navigate static / dynamic iframes, then navigate top level window + // and navigate back. Both iframes should still exist with history + // entries preserved. + window.onunload = null; // enable bfcache + await createDynamicFrame(document); + await loadUriInFrame(document.getElementById("staticFrame"), "frame1.html"); + await loadUriInFrame(document.getElementById("dynamicFrame"), "frame1.html"); + await loadUriInFrame(document.getElementById("staticFrame"), "frame2.html"); + await loadUriInFrame(document.getElementById("dynamicFrame"), "frame2.html"); + opener.is(history.length, 5, "history.length"); + window.location = "goback.html"; + }, + async function() { + let webNav = SpecialPowers.wrap(window) + .docShell + .QueryInterface(SpecialPowers.Ci.nsIWebNavigation); + let shistory = webNav.sessionHistory; + opener.is(webNav.canGoForward, true, "canGoForward"); + opener.is(shistory.index, 4, "shistory.index"); + opener.is(history.length, 6, "history.length"); + opener.is(document.getElementById("staticFrame").contentWindow.location.href, BASE_URL + "frame2.html", "staticFrame location"); + opener.is(document.getElementById("dynamicFrame").contentWindow.location.href, BASE_URL + "frame2.html", "dynamicFrame location"); + + // Test 2: Load another page in dynamic iframe, canGoForward should be + // false. + await loadUriInFrame(document.getElementById("dynamicFrame"), "frame3.html"); + opener.is(webNav.canGoForward, false, "canGoForward"); + opener.is(shistory.index, 5, "shistory.index"); + opener.is(history.length, 6, "history.length"); + + // Test 3: Navigate to antoher page with bfcache disabled, all dynamic + // iframe entries should be removed. + window.onunload = function() {}; // disable bfcache + window.location = "goback.html"; + }, + async function() { + let windowWrap = SpecialPowers.wrap(window); + let docShell = windowWrap.docShell; + let shistory = docShell.QueryInterface(SpecialPowers.Ci.nsIWebNavigation) + .sessionHistory; + // Now staticFrame has frame0 -> frame1 -> frame2. + opener.is(docShell.previousEntryIndex, 3, "docShell.previousEntryIndex"); + opener.is(docShell.loadedEntryIndex, 2, "docShell.loadedEntryIndex"); + opener.is(shistory.index, 2, "shistory.index"); + opener.is(history.length, 4, "history.length"); + opener.is(document.getElementById("staticFrame").contentWindow.location.href, BASE_URL + "frame2.html", "staticFrame location"); + opener.ok(!document.getElementById("dynamicFrame"), "dynamicFrame should not exist"); + + // Test 4: Load a nested frame in the static frame, navigate the inner + // static frame, add a inner dynamic frame and navigate the dynamic + // frame. Then navigate the outer static frame and go back. The inner + // iframe should show the last entry of inner static frame. + let staticFrame = document.getElementById("staticFrame"); + staticFrame.width = "320px"; + staticFrame.height = "360px"; + await loadUriInFrame(staticFrame, "iframe_static.html"); + let innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame"); + await loadUriInFrame(innerStaticFrame, "frame1.html"); + let innerDynamicFrame = await createDynamicFrame(staticFrame.contentDocument, "frame2.html"); + await loadUriInFrame(innerDynamicFrame, "frame3.html"); + // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static + // innerStaticFrame: frame0 -> frame1 + // innerDynamicFrame: frame2 -> frame3 + opener.is(shistory.index, 5, "shistory.index"); + opener.is(history.length, 6, "history.length"); + + // Wait for 2 load events - navigation and goback. + let onloadPromise = awaitOnload(staticFrame, 2); + await loadUriInFrame(staticFrame, "goback.html"); + await onloadPromise; + // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static -> goback + // innerStaticFrame: frame0 -> frame1 + opener.is(shistory.index, 4, "shistory.index"); + opener.is(history.length, 6, "history.length"); + innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame"); + opener.is(innerStaticFrame.contentDocument.location.href, BASE_URL + "frame1.html", "innerStaticFrame location"); + opener.ok(!staticFrame.contentDocument.getElementById("dynamicFrame"), "innerDynamicFrame should not exist"); + + // Test 5: Insert and navigate inner dynamic frame again with bfcache + // enabled, and navigate top level window to a special page which will + // evict bfcache then goback. Verify that dynamic entries are correctly + // removed in this case. + window.onunload = null; // enable bfcache + staticFrame.width = "320px"; + staticFrame.height = "360px"; + innerDynamicFrame = await createDynamicFrame(staticFrame.contentDocument, "frame2.html"); + await loadUriInFrame(innerDynamicFrame, "frame3.html"); + // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static + // innerStaticFrame: frame0 -> frame1 + // innerDynamicFrame: frame2 -> frame3 + opener.is(shistory.index, 5, "shistory.index"); + opener.is(history.length, 6, "history.length"); + window.location = "file_bug1326251_evict_cache.html"; + }, + async function() { + let windowWrap = SpecialPowers.wrap(window); + let docShell = windowWrap.docShell; + let shistory = docShell.QueryInterface(SpecialPowers.Ci.nsIWebNavigation) + .sessionHistory; + // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static + // innerStaticFrame: frame0 -> frame1 + opener.is(docShell.previousEntryIndex, 5, "docShell.previousEntryIndex"); + opener.is(docShell.loadedEntryIndex, 4, "docShell.loadedEntryIndex"); + opener.is(shistory.index, 4, "shistory.index"); + opener.is(history.length, 6, "history.length"); + let staticFrame = document.getElementById("staticFrame"); + let innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame"); + opener.is(innerStaticFrame.contentDocument.location.href, BASE_URL + "frame1.html", "innerStaticFrame location"); + opener.ok(!staticFrame.contentDocument.getElementById("dynamicFrame"), "innerDynamicFrame should not exist"); + + // Test 6: Insert and navigate inner dynamic frame and then reload outer + // frame. Verify that inner dynamic frame entries are all removed. + staticFrame.width = "320px"; + staticFrame.height = "360px"; + let innerDynamicFrame = await createDynamicFrame(staticFrame.contentDocument, "frame2.html"); + await loadUriInFrame(innerDynamicFrame, "frame3.html"); + // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static + // innerStaticFrame: frame0 -> frame1 + // innerDynamicFrame: frame2 -> frame3 + opener.is(shistory.index, 5, "shistory.index"); + opener.is(history.length, 6, "history.length"); + let staticFrameLoadPromise = new Promise(resolve => { + staticFrame.onload = resolve; + }); + staticFrame.contentWindow.location.reload(); + await staticFrameLoadPromise; + // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static + // innerStaticFrame: frame0 -> frame1 + opener.is(shistory.index, 4, "shistory.index"); + opener.is(history.length, 5, "history.length"); + innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame"); + opener.is(innerStaticFrame.contentDocument.location.href, BASE_URL + "frame1.html", "innerStaticFrame location"); + opener.ok(!staticFrame.contentDocument.getElementById("dynamicFrame"), "innerDynamicFrame should not exist"); + opener.finishTest(); + }, + ]; + + function awaitOnload(frame, occurances = 1) { + return new Promise(function(resolve, reject) { + let count = 0; + frame.addEventListener("load", function listener(e) { + if (++count == occurances) { + frame.removeEventListener("load", listener); + setTimeout(resolve, 0); + } + }); + }); + } + + async function createDynamicFrame(targetDocument, frameSrc = "frame0.html") { + let dynamicFrame = targetDocument.createElement("iframe"); + let onloadPromise = awaitOnload(dynamicFrame); + dynamicFrame.id = "dynamicFrame"; + dynamicFrame.src = frameSrc; + let container = targetDocument.getElementById("frameContainer"); + container.appendChild(dynamicFrame); + await onloadPromise; + return dynamicFrame; + } + + async function loadUriInFrame(frame, uri) { + let onloadPromise = awaitOnload(frame); + frame.src = uri; + return onloadPromise; + } + + function test() { + if (opener) { + // Ensure the tests are not executed in onload hander. + setTimeout(testSteps[opener.testCount++], 0); + } + } + </script> + </head> + <body onpageshow="test();"> + <div id="frameContainer"> + <iframe id="staticFrame" src="frame0.html"></iframe> + </div> + </body> +</html> diff --git a/docshell/test/navigation/file_bug1326251_evict_cache.html b/docshell/test/navigation/file_bug1326251_evict_cache.html new file mode 100644 index 0000000000..0f46a26b87 --- /dev/null +++ b/docshell/test/navigation/file_bug1326251_evict_cache.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Bug 1326251</title> + <script> + SpecialPowers.Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); + + // Evict bfcache and then go back. + async function evictCache() { + let shistory = SpecialPowers.wrap(window) + .docShell + .QueryInterface(SpecialPowers.Ci.nsIWebNavigation) + .sessionHistory; + if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) { + shistory.legacySHistory.evictAllContentViewers(); + } else { + opener.evictAllContentViewers(); + } + + history.back(); + } + </script> + </head> + <body onload="setTimeout(evictCache, 0);"> + </body> +</html> diff --git a/docshell/test/navigation/file_bug1364364-1.html b/docshell/test/navigation/file_bug1364364-1.html new file mode 100644 index 0000000000..d4ecc42ad4 --- /dev/null +++ b/docshell/test/navigation/file_bug1364364-1.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>title</title> + </head> + <body onload="loadFramesAndNavigate();"> + <p id="content"></p> + <div id="frameContainer"> + </div> + <script type="application/javascript"> + function waitForLoad(frame) { + return new Promise(r => frame.onload = () => setTimeout(r, 0)); + } + + async function loadFramesAndNavigate() { + let dynamicFrame = document.createElement("iframe"); + dynamicFrame.src = "data:text/html,iframe1"; + document.querySelector("#frameContainer").appendChild(dynamicFrame); + await waitForLoad(dynamicFrame); + dynamicFrame.src = "data:text/html,iframe2"; + await waitForLoad(dynamicFrame); + dynamicFrame.src = "data:text/html,iframe3"; + await waitForLoad(dynamicFrame); + dynamicFrame.src = "data:text/html,iframe4"; + await waitForLoad(dynamicFrame); + dynamicFrame.src = "data:text/html,iframe5"; + await waitForLoad(dynamicFrame); + location.href = "file_bug1364364-2.html"; + } + </script> + </body> +</html> diff --git a/docshell/test/navigation/file_bug1364364-2.html b/docshell/test/navigation/file_bug1364364-2.html new file mode 100644 index 0000000000..6e52ecaaa9 --- /dev/null +++ b/docshell/test/navigation/file_bug1364364-2.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>title</title> + </head> + <body onload="notifyOpener();"> + <script type="application/javascript"> + function notifyOpener() { + opener.postMessage("navigation-done", "*"); + } + </script> + </body> +</html> diff --git a/docshell/test/navigation/file_bug1375833-frame1.html b/docshell/test/navigation/file_bug1375833-frame1.html new file mode 100644 index 0000000000..ea38326479 --- /dev/null +++ b/docshell/test/navigation/file_bug1375833-frame1.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>iframe test page 1</title> + </head> + <body>iframe test page 1</body> +</html> diff --git a/docshell/test/navigation/file_bug1375833-frame2.html b/docshell/test/navigation/file_bug1375833-frame2.html new file mode 100644 index 0000000000..6e76ab7e47 --- /dev/null +++ b/docshell/test/navigation/file_bug1375833-frame2.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>iframe test page 2</title> + </head> + <body>iframe test page 2</body> +</html> diff --git a/docshell/test/navigation/file_bug1375833.html b/docshell/test/navigation/file_bug1375833.html new file mode 100644 index 0000000000..373a7fe08e --- /dev/null +++ b/docshell/test/navigation/file_bug1375833.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Test for bug 1375833</title> + </head> + <body onload="test();"> + <iframe id="testFrame" src="file_bug1375833-frame1.html"></iframe> + <script type="application/javascript"> + function test() { + let iframe = document.querySelector("#testFrame"); + setTimeout(function() { iframe.src = "file_bug1375833-frame1.html"; }, 0); + iframe.onload = function(e) { + setTimeout(function() { iframe.src = "file_bug1375833-frame2.html"; }, 0); + iframe.onload = function() { + opener.postMessage(iframe.contentWindow.location.href, "*"); + }; + }; + } + </script> + </body> +</html> diff --git a/docshell/test/navigation/file_bug1379762-1.html b/docshell/test/navigation/file_bug1379762-1.html new file mode 100644 index 0000000000..c8cd666667 --- /dev/null +++ b/docshell/test/navigation/file_bug1379762-1.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Bug 1379762</title> + </head> + <img srcset> <!-- This tries to add load blockers during bfcache restoration --> + <script> + onunload = null; // enable bfcache + var bc = new BroadcastChannel('bug1379762'); + bc.postMessage("init"); + onpageshow = function() { + bc.onmessage = (messageEvent) => { + let message = messageEvent.data; + if (message == "forward_back") { + // Navigate forward and then back. + // eslint-disable-next-line no-global-assign + setTimeout(function() { location = "goback.html"; }, 0); + } else if (message == "finish_test") { + // Do this async so our load event gets a chance to fire if it plans to + // do it. + setTimeout(function() { + bc.postMessage("finished"); + bc.close(); + window.close(); + }); + } + } + bc.postMessage("increment_testCount"); + }; + onload = function() { + bc.postMessage("increment_loadCount"); + }; + </script> +</html> diff --git a/docshell/test/navigation/file_bug1536471.html b/docshell/test/navigation/file_bug1536471.html new file mode 100644 index 0000000000..53012257ee --- /dev/null +++ b/docshell/test/navigation/file_bug1536471.html @@ -0,0 +1,8 @@ +<html> + <body onload="opener.bodyOnLoad()"> + Nested Frame + <div id="frameContainer"> + <iframe id="staticFrame" src="frame0.html"></iframe> + </div> + </body> +</html> diff --git a/docshell/test/navigation/file_bug1609475.html b/docshell/test/navigation/file_bug1609475.html new file mode 100644 index 0000000000..7699d46b08 --- /dev/null +++ b/docshell/test/navigation/file_bug1609475.html @@ -0,0 +1,51 @@ +<html> + <head> + <script> + + var loadCount = 0; + function loadListener(event) { + ++loadCount; + if (loadCount == 2) { + // Use a timer to ensure we don't get extra load events. + setTimeout(function() { + var doc1URI = document.getElementById("i1").contentDocument.documentURI; + opener.ok(doc1URI.includes("frame1.html"), + "Should have loaded the initial page to the first iframe. Got " + doc1URI); + var doc2URI = document.getElementById("i2").contentDocument.documentURI; + opener.ok(doc2URI.includes("frame1.html"), + "Should have loaded the initial page to the second iframe. Got " + doc2URI); + opener.finishTest(); + }, 1000); + } else if (loadCount > 2) { + opener.ok(false, "Too many load events"); + } + // if we don't get enough load events, the test will time out. + } + + function setupIframe(id) { + var ifr = document.getElementById(id); + return new Promise(function(resolve) { + ifr.onload = function() { + // Replace load listener to catch page loads from the session history. + ifr.onload = loadListener; + // Need to use setTimeout, because triggering loads inside + // load event listener has special behavior since at the moment + // the docshell keeps track of whether it is executing a load handler or not. + setTimeout(resolve); + } + ifr.contentWindow.location.href = "frame2.html"; + }); + } + + async function test() { + await setupIframe("i1"); + await setupIframe("i2"); + history.go(-2); + } + </script> + </head> + <body onload="setTimeout(test)"> + <iframe id="i1" src="frame1.html"></iframe> + <iframe id="i2" src="frame1.html"></iframe> + </body> +</html>
\ No newline at end of file diff --git a/docshell/test/navigation/file_bug386782_contenteditable.html b/docshell/test/navigation/file_bug386782_contenteditable.html new file mode 100644 index 0000000000..4515d015d9 --- /dev/null +++ b/docshell/test/navigation/file_bug386782_contenteditable.html @@ -0,0 +1 @@ +<html><head><meta charset="utf-8"><script>window.addEventListener("pageshow", function(event) { window.opener.postMessage({persisted: event.persisted}, "*"); });</script></head><body contentEditable="true"><p>contentEditable</p></body></html>
\ No newline at end of file diff --git a/docshell/test/navigation/file_bug386782_designmode.html b/docshell/test/navigation/file_bug386782_designmode.html new file mode 100644 index 0000000000..faa063cbae --- /dev/null +++ b/docshell/test/navigation/file_bug386782_designmode.html @@ -0,0 +1 @@ +<html><head><meta charset="utf-8"><script>window.addEventListener("pageshow", function(event) { window.opener.postMessage({persisted: event.persisted}, "*"); });</script></head><body><p>designModeDocument</p></body></html>
\ No newline at end of file diff --git a/docshell/test/navigation/file_bug462076_1.html b/docshell/test/navigation/file_bug462076_1.html new file mode 100644 index 0000000000..5050e79fdc --- /dev/null +++ b/docshell/test/navigation/file_bug462076_1.html @@ -0,0 +1,55 @@ +<html> + <head> + <title>Bug 462076</title> + <script> + var srcs = [ "frame0.html", + "frame1.html", + "frame2.html", + "frame3.html" ]; + + var checkCount = 0; + + function makeFrame(index) { + var ifr = document.createElement("iframe"); + ifr.src = srcs[index]; + ifr.onload = checkFrame; + document.getElementById("container" + index).appendChild(ifr); + } + + function runTest() { + var randomNumber = Math.floor(Math.random() * 4); + for (var i = randomNumber; i < 4; ++i) { + makeFrame(i); + } + for (var k = 0; k < randomNumber; ++k) { + makeFrame(k); + } + } + + function checkFrame(evt) { + var ifr = evt.target; + opener.ok(String(ifr.contentWindow.location).includes(ifr.src), + "Wrong document loaded (" + ifr.src + ", " + + ifr.contentWindow.location + ")!"); + + if (++checkCount == 4) { + if (++opener.testCount == 10) { + opener.nextTest(); + window.close(); + } else { + window.location.reload(); + } + } + } + </script> + </head> + <body> + <div id="container0"></div> + <div id="container1"></div> + <div id="container2"></div> + <div id="container3"></div> + <script> + runTest(); + </script> + </body> +</html> diff --git a/docshell/test/navigation/file_bug462076_2.html b/docshell/test/navigation/file_bug462076_2.html new file mode 100644 index 0000000000..63cf3de3f9 --- /dev/null +++ b/docshell/test/navigation/file_bug462076_2.html @@ -0,0 +1,52 @@ +<html> + <head> + <title>Bug 462076</title> + <script> + var srcs = [ "frame0.html", + "frame1.html", + "frame2.html", + "frame3.html" ]; + + var checkCount = 0; + + function makeFrame(index) { + var ifr = document.createElement("iframe"); + ifr.src = srcs[index]; + ifr.onload = checkFrame; + document.getElementById("container" + index).appendChild(ifr); + } + + function runTest() { + var randomNumber = Math.floor(Math.random() * 4); + for (var i = randomNumber; i < 4; ++i) { + makeFrame(i); + } + for (var k = 0; k < randomNumber; ++k) { + makeFrame(k); + } + } + + function checkFrame(evt) { + var ifr = evt.target; + opener.ok(String(ifr.contentWindow.location).includes(ifr.src), + "Wrong document loaded (" + ifr.src + ", " + + ifr.contentWindow.location + ")!"); + + if (++checkCount == 4) { + if (++opener.testCount == 10) { + opener.nextTest(); + window.close(); + } else { + window.location.reload(); + } + } + } + </script> + </head> + <body onload="runTest();"> + <div id="container0"></div> + <div id="container1"></div> + <div id="container2"></div> + <div id="container3"></div> + </body> +</html> diff --git a/docshell/test/navigation/file_bug462076_3.html b/docshell/test/navigation/file_bug462076_3.html new file mode 100644 index 0000000000..5c779d2f49 --- /dev/null +++ b/docshell/test/navigation/file_bug462076_3.html @@ -0,0 +1,52 @@ +<html> + <head> + <title>Bug 462076</title> + <script> + var srcs = [ "frame0.html", + "frame1.html", + "frame2.html", + "frame3.html" ]; + + var checkCount = 0; + + function makeFrame(index) { + var ifr = document.createElement("iframe"); + ifr.src = srcs[index]; + ifr.onload = checkFrame; + document.getElementById("container" + index).appendChild(ifr); + } + + function runTest() { + var randomNumber = Math.floor(Math.random() * 4); + for (var i = randomNumber; i < 4; ++i) { + makeFrame(i); + } + for (var k = 0; k < randomNumber; ++k) { + makeFrame(k); + } + } + + function checkFrame(evt) { + var ifr = evt.target; + opener.ok(String(ifr.contentWindow.location).includes(ifr.src), + "Wrong document loaded (" + ifr.src + ", " + + ifr.contentWindow.location + ")!"); + + if (++checkCount == 4) { + if (++opener.testCount == 10) { + opener.nextTest(); + window.close(); + } else { + window.location.reload(); + } + } + } + </script> + </head> + <body onload="setTimeout(runTest, 0);"> + <div id="container0"></div> + <div id="container1"></div> + <div id="container2"></div> + <div id="container3"></div> + </body> +</html> diff --git a/docshell/test/navigation/file_bug508537_1.html b/docshell/test/navigation/file_bug508537_1.html new file mode 100644 index 0000000000..182c085670 --- /dev/null +++ b/docshell/test/navigation/file_bug508537_1.html @@ -0,0 +1,33 @@ +<html> + <head> + <script> + function dynFrameLoad() { + var ifrs = document.getElementsByTagName("iframe"); + opener.ok(String(ifrs[0].contentWindow.location).includes(ifrs[0].src), + "Wrong document loaded (1)\n"); + opener.ok(String(ifrs[1].contentWindow.location).includes(ifrs[1].src), + "Wrong document loaded (2)\n"); + if (opener && ++opener.testCount == 1) { + window.location = "goback.html"; + } else { + opener.finishTest(); + } + } + + window.addEventListener("load", + function() { + var container = document.getElementById("t1"); + container.addEventListener("load", dynFrameLoad, true); + container.appendChild(container.appendChild(document.getElementById("i1"))); + }); + </script> + </head> + <body> + <h5>Container:</h5> + <div id="t1"></div> + <h5>Original frames:</h5> + <iframe id="i1" src="frame0.html"></iframe> + <iframe src="frame1.html"></iframe> + </body> +</html> + diff --git a/docshell/test/navigation/file_bug534178.html b/docshell/test/navigation/file_bug534178.html new file mode 100644 index 0000000000..4d77dd824b --- /dev/null +++ b/docshell/test/navigation/file_bug534178.html @@ -0,0 +1,30 @@ +<html> + <head> + <script> + + function testDone() { + document.body.firstChild.remove(); + var isOK = false; + try { + isOK = history.previous != location; + } catch (ex) { + // history.previous should throw if this is the first page in shistory. + isOK = true; + } + document.body.textContent = isOK ? "PASSED" : "FAILED"; + opener.ok(isOK, "Duplicate session history entries should have been removed!"); + opener.finishTest(); + } + function ifrload() { + setTimeout(testDone, 0); + } + function test() { + var ifr = document.getElementsByTagName("iframe")[0]; + ifr.onload = ifrload; + ifr.src = "data:text/html,doc2"; + } + </script> + </head> + <body onload="setTimeout(test, 0)"><iframe src="data:text/html,doc1"></iframe> + </body> +</html> diff --git a/docshell/test/navigation/file_contentpolicy_block_window.html b/docshell/test/navigation/file_contentpolicy_block_window.html new file mode 100644 index 0000000000..c51e574e5e --- /dev/null +++ b/docshell/test/navigation/file_contentpolicy_block_window.html @@ -0,0 +1,5 @@ +<html> +<body> +This window should never be openend! +</body> +</html> diff --git a/docshell/test/navigation/file_docshell_gotoindex.html b/docshell/test/navigation/file_docshell_gotoindex.html new file mode 100644 index 0000000000..f3e8919822 --- /dev/null +++ b/docshell/test/navigation/file_docshell_gotoindex.html @@ -0,0 +1,42 @@ +<html> + <head> + <script> + function loaded() { + if (location.search == "") { + if (opener.loadedInitialPage) { + opener.ok(true, "got back to the initial page."); + opener.setTimeout("SimpleTest.finish();"); + window.close(); + return; + } + opener.loadedInitialPage = true; + opener.info("Loaded initial page."); + // Load another page (which is this same document, but different URL.) + location.href = location.href + "?anotherPage"; + } else { + opener.info("Loaded the second page."); + location.hash = "1"; + window.onhashchange = function() { + opener.info("hash: " + location.hash); + location.hash = "2"; + window.onhashchange = function() { + opener.info("hash: " + location.hash); + var docShell = SpecialPowers.wrap(window).docShell; + var webNavigation = + SpecialPowers.do_QueryInterface(docShell, "nsIWebNavigation"); + webNavigation.gotoIndex(history.length - 2); + window.onhashchange = function() { + opener.info("hash: " + location.hash); + webNavigation.gotoIndex(history.length - 4); + } + } + } + } + } + </script> + </head> + <body onpageshow="setTimeout(loaded)"> + <a href="#1" name="1">1</a> + <a href="#2" name="2">2</a> + </body> +</html>
\ No newline at end of file diff --git a/docshell/test/navigation/file_document_write_1.html b/docshell/test/navigation/file_document_write_1.html new file mode 100644 index 0000000000..be52b60231 --- /dev/null +++ b/docshell/test/navigation/file_document_write_1.html @@ -0,0 +1,18 @@ +<html> + <head> + <script> + function start() { + var length = history.length; + document.open(); + document.write("<h5 id='dynamic'>document.written content</h5>"); + document.close(); + opener.is(history.length, length, + "document.open/close should not change history"); + opener.finishTest(); + } + </script> + </head> + <body onload="start();"> + <h5>static content</h5> + </body> +</html> diff --git a/docshell/test/navigation/file_fragment_handling_during_load.html b/docshell/test/navigation/file_fragment_handling_during_load.html new file mode 100644 index 0000000000..a7f468c32d --- /dev/null +++ b/docshell/test/navigation/file_fragment_handling_during_load.html @@ -0,0 +1,27 @@ +<html> + <head> + <script> + function checkHaveLoadedNewDoc() { + let l = document.body.firstChild.contentWindow.location.href; + if (!l.endsWith("file_fragment_handling_during_load_frame2.sjs")) { + opener.ok(true, "Fine. We will check later."); + setTimeout(checkHaveLoadedNewDoc, 500); + return; + } + opener.ok(true, "Have loaded a new document."); + opener.finishTest(); + } + function test() { + // Test that executing back() before load has started doesn't interrupt + // the load. + var ifr = document.getElementsByTagName("iframe")[0]; + ifr.onload = checkHaveLoadedNewDoc; + ifr.contentWindow.location.hash = "b"; + ifr.contentWindow.location.href = "file_fragment_handling_during_load_frame2.sjs"; + history.back(); + } + </script> + </head> + <body onload="setTimeout(test, 0)"><iframe src="file_fragment_handling_during_load_frame1.html#a"></iframe> + </body> +</html> diff --git a/docshell/test/navigation/file_fragment_handling_during_load_frame1.html b/docshell/test/navigation/file_fragment_handling_during_load_frame1.html new file mode 100644 index 0000000000..c03ba2bda6 --- /dev/null +++ b/docshell/test/navigation/file_fragment_handling_during_load_frame1.html @@ -0,0 +1,6 @@ +<!DOCTYPE HTML> +<html> +<body> +foo +</body> +</html> diff --git a/docshell/test/navigation/file_fragment_handling_during_load_frame2.sjs b/docshell/test/navigation/file_fragment_handling_during_load_frame2.sjs new file mode 100644 index 0000000000..e00d896947 --- /dev/null +++ b/docshell/test/navigation/file_fragment_handling_during_load_frame2.sjs @@ -0,0 +1,19 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80 ft=javascript: */ +"use strict"; + +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/html", false); + response.setHeader("Cache-Control", "no-cache", false); + // Wait a bit. + var s = Date.now(); + while (Date.now() - s < 1000); + + response.write(`<!DOCTYPE HTML> + <html> + <body> + bar + </body> + </html> + `); +}
\ No newline at end of file diff --git a/docshell/test/navigation/file_load_history_entry_page_with_one_link.html b/docshell/test/navigation/file_load_history_entry_page_with_one_link.html new file mode 100644 index 0000000000..a4d1b62176 --- /dev/null +++ b/docshell/test/navigation/file_load_history_entry_page_with_one_link.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> +<body onpageshow="opener.bodyOnLoad()"> +<a id="link1" href="#1">Link 1</a> +<a name="1">link 1</a> +</body> +</html> diff --git a/docshell/test/navigation/file_load_history_entry_page_with_two_links.html b/docshell/test/navigation/file_load_history_entry_page_with_two_links.html new file mode 100644 index 0000000000..4be2ea6f4e --- /dev/null +++ b/docshell/test/navigation/file_load_history_entry_page_with_two_links.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> +<body onpageshow="opener.bodyOnLoad()"> +<a id="link1" href="#1">Link 1</a> +<a id="link2" href="#2">Link 2</a> +<a name="1">link 1</a> +<a name="2">link 2</a> +</body> +</html> diff --git a/docshell/test/navigation/file_nested_frames.html b/docshell/test/navigation/file_nested_frames.html new file mode 100644 index 0000000000..6ec286aa3e --- /dev/null +++ b/docshell/test/navigation/file_nested_frames.html @@ -0,0 +1,27 @@ +<html> + <head> + <script> + function nestedIframeLoaded() { + var tf = document.getElementById("testframe"); + var innerf = tf.contentDocument.getElementsByTagName("iframe")[0]; + if (!innerf.contentDocument.documentURI.includes("frame0")) { + innerf.contentWindow.location.href = "http://mochi.test:8888/tests/docshell/test/navigation/frame0.html"; + return; + } + innerf.onload = null; + innerf.src = "about:blank"; + var d = innerf.contentDocument; + d.open(); + d.write("test"); + d.close(); + opener.is(window.history.length, 1, "Unexpected history length"); + opener.finishTest(); + } + </script> + </head> + <body> + <iframe id="testframe" src="file_nested_frames_innerframe.html" onload="frameLoaded()"></iframe> + <script> + </script> + </body> +</html> diff --git a/docshell/test/navigation/file_nested_frames_innerframe.html b/docshell/test/navigation/file_nested_frames_innerframe.html new file mode 100644 index 0000000000..e25b6a4f6a --- /dev/null +++ b/docshell/test/navigation/file_nested_frames_innerframe.html @@ -0,0 +1 @@ +<iframe onload='parent.nestedIframeLoaded();'></iframe> diff --git a/docshell/test/navigation/file_scrollRestoration.html b/docshell/test/navigation/file_scrollRestoration.html new file mode 100644 index 0000000000..90044894e4 --- /dev/null +++ b/docshell/test/navigation/file_scrollRestoration.html @@ -0,0 +1,153 @@ +<html> + <head> + <script> + var oldHistoryObject = null; + + function test(event) { + if (!opener.scrollRestorationTest) { + opener.scrollRestorationTest = 0; + } + ++opener.scrollRestorationTest; + + switch (opener.scrollRestorationTest) { + case 1: { + opener.is(event.persisted, false, "Shouldn't have persisted session history entry."); + opener.ok(history.scrollRestoration, "History object has scrollRestoration property."); + opener.is(history.scrollRestoration, "auto", "history.scrollRestoration's default value should be 'auto'."); + history.scrollRestoration = "foobar"; + opener.is(history.scrollRestoration, "auto", "Invalid enum value should not change the value of an attribute."); + history.scrollRestoration = "manual"; + opener.is(history.scrollRestoration, "manual", "Valid enum value should change the value of an attribute."); + history.scrollRestoration = "auto"; + opener.is(history.scrollRestoration, "auto", "Valid enum value should change the value of an attribute."); + document.getElementById("bottom").scrollIntoView(); + window.location.reload(false); + break; + } + case 2: { + opener.is(event.persisted, false, "Shouldn't have persisted session history entry."); + opener.isnot(Math.round(window.scrollY), 0, "Should have restored scrolling."); + opener.is(history.scrollRestoration, "auto", "Should have the same scrollRestoration as before reload."); + history.scrollRestoration = "manual"; + window.onunload = function() {}; // Disable bfcache. + window.location.reload(false); + break; + } + case 3: { + opener.is(event.persisted, false, "Shouldn't have persisted session history entry."); + opener.is(window.scrollY, 0, "Should not have restored scrolling."); + opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload."); + document.getElementById("bottom").scrollIntoView(); + window.onunload = null; // Should get bfcache behavior. + window.opener.case3WaitForBlank(); + window.location.href = "about:blank"; + break; + } + case 4: { + opener.is(event.persisted, true, "Should have persisted session history entry."); + opener.isnot(Math.round(window.scrollY), 0, "Should have kept the old scroll position."); + opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload."); + window.scrollTo(0, 0); + window.location.hash = "hash"; + requestAnimationFrame(test); + break; + } + case 5: { + opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled to #hash."); + opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation."); + window.onunload = function() { + opener.setTimeout("is(SpecialPowers.wrap(testWindow).history.scrollRestoration, 'auto'); SpecialPowers.wrap(testWindow).history.back();", 250); + }; // Disable bfcache. + window.location.href = "about:blank"; + break; + } + case 6: { + opener.is(event.persisted, false, "Shouldn't have persisted session history entry."); + opener.is(window.scrollY, 0, "Shouldn't have kept the old scroll position."); + opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation."); + history.scrollRestoration = "auto"; + document.getElementById("bottom").scrollIntoView(); + history.pushState({ state: "state1" }, "state1"); + history.pushState({ state: "state2" }, "state2"); + window.scrollTo(0, 0); + history.back(); + setTimeout(test); + break; + } + case 7: { + opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled back to the state1's position"); + opener.is(history.state.state, "state1", "Unexpected state."); + + history.scrollRestoration = "manual"; + document.getElementById("bottom").scrollIntoView(); + history.pushState({ state: "state3" }, "state3"); + history.pushState({ state: "state4" }, "state4"); + window.scrollTo(0, 0); + history.back(); + setTimeout(test); + break; + } + case 8: { + opener.is(Math.round(window.scrollY), 0, "Shouldn't have scrolled back to the state3's position"); + opener.is(history.state.state, "state3", "Unexpected state."); + + history.pushState({ state: "state5" }, "state5"); + history.scrollRestoration = "auto"; + document.getElementById("bottom").scrollIntoView(); + opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled to 'bottom'."); + history.back(); + setTimeout(test); + break; + } + case 9: { + window.scrollTo(0, 0); + history.forward(); + setTimeout(test); + break; + } + case 10: { + opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled back to the state5's position"); + + var ifr = document.createElement("iframe"); + ifr.src = "data:text/html,"; + document.body.appendChild(ifr); + ifr.onload = test; + break; + } + case 11: { + oldHistoryObject = SpecialPowers.wrap(event.target).contentWindow.history; + event.target.src = "about:blank"; + break; + } + case 12: { + try { + oldHistoryObject.scrollRestoration; + opener.ok(false, "Should have thrown an exception."); + } catch (ex) { + opener.isnot(ex, null, "Did get an exception"); + } + try { + oldHistoryObject.scrollRestoration = "auto"; + opener.ok(false, "Should have thrown an exception."); + } catch (ex) { + opener.isnot(ex, null, "Did get an exception"); + } + opener.finishTest(); + break; + } + } + } + + window.addEventListener("pageshow", + function(e) { + setTimeout(test, 0, e); + }); + </script> + </head> + <body> + <div style="border: 1px solid black; height: 5000px;"> + </div> + <div id="bottom">Hello world</div> + <a href="#hash" name="hash">hash</a> + </body> +</html> diff --git a/docshell/test/navigation/file_shiftReload_and_pushState.html b/docshell/test/navigation/file_shiftReload_and_pushState.html new file mode 100644 index 0000000000..7882143c83 --- /dev/null +++ b/docshell/test/navigation/file_shiftReload_and_pushState.html @@ -0,0 +1,28 @@ +<html> + <head> + <script> + function test() { + try { + frames[0].history.pushState({}, "state", "?pushed"); + } catch (ex) { + opener.ok(false, "history.pushState shouldn't throw"); + } + + if (!opener.shiftReloadPushStateFirstRound) { + opener.shiftReloadPushStateFirstRound = true; + window.location.reload(true); + } else { + opener.ok(true, "Did run history.push"); + opener.finishTest(); + } + } + + window.addEventListener("load", function() { setTimeout(test, 0); }); + </script> + </head> + <body> + <iframe src="frame0.html"></iframe> + <script> + </script> + </body> +</html> diff --git a/docshell/test/navigation/file_static_and_dynamic_1.html b/docshell/test/navigation/file_static_and_dynamic_1.html new file mode 100644 index 0000000000..e66216c41e --- /dev/null +++ b/docshell/test/navigation/file_static_and_dynamic_1.html @@ -0,0 +1,31 @@ +<html> + <head> + <script> + function test() { + var ifr = document.createElement("iframe"); + ifr.src = "frame0.html"; + document.getElementById("dynamic").appendChild(ifr); + var staticFrame = document.getElementById("staticframe"); + staticFrame.onload = window.location = "goback.html"; + staticFrame.contentWindow.location = "frame1.html"; + } + + function start() { + if (++opener.testCount == 1) { + test(); + } else { + var staticFrame = document.getElementById("staticframe"); + opener.ok(String(staticFrame.contentWindow.location).includes(staticFrame.src), + "Wrong document loaded!"); + opener.finishTest(); + } + } + </script> + </head> + <body onload="setTimeout('start()', 0)"> + <h5>Dynamic</h5> + <div id="dynamic"></div> + <h5>Static</h5> + <div id="static"><iframe id="staticframe" src="frame0.html"></iframe></div> + </body> +</html> diff --git a/docshell/test/navigation/file_tell_opener.html b/docshell/test/navigation/file_tell_opener.html new file mode 100644 index 0000000000..bd45c275e6 --- /dev/null +++ b/docshell/test/navigation/file_tell_opener.html @@ -0,0 +1,8 @@ +<html> + <body onload="bodyLoaded()">Frame 1</body> + <script> + function bodyLoaded() { + opener.postMessage("body-loaded", "*"); + } + </script> +</html> diff --git a/docshell/test/navigation/file_triggeringprincipal_frame_1.html b/docshell/test/navigation/file_triggeringprincipal_frame_1.html new file mode 100644 index 0000000000..528437f892 --- /dev/null +++ b/docshell/test/navigation/file_triggeringprincipal_frame_1.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> +<head><meta charset="utf-8"></head> +<body> +<b>Frame 1</b><br/> +<a href="#"" id="testlink" onclick="parent.frames[1].frames[0].location='http://test2.mochi.test:8888/tests/docshell/test/navigation/file_triggeringprincipal_subframe_nav.html'">click me</a> + +<script type="application/javascript"> + // make sure to set document.domain to the same domain as the subframe + window.onload = function() { + document.domain = "mochi.test"; + }; + window.addEventListener("message", receiveMessage); + function receiveMessage(event) { + // make sure to get the right start command, otherwise + // let the parent know and fail the test + if (event.data.start !== "startTest") { + window.removeEventListener("message", receiveMessage); + window.parent.postMessage({triggeringPrincipalURI: "false"}, "*"); + } + // click the link to navigate the subframe + document.getElementById("testlink").click(); + } +</script> + +</body> +</html> diff --git a/docshell/test/navigation/file_triggeringprincipal_frame_2.html b/docshell/test/navigation/file_triggeringprincipal_frame_2.html new file mode 100644 index 0000000000..ef7cdfc178 --- /dev/null +++ b/docshell/test/navigation/file_triggeringprincipal_frame_2.html @@ -0,0 +1,8 @@ +<!DOCTYPE HTML> +<html> +<head><meta charset="utf-8"></head> +<body> +<b>Frame 2</b><br/> +<iframe src="http://test2.mochi.test:8888/tests/docshell/test/navigation/file_triggeringprincipal_subframe.html"></iframe> +</body> +</html> diff --git a/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a.html b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a.html new file mode 100644 index 0000000000..75b2933c1b --- /dev/null +++ b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<body> +Frame A +</body> +</html> diff --git a/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html new file mode 100644 index 0000000000..0479f5e1e5 --- /dev/null +++ b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<body> +Frame A navigated by Frame B +</body> +</html> diff --git a/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_b.html b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_b.html new file mode 100644 index 0000000000..e5d40b267a --- /dev/null +++ b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_b.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<body> +Frame B navigating Frame A + +<script type="text/javascript"> + +window.open("file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html", "framea"); + +</script> + +</body> +</html> + + diff --git a/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_base.html b/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_base.html new file mode 100644 index 0000000000..caa6b275b9 --- /dev/null +++ b/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_base.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<body> +base test frame +</body> +</html> diff --git a/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_nav.html b/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_nav.html new file mode 100644 index 0000000000..f4a4d0e631 --- /dev/null +++ b/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_nav.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<body> +navigated by window.open() +</body> +</html> diff --git a/docshell/test/navigation/file_triggeringprincipal_subframe.html b/docshell/test/navigation/file_triggeringprincipal_subframe.html new file mode 100644 index 0000000000..ba6b6dc09a --- /dev/null +++ b/docshell/test/navigation/file_triggeringprincipal_subframe.html @@ -0,0 +1,15 @@ +<!DOCTYPE HTML> +<html> +<head><meta charset='utf-8'></head> +<body> +<b>Sub Frame 2</b><br/> +<script type='application/javascript'> + // make sure to set document.domain to same domain as frame 1 + window.onload = function() { + document.domain = "mochi.test"; + // let Frame 1 know that we are ready to run the test + window.parent.parent.frames[0].postMessage({start: "startTest"}, "*"); + }; +</script> +</body> +</html> diff --git a/docshell/test/navigation/file_triggeringprincipal_subframe_nav.html b/docshell/test/navigation/file_triggeringprincipal_subframe_nav.html new file mode 100644 index 0000000000..582181c00d --- /dev/null +++ b/docshell/test/navigation/file_triggeringprincipal_subframe_nav.html @@ -0,0 +1,21 @@ +<!DOCTYPE HTML> +<html> +<head><meta charset="utf-8"></head> +<body onload="checkResults()"> +<b>Sub Frame 2 Navigated</b><br/> + +<script type='application/javascript'> + function checkResults() { + // query the uri of the loadingPrincipal and the TriggeringPrincipal and pass + // that information on to the parent for verification. + var channel = SpecialPowers.wrap(window).docShell.currentDocumentChannel; + var triggeringPrincipalURI = channel.loadInfo.triggeringPrincipal.asciiSpec; + var loadingPrincipalURI = channel.loadInfo.loadingPrincipal.asciiSpec; + var referrerURI = document.referrer; + window.parent.parent.postMessage({triggeringPrincipalURI, + loadingPrincipalURI, + referrerURI}, "*"); + } +</script> +</body> +</html> diff --git a/docshell/test/navigation/file_triggeringprincipal_subframe_same_origin_nav.html b/docshell/test/navigation/file_triggeringprincipal_subframe_same_origin_nav.html new file mode 100644 index 0000000000..c84e216ae8 --- /dev/null +++ b/docshell/test/navigation/file_triggeringprincipal_subframe_same_origin_nav.html @@ -0,0 +1,20 @@ +<!DOCTYPE HTML> +<html> +<head><meta charset="utf-8"></head> +<body onload="checkResults()"> +<b>SubFrame Same-Origin Navigated</b><br/> + +<script type='application/javascript'> + function checkResults() { + // query the uri of the loadingPrincipal and the TriggeringPrincipal and pass + // that information on to the parent for verification. + var channel = SpecialPowers.wrap(window).docShell.currentDocumentChannel; + var triggeringPrincipalURI = channel.loadInfo.triggeringPrincipal.asciiSpec; + var loadingPrincipalURI = channel.loadInfo.loadingPrincipal.asciiSpec; + + window.parent.postMessage({triggeringPrincipalURI, + loadingPrincipalURI}, "*"); + } +</script> +</body> +</html> diff --git a/docshell/test/navigation/file_triggeringprincipal_window_open.html b/docshell/test/navigation/file_triggeringprincipal_window_open.html new file mode 100644 index 0000000000..d0644a4d5c --- /dev/null +++ b/docshell/test/navigation/file_triggeringprincipal_window_open.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<body> +http +</body> +</html> diff --git a/docshell/test/navigation/frame0.html b/docshell/test/navigation/frame0.html new file mode 100644 index 0000000000..93d1c9c822 --- /dev/null +++ b/docshell/test/navigation/frame0.html @@ -0,0 +1,3 @@ +<html> + <body>Frame 0</body> +</html> diff --git a/docshell/test/navigation/frame1.html b/docshell/test/navigation/frame1.html new file mode 100644 index 0000000000..4d06c09d1c --- /dev/null +++ b/docshell/test/navigation/frame1.html @@ -0,0 +1,3 @@ +<html> + <body>Frame 1</body> +</html> diff --git a/docshell/test/navigation/frame2.html b/docshell/test/navigation/frame2.html new file mode 100644 index 0000000000..7a3b5e0b9b --- /dev/null +++ b/docshell/test/navigation/frame2.html @@ -0,0 +1,3 @@ +<html> + <body>Frame 2</body> +</html> diff --git a/docshell/test/navigation/frame3.html b/docshell/test/navigation/frame3.html new file mode 100644 index 0000000000..fd24293873 --- /dev/null +++ b/docshell/test/navigation/frame3.html @@ -0,0 +1,3 @@ +<html> + <body>Frame 3</body> +</html> diff --git a/docshell/test/navigation/goback.html b/docshell/test/navigation/goback.html new file mode 100644 index 0000000000..ce2968374e --- /dev/null +++ b/docshell/test/navigation/goback.html @@ -0,0 +1,5 @@ +<html> + <body onload="setTimeout('window.history.go(-1)', 1000);"> + window.history.go(-1); + </body> +</html> diff --git a/docshell/test/navigation/iframe.html b/docshell/test/navigation/iframe.html new file mode 100644 index 0000000000..4685fea7b7 --- /dev/null +++ b/docshell/test/navigation/iframe.html @@ -0,0 +1,8 @@ +<html> +<body> +<script> +var src = window.location.hash.substring(1); +document.write('<iframe src="' + src + '"></iframe>'); +</script> +</body> +</html> diff --git a/docshell/test/navigation/iframe_static.html b/docshell/test/navigation/iframe_static.html new file mode 100644 index 0000000000..1bdd1437c1 --- /dev/null +++ b/docshell/test/navigation/iframe_static.html @@ -0,0 +1,8 @@ +<html> + <body> + Nested Frame + <div id="frameContainer"> + <iframe id="staticFrame" src="frame0.html"></iframe> + </div> + </body> +</html> diff --git a/docshell/test/navigation/mochitest.ini b/docshell/test/navigation/mochitest.ini new file mode 100644 index 0000000000..9e5be6a625 --- /dev/null +++ b/docshell/test/navigation/mochitest.ini @@ -0,0 +1,122 @@ +[DEFAULT] +support-files = + NavigationUtils.js + navigation_target_url.html + navigation_target_popup_url.html + blank.html + file_bug386782_contenteditable.html + file_bug386782_designmode.html + redbox_bug430723.html + bluebox_bug430723.html + file_bug462076_1.html + file_bug462076_2.html + file_bug462076_3.html + file_bug508537_1.html + file_bug534178.html + file_document_write_1.html + file_fragment_handling_during_load.html + file_fragment_handling_during_load_frame1.html + file_fragment_handling_during_load_frame2.sjs + file_nested_frames.html + file_nested_frames_innerframe.html + file_scrollRestoration.html + file_shiftReload_and_pushState.html + file_static_and_dynamic_1.html + frame0.html + frame1.html + frame2.html + frame3.html + goback.html + iframe.html + iframe_static.html + navigate.html + open.html + parent.html + file_tell_opener.html + file_triggeringprincipal_frame_1.html + file_triggeringprincipal_frame_2.html + file_triggeringprincipal_subframe.html + file_triggeringprincipal_subframe_nav.html + file_triggeringprincipal_subframe_same_origin_nav.html + file_triggeringprincipal_window_open.html + file_triggeringprincipal_parent_iframe_window_open_base.html + file_triggeringprincipal_parent_iframe_window_open_nav.html + file_triggeringprincipal_iframe_iframe_window_open_frame_a.html + file_triggeringprincipal_iframe_iframe_window_open_frame_b.html + file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html + file_load_history_entry_page_with_one_link.html + file_load_history_entry_page_with_two_links.html + file_bug1300461.html + file_bug1300461_redirect.html + file_bug1300461_redirect.html^headers^ + file_bug1300461_back.html + file_contentpolicy_block_window.html + file_bug1326251.html + file_bug1326251_evict_cache.html + file_bug1364364-1.html + file_bug1364364-2.html + file_bug1375833.html + file_bug1375833-frame1.html + file_bug1375833-frame2.html + test_bug145971.html + file_bug1609475.html + file_bug1379762-1.html + +[test_aboutblank_change_process.html] +[test_bug13871.html] +[test_bug270414.html] +[test_bug278916.html] +[test_bug279495.html] +[test_bug344861.html] +skip-if = toolkit == "android" || toolkit == "windows" # disabled on Windows because of bug 1234520 +[test_bug386782.html] +[test_bug430624.html] +[test_bug430723.html] +skip-if = (!debug && (os == 'mac' || os == 'win')) # Bug 874423 +[test_bug1364364.html] +skip-if = (os == "android") || fission # Bug 1560378, bug 1666449 +[test_bug1375833.html] +[test_bug1536471.html] +support-files = file_bug1536471.html +[test_child.html] +[test_docshell_gotoindex.html] +support-files = file_docshell_gotoindex.html +[test_grandchild.html] +[test_load_history_entry.html] +[test_not-opener.html] +[test_opener.html] +[test_popup-navigates-children.html] +[test_reserved.html] +skip-if = + (debug && e10s) # bug 1263213 + (os == 'mac' && os_version == '10.14') # Bug 1548821 +[test_performance_navigation.html] +skip-if = fission # bug 1666602 +[test_sessionhistory.html] +skip-if = verify && (os == 'mac') && debug && webrender # Hit MOZ_CRASH(Shutdown too long, probably frozen, causing a crash.) bug 1677545 +[test_dynamic_frame_forward_back.html] +[test_sessionhistory_document_write.html] +[test_session_history_entry_cleanup.html] +[test_fragment_handling_during_load.html] +[test_nested_frames.html] +[test_shiftReload_and_pushState.html] +[test_scrollRestoration.html] +skip-if = sessionHistoryInParent # It relies on the bfcache +[test_bug1609475.html] +[test_bug1300461.html] +fail-if = sessionHistoryInParent +[test_bug1326251.html] +skip-if = toolkit == 'android' || sessionHistoryInParent # It relies on the bfcache +[test_bug1379762.html] +skip-if = sessionHistoryInParent # It relies on the bfcache +[test_static_and_dynamic.html] +skip-if = true # This was disabled for a few years now anyway, bug 1677544 +[test_sibling-matching-parent.html] +[test_sibling-off-domain.html] +[test_triggeringprincipal_frame_nav.html] +[test_triggeringprincipal_frame_same_origin_nav.html] +[test_triggeringprincipal_window_open.html] +[test_triggeringprincipal_parent_iframe_window_open.html] +[test_triggeringprincipal_iframe_iframe_window_open.html] +[test_contentpolicy_block_window.html] +[test_rate_limit_location_change.html] diff --git a/docshell/test/navigation/navigate.html b/docshell/test/navigation/navigate.html new file mode 100644 index 0000000000..fe191f1d93 --- /dev/null +++ b/docshell/test/navigation/navigate.html @@ -0,0 +1,37 @@ +<html> +<head> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <script src="NavigationUtils.js"></script> + <script> + async function navigate() { + var args = window.location.hash.substring(1).split(","); + var target = args[0]; + var mechanism = args[1]; + + switch (mechanism) { + case "location": + // eslint-disable-next-line no-eval + navigateByLocation(eval(target)); + break; + case "open": + navigateByOpen(target); + break; + case "form": + navigateByForm(target); + break; + case "hyperlink": + await navigateByHyperlink(target); + break; + } + } + </script> +</head> +<body onload="navigate();"> +<script> +var args = window.location.hash.substring(1).split(","); +var target = args[0]; +var mechanism = args[1]; +document.write("target=" + target + " mechanism=" + mechanism); +</script> +</body> +</html> diff --git a/docshell/test/navigation/navigation_target_popup_url.html b/docshell/test/navigation/navigation_target_popup_url.html new file mode 100644 index 0000000000..cfe6de009d --- /dev/null +++ b/docshell/test/navigation/navigation_target_popup_url.html @@ -0,0 +1 @@ +<html><body>This is a popup</body></html> diff --git a/docshell/test/navigation/navigation_target_url.html b/docshell/test/navigation/navigation_target_url.html new file mode 100644 index 0000000000..a485e8133f --- /dev/null +++ b/docshell/test/navigation/navigation_target_url.html @@ -0,0 +1 @@ +<html><body>This frame was navigated.</body></html> diff --git a/docshell/test/navigation/open.html b/docshell/test/navigation/open.html new file mode 100644 index 0000000000..97eb9b76e1 --- /dev/null +++ b/docshell/test/navigation/open.html @@ -0,0 +1,9 @@ +<html> +<body> +<script> +var target = window.location.hash.substring(1); +document.write("target=" + target); +window.open("navigation_target_popup_url.html", target, "width=10,height=10"); +</script> +</body> +</html> diff --git a/docshell/test/navigation/parent.html b/docshell/test/navigation/parent.html new file mode 100644 index 0000000000..74722b8bdf --- /dev/null +++ b/docshell/test/navigation/parent.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<body> +This document contains a frame. +<div><iframe src="blank.html"></iframe></div> +<script> +frames[0].name = window.name + "_child0"; +window.onload = function() { + opener.postMessage("ready", "*"); +}; +</script> +</body> +</html> + diff --git a/docshell/test/navigation/redbox_bug430723.html b/docshell/test/navigation/redbox_bug430723.html new file mode 100644 index 0000000000..c2d1f98092 --- /dev/null +++ b/docshell/test/navigation/redbox_bug430723.html @@ -0,0 +1,6 @@ +<html><head> +<script> window.addEventListener("pageshow", function() { opener.nextTest(); }); </script> +</head><body> +<div style="position:absolute; left:0px; top:0px; width:50%; height:150%; background-color:red"> +<p>This is a very tall red box.</p> +</div></body></html> diff --git a/docshell/test/navigation/test_aboutblank_change_process.html b/docshell/test/navigation/test_aboutblank_change_process.html new file mode 100644 index 0000000000..bde79bd21c --- /dev/null +++ b/docshell/test/navigation/test_aboutblank_change_process.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<head> + <meta charset="utf-8"> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css" /> +</head> +<script> +// Open a window and navigate it from http://example.net to about:blank +// With fission, we should switch processes and about:blank should load in +// the same process as this test page. +// This is a crash test. +add_task(async function test_aboutblank_change_process() { + let exampleLoaded = new Promise(resolve => { + function onMessage(event) { + if (event.data == "body-loaded") { + window.removeEventListener("message", onMessage); + resolve(); + } + } + window.addEventListener("message", onMessage); + }); + let win = window.open(); + win.location = "http://example.net/tests/docshell/test/navigation/file_tell_opener.html"; + await exampleLoaded; + + win.location = "about:blank"; + + // A crash happens somewhere here when about:blank does not go via + // DocumentChannel with fission enabled + + // Wait for about:blank to load in this process + await SimpleTest.promiseWaitForCondition(() => { + try { + return win.location.href == "about:blank"; + } catch (e) { + // While the `win` still has example.net page loaded, `win.location` will + // be a cross origin object and querying win.location.href will throw a + // SecurityError. Return false as long as this is the case. + return false; + } + }) + + ok(true, "We did not crash"); + win.close(); +}); +</script> diff --git a/docshell/test/navigation/test_bug1300461.html b/docshell/test/navigation/test_bug1300461.html new file mode 100644 index 0000000000..b0b7d70c9e --- /dev/null +++ b/docshell/test/navigation/test_bug1300461.html @@ -0,0 +1,75 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug 1300461</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1300461">Mozilla Bug 1300461</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + + let chromeScript = null; + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + chromeScript = SpecialPowers.loadChromeScript(() => { + const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); + + function doSend(message, fn) { + try { + // eslint-disable-next-line no-undef + sendAsyncMessage(message, {success: true, value: fn()}); + } catch(_) { + // eslint-disable-next-line no-undef + sendAsyncMessage(message, {success: false}); + } + } + + // eslint-disable-next-line no-undef + addMessageListener("requestedIndex", () => { + doSend("requestedIndex", () => { + let win = Services.wm.getMostRecentWindow("navigator:browser"); + let shistory = win.gBrowser.selectedBrowser.browsingContext.sessionHistory; + return shistory.requestedIndex; + }) + }); + }); + } + + async function getSHRequestedIndex() { + let p = chromeScript.promiseOneMessage("requestedIndex"); + chromeScript.sendAsyncMessage("requestedIndex"); + let result = await p; + ok(result.success, "Got requested index from parent"); + return result.value; + } + + var testCount = 0; + + SimpleTest.waitForExplicitFinish(); + + var testWindow; + function runTest() { + testWindow = window.open("file_bug1300461.html", "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } + + function finishTest() { + if (chromeScript) { + chromeScript.destroy(); + } + testWindow.close(); + SimpleTest.finish(); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_bug1326251.html b/docshell/test/navigation/test_bug1326251.html new file mode 100644 index 0000000000..a04431a2c4 --- /dev/null +++ b/docshell/test/navigation/test_bug1326251.html @@ -0,0 +1,74 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug 1326251</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1326251">Mozilla Bug 1326251</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + + let chromeScript = null; + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + chromeScript = SpecialPowers.loadChromeScript(() => { + const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); + + function doSend(message, fn) { + try { + // eslint-disable-next-line no-undef + sendAsyncMessage(message, {success: true, value: fn()}); + } catch(_) { + // eslint-disable-next-line no-undef + sendAsyncMessage(message, {success: false}); + } + } + + // eslint-disable-next-line no-undef + addMessageListener("evictAllContentViewers", _ => { + doSend("evictAllContentViewers", () => { + let win = Services.wm.getMostRecentWindow("navigator:browser"); + let shistory = win.gBrowser.selectedBrowser.browsingContext.sessionHistory; + return shistory.evictAllContentViewers(); + }) + }); + }); + } + + async function evictAllContentViewers() { + let p = chromeScript.promiseOneMessage("evictAllContentViewers"); + chromeScript.sendAsyncMessage("evictAllContentViewers"); + let result = await p; + ok(result.success, "Called evictAllContentViewers from parent"); + } + + var testCount = 0; + + SimpleTest.waitForExplicitFinish(); + + var testWindow; + function runTest() { + testWindow = window.open("file_bug1326251.html", "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } + + function finishTest() { + if (chromeScript) { + chromeScript.destroy(); + } + testWindow.close(); + SimpleTest.finish(); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_bug1364364.html b/docshell/test/navigation/test_bug1364364.html new file mode 100644 index 0000000000..b237e5339f --- /dev/null +++ b/docshell/test/navigation/test_bug1364364.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1364364 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1364364</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1364364 **/ + let testWin, testDoc; + async function test() { + SimpleTest.waitForExplicitFinish(); + testWin = window.open("file_bug1364364-1.html"); + await waitForLoad(testWin); + testDoc = testWin.document; + + // file_bug1364364-1.html will load a few dynamic iframes and then navigate + // top browsing context to file_bug1364364-2.html, which will postMessage + // back. + } + + function waitForLoad(win) { + return new Promise(r => win.addEventListener("load", r, { once: true})); + } + + window.addEventListener("message", async function(msg) { + if (msg.data == "navigation-done") { + is(testWin.history.length, 6, "check history.length"); + + // Modify a document in bfcache should cause the cache being dropped tho + // RemoveFromBFCacheAsync. + testDoc.querySelector("#content").textContent = "modified"; + await new Promise(r => setTimeout(r, 0)); + + is(testWin.history.length, 2, "check history.length after bfcache dropped"); + testWin.close(); + SimpleTest.finish(); + } + }); + + </script> +</head> +<body onload="test();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1364364">Mozilla Bug 1364364</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_bug1375833.html b/docshell/test/navigation/test_bug1375833.html new file mode 100644 index 0000000000..49b6646ee3 --- /dev/null +++ b/docshell/test/navigation/test_bug1375833.html @@ -0,0 +1,136 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1375833 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1375833</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + SimpleTest.waitForExplicitFinish(); + + /** + * Test for Bug 1375833. It tests for 2 things in a normal reload - + * 1. Static frame history should not be dropped. + * 2. In a reload, docshell would parse the reloaded root document and + * genearate new child docshells, and then use the child offset + */ + + let testWin = window.open("file_bug1375833.html"); + let count = 0; + let webNav, shistory; + let frameDocShellId; + let chromeScript = null; + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + chromeScript = SpecialPowers.loadChromeScript(() => { + const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); + + function doSend(message, fn) { + try { + // eslint-disable-next-line no-undef + sendAsyncMessage(message, {success: true, value: fn()}); + } catch(_) { + // eslint-disable-next-line no-undef + sendAsyncMessage(message, {success: false}); + } + } + + // eslint-disable-next-line no-undef + addMessageListener("test1", index => { + doSend("test1", () => { + let win = Services.wm.getMostRecentWindow("navigator:browser"); + let sessionHistory = win.gBrowser.selectedBrowser.browsingContext.sessionHistory; + let entry = sessionHistory.getEntryAtIndex(sessionHistory.index); + let frameEntry = entry.GetChildAt(0); + return String(frameEntry.docshellID); + }) + }); + }); + } + + window.addEventListener("message", async e => { + switch (count++) { + case 0: + ok(e.data.endsWith("file_bug1375833-frame2.html"), "check location"); + + webNav = SpecialPowers.wrap(testWin) + .docShell + .QueryInterface(SpecialPowers.Ci.nsIWebNavigation); + shistory = webNav.sessionHistory; + is(shistory.count, 2, "check history length"); + is(shistory.index, 1, "check history index"); + + frameDocShellId = String(getFrameDocShell().historyID); + ok(frameDocShellId, "sanity check for docshell ID"); + + testWin.location.reload(); + break; + case 1: + ok(e.data.endsWith("file_bug1375833-frame2.html"), "check location"); + is(shistory.count, 4, "check history length"); + is(shistory.index, 3, "check history index"); + + let newFrameDocShellId = String(getFrameDocShell().historyID); + ok(newFrameDocShellId, "sanity check for docshell ID"); + is(newFrameDocShellId, frameDocShellId, "check docshell ID remains after reload"); + + if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) { + let entry = shistory.legacySHistory.getEntryAtIndex(shistory.index); + let frameEntry = entry.GetChildAt(0); + is(String(frameEntry.docshellID), frameDocShellId, "check newly added shentry uses the same docshell ID"); + } else { + let p = chromeScript.promiseOneMessage("test1"); + chromeScript.sendAsyncMessage("test1", shistory.index); + let result = await p; + ok(result.success, "legacySHistory worked around ok"); + is(result.value, frameDocShellId, "check newly added shentry uses the same docshell ID"); + } + + webNav.goBack(); + break; + case 2: + ok(e.data.endsWith("file_bug1375833-frame1.html"), "check location"); + is(shistory.count, 4, "check history length"); + is(shistory.index, 2, "check history index"); + + webNav.goBack(); + break; + case 3: + ok(e.data.endsWith("file_bug1375833-frame2.html"), "check location"); + is(shistory.count, 4, "check history length"); + is(shistory.index, 1, "check history index"); + + webNav.goBack(); + break; + case 4: + ok(e.data.endsWith("file_bug1375833-frame1.html"), "check location"); + is(shistory.count, 4, "check history length"); + is(shistory.index, 0, "check history index"); + + if (chromeScript) { + chromeScript.destroy(); + } + testWin.close(); + SimpleTest.finish(); + } + }); + + function getFrameDocShell() { + return SpecialPowers.wrap(testWin.window[0]).docShell; + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1375833">Mozilla Bug 1375833</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_bug1379762.html b/docshell/test/navigation/test_bug1379762.html new file mode 100644 index 0000000000..03afb20cad --- /dev/null +++ b/docshell/test/navigation/test_bug1379762.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug 1379762</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1379762">Mozilla Bug 1379762</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + /** + * - This page opens new window + * - new window sends 'init' msg + * - onload() in new window sends 'increment_loadCount' msg + * - onpageshow() in new window sends 'increment_testCount' msg + * - This page sends 'forward_back' msg + * - onpageshow() in new window 'increment_testCount' + * - This page sends 'finish_test' msg + * - onpageshow() in new window sends 'finished' msg + */ + var testCount = 0; // Used by the test files. + var loadCount = 0; + var goneBack = false; + var bc = new BroadcastChannel("bug1379762"); + bc.onmessage = (messageEvent) => { + let message = messageEvent.data; + if (message == "init") { + is(testCount, 0, "new window should only be loaded once; otherwise the loadCount variable makes no sense"); + } else if (message == "increment_loadCount") { + loadCount++; + is(loadCount, 1, "Should only get one load") + } else if (message == 'increment_testCount') { + testCount++; + if (testCount == 1) { + bc.postMessage("forward_back"); + goneBack = true; + } else if (testCount == 2) { + ok(goneBack, "We had a chance to navigate backwards and forwards in the new window to test BFCache"); + bc.postMessage("finish_test"); + } + } else if (message == "finished") { + bc.close(); + SimpleTest.finish(); + } + } + + SimpleTest.waitForExplicitFinish(); + + function runTest() { + window.open("file_bug1379762-1.html", "", "width=360,height=480,noopener"); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_bug13871.html b/docshell/test/navigation/test_bug13871.html new file mode 100644 index 0000000000..c3f54776aa --- /dev/null +++ b/docshell/test/navigation/test_bug13871.html @@ -0,0 +1,81 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> + <style type="text/css"> + iframe { width: 90%; height: 50px; } + </style> +<script> +async function runTest() { + navigateByLocation(window0.frames[0]); + navigateByOpen("window1_child0"); + navigateByForm("window2_child0"); + await navigateByHyperlink("window3_child0"); + + await waitForFinishedFrames(4); + + isInaccessible(window0.frames[0], "Should not be able to navigate off-domain frame by setting location."); + isInaccessible(window1.frames[0], "Should not be able to navigate off-domain frame by calling window.open."); + isInaccessible(window2.frames[0], "Should not be able to navigate off-domain frame by submitting form."); + isInaccessible(window3.frames[0], "Should not be able to navigate off-domain frame by targeted hyperlink."); + + window0.close(); + window1.close(); + window2.close(); + window3.close(); + + await cleanupWindows(); + SimpleTest.finish(); +} + +// Because our open()'d windows are cross-origin, we can't wait for onload. +// We instead wait for a postMessage from parent.html. +var windows = new Map(); +addEventListener("message", function windowLoaded(evt) { + // Because window.open spins the event loop in order to open new windows, + // we might receive the "ready" message before we call waitForLoad. + // In that case, windows won't contain evt.source and we just note that the + // window is ready. Otherwise, windows contains the "resolve" function for + // that window's promise and we just have to call it. + if (windows.has(evt.source)) { + windows.get(evt.source)(); + } else { + windows.set(evt.source, true); + } +}); + +var window0 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window0", "width=10,height=10"); +var window1 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window1", "width=10,height=10"); +var window2 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window2", "width=10,height=10"); +var window3 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window3", "width=10,height=10"); + +function waitForLoad(w) { + return new Promise(function(resolve, reject) { + // If we already got the "ready" message, resolve immediately. + if (windows.has(w)) { + resolve(); + } else { + windows.set(w, resolve); + } + }); +} + +Promise.all([ waitForLoad(window0), + waitForLoad(window1), + waitForLoad(window2), + waitForLoad(window3) ]) + .then(runTest); +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=13871">Mozilla Bug 13871</a> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_bug145971.html b/docshell/test/navigation/test_bug145971.html new file mode 100644 index 0000000000..ffad27a9c3 --- /dev/null +++ b/docshell/test/navigation/test_bug145971.html @@ -0,0 +1,29 @@ +<html> + <head> + <script> + let pass = false; + let initialLoad = false; + var bc = new BroadcastChannel("bug145971"); + function checkNavigationTypeEquals2() { + if (performance.navigation.type == 2) { + pass = true; + } + testDone(); + } + + function testDone() { + bc.postMessage({result: pass}); + bc.close(); + window.close(); + } + + function test() { + window.onpageshow = checkNavigationTypeEquals2; + window.location.href = 'goback.html'; + } + </script> + </head> + <body onload="setTimeout(test, 0);"> + Testing bug 145971. + </body> +</html> diff --git a/docshell/test/navigation/test_bug1536471.html b/docshell/test/navigation/test_bug1536471.html new file mode 100644 index 0000000000..f37aedba21 --- /dev/null +++ b/docshell/test/navigation/test_bug1536471.html @@ -0,0 +1,75 @@ + +<!DOCTYPE HTML> +<html> + <!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=1536471 + --> +<head> + <title>Test for Bug 1536471</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="application/javascript"> + + let testWin; + async function test() { + // Open a new tab and load a document with an iframe inside + testWin = window.open("file_bug1536471.html"); + await waitForLoad(); + var iframe = testWin.document.getElementById("staticFrame"); + is(testWin.history.length, 1, "Checking the number of session history entries when there is only one iframe"); + + // Navigate the iframe to different pages + await loadUriInFrame(iframe, "frame1.html"); + is(testWin.history.length, 2, "Checking the number of session history entries after having navigated a single iframe 1 time"); + await loadUriInFrame(iframe, "frame2.html"); + is(testWin.history.length, 3, "Checking the number of session history entries after having navigated a single iframe 2 times"); + await loadUriInFrame(iframe, "frame3.html"); + is(testWin.history.length, 4, "Checking the number of session history entries after having navigated a single iframe 3 times"); + + // Reload the top document + testWin.location.reload(true); + await waitForLoad(); + is(testWin.history.length, 1, "Checking the number of session history entries after reloading the top document"); + + testWin.close(); + SimpleTest.finish(); + } + + async function waitForLoad() { + await new Promise(resolve => { + window.bodyOnLoad = function() { + setTimeout(resolve, 0); + window.bodyOnLoad = undefined; + }; + }); + } + + async function iframeOnload(frame) { + return new Promise(resolve => { + frame.addEventListener("load", () => { + setTimeout(resolve, 0); + }, {once: true}); + }); + } + + async function loadUriInFrame(frame, uri) { + let onloadPromise = iframeOnload(frame); + frame.src = uri; + await onloadPromise; + } + </script> +</head> + +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1536471">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +<body onload="test()"> +</body> +</html> + diff --git a/docshell/test/navigation/test_bug1609475.html b/docshell/test/navigation/test_bug1609475.html new file mode 100644 index 0000000000..4dbe7d17d6 --- /dev/null +++ b/docshell/test/navigation/test_bug1609475.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug 1609475</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1609475">Mozilla Bug 1609475</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + + var testWindow; + function runTest() { + testWindow = window.open("file_bug1609475.html", "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } + + function finishTest() { + testWindow.close(); + SimpleTest.finish(); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_bug270414.html b/docshell/test/navigation/test_bug270414.html new file mode 100644 index 0000000000..317eabb54e --- /dev/null +++ b/docshell/test/navigation/test_bug270414.html @@ -0,0 +1,95 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> + <style type="text/css"> + iframe { width: 90%; height: 50px; } + </style> +<script> +/* eslint-disable no-useless-concat */ +/* global window0:true, window1:true, window2:true, window3:true */ +var headerHTML = "<html><head>" + + "<script src='/tests/SimpleTest/EventUtils.js'><\/script>" + + "<script src='NavigationUtils.js'><\/script>" + + "</head><body>"; +var footerHTML = "</body></html>"; + +function testChild0() { + if (!window.window0) { + window0 = window.open("", "window0", "width=10,height=10"); + window0.document.open(); + window0.document.write(headerHTML); + window0.document.write("<script>navigateByLocation(opener.frames[0])<\/script>"); + window0.document.write(footerHTML); + window0.document.close(); + } +} + +function testChild1() { + if (!window.window1) { + window1 = window.open("", "window1", "width=10,height=10"); + window1.document.open(); + window1.document.write(headerHTML); + window1.document.write("<script>navigateByOpen('child1');<\/script>"); + window1.document.write(footerHTML); + window1.document.close(); + } +} + +function testChild2() { + if (!window.window2) { + window2 = window.open("", "window2", "width=10,height=10"); + window2.document.open(); + window2.document.write(headerHTML); + window2.document.write("<script>navigateByForm('child2');<\/script>"); + window2.document.write(footerHTML); + window2.document.close(); + } +} + +function testChild3() { + if (!window.window3) { + window3 = window.open("", "window3", "width=10,height=10"); + window3.document.open(); + window3.document.write(headerHTML); + window3.document.write("<script>(async function() { await navigateByHyperlink('child3'); })();<\/script>"); + window3.document.write(footerHTML); + window3.document.close(); + } +} + +add_task(async function() { + await waitForFinishedFrames(4); + + await isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location."); + await isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open."); + await isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form."); + await isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink."); + + window0.close(); + window1.close(); + window2.close(); + window3.close(); + + await cleanupWindows(); +}); + +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=270414">Mozilla Bug 270414</a> +<div id="frames"> +<iframe onload="testChild0();" name="child0" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe onload="testChild1();" name="child1" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe onload="testChild2();" name="child2" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe onload="testChild3();" name="child3" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +</div> +<pre id="test"> +<script type="text/javascript"> +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_bug278916.html b/docshell/test/navigation/test_bug278916.html new file mode 100644 index 0000000000..9e2335721e --- /dev/null +++ b/docshell/test/navigation/test_bug278916.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> +<script> +window.onload = async function() { + document.getElementById("link0").href = target_url; + sendMouseEvent({type: "click"}, "link0"); + + await waitForFinishedFrames(1); + + var array_of_frames = await getFramesByName("window0"); + is(array_of_frames.length, 1, "Should only open one window using a fancy hyperlink."); + + for (var i = 0; i < array_of_frames.length; ++i) + array_of_frames[i].close(); + + await cleanupWindows(); + SimpleTest.finish(); +}; +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=278916">Mozilla Bug 278916</a> +<div id="links"> +<a id="link0" target="window0" onclick="window.open('', 'window0', 'width=10,height=10');">This is a fancy hyperlink</a> +</div> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_bug279495.html b/docshell/test/navigation/test_bug279495.html new file mode 100644 index 0000000000..fdbdbf6b9f --- /dev/null +++ b/docshell/test/navigation/test_bug279495.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> +<script> +window.onload = async function() { + document.getElementById("link0").href = target_url; + document.getElementById("link1").href = target_url; + + sendMouseEvent({type: "click"}, "link0"); + sendMouseEvent({type: "click"}, "link1"); + + await waitForFinishedFrames(2); + await countAndClose("window0", 1); + await countAndClose("window1", 1); + + await cleanupWindows(); + SimpleTest.finish(); +}; + +async function countAndClose(name, expected_count) { + var array_of_frames = await getFramesByName(name); + is(array_of_frames.length, expected_count, + "Should only open " + expected_count + + " window(s) with name " + name + " using a fancy hyperlink."); +} +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=279495">Mozilla Bug 279495</a> +<div id="links"> +<a id="link0" target="window0" onclick="window.open('blank.html', 'window0', 'width=10,height=10');">This is a fancy hyperlink</a> +<a id="link1" target="window1" onclick="window.open('http://test1.example.org:80/tests/docshell/test/navigation/blank.html', 'window1', 'width=10,height=10');">This is a fancy hyperlink</a> +</div> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_bug344861.html b/docshell/test/navigation/test_bug344861.html new file mode 100644 index 0000000000..76967b7b17 --- /dev/null +++ b/docshell/test/navigation/test_bug344861.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=344861 +--> +<head> + <title>Test for Bug 344861</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=344861">Mozilla Bug 344861</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 344861 **/ +SimpleTest.waitForExplicitFinish(); + +var newwindow = window.open("/", "testwindow", "width=200,height=200"); +newwindow.onload = function() { + is(newwindow.innerHeight, 200, "window.open has correct height dimensions"); + is(newwindow.innerWidth, 200, "window.open has correct width dimensions"); + SimpleTest.finish(); + newwindow.close(); +}; +</script> +</pre> +</body> +</html> + + diff --git a/docshell/test/navigation/test_bug386782.html b/docshell/test/navigation/test_bug386782.html new file mode 100644 index 0000000000..daa2ced74b --- /dev/null +++ b/docshell/test/navigation/test_bug386782.html @@ -0,0 +1,132 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=386782 +--> +<head> + <title>Test for Bug 386782</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script> + + // This tests if we can load a document whose root is in designMode, + // edit it, navigate to a new page, navigate back, still edit, and still + // undo/redo. Note that this is different from the case where the + // designMode document is in a frame inside the window, as this means + // the editable region is not in the root docshell (a less complicated case). + + var gTests = [ + { + // <html><body><p>designModeDocument</p></body></html> + url: "file_bug386782_designmode.html", + name: "designModeNavigate", + onload(doc) { doc.designMode = "on"; }, + expectedBodyBeforeEdit: "<p>designModeDocument</p>", + expectedBodyAfterEdit: "<p>EDITED designModeDocument</p>", + expectedBodyAfterSecondEdit: "<p>EDITED TWICE designModeDocument</p>", + }, + { + // <html><body contentEditable="true"><p>contentEditable</p></body></html> + url: "file_bug386782_contenteditable.html", + name: "contentEditableNavigate", + expectedBodyBeforeEdit: "<p>contentEditable</p>", + expectedBodyAfterEdit: "EDITED <br><p>contentEditable</p>", + expectedBodyAfterSecondEdit: "EDITED TWICE <br><p>contentEditable</p>", + }, + ]; + + var gTestNum = -1; + var gTest = null; + + window.onload = goNext; + + function goNext() { + gTestNum++; + if (gTestNum >= gTests.length) { + SimpleTest.finish(); + return; + } + gTest = gTests[gTestNum]; + gTest.window = window.open(gTest.url, gTest.name, "width=500,height=500"); + window.onmessage = function(e) { + is(e.data.persisted, false, "Initial load cannot be persisted"); + window.onmessage = null; + if ("onload" in gTest) { + gTest.onload(gTest.window.document); + } + SimpleTest.waitForFocus(beginTest, gTest.window); + }; + } + + function beginTest() { + gTest.window.document.body.focus(); + + // WARNING: If the following test fails, give the setTimeout() in the onload() + // a bit longer; the doc hasn't had enough time to setup its editor. + is(gTest.window.document.body.innerHTML, gTest.expectedBodyBeforeEdit, "Is doc setup yet"); + sendString("EDITED ", gTest.window); + is(gTest.window.document.body.innerHTML, gTest.expectedBodyAfterEdit, "Editing failed."); + + gTest.window.location = "about:blank"; + let cond = () => gTest.window.location.href == "about:blank"; + SimpleTest.waitForCondition(cond, () => { + SimpleTest.waitForFocus(goBack, gTest.window, true); + }, "about:blank never loaded"); + } + + function goBack() { + window.onmessage = function(e) { + window.onmessage = null; + // Skip the test if the page is not loaded from the bf-cache when going back. + if (e.data.persisted) { + checkStillEditable(); + } else { + gTest.window.close(); + goNext(); + } + }; + gTest.window.history.back(); + } + + function checkStillEditable() { + // Check that the contents are correct. + is(gTest.window.document.body.innerHTML, gTest.expectedBodyAfterEdit, "Edited contents still correct?"); + + // Check that we can undo/redo and the contents are correct. + gTest.window.document.execCommand("undo", false, null); + is(gTest.window.document.body.innerHTML, gTest.expectedBodyBeforeEdit, "Can we undo?"); + + gTest.window.document.execCommand("redo", false, null); + is(gTest.window.document.body.innerHTML, gTest.expectedBodyAfterEdit, "Can we redo?"); + + // Check that we can still edit the page. + gTest.window.document.body.focus(); + sendString("TWICE ", gTest.window); + is(gTest.window.document.body.innerHTML, gTest.expectedBodyAfterSecondEdit, "Can we still edit?"); + + gTest.window.close(); + goNext(); + } + + </script> + +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=386782">Mozilla Bug 386782</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 386782 **/ + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_bug430624.html b/docshell/test/navigation/test_bug430624.html new file mode 100644 index 0000000000..fbdc5d2677 --- /dev/null +++ b/docshell/test/navigation/test_bug430624.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=430624 +--> +<head> + <title>Test for Bug 430624</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script src="/tests/SimpleTest/EventUtils.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=430624">Mozilla Bug 430624</a> +<p id="display"></p> + + + +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 430624 **/ + +function onLoad() { + window.frames[0].frameElement.onload = onReload; + // eslint-disable-next-line no-self-assign + window.frames[0].frameElement.srcdoc = window.frames[0].frameElement.srcdoc; +} + +function onReload() { + var iframe = window.frames[0].frameElement; + SimpleTest.waitForFocus(doTest, iframe.contentWindow); + iframe.contentDocument.body.focus(); +} + +function doTest() { + var bodyElement = window.frames[0].frameElement.contentDocument.body; + bodyElement.focus(); + sendString("Still ", window.frames[0].frameElement.contentWindow); + + is(bodyElement.innerHTML, "Still contentEditable", "Check we're contentEditable after reload"); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> + +<iframe onload="onLoad()" srcdoc="<body contenteditable>contentEditable</body>"></iframe> + +</body> +</html> + diff --git a/docshell/test/navigation/test_bug430723.html b/docshell/test/navigation/test_bug430723.html new file mode 100644 index 0000000000..c2ba4b41c3 --- /dev/null +++ b/docshell/test/navigation/test_bug430723.html @@ -0,0 +1,124 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=430723 +--> +<head> + <title>Test for Bug 430723</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=430723">Mozilla Bug 430723</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +// <![CDATA[ + +/** Test for Bug 430723 **/ + +var BASE_URI = "http://mochi.test:8888/tests/docshell/test/navigation/"; +var gTallRedBoxURI = BASE_URI + "redbox_bug430723.html"; +var gTallBlueBoxURI = BASE_URI + "bluebox_bug430723.html"; + +window.onload = runTest; + +var testWindow; +var testNum = 0; + +var smoothScrollPref = "general.smoothScroll"; +function runTest() { + SpecialPowers.pushPrefEnv({"set": [[smoothScrollPref, false]]}, function() { + testWindow = window.open(gTallRedBoxURI, "testWindow", "width=300,height=300,location=yes,scrollbars=yes"); + }); +} + +var nextTest = function() { + testNum++; + switch (testNum) { + case 1: setTimeout(step1, 0); break; + case 2: setTimeout(step2, 0); break; + case 3: setTimeout(step3, 0); break; + } +}; + +var step1 = function() { + window.is(String(testWindow.location), gTallRedBoxURI, "Ensure red page loaded."); + + // Navigate down and up. + is(testWindow.document.body.scrollTop, 0, + "Page1: Ensure the scrollpane is at the top before we start scrolling."); + testWindow.addEventListener("scroll", function() { + isnot(testWindow.document.body.scrollTop, 0, + "Page1: Ensure we can scroll down."); + SimpleTest.executeSoon(step1_2); + }, {capture: true, once: true}); + sendKey("DOWN", testWindow); + + function step1_2() { + testWindow.addEventListener("scroll", function() { + is(testWindow.document.body.scrollTop, 0, + "Page1: Ensure we can scroll up, back to the top."); + + // Nav to blue box page. This should fire step2. + testWindow.location = gTallBlueBoxURI; + }, {capture: true, once: true}); + sendKey("UP", testWindow); + } +}; + + +var step2 = function() { + window.is(String(testWindow.location), gTallBlueBoxURI, "Ensure blue page loaded."); + + // Scroll around a bit. + is(testWindow.document.body.scrollTop, 0, + "Page2: Ensure the scrollpane is at the top before we start scrolling."); + + var scrollTest = function() { + if (++count < 2) { + SimpleTest.executeSoon(function() { sendKey("DOWN", testWindow); }); + } else { + testWindow.removeEventListener("scroll", scrollTest, true); + + isnot(testWindow.document.body.scrollTop, 0, + "Page2: Ensure we could scroll."); + + // Navigate backwards. This should fire step3. + testWindow.history.back(); + } + }; + + var count = 0; + testWindow.addEventListener("scroll", scrollTest, true); + sendKey("DOWN", testWindow); +}; + +var step3 = function() { + window.is(String(testWindow.location), gTallRedBoxURI, + "Ensure red page restored from history."); + + // Check we can still scroll with the keys. + is(testWindow.document.body.scrollTop, 0, + "Page1Again: Ensure scroll pane at top before we scroll."); + testWindow.addEventListener("scroll", function() { + isnot(testWindow.document.body.scrollTop, 0, + "Page2Again: Ensure we can still scroll."); + + testWindow.close(); + window.SimpleTest.finish(); + }, {capture: true, once: true}); + sendKey("DOWN", testWindow); +}; + +SimpleTest.waitForExplicitFinish(); + +// ]]> +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_child.html b/docshell/test/navigation/test_child.html new file mode 100644 index 0000000000..7b621b4b78 --- /dev/null +++ b/docshell/test/navigation/test_child.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> + <style type="text/css"> + iframe { width: 90%; height: 50px; } + </style> +<script> +if (!navigator.platform.startsWith("Win")) { + SimpleTest.expectAssertions(0, 1); +} + +window.onload = async function() { + navigateByLocation(frames[0]); + navigateByOpen("child1"); + navigateByForm("child2"); + await navigateByHyperlink("child3"); + + await waitForFinishedFrames(4); + await isNavigated(frames[0], "Should be able to navigate off-domain child by setting location."); + await isNavigated(frames[1], "Should be able to navigate off-domain child by calling window.open."); + await isNavigated(frames[2], "Should be able to navigate off-domain child by submitting form."); + await isNavigated(frames[3], "Should be able to navigate off-domain child by targeted hyperlink."); + + await cleanupWindows(); + SimpleTest.finish(); +}; +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a> +<div id="frames"> +<iframe name="child0" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe name="child1" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe name="child2" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe name="child3" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +</div> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_contentpolicy_block_window.html b/docshell/test/navigation/test_contentpolicy_block_window.html new file mode 100644 index 0000000000..b7f463a57e --- /dev/null +++ b/docshell/test/navigation/test_contentpolicy_block_window.html @@ -0,0 +1,102 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1329288 +--> +<head> + <title>Test for Bug 1329288</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1329288">Mozilla Bug 1329288</a> + + +<!-- have a testlink which we can use for the test to open a new window --> +<a href="http://test1.example.org/tests/docshell/test/navigation/file_contentpolicy_block_window.html" + target="_blank" + id="testlink">This is a link</a> + +<script class="testbody" type="text/javascript"> +/* + * Description of the test: + * The test tries to open a new window and makes sure that a registered contentPolicy + * gets called with the right (a non null) 'context' for the TYPE_DOCUMENT load. + */ + +// Services.jsm is disabled as ChromeUtils appears to be out of scope +/* eslint-disable mozilla/use-services */ + +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; + +var categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager); +var componentManager = SpecialPowers.wrap(SpecialPowers.Components).manager + .QueryInterface(Ci.nsIComponentRegistrar); + +// Content policy / factory implementation for the test +var policyID = SpecialPowers.wrap(SpecialPowers.Components).ID("{b80e19d0-878f-d41b-2654-194714a4115c}"); +var policyName = "@mozilla.org/testpolicy;1"; +var policy = { + // nsISupports implementation + // eslint-disable-next-line mozilla/use-chromeutils-generateqi + QueryInterface(iid) { + iid = SpecialPowers.wrap(iid); + if (iid.equals(Ci.nsISupports) || + iid.equals(Ci.nsIFactory) || + iid.equals(Ci.nsIContentPolicy)) + return this; + throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE; + }, + + // nsIFactory implementation + createInstance(outer, iid) { + return this.QueryInterface(iid); + }, + + // nsIContentPolicy implementation + shouldLoad(contentLocation, loadInfo, mimeTypeGuess) { + let contentType = loadInfo.externalContentPolicyType; + let context = loadInfo.loadingContext; + + if (SpecialPowers.wrap(contentLocation).spec !== document.getElementById("testlink").href) { + // not the URI we are looking for, allow the load + return Ci.nsIContentPolicy.ACCEPT; + } + + is(contentType, Ci.nsIContentPolicy.TYPE_DOCUMENT, + "needs to be type document load"); + ok(context, "context is not allowed to be null"); + ok(context.name.endsWith("test_contentpolicy_block_window.html"), + "context should be the current window"); + + // remove the policy and finish test. + categoryManager.deleteCategoryEntry("content-policy", policyName, false); + + setTimeout(function() { + // Component must be unregistered delayed, otherwise other content + // policy will not be removed from the category correctly + componentManager.unregisterFactory(policyID, policy); + }, 0); + + SimpleTest.finish(); + return Ci.nsIContentPolicy.REJECT_REQUEST; + }, + + shouldProcess(contentLocation, loadInfo, mimeTypeGuess) { + return Ci.nsIContentPolicy.ACCEPT; + }, +}; + +policy = SpecialPowers.wrapCallbackObject(policy); +componentManager.registerFactory(policyID, "Test content policy", policyName, policy); +categoryManager.addCategoryEntry("content-policy", policyName, policyName, false, true); + +SimpleTest.waitForExplicitFinish(); + +// now everything is set up, let's start the test +document.getElementById("testlink").click(); + +</script> +</body> +</html> diff --git a/docshell/test/navigation/test_docshell_gotoindex.html b/docshell/test/navigation/test_docshell_gotoindex.html new file mode 100644 index 0000000000..992c9c9dbe --- /dev/null +++ b/docshell/test/navigation/test_docshell_gotoindex.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Bug 1684310</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + SimpleTest.waitForExplicitFinish(); + function test() { + /* + * This test is for nsIWebNavigation.gotoIndex. + * + * The test + * - opens a new window + * - loads a page there + * - loads another page + * - navigates to some fragments in the page + * - goes back to one of the fragments + * - tries to go back to the initial page. + */ + window.open("file_docshell_gotoindex.html"); + } + </script> +</head> +<body onload="test()"> +<p id="display"></p> +</body> +</html> diff --git a/docshell/test/navigation/test_dynamic_frame_forward_back.html b/docshell/test/navigation/test_dynamic_frame_forward_back.html new file mode 100644 index 0000000000..f3a349e09a --- /dev/null +++ b/docshell/test/navigation/test_dynamic_frame_forward_back.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug 508537</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=508537">Mozilla Bug 508537</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + + var testWindow; + function runTest() { + testWindow = window.open("file_bug508537_1.html", "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } + + function finishTest() { + testWindow.close(); + SimpleTest.finish(); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_fragment_handling_during_load.html b/docshell/test/navigation/test_fragment_handling_during_load.html new file mode 100644 index 0000000000..9c082c2ecf --- /dev/null +++ b/docshell/test/navigation/test_fragment_handling_during_load.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for fragment navigation during load</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=978408">Mozilla Bug 978408</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + + var testWindow; + function runTest() { + testWindow = window.open("file_fragment_handling_during_load.html", "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } + + function finishTest() { + testWindow.close(); + SimpleTest.finish(); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_grandchild.html b/docshell/test/navigation/test_grandchild.html new file mode 100644 index 0000000000..1f78ca974c --- /dev/null +++ b/docshell/test/navigation/test_grandchild.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> + <style type="text/css"> + iframe { width: 90%; height: 200px; } + </style> +<script> +if (!navigator.platform.startsWith("Win")) { + SimpleTest.expectAssertions(0, 1); +} + +window.onload = async function() { + navigateByLocation(frames[0].frames[0]); + navigateByOpen("child1_child0"); + navigateByForm("child2_child0"); + await navigateByHyperlink("child3_child0"); + + await waitForFinishedFrames(4); + await isNavigated(frames[0].frames[0], "Should be able to navigate off-domain grandchild by setting location."); + await isNavigated(frames[1].frames[0], "Should be able to navigate off-domain grandchild by calling window.open."); + await isNavigated(frames[2].frames[0], "Should be able to navigate off-domain grandchild by submitting form."); + await isNavigated(frames[3].frames[0], "Should be able to navigate off-domain grandchild by targeted hyperlink."); + + await cleanupWindows(); + SimpleTest.finish(); +}; +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a> +<div id="frames"> +<iframe name="child0" src="http://test1.example.org:80/tests/docshell/test/navigation/parent.html"></iframe> +<iframe name="child1" src="http://test1.example.org:80/tests/docshell/test/navigation/parent.html"></iframe> +<iframe name="child2" src="http://test1.example.org:80/tests/docshell/test/navigation/parent.html"></iframe> +<iframe name="child3" src="http://test1.example.org:80/tests/docshell/test/navigation/parent.html"></iframe> +</div> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_load_history_entry.html b/docshell/test/navigation/test_load_history_entry.html new file mode 100644 index 0000000000..8ca3fcb913 --- /dev/null +++ b/docshell/test/navigation/test_load_history_entry.html @@ -0,0 +1,196 @@ + +<!DOCTYPE HTML> +<html> +<head> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="application/javascript" src="/tests/SimpleTest/SpecialPowers.js"></script> + <script type="application/javascript"> + /* + * Perform the following steps. + * 1) Go to file_load_history_entry_page_with_two_links.html, which contains two links, 'link1' and 'link2' + * 2) Click on 'link1' to be taken to file_load_history_entry_page_with_two_links.html#1 + * 3) Click on 'link2' to be taken to file_load_history_entry_page_with_two_links.html#2 + * 4) Go to file_load_history_entry_page_with_one_link.html + * 5) Push state to go to file_load_history_entry_page_with_one_link.html#1 + * + * After each step + * - Check the number of session history entries + * - Reload the document and do the above again + * - Navigate back and check the correct history index + * - Navigate forward and check the correct history index and location + */ + async function test() { + let testWin; + var promise; + var previousLocation; + var numSHEntries = 0; + + // Step 1. Open a new tab and load a document with two links inside + // Now we are at file_load_history_entry_page_with_two_links.html + numSHEntries++; + promise = waitForLoad(); + testWin = window.open("file_load_history_entry_page_with_two_links.html"); + await promise; + + let shistory = SpecialPowers.wrap(testWin) + .docShell + .QueryInterface(SpecialPowers.Ci.nsIWebNavigation) + .sessionHistory; + + // Step 2. Navigate the document by clicking on the 1st link + // Now we are at file_load_history_entry_page_with_two_links.html#1 + numSHEntries++; + previousLocation = testWin.location.href; + await clickLink(testWin, "link1"); + await doAfterEachTest(testWin, shistory, numSHEntries, previousLocation); + + // Step 3. Navigate the document by clicking the 2nd link + // Now we are file_load_history_entry_page_with_two_links.html#2 + numSHEntries++; + previousLocation = testWin.location.href; + await clickLink(testWin, "link2"); + await doAfterEachTest(testWin, shistory, numSHEntries, previousLocation); + + // Step 4. Navigate the document to a different page + // Now we are at file_load_history_entry_page_with_one_link.html + numSHEntries++; + previousLocation = testWin.location.href; + promise = waitForLoad(); + testWin.location = "file_load_history_entry_page_with_one_link.html"; + await promise; + await doAfterEachTest(testWin, shistory, numSHEntries, previousLocation, + true /* isCrossDocumentLoad */, false /* hashChangeExpected */); + + // Step 5. Push some state + // Now we are at file_load_history_entry_page_with_one_link.html#1 + numSHEntries++; + previousLocation = testWin.location.href; + testWin.history.pushState({foo: "bar"}, "", "#1"); + is(testWin.history.length, numSHEntries, "Session history's length is correct after pushing state"); + is(shistory.index, numSHEntries - 1 /* we haven't switched to new history entry yet*/, + "Session history's index is correct after pushing state"); + await doAfterEachTest(testWin, shistory, numSHEntries, previousLocation); + + // We are done with the test + testWin.close(); + SimpleTest.finish(); + } + + /* + * @prevLocation + * if undefined, it is because there is no page to go back to + * + * @isCrossDocumentLoad + * did we just open a different document + * @hashChangeExpected + * Would we get a hash change event if we navigated backwards and forwards in history? + * This is framed with respect to the previous step, e.g. in the previous step was the + * hash different from the location we have navigated to just before calling this function? + * When we navigate forwards or backwards, we need to wait for this event + * because clickLink() also waits for hashchange event and + * if this function gets called before clickLink(), sometimes hashchange + * events from this function will leak to clickLink. + */ + async function doAfterEachTest(testWin, shistory, expectedNumSHEntries, prevLocation, + isCrossDocumentLoad = false, hashChangeExpected = true) { + var initialLocation = testWin.location.href; + var initialSHIndex = shistory.index; + var promise; + is(testWin.history.length, expectedNumSHEntries, "Session history's length is correct"); + + // Reload the document + promise = waitForLoad(); + testWin.location.reload(true); + await promise; + is(testWin.history.length, expectedNumSHEntries, "Session history's length is correct after reloading"); + + if (prevLocation == undefined) { + return; + } + + var hashChangePromise; + if (hashChangeExpected) { + hashChangePromise = new Promise(resolve => { + testWin.addEventListener("hashchange", resolve, {once: true}); + }); + } + // Navigate backwards + if (isCrossDocumentLoad) { + // Current page must have been a cross document load, so we just need to wait for + // document load to complete after we navigate the history back + // because popstate event will not be fired in this case + promise = waitForLoad(); + } else { + promise = waitForPopstate(testWin); + } + testWin.history.back(); + await promise; + if (hashChangeExpected) { + await hashChangePromise; + } + is(testWin.location.href, prevLocation, "Window location is correct after navigating back in history"); + is(shistory.index, initialSHIndex - 1, "Session history's index is correct after navigating back in history"); + + // Navigate forwards + if (isCrossDocumentLoad) { + promise = waitForLoad(); + } else { + promise = waitForPopstate(testWin); + } + if (hashChangeExpected) { + hashChangePromise = new Promise(resolve => { + testWin.addEventListener("hashchange", resolve, {once: true}); + }); + } + testWin.history.forward(); + await promise; + if (hashChangeExpected) { + await hashChangePromise; + } + is(testWin.location.href, initialLocation, "Window location is correct after navigating forward in history"); + is(shistory.index, initialSHIndex, "Session history's index is correct after navigating forward in history"); + } + + async function waitForLoad() { + return new Promise(resolve => { + window.bodyOnLoad = function() { + setTimeout(resolve, 0); + window.bodyOnLoad = undefined; + }; + }); + } + + async function waitForPopstate(win) { + return new Promise(resolve => { + win.addEventListener("popstate", (e) => { + setTimeout(resolve, 0); + }, {once: true}); + }); + } + + async function clickLink(win, id) { + var link = win.document.getElementById(id); + let clickPromise = new Promise(resolve => { + win.addEventListener("hashchange", resolve, {once: true}); + }); + link.click(); + await clickPromise; + } + + </script> +</head> + +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1539482">Bug 1539482</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +<body onload="test()"> +</body> +</html> + diff --git a/docshell/test/navigation/test_nested_frames.html b/docshell/test/navigation/test_nested_frames.html new file mode 100644 index 0000000000..c3b49e0e23 --- /dev/null +++ b/docshell/test/navigation/test_nested_frames.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug 1090918</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1090918">Mozilla Bug 1090918</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + + var testWindow; + function runTest() { + testWindow = window.open("file_nested_frames.html", "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } + + function finishTest() { + testWindow.close() + SimpleTest.finish(); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_not-opener.html b/docshell/test/navigation/test_not-opener.html new file mode 100644 index 0000000000..aa215e4052 --- /dev/null +++ b/docshell/test/navigation/test_not-opener.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> + <style type="text/css"> + iframe { width: 90%; height: 50px; } + </style> +<script> +if (!navigator.platform.startsWith("Win")) { + SimpleTest.expectAssertions(0, 1); +} + +window.onload = async function() { + // navigateByLocation(window0); // Don't have a handle to the window. + navigateByOpen("window1"); + navigateByForm("window2"); + await navigateByHyperlink("window3"); + + await waitForFinishedFrames(6); + + is((await getFramesByName("window1")).length, 2, "Should not be able to navigate popup's popup by calling window.open."); + is((await getFramesByName("window2")).length, 2, "Should not be able to navigate popup's popup by submitting form."); + is((await getFramesByName("window3")).length, 2, "Should not be able to navigate popup's popup by targeted hyperlink."); + + // opener0.close(); + opener1.close(); + opener2.close(); + opener3.close(); + + info("here") + await cleanupWindows(); + info("there") + SimpleTest.finish(); +}; + +// opener0 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window0", "_blank", "width=10,height=10"); +let opener1 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window1", "_blank", "width=10,height=10"); +let opener2 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window2", "_blank", "width=10,height=10"); +let opener3 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window3", "_blank", "width=10,height=10"); +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_opener.html b/docshell/test/navigation/test_opener.html new file mode 100644 index 0000000000..89f1c32187 --- /dev/null +++ b/docshell/test/navigation/test_opener.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> + <style type="text/css"> + iframe { width: 90%; height: 50px; } + </style> +<script> +if (navigator.platform.startsWith("Linux")) { + SimpleTest.expectAssertions(0, 1); +} + +window.onload = async function() { + navigateByLocation(window0); + navigateByOpen("window1"); + navigateByForm("window2"); + await navigateByHyperlink("window3"); + + await waitForFinishedFrames(4); + await isNavigated(window0, "Should be able to navigate popup by setting location."); + await isNavigated(window1, "Should be able to navigate popup by calling window.open."); + await isNavigated(window2, "Should be able to navigate popup by submitting form."); + await isNavigated(window3, "Should be able to navigate popup by targeted hyperlink."); + + window0.close(); + window1.close(); + window2.close(); + window3.close(); + + await cleanupWindows(); + + SimpleTest.finish(); +}; + +var window0 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/blank.html", "window0", "width=10,height=10"); +var window1 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/blank.html", "window1", "width=10,height=10"); +var window2 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/blank.html", "window2", "width=10,height=10"); +var window3 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/blank.html", "window3", "width=10,height=10"); +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_performance_navigation.html b/docshell/test/navigation/test_performance_navigation.html new file mode 100644 index 0000000000..55b4081a0d --- /dev/null +++ b/docshell/test/navigation/test_performance_navigation.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=145971 +--> +<head> + <title>Test for Bug 145971</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=145971">Mozilla Bug 145971</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +var testWindow; +var bc = new BroadcastChannel("bug145971"); +bc.onmessage = function(msgEvent) { + var result = msgEvent.data.result; + if (result == undefined) { + info("Got unexpected message from BroadcastChannel"); + return; + } + ok(result, "Bug 145971: Navigation type does not equal 2 when restoring document from session history."); + SimpleTest.finish(); +}; + +function runTest() { + window.open("test_bug145971.html", "", "width=360,height=480,noopener"); +} + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_popup-navigates-children.html b/docshell/test/navigation/test_popup-navigates-children.html new file mode 100644 index 0000000000..82d69e7982 --- /dev/null +++ b/docshell/test/navigation/test_popup-navigates-children.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> + <style type="text/css"> + iframe { width: 90%; height: 50px; } + </style> +<script> + +let window0 = null; +let window1 = null; +let window2 = null; +let window3 = null; + +function testChild0() { + if (!window.window0) + window0 = window.open("navigate.html#opener.frames[0],location", "window0", "width=10,height=10"); +} + +function testChild1() { + if (!window.window1) + window1 = window.open("navigate.html#child1,open", "window1", "width=10,height=10"); +} + +function testChild2() { + if (!window.window2) + window2 = window.open("navigate.html#child2,form", "window2", "width=10,height=10"); +} + +function testChild3() { + if (!window.window3) + window3 = window.open("navigate.html#child3,hyperlink", "window3", "width=10,height=10"); +} + +window.onload = async function() { + await waitForFinishedFrames(4); + await isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location."); + await isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open."); + await isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form."); + await isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink."); + + window0.close(); + window1.close(); + window2.close(); + window3.close(); + + await cleanupWindows(); + SimpleTest.finish(); +}; + +</script> +</head> +<body> +<div id="frames"> +<iframe onload="testChild0()" name="child0" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe onload="testChild1()" name="child1" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe onload="testChild2()" name="child2" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe onload="testChild3()" name="child3" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +</div> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_rate_limit_location_change.html b/docshell/test/navigation/test_rate_limit_location_change.html new file mode 100644 index 0000000000..3ca002a9c1 --- /dev/null +++ b/docshell/test/navigation/test_rate_limit_location_change.html @@ -0,0 +1,96 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1314912 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1314912</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1314912 **/ + + const RATE_LIMIT_COUNT = 90; + const RATE_LIMIT_TIME_SPAN = 3; + + async function setup() { + await SpecialPowers.pushPrefEnv({set: [ + ["dom.navigation.locationChangeRateLimit.count", RATE_LIMIT_COUNT], + ["dom.navigation.locationChangeRateLimit.timespan", RATE_LIMIT_TIME_SPAN]]}); + } + + let inc = 0; + + const rateLimitedFunctions = (win) => ({ + "history.replaceState": () => win.history.replaceState(null, "test", `${win.location.href}#${inc++}`), + "history.pushState": () => win.history.pushState(null, "test", `${win.location.href}#${inc++}`), + "history.back": () => win.history.back(), + "history.forward": () => win.history.forward(), + "history.go": () => win.history.go(-1), + "location.hash": () => win.location.hash = inc++, + "location.host": () => win.location.host = win.location.host + "", + "location.hostname": () => win.location.hostname = win.location.hostname + "", + "location.pathname": () => win.location.pathname = win.location.pathname + "", + "location.port": () => win.location.port = win.location.port + "", + "location.protocol": () => win.location.protocol = win.location.protocol + "", + "location.search": () => win.location.search = win.location.search + "", + }); + + async function test() { + await setup(); + + // Open new window and wait for it to load + let win = window.open("blank.html"); + await new Promise((resolve) => SimpleTest.waitForFocus(resolve, win)) + + // Execute the history and location functions + Object.entries(rateLimitedFunctions(win)).forEach(([name, fn]) => { + // Reset the rate limit for the next run. + info("Reset rate limit."); + SpecialPowers.wrap(win).browsingContext.resetLocationChangeRateLimit(); + + info(`Calling ${name} ${RATE_LIMIT_COUNT} times to reach the rate limit.`); + for(let i = 0; i< RATE_LIMIT_COUNT; i++) { + fn.call(this); + } + // Next calls should throw because we're above the rate limit + for(let i = 0; i < 5; i++) { + SimpleTest.doesThrow(() => fn.call(this), `Call #${RATE_LIMIT_COUNT + i + 1} to ${name} should throw.`); + } + }) + + // We didn't reset the rate limit after the last loop iteration above. + // Wait for the rate limit timer to expire. + SimpleTest.requestFlakyTimeout("Waiting to trigger rate limit reset."); + await new Promise((resolve) => setTimeout(resolve, 5000)); + + // Calls should be allowed again. + Object.entries(rateLimitedFunctions(win)).forEach(([name, fn]) => { + let didThrow = false; + try { + fn.call(this); + } catch(error) { + didThrow = true; + } + is(didThrow, false, `Call to ${name} must not throw.`) + }); + + // Cleanup + win.close(); + SpecialPowers.wrap(win).browsingContext.resetLocationChangeRateLimit(); + SimpleTest.finish(); + } + + </script> +</head> +<body onload="setTimeout(test, 0);"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1314912">Mozilla Bug 1314912</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_reserved.html b/docshell/test/navigation/test_reserved.html new file mode 100644 index 0000000000..0242f3941b --- /dev/null +++ b/docshell/test/navigation/test_reserved.html @@ -0,0 +1,92 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> + <style type="text/css"> + iframe { width: 90%; height: 200px; } + </style> +<script> +if (navigator.platform.startsWith("Mac")) { + SimpleTest.expectAssertions(0, 2); +} + +async function testTop() { + let window0 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#top,location", "_blank", "width=10,height=10"); + + await waitForFinishedFrames(1); + isInaccessible(window0, "Should be able to navigate off-domain top by setting location."); + window0.close(); + await cleanupWindows(); + + let window1 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_top,open", "_blank", "width=10,height=10"); + + await waitForFinishedFrames(1); + isInaccessible(window1, "Should be able to navigate off-domain top by calling window.open."); + window1.close(); + await cleanupWindows(); + + let window2 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_top,form", "_blank", "width=10,height=10"); + + await waitForFinishedFrames(1); + isInaccessible(window2, "Should be able to navigate off-domain top by submitting form."); + window2.close(); + await cleanupWindows(); + + let window3 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_top,hyperlink", "_blank", "width=10,height=10"); + + await waitForFinishedFrames(1); + isInaccessible(window3, "Should be able to navigate off-domain top by targeted hyperlink."); + window3.close(); + await cleanupWindows(); + + await testParent(); +} + +async function testParent() { + document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#parent,location"></iframe>'; + + await waitForFinishedFrames(1); + isAccessible(frames[0], "Should not be able to navigate off-domain parent by setting location."); + await cleanupWindows(); + + document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_parent,open"></iframe>'; + + await waitForFinishedFrames(1); + isAccessible(frames[0], "Should not be able to navigate off-domain parent by calling window.open."); + await cleanupWindows(); + + document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_parent,form"></iframe>'; + + await waitForFinishedFrames(1); + isAccessible(frames[0], "Should not be able to navigate off-domain parent by submitting form."); + await cleanupWindows(); + + document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_parent,hyperlink"></iframe>'; + + await waitForFinishedFrames(1); + isAccessible(frames[0], "Should not be able to navigate off-domain parent by targeted hyperlink."); + await cleanupWindows(); + + document.getElementById("frames").innerHTML = ""; + SimpleTest.finish(); +} + +window.onload = async function() { + await testTop(); +}; +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a> +<div id="frames"> +</div> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_scrollRestoration.html b/docshell/test/navigation/test_scrollRestoration.html new file mode 100644 index 0000000000..4b8d1b213c --- /dev/null +++ b/docshell/test/navigation/test_scrollRestoration.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug 1155730</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1155730">Mozilla Bug 1155730</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestFlakyTimeout("untriaged"); + + var testWindow; + function runTest() { + testWindow = window.open("file_scrollRestoration.html", "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } + + async function case3WaitForBlank() { + let loaded = SimpleTest.promiseWaitForCondition(() => { + return testWindow.location.href == "about:blank"; + }); + await loaded; + SpecialPowers.wrap(testWindow).history.back(); + } + + function finishTest() { + testWindow.close(); + SimpleTest.finish(); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_session_history_entry_cleanup.html b/docshell/test/navigation/test_session_history_entry_cleanup.html new file mode 100644 index 0000000000..a55de0d6c3 --- /dev/null +++ b/docshell/test/navigation/test_session_history_entry_cleanup.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug 534178</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=534178">Mozilla Bug 534178</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + + var testWindow; + function runTest() { + testWindow = window.open("file_bug534178.html", "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } + + function finishTest() { + testWindow.close(); + SimpleTest.finish(); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_sessionhistory.html b/docshell/test/navigation/test_sessionhistory.html new file mode 100644 index 0000000000..2254ec876b --- /dev/null +++ b/docshell/test/navigation/test_sessionhistory.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug 462076</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="nextTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=462076">Mozilla Bug 462076</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + var testFiles = + [ "file_bug462076_1.html", // Dynamic frames before onload + "file_bug462076_2.html", // Dynamic frames when handling onload + "file_bug462076_3.html", // Dynamic frames after onload + ]; + var testCount = 0; // Used by the test files. + + SimpleTest.waitForExplicitFinish(); + + var testWindow; + function nextTest_() { + if (testFiles.length) { + testCount = 0; + let nextFile = testFiles.shift(); + info("Running " + nextFile); + testWindow = window.open(nextFile, "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } else { + SimpleTest.finish(); + } + } + + function nextTest() { + setTimeout(nextTest_, 0); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_sessionhistory_document_write.html b/docshell/test/navigation/test_sessionhistory_document_write.html new file mode 100644 index 0000000000..2a48a8154e --- /dev/null +++ b/docshell/test/navigation/test_sessionhistory_document_write.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Session history + document.write</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + + var testWindow; + function runTest() { + testWindow = window.open("file_document_write_1.html", "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } + + function finishTest() { + testWindow.close(); + SimpleTest.finish(); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_shiftReload_and_pushState.html b/docshell/test/navigation/test_shiftReload_and_pushState.html new file mode 100644 index 0000000000..7525e2e21f --- /dev/null +++ b/docshell/test/navigation/test_shiftReload_and_pushState.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug 1003100</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1003100">Mozilla Bug 1003100</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + + var testWindow; + function runTest() { + testWindow = window.open("file_shiftReload_and_pushState.html", "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } + + function finishTest() { + testWindow.close(); + SimpleTest.finish(); + } + + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_sibling-matching-parent.html b/docshell/test/navigation/test_sibling-matching-parent.html new file mode 100644 index 0000000000..3c1bc768db --- /dev/null +++ b/docshell/test/navigation/test_sibling-matching-parent.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> + <style type="text/css"> + iframe { width: 90%; height: 50px; } + </style> +<script> +window.onload = async function() { + document.getElementById("active").innerHTML = + '<iframe src="navigate.html#parent.frames[0],location"></iframe>' + + '<iframe src="navigate.html#child1,open"></iframe>' + + '<iframe src="navigate.html#child2,form"></iframe>' + + '<iframe src="navigate.html#child3,hyperlink"></iframe>'; + + await waitForFinishedFrames(4); + + await isNavigated(frames[0], "Should be able to navigate sibling with on-domain parent by setting location."); + await isNavigated(frames[1], "Should be able to navigate sibling with on-domain parent by calling window.open."); + await isNavigated(frames[2], "Should be able to navigate sibling with on-domain parent by submitting form."); + await isNavigated(frames[3], "Should be able to navigate sibling with on-domain parent by targeted hyperlink."); + + await cleanupWindows(); + SimpleTest.finish(); +}; +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a> +<div id="frames"> +<iframe name="child0" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe name="child1" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe name="child2" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +<iframe name="child3" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe> +</div> +<div id="active"></div> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_sibling-off-domain.html b/docshell/test/navigation/test_sibling-off-domain.html new file mode 100644 index 0000000000..cd70d1ae91 --- /dev/null +++ b/docshell/test/navigation/test_sibling-off-domain.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> + <style type="text/css"> + iframe { width: 90%; height: 50px; } + </style> +<script> +window.onload = async function() { + document.getElementById("active").innerHTML = + '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#parent.frames[0],location"></iframe>' + + '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#child1,open"></iframe>' + + '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#child2,form"></iframe>' + + '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#child3,hyperlink"></iframe>'; + + await waitForFinishedFrames(4); + + isBlank(frames[0], "Should not be able to navigate off-domain sibling by setting location."); + isBlank(frames[1], "Should not be able to navigate off-domain sibling by calling window.open."); + isBlank(frames[2], "Should not be able to navigate off-domain sibling by submitting form."); + isBlank(frames[3], "Should not be able to navigate off-domain sibling by targeted hyperlink."); + + await cleanupWindows(); + SimpleTest.finish(); +}; +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a> +<div id="frames"> +<iframe name="child0" src="blank.html"></iframe> +<iframe name="child1" src="blank.html"></iframe> +<iframe name="child2" src="blank.html"></iframe> +<iframe name="child3" src="blank.html"></iframe> +</div> +<div id="active"></div> +<pre id="test"> +<script type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_static_and_dynamic.html b/docshell/test/navigation/test_static_and_dynamic.html new file mode 100644 index 0000000000..ff72a8188c --- /dev/null +++ b/docshell/test/navigation/test_static_and_dynamic.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for static and dynamic frames and forward-back </title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <script type="application/javascript"> + var testCount = 0; // Used by the test files. + + SimpleTest.waitForExplicitFinish(); + + var testWindow; + function runTest() { + testWindow = window.open("file_static_and_dynamic_1.html", "", "width=360,height=480"); + testWindow.onunload = function() { }; // to prevent bfcache + } + + function finishTest() { + testWindow.close(); + SimpleTest.finish(); + } + </script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_triggeringprincipal_frame_nav.html b/docshell/test/navigation/test_triggeringprincipal_frame_nav.html new file mode 100644 index 0000000000..a580995e11 --- /dev/null +++ b/docshell/test/navigation/test_triggeringprincipal_frame_nav.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Bug 1181370 - Test triggeringPrincipal for iframe navigations</title> + <!-- Including SimpleTest.js so we can use waitForExplicitFinish !--> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<iframe style="width:100%;" id="testframe1"></iframe> +<iframe style="width:100%;" id="testframe2"></iframe> + +<script class="testbody" type="text/javascript"> + +/* Description of the test: + * + * +------------------------------------+ + * | +----------+ +--------------+ | + * | | Frame 1 | | Frame 2 | | + * | +----------+ | | | + * | | +----------+ | | + * | | | Subframe | | | + * | | +----------+ | | + * | +--------------+ | + * +------------------------------------+ + * + * Frame1: test1.mochi.test + * Frame2: test2.mochi.test + * Subframe: test2.mochi.test + * + * (*) Frame1 and Subframe set their document.domain to mochi.test + * (*) Frame1 navigates the Subframe + * (*) TriggeringPrincipal for the Subframe navigation should be + * ==> test1.mochi.test + * (*) LoadingPrincipal for the Subframe navigation should be + * ==> test2.mochi.test + */ + +const BASEURL1 = "http://test1.mochi.test:8888/tests/docshell/test/navigation/"; +const BASEURL2 = "http://test2.mochi.test:8888/tests/docshell/test/navigation/"; +const TRIGGERINGPRINCIPALURI = BASEURL1 + "file_triggeringprincipal_frame_1.html"; +const LOADINGPRINCIPALURI = BASEURL2 + "file_triggeringprincipal_frame_2.html"; + +SimpleTest.waitForExplicitFinish(); + +window.addEventListener("message", receiveMessage); + +function receiveMessage(event) { + is(event.data.triggeringPrincipalURI, TRIGGERINGPRINCIPALURI, + "TriggeringPrincipal should be the navigating iframe (Frame 1)"); + is(event.data.loadingPrincipalURI, LOADINGPRINCIPALURI, + "LoadingPrincipal should be the enclosing iframe (Frame 2)"); + is(event.data.referrerURI, TRIGGERINGPRINCIPALURI, + "Referrer and TriggeringPrincipal should be identical (Frame 1)"); + + window.removeEventListener("message", receiveMessage); + SimpleTest.finish(); +} + +var frame1 = document.getElementById("testframe1"); +frame1.src = BASEURL1 + "file_triggeringprincipal_frame_1.html"; + +var frame2 = document.getElementById("testframe2"); +frame2.src = BASEURL2 + "file_triggeringprincipal_frame_2.html"; + +</script> +</body> +</html> diff --git a/docshell/test/navigation/test_triggeringprincipal_frame_same_origin_nav.html b/docshell/test/navigation/test_triggeringprincipal_frame_same_origin_nav.html new file mode 100644 index 0000000000..b9790cd0fa --- /dev/null +++ b/docshell/test/navigation/test_triggeringprincipal_frame_same_origin_nav.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Bug 1639195 - Test triggeringPrincipal for iframe same-origin navigations</title> + <!-- Including SimpleTest.js so we can use waitForExplicitFinish !--> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<iframe style="width:100%;" id="testframe" src="http://example.com/"></iframe> + +<script type="text/javascript"> +/* We load an third-party iframe which then gets navigated by the iframe's + * parent by calling iframe.setAttribute("src", same-origin url) later in the + * test. We then verify the TriggeringPrincipal and LoadingPrincipal of the + * navigated iframe. + * + * +------------------------------------------+ + * | | + * | +------------------+ | + * | | testframe | | + * | +------------------+ | + * | | + * | iframe.setAttribute("src", | + * | same-origin url) | + * | | + * +------------------------------------------+ + */ + +var testframe = document.getElementById("testframe"); + +window.addEventListener("message", receiveMessage); + +const TRIGGERING_PRINCIPAL_URI = + "http://mochi.test:8888/tests/docshell/test/navigation/test_triggeringprincipal_frame_same_origin_nav.html"; + +const LOADING_PRINCIPAL_URI = TRIGGERING_PRINCIPAL_URI; + +function receiveMessage(event) { + is(event.data.triggeringPrincipalURI.split("?")[0], TRIGGERING_PRINCIPAL_URI, + "TriggeringPrincipal should be the parent iframe"); + is(event.data.loadingPrincipalURI.split("?")[0], TRIGGERING_PRINCIPAL_URI, + "LoadingPrincipal should be the parent iframe"); + + window.removeEventListener("message", receiveMessage); + SimpleTest.finish(); +} + +function performNavigation() { + testframe.removeEventListener("load", performNavigation); + testframe.setAttribute("src", "http://example.com/tests/docshell/test/navigation/file_triggeringprincipal_subframe_same_origin_nav.html"); +} + +// start the test +SimpleTest.waitForExplicitFinish(); + +testframe.addEventListener("load", performNavigation); +</script> + +</body> +</html> diff --git a/docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html b/docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html new file mode 100644 index 0000000000..115c5f4462 --- /dev/null +++ b/docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html @@ -0,0 +1,87 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> +</head> +<body> + +<iframe name="framea" id="framea" src="file_triggeringprincipal_iframe_iframe_window_open_frame_a.html"></iframe> +<iframe name="frameb" id="frameb"></iframe> + +<script type="text/javascript"> + +/* We load an iframe (Frame A) which then gets navigated by another iframe (Frame B) + * by calling window.open("http://", "Frame A") later in the test. We then verify the + * TriggeringPrincipal and LoadingPrincipal of the navigated iframe (Frame A). + * + * +---------------------------------------+ + * | Parent | + * | | + * | +----------------------------+ | + * | | Frame A | | + * | | | | + * | | | | + * | +----------------------------+ | + * | | + * | +----------------------------+ | + * | | Frame B | | + * | | | | + * | | win.open("http://", "A") | | + * | +----------------------------+ | + * | | + * +---------------------------------------+ + * + * Sequence of the test: + * [1] load Frame A + * [2] load Frame B which navigates A + * [3] load navigated Frame A and check triggeringPrincipal and loadingPrincipal + */ + +const TRIGGERING_PRINCIPAL_URI = + "http://mochi.test:8888/tests/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_b.html"; + +const LOADING_PRINCIPAL_URI = + "http://mochi.test:8888/tests/docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html"; + +var frameA = document.getElementById("framea"); + +function checkResults() { + frameA.removeEventListener("load", checkResults); + + var channel = SpecialPowers.wrap(frameA.contentWindow).docShell.currentDocumentChannel; + var triggeringPrincipal = channel.loadInfo.triggeringPrincipal.asciiSpec; + var loadingPrincipal = channel.loadInfo.loadingPrincipal.asciiSpec; + + is(triggeringPrincipal, TRIGGERING_PRINCIPAL_URI, + "TriggeringPrincipal for targeted window.open() should be the iframe triggering the load"); + + is(frameA.contentDocument.referrer, TRIGGERING_PRINCIPAL_URI, + "Referrer for targeted window.open() should be the principal of the iframe triggering the load"); + + is(loadingPrincipal.split("?")[0], LOADING_PRINCIPAL_URI, + "LoadingPrincipal for targeted window.open() should be the containing document"); + + SimpleTest.finish(); +} + +function performNavigation() { + frameA.removeEventListener("load", performNavigation); + frameA.addEventListener("load", checkResults); + + // load Frame B which then navigates Frame A + var frameB = document.getElementById("frameb"); + frameB.src = "file_triggeringprincipal_iframe_iframe_window_open_frame_b.html"; +} + +// start the test +SimpleTest.waitForExplicitFinish(); + +frameA.addEventListener("load", performNavigation); + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html b/docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html new file mode 100644 index 0000000000..1611ebf479 --- /dev/null +++ b/docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html @@ -0,0 +1,70 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> +</head> +<body> + +<iframe name="testframe" id="testframe" src="file_triggeringprincipal_iframe_iframe_window_open_base.html"></iframe> + +<script type="text/javascript"> + +/* We load an iframe which then gets navigated by the iframe's parent by calling + * window.open("http://", iframe) later in the test. We then verify the + * TriggeringPrincipal and LoadingPrincipal of the navigated iframe. + * + * +------------------------------------------+ + * | | + * | +------------------+ | + * | | testframe | | + * | +------------------+ | + * | | + * | window.open("http://", "testframe"); | + * | | + * +------------------------------------------+ + */ + +const TRIGGERING_PRINCIPAL_URI = + "http://mochi.test:8888/tests/docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html"; + +const LOADING_PRINCIPAL_URI = TRIGGERING_PRINCIPAL_URI; + +var testframe = document.getElementById("testframe"); + +function checkResults() { + testframe.removeEventListener("load", checkResults); + + var channel = SpecialPowers.wrap(testframe.contentWindow).docShell.currentDocumentChannel; + var triggeringPrincipal = channel.loadInfo.triggeringPrincipal.asciiSpec.split("?")[0]; + var loadingPrincipal = channel.loadInfo.loadingPrincipal.asciiSpec.split("?")[0]; + + is(triggeringPrincipal, TRIGGERING_PRINCIPAL_URI, + "TriggeringPrincipal for targeted window.open() should be the principal of the document"); + + is(testframe.contentDocument.referrer.split("?")[0], TRIGGERING_PRINCIPAL_URI, + "Referrer for targeted window.open() should be the principal of the document"); + + is(loadingPrincipal, LOADING_PRINCIPAL_URI, + "LoadingPrincipal for targeted window.open() should be the <iframe>.ownerDocument"); + + SimpleTest.finish(); +} + +function performNavigation() { + testframe.removeEventListener("load", performNavigation); + testframe.addEventListener("load", checkResults); + window.open("file_triggeringprincipal_parent_iframe_window_open_nav.html", "testframe"); +} + +// start the test +SimpleTest.waitForExplicitFinish(); + +testframe.addEventListener("load", performNavigation); + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/navigation/test_triggeringprincipal_window_open.html b/docshell/test/navigation/test_triggeringprincipal_window_open.html new file mode 100644 index 0000000000..439a125f97 --- /dev/null +++ b/docshell/test/navigation/test_triggeringprincipal_window_open.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="NavigationUtils.js"></script> +</head> +<body> + +<script type="text/javascript"> + +/* We call window.open() using different URIs and make sure the triggeringPrincipal + * loadingPrincipal are correct. + * Test1: window.open(http:) + * Test2: window.open(javascript:) + */ + +const TRIGGERING_PRINCIPAL_URI = + "http://mochi.test:8888/tests/docshell/test/navigation/test_triggeringprincipal_window_open.html"; + +SimpleTest.waitForExplicitFinish(); + +const NUM_TESTS = 2; +var test_counter = 0; + +function checkFinish() { + test_counter++; + if (test_counter === NUM_TESTS) { + SimpleTest.finish(); + } +} + +// ---------------------------------------------------------------------------- +// Test 1: window.open(http:) +var httpWin = window.open("file_triggeringprincipal_window_open.html", "_blank", "width=10,height=10"); +httpWin.onload = function() { + var httpChannel = SpecialPowers.wrap(httpWin).docShell.currentDocumentChannel; + var httpTriggeringPrincipal = httpChannel.loadInfo.triggeringPrincipal.asciiSpec; + var httpLoadingPrincipal = httpChannel.loadInfo.loadingPrincipal; + + is(httpTriggeringPrincipal.split("?")[0], TRIGGERING_PRINCIPAL_URI, + "TriggeringPrincipal for window.open(http:) should be the principal of the document"); + + is(httpWin.document.referrer.split("?")[0], TRIGGERING_PRINCIPAL_URI, + "Referrer for window.open(http:) should be the principal of the document"); + + is(httpLoadingPrincipal, null, + "LoadingPrincipal for window.open(http:) should be null"); + + httpWin.close(); + checkFinish(); +}; + +// ---------------------------------------------------------------------------- +// Test 2: window.open(javascript:) +var jsWin = window.open("javascript:'<html><body>js</body></html>';", "_blank", "width=10,height=10"); +jsWin.onload = function() { + var jsChannel = SpecialPowers.wrap(jsWin).docShell.currentDocumentChannel; + var jsTriggeringPrincipal = jsChannel.loadInfo.triggeringPrincipal.asciiSpec; + var jsLoadingPrincipal = jsChannel.loadInfo.loadingPrincipal; + + is(jsTriggeringPrincipal.split("?")[0], TRIGGERING_PRINCIPAL_URI, + "TriggeringPrincipal for window.open(javascript:) should be the principal of the document"); + + is(jsWin.document.referrer, "", + "Referrer for window.open(javascript:) should be empty"); + + is(jsLoadingPrincipal, null, + "LoadingPrincipal for window.open(javascript:) should be null"); + + jsWin.close(); + checkFinish(); +}; + +</script> +</pre> +</body> +</html> |