diff options
author | Matt A. Tobin <email@mattatobin.com> | 2021-11-22 11:41:22 -0500 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2021-11-22 11:41:22 -0500 |
commit | 7572f6fb227f67f5f820019fe8afa899aa700862 (patch) | |
tree | 33e53aa11ae6107f5048f313a0e7b1e748baad0f /system/docshell/test | |
parent | 3bcef0ff65fa2ab6a482543afd1b1e00dd31cfee (diff) | |
download | aura-central-7572f6fb227f67f5f820019fe8afa899aa700862.tar.gz |
Issue %3005 - Move docshell/ to system/
Diffstat (limited to 'system/docshell/test')
386 files changed, 18712 insertions, 0 deletions
diff --git a/system/docshell/test/browser/browser.ini b/system/docshell/test/browser/browser.ini new file mode 100644 index 000000000..300caff1a --- /dev/null +++ b/system/docshell/test/browser/browser.ini @@ -0,0 +1,96 @@ +[DEFAULT] +support-files = + dummy_page.html + favicon_bug655270.ico + file_bug234628-1-child.html + file_bug234628-1.html + file_bug234628-10-child.xhtml + file_bug234628-10.html + file_bug234628-11-child.xhtml + file_bug234628-11-child.xhtml^headers^ + file_bug234628-11.html + file_bug234628-2-child.html + file_bug234628-2.html + file_bug234628-3-child.html + file_bug234628-3.html + file_bug234628-4-child.html + file_bug234628-4.html + file_bug234628-5-child.html + file_bug234628-5.html + file_bug234628-6-child.html + file_bug234628-6-child.html^headers^ + file_bug234628-6.html + file_bug234628-7-child.html + file_bug234628-7-child.html^headers^ + file_bug234628-7.html + file_bug234628-8-child.html + file_bug234628-8.html + file_bug234628-9-child.html + file_bug234628-9.html + file_bug420605.html + file_bug422543_script.js + file_bug503832.html + file_bug655270.html + file_bug670318.html + file_bug852909.pdf + file_bug852909.png + file_bug1046022.html + file_bug1206879.html + file_multiple_pushState.html + print_postdata.sjs + test-form_sjis.html + timelineMarkers-04.html + browser_timelineMarkers-frame-02.js + browser_timelineMarkers-frame-03.js + browser_timelineMarkers-frame-04.js + browser_timelineMarkers-frame-05.js + head.js + frame-head.js + file_click_link_within_view_source.html + +[browser_bug1206879.js] +[browser_bug1309900_crossProcessHistoryNavigation.js] +[browser_bug134911.js] +[browser_bug234628-1.js] +[browser_bug234628-10.js] +[browser_bug234628-11.js] +[browser_bug234628-2.js] +[browser_bug234628-3.js] +[browser_bug234628-4.js] +[browser_bug234628-5.js] +[browser_bug234628-6.js] +[browser_bug234628-7.js] +[browser_bug234628-8.js] +[browser_bug234628-9.js] +[browser_bug349769.js] +[browser_bug388121-1.js] +[browser_bug388121-2.js] +[browser_bug420605.js] +[browser_bug422543.js] +[browser_bug441169.js] +[browser_bug503832.js] +[browser_bug554155.js] +[browser_bug655270.js] +[browser_bug655273.js] +[browser_bug670318.js] +[browser_bug673467.js] +[browser_bug852909.js] +[browser_bug92473.js] +[browser_uriFixupIntegration.js] +[browser_uriFixupAlternateRedirects.js] +support-files = + redirect_to_example.sjs +[browser_loadDisallowInherit.js] +[browser_loadURI.js] +[browser_multiple_pushState.js] +[browser_onbeforeunload_navigation.js] +[browser_search_notification.js] +[browser_tab_touch_events.js] +[browser_timelineMarkers-01.js] +[browser_timelineMarkers-02.js] +skip-if = true # Bug 1220415 +[browser_timelineMarkers-03.js] +[browser_timelineMarkers-04.js] +[browser_timelineMarkers-05.js] +[browser_ua_emulation.js] +[browser_click_link_within_view_source.js] diff --git a/system/docshell/test/browser/browser_bug1206879.js b/system/docshell/test/browser/browser_bug1206879.js new file mode 100644 index 000000000..1276f6428 --- /dev/null +++ b/system/docshell/test/browser/browser_bug1206879.js @@ -0,0 +1,31 @@ +add_task(function*() { + let url = getRootDirectory(gTestPath) + "file_bug1206879.html"; + let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url, true); + + let numLocationChanges = 0; + + let listener = { + onLocationChange: function(browser, wp, request, uri, flags) { + if (browser != tab.linkedBrowser) { + return; + } + info("onLocationChange: " + uri.spec); + numLocationChanges++; + this.resolve(); + } + }; + let locationPromise = new Promise((resolve, reject) => { + listener.resolve = resolve; + gBrowser.addTabsProgressListener(listener); + }); + yield ContentTask.spawn(tab.linkedBrowser, {}, function() { + content.frames[0].history.pushState(null, null, "foo"); + }); + + yield locationPromise; + + gBrowser.removeTab(tab); + gBrowser.removeTabsProgressListener(listener); + is(numLocationChanges, 1, + "pushState with a different URI should cause a LocationChange event."); +}); diff --git a/system/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js b/system/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js new file mode 100644 index 000000000..55de27def --- /dev/null +++ b/system/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +add_task(function* runTests() { + let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:about"); + + registerCleanupFunction(function* () { + gBrowser.removeTab(tab); + }); + + let browser = tab.linkedBrowser; + + browser.loadURI("about:accounts"); + let href = yield BrowserTestUtils.browserLoaded(browser); + is(href, "about:accounts", "Check about:accounts loaded"); + + // Using a dummy onunload listener to disable the bfcache as that can prevent + // the test browser load detection mechanism from working. + browser.loadURI("data:text/html,<body%20onunload=''><iframe></iframe></body>"); + href = yield BrowserTestUtils.browserLoaded(browser); + is(href, "data:text/html,<body%20onunload=''><iframe></iframe></body>", + "Check data URL loaded"); + + browser.goBack(); + href = yield BrowserTestUtils.browserLoaded(browser); + is(href, "about:accounts", "Check we've gone back to about:accounts"); + + browser.goForward(); + href = yield BrowserTestUtils.browserLoaded(browser); + is(href, "data:text/html,<body%20onunload=''><iframe></iframe></body>", + "Check we've gone forward to data URL"); +}); diff --git a/system/docshell/test/browser/browser_bug134911.js b/system/docshell/test/browser/browser_bug134911.js new file mode 100644 index 000000000..aa54cfd1a --- /dev/null +++ b/system/docshell/test/browser/browser_bug134911.js @@ -0,0 +1,41 @@ +const TEXT = { + /* The test text decoded correctly as Shift_JIS */ + rightText: "\u30E6\u30CB\u30B3\u30FC\u30C9\u306F\u3001\u3059\u3079\u3066\u306E\u6587\u5B57\u306B\u56FA\u6709\u306E\u756A\u53F7\u3092\u4ED8\u4E0E\u3057\u307E\u3059", + + enteredText1: "The quick brown fox jumps over the lazy dog", + enteredText2: "\u03BE\u03B5\u03C3\u03BA\u03B5\u03C0\u03AC\u03B6\u03C9\u0020\u03C4\u1F74\u03BD\u0020\u03C8\u03C5\u03C7\u03BF\u03C6\u03B8\u03CC\u03C1\u03B1\u0020\u03B2\u03B4\u03B5\u03BB\u03C5\u03B3\u03BC\u03AF\u03B1", +}; + +function test() { + waitForExplicitFinish(); + + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + gBrowser.selectedTab = gBrowser.addTab(rootDir + "test-form_sjis.html"); + BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterOpen); +} + +function afterOpen() { + BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterChangeCharset); + + ContentTask.spawn(gBrowser.selectedBrowser, TEXT, function(TEXT) { + content.document.getElementById("testtextarea").value = TEXT.enteredText1; + content.document.getElementById("testinput").value = TEXT.enteredText2; + }).then(() => { + /* Force the page encoding to Shift_JIS */ + BrowserSetForcedCharacterSet("Shift_JIS"); + }); +} + +function afterChangeCharset() { + ContentTask.spawn(gBrowser.selectedBrowser, TEXT, function(TEXT) { + is(content.document.getElementById("testpar").innerHTML, TEXT.rightText, + "encoding successfully changed"); + is(content.document.getElementById("testtextarea").value, TEXT.enteredText1, + "text preserved in <textarea>"); + is(content.document.getElementById("testinput").value, TEXT.enteredText2, + "text preserved in <input>"); + }).then(() => { + gBrowser.removeCurrentTab(); + finish(); + }); +} diff --git a/system/docshell/test/browser/browser_bug234628-1.js b/system/docshell/test/browser/browser_bug234628-1.js new file mode 100644 index 000000000..bfb4d3708 --- /dev/null +++ b/system/docshell/test/browser/browser_bug234628-1.js @@ -0,0 +1,18 @@ +function test() { + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + runCharsetTest(rootDir + "file_bug234628-1.html", afterOpen, "windows-1251", afterChangeCharset); +} + +function afterOpen() { + is(content.document.documentElement.textContent.indexOf('\u20AC'), 129, "Parent doc should be windows-1252 initially"); + + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 85, "Child doc should be windows-1252 initially"); +} + +function afterChangeCharset() { + is(content.document.documentElement.textContent.indexOf('\u0402'), 129, "Parent doc should decode as windows-1251 subsequently"); + is(content.frames[0].document.documentElement.textContent.indexOf('\u0402'), 85, "Child doc should decode as windows-1251 subsequently"); + + is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); + is(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently"); +} diff --git a/system/docshell/test/browser/browser_bug234628-10.js b/system/docshell/test/browser/browser_bug234628-10.js new file mode 100644 index 000000000..7dbe805c4 --- /dev/null +++ b/system/docshell/test/browser/browser_bug234628-10.js @@ -0,0 +1,18 @@ +function test() { + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + runCharsetTest(rootDir + "file_bug234628-10.html", afterOpen, "windows-1251", afterChangeCharset); +} + +function afterOpen() { + is(content.document.documentElement.textContent.indexOf('\u20AC'), 151, "Parent doc should be windows-1252 initially"); + + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 71, "Child doc should be utf-8 initially"); +} + +function afterChangeCharset() { + is(content.document.documentElement.textContent.indexOf('\u0402'), 151, "Parent doc should decode as windows-1251 subsequently"); + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 71, "Child doc should decode as utf-8 subsequently"); + + is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); + is(content.frames[0].document.characterSet, "UTF-8", "Child doc should report UTF-8 subsequently"); +} diff --git a/system/docshell/test/browser/browser_bug234628-11.js b/system/docshell/test/browser/browser_bug234628-11.js new file mode 100644 index 000000000..fc597f5c0 --- /dev/null +++ b/system/docshell/test/browser/browser_bug234628-11.js @@ -0,0 +1,18 @@ +function test() { + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + runCharsetTest(rootDir + "file_bug234628-11.html", afterOpen, "windows-1251", afterChangeCharset); +} + +function afterOpen() { + is(content.document.documentElement.textContent.indexOf('\u20AC'), 193, "Parent doc should be windows-1252 initially"); + + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 107, "Child doc should be utf-8 initially"); +} + +function afterChangeCharset() { + is(content.document.documentElement.textContent.indexOf('\u0402'), 193, "Parent doc should decode as windows-1251 subsequently"); + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 107, "Child doc should decode as utf-8 subsequently"); + + is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); + is(content.frames[0].document.characterSet, "UTF-8", "Child doc should report UTF-8 subsequently"); +} diff --git a/system/docshell/test/browser/browser_bug234628-2.js b/system/docshell/test/browser/browser_bug234628-2.js new file mode 100644 index 000000000..638e223c0 --- /dev/null +++ b/system/docshell/test/browser/browser_bug234628-2.js @@ -0,0 +1,18 @@ +function test() { + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + runCharsetTest(rootDir + "file_bug234628-2.html", afterOpen, "windows-1251", afterChangeCharset); +} + +function afterOpen() { + is(content.document.documentElement.textContent.indexOf('\u20AC'), 129, "Parent doc should be windows-1252 initially"); + + is(content.frames[0].document.documentElement.textContent.indexOf('\u00E2\u201A\u00AC'), 78, "Child doc should be windows-1252 initially"); +} + +function afterChangeCharset() { + is(content.document.documentElement.textContent.indexOf('\u0402'), 129, "Parent doc should decode as windows-1251 subsequently"); + is(content.frames[0].document.documentElement.textContent.indexOf('\u0432\u201A\u00AC'), 78, "Child doc should decode as windows-1251 subsequently"); + + is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); + is(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently"); +} diff --git a/system/docshell/test/browser/browser_bug234628-3.js b/system/docshell/test/browser/browser_bug234628-3.js new file mode 100644 index 000000000..51aca7ec8 --- /dev/null +++ b/system/docshell/test/browser/browser_bug234628-3.js @@ -0,0 +1,18 @@ +function test() { + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + runCharsetTest(rootDir + "file_bug234628-3.html", afterOpen, "windows-1251", afterChangeCharset); +} + +function afterOpen() { + is(content.document.documentElement.textContent.indexOf('\u20AC'), 118, "Parent doc should be windows-1252 initially"); + + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 73, "Child doc should be utf-8 initially"); +} + +function afterChangeCharset() { + is(content.document.documentElement.textContent.indexOf('\u0402'), 118, "Parent doc should decode as windows-1251 subsequently"); + is(content.frames[0].document.documentElement.textContent.indexOf('\u0432\u201A\u00AC'), 73, "Child doc should decode as windows-1251 subsequently"); + + is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); + is(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently"); +} diff --git a/system/docshell/test/browser/browser_bug234628-4.js b/system/docshell/test/browser/browser_bug234628-4.js new file mode 100644 index 000000000..fe7f1545f --- /dev/null +++ b/system/docshell/test/browser/browser_bug234628-4.js @@ -0,0 +1,18 @@ +function test() { + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + runCharsetTest(rootDir + "file_bug234628-4.html", afterOpen, "windows-1251", afterChangeCharset); +} + +function afterOpen() { + is(content.document.documentElement.textContent.indexOf('\u20AC'), 132, "Parent doc should be windows-1252 initially"); + + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 79, "Child doc should be utf-8 initially"); +} + +function afterChangeCharset() { + is(content.document.documentElement.textContent.indexOf('\u0402'), 132, "Parent doc should decode as windows-1251 subsequently"); + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 79, "Child doc should decode as utf-8 subsequently"); + + is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); + is(content.frames[0].document.characterSet, "UTF-8", "Child doc should report UTF-8 subsequently"); +} diff --git a/system/docshell/test/browser/browser_bug234628-5.js b/system/docshell/test/browser/browser_bug234628-5.js new file mode 100644 index 000000000..a37f14b8d --- /dev/null +++ b/system/docshell/test/browser/browser_bug234628-5.js @@ -0,0 +1,18 @@ +function test() { + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + runCharsetTest(rootDir + "file_bug234628-5.html", afterOpen, "windows-1251", afterChangeCharset); +} + +function afterOpen() { + is(content.document.documentElement.textContent.indexOf('\u20AC'), 146, "Parent doc should be windows-1252 initially"); + + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 87, "Child doc should be utf-16 initially"); +} + +function afterChangeCharset() { + is(content.document.documentElement.textContent.indexOf('\u0402'), 146, "Parent doc should decode as windows-1251 subsequently"); + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 87, "Child doc should decode as utf-16 subsequently"); + + is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); + is(content.frames[0].document.characterSet, "UTF-16LE", "Child doc should report UTF-16LE subsequently"); +} diff --git a/system/docshell/test/browser/browser_bug234628-6.js b/system/docshell/test/browser/browser_bug234628-6.js new file mode 100644 index 000000000..7d2d92531 --- /dev/null +++ b/system/docshell/test/browser/browser_bug234628-6.js @@ -0,0 +1,18 @@ +function test() { + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + runCharsetTest(rootDir + "file_bug234628-6.html", afterOpen, "windows-1251", afterChangeCharset); +} + +function afterOpen() { + is(content.document.documentElement.textContent.indexOf('\u20AC'), 190, "Parent doc should be windows-1252 initially"); + + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 109, "Child doc should be utf-16 initially"); +} + +function afterChangeCharset() { + is(content.document.documentElement.textContent.indexOf('\u0402'), 190, "Parent doc should decode as windows-1251 subsequently"); + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 109, "Child doc should decode as utf-16 subsequently"); + + is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); + is(content.frames[0].document.characterSet, "UTF-16BE", "Child doc should report UTF-16 subsequently"); +} diff --git a/system/docshell/test/browser/browser_bug234628-7.js b/system/docshell/test/browser/browser_bug234628-7.js new file mode 100644 index 000000000..0bafd67e7 --- /dev/null +++ b/system/docshell/test/browser/browser_bug234628-7.js @@ -0,0 +1,18 @@ +function test() { + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + runCharsetTest(rootDir + "file_bug234628-7.html", afterOpen, "windows-1251", afterChangeCharset); +} + +function afterOpen() { + is(content.document.documentElement.textContent.indexOf('\u20AC'), 188, "Parent doc should be windows-1252 initially"); + + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 107, "Child doc should be utf-8 initially"); +} + +function afterChangeCharset() { + is(content.document.documentElement.textContent.indexOf('\u0402'), 188, "Parent doc should decode as windows-1251 subsequently"); + is(content.frames[0].document.documentElement.textContent.indexOf('\u0432\u201A\u00AC'), 107, "Child doc should decode as windows-1251 subsequently"); + + is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); + is(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently"); +} diff --git a/system/docshell/test/browser/browser_bug234628-8.js b/system/docshell/test/browser/browser_bug234628-8.js new file mode 100644 index 000000000..40a0c6946 --- /dev/null +++ b/system/docshell/test/browser/browser_bug234628-8.js @@ -0,0 +1,11 @@ +function test() { + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + runCharsetTest(rootDir + "file_bug234628-8.html", afterOpen); +} + +function afterOpen() { + is(content.document.documentElement.textContent.indexOf('\u0402'), 156, "Parent doc should be windows-1251"); + + is(content.frames[0].document.documentElement.textContent.indexOf('\u0402'), 99, "Child doc should be windows-1251"); +} + diff --git a/system/docshell/test/browser/browser_bug234628-9.js b/system/docshell/test/browser/browser_bug234628-9.js new file mode 100644 index 000000000..72da65e80 --- /dev/null +++ b/system/docshell/test/browser/browser_bug234628-9.js @@ -0,0 +1,11 @@ +function test() { + var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + runCharsetTest(rootDir + "file_bug234628-9.html", afterOpen); +} + +function afterOpen() { + is(content.document.documentElement.textContent.indexOf('\u20AC'), 145, "Parent doc should be UTF-16"); + + is(content.frames[0].document.documentElement.textContent.indexOf('\u20AC'), 96, "Child doc should be windows-1252"); +} + diff --git a/system/docshell/test/browser/browser_bug349769.js b/system/docshell/test/browser/browser_bug349769.js new file mode 100644 index 000000000..76d4e0f28 --- /dev/null +++ b/system/docshell/test/browser/browser_bug349769.js @@ -0,0 +1,47 @@ +add_task(function* test() { + const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager); + const uris = [undefined, "about:blank"]; + + function checkContentProcess(uri) { + yield ContentTask.spawn(newBrowser, uri, function* (uri) { + var prin = content.document.nodePrincipal; + Assert.notEqual(prin, null, "Loaded principal must not be null when adding " + uri); + Assert.notEqual(prin, undefined, "Loaded principal must not be undefined when loading " + uri); + + const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"] + .getService(Ci.nsIScriptSecurityManager); + Assert.equal(secMan.isSystemPrincipal(prin), false, + "Loaded principal must not be system when loading " + uri); + }); + } + + for (var uri of uris) { + yield BrowserTestUtils.withNewTab({ gBrowser }, function* (newBrowser) { + yield BrowserTestUtils.loadURI(newBrowser, uri); + + var prin = newBrowser.contentPrincipal; + isnot(prin, null, "Forced principal must not be null when loading " + uri); + isnot(prin, undefined, + "Forced principal must not be undefined when loading " + uri); + is(secMan.isSystemPrincipal(prin), false, + "Forced principal must not be system when loading " + uri); + + // Belt-and-suspenders e10s check: make sure that the same checks hold + // true in the content process. + checkContentProcess(uri); + + yield BrowserTestUtils.browserLoaded(newBrowser); + + prin = newBrowser.contentPrincipal; + isnot(prin, null, "Loaded principal must not be null when adding " + uri); + isnot(prin, undefined, "Loaded principal must not be undefined when loading " + uri); + is(secMan.isSystemPrincipal(prin), false, + "Loaded principal must not be system when loading " + uri); + + // Belt-and-suspenders e10s check: make sure that the same checks hold + // true in the content process. + checkContentProcess(uri); + }); + } +}); + diff --git a/system/docshell/test/browser/browser_bug388121-1.js b/system/docshell/test/browser/browser_bug388121-1.js new file mode 100644 index 000000000..7da617594 --- /dev/null +++ b/system/docshell/test/browser/browser_bug388121-1.js @@ -0,0 +1,15 @@ +add_task(function* test() { + yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, function* (newBrowser) { + yield ContentTask.spawn(newBrowser, null, function* () { + var prin = content.document.nodePrincipal; + Assert.notEqual(prin, null, "Loaded principal must not be null"); + Assert.notEqual(prin, undefined, "Loaded principal must not be undefined"); + + const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"] + .getService(Ci.nsIScriptSecurityManager); + Assert.equal(secMan.isSystemPrincipal(prin), false, + "Loaded principal must not be system"); + }); + }); +}); + diff --git a/system/docshell/test/browser/browser_bug388121-2.js b/system/docshell/test/browser/browser_bug388121-2.js new file mode 100644 index 000000000..6c050d971 --- /dev/null +++ b/system/docshell/test/browser/browser_bug388121-2.js @@ -0,0 +1,58 @@ +function test() { + waitForExplicitFinish(); + + var w; + const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager); + var iteration = 1; + const uris = ["", "about:blank"]; + var uri; + var origDoc; + + function testLoad() { + if (w.document == origDoc) { + // Go back to polling + setTimeout(testLoad, 10); + return; + } + var prin = w.document.nodePrincipal; + isnot(prin, null, "Loaded principal must not be null when adding " + uri); + isnot(prin, undefined, "Loaded principal must not be undefined when loading " + uri); + is(secMan.isSystemPrincipal(prin), false, + "Loaded principal must not be system when loading " + uri); + w.close(); + + if (iteration == uris.length) { + finish(); + } else { + ++iteration; + doTest(); + } + } + + function doTest() { + uri = uris[iteration - 1]; + w = window.open(uri, "_blank", "width=10,height=10"); + var prin = w.document.nodePrincipal; + if (!uri) { + uri = undefined; + } + isnot(prin, null, "Forced principal must not be null when loading " + uri); + isnot(prin, undefined, + "Forced principal must not be undefined when loading " + uri); + is(secMan.isSystemPrincipal(prin), false, + "Forced principal must not be system when loading " + uri); + if (uri == undefined) { + // No actual load here, so just move along. + w.close(); + ++iteration; + doTest(); + } else { + origDoc = w.document; + // Need to poll, because load listeners on the content window won't + // survive the load. + setTimeout(testLoad, 10); + } + } + + doTest(); +} diff --git a/system/docshell/test/browser/browser_bug420605.js b/system/docshell/test/browser/browser_bug420605.js new file mode 100644 index 000000000..f07d45e93 --- /dev/null +++ b/system/docshell/test/browser/browser_bug420605.js @@ -0,0 +1,122 @@ +/* Test for Bug 420605 + * https://bugzilla.mozilla.org/show_bug.cgi?id=420605 + */ + +function test() { + waitForExplicitFinish(); + + var pageurl = "http://mochi.test:8888/browser/docshell/test/browser/file_bug420605.html"; + var fragmenturl = "http://mochi.test:8888/browser/docshell/test/browser/file_bug420605.html#firefox"; + + var historyService = Cc["@mozilla.org/browser/nav-history-service;1"] + .getService(Ci.nsINavHistoryService); + + /* Queries nsINavHistoryService and returns a single history entry + * for a given URI */ + function getNavHistoryEntry(aURI) { + var options = historyService.getNewQueryOptions(); + options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY; + options.maxResults = 1; + + var query = historyService.getNewQuery(); + query.uri = aURI; + + var result = historyService.executeQuery(query, options); + result.root.containerOpen = true; + + if (!result.root.childCount) { + return null; + } + return result.root.getChild(0); + } + + // We'll save the favicon URL of the orignal page here and check that the + // page with a hash has the same favicon. + var originalFavicon; + + // Control flow in this test is a bit complicated. + // + // When the page loads, onPageLoad (the DOMContentLoaded handler) and + // historyObserver::onPageChanged are both called, in some order. Once + // they've both run, we click a fragment link in the content page + // (clickLinkIfReady), which should trigger another onPageChanged event, + // this time for the fragment's URL. + + var _clickLinkTimes = 0; + function clickLinkIfReady() { + _clickLinkTimes++; + if (_clickLinkTimes == 2) { + BrowserTestUtils.synthesizeMouseAtCenter('#firefox-link', {}, + gBrowser.selectedBrowser); + } + } + + /* Global history observer that triggers for the two test URLs above. */ + var historyObserver = { + onBeginUpdateBatch: function() {}, + onEndUpdateBatch: function() {}, + onVisit: function(aURI, aVisitID, aTime, aSessionId, aReferringId, + aTransitionType, _added) {}, + onTitleChanged: function(aURI, aPageTitle) {}, + onDeleteURI: function(aURI) {}, + onClearHistory: function() {}, + onPageChanged: function(aURI, aWhat, aValue) { + if (aWhat != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) { + return; + } + aURI = aURI.spec; + switch (aURI) { + case pageurl: + ok(aValue, "Favicon value is not null for page without fragment."); + originalFavicon = aValue; + + // Now that the favicon has loaded, click on fragment link. + // This should trigger the |case fragmenturl| below. + clickLinkIfReady(); + + return; + case fragmenturl: + // If the fragment URL's favicon isn't set, this branch won't + // be called and the test will time out. + + is(aValue, originalFavicon, "New favicon should be same as original favicon."); + + // Let's explicitly check that we can get the favicon + // from nsINavHistoryService now. + let info = getNavHistoryEntry(makeURI(aURI)); + ok(info, "There must be a history entry for the fragment."); + ok(info.icon, "The history entry must have an associated favicon."); + historyService.removeObserver(historyObserver, false); + gBrowser.removeCurrentTab(); + finish(); + } + }, + onPageExpired: function(aURI, aVisitTime, aWholeEntry) {}, + QueryInterface: function(iid) { + if (iid.equals(Ci.nsINavHistoryObserver) || + iid.equals(Ci.nsISupports)) { + return this; + } + throw Cr.NS_ERROR_NO_INTERFACE; + } + }; + historyService.addObserver(historyObserver, false); + + function onPageLoad() { + gBrowser.selectedBrowser + .removeEventListener("DOMContentLoaded", arguments.callee, true); + clickLinkIfReady(); + } + + // Make sure neither of the test pages haven't been loaded before. + var info = getNavHistoryEntry(makeURI(pageurl)); + ok(!info, "The test page must not have been visited already."); + info = getNavHistoryEntry(makeURI(fragmenturl)); + ok(!info, "The fragment test page must not have been visited already."); + + // Now open the test page in a new tab. + gBrowser.selectedTab = gBrowser.addTab(); + gBrowser.selectedBrowser.addEventListener( + "DOMContentLoaded", onPageLoad, true); + content.location = pageurl; +} diff --git a/system/docshell/test/browser/browser_bug422543.js b/system/docshell/test/browser/browser_bug422543.js new file mode 100644 index 000000000..0655a17b7 --- /dev/null +++ b/system/docshell/test/browser/browser_bug422543.js @@ -0,0 +1,116 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +add_task(function* runTests() { + yield setup(); + let browser = gBrowser.selectedBrowser; + // Now that we're set up, initialize our frame script. + yield checkListeners("initial", "listeners initialized"); + + // Check if all history listeners are always notified. + info("# part 1"); + yield whenPageShown(browser, () => browser.loadURI("http://www.example.com/")); + yield checkListeners("newentry", "shistory has a new entry"); + ok(browser.canGoBack, "we can go back"); + + yield whenPageShown(browser, () => browser.goBack()); + yield checkListeners("goback", "back to the first shentry"); + ok(browser.canGoForward, "we can go forward"); + + yield whenPageShown(browser, () => browser.goForward()); + yield checkListeners("goforward", "forward to the second shentry"); + + yield whenPageShown(browser, () => browser.reload()); + yield checkListeners("reload", "current shentry reloaded"); + + yield whenPageShown(browser, () => browser.gotoIndex(0)); + yield checkListeners("gotoindex", "back to the first index"); + + // Check nsISHistoryInternal.notifyOnHistoryReload + info("# part 2"); + ok((yield notifyReload()), "reloading has not been canceled"); + yield checkListeners("reload", "saw the reload notification"); + + // Let the first listener cancel the reload action. + info("# part 3"); + yield resetListeners(); + yield setListenerRetval(0, false); + ok(!(yield notifyReload()), "reloading has been canceled"); + yield checkListeners("reload", "saw the reload notification"); + + // Let both listeners cancel the reload action. + info("# part 4"); + yield resetListeners(); + yield setListenerRetval(1, false); + ok(!(yield notifyReload()), "reloading has been canceled"); + yield checkListeners("reload", "saw the reload notification"); + + // Let the second listener cancel the reload action. + info("# part 5"); + yield resetListeners(); + yield setListenerRetval(0, true); + ok(!(yield notifyReload()), "reloading has been canceled"); + yield checkListeners("reload", "saw the reload notification"); +}); + +function listenOnce(message, arg = {}) { + return new Promise(resolve => { + let mm = gBrowser.selectedBrowser.messageManager; + mm.addMessageListener(message + ":return", function listener(msg) { + mm.removeMessageListener(message + ":return", listener); + resolve(msg.data); + }); + + mm.sendAsyncMessage(message, arg); + }); +} + +function checkListeners(aLast, aMessage) { + return listenOnce("bug422543:getListenerStatus").then((listenerStatuses) => { + is(listenerStatuses[0], aLast, aMessage); + is(listenerStatuses[1], aLast, aMessage); + }); +} + +function resetListeners() { + return listenOnce("bug422543:resetListeners"); +} + +function notifyReload() { + return listenOnce("bug422543:notifyReload").then(({ rval }) => { + return rval; + }); +} + +function setListenerRetval(num, val) { + return listenOnce("bug422543:setRetval", { num, val }); +} + +function setup() { + return BrowserTestUtils.openNewForegroundTab(gBrowser, + "http://mochi.test:8888") + .then(function (tab) { + let browser = tab.linkedBrowser; + registerCleanupFunction(function* () { + yield listenOnce("bug422543:cleanup"); + gBrowser.removeTab(tab); + }); + + browser.messageManager + .loadFrameScript(getRootDirectory(gTestPath) + "file_bug422543_script.js", false); + }); +} + +function whenPageShown(aBrowser, aNavigation) { + let listener = ContentTask.spawn(aBrowser, null, function () { + return new Promise(resolve => { + addEventListener("pageshow", function onLoad() { + removeEventListener("pageshow", onLoad, true); + resolve(); + }, true); + }); + }); + + aNavigation(); + return listener; +} diff --git a/system/docshell/test/browser/browser_bug441169.js b/system/docshell/test/browser/browser_bug441169.js new file mode 100644 index 000000000..015115793 --- /dev/null +++ b/system/docshell/test/browser/browser_bug441169.js @@ -0,0 +1,37 @@ +/* Make sure that netError won't allow HTML injection through badcert parameters. See bug 441169. */ +var newBrowser + +function task() { + let resolve; + let promise = new Promise(r => { resolve = r; }); + + addEventListener("DOMContentLoaded", checkPage, false); + + function checkPage(event) { + if (event.target != content.document) { + return; + } + removeEventListener("DOMContentLoaded", checkPage, false); + + is(content.document.getElementById("test_span"), null, "Error message should not be parsed as HTML, and hence shouldn't include the 'test_span' element."); + resolve(); + } + + var chromeURL = "about:neterror?e=nssBadCert&u=https%3A//test.kuix.de/&c=UTF-8&d=This%20sentence%20should%20not%20be%20parsed%20to%20include%20a%20%3Cspan%20id=%22test_span%22%3Enamed%3C/span%3E%20span%20tag.%0A%0AThe%20certificate%20is%20only%20valid%20for%20%3Ca%20id=%22cert_domain_link%22%20title=%22kuix.de%22%3Ekuix.de%3C/a%3E%0A%0A(Error%20code%3A%20ssl_error_bad_cert_domain)"; + content.location = chromeURL; + + return promise; +} + +function test() { + waitForExplicitFinish(); + + var newTab = gBrowser.addTab(); + gBrowser.selectedTab = newTab; + newBrowser = gBrowser.getBrowserForTab(newTab); + + ContentTask.spawn(newBrowser, null, task).then(() => { + gBrowser.removeCurrentTab(); + finish(); + }); +} diff --git a/system/docshell/test/browser/browser_bug503832.js b/system/docshell/test/browser/browser_bug503832.js new file mode 100644 index 000000000..66904cbae --- /dev/null +++ b/system/docshell/test/browser/browser_bug503832.js @@ -0,0 +1,87 @@ +/* Test for Bug 503832 + * https://bugzilla.mozilla.org/show_bug.cgi?id=503832 + */ + +add_task(function* () { + var pagetitle = "Page Title for Bug 503832"; + var pageurl = "http://mochi.test:8888/browser/docshell/test/browser/file_bug503832.html"; + var fragmenturl = "http://mochi.test:8888/browser/docshell/test/browser/file_bug503832.html#firefox"; + + var historyService = Cc["@mozilla.org/browser/nav-history-service;1"] + .getService(Ci.nsINavHistoryService); + + let fragmentPromise = new Promise(resolve => { + /* Global history observer that triggers for the two test URLs above. */ + var historyObserver = { + onBeginUpdateBatch: function() {}, + onEndUpdateBatch: function() {}, + onVisit: function(aURI, aVisitID, aTime, aSessionId, aReferringId, + aTransitionType, _added) {}, + onTitleChanged: function(aURI, aPageTitle) { + aURI = aURI.spec; + switch (aURI) { + case pageurl: + is(aPageTitle, pagetitle, "Correct page title for " + aURI); + return; + case fragmenturl: + is(aPageTitle, pagetitle, "Correct page title for " + aURI); + // If titles for fragment URLs aren't set, this code + // branch won't be called and the test will timeout, + // resulting in a failure + historyService.removeObserver(historyObserver, false); + resolve(); + } + }, + onDeleteURI: function(aURI) {}, + onClearHistory: function() {}, + onPageChanged: function(aURI, aWhat, aValue) {}, + onDeleteVisits: function () {}, + QueryInterface: function(iid) { + if (iid.equals(Ci.nsINavHistoryObserver) || + iid.equals(Ci.nsISupports)) { + return this; + } + throw Cr.NS_ERROR_NO_INTERFACE; + } + }; + + historyService.addObserver(historyObserver, false); + }); + + /* Queries nsINavHistoryService and returns a single history entry + * for a given URI */ + function getNavHistoryEntry(aURI) { + var options = historyService.getNewQueryOptions(); + options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY; + options.maxResults = 1; + + var query = historyService.getNewQuery(); + query.uri = aURI; + + var result = historyService.executeQuery(query, options); + result.root.containerOpen = true; + + if (!result.root.childCount) { + return null; + } + var node = result.root.getChild(0); + result.root.containerOpen = false; + return node; + } + + // Make sure neither of the test pages haven't been loaded before. + var info = getNavHistoryEntry(makeURI(pageurl)); + ok(!info, "The test page must not have been visited already."); + info = getNavHistoryEntry(makeURI(fragmenturl)); + ok(!info, "The fragment test page must not have been visited already."); + + // Now open the test page in a new tab + yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageurl); + + // Now that the page is loaded, click on fragment link + yield BrowserTestUtils.synthesizeMouseAtCenter("#firefox-link", {}, + gBrowser.selectedBrowser); + yield fragmentPromise; + + gBrowser.removeCurrentTab(); +}); diff --git a/system/docshell/test/browser/browser_bug554155.js b/system/docshell/test/browser/browser_bug554155.js new file mode 100644 index 000000000..efc74a1c1 --- /dev/null +++ b/system/docshell/test/browser/browser_bug554155.js @@ -0,0 +1,26 @@ +add_task(function* test() { + yield BrowserTestUtils.withNewTab({ gBrowser, url: "http://example.com" }, function* (browser) { + let numLocationChanges = 0; + + let listener = { + onLocationChange: function(browser, webProgress, request, uri, flags) { + info("location change: " + (uri && uri.spec)); + numLocationChanges++; + } + }; + + gBrowser.addTabsProgressListener(listener); + + yield ContentTask.spawn(browser, null, function() { + // pushState to a new URL (http://example.com/foo"). This should trigger + // exactly one LocationChange event. + content.history.pushState(null, null, "foo"); + }); + + yield Promise.resolve(); + + gBrowser.removeTabsProgressListener(listener); + is(numLocationChanges, 1, + "pushState should cause exactly one LocationChange event."); + }); +}); diff --git a/system/docshell/test/browser/browser_bug655270.js b/system/docshell/test/browser/browser_bug655270.js new file mode 100644 index 000000000..275245df8 --- /dev/null +++ b/system/docshell/test/browser/browser_bug655270.js @@ -0,0 +1,60 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test for Bug 655273 + * + * Call pushState and then make sure that the favicon service associates our + * old favicon with the new URI. + */ + +function test() { + const testDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + const origURL = testDir + "file_bug655270.html"; + const newURL = origURL + '?new_page'; + + const faviconURL = testDir + "favicon_bug655270.ico"; + + waitForExplicitFinish(); + + let tab = gBrowser.addTab(origURL); + + // The page at origURL has a <link rel='icon'>, so we should get a call into + // our observer below when it loads. Once we verify that we have the right + // favicon URI, we call pushState, which should trigger another onPageChange + // event, this time for the URI after pushState. + + let observer = { + onPageChanged: function(aURI, aWhat, aValue) { + if (aWhat != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) + return; + + if (aURI.spec == origURL) { + is(aValue, faviconURL, 'FaviconURL for original URI'); + // Ignore the promise returned here and wait for the next + // onPageChanged notification. + ContentTask.spawn(tab.linkedBrowser, null, function() { + content.history.pushState('', '', '?new_page'); + }); + } + + if (aURI.spec == newURL) { + is(aValue, faviconURL, 'FaviconURL for new URI'); + gBrowser.removeTab(tab); + PlacesUtils.history.removeObserver(this); + finish(); + } + }, + + onBeginUpdateBatch: function() { }, + onEndUpdateBatch: function() { }, + onVisit: function() { }, + onTitleChanged: function() { }, + onDeleteURI: function() { }, + onClearHistory: function() { }, + onDeleteVisits: function() { }, + QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver]) + }; + + PlacesUtils.history.addObserver(observer, false); +} diff --git a/system/docshell/test/browser/browser_bug655273.js b/system/docshell/test/browser/browser_bug655273.js new file mode 100644 index 000000000..3acb6ddd5 --- /dev/null +++ b/system/docshell/test/browser/browser_bug655273.js @@ -0,0 +1,30 @@ +/* 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/. */ + +/** + * Test for Bug 655273. Make sure that after changing the URI via + * history.pushState, the resulting SHEntry has the same title as our old + * SHEntry. + **/ + +add_task(function* test() { + waitForExplicitFinish(); + + yield BrowserTestUtils.withNewTab({ gBrowser, url: "http://example.com" }, + function* (browser) { + yield ContentTask.spawn(browser, null, function* () { + let cw = content; + let oldTitle = cw.document.title; + ok(oldTitle, 'Content window should initially have a title.'); + cw.history.pushState('', '', 'new_page'); + + let shistory = cw.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .sessionHistory; + + is(shistory.getEntryAtIndex(shistory.index, false).title, + oldTitle, 'SHEntry title after pushstate.'); + }); + }); +}); diff --git a/system/docshell/test/browser/browser_bug670318.js b/system/docshell/test/browser/browser_bug670318.js new file mode 100644 index 000000000..a73639cab --- /dev/null +++ b/system/docshell/test/browser/browser_bug670318.js @@ -0,0 +1,70 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test for Bug 670318 + * + * When LoadEntry() is called on a browser that has multiple duplicate history + * entries, history.index can end up out of range (>= history.count). + */ + +const URL = "http://mochi.test:8888/browser/docshell/test/browser/file_bug670318.html"; + +add_task(function* test() { + yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, + function* (browser) { + yield ContentTask.spawn(browser, URL, function* (URL) { + let history = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory; + let count = 0; + + let testDone = {}; + testDone.promise = new Promise(resolve => { testDone.resolve = resolve; }); + + let listener = { + OnHistoryNewEntry: function (aNewURI) { + if (aNewURI.spec == URL && 5 == ++count) { + addEventListener("load", function onLoad() { + removeEventListener("load", onLoad, true); + + Assert.ok(history.index < history.count, "history.index is valid"); + testDone.resolve(); + }, true); + + history.removeSHistoryListener(listener); + delete content._testListener; + content.setTimeout(() => { content.location.reload(); }, 0); + } + + return true; + }, + + OnHistoryReload: () => true, + OnHistoryGoBack: () => true, + OnHistoryGoForward: () => true, + OnHistoryGotoIndex: () => true, + OnHistoryPurge: () => true, + OnHistoryReplaceEntry: () => { + // The initial load of about:blank causes a transient entry to be + // created, so our first navigation to a real page is a replace + // instead of a new entry. + ++count; + return true; + }, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsISHistoryListener, + Ci.nsISupportsWeakReference]) + }; + + history.addSHistoryListener(listener); + // Since listener implements nsISupportsWeakReference, we are + // responsible for keeping it alive so that the GC doesn't clear + // it before the test completes. We do this by anchoring the listener + // to the content global window, and clearing it just before the test + // completes. + content._testListener = listener; + content.location = URL; + + yield testDone.promise; + }); + }); +}); diff --git a/system/docshell/test/browser/browser_bug673467.js b/system/docshell/test/browser/browser_bug673467.js new file mode 100644 index 000000000..10139a48c --- /dev/null +++ b/system/docshell/test/browser/browser_bug673467.js @@ -0,0 +1,51 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Test for bug 673467. In a new tab, load a page which inserts a new iframe +// before the load and then sets its location during the load. This should +// create just one SHEntry. + +var doc = "data:text/html,<html><body onload='load()'>" + + "<script>" + + " var iframe = document.createElement('iframe');" + + " iframe.id = 'iframe';" + + " document.documentElement.appendChild(iframe);" + + " function load() {" + + " iframe.src = 'data:text/html,Hello!';" + + " }" + + "</script>" + + "</body></html>" + +function test() { + waitForExplicitFinish(); + + let tab = gBrowser.addTab(doc); + let tabBrowser = tab.linkedBrowser; + + BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => { + return ContentTask.spawn(tab.linkedBrowser, null, () => { + return new Promise(resolve => { + // The main page has loaded. Now wait for the iframe to load. + let iframe = content.document.getElementById('iframe'); + iframe.addEventListener('load', function listener(aEvent) { + + // Wait for the iframe to load the new document, not about:blank. + if (!iframe.src) + return; + + iframe.removeEventListener('load', listener, true); + let shistory = content + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .sessionHistory; + + Assert.equal(shistory.count, 1, "shistory count should be 1."); + resolve(); + }, true); + }); + }); + }).then(() => { + gBrowser.removeTab(tab); + finish(); + }); +} diff --git a/system/docshell/test/browser/browser_bug852909.js b/system/docshell/test/browser/browser_bug852909.js new file mode 100644 index 000000000..5e2374c43 --- /dev/null +++ b/system/docshell/test/browser/browser_bug852909.js @@ -0,0 +1,23 @@ +var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; + +function test() { + waitForExplicitFinish(); + + gBrowser.selectedTab = gBrowser.addTab(rootDir + "file_bug852909.png"); + BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(image); +} + +function image(event) { + ok(!gBrowser.selectedTab.mayEnableCharacterEncodingMenu, "Docshell should say the menu should be disabled for images."); + + gBrowser.removeCurrentTab(); + gBrowser.selectedTab = gBrowser.addTab(rootDir + "file_bug852909.pdf"); + BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(pdf); +} + +function pdf(event) { + ok(!gBrowser.selectedTab.mayEnableCharacterEncodingMenu, "Docshell should say the menu should be disabled for PDF.js."); + + gBrowser.removeCurrentTab(); + finish(); +} diff --git a/system/docshell/test/browser/browser_bug92473.js b/system/docshell/test/browser/browser_bug92473.js new file mode 100644 index 000000000..d1c4aebdb --- /dev/null +++ b/system/docshell/test/browser/browser_bug92473.js @@ -0,0 +1,54 @@ +/* The test text as octets for reference + * %83%86%83%6a%83%52%81%5b%83%68%82%cd%81%41%82%b7%82%d7%82%c4%82%cc%95%b6%8e%9a%82%c9%8c%c5%97%4c%82%cc%94%d4%8d%86%82%f0%95%74%97%5e%82%b5%82%dc%82%b7 + */ + +function testContent(text) { + return ContentTask.spawn(gBrowser.selectedBrowser, text, text => { + Assert.equal(content.document.getElementById("testpar").innerHTML, text, + "<p> contains expected text"); + Assert.equal(content.document.getElementById("testtextarea").innerHTML, text, + "<textarea> contains expected text"); + Assert.equal(content.document.getElementById("testinput").value, text, + "<input> contains expected text"); + }); +} + +function afterOpen() { + BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterChangeCharset); + + /* The test text decoded incorrectly as Windows-1251. This is the "right" wrong + text; anything else is unexpected. */ + const wrongText="\u0453\u2020\u0453\u006A\u0453\u0052\u0403\u005B\u0453\u0068\u201A\u041D\u0403\u0041\u201A\u00B7\u201A\u0427\u201A\u0414\u201A\u041C\u2022\u00B6\u040B\u0459\u201A\u0419\u040A\u0415\u2014\u004C\u201A\u041C\u201D\u0424\u040C\u2020\u201A\u0440\u2022\u0074\u2014\u005E\u201A\u00B5\u201A\u042C\u201A\u00B7"; + + /* Test that the content on load is the expected wrong decoding */ + testContent(wrongText).then(() => { + BrowserSetForcedCharacterSet("Shift_JIS"); + }); +} + +function afterChangeCharset() { + /* The test text decoded correctly as Shift_JIS */ + const rightText="\u30E6\u30CB\u30B3\u30FC\u30C9\u306F\u3001\u3059\u3079\u3066\u306E\u6587\u5B57\u306B\u56FA\u6709\u306E\u756A\u53F7\u3092\u4ED8\u4E0E\u3057\u307E\u3059"; + + /* test that the content is decoded correctly */ + testContent(rightText).then(() => { + gBrowser.removeCurrentTab(); + finish(); + }); +} + +function test() { + waitForExplicitFinish(); + + // Get the local directory. This needs to be a file: URI because chrome: URIs + // are always UTF-8 (bug 617339) and we are testing decoding from other + // charsets. + var jar = getJar(getRootDirectory(gTestPath)); + var dir = jar ? + extractJarToTmp(jar) : + getChromeDir(getResolvedURI(gTestPath)); + var rootDir = Services.io.newFileURI(dir).spec; + + gBrowser.selectedTab = gBrowser.addTab(rootDir + "test-form_sjis.html"); + BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterOpen); +} diff --git a/system/docshell/test/browser/browser_click_link_within_view_source.js b/system/docshell/test/browser/browser_click_link_within_view_source.js new file mode 100644 index 000000000..84cfc1f0f --- /dev/null +++ b/system/docshell/test/browser/browser_click_link_within_view_source.js @@ -0,0 +1,60 @@ +"use strict"; + +/** + * Test for Bug 1359204 + * + * Loading a local file, then view-source on that file. Make sure that + * clicking a link within that view-source page is not blocked by security checks. + */ + +add_task(function* test_click_link_within_view_source() { + let TEST_FILE = "file_click_link_within_view_source.html"; + let TEST_FILE_URI = getChromeDir(getResolvedURI(gTestPath)); + TEST_FILE_URI.append(TEST_FILE); + TEST_FILE_URI = Services.io.newFileURI(TEST_FILE_URI).spec; + + let DUMMY_FILE = "dummy_page.html"; + let DUMMY_FILE_URI = getChromeDir(getResolvedURI(gTestPath)); + DUMMY_FILE_URI.append(DUMMY_FILE); + DUMMY_FILE_URI = Services.io.newFileURI(DUMMY_FILE_URI).spec; + + yield BrowserTestUtils.withNewTab(TEST_FILE_URI, function*(aBrowser) { + let tabSpec = gBrowser.selectedBrowser.currentURI.spec; + info("loading: " + tabSpec); + ok(tabSpec.startsWith("file://") && tabSpec.endsWith(TEST_FILE), + "sanity check to make sure html loaded"); + + info("click view-source of html"); + let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser); + document.getElementById("View:PageSource").doCommand(); + + let tab = yield tabPromise; + tabSpec = gBrowser.selectedBrowser.currentURI.spec; + info("loading: " + tabSpec); + ok(tabSpec.startsWith("view-source:file://") && tabSpec.endsWith(TEST_FILE), + "loading view-source of html succeeded"); + + info("click testlink within view-source page"); + let loadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, url => url.endsWith("dummy_page.html")); + yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function*() { + if (content.document.readyState != "complete") { + yield ContentTaskUtils.waitForEvent(content.document, "readystatechange", false, () => + content.document.readyState == "complete"); + } + // document.getElementById() does not work on a view-source page, hence we use document.links + let linksOnPage = content.document.links; + is (linksOnPage.length, 1, "sanity check: make sure only one link is present on page"); + let myLink = content.document.links[0]; + myLink.click(); + }); + + yield loadPromise; + + tabSpec = gBrowser.selectedBrowser.currentURI.spec; + info("loading: " + tabSpec); + ok(tabSpec.startsWith("view-source:file://") && tabSpec.endsWith(DUMMY_FILE), + "loading view-source of html succeeded"); + + yield BrowserTestUtils.removeTab(tab); + }); +}); diff --git a/system/docshell/test/browser/browser_history_triggeringprincipal_viewsource.js b/system/docshell/test/browser/browser_history_triggeringprincipal_viewsource.js new file mode 100644 index 000000000..96908bbc2 --- /dev/null +++ b/system/docshell/test/browser/browser_history_triggeringprincipal_viewsource.js @@ -0,0 +1,50 @@ +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com"); +const HTML_URI = TEST_PATH + "dummy_page.html"; +const VIEW_SRC_URI = "view-source:" + HTML_URI; + +add_task(function*() { + info("load baseline html in new tab"); + yield BrowserTestUtils.withNewTab(HTML_URI, function*(aBrowser) { + is(gBrowser.selectedBrowser.currentURI.spec, HTML_URI, + "sanity check to make sure html loaded"); + + info("right-click -> view-source of html"); + let vSrcCtxtMenu = document.getElementById("contentAreaContextMenu"); + let popupPromise = BrowserTestUtils.waitForEvent(vSrcCtxtMenu, "popupshown"); + BrowserTestUtils.synthesizeMouseAtCenter("body", { type: "contextmenu", button: 2 }, aBrowser); + yield popupPromise; + let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, VIEW_SRC_URI); + let vSrcItem = vSrcCtxtMenu.getElementsByAttribute("id", "context-viewsource")[0]; + vSrcItem.click(); + vSrcCtxtMenu.hidePopup(); + let tab = yield tabPromise; + is(gBrowser.selectedBrowser.currentURI.spec, VIEW_SRC_URI, + "loading view-source of html succeeded"); + + info ("load html file again before going .back()"); + let loadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, HTML_URI); + yield ContentTask.spawn(tab.linkedBrowser, HTML_URI, HTML_URI => { + content.document.location = HTML_URI; + }); + yield loadPromise; + is(gBrowser.selectedBrowser.currentURI.spec, HTML_URI, + "loading html another time succeeded"); + + info("click .back() to view-source of html again and make sure the history entry has a triggeringPrincipal"); + let backCtxtMenu = document.getElementById("contentAreaContextMenu"); + popupPromise = BrowserTestUtils.waitForEvent(backCtxtMenu, "popupshown"); + BrowserTestUtils.synthesizeMouseAtCenter("body", { type: "contextmenu", button: 2 }, aBrowser); + yield popupPromise; + loadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, VIEW_SRC_URI); + let backItem = backCtxtMenu.getElementsByAttribute("id", "context-back")[0]; + backItem.click(); + backCtxtMenu.hidePopup(); + yield loadPromise; + is(gBrowser.selectedBrowser.currentURI.spec, VIEW_SRC_URI, + "clicking .back() to view-source of html succeeded"); + + yield BrowserTestUtils.removeTab(tab); + }); +}); diff --git a/system/docshell/test/browser/browser_loadDisallowInherit.js b/system/docshell/test/browser/browser_loadDisallowInherit.js new file mode 100644 index 000000000..71789890f --- /dev/null +++ b/system/docshell/test/browser/browser_loadDisallowInherit.js @@ -0,0 +1,65 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +function test() { + waitForExplicitFinish(); + + let tab = gBrowser.selectedTab = gBrowser.addTab(); + registerCleanupFunction(function () { + gBrowser.removeTab(tab); + }); + + let browser = gBrowser.getBrowserForTab(tab); + + function loadURL(url, flags, func) { + browser.addEventListener("load", function loadListener(e) { + if (browser.currentURI.spec != url) + return; + browser.removeEventListener(e.type, loadListener, true); + func(); + }, true); + browser.loadURIWithFlags(url, flags, null, null, null); + } + + // Load a normal http URL + function testURL(url, func) { + loadURL("http://example.com/", 0, function () { + let pagePrincipal = browser.contentPrincipal; + ok(pagePrincipal, "got principal for http:// page"); + + // Now load the URL normally + loadURL(url, 0, function () { + ok(browser.contentPrincipal.equals(pagePrincipal), url + " should inherit principal"); + + // Now load the URL and disallow inheriting the principal + let webNav = Components.interfaces.nsIWebNavigation; + loadURL(url, webNav.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL, function () { + let newPrincipal = browser.contentPrincipal; + ok(newPrincipal, "got inner principal"); + ok(!newPrincipal.equals(pagePrincipal), + url + " should not inherit principal when loaded with DISALLOW_INHERIT_OWNER"); + + func(); + }); + }); + }); + } + + let urls = [ + "data:text/html,<body>hi", + // We used to test javascript: here as well, but now that we no longer run + // javascript: in a sandbox, we end up not running it at all in the + // DISALLOW_INHERIT_OWNER case, so never actually do a load for it at all. + ]; + + function nextTest() { + let url = urls.shift(); + if (url) + testURL(url, nextTest); + else + finish(); + } + + nextTest(); +} + diff --git a/system/docshell/test/browser/browser_loadURI.js b/system/docshell/test/browser/browser_loadURI.js new file mode 100644 index 000000000..a68e1c2de --- /dev/null +++ b/system/docshell/test/browser/browser_loadURI.js @@ -0,0 +1,34 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +var Cc = Components.classes; +var Ci = Components.interfaces; + +const gPostData = "postdata=true"; + +function test() { + waitForExplicitFinish(); + + let tab = gBrowser.selectedTab = gBrowser.addTab(); + registerCleanupFunction(function () { + gBrowser.removeTab(tab); + }); + + var dataStream = Cc["@mozilla.org/io/string-input-stream;1"]. + createInstance(Ci.nsIStringInputStream); + dataStream.data = gPostData; + + var postStream = Cc["@mozilla.org/network/mime-input-stream;1"]. + createInstance(Ci.nsIMIMEInputStream); + postStream.addHeader("Content-Type", "application/x-www-form-urlencoded"); + postStream.addContentLength = true; + postStream.setData(dataStream); + + tab.linkedBrowser.loadURIWithFlags("http://mochi.test:8888/browser/docshell/test/browser/print_postdata.sjs", 0, null, null, postStream); + BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => { + ContentTask.spawn(tab.linkedBrowser, gPostData, function(postData) { + var bodyText = content.document.body.textContent; + is(bodyText, postData, "post data was submitted correctly"); + }).then(() => { finish(); }); + }); +} diff --git a/system/docshell/test/browser/browser_multiple_pushState.js b/system/docshell/test/browser/browser_multiple_pushState.js new file mode 100644 index 000000000..5c2f5aef4 --- /dev/null +++ b/system/docshell/test/browser/browser_multiple_pushState.js @@ -0,0 +1,15 @@ +add_task(function* test_multiple_pushState() { + yield BrowserTestUtils.withNewTab({ + gBrowser, + url: "http://example.org/browser/docshell/test/browser/file_multiple_pushState.html", + }, function* (browser) { + const kExpected = "http://example.org/bar/ABC/DEF?key=baz"; + + let contentLocation = yield ContentTask.spawn(browser, null, function* () { + return content.document.location.href; + }); + + is(contentLocation, kExpected); + is(browser.documentURI.spec, kExpected); + }); +}); diff --git a/system/docshell/test/browser/browser_onbeforeunload_navigation.js b/system/docshell/test/browser/browser_onbeforeunload_navigation.js new file mode 100644 index 000000000..d2feb69d4 --- /dev/null +++ b/system/docshell/test/browser/browser_onbeforeunload_navigation.js @@ -0,0 +1,176 @@ +var contentWindow; +var originalLocation; +var currentTest = -1; +var stayingOnPage = true; + +var TEST_PAGE = "http://mochi.test:8888/browser/docshell/test/browser/file_bug1046022.html"; +var TARGETED_PAGE = "data:text/html," + encodeURIComponent("<body>Shouldn't be seeing this</body>"); + +SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]}); + +var loadExpected = TEST_PAGE; +var testTab; +var testsLength; + +var loadStarted = false; +var tabStateListener = { + onStateChange: function(webprogress, request, stateFlags, status) { + let startDocumentFlags = Ci.nsIWebProgressListener.STATE_START | + Ci.nsIWebProgressListener.STATE_IS_DOCUMENT; + if ((stateFlags & startDocumentFlags) == startDocumentFlags) { + loadStarted = true; + } + }, + onStatusChange: () => {}, + onLocationChange: () => {}, + onSecurityChange: () => {}, + onProgressChange: () => {}, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener]) +}; + +function onTabLoaded(event) { + info("A document loaded in a tab!"); + let loadedPage = event.target.location.href; + if (loadedPage == "about:blank" || + event.originalTarget != testTab.linkedBrowser.contentDocument) { + return; + } + + if (!loadExpected) { + ok(false, "Expected no page loads, but loaded " + loadedPage + " instead!"); + return; + } + + if (!testsLength) { + testsLength = testTab.linkedBrowser.contentWindow.wrappedJSObject.testFns.length; + } + + is(loadedPage, loadExpected, "Loaded the expected page"); + if (contentWindow) { + is(contentWindow.document, event.target, "Same doc"); + } + if (onAfterPageLoad) { + onAfterPageLoad(); + } +} + +function onAfterTargetedPageLoad() { + ok(!stayingOnPage, "We should only fire if we're expecting to let the onbeforeunload dialog proceed to the new location"); + is(testTab.linkedBrowser.currentURI.spec, TARGETED_PAGE, "Should have loaded the expected new page"); + + runNextTest(); +} + +function onTabModalDialogLoaded(node) { + let content = testTab.linkedBrowser.contentWindow; + ok(!loadStarted, "No load should be started."); + info(content.location.href); + is(content, contentWindow, "Window should be the same still."); + is(content.location.href, originalLocation, "Page should not have changed."); + is(content.mySuperSpecialMark, 42, "Page should not have refreshed."); + + ok(!content.dialogWasInvoked, "Dialog should only be invoked once per test."); + content.dialogWasInvoked = true; + + + // Now listen for the dialog going away again... + let observer = new MutationObserver(function(muts) { + if (!node.parentNode) { + info("Dialog is gone"); + observer.disconnect(); + observer = null; + // If we're staying on the page, run the next test from here + if (stayingOnPage) { + // Evil, but necessary: without this delay, we manage to still break our + // own onbeforeunload code, because we'll basically cause a new load to be + // started while processing the destruction of the dialog for the old one. + executeSoon(runNextTest); + } + // if we accepted a page load in the dialog, the next test will get started + // by the load handler for that page loading + } + }); + observer.observe(node.parentNode, {childList: true}); + + // If we're going to let the page load, set us up to listen for that happening: + if (!stayingOnPage) { + loadExpected = TARGETED_PAGE; + onAfterPageLoad = onAfterTargetedPageLoad; + } + + let button = stayingOnPage ? node.ui.button1 : node.ui.button0; + // ... and then actually make the dialog go away + info("Clicking button: " + button.label); + EventUtils.synthesizeMouseAtCenter(button, {}); +} + +// Listen for the dialog being created +Services.obs.addObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded", false); + +function runNextTest() { + currentTest++; + if (currentTest >= testsLength) { + if (!stayingOnPage) { + finish(); + return; + } + // Run the same tests again, but this time let the navigation happen: + stayingOnPage = false; + // Remove onbeforeunload handler, or this load will trigger the dialog... + contentWindow.onbeforeunload = null; + currentTest = 0; + } + + + if (!stayingOnPage) { + // Right now we're on the data: page. Null contentWindow out to + // avoid CPOW errors when contentWindow is no longer the correct + // outer window proxy object. + contentWindow = null; + + onAfterPageLoad = runCurrentTest; + loadExpected = TEST_PAGE; + testTab.linkedBrowser.loadURI(TEST_PAGE); + } else { + runCurrentTest(); + } +} + +function runCurrentTest() { + // Reset things so we're sure the previous tests failings don't influence this one: + contentWindow = testTab.linkedBrowser.contentWindow; + contentWindow.mySuperSpecialMark = 42; + contentWindow.dialogWasInvoked = false; + originalLocation = contentWindow.location.href; + // And run this test: + info("Running test with onbeforeunload " + contentWindow.wrappedJSObject.testFns[currentTest].toSource()); + contentWindow.onbeforeunload = contentWindow.wrappedJSObject.testFns[currentTest]; + loadStarted = false; + testTab.linkedBrowser.loadURI(TARGETED_PAGE); +} + +var onAfterPageLoad = runNextTest; + +function test() { + waitForExplicitFinish(); + gBrowser.addProgressListener(tabStateListener); + + testTab = gBrowser.selectedTab = gBrowser.addTab(); + testTab.linkedBrowser.addEventListener("load", onTabLoaded, true); + testTab.linkedBrowser.loadURI(TEST_PAGE); +} + +registerCleanupFunction(function() { + // Remove the handler, or closing this tab will prove tricky: + if (contentWindow) { + try { + contentWindow.onbeforeunload = null; + } catch (ex) {} + } + contentWindow = null; + testTab.linkedBrowser.removeEventListener("load", onTabLoaded, true); + Services.obs.removeObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded"); + gBrowser.removeProgressListener(tabStateListener); + gBrowser.removeTab(testTab); +}); + diff --git a/system/docshell/test/browser/browser_search_notification.js b/system/docshell/test/browser/browser_search_notification.js new file mode 100644 index 000000000..b0a4571e5 --- /dev/null +++ b/system/docshell/test/browser/browser_search_notification.js @@ -0,0 +1,51 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +function test() { + waitForExplicitFinish(); + + const kSearchEngineID = "test_urifixup_search_engine"; + const kSearchEngineURL = "http://localhost/?search={searchTerms}"; + Services.search.addEngineWithDetails(kSearchEngineID, "", "", "", "get", + kSearchEngineURL); + + let oldDefaultEngine = Services.search.defaultEngine; + Services.search.defaultEngine = Services.search.getEngineByName(kSearchEngineID); + + let selectedName = Services.search.defaultEngine.name; + is(selectedName, kSearchEngineID, "Check fake search engine is selected"); + + registerCleanupFunction(function() { + if (oldDefaultEngine) { + Services.search.defaultEngine = oldDefaultEngine; + } + let engine = Services.search.getEngineByName(kSearchEngineID); + if (engine) { + Services.search.removeEngine(engine); + } + }); + + let tab = gBrowser.addTab(); + gBrowser.selectedTab = tab; + + function observer(subject, topic, data) { + Services.obs.removeObserver(observer, "keyword-search"); + is(topic, "keyword-search", "Got keyword-search notification"); + + let engine = Services.search.defaultEngine; + ok(engine, "Have default search engine."); + is(engine, subject, "Notification subject is engine."); + is("firefox health report", data, "Notification data is search term."); + + executeSoon(function cleanup() { + gBrowser.removeTab(tab); + finish(); + }); + } + + Services.obs.addObserver(observer, "keyword-search", false); + + gURLBar.value = "firefox health report"; + gURLBar.handleCommand(); +} + diff --git a/system/docshell/test/browser/browser_tab_touch_events.js b/system/docshell/test/browser/browser_tab_touch_events.js new file mode 100644 index 000000000..615983f61 --- /dev/null +++ b/system/docshell/test/browser/browser_tab_touch_events.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(function*() { + const URI = "data:text/html;charset=utf-8,<iframe id='test-iframe'></iframe>"; + + yield BrowserTestUtils.withNewTab({ gBrowser, url: URI }, function* (browser) { + yield ContentTask.spawn(browser, null, test_body); + }); +}); + +function* test_body() { + let docshell = docShell; + + is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_NONE, + "touchEventsOverride flag should be initially set to NONE"); + + docshell.touchEventsOverride = Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED; + is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED, + "touchEventsOverride flag should be changed to DISABLED"); + + let frameWin = content.document.querySelector("#test-iframe").contentWindow; + docshell = frameWin.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell); + is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED, + "touchEventsOverride flag should be passed on to frames."); + + let newFrame = content.document.createElement("iframe"); + content.document.body.appendChild(newFrame); + + let newFrameWin = newFrame.contentWindow; + docshell = newFrameWin.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell); + is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED, + "Newly created frames should use the new touchEventsOverride flag"); + + newFrameWin.location.reload(); + yield ContentTaskUtils.waitForEvent(newFrameWin, "load"); + + docshell = newFrameWin.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell); + is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED, + "New touchEventsOverride flag should persist across reloads"); +} diff --git a/system/docshell/test/browser/browser_timelineMarkers-01.js b/system/docshell/test/browser/browser_timelineMarkers-01.js new file mode 100644 index 000000000..59eeb57db --- /dev/null +++ b/system/docshell/test/browser/browser_timelineMarkers-01.js @@ -0,0 +1,32 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the docShell has the right profile timeline API + +const URL = "data:text/html;charset=utf-8,Test page"; + +add_task(function* () { + yield BrowserTestUtils.withNewTab({ gBrowser, url: URL }, + function* (browser) { + yield ContentTask.spawn(browser, null, function() { + ok("recordProfileTimelineMarkers" in docShell, + "The recordProfileTimelineMarkers attribute exists"); + ok("popProfileTimelineMarkers" in docShell, + "The popProfileTimelineMarkers function exists"); + ok(docShell.recordProfileTimelineMarkers === false, + "recordProfileTimelineMarkers is false by default"); + ok(docShell.popProfileTimelineMarkers().length === 0, + "There are no markers by default"); + + docShell.recordProfileTimelineMarkers = true; + ok(docShell.recordProfileTimelineMarkers === true, + "recordProfileTimelineMarkers can be set to true"); + + docShell.recordProfileTimelineMarkers = false; + ok(docShell.recordProfileTimelineMarkers === false, + "recordProfileTimelineMarkers can be set to false"); + }); + }); +}); diff --git a/system/docshell/test/browser/browser_timelineMarkers-02.js b/system/docshell/test/browser/browser_timelineMarkers-02.js new file mode 100644 index 000000000..34142760e --- /dev/null +++ b/system/docshell/test/browser/browser_timelineMarkers-02.js @@ -0,0 +1,15 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +var URL = '<!DOCTYPE html><style>' + + 'body {margin:0; padding: 0;} ' + + 'div {width:100px;height:100px;background:red;} ' + + '.resize-change-color {width:50px;height:50px;background:blue;} ' + + '.change-color {width:50px;height:50px;background:yellow;} ' + + '.add-class {}' + + '</style><div></div>'; +URL = "data:text/html;charset=utf8," + encodeURIComponent(URL); + +var test = makeTimelineTest("browser_timelineMarkers-frame-02.js", URL); diff --git a/system/docshell/test/browser/browser_timelineMarkers-03.js b/system/docshell/test/browser/browser_timelineMarkers-03.js new file mode 100644 index 000000000..b104367c1 --- /dev/null +++ b/system/docshell/test/browser/browser_timelineMarkers-03.js @@ -0,0 +1,8 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +var URL = "data:text/html;charset=utf-8,<p>Test page</p>"; + +var test = makeTimelineTest("browser_timelineMarkers-frame-03.js", URL); diff --git a/system/docshell/test/browser/browser_timelineMarkers-04.js b/system/docshell/test/browser/browser_timelineMarkers-04.js new file mode 100644 index 000000000..fdee867e7 --- /dev/null +++ b/system/docshell/test/browser/browser_timelineMarkers-04.js @@ -0,0 +1,8 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const URL = "http://mochi.test:8888/browser/docshell/test/browser/timelineMarkers-04.html"; + +var test = makeTimelineTest("browser_timelineMarkers-frame-04.js", URL); diff --git a/system/docshell/test/browser/browser_timelineMarkers-05.js b/system/docshell/test/browser/browser_timelineMarkers-05.js new file mode 100644 index 000000000..0130c58d9 --- /dev/null +++ b/system/docshell/test/browser/browser_timelineMarkers-05.js @@ -0,0 +1,15 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +var URL = '<!DOCTYPE html><style>' + + 'body {margin:0; padding: 0;} ' + + 'div {width:100px;height:100px;background:red;} ' + + '.resize-change-color {width:50px;height:50px;background:blue;} ' + + '.change-color {width:50px;height:50px;background:yellow;} ' + + '.add-class {}' + + '</style><div></div>'; +URL = "data:text/html;charset=utf8," + encodeURIComponent(URL); + +var test = makeTimelineTest("browser_timelineMarkers-frame-05.js", URL); diff --git a/system/docshell/test/browser/browser_timelineMarkers-frame-02.js b/system/docshell/test/browser/browser_timelineMarkers-frame-02.js new file mode 100644 index 000000000..83750395d --- /dev/null +++ b/system/docshell/test/browser/browser_timelineMarkers-frame-02.js @@ -0,0 +1,133 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the docShell profile timeline API returns the right markers when +// restyles, reflows and paints occur + +function rectangleContains(rect, x, y, width, height) { + return rect.x <= x && rect.y <= y && rect.width >= width && + rect.height >= height; +} + +function sanitizeMarkers(list) { + // These markers are currently gathered from all docshells, which may + // interfere with this test. + return list.filter(e => e.name != "Worker" && e.name != "MinorGC"); +} + +var TESTS = [{ + desc: "Changing the width of the test element", + searchFor: "Paint", + setup: function(docShell) { + let div = content.document.querySelector("div"); + div.setAttribute("class", "resize-change-color"); + }, + check: function(markers) { + markers = sanitizeMarkers(markers); + ok(markers.length > 0, "markers were returned"); + console.log(markers); + info(JSON.stringify(markers.filter(m => m.name == "Paint"))); + ok(markers.some(m => m.name == "Reflow"), "markers includes Reflow"); + ok(markers.some(m => m.name == "Paint"), "markers includes Paint"); + for (let marker of markers.filter(m => m.name == "Paint")) { + // This change should generate at least one rectangle. + ok(marker.rectangles.length >= 1, "marker has one rectangle"); + // One of the rectangles should contain the div. + ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 100, 100))); + } + ok(markers.some(m => m.name == "Styles"), "markers includes Restyle"); + } +}, { + desc: "Changing the test element's background color", + searchFor: "Paint", + setup: function(docShell) { + let div = content.document.querySelector("div"); + div.setAttribute("class", "change-color"); + }, + check: function(markers) { + markers = sanitizeMarkers(markers); + ok(markers.length > 0, "markers were returned"); + ok(!markers.some(m => m.name == "Reflow"), "markers doesn't include Reflow"); + ok(markers.some(m => m.name == "Paint"), "markers includes Paint"); + for (let marker of markers.filter(m => m.name == "Paint")) { + // This change should generate at least one rectangle. + ok(marker.rectangles.length >= 1, "marker has one rectangle"); + // One of the rectangles should contain the div. + ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 50, 50))); + } + ok(markers.some(m => m.name == "Styles"), "markers includes Restyle"); + } +}, { + desc: "Changing the test element's classname", + searchFor: "Paint", + setup: function(docShell) { + let div = content.document.querySelector("div"); + div.setAttribute("class", "change-color add-class"); + }, + check: function(markers) { + markers = sanitizeMarkers(markers); + ok(markers.length > 0, "markers were returned"); + ok(!markers.some(m => m.name == "Reflow"), "markers doesn't include Reflow"); + ok(!markers.some(m => m.name == "Paint"), "markers doesn't include Paint"); + ok(markers.some(m => m.name == "Styles"), "markers includes Restyle"); + } +}, { + desc: "sync console.time/timeEnd", + searchFor: "ConsoleTime", + setup: function(docShell) { + content.console.time("FOOBAR"); + content.console.timeEnd("FOOBAR"); + let markers = docShell.popProfileTimelineMarkers(); + is(markers.length, 1, "Got one marker"); + is(markers[0].name, "ConsoleTime", "Got ConsoleTime marker"); + is(markers[0].causeName, "FOOBAR", "Got ConsoleTime FOOBAR detail"); + content.console.time("FOO"); + content.setTimeout(() => { + content.console.time("BAR"); + content.setTimeout(() => { + content.console.timeEnd("FOO"); + content.console.timeEnd("BAR"); + }, 100); + }, 100); + }, + check: function(markers) { + markers = sanitizeMarkers(markers); + is(markers.length, 2, "Got 2 markers"); + is(markers[0].name, "ConsoleTime", "Got first ConsoleTime marker"); + is(markers[0].causeName, "FOO", "Got ConsoleTime FOO detail"); + is(markers[1].name, "ConsoleTime", "Got second ConsoleTime marker"); + is(markers[1].causeName, "BAR", "Got ConsoleTime BAR detail"); + } +}, { + desc: "Timestamps created by console.timeStamp()", + searchFor: "Timestamp", + setup: function(docshell) { + content.console.timeStamp("rock"); + let markers = docShell.popProfileTimelineMarkers(); + is(markers.length, 1, "Got one marker"); + is(markers[0].name, "TimeStamp", "Got Timestamp marker"); + is(markers[0].causeName, "rock", "Got Timestamp label value"); + content.console.timeStamp("paper"); + content.console.timeStamp("scissors"); + content.console.timeStamp(); + content.console.timeStamp(undefined); + }, + check: function (markers) { + markers = sanitizeMarkers(markers); + is(markers.length, 4, "Got 4 markers"); + is(markers[0].name, "TimeStamp", "Got Timestamp marker"); + is(markers[0].causeName, "paper", "Got Timestamp label value"); + is(markers[1].name, "TimeStamp", "Got Timestamp marker"); + is(markers[1].causeName, "scissors", "Got Timestamp label value"); + is(markers[2].name, "TimeStamp", "Got empty Timestamp marker when no argument given"); + is(markers[2].causeName, void 0, "Got empty Timestamp label value"); + is(markers[3].name, "TimeStamp", "Got empty Timestamp marker when argument is undefined"); + is(markers[3].causeName, void 0, "Got empty Timestamp label value"); + markers.forEach(m => is(m.end, m.start, + "All Timestamp markers should have identical start/end times")); + } +}]; + +timelineContentTest(TESTS); diff --git a/system/docshell/test/browser/browser_timelineMarkers-frame-03.js b/system/docshell/test/browser/browser_timelineMarkers-frame-03.js new file mode 100644 index 000000000..cf5f150ad --- /dev/null +++ b/system/docshell/test/browser/browser_timelineMarkers-frame-03.js @@ -0,0 +1,91 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the docShell profile timeline API returns the right +// markers for DOM events. + +var TESTS = [{ + desc: "Event dispatch with single handler", + searchFor: 'DOMEvent', + setup: function(docShell) { + content.document.body.addEventListener("dog", + function(e) { console.log("hi"); }, + true); + content.document.body.dispatchEvent(new content.Event("dog")); + }, + check: function(markers) { + markers = markers.filter(m => m.name == 'DOMEvent'); + is(markers.length, 1, "Got 1 marker"); + is(markers[0].type, "dog", "Got dog event name"); + is(markers[0].eventPhase, 2, "Got phase 2"); + } +}, { + desc: "Event dispatch with a second handler", + searchFor: function(markers) { + return markers.filter(m => m.name == 'DOMEvent').length >= 2; + }, + setup: function(docShell) { + content.document.body.addEventListener("dog", + function(e) { console.log("hi"); }, + false); + content.document.body.dispatchEvent(new content.Event("dog")); + }, + check: function(markers) { + markers = markers.filter(m => m.name == 'DOMEvent'); + is(markers.length, 2, "Got 2 markers"); + } +}, { + desc: "Event targeted at child", + searchFor: function(markers) { + return markers.filter(m => m.name == 'DOMEvent').length >= 2; + }, + setup: function(docShell) { + let child = content.document.body.firstElementChild; + child.addEventListener("dog", function(e) { }); + child.dispatchEvent(new content.Event("dog")); + }, + check: function(markers) { + markers = markers.filter(m => m.name == 'DOMEvent'); + is(markers.length, 2, "Got 2 markers"); + is(markers[0].eventPhase, 1, "Got phase 1 marker"); + is(markers[1].eventPhase, 2, "Got phase 2 marker"); + } +}, { + desc: "Event dispatch on a new document", + searchFor: function(markers) { + return markers.filter(m => m.name == 'DOMEvent').length >= 2; + }, + setup: function(docShell) { + let doc = content.document.implementation.createHTMLDocument("doc"); + let p = doc.createElement("p"); + p.innerHTML = "inside"; + doc.body.appendChild(p); + + p.addEventListener("zebra", function(e) {console.log("hi");}); + p.dispatchEvent(new content.Event("zebra")); + }, + check: function(markers) { + markers = markers.filter(m => m.name == 'DOMEvent'); + is(markers.length, 1, "Got 1 marker"); + } +}, { + desc: "Event dispatch on window", + searchFor: function(markers) { + return markers.filter(m => m.name == 'DOMEvent').length >= 2; + }, + setup: function(docShell) { + let doc = content.window.addEventListener("aardvark", function(e) { + console.log("I like ants!"); + }); + + content.window.dispatchEvent(new content.Event("aardvark")); + }, + check: function(markers) { + markers = markers.filter(m => m.name == 'DOMEvent'); + is(markers.length, 1, "Got 1 marker"); + } +}]; + +timelineContentTest(TESTS); diff --git a/system/docshell/test/browser/browser_timelineMarkers-frame-04.js b/system/docshell/test/browser/browser_timelineMarkers-frame-04.js new file mode 100644 index 000000000..427312993 --- /dev/null +++ b/system/docshell/test/browser/browser_timelineMarkers-frame-04.js @@ -0,0 +1,88 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the docShell profile timeline API returns the right +// markers for XMLHttpRequest events. + +var TESTS = [{ + desc: "Event dispatch from XMLHttpRequest", + searchFor: function(markers) { + return markers.filter(m => m.name == "DOMEvent").length >= 5; + }, + setup: function(docShell) { + content.dispatchEvent(new content.Event("dog")); + }, + check: function(markers) { + let domMarkers = markers.filter(m => m.name == "DOMEvent"); + // One subtlety here is that we have five events: the event we + // inject in "setup", plus the four state transition events. The + // first state transition is reported synchronously and so should + // show up as a nested marker. + is(domMarkers.length, 5, "Got 5 markers"); + + // We should see some Javascript markers, and they should have a + // cause. + let jsMarkers = markers.filter(m => m.name == "Javascript" && m.causeName); + ok(jsMarkers.length > 0, "Got some Javascript markers"); + is(jsMarkers[0].stack.functionDisplayName, "do_xhr", + "Javascript marker has entry point name"); + } +}]; + +if (Services.prefs.getBoolPref("javascript.options.asyncstack")) { + TESTS.push({ + desc: "Async stack trace on Javascript marker", + searchFor: (markers) => { + return markers.some(m => (m.name == "Javascript" && + m.causeName == "promise callback")); + }, + setup: function(docShell) { + content.dispatchEvent(new content.Event("promisetest")); + }, + check: function(markers) { + markers = markers.filter(m => (m.name == "Javascript" && + m.causeName == "promise callback")); + ok(markers.length > 0, "Found a Javascript marker"); + + let frame = markers[0].stack; + ok(frame.asyncParent !== null, "Parent frame has async parent"); + is(frame.asyncParent.asyncCause, "promise callback", + "Async parent has correct cause"); + let asyncFrame = frame.asyncParent; + // Skip over self-hosted parts of our Promise implementation. + while (asyncFrame.source === 'self-hosted') + asyncFrame = asyncFrame.parent; + is(asyncFrame.functionDisplayName, "do_promise", + "Async parent has correct function name"); + } + }, { + desc: "Async stack trace on Javascript marker with script", + searchFor: (markers) => { + return markers.some(m => (m.name == "Javascript" && + m.causeName == "promise callback")); + }, + setup: function(docShell) { + content.dispatchEvent(new content.Event("promisescript")); + }, + check: function(markers) { + markers = markers.filter(m => (m.name == "Javascript" && + m.causeName == "promise callback")); + ok(markers.length > 0, "Found a Javascript marker"); + + let frame = markers[0].stack; + ok(frame.asyncParent !== null, "Parent frame has async parent"); + is(frame.asyncParent.asyncCause, "promise callback", + "Async parent has correct cause"); + let asyncFrame = frame.asyncParent; + // Skip over self-hosted parts of our Promise implementation. + while (asyncFrame.source === 'self-hosted') + asyncFrame = asyncFrame.parent; + is(asyncFrame.functionDisplayName, "do_promise_script", + "Async parent has correct function name"); + } + }); +} + +timelineContentTest(TESTS); diff --git a/system/docshell/test/browser/browser_timelineMarkers-frame-05.js b/system/docshell/test/browser/browser_timelineMarkers-frame-05.js new file mode 100644 index 000000000..713f0e560 --- /dev/null +++ b/system/docshell/test/browser/browser_timelineMarkers-frame-05.js @@ -0,0 +1,117 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +function forceSyncReflow(div) { + div.setAttribute('class', 'resize-change-color'); + // Force a reflow. + return div.offsetWidth; +} + +function testSendingEvent() { + content.document.body.dispatchEvent(new content.Event("dog")); +} + +function testConsoleTime() { + content.console.time("cats"); +} + +function testConsoleTimeEnd() { + content.console.timeEnd("cats"); +} + +function makePromise() { + let resolver; + new Promise(function(resolve, reject) { + testConsoleTime(); + resolver = resolve; + }).then(function(val) { + testConsoleTimeEnd(); + }); + return resolver; +} + +function resolvePromise(resolver) { + resolver(23); +} + +var TESTS = [{ + desc: "Stack trace on sync reflow", + searchFor: "Reflow", + setup: function(docShell) { + let div = content.document.querySelector("div"); + forceSyncReflow(div); + }, + check: function(markers) { + markers = markers.filter(m => m.name == "Reflow"); + ok(markers.length > 0, "Reflow marker includes stack"); + ok(markers[0].stack.functionDisplayName == "forceSyncReflow"); + } +}, { + desc: "Stack trace on DOM event", + searchFor: "DOMEvent", + setup: function(docShell) { + content.document.body.addEventListener("dog", + function(e) { console.log("hi"); }, + true); + testSendingEvent(); + }, + check: function(markers) { + markers = markers.filter(m => m.name == "DOMEvent"); + ok(markers.length > 0, "DOMEvent marker includes stack"); + ok(markers[0].stack.functionDisplayName == "testSendingEvent", + "testSendingEvent is on the stack"); + } +}, { + desc: "Stack trace on console event", + searchFor: "ConsoleTime", + setup: function(docShell) { + testConsoleTime(); + testConsoleTimeEnd(); + }, + check: function(markers) { + markers = markers.filter(m => m.name == "ConsoleTime"); + ok(markers.length > 0, "ConsoleTime marker includes stack"); + ok(markers[0].stack.functionDisplayName == "testConsoleTime", + "testConsoleTime is on the stack"); + ok(markers[0].endStack.functionDisplayName == "testConsoleTimeEnd", + "testConsoleTimeEnd is on the stack"); + } +}]; + +if (Services.prefs.getBoolPref("javascript.options.asyncstack")) { + TESTS.push({ + desc: "Async stack trace on Promise", + searchFor: "ConsoleTime", + setup: function(docShell) { + let resolver = makePromise(); + resolvePromise(resolver); + }, + check: function(markers) { + markers = markers.filter(m => m.name == "ConsoleTime"); + ok(markers.length > 0, "Promise marker includes stack"); + ok(markers[0].stack.functionDisplayName == "testConsoleTime", + "testConsoleTime is on the stack"); + let frame = markers[0].endStack; + ok(frame.functionDisplayName == "testConsoleTimeEnd", + "testConsoleTimeEnd is on the stack"); + + frame = frame.parent; + ok(frame.functionDisplayName == "makePromise/<", + "makePromise/< is on the stack"); + let asyncFrame = frame.asyncParent; + ok(asyncFrame !== null, "Frame has async parent"); + is(asyncFrame.asyncCause, "promise callback", + "Async parent has correct cause"); + // Skip over self-hosted parts of our Promise implementation. + while (asyncFrame.source === 'self-hosted') { + asyncFrame = asyncFrame.parent; + } + is(asyncFrame.functionDisplayName, "makePromise", + "Async parent has correct function name"); + } + }); +} + +timelineContentTest(TESTS); diff --git a/system/docshell/test/browser/browser_ua_emulation.js b/system/docshell/test/browser/browser_ua_emulation.js new file mode 100644 index 000000000..94a602d4b --- /dev/null +++ b/system/docshell/test/browser/browser_ua_emulation.js @@ -0,0 +1,36 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const URL = "data:text/html;charset=utf-8,<iframe id='test-iframe'></iframe>"; + +// Test that the docShell UA emulation works +function* contentTask() { + let docshell = docShell; + is(docshell.customUserAgent, "", "There should initially be no customUserAgent"); + + docshell.customUserAgent = "foo"; + is(content.navigator.userAgent, "foo", "The user agent should be changed to foo"); + + let frameWin = content.document.querySelector("#test-iframe").contentWindow; + is(frameWin.navigator.userAgent, "foo", "The UA should be passed on to frames."); + + let newFrame = content.document.createElement("iframe"); + content.document.body.appendChild(newFrame); + + let newFrameWin = newFrame.contentWindow; + is(newFrameWin.navigator.userAgent, "foo", "Newly created frames should use the new UA"); + + newFrameWin.location.reload(); + yield ContentTaskUtils.waitForEvent(newFrameWin, "load"); + + is(newFrameWin.navigator.userAgent, "foo", "New UA should persist across reloads"); +} + +add_task(function* () { + yield BrowserTestUtils.withNewTab({ gBrowser, url: URL }, + function* (browser) { + yield ContentTask.spawn(browser, null, contentTask); + }); +}); diff --git a/system/docshell/test/browser/browser_uriFixupAlternateRedirects.js b/system/docshell/test/browser/browser_uriFixupAlternateRedirects.js new file mode 100644 index 000000000..f5a00a2df --- /dev/null +++ b/system/docshell/test/browser/browser_uriFixupAlternateRedirects.js @@ -0,0 +1,24 @@ +"use strict"; + +const REDIRECTURL = "http://www.example.com/browser/docshell/test/browser/redirect_to_example.sjs" + +add_task(function* () { + let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); + gURLBar.value = REDIRECTURL; + gURLBar.select(); + let errorPageLoaded = BrowserTestUtils.waitForErrorPage(tab.linkedBrowser); + EventUtils.sendKey("return"); + yield errorPageLoaded; + let [contentURL, originalURL] = yield ContentTask.spawn(tab.linkedBrowser, null, () => { + return [ + content.document.documentURI, + content.document.mozDocumentURIIfNotForErrorPages.spec, + ]; + }); + info("Page that loaded: " + contentURL); + ok(contentURL.startsWith("about:neterror?"), "Should be on an error page"); + originalURL = new URL(originalURL); + is(originalURL.host, "example", "Should be an error for http://example, not http://www.example.com/"); + + yield BrowserTestUtils.removeTab(tab); +}); diff --git a/system/docshell/test/browser/browser_uriFixupIntegration.js b/system/docshell/test/browser/browser_uriFixupIntegration.js new file mode 100644 index 000000000..e041e1f67 --- /dev/null +++ b/system/docshell/test/browser/browser_uriFixupIntegration.js @@ -0,0 +1,51 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const kSearchEngineID = "browser_urifixup_search_engine"; +const kSearchEngineURL = "http://example.com/?search={searchTerms}"; + +add_task(function* setup() { + // Add a new fake search engine. + Services.search.addEngineWithDetails(kSearchEngineID, "", "", "", "get", + kSearchEngineURL); + + let oldDefaultEngine = Services.search.defaultEngine; + Services.search.defaultEngine = Services.search.getEngineByName(kSearchEngineID); + + // Remove the fake engine when done. + registerCleanupFunction(() => { + if (oldDefaultEngine) { + Services.search.defaultEngine = oldDefaultEngine; + } + + let engine = Services.search.getEngineByName(kSearchEngineID); + if (engine) { + Services.search.removeEngine(engine); + } + }); +}); + +add_task(function* test() { + for (let searchParams of ["foo bar", "brokenprotocol:somethingelse"]) { + // Add a new blank tab. + gBrowser.selectedTab = gBrowser.addTab("about:blank"); + yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + + // Enter search terms and start a search. + gURLBar.value = searchParams; + gURLBar.focus(); + EventUtils.synthesizeKey("VK_RETURN", {}); + yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + + // Check that we arrived at the correct URL. + let escapedParams = encodeURIComponent(searchParams).replace("%20", "+"); + let expectedURL = kSearchEngineURL.replace("{searchTerms}", escapedParams); + is(gBrowser.selectedBrowser.currentURI.spec, expectedURL, + "New tab should have loaded with expected url."); + + // Cleanup. + gBrowser.removeCurrentTab(); + } +}); diff --git a/system/docshell/test/browser/dummy_page.html b/system/docshell/test/browser/dummy_page.html new file mode 100644 index 000000000..59bf2a5f8 --- /dev/null +++ b/system/docshell/test/browser/dummy_page.html @@ -0,0 +1,6 @@ +<html> +<head> <meta charset="utf-8"> </head> + <body> + just a dummy html file + </body> +</html> diff --git a/system/docshell/test/browser/favicon_bug655270.ico b/system/docshell/test/browser/favicon_bug655270.ico Binary files differnew file mode 100644 index 000000000..d44438903 --- /dev/null +++ b/system/docshell/test/browser/favicon_bug655270.ico diff --git a/system/docshell/test/browser/file_bug1046022.html b/system/docshell/test/browser/file_bug1046022.html new file mode 100644 index 000000000..2de68cb43 --- /dev/null +++ b/system/docshell/test/browser/file_bug1046022.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Bug 1046022 - test navigating inside onbeforeunload</title> + </head> + <body> + Waiting for onbeforeunload to hit... + </body> + + <script> +var testFns = [ + function(e) { + e.target.location.href = 'otherpage-href-set.html'; + return "stop"; + }, + function(e) { + e.target.location.reload(); + return "stop"; + }, + function(e) { + e.target.location.replace('otherpage-location-replaced.html'); + return "stop"; + }, + function(e) { + var link = e.target.createElement('a'); + link.href = "otherpage.html"; + e.target.body.appendChild(link); + link.click(); + return "stop"; + }, + function(e) { + var link = e.target.createElement('a'); + link.href = "otherpage.html"; + link.setAttribute("target", "_blank"); + e.target.body.appendChild(link); + link.click(); + return "stop"; + }, + function(e) { + var link = e.target.createElement('a'); + link.href = e.target.location.href; + e.target.body.appendChild(link); + link.setAttribute("target", "somearbitrarywindow"); + link.click(); + return "stop"; + }, +]; + </script> +</html> diff --git a/system/docshell/test/browser/file_bug1206879.html b/system/docshell/test/browser/file_bug1206879.html new file mode 100644 index 000000000..5313902a9 --- /dev/null +++ b/system/docshell/test/browser/file_bug1206879.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> + <head> + <title>Test page for bug 1206879</title> + </head> + <body> + <iframe src="http://example.com/"></iframe> + </body> +</html> diff --git a/system/docshell/test/browser/file_bug234628-1-child.html b/system/docshell/test/browser/file_bug234628-1-child.html new file mode 100644 index 000000000..c36197ac4 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-1-child.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>No encoding declaration in parent or child</title> +</head> +<body> +<p>Euro sign if decoded as Windows-1252: </p> +<p>a with diaeresis if decoded as Windows-1252: </p> +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-1.html b/system/docshell/test/browser/file_bug234628-1.html new file mode 100644 index 000000000..11c523ccd --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-1.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>No encoding declaration in parent or child</title> +</head> +<body> +<h1>No encoding declaration in parent or child</h1> + +<p>Euro sign if decoded as Windows-1252: </p> +<p>a with diaeresis if decoded as Windows-1252: </p> + +<iframe src="file_bug234628-1-child.html"></iframe> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-10-child.xhtml b/system/docshell/test/browser/file_bug234628-10-child.xhtml new file mode 100644 index 000000000..cccf6f2bc --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-10-child.xhtml @@ -0,0 +1,4 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title>XML child with no encoding declaration</title></head> +<body><p>Euro sign if decoded as UTF-8: €</p></body> +</html> diff --git a/system/docshell/test/browser/file_bug234628-10.html b/system/docshell/test/browser/file_bug234628-10.html new file mode 100644 index 000000000..78b8f0035 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-10.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>No encoding declaration in HTML parent or XHTML child</title> +</head> +<body> +<h1>No encoding declaration in HTML parent or XHTML child</h1> + +<p>Euro sign if decoded as Windows-1252: </p> +<p>a with diaeresis if decoded as Windows-1252: </p> + +<iframe src="file_bug234628-10-child.xhtml"></iframe> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-11-child.xhtml b/system/docshell/test/browser/file_bug234628-11-child.xhtml new file mode 100644 index 000000000..11ef668b0 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-11-child.xhtml @@ -0,0 +1,4 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title>No encoding declaration in HTML parent and HTTP declaration in XHTML child</title></head> +<body><p>Euro sign if decoded as UTF-8: €</p></body> +</html> diff --git a/system/docshell/test/browser/file_bug234628-11-child.xhtml^headers^ b/system/docshell/test/browser/file_bug234628-11-child.xhtml^headers^ new file mode 100644 index 000000000..30fb30405 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-11-child.xhtml^headers^ @@ -0,0 +1 @@ +Content-Type: application/xhtml+xml; charset=utf-8 diff --git a/system/docshell/test/browser/file_bug234628-11.html b/system/docshell/test/browser/file_bug234628-11.html new file mode 100644 index 000000000..21c5b733e --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-11.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>No encoding declaration in HTML parent and HTTP declaration in XHTML child</title> +</head> +<body> +<h1>No encoding declaration in HTML parent and HTTP declaration in XHTML child</h1> + +<p>Euro sign if decoded as Windows-1252: </p> +<p>a with diaeresis if decoded as Windows-1252: </p> + +<iframe src="file_bug234628-11-child.xhtml"></iframe> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-2-child.html b/system/docshell/test/browser/file_bug234628-2-child.html new file mode 100644 index 000000000..0acd2e0b2 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-2-child.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>No encoding declaration in parent or child</title> +</head> +<body> +<p>Euro sign if decoded as UTF-8: €</p> +<p>a with diaeresis if decoded as UTF-8: ä</p> +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-2.html b/system/docshell/test/browser/file_bug234628-2.html new file mode 100644 index 000000000..a87d29e12 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-2.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>No encoding declaration in parent or child</title> +</head> +<body> +<h1>No encoding declaration in parent or child</h1> + +<p>Euro sign if decoded as Windows-1252: </p> +<p>a with diaeresis if decoded as Windows-1252: </p> + +<iframe src="file_bug234628-2-child.html"></iframe> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-3-child.html b/system/docshell/test/browser/file_bug234628-3-child.html new file mode 100644 index 000000000..a6ad83231 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-3-child.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>meta declaration in parent and child</title> +</head> +<body> +<p>Euro sign if decoded as UTF-8: €</p> +<p>a with diaeresis if decoded as UTF-8: ä</p> +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-3.html b/system/docshell/test/browser/file_bug234628-3.html new file mode 100644 index 000000000..8caab6040 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-3.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="windows-1252"> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>meta declaration in parent and child</title> +</head> +<body> +<h1>meta declaration in parent and child</h1> + +<p>Euro sign if decoded as Windows-1252: </p> +<p>a with diaeresis if decoded as Windows-1252: </p> + +<iframe src="file_bug234628-3-child.html"></iframe> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-4-child.html b/system/docshell/test/browser/file_bug234628-4-child.html new file mode 100644 index 000000000..f0e7c2c05 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-4-child.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>meta declaration in parent and BOM in child</title> +</head> +<body> +<p>Euro sign if decoded as UTF-8: €</p> +<p>a with diaeresis if decoded as UTF-8: ä</p> +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-4.html b/system/docshell/test/browser/file_bug234628-4.html new file mode 100644 index 000000000..013757901 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-4.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="windows-1252"> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>meta declaration in parent and BOM in child</title> +</head> +<body> +<h1>meta declaration in parent and BOM in child</h1> + +<p>Euro sign if decoded as Windows-1252: </p> +<p>a with diaeresis if decoded as Windows-1252: </p> + +<iframe src="file_bug234628-4-child.html"></iframe> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-5-child.html b/system/docshell/test/browser/file_bug234628-5-child.html Binary files differnew file mode 100644 index 000000000..a650552f6 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-5-child.html diff --git a/system/docshell/test/browser/file_bug234628-5.html b/system/docshell/test/browser/file_bug234628-5.html new file mode 100644 index 000000000..987e6420b --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-5.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="windows-1252"> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>meta declaration in parent and UTF-16 BOM in child</title> +</head> +<body> +<h1>meta declaration in parent and UTF-16 BOM in child</h1> + +<p>Euro sign if decoded as Windows-1252: </p> +<p>a with diaeresis if decoded as Windows-1252: </p> + +<iframe src="file_bug234628-5-child.html"></iframe> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-6-child.html b/system/docshell/test/browser/file_bug234628-6-child.html Binary files differnew file mode 100644 index 000000000..52c37f259 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-6-child.html diff --git a/system/docshell/test/browser/file_bug234628-6-child.html^headers^ b/system/docshell/test/browser/file_bug234628-6-child.html^headers^ new file mode 100644 index 000000000..bfdcf487f --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-6-child.html^headers^ @@ -0,0 +1 @@ +Content-Type: text/html; charset=utf-16be diff --git a/system/docshell/test/browser/file_bug234628-6.html b/system/docshell/test/browser/file_bug234628-6.html new file mode 100644 index 000000000..9d7fc580c --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-6.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="windows-1252"> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>meta declaration in parent and BOMless UTF-16 with HTTP charset in child</title> +</head> +<body> +<h1>meta declaration in parent and BOMless UTF-16 with HTTP charset in child</h1> + +<p>Euro sign if decoded as Windows-1252: </p> +<p>a with diaeresis if decoded as Windows-1252: </p> + +<iframe src="file_bug234628-6-child.html"></iframe> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-7-child.html b/system/docshell/test/browser/file_bug234628-7-child.html new file mode 100644 index 000000000..c761ace10 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-7-child.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>meta declaration in parent and BOMless UTF-8 with HTTP charset in child</title> +</head> +<body> +<p>Euro sign if decoded as UTF-8: €</p> +<p>a with diaeresis if decoded as UTF-8: ä</p> +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-7-child.html^headers^ b/system/docshell/test/browser/file_bug234628-7-child.html^headers^ new file mode 100644 index 000000000..2d1c08b9e --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-7-child.html^headers^ @@ -0,0 +1 @@ +Content-Type: text/html; charset=utf-8 diff --git a/system/docshell/test/browser/file_bug234628-7.html b/system/docshell/test/browser/file_bug234628-7.html new file mode 100644 index 000000000..7cb506096 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-7.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="windows-1252"> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>meta declaration in parent and BOMless UTF-8 with HTTP charset in child</title> +</head> +<body> +<h1>meta declaration in parent and BOMless UTF-8 with HTTP charset in child</h1> + +<p>Euro sign if decoded as Windows-1252: </p> +<p>a with diaeresis if decoded as Windows-1252: </p> + +<iframe src="file_bug234628-7-child.html"></iframe> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-8-child.html b/system/docshell/test/browser/file_bug234628-8-child.html new file mode 100644 index 000000000..254e0fb2b --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-8-child.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>meta declaration in parent and no declaration in child</title> +</head> +<body> +<p>Capital dje if decoded as Windows-1251: </p> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-8.html b/system/docshell/test/browser/file_bug234628-8.html new file mode 100644 index 000000000..b44e91801 --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-8.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="windows-1251"> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>meta declaration in parent and no declaration in child</title> +</head> +<body> +<h1>meta declaration in parent and no declaration in child</h1> + +<p>Capital dje if decoded as Windows-1251: </p> + +<iframe src="file_bug234628-8-child.html"></iframe> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-9-child.html b/system/docshell/test/browser/file_bug234628-9-child.html new file mode 100644 index 000000000..a86b14d7e --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-9-child.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta content="width=device-width, initial-scale=1" name="viewport"> +<title>UTF-16 with BOM in parent and no declaration in child</title> +</head> +<body> +<p>Euro sign if decoded as Windows-1251: </p> + +</body> +</html> + diff --git a/system/docshell/test/browser/file_bug234628-9.html b/system/docshell/test/browser/file_bug234628-9.html Binary files differnew file mode 100644 index 000000000..8a469da3a --- /dev/null +++ b/system/docshell/test/browser/file_bug234628-9.html diff --git a/system/docshell/test/browser/file_bug420605.html b/system/docshell/test/browser/file_bug420605.html new file mode 100644 index 000000000..8424b92f8 --- /dev/null +++ b/system/docshell/test/browser/file_bug420605.html @@ -0,0 +1,31 @@ +<head> +<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="/> + <title>Page Title for Bug 420605</title> +</head> +<body> + <h1>Fragment links</h1> + + <p>This page has a bunch of fragment links to sections below:</p> + + <ul> + <li><a id="firefox-link" href="#firefox">Firefox</a></li> + <li><a id="thunderbird-link" href="#thunderbird">Thunderbird</a></li> + <li><a id="seamonkey-link" href="#seamonkey">Seamonkey</a></li> + </ul> + + <p>And here are the sections:</p> + + <h2 id="firefox">Firefox</h2> + + <p>Firefox is a browser.</p> + + <h2 id="thunderbird">Thunderbird</h2> + + <p>Thunderbird is an email client</p> + + <h2 id="seamonkey">Seamonkey</h2> + + <p>Seamonkey is the all-in-one application.</p> + +</body> +</html> diff --git a/system/docshell/test/browser/file_bug422543_script.js b/system/docshell/test/browser/file_bug422543_script.js new file mode 100644 index 000000000..cd69df1ec --- /dev/null +++ b/system/docshell/test/browser/file_bug422543_script.js @@ -0,0 +1,98 @@ +const { utils: Cu, interfaces: Ci } = Components; +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +function SHistoryListener() { +} + +SHistoryListener.prototype = { + retval: true, + last: "initial", + + OnHistoryNewEntry: function (aNewURI) { + this.last = "newentry"; + }, + + OnHistoryGoBack: function (aBackURI) { + this.last = "goback"; + return this.retval; + }, + + OnHistoryGoForward: function (aForwardURI) { + this.last = "goforward"; + return this.retval; + }, + + OnHistoryGotoIndex: function (aIndex, aGotoURI) { + this.last = "gotoindex"; + return this.retval; + }, + + OnHistoryPurge: function (aNumEntries) { + this.last = "purge"; + return this.retval; + }, + + OnHistoryReload: function (aReloadURI, aReloadFlags) { + this.last = "reload"; + return this.retval; + }, + + OnHistoryReplaceEntry: function (aIndex) {}, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsISHistoryListener, + Ci.nsISupportsWeakReference]) +}; + +let testAPI = { + shistory: null, + listeners: [ new SHistoryListener(), + new SHistoryListener() ], + + init() { + this.shistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory; + for (let listener of this.listeners) { + this.shistory.addSHistoryListener(listener); + } + }, + + cleanup() { + for (let listener of this.listeners) { + this.shistory.removeSHistoryListener(listener); + } + this.shistory = null; + sendAsyncMessage("bug422543:cleanup:return", {}); + }, + + getListenerStatus() { + sendAsyncMessage("bug422543:getListenerStatus:return", + this.listeners.map(l => l.last)); + }, + + resetListeners() { + for (let listener of this.listeners) { + listener.last = "initial"; + } + + sendAsyncMessage("bug422543:resetListeners:return", {}); + }, + + notifyReload() { + let internal = this.shistory.QueryInterface(Ci.nsISHistoryInternal); + let rval = + internal.notifyOnHistoryReload(content.document.documentURIObject, 0); + sendAsyncMessage("bug422543:notifyReload:return", { rval }); + }, + + setRetval({ num, val }) { + this.listeners[num].retval = val; + sendAsyncMessage("bug422543:setRetval:return", {}); + }, +}; + +addMessageListener("bug422543:cleanup", () => { testAPI.cleanup(); }); +addMessageListener("bug422543:getListenerStatus", () => { testAPI.getListenerStatus(); }); +addMessageListener("bug422543:notifyReload", () => { testAPI.notifyReload(); }); +addMessageListener("bug422543:resetListeners", () => { testAPI.resetListeners(); }); +addMessageListener("bug422543:setRetval", (msg) => { testAPI.setRetval(msg.data); }); + +testAPI.init(); diff --git a/system/docshell/test/browser/file_bug503832.html b/system/docshell/test/browser/file_bug503832.html new file mode 100644 index 000000000..338631c8a --- /dev/null +++ b/system/docshell/test/browser/file_bug503832.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html> +<!-- +Test page for https://bugzilla.mozilla.org/show_bug.cgi?id=503832 +--> +<head> + <title>Page Title for Bug 503832</title> +</head> +<body> + <h1>Fragment links</h1> + + <p>This page has a bunch of fragment links to sections below:</p> + + <ul> + <li><a id="firefox-link" href="#firefox">Firefox</a></li> + <li><a id="thunderbird-link" href="#thunderbird">Thunderbird</a></li> + <li><a id="seamonkey-link" href="#seamonkey">Seamonkey</a></li> + </ul> + + <p>And here are the sections:</p> + + <h2 id="firefox">Firefox</h2> + + <p>Firefox is a browser.</p> + + <h2 id="thunderbird">Thunderbird</h2> + + <p>Thunderbird is an email client</p> + + <h2 id="seamonkey">Seamonkey</h2> + + <p>Seamonkey is the all-in-one application.</p> + +</body> +</html> diff --git a/system/docshell/test/browser/file_bug655270.html b/system/docshell/test/browser/file_bug655270.html new file mode 100644 index 000000000..0c08d982b --- /dev/null +++ b/system/docshell/test/browser/file_bug655270.html @@ -0,0 +1,11 @@ +<html> + +<head> + <link rel='icon' href='favicon_bug655270.ico'> +</head> + +<body> +Nothing to see here... +</body> + +</html> diff --git a/system/docshell/test/browser/file_bug670318.html b/system/docshell/test/browser/file_bug670318.html new file mode 100644 index 000000000..4cd9b454a --- /dev/null +++ b/system/docshell/test/browser/file_bug670318.html @@ -0,0 +1,23 @@ +<html><head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<script> +function load() { + function next() { + if (count < 5) + iframe.src = 'data:text/html;charset=utf-8,iframe ' + (++count); + } + + var count = 0; + var iframe = document.createElement('iframe'); + iframe.onload = function () { setTimeout(next, 0) }; + document.body.appendChild(iframe); + + setTimeout(next, 0); +} +</script> +</head> + +<body onload="load()"> +Testcase +</body> +</html> diff --git a/system/docshell/test/browser/file_bug852909.pdf b/system/docshell/test/browser/file_bug852909.pdf Binary files differnew file mode 100644 index 000000000..89066463f --- /dev/null +++ b/system/docshell/test/browser/file_bug852909.pdf diff --git a/system/docshell/test/browser/file_bug852909.png b/system/docshell/test/browser/file_bug852909.png Binary files differnew file mode 100644 index 000000000..c7510d388 --- /dev/null +++ b/system/docshell/test/browser/file_bug852909.png diff --git a/system/docshell/test/browser/file_click_link_within_view_source.html b/system/docshell/test/browser/file_click_link_within_view_source.html new file mode 100644 index 000000000..d78e4ba0f --- /dev/null +++ b/system/docshell/test/browser/file_click_link_within_view_source.html @@ -0,0 +1,6 @@ +<html> +<head> <meta charset="utf-8"> </head> + <body> + <a id="testlink" href="dummy_page.html">clickme</a> + </body> +</html> diff --git a/system/docshell/test/browser/file_multiple_pushState.html b/system/docshell/test/browser/file_multiple_pushState.html new file mode 100644 index 000000000..c58a1a71b --- /dev/null +++ b/system/docshell/test/browser/file_multiple_pushState.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Test multiple calls to history.pushState</title> + </head> + <body> + <h1>Ohai</h1> + </body> + <script type="text/javascript"> + window.history.pushState({}, "", "/bar/ABC?key=baz"); + window.history.pushState({}, "", "/bar/ABC/DEF?key=baz"); + </script> +</html> diff --git a/system/docshell/test/browser/frame-head.js b/system/docshell/test/browser/frame-head.js new file mode 100644 index 000000000..5cb3b1513 --- /dev/null +++ b/system/docshell/test/browser/frame-head.js @@ -0,0 +1,113 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Functions that are automatically loaded as frame scripts for +// timeline tests. + +var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; +var { Task } = Cu.import("resource://gre/modules/Task.jsm", {}); +var { Promise } = Cu.import('resource://gre/modules/Promise.jsm', {}); + +Cu.import("resource://gre/modules/Timer.jsm"); + +// Functions that look like mochitest functions but forward to the +// browser process. + +this.ok = function(value, message) { + sendAsyncMessage("browser:test:ok", { + value: !!value, + message: message}); +} + +this.is = function(v1, v2, message) { + ok(v1 == v2, message); +} + +this.info = function(message) { + sendAsyncMessage("browser:test:info", {message: message}); +} + +this.finish = function() { + sendAsyncMessage("browser:test:finish"); +} + +/* Start a task that runs some timeline tests in the ordinary way. + * + * @param array tests + * The tests to run. This is an array where each element + * is of the form { desc, searchFor, setup, check }. + * + * desc is the test description, a string. + * searchFor is a string or a function + * If a string, then when a marker with this name is + * found, marker-reading is stopped. + * If a function, then the accumulated marker array is + * passed to it, and marker reading stops when it returns + * true. + * setup is a function that takes the docshell as an argument. + * It should start the test. + * check is a function that takes an array of markers + * as an argument and checks the results of the test. + */ +this.timelineContentTest = function(tests) { + Task.spawn(function*() { + let docShell = content.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell); + + info("Start recording"); + docShell.recordProfileTimelineMarkers = true; + + for (let {desc, searchFor, setup, check} of tests) { + + info("Running test: " + desc); + + info("Flushing the previous markers if any"); + docShell.popProfileTimelineMarkers(); + + info("Running the test setup function"); + let onMarkers = timelineWaitForMarkers(docShell, searchFor); + setup(docShell); + info("Waiting for new markers on the docShell"); + let markers = yield onMarkers; + + // Cycle collection markers are non-deterministic, and none of these tests + // expect them to show up. + markers = markers.filter(m => m.name.indexOf("nsCycleCollector") === -1); + + info("Running the test check function"); + check(markers); + } + + info("Stop recording"); + docShell.recordProfileTimelineMarkers = false; + finish(); + }); +} + +function timelineWaitForMarkers(docshell, searchFor) { + if (typeof(searchFor) == "string") { + let searchForString = searchFor; + let f = function (markers) { + return markers.some(m => m.name == searchForString); + }; + searchFor = f; + } + + return new Promise(function(resolve, reject) { + let waitIterationCount = 0; + let maxWaitIterationCount = 10; // Wait for 2sec maximum + let markers = []; + + setTimeout(function timeoutHandler() { + let newMarkers = docshell.popProfileTimelineMarkers(); + markers = [...markers, ...newMarkers]; + if (searchFor(markers) || waitIterationCount > maxWaitIterationCount) { + resolve(markers); + } else { + setTimeout(timeoutHandler, 200); + waitIterationCount++; + } + }, 200); + }); +} diff --git a/system/docshell/test/browser/head.js b/system/docshell/test/browser/head.js new file mode 100644 index 000000000..24ca8f45b --- /dev/null +++ b/system/docshell/test/browser/head.js @@ -0,0 +1,99 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* Helper function for timeline tests. Returns an async task that is + * suitable for use as a particular timeline test. + * @param string frameScriptName + * Base name of the frame script file. + * @param string url + * URL to load. + */ +function makeTimelineTest(frameScriptName, url) { + info("in timelineTest"); + return Task.async(function*() { + info("in in timelineTest"); + waitForExplicitFinish(); + + yield timelineTestOpenUrl(url); + + const here = "chrome://mochitests/content/browser/docshell/test/browser/"; + + let mm = gBrowser.selectedBrowser.messageManager; + mm.loadFrameScript(here + "frame-head.js", false); + mm.loadFrameScript(here + frameScriptName, false); + + // Set up some listeners so that timeline tests running in the + // content process can forward their results to the main process. + mm.addMessageListener("browser:test:ok", function(message) { + ok(message.data.value, message.data.message); + }); + mm.addMessageListener("browser:test:info", function(message) { + info(message.data.message); + }); + mm.addMessageListener("browser:test:finish", function(ignore) { + gBrowser.removeCurrentTab(); + finish(); + }); + }); +} + +/* Open a URL for a timeline test. */ +function timelineTestOpenUrl(url) { + window.focus(); + + let tabSwitchPromise = new Promise((resolve, reject) => { + window.gBrowser.addEventListener("TabSwitchDone", function listener() { + window.gBrowser.removeEventListener("TabSwitchDone", listener); + resolve(); + }); + }); + + let loadPromise = new Promise(function(resolve, reject) { + let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url); + let linkedBrowser = tab.linkedBrowser; + + linkedBrowser.addEventListener("load", function onload() { + linkedBrowser.removeEventListener("load", onload, true); + resolve(tab); + }, true); + }); + + return Promise.all([tabSwitchPromise, loadPromise]).then(([_, tab]) => tab); +} + +/** + * Helper function for charset tests. It loads |url| in a new tab, + * runs |check1| in a ContentTask when the page is ready, switches the + * charset to |charset|, and then runs |check2| in a ContentTask when + * the page has finished reloading. + * + * |charset| and |check2| can be omitted, in which case the test + * finishes when |check1| completes. + */ +function runCharsetTest(url, check1, charset, check2) { + waitForExplicitFinish(); + + BrowserTestUtils.openNewForegroundTab(gBrowser, url, true).then(afterOpen); + + function afterOpen() { + if (charset) { + BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterChangeCharset); + + ContentTask.spawn(gBrowser.selectedBrowser, null, check1).then(() => { + BrowserSetForcedCharacterSet(charset); + }); + } else { + ContentTask.spawn(gBrowser.selectedBrowser, null, check1).then(() => { + gBrowser.removeCurrentTab(); + finish(); + }); + } + } + + function afterChangeCharset() { + ContentTask.spawn(gBrowser.selectedBrowser, null, check2).then(() => { + gBrowser.removeCurrentTab(); + finish(); + }); + } +} diff --git a/system/docshell/test/browser/print_postdata.sjs b/system/docshell/test/browser/print_postdata.sjs new file mode 100644 index 000000000..4175a2480 --- /dev/null +++ b/system/docshell/test/browser/print_postdata.sjs @@ -0,0 +1,22 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/plain", false); + if (request.method == "GET") { + response.write(request.queryString); + } else { + var body = new BinaryInputStream(request.bodyInputStream); + + var avail; + var bytes = []; + + while ((avail = body.available()) > 0) + Array.prototype.push.apply(bytes, body.readByteArray(avail)); + + var data = String.fromCharCode.apply(null, bytes); + response.bodyOutputStream.write(data, data.length); + } +} diff --git a/system/docshell/test/browser/redirect_to_example.sjs b/system/docshell/test/browser/redirect_to_example.sjs new file mode 100644 index 000000000..eef5e49f4 --- /dev/null +++ b/system/docshell/test/browser/redirect_to_example.sjs @@ -0,0 +1,4 @@ +function handleRequest(request, response) { + response.setStatusLine(request.httpVersion, 302, "Moved Permanently"); + response.setHeader("Location", "http://example"); +} diff --git a/system/docshell/test/browser/test-form_sjis.html b/system/docshell/test/browser/test-form_sjis.html new file mode 100644 index 000000000..91c375dee --- /dev/null +++ b/system/docshell/test/browser/test-form_sjis.html @@ -0,0 +1,24 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/REC-html401-19991224/strict.dtd"> +<html> + <head> + <meta http-equiv="content-type" content="text/html; charset=windows-1251"> + <title>Shift_JIS in body and text area</title> + </head> + <body> + <h1>Incorrect meta charset</h1> + <h2>This page is encoded in Shift_JIS, but has an incorrect meta charset + claiming that it is windows-1251</h2> + <p id="testpar">jR[h́AׂĂ̕ɌŗL̔ԍt^܂</p> + <form> + <p> + <textarea id="testtextarea" rows=6 cols=60>jR[h́AׂĂ̕ɌŗL̔ԍt^܂</textarea> + <input id="testinput" type="text" size=60 value="jR[h́AׂĂ̕ɌŗL̔ԍt^܂"> + </p> + </form> + <h2>Expected text on load:</h2> + <p>ѓ†ѓjѓRЃ[ѓh‚НЃA‚·‚Ч‚Д‚М•¶Ћљ‚ЙЊЕ—L‚М”ФЌ†‚р•t—^‚µ‚Ь‚·</p> + <h2>Expected text on resetting the encoding to Shift_JIS:</h2> + <p>ユニコードは、すべての文字に固有の番号を付与します</p> + </body> +</html> diff --git a/system/docshell/test/browser/timelineMarkers-04.html b/system/docshell/test/browser/timelineMarkers-04.html new file mode 100644 index 000000000..829998387 --- /dev/null +++ b/system/docshell/test/browser/timelineMarkers-04.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"></meta> + <title>markers test</title> +</head> +<body> + + <p>Test page</p> + + <script> + function do_xhr() { + const theURL = "timelineMarkers-04.html"; + + xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function() { + dump("ReadyState = " + xhr.readyState + "\n"); + }; + xhr.open("get", theURL, true); + xhr.send(); + } + + window.addEventListener("dog", do_xhr, true); + + function do_promise() { + new Promise(function(resolve, reject) { + console.time("Bob"); + window.setTimeout(function() { + resolve(23); + }, 10); + }).then(function (val) { + console.timeEnd("Bob"); + }); + } + + window.addEventListener("promisetest", do_promise, true); + + var globalResolver; + function do_promise_script() { + new Promise(function(resolve, reject) { + console.time("Bob"); + globalResolver = resolve; + window.setTimeout("globalResolver(23);", 10); + }).then(function (val) { + console.timeEnd("Bob"); + }); + } + + window.addEventListener("promisescript", do_promise_script, true); + + </script> + +</body> +</html> + diff --git a/system/docshell/test/bug123696-subframe.html b/system/docshell/test/bug123696-subframe.html new file mode 100644 index 000000000..136d0a184 --- /dev/null +++ b/system/docshell/test/bug123696-subframe.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> + <head> + <script> + function change() { + return "<html><body>change</body></html>"; + } + function change2() { + return "<html><body>change2</body></html>"; + } + </script> + </head> + <body> + <iframe src="javascript:parent.change()"></iframe> + </body> +</html> diff --git a/system/docshell/test/bug369814.jar b/system/docshell/test/bug369814.jar Binary files differnew file mode 100644 index 000000000..86b9c8c09 --- /dev/null +++ b/system/docshell/test/bug369814.jar diff --git a/system/docshell/test/bug369814.zip b/system/docshell/test/bug369814.zip Binary files differnew file mode 100644 index 000000000..ed8234dbc --- /dev/null +++ b/system/docshell/test/bug369814.zip diff --git a/system/docshell/test/bug404548-subframe.html b/system/docshell/test/bug404548-subframe.html new file mode 100644 index 000000000..0afd17544 --- /dev/null +++ b/system/docshell/test/bug404548-subframe.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> +<body onload="setTimeout(function() { window.location = "data:text/html,<body onload='window.opener.finishTest()'>" }, 10)"> +<iframe src="data:text/html,<body onpagehide='var p = window.parent.opener; var e = window.frameElement; e.parentNode.removeChild(e); if (e.parentNode == null && e.contentWindow == null) { p.firstRemoved = true; }'>"> +</iframe> +<iframe src="data:text/html,<body onpagehide='window.parent.opener.secondHidden = true;'>"> +</iframe> diff --git a/system/docshell/test/bug413310-post.sjs b/system/docshell/test/bug413310-post.sjs new file mode 100644 index 000000000..b8d85dd3c --- /dev/null +++ b/system/docshell/test/bug413310-post.sjs @@ -0,0 +1,7 @@ +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/html"); + response.write("<body onload='window.parent.onloadCount++'>" + + request.method + " " + + Date.now() + + "</body>"); +} diff --git a/system/docshell/test/bug413310-subframe.html b/system/docshell/test/bug413310-subframe.html new file mode 100644 index 000000000..bcff1886f --- /dev/null +++ b/system/docshell/test/bug413310-subframe.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> + <body onload="window.parent.onloadCount++"> + <form action="bug413310-post.sjs" method="POST"> + </form> + </body> +</html> diff --git a/system/docshell/test/bug529119-window.html b/system/docshell/test/bug529119-window.html new file mode 100644 index 000000000..f1908835a --- /dev/null +++ b/system/docshell/test/bug529119-window.html @@ -0,0 +1,7 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test bug 529119, sub-window</title> +<body onload="window.opener.windowLoaded();"> +</body> +</html> diff --git a/system/docshell/test/bug530396-noref.sjs b/system/docshell/test/bug530396-noref.sjs new file mode 100644 index 000000000..1ed5f7aa2 --- /dev/null +++ b/system/docshell/test/bug530396-noref.sjs @@ -0,0 +1,20 @@ +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/html"); + response.setHeader("Cache-Control", "no-cache"); + response.write("<body onload='"); + + if (!request.hasHeader('Referer')) { + response.write("window.parent.onloadCount++;"); + } + + if (request.queryString == "newwindow") { + response.write("if (window.opener) { window.opener.parent.onloadCount++; window.opener.parent.doNextStep(); }"); + response.write("if (!window.opener) window.close();"); + response.write("'>"); + } else { + response.write("window.parent.doNextStep();'>"); + } + + response.write(request.method + " " + Date.now()); + response.write("</body>"); +} diff --git a/system/docshell/test/bug530396-subframe.html b/system/docshell/test/bug530396-subframe.html new file mode 100644 index 000000000..be81b9f14 --- /dev/null +++ b/system/docshell/test/bug530396-subframe.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> + <body onload="window.parent.onloadCount++"> + <a href="bug530396-noref.sjs" rel="noreferrer foo" id="target1">bug530396-noref.sjs</a> + <a href="bug530396-noref.sjs?newwindow" rel="nofollow noreferrer" id="target2" target="newwindow">bug530396-noref.sjs with new window</a> + </body> +</html> diff --git a/system/docshell/test/bug570341_recordevents.html b/system/docshell/test/bug570341_recordevents.html new file mode 100644 index 000000000..51fc1cd76 --- /dev/null +++ b/system/docshell/test/bug570341_recordevents.html @@ -0,0 +1,21 @@ +<html> +<head> +<script> + var start = Date.now(); + window._testing_js_start = Date.now(); + window['_testing_js_after_' + document.readyState] = start; + document.addEventListener('DOMContentLoaded', + function () { + window._testing_evt_DOMContentLoaded = Date.now(); + }, true); + document.addEventListener('readystatechange', function(){ + window['_testing_evt_DOM_' + document.readyState] = Date.now(); + }, true); + function recordLoad() { + window._testing_evt_load = Date.now(); + } +</script> +</head> +<body onload="recordLoad()">This document collects time +for events related to the page load progress.</body> +</html> diff --git a/system/docshell/test/bug668513_redirect.html b/system/docshell/test/bug668513_redirect.html new file mode 100644 index 000000000..1b8f66c63 --- /dev/null +++ b/system/docshell/test/bug668513_redirect.html @@ -0,0 +1 @@ +<html><body>This document is redirected to a blank document.</body></html> diff --git a/system/docshell/test/bug668513_redirect.html^headers^ b/system/docshell/test/bug668513_redirect.html^headers^ new file mode 100644 index 000000000..0e785833c --- /dev/null +++ b/system/docshell/test/bug668513_redirect.html^headers^ @@ -0,0 +1,2 @@ +HTTP 302 Moved Temporarily +Location: navigation/blank.html diff --git a/system/docshell/test/bug691547_frame.html b/system/docshell/test/bug691547_frame.html new file mode 100644 index 000000000..00172f711 --- /dev/null +++ b/system/docshell/test/bug691547_frame.html @@ -0,0 +1,12 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=691547 +--> +<head> + <title>Test for Bug 691547</title> +</head> +<body> +<iframe style="width:95%"></iframe> +</body> +</html> diff --git a/system/docshell/test/chrome/112564_nocache.html b/system/docshell/test/chrome/112564_nocache.html new file mode 100644 index 000000000..29fb990b8 --- /dev/null +++ b/system/docshell/test/chrome/112564_nocache.html @@ -0,0 +1,10 @@ +<html> +<head> +<title>test1</title> +</head> +<body> +<p> +This document will be sent with a no-cache cache-control header. When sent over a secure connection, it should not be stored in bfcache. +</p> +</body> +</html> diff --git a/system/docshell/test/chrome/112564_nocache.html^headers^ b/system/docshell/test/chrome/112564_nocache.html^headers^ new file mode 100644 index 000000000..c829a41ae --- /dev/null +++ b/system/docshell/test/chrome/112564_nocache.html^headers^ @@ -0,0 +1 @@ +Cache-control: no-cache diff --git a/system/docshell/test/chrome/215405_nocache.html b/system/docshell/test/chrome/215405_nocache.html new file mode 100644 index 000000000..c7d48c4eb --- /dev/null +++ b/system/docshell/test/chrome/215405_nocache.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html style="height: 100%"> +<head> + <title>test1</title> +</head> +<body style="height: 100%"> + <input type="text" id="inp" value=""> + </input> + <div style="height: 50%">Some text</div> + <div style="height: 50%">Some text</div> + <div style="height: 50%">Some text</div> + <div style="height: 50%; width: 300%">Some more text</div> +</body> +</html> diff --git a/system/docshell/test/chrome/215405_nocache.html^headers^ b/system/docshell/test/chrome/215405_nocache.html^headers^ new file mode 100644 index 000000000..c829a41ae --- /dev/null +++ b/system/docshell/test/chrome/215405_nocache.html^headers^ @@ -0,0 +1 @@ +Cache-control: no-cache diff --git a/system/docshell/test/chrome/215405_nostore.html b/system/docshell/test/chrome/215405_nostore.html new file mode 100644 index 000000000..4f5bd0f4f --- /dev/null +++ b/system/docshell/test/chrome/215405_nostore.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html style="height: 100%"> +<head> + <title>test1</title> +</head> +<body style="height: 100%"> + <input type="text" id="inp" value=""> + </input> + <div style="height: 50%">Some text</div> + <div style="height: 50%">Some text</div> + <div style="height: 50%">Some text</div> + <div style="height: 50%; width: 350%">Some more text</div> +</body> +</html> diff --git a/system/docshell/test/chrome/215405_nostore.html^headers^ b/system/docshell/test/chrome/215405_nostore.html^headers^ new file mode 100644 index 000000000..59ba29610 --- /dev/null +++ b/system/docshell/test/chrome/215405_nostore.html^headers^ @@ -0,0 +1 @@ +Cache-control: no-store diff --git a/system/docshell/test/chrome/582176_dummy.html b/system/docshell/test/chrome/582176_dummy.html new file mode 100644 index 000000000..3b18e512d --- /dev/null +++ b/system/docshell/test/chrome/582176_dummy.html @@ -0,0 +1 @@ +hello world diff --git a/system/docshell/test/chrome/582176_xml.xml b/system/docshell/test/chrome/582176_xml.xml new file mode 100644 index 000000000..d3dd576df --- /dev/null +++ b/system/docshell/test/chrome/582176_xml.xml @@ -0,0 +1,2 @@ +<?xml-stylesheet type="text/xsl" href="582176_xslt.xsl"?> +<out/> diff --git a/system/docshell/test/chrome/582176_xslt.xsl b/system/docshell/test/chrome/582176_xslt.xsl new file mode 100644 index 000000000..595741689 --- /dev/null +++ b/system/docshell/test/chrome/582176_xslt.xsl @@ -0,0 +1,8 @@ +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + <xsl:template match="out"> + <html> + <head><title>XSLT result doc</title></head> + <body><p>xslt result</p></body> + </html> + </xsl:template> +</xsl:stylesheet> diff --git a/system/docshell/test/chrome/662200a.html b/system/docshell/test/chrome/662200a.html new file mode 100644 index 000000000..0b9ead6f3 --- /dev/null +++ b/system/docshell/test/chrome/662200a.html @@ -0,0 +1,8 @@ +<html> + <head> + <title>A</title> + </head> + <body> + <a id="link" href="662200b.html">Next</a> + </body> +</html> diff --git a/system/docshell/test/chrome/662200b.html b/system/docshell/test/chrome/662200b.html new file mode 100644 index 000000000..91e6b971d --- /dev/null +++ b/system/docshell/test/chrome/662200b.html @@ -0,0 +1,8 @@ +<html> + <head> + <title>B</title> + </head> + <body> + <a id="link" href="662200c.html">Next</a> + </body> +</html> diff --git a/system/docshell/test/chrome/662200c.html b/system/docshell/test/chrome/662200c.html new file mode 100644 index 000000000..bc00e6b14 --- /dev/null +++ b/system/docshell/test/chrome/662200c.html @@ -0,0 +1,7 @@ +<html> + <head> + <title>C</title> + </head> + <body> + </body> +</html> diff --git a/system/docshell/test/chrome/89419.html b/system/docshell/test/chrome/89419.html new file mode 100644 index 000000000..b36b8d788 --- /dev/null +++ b/system/docshell/test/chrome/89419.html @@ -0,0 +1,7 @@ +<html> +<head> +<title>Bug 89419</title> +</head> +<body> +<img src="http://mochi.test:8888/tests/docshell/test/chrome/bug89419.sjs"> +</body> diff --git a/system/docshell/test/chrome/92598_nostore.html b/system/docshell/test/chrome/92598_nostore.html new file mode 100644 index 000000000..47bb90441 --- /dev/null +++ b/system/docshell/test/chrome/92598_nostore.html @@ -0,0 +1,10 @@ +<html> +<head> +<title>test1</title> +</head> +<body> +<p> +This document will be sent with a no-store cache-control header. It should not be stored in bfcache. +</p> +</body> +</html> diff --git a/system/docshell/test/chrome/92598_nostore.html^headers^ b/system/docshell/test/chrome/92598_nostore.html^headers^ new file mode 100644 index 000000000..59ba29610 --- /dev/null +++ b/system/docshell/test/chrome/92598_nostore.html^headers^ @@ -0,0 +1 @@ +Cache-control: no-store diff --git a/system/docshell/test/chrome/allowContentRetargeting.sjs b/system/docshell/test/chrome/allowContentRetargeting.sjs new file mode 100644 index 000000000..96e467ef6 --- /dev/null +++ b/system/docshell/test/chrome/allowContentRetargeting.sjs @@ -0,0 +1,7 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function handleRequest(req, resp) { + resp.setHeader("Content-Type", "application/octet-stream", false); + resp.write("hi"); +} diff --git a/system/docshell/test/chrome/blue.png b/system/docshell/test/chrome/blue.png Binary files differnew file mode 100644 index 000000000..8df58f3a5 --- /dev/null +++ b/system/docshell/test/chrome/blue.png diff --git a/system/docshell/test/chrome/bug112564_window.xul b/system/docshell/test/chrome/bug112564_window.xul new file mode 100644 index 000000000..e9c05ca9f --- /dev/null +++ b/system/docshell/test/chrome/bug112564_window.xul @@ -0,0 +1,117 @@ +<?xml version="1.0"?> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="112564Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="onLoad();" + title="112564 test"> + + <script type="application/javascript"><![CDATA[ + const LISTEN_EVENTS = ["load", "unload", "pageshow", "pagehide"]; + + var gBrowser; + var gTestsIterator; + var gExpected = []; + + function ok(condition, message) { + window.opener.wrappedJSObject.SimpleTest.ok(condition, message); + } + + function is(a, b, message) { + window.opener.wrappedJSObject.SimpleTest.is(a, b, message); + } + + function finish() { + for (let eventType of LISTEN_EVENTS) { + gBrowser.removeEventListener(eventType, eventListener, true); + } + + // Work around bug 467960 + var history = gBrowser.webNavigation.sessionHistory; + history.PurgeHistory(history.count); + + window.close(); + window.opener.wrappedJSObject.SimpleTest.finish(); + } + + function onLoad() { + gBrowser = document.getElementById("content"); + for (let eventType of LISTEN_EVENTS) { + gBrowser.addEventListener(eventType, eventListener, true); + } + + gTestsIterator = testsIterator(); + nextTest(); + } + + function eventListener(event) { + ok(gExpected.length >= 1, "Unexpected event " + event.type); + if (gExpected.length == 0) { + // in case of unexpected event, try to continue anyway + setTimeout(nextTest, 0); + return; + } + + var exp = gExpected.shift(); + is(event.type, exp.type, "Invalid event received"); + if (typeof(exp.persisted) != "undefined") { + is(event.persisted, exp.persisted, "Invalid persisted state"); + } + if (exp.title) { + ok(event.originalTarget instanceof HTMLDocument, + "originalTarget not a HTMLDocument"); + is(event.originalTarget.title, exp.title, "titles don't match"); + } + + if (gExpected.length == 0) { + setTimeout(nextTest, 0); + } + } + + function nextTest() { + try { + gTestsIterator.next(); + } catch (err if err instanceof StopIteration) { + finish(); + } + } + + function testsIterator() { + // Load a secure page with a no-cache header, followed by a simple page. + // no-cache should not interfere with the bfcache in the way no-store + // does. + var test1DocURI = "https://example.com:443/tests/docshell/test/chrome/112564_nocache.html"; + + gExpected = [{type: "pagehide", persisted: true}, + {type: "load", title: "test1"}, + {type: "pageshow", title: "test1", persisted: false}]; + gBrowser.loadURI(test1DocURI); + yield undefined; + + var test2Doc = "data:text/html,<html><head><title>test2</title></head>" + + "<body>test2</body></html>"; + + gExpected = [{type: "pagehide", title: "test1", persisted: true}, + {type: "load", title: "test2"}, + {type: "pageshow", title: "test2", persisted: false}]; + gBrowser.loadURI(test2Doc); + yield undefined; + + // Now go back in history. First page has been cached. + // Check persisted property to confirm + gExpected = [{type: "pagehide", title: "test2", persisted: true}, + {type: "pageshow", title: "test1", persisted: true}]; + gBrowser.goBack(); + yield undefined; + } + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug113934_window.xul b/system/docshell/test/chrome/bug113934_window.xul new file mode 100644 index 000000000..9dbfc3b8f --- /dev/null +++ b/system/docshell/test/chrome/bug113934_window.xul @@ -0,0 +1,161 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<window title="Mozilla Bug 113934" onload="doTheTest()" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox> + <vbox id="box1"> + </vbox> + <vbox id="box2"> + </vbox> + <spacer flex="1"/> + </hbox> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + var imports = [ "SimpleTest", "is", "isnot", "ok", "snapshotWindow", + "compareSnapshots", "onerror" ]; + for (var name of imports) { + window[name] = window.opener.wrappedJSObject[name]; + } + + function $(id) { + return document.getElementById(id); + } + + function addBrowser(parent, id, width, height) { + var b = + document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "browser"); + var type = window.location.search.slice(1); + is(type == "chrome" || type == "content", true, "Unexpected type"); + b.setAttribute("type", type); + b.setAttribute("id", id); + b.setAttribute("width", width); + b.setAttribute("height", height); + $(parent).appendChild(b); + } + addBrowser("box1", "f1", 300, 200); + addBrowser("box1", "f2", 300, 200); + addBrowser("box2", "f3", 30, 200); + + /** Test for Bug 113934 **/ + var doc1 = + "data:text/html,<html><body onbeforeunload='document.documentElement.textContent = \"\"' onunload='document.documentElement.textContent = \"\"' onpagehide='document.documentElement.textContent = \"\"'>This is a test</body></html>"; + var doc2 = "data:text/html,<html><head></head><body>This is a second test</body></html>"; + + + $("f1").setAttribute("src", doc1); + $("f2").setAttribute("src", doc2); + $("f3").setAttribute("src", doc2); + + function doTheTest() { + var s1 = snapshotWindow($("f1").contentWindow); + var s2 = snapshotWindow($("f2").contentWindow); + var s3 = snapshotWindow($("f3").contentWindow); + + // This test is broken - see bug 1090274 + //ok(!compareSnapshots(s2, s3, true)[0], + // "Should look different due to different sizing"); + + function getDOM(id) { + return $(id).contentDocument.documentElement.innerHTML; + } + + var dom1 = getDOM("f1"); + + var dom2 = getDOM("f2"); + $("f2").contentDocument.body.textContent = "Modified the text"; + var dom2star = getDOM("f2"); + isnot(dom2, dom2star, "We changed the DOM!"); + + $("f1").swapDocShells($("f2")); + // now we have doms 2*, 1, 2 in the frames + + is(getDOM("f1"), dom2star, "Shouldn't have changed the DOM on swap"); + is(getDOM("f2"), dom1, "Shouldn't have fired event handlers"); + + // Test for bug 480149 + // The DOMLink* events are dispatched asynchronously, thus I cannot + // just include the <link> element in the initial DOM and swap the + // docshells. Instead, the link element is added now. Then, when the + // first DOMLinkAdded event (which is a result of the actual addition) + // is dispatched, the docshells are swapped and the pageshow and pagehide + // events are tested. Only then, we wait for the DOMLink* events, + // which are a result of swapping the docshells. + var DOMLinkListener = { + _afterFirst: false, + _removedDispatched: false, + _addedDispatched: false, + handleEvent: function(aEvent) { + if (!this._afterFirst) { + is(aEvent.type, "DOMLinkAdded"); + + var strs = { "f1": "", "f3" : "" }; + function attachListener(node, type) { + var listener = function(e) { + if (strs[node.id]) strs[node.id] += " "; + strs[node.id] += node.id + ".page" + type; + } + node.addEventListener("page" + type, listener, false); + + listener.detach = function() { + node.removeEventListener("page" + type, listener, false); + } + return listener; + } + + var l1 = attachListener($("f1"), "show"); + var l2 = attachListener($("f1"), "hide"); + var l3 = attachListener($("f3"), "show"); + var l4 = attachListener($("f3"), "hide"); + + $("f1").swapDocShells($("f3")); + // now we have DOMs 2, 1, 2* in the frames + + l1.detach(); + l2.detach(); + l3.detach(); + l4.detach(); + + var s1_new = snapshotWindow($("f1").contentWindow); + var [same, first, second] = compareSnapshots(s1_new, s2, true); + ok(same, "Should reflow on swap", "Expected " + second + " but got " + first); + + is(strs["f1"], "f1.pagehide f1.pageshow"); + is(strs["f3"], "f3.pagehide f3.pageshow"); + this._afterFirst = true; + return; + } + if (aEvent.type == "DOMLinkAdded") { + is(this._addedDispatched, false); + this._addedDispatched = true; + } + else { + is(this._removedDispatched, false); + this._removedDispatched = true; + } + + if (this._addedDispatched && this._removedDispatched) { + $("f1").removeEventListener("DOMLinkAdded", this, false); + $("f1").removeEventListener("DOMLinkRemoved", this, false); + $("f3").removeEventListener("DOMLinkAdded", this, false); + $("f3").removeEventListener("DOMLinkRemoved", this, false); + window.close(); + SimpleTest.finish(); + } + } + }; + + $("f1").addEventListener("DOMLinkAdded", DOMLinkListener, false); + $("f1").addEventListener("DOMLinkRemoved", DOMLinkListener, false); + $("f3").addEventListener("DOMLinkAdded", DOMLinkListener, false); + $("f3").addEventListener("DOMLinkRemoved", DOMLinkListener, false); + + var linkElement = $("f1").contentDocument.createElement("link"); + linkElement.setAttribute("rel", "alternate"); + linkElement.setAttribute("href", "about:blank"); + $("f1").contentDocument.documentElement.firstChild.appendChild(linkElement); + } + + ]]></script> +</window> diff --git a/system/docshell/test/chrome/bug215405_window.xul b/system/docshell/test/chrome/bug215405_window.xul new file mode 100644 index 000000000..1935eddee --- /dev/null +++ b/system/docshell/test/chrome/bug215405_window.xul @@ -0,0 +1,167 @@ +<?xml version="1.0"?> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="215405Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="onLoad();" + title="215405 test"> + + <script type="application/javascript"><![CDATA[ + var imports = [ "SimpleTest", "is", "isnot", "ok"]; + for (var name of imports) { + window[name] = window.opener.wrappedJSObject[name]; + } + + const text="MOZILLA"; + const nostoreURI = "http://mochi.test:8888/tests/docshell/test/chrome/" + + "215405_nostore.html"; + const nocacheURI = "https://example.com:443/tests/docshell/test/chrome/" + + "215405_nocache.html"; + + var gBrowser; + var gTestsIterator; + var scrollX = 0; + var scrollY = 0; + + function finish() { + gBrowser.removeEventListener("pageshow", eventListener, true); + // Work around bug 467960 + var history = gBrowser.webNavigation.sessionHistory; + history.PurgeHistory(history.count); + + window.close(); + window.opener.wrappedJSObject.SimpleTest.finish(); + } + + function onLoad(e) { + gBrowser = document.getElementById("content"); + gBrowser.addEventListener("pageshow", eventListener, true); + + gTestsIterator = testsIterator(); + nextTest(); + } + + function eventListener(event) { + setTimeout(nextTest, 0); + } + + function nextTest() { + try { + gTestsIterator.next(); + } catch (err if err instanceof StopIteration) { + finish(); + } + } + + function testsIterator() { + // No-store tests + var testName = "[nostore]"; + + // Load a page with a no-store header + gBrowser.loadURI(nostoreURI); + yield undefined; + + + // Now that the page has loaded, amend the form contents + var form = gBrowser.contentDocument.getElementById("inp"); + form.value = text; + + // Attempt to scroll the page + var originalXPosition = gBrowser.contentWindow.scrollX; + var originalYPosition = gBrowser.contentWindow.scrollY; + var scrollToX = gBrowser.contentWindow.scrollMaxX; + var scrollToY = gBrowser.contentWindow.scrollMaxY; + gBrowser.contentWindow.scrollBy(scrollToX, scrollToY); + + // Save the scroll position for future comparison + scrollX = gBrowser.contentWindow.scrollX; + scrollY = gBrowser.contentWindow.scrollY; + isnot(scrollX, originalXPosition, + testName + " failed to scroll window horizontally"); + isnot(scrollY, originalYPosition, + testName + " failed to scroll window vertically"); + + // Load a new document into the browser + var simple = "data:text/html,<html><head><title>test2</title></head>" + + "<body>test2</body></html>"; + gBrowser.loadURI(simple); + yield undefined; + + + // Now go back in history. First page should not have been cached. + gBrowser.goBack(); + yield undefined; + + + // First uncacheable page will now be reloaded. Check scroll position + // restored, and form contents not + is(gBrowser.contentWindow.scrollX, scrollX, testName + + " horizontal axis scroll position not correctly restored"); + is(gBrowser.contentWindow.scrollY, scrollY, testName + + " vertical axis scroll position not correctly restored"); + var formValue = gBrowser.contentDocument.getElementById("inp").value; + isnot(formValue, text, testName + " form value incorrectly restored"); + + + // https no-cache + testName = "[nocache]"; + + // Load a page with a no-cache header. This should not be + // restricted like no-store (bug 567365) + gBrowser.loadURI(nocacheURI); + yield undefined; + + + // Now that the page has loaded, amend the form contents + form = gBrowser.contentDocument.getElementById("inp"); + form.value = text; + + // Attempt to scroll the page + originalXPosition = gBrowser.contentWindow.scrollX; + originalYPosition = gBrowser.contentWindow.scrollY; + scrollToX = gBrowser.contentWindow.scrollMaxX; + scrollToY = gBrowser.contentWindow.scrollMaxY; + gBrowser.contentWindow.scrollBy(scrollToX, scrollToY); + + // Save the scroll position for future comparison + scrollX = gBrowser.contentWindow.scrollX; + scrollY = gBrowser.contentWindow.scrollY; + isnot(scrollX, originalXPosition, + testName + " failed to scroll window horizontally"); + isnot(scrollY, originalYPosition, + testName + " failed to scroll window vertically"); + + gBrowser.loadURI(simple); + yield undefined; + + + // Now go back in history to the cached page. + gBrowser.goBack(); + yield undefined; + + + // First page will now be reloaded. Check scroll position + // and form contents are restored + is(gBrowser.contentWindow.scrollX, scrollX, testName + + " horizontal axis scroll position not correctly restored"); + is(gBrowser.contentWindow.scrollY, scrollY, testName + + " vertical axis scroll position not correctly restored"); + var formValue = gBrowser.contentDocument.getElementById("inp").value; + is(formValue, text, testName + " form value not correctly restored"); + + // nextTest has to be called from here, as no events are fired in this + // step + setTimeout(nextTest, 0); + yield undefined; + } + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug293235.html b/system/docshell/test/chrome/bug293235.html new file mode 100644 index 000000000..458f88431 --- /dev/null +++ b/system/docshell/test/chrome/bug293235.html @@ -0,0 +1,13 @@ +<html> + <head> + <title>Bug 293235 page1</title> + <style type="text/css"> + a:visited, a.forcevisited.forcevisited { color: rgb(128, 0, 128); } + a:link, a.forcelink.forcelink { color: rgb(0, 0, 128); } + a:focus { color: rgb(128, 0, 0); } + </style> + </head> + <body> + <a id="link1" href="bug293235_p2.html">This is a test link.</a> + </body> +</html> diff --git a/system/docshell/test/chrome/bug293235_p2.html b/system/docshell/test/chrome/bug293235_p2.html new file mode 100644 index 000000000..2de067b80 --- /dev/null +++ b/system/docshell/test/chrome/bug293235_p2.html @@ -0,0 +1,8 @@ +<html> + <head> + <title>Bug 293235 page2</title> + </head> + <body> + Nothing to see here, move along. + </body> +</html> diff --git a/system/docshell/test/chrome/bug293235_window.xul b/system/docshell/test/chrome/bug293235_window.xul new file mode 100644 index 000000000..b5b359d48 --- /dev/null +++ b/system/docshell/test/chrome/bug293235_window.xul @@ -0,0 +1,162 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="293235Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug 293235 test"> + + <script type="text/javascript" + src="chrome://mochikit/content/tests/SimpleTest/specialpowersAPI.js"/> + <script type="text/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js"/> + <script type="text/javascript" + src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/> + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <script type="application/javascript"><![CDATA[ + var Ci = Components.interfaces; + var Cc = Components.classes; + Components.utils.import("resource://gre/modules/NetUtil.jsm"); + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + // Return the Element object for the specified element id + function $(id) { return TestWindow.getDocument().getElementById(id); } + + //// + // Generator function for test steps for bug 293235: + // A visited link should have the :visited style applied + // to it when displayed on a page which was fetched from + // the bfcache. + // + function testIterator() + { + // Register our observer to know when the link lookup is complete. + let testURI = NetUtil.newURI(getHttpUrl("bug293235_p2.html")); + let os = Cc["@mozilla.org/observer-service;1"]. + getService(Ci.nsIObserverService); + const URI_VISITED_RESOLUTION_TOPIC = "visited-status-resolution"; + let observer = { + notified: false, + observe: function(aSubject, aTopic, aData) + { + if (!testURI.equals(aSubject.QueryInterface(Ci.nsIURI))) { + return; + } + is(aTopic, URI_VISITED_RESOLUTION_TOPIC, "Unexpected topic"); + this.notified = true; + + // Cleanup after ourselves... + os.removeObserver(this, URI_VISITED_RESOLUTION_TOPIC); + }, + }; + os.addObserver(observer, URI_VISITED_RESOLUTION_TOPIC, false); + function notified() { + return observer.notified; + } + + // Load a test page containing a link that should be initially + // blue, per the :link style. + doPageNavigation({ + uri: getHttpUrl("bug293235.html"), + onNavComplete: nextTest + }); + yield undefined; + + // Before we go any further, make sure our link has been notified. + waitForTrue(notified, nextTest); + yield undefined; + + // Now that we've been notified, we can check our link color. + // Since we can't use getComputedStyle() for this because + // getComputedStyle lies about styles that result from :visited, + // we have to take snapshots. + // First, take two reference snapshots. + var link1 = $("link1"); + link1.className = "forcelink"; + var refLink = snapshotWindow(TestWindow.getWindow()); + link1.className = "forcevisited"; + var refVisited = snapshotWindow(TestWindow.getWindow()); + link1.className = ""; + function snapshotsEqual(snap1, snap2) { + return compareSnapshots(snap1, snap2, true)[0]; + } + ok(!snapshotsEqual(refLink, refVisited), "references should not match"); + ok(snapshotsEqual(refLink, snapshotWindow(TestWindow.getWindow())), + "link should initially be blue"); + + let observedVisit = false, observedPageShow = false; + function maybeRunNextTest() { + ok(true, "maybe run next test? visited: " + observedVisit + " pageShow: " + observedPageShow); + if (observedVisit && observedPageShow) + nextTest(); + } + + // Because adding visits is async, we will not be notified imemdiately. + let visitObserver = { + observe: function(aSubject, aTopic, aData) + { + if (!testURI.equals(aSubject.QueryInterface(Ci.nsIURI))) { + return; + } + os.removeObserver(this, aTopic); + observedVisit = true; + maybeRunNextTest(); + }, + }; + os.addObserver(visitObserver, "uri-visit-saved", false); + // Load the page that the link on the previous page points to. + doPageNavigation({ + uri: getHttpUrl("bug293235_p2.html"), + onNavComplete: function() { + observedPageShow = true; + maybeRunNextTest(); + } + }); + yield undefined; + + // And the nodes get notified after the "link-visited" topic, so + // we need to execute soon... + SimpleTest.executeSoon(nextTest); + yield undefined; + + // Go back, verify the original page was loaded from the bfcache, + // and verify that the link is now purple, per the + // :visited style. + doPageNavigation({ + back: true, + eventsToListenFor: ["pageshow"], + expectedEvents: [ { type: "pageshow", + persisted: true, + title: "Bug 293235 page1" } ], + onNavComplete: nextTest + }); + yield undefined; + + // Now we can test the link color. + ok(snapshotsEqual(refVisited, snapshotWindow(TestWindow.getWindow())), + "visited link should be purple"); + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug294258_testcase.html b/system/docshell/test/chrome/bug294258_testcase.html new file mode 100644 index 000000000..cd80fefd0 --- /dev/null +++ b/system/docshell/test/chrome/bug294258_testcase.html @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>Bug 294258 Testcase</title> + <meta http-equiv="Content-Type" content="application/xhtml+xml"/> + <style type="text/css"> + * { + font-family: monospace; + } + </style> + </head> + <body> + <div> + <p> + input type="text": <input id="text" type="text"/> + </p> + <p> + input type="checkbox": <input id="checkbox" type="checkbox"/> + </p> + <p> + input type="file": <input id="file" type="file"/> + </p> + <p> + input type="radio": + <input type="radio" id="radio1" name="radio" value="radio1"/> + <input id="radio2" type="radio" name="radio" value="radio2"/> + </p> + <p> + textarea: <textarea id="textarea" rows="4" cols="80"></textarea> + </p> + <p> + select -> option: <select id="select"> + <option>1</option> + <option>2</option> + <option>3</option> + <option>4</option> + </select> + </p> + </div> + </body> +</html> diff --git a/system/docshell/test/chrome/bug294258_window.xul b/system/docshell/test/chrome/bug294258_window.xul new file mode 100644 index 000000000..f25097eab --- /dev/null +++ b/system/docshell/test/chrome/bug294258_window.xul @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="294258Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug 294258 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + function $(id) { return TestWindow.getDocument().getElementById(id); } + + //// + // Generator function for test steps for bug 294258: + // Form values should be preserved on reload. + // + function testIterator() + { + // Load a page containing a form. + doPageNavigation( { + uri: getHttpUrl("bug294258_testcase.html"), + onNavComplete: nextTest + } ); + yield undefined; + + // Change the data for each of the form fields, and reload. + $("text").value = "text value"; + $("checkbox").checked = true; + var file = Components.classes["@mozilla.org/file/directory_service;1"] + .getService(Components.interfaces.nsIProperties) + .get("TmpD", Components.interfaces.nsILocalFile); + file.append("294258_test.file"); + file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666); + filePath = file.path; + $("file").value = filePath; + $("textarea").value = "textarea value"; + $("radio1").checked = true; + $("select").selectedIndex = 2; + doPageNavigation( { + reload: true, + onNavComplete: nextTest + } ); + yield undefined; + + // Verify that none of the form data has changed. + is($("text").value, "text value", "Text value changed"); + is($("checkbox").checked, true, "Checkbox value changed"); + is($("file").value, filePath, "File value changed"); + is($("textarea").value, "textarea value", "Textarea value changed"); + is($("radio1").checked, true, "Radio value changed"); + is($("select").selectedIndex, 2, "Select value changed"); + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug298622_window.xul b/system/docshell/test/chrome/bug298622_window.xul new file mode 100644 index 000000000..2773f3420 --- /dev/null +++ b/system/docshell/test/chrome/bug298622_window.xul @@ -0,0 +1,148 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="298622Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug 298622 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src= "docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + // Global variable that holds a reference to the find bar. + var gFindBar; + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + //// + // Generator function for test steps for bug 298622: + // Find should work correctly on a page loaded from the + // bfcache. + // + function testIterator() + { + // Make sure bfcache is on. + enableBFCache(true); + + // Load a test page which contains some text to be found. + doPageNavigation({ + uri: "data:text/html,<html><head><title>test1</title></head>" + + "<body>find this!</body></html>", + onNavComplete: nextTest + }); + yield undefined; + + // Load a second, dummy page, verifying that the original + // page gets stored in the bfcache. + doPageNavigation({ + uri: getHttpUrl("generic.html"), + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "test1", + persisted: true }, + { type: "pageshow", + title: "generic page" } ], + onNavComplete: nextTest + }); + yield undefined; + + // Make sure we unsuppress painting before continuing + SimpleTest.executeSoon(nextTest); + yield undefined; + + // Search for some text that's on the second page (but not on + // the first page), and verify that it can be found. + gFindBar = document.getElementById("FindToolbar"); + document.getElementById("cmd_find").doCommand(); + ok(!gFindBar.hidden, "failed to open findbar"); + gFindBar._findField.value = "A generic page"; + gFindBar._find(); + SimpleTest.executeSoon(nextTest); + yield undefined; + + // Make sure Find bar's internal status is not 'notfound' + isnot(gFindBar._findField.getAttribute("status"), "notfound", + "Findfield status attribute should not have been 'notfound'" + + " after Find"); + + // Make sure the key events above have time to be processed + // before continuing + waitForTrue(function() { + return ( + TestWindow.getWindow().getSelection().toString().toLowerCase() == + "a generic page"); + }, nextTest, 20); + yield undefined; + + is(gFindBar._findField.inputField.value, "A generic page", + "expected text not present in find input field"); + is(TestWindow.getWindow().getSelection().toString().toLowerCase(), + "a generic page", + "find failed on second page loaded"); + + // Go back to the original page and verify it's loaded from the + // bfcache. + doPageNavigation({ + back: true, + eventsToListenFor: ["pageshow"], + expectedEvents: [ { type: "pageshow", + title: "test1", + persisted: true } ], + onNavComplete: nextTest + }); + yield undefined; + + // Search for some text that's on the original page (but not + // the dummy page loaded above), and verify that it can + // be found. + gFindBar = document.getElementById("FindToolbar"); + document.getElementById("cmd_find").doCommand(); + ok(!gFindBar.hidden, "failed to open findbar"); + gFindBar._findField.value = "find this"; + gFindBar._find(); + SimpleTest.executeSoon(nextTest); + yield undefined; + + // Make sure Find bar's internal status is not 'notfound' + isnot(gFindBar._findField.getAttribute("status"), "notfound", + "Findfield status attribute should not have been 'notfound'" + + " after Find"); + + // Make sure the key events above have time to be processed + // before continuing + waitForTrue(function() { + return ( + TestWindow.getWindow().getSelection().toString().toLowerCase() == + "find this"); + }, nextTest, 20); + yield undefined; + + is(TestWindow.getWindow().getSelection().toString().toLowerCase(), + "find this", + "find failed on page loaded from bfcache"); + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + + <commandset> + <command id="cmd_find" + oncommand="document.getElementById('FindToolbar').onFindCommand();"/> + </commandset> + <browser type="content-primary" flex="1" id="content" src="about:blank"/> + <findbar id="FindToolbar" browserid="content"/> +</window> diff --git a/system/docshell/test/chrome/bug301397_1.html b/system/docshell/test/chrome/bug301397_1.html new file mode 100644 index 000000000..9943c2efe --- /dev/null +++ b/system/docshell/test/chrome/bug301397_1.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> +<head> + <title>iframe parent</title> + </head> +<body> + <iframe id="iframe" src="bug301397_2.html"/> + </body> +</html> diff --git a/system/docshell/test/chrome/bug301397_2.html b/system/docshell/test/chrome/bug301397_2.html new file mode 100644 index 000000000..423710706 --- /dev/null +++ b/system/docshell/test/chrome/bug301397_2.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> +<head> + <title>iframe content #1</title> + </head> +<body> + iframe page 1<br/> + <a id="link" href="bug301397_3.html">go to next page</a> + </body> +</html> diff --git a/system/docshell/test/chrome/bug301397_3.html b/system/docshell/test/chrome/bug301397_3.html new file mode 100644 index 000000000..8d36e9246 --- /dev/null +++ b/system/docshell/test/chrome/bug301397_3.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> +<head> + <title>iframe content #2</title> + </head> +<body> + iframe page 2<br/> + You made it! + </body> +</html> diff --git a/system/docshell/test/chrome/bug301397_4.html b/system/docshell/test/chrome/bug301397_4.html new file mode 100644 index 000000000..5584a4554 --- /dev/null +++ b/system/docshell/test/chrome/bug301397_4.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> +<head> + <title>dummy page, no iframe</title> + </head> +<body> + Just a boring test page, nothing special. + </body> +</html> diff --git a/system/docshell/test/chrome/bug301397_window.xul b/system/docshell/test/chrome/bug301397_window.xul new file mode 100644 index 000000000..5df33c5c9 --- /dev/null +++ b/system/docshell/test/chrome/bug301397_window.xul @@ -0,0 +1,250 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="301397Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug 301397 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + //// + // Return the document element with the specified id. + // + function $(id) { return TestWindow.getDocument().getElementById(id); } + + //// + // Verifies that the given string exists in the innerHTML of the iframe + // content. + // + function verifyIframeInnerHtml(string) { + var iframeInnerHtml = $("iframe").contentDocument.body.innerHTML; + ok(iframeInnerHtml.indexOf(string) != -1, + "iframe contains wrong document: " + iframeInnerHtml); + } + + //// + // Generator function for test steps for bug 301397: + // The correct page should be displayed in an iframe when + // navigating back and forwards, when the parent page + // occupies multiple spots in the session history. + // + function testIterator() + { + // Make sure the bfcache is enabled. + enableBFCache(8); + + // Load a dummy page. + doPageNavigation({ + uri: getHttpUrl("generic.html"), + onNavComplete: nextTest + }); + yield undefined; + + // Load a page containing an iframe. + doPageNavigation({ + uri: getHttpUrl("bug301397_1.html"), + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "generic page", + persisted: true }, + { type: "pageshow", + title: "iframe content #1", + persisted: false }, // false on initial load + { type: "pageshow", + title: "iframe parent", + persisted: false } ], // false on initial load + onNavComplete: nextTest + }); + yield undefined; + + // Click a link in the iframe to cause the iframe to navigate + // to a new page, and wait until the related pagehide/pageshow + // events have occurred. + waitForPageEvents({ + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe content #1", + persisted: false }, // false, subframe nav + { type: "pageshow", + title: "iframe content #2", + persisted: false } ], // false on initial load + onNavComplete: nextTest + }); + var link = $("iframe").contentDocument.getElementById("link"); + var event = $("iframe").contentDocument.createEvent("MouseEvents"); + event.initMouseEvent("click", true, true, $("iframe").contentWindow, + 0, 0, 0, 0, 0, + false, false, false, false, + 0, null); + link.dispatchEvent(event); + yield undefined; + + // Load another dummy page. Verify that both the outgoing parent and + // iframe pages are stored in the bfcache. + doPageNavigation({ + uri: getHttpUrl("bug301397_4.html"), + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe parent", + persisted: true }, + { type: "pagehide", + title: "iframe content #2", + persisted: true }, + { type: "pageshow", + title: "dummy page, no iframe", + persisted: false } ], // false on initial load + onNavComplete: nextTest + }); + yield undefined; + + // Go back. The iframe should show the second page loaded in it. + // Both the parent and the iframe pages should be loaded from + // the bfcache. + doPageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "dummy page, no iframe", + persisted: true }, + { type: "pageshow", + persisted: true, + title: "iframe content #2" }, + { type: "pageshow", + persisted: true, + title: "iframe parent" } ], + onNavComplete: nextTest + }); + yield undefined; + + verifyIframeInnerHtml("You made it"); + + // Go gack again. The iframe should show the first page loaded in it. + doPageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe content #2", + persisted: false }, // false, subframe nav + { type: "pageshow", + title: "iframe content #1", + // false since this page was never stored + // in the bfcache in the first place + persisted: false } ], + onNavComplete: nextTest + }); + yield undefined; + + verifyIframeInnerHtml("go to next page"); + + // Go back to the generic page. Now go forward to the last page, + // again verifying that the iframe shows the first and second + // pages in order. + doPageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe parent", + persisted: true }, + { type: "pagehide", + title: "iframe content #1", + persisted: true }, + { type: "pageshow", + title: "generic page", + persisted: true } ], + onNavComplete: nextTest + }); + yield undefined; + + doPageNavigation({ + forward: true, + eventsToListenFor: ["pageshow"], + expectedEvents: [ {type: "pageshow", + title: "iframe content #1", + persisted: true}, + {type: "pageshow", + title: "iframe parent", + persisted: true} ], + onNavComplete: nextTest + }); + yield undefined; + + verifyIframeInnerHtml("go to next page"); + + doPageNavigation({ + forward: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe content #1", + persisted: false }, // false, subframe nav + { type: "pageshow", + title: "iframe content #2", + // false because the page wasn't stored in + // bfcache last time it was unloaded + persisted: false } ], + onNavComplete: nextTest + }); + yield undefined; + + verifyIframeInnerHtml("You made it"); + + doPageNavigation({ + forward: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe parent", + persisted: true }, + { type: "pagehide", + title: "iframe content #2", + persisted: true }, + { type: "pageshow", + title: "dummy page, no iframe", + persisted: true } ], + onNavComplete: nextTest + }); + yield undefined; + + // Go back once more, and again verify that the iframe shows the + // second page loaded in it. + doPageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "dummy page, no iframe", + persisted: true }, + { type: "pageshow", + persisted: true, + title: "iframe content #2" }, + { type: "pageshow", + persisted: true, + title: "iframe parent" } ], + onNavComplete: nextTest + }); + yield undefined; + + verifyIframeInnerHtml("You made it"); + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug303267.html b/system/docshell/test/chrome/bug303267.html new file mode 100644 index 000000000..32b575eee --- /dev/null +++ b/system/docshell/test/chrome/bug303267.html @@ -0,0 +1,25 @@ +<html> +<head> + <title> + bug303267.html + </title> + </head> +<body onpageshow="showpageshowcount()"> +<script> +var pageshowcount = 0; +function showpageshowcount() +{ + pageshowcount++; + var div1 = document.getElementById("div1"); + while (div1.firstChild) + { + div1.removeChild(div1.firstChild); + } + div1.appendChild(document.createTextNode( + "pageshowcount: " + pageshowcount)); +} +</script> +<div id="div1"> + </div> +</body> +</html> diff --git a/system/docshell/test/chrome/bug303267_window.xul b/system/docshell/test/chrome/bug303267_window.xul new file mode 100644 index 000000000..46a193712 --- /dev/null +++ b/system/docshell/test/chrome/bug303267_window.xul @@ -0,0 +1,101 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="303267Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug 303267 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + //// + // Generator function for test steps for bug 303267: When a page is + // displayed from the bfcache, the script globals should + // remain intact from the page's initial load. + // + function testIterator() + { + // Load an initial test page which should be saved in the bfcache. + var navData = { + uri: getHttpUrl("bug303267.html"), + eventsToListenFor: ["pageshow"], + expectedEvents: [ {type: "pageshow", title: "bug303267.html"} ], + onNavComplete: nextTest + }; + doPageNavigation(navData); + yield undefined; + + // Save the HTML of the test page for later comparison. + var originalHTML = getInnerHTMLById("div1"); + + // Load a second test page. The first test page's pagehide event should + // have the .persisted property set to true, indicating that it was + // stored in the bfcache. + navData = { + uri: "data:text/html,<html><head><title>page2</title></head>" + + "<body>bug303267, page2</body></html>", + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "bug303267.html", + persisted: true}, + {type: "pageshow", + title: "page2"} ], + onNavComplete: nextTest + }; + doPageNavigation(navData); + yield undefined; + + // Go back. Verify that the pageshow event for the original test page + // had a .persisted property of true, indicating that it came from the + // bfcache. + navData = { + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "page2"}, + {type: "pageshow", + title: "bug303267.html", + persisted: true} ], + onNavComplete: nextTest + }; + doPageNavigation(navData); + yield undefined; + + // After going back, if showpagecount() could access a global variable + // and change the test div's innerHTML, then we pass. Otherwise, it + // threw an exception and the following test will fail. + var newHTML = getInnerHTMLById("div1"); + isnot(originalHTML, + newHTML, "HTML not updated on pageshow; javascript broken?"); + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + //// + // Return the innerHTML of a particular element in the content document. + // + function getInnerHTMLById(id) { + return TestWindow.getDocument().getElementById(id).innerHTML; + } + + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug311007_window.xul b/system/docshell/test/chrome/bug311007_window.xul new file mode 100644 index 000000000..730580cc2 --- /dev/null +++ b/system/docshell/test/chrome/bug311007_window.xul @@ -0,0 +1,199 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="311007Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="startup();" + title="bug 311007 test"> + + <script type="application/javascript" src="docshell_helpers.js"></script> + <script type="application/javascript"><![CDATA[ +/* + Regression test for bug 283733 and bug 307027. + + Bug 283733 + "accessing a relative anchor in a secure page removes the + locked icon and yellow background UI" + + Bug 307027 + "Going back from secure page to error page does not clear yellow bar" + + And enhancements: + + Bug 478927 + onLocationChange should notify whether or not loading an error page. + + */ + +const kDNSErrorURI = "https://example/err.html"; +const kSecureURI = + "https://example.com/tests/docshell/test/navigation/blank.html"; + +/* + Step 1: load a network error page. <err.html> Not Secure + Step 2: load a secure page. <blank.html> Secure + Step 3: a secure page + hashchange. <blank.html#foo> Secure (bug 283733) + Step 4: go back to the error page. <err.html> Not Secure (bug 307027) + */ + +var gListener = null; + +function WebProgressListener() { + this._callback = null; +} + +WebProgressListener.prototype = { + QueryInterface: function(aIID) { + if (aIID.equals(Components.interfaces.nsIWebProgressListener) || + aIID.equals(Components.interfaces.nsISupportsWeakReference) || + aIID.equals(Components.interfaces.nsISupports)) + return this; + throw Components.results.NS_NOINTERFACE; + }, + + onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) { + setTimeout(this._callback, 0, aWebProgress, aRequest, aLocation, aFlags); + }, + + set callback(aVal) { + this._callback = aVal; + } +}; + +function startup() { + gListener = new WebProgressListener(); + + document.getElementById("content") + .webProgress + .addProgressListener(gListener, + Components.interfaces.nsIWebProgress + .NOTIFY_LOCATION); + + setTimeout(step1A, 0); +} + +/****************************************************************************** + * Step 1: Load an error page, and confirm UA knows it's insecure. + ******************************************************************************/ + +function step1A() { + gListener.callback = step1B; + content.location = kDNSErrorURI; +} + +function step1B(aWebProgress, aRequest, aLocation, aFlags) { + is(aLocation.spec, kDNSErrorURI, "Error page's URI (1)"); + + ok(!(aFlags & Components.interfaces.nsIWebProgressListener + .LOCATION_CHANGE_SAME_DOCUMENT), + "DocShell loaded a document (1)"); + + ok((aFlags & Components.interfaces.nsIWebProgressListener + .LOCATION_CHANGE_ERROR_PAGE), + "This page is an error page."); + + ok(!(aWebProgress.QueryInterface(Components.interfaces.nsIDocShell) + .securityUI.state & + Components.interfaces.nsIWebProgressListener.STATE_IS_SECURE), + "This is not a secure page (1)"); + + /* Go to step 2. */ + setTimeout(step2A, 0); +} + +/****************************************************************************** + * Step 2: Load a HTTPS page, and confirm it's secure. + ******************************************************************************/ + +function step2A() { + gListener.callback = step2B; + content.location = kSecureURI; +} + +function step2B(aWebProgress, aRequest, aLocation, aFlags) { + is(aLocation.spec, kSecureURI, "A URI on HTTPS (2)"); + + ok(!(aFlags & Components.interfaces.nsIWebProgressListener + .LOCATION_CHANGE_SAME_DOCUMENT), + "DocShell loaded a document (2)"); + + ok(!(aFlags & Components.interfaces.nsIWebProgressListener + .LOCATION_CHANGE_ERROR_PAGE), + "This page is not an error page."); + + ok((aWebProgress.QueryInterface(Components.interfaces.nsIDocShell) + .securityUI.state & + Components.interfaces.nsIWebProgressListener.STATE_IS_SECURE), + "This is a secure page (2)"); + + /* Go to step 3. */ + setTimeout(step3A, 0); +} + +/***************************************************************************** + * Step 3: Trigger hashchange within a secure page, and confirm UA knows + * it's secure. (Bug 283733) + *****************************************************************************/ + +function step3A() { + gListener.callback = step3B; + content.location += "#foo"; +} + +function step3B(aWebProgress, aRequest, aLocation, aFlags) { + is(aLocation.spec, kSecureURI + "#foo", "hashchange on HTTPS (3)"); + + ok((aFlags & Components.interfaces.nsIWebProgressListener + .LOCATION_CHANGE_SAME_DOCUMENT), + "We are in the same document as before (3)"); + + ok(!(aFlags & Components.interfaces.nsIWebProgressListener + .LOCATION_CHANGE_ERROR_PAGE), + "This page is not an error page."); + + ok((aWebProgress.QueryInterface(Components.interfaces.nsIDocShell) + .securityUI.state & + Components.interfaces.nsIWebProgressListener.STATE_IS_SECURE), + "This is a secure page (3)"); + + /* Go to step 4. */ + setTimeout(step4A, 0); +} + +/***************************************************************************** + * Step 4: Go back from a secure page to an error page, and confirm UA knows + * it's not secure. (Bug 307027) + *****************************************************************************/ + +function step4A() { + gListener.callback = step4B; + content.history.go(-2); +} + +function step4B(aWebProgress, aRequest, aLocation, aFlags) { + is(aLocation.spec, kDNSErrorURI, "Go back to the error URI (4)"); + + ok(!(aFlags & Components.interfaces.nsIWebProgressListener + .LOCATION_CHANGE_SAME_DOCUMENT), + "DocShell loaded a document (4)"); + + ok((aFlags & Components.interfaces.nsIWebProgressListener + .LOCATION_CHANGE_ERROR_PAGE), + "This page is an error page."); + + ok(!(aWebProgress.QueryInterface(Components.interfaces.nsIDocShell) + .securityUI.state & + Components.interfaces.nsIWebProgressListener.STATE_IS_SECURE), + "This is not a secure page (4)"); + + /* End. */ + aWebProgress.removeProgressListener(gListener); + delete(gListener); + finish(); +} + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug321671_window.xul b/system/docshell/test/chrome/bug321671_window.xul new file mode 100644 index 000000000..addd04570 --- /dev/null +++ b/system/docshell/test/chrome/bug321671_window.xul @@ -0,0 +1,133 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="321671Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug 321671 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + // Maximum number of entries in the bfcache for this session history. + // This number is hardcoded in docshell code. In the test, we'll + // navigate through enough pages so that we hit one that's been + // evicted from the bfcache because it's farther from the current + // page than this number. + const MAX_BFCACHE_PAGES = 3; + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + //// + // Generator function for test steps for bug 321671: Scroll position + // should be retained when moving backwards and forwards through pages + // when bfcache is enabled. + // + function testIterator() + { + // Variable to hold the scroll positions of the test pages. + var scrollPositions = []; + + // Make sure bfcache is on. + enableBFCache(true); + + // Load enough test pages that so the first one is evicted from the + // bfcache, scroll down on each page, and save the + // current scroll position before continuing. Verify that each + // page we're navigating away from is initially put into the bfcache. + for (var i = 0; i <= MAX_BFCACHE_PAGES + 1; i++) { + doPageNavigation( { + uri: "data:text/html,<html><head><title>bug321671 page" + (i + 1) + + "</title></head>" + + "<body><table border='1' width='300' height='1000'>" + + "<tbody><tr><td>" + + " page " + (i + 1) + ": foobar foobar foobar foobar " + + "</td></tr></tbody></table> " + + "</body></html>", + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + persisted: true, + title: i == 0 ? + undefined : "bug321671 page" + i }, + { type: "pageshow", + title: "bug321671 page" + (i + 1) } ], + onNavComplete: nextTest + } ); + yield undefined; + + is(TestWindow.getWindow().scrollY, 0, + "Page initially has non-zero scrollY position"); + TestWindow.getWindow().scrollByLines(10 + (2*i)); + ok(TestWindow.getWindow().scrollY > 0, + "Page has zero scrollY position after scrolling"); + scrollPositions[i] = TestWindow.getWindow().scrollY; + } + + // Go back to the first page, one page at a time. For each 'back' + // action, verify that its vertical scroll position is restored + // correctly. Verify that the last page in the sequence + // does not come from the bfcache. Again verify that all pages + // that we navigate away from are initially + // stored in the bfcache. + for (i = MAX_BFCACHE_PAGES + 1; i > 0; i--) { + doPageNavigation( { + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "bug321671 page" + (i+1), + persisted: true }, + { type: "pageshow", + title: "bug321671 page" + i, + persisted: i > 1 } ], + onNavComplete: nextTest + } ); + yield undefined; + + is(TestWindow.getWindow().scrollY, scrollPositions[i-1], + "Scroll position not restored while going back!"); + } + + // Traverse history forward now, and verify scroll position is still + // restored. Similar to the backward traversal, verify that all + // but the last page in the sequence comes from the bfcache. Also + // verify that all of the pages get stored in the bfcache when we + // navigate away from them. + for (i = 1; i <= MAX_BFCACHE_PAGES + 1; i++) { + doPageNavigation( { + forward: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + persisted: true, + title: "bug321671 page" + i }, + { type: "pageshow", + persisted: i < MAX_BFCACHE_PAGES + 1, + title: "bug321671 page" + (i + 1) } ], + onNavComplete: nextTest + } ); + yield undefined; + + is(TestWindow.getWindow().scrollY, scrollPositions[i], + "Scroll position not restored while going forward!"); + } + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug360511_case1.html b/system/docshell/test/chrome/bug360511_case1.html new file mode 100644 index 000000000..cca043bb6 --- /dev/null +++ b/system/docshell/test/chrome/bug360511_case1.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html style="height: 100%"> +<head> + <title> + bug360511 case 1 + </title> + </head> +<body style="height: 100%"> +<a id="link1" href="#bottom">jump to bottom</a> +<div id="div1" style="height: 200%; border: thin solid black;"> + hello large div + </div> + <a name="bottom">here's the bottom of the page</a> +</body> +</html> diff --git a/system/docshell/test/chrome/bug360511_case2.html b/system/docshell/test/chrome/bug360511_case2.html new file mode 100644 index 000000000..217f47724 --- /dev/null +++ b/system/docshell/test/chrome/bug360511_case2.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html style="height: 100%"> +<head> + <title> + bug360511 case 2 + </title> + </head> +<body style="height: 100%"> +<a id="link1" href="#bottom">jump to bottom</a> +<div id="div1" style="height: 200%; border: thin solid black;"> + hello large div + </div> + <a name="bottom">here's the bottom of the page</a> +</body> +</html> diff --git a/system/docshell/test/chrome/bug360511_window.xul b/system/docshell/test/chrome/bug360511_window.xul new file mode 100644 index 000000000..9d0cde7f1 --- /dev/null +++ b/system/docshell/test/chrome/bug360511_window.xul @@ -0,0 +1,134 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="360511Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug 360511 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + //// + // Generator function for test steps for bug 360511: + // Fragment uri's in session history should be restored correctly + // upon back navigation. + // + function testIterator() + { + // Case 1: load a page containing a fragment link; the page should be + // stored in the bfcache. + // Case 2: load a page containing a fragment link; the page should NOT + // be stored in the bfcache. + for (var i = 1; i < 3; i++) + { + var url = "bug360511_case" + i + ".html"; + doPageNavigation( { + uri: getHttpUrl(url), + onNavComplete: nextTest, + preventBFCache: i != 1 + } ); + yield undefined; + + // Store the original url for later comparison. + var originalUrl = TestWindow.getBrowser().currentURI.spec; + var originalDocLocation = TestWindow.getDocument().location.href; + + // Verify we're at the top of the page. + is(TestWindow.getWindow().scrollY, 0, + "Page initially has a non-zero scrollY property"); + + // Click the on the fragment link in the browser, and use setTimeout + // to give the event a chance to be processed. + var event = TestWindow.getDocument().createEvent('MouseEvent'); + event.initMouseEvent("click", true, true, TestWindow.getWindow(), 0, + 0, 0, 0, 0, + false, false, false, false, 0, null); + TestWindow.getDocument().getElementById("link1").dispatchEvent(event); + setTimeout(nextTest, 0); + yield undefined; + + // Store the fragment url for later comparison. + var fragmentUrl = TestWindow.getBrowser().currentURI.spec; + var fragDocLocation = TestWindow.getDocument().location.href; + + // Verify we're no longer at the top of the page. + ok(TestWindow.getWindow().scrollY > 0, + "We're at the top of the page but we should be at the bottom"); + + // Now navigate to any other page + var expectedPageTitle = "bug360511 case " + i; + doPageNavigation( { + uri: getHttpUrl("generic.html"), + eventsToListenFor: ["pagehide", "pageshow"], + expectedEvents: [ {type: "pagehide", title: expectedPageTitle, + persisted: i == 1}, + {type: "pageshow"} ], + onNavComplete: nextTest + } ); + yield undefined; + + // Go back + doPageNavigation( { + back: true, + eventsToListenFor: ["pageshow"], + expectedEvents: [ {type: "pageshow", title: expectedPageTitle, + persisted: i == 1} ], + onNavComplete: nextTest + } ); + yield undefined; + + // Verify the current url is the fragment url + is(TestWindow.getBrowser().currentURI.spec, fragmentUrl, + "current url is not the previous fragment url"); + is(TestWindow.getDocument().location.href, fragDocLocation, + "document.location is not the previous fragment url"); + + // Go back again. Since we're just going from a fragment url to + // parent url, no pageshow event is fired, so don't wait for any + // events. Rather, just wait for the page's scrollY property to + // change. + var originalScrollY = TestWindow.getWindow().scrollY; + doPageNavigation( { + back: true, + eventsToListenFor: [] + } ); + waitForTrue( + function() { + return (TestWindow.getWindow().scrollY != originalScrollY); + }, + function() { + setTimeout(nextTest, 0); + }, 20); + yield undefined; + + // Verify the current url is the original url without fragment + is(TestWindow.getBrowser().currentURI.spec, originalUrl, + "current url is not the original url"); + is(TestWindow.getDocument().location.href, originalDocLocation, + "document.location is not the original url"); + } + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug364461_window.xul b/system/docshell/test/chrome/bug364461_window.xul new file mode 100644 index 000000000..a05a33b3f --- /dev/null +++ b/system/docshell/test/chrome/bug364461_window.xul @@ -0,0 +1,277 @@ +<?xml version="1.0"?> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="364461Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="onLoad();" + title="364461 test"> + + <script type="application/javascript"><![CDATA[ + + const LISTEN_EVENTS = ["load", "unload", "pageshow", "pagehide"]; + + var gBrowser; + var gTestsIterator; + var gExpected = []; + + function ok(condition, message) { + window.opener.wrappedJSObject.SimpleTest.ok(condition, message); + } + function is(a, b, message) { + window.opener.wrappedJSObject.SimpleTest.is(a, b, message); + } + function finish() { + for (let eventType of LISTEN_EVENTS) { + gBrowser.removeEventListener(eventType, eventListener, true); + } + + window.close(); + window.opener.wrappedJSObject.SimpleTest.finish(); + } + + function onLoad() { + gBrowser = document.getElementById("content"); + + for (let eventType of LISTEN_EVENTS) { + gBrowser.addEventListener(eventType, eventListener, true); + } + + gTestsIterator = testsIterator(); + nextTest(); + } + + function eventListener(event) { + ok(gExpected.length >= 1, "Unexpected event " + event.type); + if (gExpected.length == 0) { + // in case of unexpected event, try to continue anyway + setTimeout(nextTest, 0); + return; + } + + var exp = gExpected.shift(); + is(event.type, exp.type, "Invalid event received"); + if (typeof(exp.persisted) != "undefined") { + is(event.persisted, exp.persisted, "Invalid persisted state"); + } + if (exp.title) { + ok(event.originalTarget instanceof HTMLDocument, + "originalTarget not a HTMLDocument"); + is(event.originalTarget.title, exp.title, "titles don't match"); + } + + if (gExpected.length == 0) { + setTimeout(nextTest, 0); + } + } + + function nextTest() { + try { + gTestsIterator.next(); + } catch (err if err instanceof StopIteration) { + finish(); + } + } + + function testsIterator() { + + // Tests 1 + 2: + // Back/forward between two simple documents. Bfcache will be used. + + var test1Doc = "data:text/html,<html><head><title>test1</title></head>" + + "<body>test1</body></html>"; + + gExpected = [{type: "pagehide", persisted: true}, + + {type: "load", title: "test1"}, + {type: "pageshow", title: "test1", persisted: false}]; + gBrowser.loadURI(test1Doc); + yield undefined; + + var test2Doc = "data:text/html,<html><head><title>test2</title></head>" + + "<body>test2</body></html>"; + + gExpected = [{type: "pagehide", title: "test1", persisted: true}, + {type: "load", title: "test2"}, + {type: "pageshow", title: "test2", persisted: false}]; + gBrowser.loadURI(test2Doc); + yield undefined; + + gExpected = [{type: "pagehide", title: "test2", persisted: true}, + {type: "pageshow", title: "test1", persisted: true}]; + gBrowser.goBack(); + yield undefined; + + gExpected = [{type: "pagehide", title: "test1", persisted: true}, + {type: "pageshow", title: "test2", persisted: true}]; + gBrowser.goForward(); + yield undefined; + + // Tests 3 + 4: + // Back/forward between a two-level deep iframed document and a simple + // document. Bfcache will be used and events should be dispatched to + // all frames. + + var test3Doc = "data:text/html,<html><head><title>test3</title>" + + "</head><body>" + + "<iframe src='data:text/html," + + "<html><head><title>test3-nested1</title></head>" + + "<body>test3-nested1" + + "<iframe src=\"data:text/html," + + "<html><head><title>test3-nested2</title></head>" + + "<body>test3-nested2</body></html>\">" + + "</iframe>" + + "</body></html>'>" + + "</iframe>" + + "</body></html>"; + + gExpected = [{type: "pagehide", title: "test2", persisted: true}, + {type: "load", title: "test3-nested2"}, + {type: "pageshow", title: "test3-nested2", persisted: false}, + {type: "load", title: "test3-nested1"}, + {type: "pageshow", title: "test3-nested1", persisted: false}, + {type: "load", title: "test3"}, + {type: "pageshow", title: "test3", persisted: false}]; + gBrowser.loadURI(test3Doc); + yield undefined; + + var test4Doc = "data:text/html,<html><head><title>test4</title></head>" + + "<body>test4</body></html>"; + + gExpected = [{type: "pagehide", title: "test3", persisted: true}, + {type: "pagehide", title: "test3-nested1", persisted: true}, + {type: "pagehide", title: "test3-nested2", persisted: true}, + {type: "load", title: "test4"}, + {type: "pageshow", title: "test4", persisted: false}]; + gBrowser.loadURI(test4Doc); + yield undefined; + + gExpected = [{type: "pagehide", title: "test4", persisted: true}, + {type: "pageshow", title: "test3-nested2", persisted: true}, + {type: "pageshow", title: "test3-nested1", persisted: true}, + {type: "pageshow", title: "test3", persisted: true}]; + gBrowser.goBack(); + yield undefined; + + // This is where the two nested pagehide are not dispatched in bug 364461 + gExpected = [{type: "pagehide", title: "test3", persisted: true}, + {type: "pagehide", title: "test3-nested1", persisted: true}, + {type: "pagehide", title: "test3-nested2", persisted: true}, + {type: "pageshow", title: "test4", persisted: true}]; + gBrowser.goForward(); + yield undefined; + + // Tests 5 + 6: + // Back/forward between a document containing an unload handler and a + // a simple document. Bfcache won't be used for the first one (see + // http://developer.mozilla.org/en/docs/Using_Firefox_1.5_caching). + + var test5Doc = "data:text/html,<html><head><title>test5</title></head>" + + "<body onunload='while(false) { /* nop */ }'>" + + "test5</body></html>"; + + gExpected = [{type: "pagehide", title: "test4", persisted: true}, + {type: "load", title: "test5"}, + {type: "pageshow", title: "test5", persisted: false}]; + gBrowser.loadURI(test5Doc); + yield undefined; + + var test6Doc = "data:text/html,<html><head><title>test6</title></head>" + + "<body>test6</body></html>"; + + gExpected = [{type: "pagehide", title: "test5", persisted: false}, + {type: "unload", title: "test5"}, + {type: "load", title: "test6"}, + {type: "pageshow", title: "test6", persisted: false}]; + gBrowser.loadURI(test6Doc); + yield undefined; + + gExpected = [{type: "pagehide", title: "test6", persisted: true}, + {type: "load", title: "test5"}, + {type: "pageshow", title: "test5", persisted: false}]; + gBrowser.goBack(); + yield undefined; + + gExpected = [{type: "pagehide", title: "test5", persisted: false}, + {type: "unload", title: "test5"}, + {type: "pageshow", title: "test6", persisted: true}]; + gBrowser.goForward(); + yield undefined; + + // Test 7: + // Testcase from https://bugzilla.mozilla.org/show_bug.cgi?id=384977#c10 + // Check that navigation is not blocked after a document is restored + // from bfcache + + var test7Doc = "data:text/html,<html><head><title>test7</title>" + + "</head><body>" + + "<iframe src='data:text/html," + + "<html><head><title>test7-nested1</title></head>" + + "<body>test7-nested1<br/>" + + "<a href=\"data:text/plain,aaa\" target=\"_top\">" + + "Click me, hit back, click me again</a>" + + "</body></html>'>" + + "</iframe>" + + "</body></html>"; + + gExpected = [{type: "pagehide", title: "test6", persisted: true}, + {type: "load", title: "test7-nested1"}, + {type: "pageshow", title: "test7-nested1", persisted: false}, + {type: "load", title: "test7"}, + {type: "pageshow", title: "test7", persisted: false}]; + gBrowser.loadURI(test7Doc); + yield undefined; + + // Simulates a click on the link inside the iframe + function clickIframeLink() { + var iframe = gBrowser.contentDocument.getElementsByTagName("iframe")[0]; + var w = iframe.contentWindow; + var d = iframe.contentDocument; + + var evt = d.createEvent("MouseEvents"); + evt.initMouseEvent("click", true, true, w, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + d.getElementsByTagName("a")[0].dispatchEvent(evt); + } + + gExpected = [{type: "pagehide", title: "test7", persisted: true}, + {type: "pagehide", title: "test7-nested1", persisted: true}, + {type: "load"}, + {type: "pageshow", persisted: false}]; + clickIframeLink(); + yield undefined; + + is(gBrowser.currentURI.spec, "data:text/plain,aaa", + "Navigation is blocked when clicking link"); + + gExpected = [{type: "pagehide", persisted: true}, + {type: "pageshow", title: "test7-nested1", persisted: true}, + {type: "pageshow", title: "test7", persisted: true}]; + gBrowser.goBack(); + yield undefined; + + gExpected = [{type: "pagehide", title: "test7", persisted: true}, + {type: "pagehide", title: "test7-nested1", persisted: true}, + {type: "load"}, + {type: "pageshow", persisted: false}]; + clickIframeLink(); + yield undefined; + + is(gBrowser.currentURI.spec, "data:text/plain,aaa", + "Navigation is blocked when clicking link"); + + // nextTest has to be called from here, as no events are fired in this + // step + setTimeout(nextTest, 0); + yield undefined; + } + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug396519_window.xul b/system/docshell/test/chrome/bug396519_window.xul new file mode 100644 index 000000000..32497b163 --- /dev/null +++ b/system/docshell/test/chrome/bug396519_window.xul @@ -0,0 +1,169 @@ +<?xml version="1.0"?> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="396519Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="onLoad();" + title="396519 test"> + + <script type="application/javascript"><![CDATA[ + + const LISTEN_EVENTS = ["pageshow"]; + + const Cc = Components.classes; + const Ci = Components.interfaces; + + var gBrowser; + var gTestCount = 0; + var gTestsIterator; + var gExpected = []; + + function ok(condition, message) { + window.opener.wrappedJSObject.SimpleTest.ok(condition, message); + } + function is(a, b, message) { + window.opener.wrappedJSObject.SimpleTest.is(a, b, message); + } + function finish() { + for (let eventType of LISTEN_EVENTS) { + gBrowser.removeEventListener(eventType, eventListener, true); + } + + window.close(); + window.opener.wrappedJSObject.SimpleTest.finish(); + } + + function onLoad() { + gBrowser = document.getElementById("content"); + + for (let eventType of LISTEN_EVENTS) { + gBrowser.addEventListener(eventType, eventListener, true); + } + + gTestsIterator = testsIterator(); + nextTest(); + } + + function eventListener(event) { + // we're in pageshow, but we need to let that finish + // content eviction and saving happen during pageshow, so when doTest + // runs, we should should be in a testable state + setTimeout(doTest, 0); + } + + function doTest() { + var history = gBrowser.webNavigation.sessionHistory; + if (history.count == gExpected.length) { + for (var i=0; i<history.count; i++) { + var shEntry = history.getEntryAtIndex(i,false). + QueryInterface(Components.interfaces.nsISHEntry); + is(!!shEntry.contentViewer, gExpected[i], "content viewer "+i+", test "+gTestCount); + } + + // Make sure none of the SHEntries share bfcache entries with one + // another. + for (var i = 0; i < history.count; i++) { + for (var j = 0; j < history.count; j++) { + if (j == i) + continue; + + let shentry1 = history.getEntryAtIndex(i, false) + .QueryInterface(Ci.nsISHEntry); + let shentry2 = history.getEntryAtIndex(j, false) + .QueryInterface(Ci.nsISHEntry); + ok(!shentry1.sharesDocumentWith(shentry2), + 'Test ' + gTestCount + ': shentry[' + i + "] shouldn't " + + "share document with shentry[" + j + ']'); + } + } + } + else { + is(history.count, gExpected.length, "Wrong history length in test "+gTestCount); + } + + setTimeout(nextTest, 0); + } + + function nextTest() { + try { + gTestsIterator.next(); + } catch (err if err instanceof StopIteration) { + finish(); + } + } + + function testsIterator() { + + // Tests 1 + 2: + // Back/forward between two simple documents. Bfcache will be used. + + var test1Doc = "data:text/html,<html><head><title>test1</title></head>" + + "<body>test1</body></html>"; + + gTestCount++; + gExpected = [false]; + gBrowser.loadURI(test1Doc); + yield undefined; + + gTestCount++; + gExpected = [true, false]; + var test2Doc = test1Doc.replace(/1/,"2"); + gBrowser.loadURI(test2Doc); + yield undefined; + + gTestCount++; + gExpected = [true, true, false]; + gBrowser.loadURI(test1Doc); + yield undefined; + + gTestCount++; + gExpected = [true, true, true, false]; + gBrowser.loadURI(test2Doc); + yield undefined; + + gTestCount++; + gExpected = [false, true, true, true, false]; + gBrowser.loadURI(test1Doc); + yield undefined; + + gTestCount++; + gExpected = [false, false, true, true, true, false]; + gBrowser.loadURI(test2Doc); + yield undefined; + + gTestCount++; + gExpected = [false, false, true, true, false, true]; + gBrowser.goBack(); + yield undefined; + + gTestCount++; + gExpected = [false, false, true, true, true, false]; + gBrowser.goForward(); + yield undefined; + + gTestCount++; + gExpected = [false, false, true, true, true, false]; + gBrowser.gotoIndex(1); + yield undefined; + + gTestCount++; + gExpected = [false, true, true, true, false, false]; + gBrowser.goBack(); + yield undefined; + + gTestCount++; + gExpected = [false, false, true, true, false, false]; + gBrowser.gotoIndex(5); + yield undefined; + } + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug396649_window.xul b/system/docshell/test/chrome/bug396649_window.xul new file mode 100644 index 000000000..c94d8b78e --- /dev/null +++ b/system/docshell/test/chrome/bug396649_window.xul @@ -0,0 +1,122 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="396649Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug 396649 test"> + + <script type="text/javascript" + src="chrome://mochikit/content/tests/SimpleTest/specialpowersAPI.js"/> + <script type="text/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js"/> + <script type="text/javascript" + src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/> + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + // Maximum number of entries in the bfcache for this session history. + // This number is hardcoded in docshell code. In the test, we'll + // navigate through enough pages so that we hit one that's been + // evicted from the bfcache because it's farther from the current + // page than this number. + const MAX_BFCACHE_PAGES = 3; + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + //// + // Generator function for test steps for bug 396649: Content + // viewers should be evicted from bfcache when going back if more + // than MAX_BFCACHE_PAGES from the current index. + // + function testIterator() + { + // Make sure bfcache is on. + enableBFCache(true); + + // Load enough pages so that the first loaded is eviced from + // the bfcache, since it is greater the MAX_BFCACHE_PAGES from + // the current position in the session history. Verify all + // of the pages are initially stored in the bfcache when + // they're unloaded. + for (var i = 0; i <= MAX_BFCACHE_PAGES + 1; i++) { + doPageNavigation( { + uri: "data:text/html,<!DOCTYPE html><html>" + + "<head><title>bug396649 page" + i + + "</title></head>" + + "<body>" + + "test page " + i + + "</body></html>", + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: i == 0 ? + undefined : "bug396649 page" + (i-1), + persisted: true }, + { type: "pageshow", + title: "bug396649 page" + i } ], + onNavComplete: nextTest + } ); + yield undefined; + } + + // Go back to the first page, one page at a time. The first + // MAX_BFCACHE_PAGES pages loaded via back should come from the bfcache, + // the last should not, since it should have been evicted during the + // previous navigation sequence. Verify all pages are initially stored + // in the bfcache when they're unloaded. + for (i = MAX_BFCACHE_PAGES + 1; i > 0; i--) { + doPageNavigation( { + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "bug396649 page" + i, + persisted: true }, + { type: "pageshow", + title: "bug396649 page" + (i - 1), + persisted: i > 1 } ], + onNavComplete: nextTest + } ); + yield undefined; + } + + // Traverse history forward now. Again, the first MAX_BFCACHE_PAGES + // pages should come from the bfcache, the last should not, + // since it should have been evicted during the backwards + // traversal above. Verify all pages are initially stored + // in the bfcache when they're unloaded. + for (i = 1; i <= MAX_BFCACHE_PAGES + 1; i++) { + doPageNavigation( { + forward: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "bug396649 page" + (i-1), + persisted: true }, + { type: "pageshow", + title: "bug396649 page" + i, + persisted: i < MAX_BFCACHE_PAGES + 1 } ], + onNavComplete: nextTest + } ); + yield undefined; + } + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug449778_window.xul b/system/docshell/test/chrome/bug449778_window.xul new file mode 100644 index 000000000..b4fc5e2ba --- /dev/null +++ b/system/docshell/test/chrome/bug449778_window.xul @@ -0,0 +1,106 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<window title="Mozilla Bug 449778" onload="doTheTest()" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox id="parent"> + </hbox> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror" ]; + for (var name of imports) { + window[name] = window.opener.wrappedJSObject[name]; + } + + function $(id) { + return document.getElementById(id); + } + + function addBrowser(parent, id, width, height) { + var b = + document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "browser"); + b.setAttribute("type", "content"); + b.setAttribute("id", id); + b.setAttribute("width", width); + b.setAttribute("height", height); + $(parent).appendChild(b); + } + addBrowser("parent", "f1", 300, 200); + addBrowser("parent", "f2", 300, 200); + + /** Test for Bug 449778 **/ + var doc1 = "data:text/html,<html><body>This is a test</body></html>"; + var doc2 = "data:text/html,<html><body>This is a second test</body></html>"; + var doc3 = "data:text/html,<html><body>This is a <script>var evt = document.createEvent('Events'); evt.initEvent('testEvt', true, true); document.dispatchEvent(evt);</script>third test</body></html>"; + + + $("f1").setAttribute("src", doc1); + $("f2").setAttribute("src", doc2); + + function doTheTest() { + var strs = { "f1": "", "f2" : "" }; + function attachListener(node, type) { + var listener = function(e) { + if (strs[node.id]) strs[node.id] += " "; + strs[node.id] += node.id + ".page" + type; + } + node.addEventListener("page" + type, listener, false); + + listener.detach = function() { + node.removeEventListener("page" + type, listener, false); + } + return listener; + } + + var l1 = attachListener($("f1"), "show"); + var l2 = attachListener($("f1"), "hide"); + var l3 = attachListener($("f2"), "show"); + var l4 = attachListener($("f2"), "hide"); + + $("f1").swapDocShells($("f2")); + + is(strs["f1"], "f1.pagehide f1.pageshow", + "Expected hide then show on first loaded page"); + is(strs["f2"], "f2.pagehide f2.pageshow", + "Expected hide then show on second loaded page"); + + function listener2() { + $("f2").removeEventListener("testEvt", listener2, false); + + strs = { "f1": "", "f2" : "" }; + + $("f1").swapDocShells($("f2")); + is(strs["f1"], "f1.pagehide", + "Expected hide on already-loaded page, then nothing"); + is(strs["f2"], "f2.pageshow f2.pagehide f2.pageshow", + "Expected show on still-loading page, then hide on it, then show " + + "on already-loaded page"); + + strs = { "f1": "", "f2" : "" }; + + $("f1").addEventListener("pageshow", listener3, false); + } + + function listener3() { + $("f1").removeEventListener("pageshow", listener3, false); + + is(strs["f1"], "f1.pageshow", + "Expected show as our page finishes loading"); + is(strs["f2"], "", "Expected no more events here."); + + l1.detach(); + l2.detach(); + l3.detach(); + l4.detach(); + + window.close(); + SimpleTest.finish(); + } + + $("f2").addEventListener("testEvt", listener2, false, true); + $("f2").setAttribute("src", doc3); + } + + ]]></script> +</window> diff --git a/system/docshell/test/chrome/bug449780_window.xul b/system/docshell/test/chrome/bug449780_window.xul new file mode 100644 index 000000000..38633c00f --- /dev/null +++ b/system/docshell/test/chrome/bug449780_window.xul @@ -0,0 +1,77 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<window title="Mozilla Bug 449780" onload="doTheTest()" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox id="parent"> + </hbox> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror" ]; + for (var name of imports) { + window[name] = window.opener.wrappedJSObject[name]; + } + + function $(id) { + return document.getElementById(id); + } + + function addBrowser(parent, id, width, height) { + var b = + document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "browser"); + b.setAttribute("type", "content"); + b.setAttribute("id", id); + b.setAttribute("width", width); + b.setAttribute("height", height); + $(parent).appendChild(b); + } + addBrowser("parent", "f1", 300, 200); + addBrowser("parent", "f2", 300, 200); + + /** Test for Bug 449780 **/ + var doc1 = "data:text/html,<html><body>This is a test</body></html>"; + var doc2 = "data:text/html,<html><body>This is a second test</body></html>"; + + function getDOM(id) { + return $(id).contentDocument.documentElement.innerHTML; + } + + var tester = (function() { + var origDOM = getDOM("f1"); + $("f1").contentDocument.body.textContent = "Modified"; + var modifiedDOM = getDOM("f1"); + isnot(origDOM, modifiedDOM, "DOM should be different"); + $("f1").contentWindow.location.href = doc2; + yield undefined; + + $("f1").goBack(); + yield undefined; + + is(getDOM("f1"), modifiedDOM, "Should have been bfcached"); + $("f1").goForward(); + yield undefined; + + // Ignore the notifications during swap + $("f1").removeEventListener("pageshow", testDriver, false); + $("f1").swapDocShells($("f2")); + $("f2").addEventListener("pageshow", testDriver, false); + $("f2").goBack(); + yield undefined; + + is(getDOM("f2"), origDOM, "Should have not have been bfcached"); + window.close(); + SimpleTest.finish(); + yield undefined; + })(); + + function testDriver() { + setTimeout(function() { tester.next() }, 0); + } + + function doTheTest() { + $("f1").addEventListener("pageshow", testDriver, false); + $("f1").setAttribute("src", doc1); + } + ]]></script> +</window> diff --git a/system/docshell/test/chrome/bug454235-subframe.xul b/system/docshell/test/chrome/bug454235-subframe.xul new file mode 100644 index 000000000..a8b6178e6 --- /dev/null +++ b/system/docshell/test/chrome/bug454235-subframe.xul @@ -0,0 +1,7 @@ +<window title="Mozilla Bug 454235 SubFrame" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <deck flex="1"> + <browser id="topBrowser" src="about:mozilla"/> + <browser id="burriedBrowser" src="about:mozilla"/> + </deck> +</window> diff --git a/system/docshell/test/chrome/bug582176_window.xul b/system/docshell/test/chrome/bug582176_window.xul new file mode 100644 index 000000000..ad594ee0c --- /dev/null +++ b/system/docshell/test/chrome/bug582176_window.xul @@ -0,0 +1,88 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="303267Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="nextTestAsync();" + title="bug 582176 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTestAsync() { + SimpleTest.executeSoon(tests.next.bind(tests)); + } + + //// + // Generator function for test steps for bug 582176: + // Description goes here. + // + function testIterator() + { + var browser = document.getElementById('content'); + browser.addEventListener("pageshow", nextTestAsync, true); + + enableBFCache(true); + + var notificationCount = 0; + var observer = { + observe: function(aSubject, aTopic, aData) { + is(aSubject, browser.contentWindow, + "correct subject"); + is(aTopic, "content-document-global-created", + "correct topic"); + is(aData, "http://mochi.test:8888", + "correct data"); + notificationCount++; + } + }; + + os = Components.classes["@mozilla.org/observer-service;1"]. + getService(Components.interfaces.nsIObserverService); + os.addObserver(observer, "content-document-global-created", false); + + browser.loadURI("http://mochi.test:8888/tests/docshell/test/chrome/582176_dummy.html"); + yield undefined; + is(browser.contentWindow.testVar, undefined, + "variable unexpectedly there already"); + browser.contentWindow.wrappedJSObject.testVar = 1; + is(notificationCount, 1, "Should notify on first navigation"); + + browser.loadURI("http://mochi.test:8888/tests/docshell/test/chrome/582176_dummy.html?2"); + yield undefined; + is(browser.contentWindow.wrappedJSObject.testVar, undefined, + "variable should no longer be there"); + is(notificationCount, 2, "Should notify on second navigation"); + + browser.goBack(); + yield undefined; + is(browser.contentWindow.wrappedJSObject.testVar, 1, + "variable should still be there"); + is(notificationCount, 2, "Should not notify on back navigation"); + + browser.loadURI("http://mochi.test:8888/tests/docshell/test/chrome/582176_xml.xml"); + yield undefined; + is(browser.contentDocument.body.textContent, "xslt result", + "Transform performed successfully"); + is(notificationCount, 3, "Should notify only once on XSLT navigation"); + + os.removeObserver(observer, "content-document-global-created") + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug608669.xul b/system/docshell/test/chrome/bug608669.xul new file mode 100644 index 000000000..1ab012c14 --- /dev/null +++ b/system/docshell/test/chrome/bug608669.xul @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<window title="Mozilla Bug 608669 - Blank page" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <description flex="1" value="This window is intentionally left blank"/> +</window> diff --git a/system/docshell/test/chrome/bug662200_window.xul b/system/docshell/test/chrome/bug662200_window.xul new file mode 100644 index 000000000..a73e2d296 --- /dev/null +++ b/system/docshell/test/chrome/bug662200_window.xul @@ -0,0 +1,129 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="303267Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug 662200 test"> + + <script type="application/javascript" + src="docshell_helpers.js"> + </script> + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript"><![CDATA[ + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + //// + // Generator function for test steps for bug 662200: + // Description goes here. + // + function testIterator() + { + // Load the first test page + var navData = { + uri: getHttpUrl("662200a.html"), + eventsToListenFor: ["pageshow"], + expectedEvents: [ {type: "pageshow", title: "A"} ], + onNavComplete: nextTest + }; + doPageNavigation(navData); + yield undefined; + + // Load the second test page. + navData = { + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "A"}, + {type: "pageshow", + title: "B"} ], + onNavComplete: nextTest + } + waitForPageEvents(navData); + var link = TestWindow.getDocument().getElementById("link"); + var event = TestWindow.getDocument().createEvent("MouseEvents"); + event.initMouseEvent("click", true, true, TestWindow.getWindow(), + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + link.dispatchEvent(event); + yield undefined; + + // Load the third test page. + navData = { + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "B"}, + {type: "pageshow", + title: "C"} ], + onNavComplete: nextTest + }; + waitForPageEvents(navData); + var link = TestWindow.getDocument().getElementById("link"); + var event = TestWindow.getDocument().createEvent("MouseEvents"); + event.initMouseEvent("click", true, true, TestWindow.getWindow(), + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + link.dispatchEvent(event); + yield undefined; + + // Go back. + navData = { + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "C"}, + {type: "pageshow", + title: "B"} ], + onNavComplete: nextTest + }; + doPageNavigation(navData); + yield undefined; + + var Ci = Components.interfaces; + var docshell = TestWindow.getWindow() + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell); + var shistory = docshell.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsISHistory) + .QueryInterface(Ci.nsIWebNavigation); + + // Reload. + navData = { + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "B"}, + {type: "pageshow", + title: "B"} ], + onNavComplete: nextTest + }; + // Asking the docshell harness to reload for us will call reload on + // nsDocShell which has different behavior than the reload on nsSHistory + // so we call reload explicitly here + waitForPageEvents(navData); + shistory.reload(0); + yield undefined; + + // After this sequence of events, we should be able to go back and forward + is(TestWindow.getBrowser().canGoBack, true, "Should be able to go back!"); + is(TestWindow.getBrowser().canGoForward, true, "Should be able to go forward!"); + is(shistory.requestedIndex, -1, "Requested index should be cleared!"); + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug690056_window.xul b/system/docshell/test/chrome/bug690056_window.xul new file mode 100644 index 000000000..ce5700e39 --- /dev/null +++ b/system/docshell/test/chrome/bug690056_window.xul @@ -0,0 +1,176 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="690056Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug 6500056 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + var tests = testIterator(); + + function nextTest() { + tests.next(); + } + + // Makes sure that we fire the visibilitychange events + function testIterator() { + // Enable bfcache + enableBFCache(8); + + // Load something for a start + doPageNavigation({ + uri: 'data:text/html,<title>initial load</title>', + onNavComplete: nextTest + }); + yield undefined; + + // Now load a new page + doPageNavigation({ + uri: 'data:text/html,<title>new load</title>', + eventsToListenFor: [ "pageshow", "pagehide", "visibilitychange" ], + expectedEvents: [ { type: "pagehide", + title: "initial load", + persisted: true }, + { type: "visibilitychange", + title: "initial load", + visibilityState: "hidden", + hidden: true }, + // No visibilitychange events fired for initial pageload + { type: "pageshow", + title: "new load", + persisted: false }, // false on initial load + ], + onNavComplete: nextTest + }); + yield undefined; + + // Now go back + doPageNavigation({ + back: true, + eventsToListenFor: [ "pageshow", "pagehide", "visibilitychange" ], + expectedEvents: [ { type: "pagehide", + title: "new load", + persisted: true }, + { type: "visibilitychange", + title: "new load", + visibilityState: "hidden", + hidden: true }, + { type: "visibilitychange", + title: "initial load", + visibilityState: "visible", + hidden: false }, + { type: "pageshow", + title: "initial load", + persisted: true }, + ], + onNavComplete: nextTest + }); + yield undefined; + + // And forward + doPageNavigation({ + forward: true, + eventsToListenFor: [ "pageshow", "pagehide", "visibilitychange" ], + expectedEvents: [ { type: "pagehide", + title: "initial load", + persisted: true }, + { type: "visibilitychange", + title: "initial load", + visibilityState: "hidden", + hidden: true }, + { type: "visibilitychange", + title: "new load", + visibilityState: "visible", + hidden: false }, + { type: "pageshow", + title: "new load", + persisted: true }, + ], + onNavComplete: nextTest + }); + yield undefined; + + function generateDetector(state, hidden, title, name) { + var detector = function (event) { + is(event.target.hidden, hidden, + name + " hidden value does not match"); + is(event.target.visibilityState, state, + name + " state value does not match"); + is(event.target.title, title, + name + " title value does not match"); + document.getElementById("content") + .removeEventListener("visibilitychange", + detector, + true); + nextTest(); + } + + document.getElementById("content") + .addEventListener("visibilitychange", detector, true); + } + + generateDetector("hidden", true, "new load", "Going hidden"); + + // Now flip our docshell to not active + document.getElementById("content").docShellIsActive = false; + yield undefined; + + // And navigate back; there should be no visibility state transitions + doPageNavigation({ + back: true, + eventsToListenFor: [ "pageshow", "pagehide", "visibilitychange" ], + expectedEvents: [ { type: "pagehide", + title: "new load", + persisted: true }, + { type: "pageshow", + title: "initial load", + persisted: true }, + ], + unexpectedEvents: [ "visibilitychange" ], + onNavComplete: nextTest + }); + yield undefined; + + generateDetector("visible", false, "initial load", "Going visible"); + + // Now set the docshell active again + document.getElementById("content").docShellIsActive = true; + yield undefined; + + // And forward + doPageNavigation({ + forward: true, + eventsToListenFor: [ "pageshow", "pagehide", "visibilitychange" ], + expectedEvents: [ { type: "pagehide", + title: "initial load", + persisted: true }, + { type: "visibilitychange", + title: "initial load", + visibilityState: "hidden", + hidden: true }, + { type: "visibilitychange", + title: "new load", + visibilityState: "visible", + hidden: false }, + { type: "pageshow", + title: "new load", + persisted: true }, + ], + onNavComplete: nextTest + }); + yield undefined; + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug846906.html b/system/docshell/test/chrome/bug846906.html new file mode 100644 index 000000000..a289417ea --- /dev/null +++ b/system/docshell/test/chrome/bug846906.html @@ -0,0 +1,10 @@ +<html> + <head> + <title> + </title> + </head> + <body> + <div id="div1" style="width:1024px; height:768px; border:none;"> + </div> + </body> +</html> diff --git a/system/docshell/test/chrome/bug89419.sjs b/system/docshell/test/chrome/bug89419.sjs new file mode 100644 index 000000000..c075b1e50 --- /dev/null +++ b/system/docshell/test/chrome/bug89419.sjs @@ -0,0 +1,13 @@ +function handleRequest(request, response) +{ + var redirectstate = "/docshell/test/chrome/bug89419.sjs"; + response.setStatusLine("1.1", 302, "Found"); + if (getState(redirectstate) == "") { + response.setHeader("Location", "red.png", false); + setState(redirectstate, "red"); + } else { + response.setHeader("Location", "blue.png", false); + setState(redirectstate, ""); + } + response.setHeader("Cache-Control", "no-cache", false); +} diff --git a/system/docshell/test/chrome/bug89419_window.xul b/system/docshell/test/chrome/bug89419_window.xul new file mode 100644 index 000000000..923378ea0 --- /dev/null +++ b/system/docshell/test/chrome/bug89419_window.xul @@ -0,0 +1,82 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="89419Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug 89419 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="text/javascript" + src="chrome://mochikit/content/tests/SimpleTest/specialpowersAPI.js"/> + <script type="text/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js"/> + <script type="text/javascript" + src="chrome://mochikit/content/tests/SimpleTest/specialpowers.js"/> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <script type="application/javascript"><![CDATA[ + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + //// + // Generator function for test steps for bug 89419: + // A visited link should have the :visited style applied + // to it when displayed on a page which was fetched from + // the bfcache. + // + function testIterator() + { + // Load a test page containing an image referring to the sjs that returns + // a different redirect every time it's loaded. + doPageNavigation({ + uri: getHttpUrl("89419.html"), + onNavComplete: nextTest, + preventBFCache: true + }); + yield undefined; + + var first = snapshotWindow(TestWindow.getWindow()); + + doPageNavigation({ + uri: "about:blank", + onNavComplete: nextTest + }); + yield undefined; + + var second = snapshotWindow(TestWindow.getWindow()); + function snapshotsEqual(snap1, snap2) { + return compareSnapshots(snap1, snap2, true)[0]; + } + ok(!snapshotsEqual(first, second), "about:blank should not be the same as the image web page"); + + doPageNavigation({ + back: true, + onNavComplete: nextTest + }); + yield undefined; + + var third = snapshotWindow(TestWindow.getWindow()); + ok(!snapshotsEqual(third, second), "going back should not be the same as about:blank"); + ok(snapshotsEqual(first, third), "going back should be the same as the initial load"); + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/bug909218.html b/system/docshell/test/chrome/bug909218.html new file mode 100644 index 000000000..a11fa6000 --- /dev/null +++ b/system/docshell/test/chrome/bug909218.html @@ -0,0 +1,11 @@ +<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="http://mochi.test:8888/tests/SimpleTest/test.css">
+ <script src="bug909218.js"></script>
+</head>
+<body>
+ <img src="http://mochi.test:8888/tests/docshell/test/chrome/red.png">
+ <!-- an iframe so we can check these too get the correct flags -->
+ <iframe src="generic.html"/>
+</body>
+</html>
diff --git a/system/docshell/test/chrome/bug909218.js b/system/docshell/test/chrome/bug909218.js new file mode 100644 index 000000000..c360616f9 --- /dev/null +++ b/system/docshell/test/chrome/bug909218.js @@ -0,0 +1,2 @@ +// This file exists just to ensure that we load it with the correct flags.
+dump("bug909218.js loaded\n");
diff --git a/system/docshell/test/chrome/bug92598_window.xul b/system/docshell/test/chrome/bug92598_window.xul new file mode 100644 index 000000000..ed877b383 --- /dev/null +++ b/system/docshell/test/chrome/bug92598_window.xul @@ -0,0 +1,118 @@ +<?xml version="1.0"?> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="92598Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="onLoad();" + title="92598 test"> + + <script type="application/javascript"><![CDATA[ + const LISTEN_EVENTS = ["load", "unload", "pageshow", "pagehide"]; + + var gBrowser; + var gTestsIterator; + var gExpected = []; + + function ok(condition, message) { + window.opener.wrappedJSObject.SimpleTest.ok(condition, message); + } + + function is(a, b, message) { + window.opener.wrappedJSObject.SimpleTest.is(a, b, message); + } + + function finish() { + for (let eventType of LISTEN_EVENTS) { + gBrowser.removeEventListener(eventType, eventListener, true); + } + + // Work around bug 467960 + var history = gBrowser.webNavigation.sessionHistory; + history.PurgeHistory(history.count); + + window.close(); + window.opener.wrappedJSObject.SimpleTest.finish(); + } + + function onLoad() { + gBrowser = document.getElementById("content"); + for (let eventType of LISTEN_EVENTS) { + gBrowser.addEventListener(eventType, eventListener, true); + } + + gTestsIterator = testsIterator(); + nextTest(); + } + + function eventListener(event) { + ok(gExpected.length >= 1, "Unexpected event " + event.type); + if (gExpected.length == 0) { + // in case of unexpected event, try to continue anyway + setTimeout(nextTest, 0); + return; + } + + var exp = gExpected.shift(); + is(event.type, exp.type, "Invalid event received"); + if (typeof(exp.persisted) != "undefined") { + is(event.persisted, exp.persisted, "Invalid persisted state"); + } + if (exp.title) { + ok(event.originalTarget instanceof HTMLDocument, + "originalTarget not a HTMLDocument"); + is(event.originalTarget.title, exp.title, "titles don't match"); + } + + if (gExpected.length == 0) { + setTimeout(nextTest, 0); + } + } + + function nextTest() { + try { + gTestsIterator.next(); + } catch (err if err instanceof StopIteration) { + finish(); + } + } + + function testsIterator() { + // Load a page with a no-cache header, followed by a simple page + // On pagehide, first page should report it is not being persisted + var test1DocURI = "http://mochi.test:8888/tests/docshell/test/chrome/92598_nostore.html"; + + gExpected = [{type: "pagehide", persisted: true}, + {type: "load", title: "test1"}, + {type: "pageshow", title: "test1", persisted: false}]; + gBrowser.loadURI(test1DocURI); + yield undefined; + + var test2Doc = "data:text/html,<html><head><title>test2</title></head>" + + "<body>test2</body></html>"; + + gExpected = [{type: "pagehide", title: "test1", persisted: false}, + {type: "unload", title: "test1"}, + {type: "load", title: "test2"}, + {type: "pageshow", title: "test2", persisted: false}]; + gBrowser.loadURI(test2Doc); + yield undefined; + + // Now go back in history. First page should not have been cached. + // Check persisted property to confirm + gExpected = [{type: "pagehide", title: "test2", persisted: true}, + {type: "load", title: "test1"}, + {type: "pageshow", title: "test1", persisted: false}]; + gBrowser.goBack(); + yield undefined; + } + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/chrome/chrome.ini b/system/docshell/test/chrome/chrome.ini new file mode 100644 index 000000000..c3c5b9f80 --- /dev/null +++ b/system/docshell/test/chrome/chrome.ini @@ -0,0 +1,88 @@ +[DEFAULT] +skip-if = os == 'android' +support-files = + 662200a.html + 662200b.html + 662200c.html + 89419.html + 92598_nostore.html + bug112564_window.xul + bug113934_window.xul + bug215405_window.xul + bug293235.html + bug293235_p2.html + bug293235_window.xul + bug294258_testcase.html + bug294258_window.xul + bug298622_window.xul + bug301397_1.html + bug301397_2.html + bug301397_3.html + bug301397_4.html + bug301397_window.xul + bug303267.html + bug303267_window.xul + bug311007_window.xul + bug321671_window.xul + bug360511_case1.html + bug360511_case2.html + bug360511_window.xul + bug364461_window.xul + bug396519_window.xul + bug396649_window.xul + bug449778_window.xul + bug449780_window.xul + bug454235-subframe.xul + bug582176_window.xul + bug608669.xul + bug662200_window.xul + bug690056_window.xul + bug846906.html + bug89419_window.xul + bug909218.html + bug909218.js + bug92598_window.xul + docshell_helpers.js + file_viewsource_forbidden_in_iframe.html + generic.html + mozFrameType_window.xul + +[test_allowContentRetargeting.html] +[test_bug112564.xul] +[test_bug113934.xul] +[test_bug215405.xul] +[test_bug293235.xul] +[test_bug294258.xul] +[test_bug298622.xul] +[test_bug301397.xul] +[test_bug303267.xul] +[test_bug311007.xul] +[test_bug321671.xul] +[test_bug360511.xul] +[test_bug364461.xul] +[test_bug396519.xul] +[test_bug396649.xul] +[test_bug428288.html] +[test_bug449778.xul] +[test_bug449780.xul] +[test_bug453650.xul] +[test_bug454235.xul] +# bug 684176 +skip-if = toolkit == "gtk2" +[test_bug456980.xul] +[test_bug565388.xul] +skip-if = os == 'linux' || os == 'mac' # Bug 1026815 +[test_bug582176.xul] +[test_bug608669.xul] +[test_bug662200.xul] +[test_bug690056.xul] +[test_bug789773.xul] +[test_bug846906.xul] +[test_bug89419.xul] +[test_bug909218.html] +[test_bug92598.xul] +[test_mozFrameType.xul] +[test_principalInherit.xul] +[test_private_hidden_window.html] +[test_viewsource_forbidden_in_iframe.xul] +skip-if = true # bug 1019315 diff --git a/system/docshell/test/chrome/docshell_helpers.js b/system/docshell/test/chrome/docshell_helpers.js new file mode 100644 index 000000000..2d55e5a6e --- /dev/null +++ b/system/docshell/test/chrome/docshell_helpers.js @@ -0,0 +1,496 @@ +/** + * Import common SimpleTest methods so that they're usable in this window. + */ +var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror", "todo", + "todo_is", "todo_isnot" ]; +for (var name of imports) { + window[name] = window.opener.wrappedJSObject[name]; +} + +/** + * Define global constants and variables. + */ +const NAV_NONE = 0; +const NAV_BACK = 1; +const NAV_FORWARD = 2; +const NAV_URI = 3; +const NAV_RELOAD = 4; + +var gExpectedEvents; // an array of events which are expected to + // be triggered by this navigation +var gUnexpectedEvents; // an array of event names which are NOT expected + // to be triggered by this navigation +var gFinalEvent; // true if the last expected event has fired +var gUrisNotInBFCache = []; // an array of uri's which shouldn't be stored + // in the bfcache +var gNavType = NAV_NONE; // defines the most recent navigation type + // executed by doPageNavigation +var gOrigMaxTotalViewers = // original value of max_total_viewers, + undefined; // to be restored at end of test + +var gExtractedPath = null; //used to cache file path for extracting files from a .jar file + +/** + * The doPageNavigation() function performs page navigations asynchronously, + * listens for specified events, and compares actual events with a list of + * expected events. When all expected events have occurred, an optional + * callback can be notified. The parameter passed to this function is an + * object with the following properties: + * + * uri: if !undefined, the browser will navigate to this uri + * + * back: if true, the browser will execute goBack() + * + * forward: if true, the browser will execute goForward() + * + * reload: if true, the browser will execute reload() + * + * eventsToListenFor: an array containing one or more of the following event + * types to listen for: "pageshow", "pagehide", "onload", + * "onunload". If this property is undefined, only a + * single "pageshow" events will be listened for. If this + * property is explicitly empty, [], then no events will + * be listened for. + * + * expectedEvents: an array of one or more expectedEvent objects, + * corresponding to the events which are expected to be + * fired for this navigation. Each object has the + * following properties: + * + * type: one of the event type strings + * title (optional): the title of the window the + * event belongs to + * persisted (optional): the event's expected + * .persisted attribute + * + * This function will verify that events with the + * specified properties are fired in the same order as + * specified in the array. If .title or .persisted + * properties for an expectedEvent are undefined, those + * properties will not be verified for that particular + * event. + * + * This property is ignored if eventsToListenFor is + * undefined or []. + * + * preventBFCache: if true, an unload handler will be added to the loaded + * page to prevent it from being bfcached. This property + * has no effect when eventsToListenFor is []. + * + * onNavComplete: a callback which is notified after all expected events + * have occurred, or after a timeout has elapsed. This + * callback is not notified if eventsToListenFor is []. + * + * There must be an expectedEvent object for each event of the types in + * eventsToListenFor which is triggered by this navigation. For example, if + * eventsToListenFor = [ "pagehide", "pageshow" ], then expectedEvents + * must contain an object for each pagehide and pageshow event which occurs as + * a result of this navigation. + */ +function doPageNavigation(params) { + // Parse the parameters. + let back = params.back ? params.back : false; + let forward = params.forward ? params.forward : false; + let reload = params.reload ? params.reload : false; + let uri = params.uri ? params.uri : false; + let eventsToListenFor = typeof(params.eventsToListenFor) != "undefined" ? + params.eventsToListenFor : ["pageshow"]; + gExpectedEvents = typeof(params.eventsToListenFor) == "undefined" || + eventsToListenFor.length == 0 ? undefined : params.expectedEvents; + gUnexpectedEvents = typeof(params.eventsToListenFor) == "undefined" || + eventsToListenFor.length == 0 ? undefined : params.unexpectedEvents; + let preventBFCache = (typeof[params.preventBFCache] == "undefined") ? + false : params.preventBFCache; + let waitOnly = (typeof(params.waitForEventsOnly) == "boolean" + && params.waitForEventsOnly); + + // Do some sanity checking on arguments. + if (back && forward) + throw "Can't specify both back and forward"; + if (back && uri) + throw "Can't specify both back and a uri"; + if (forward && uri) + throw "Can't specify both forward and a uri"; + if (reload && (forward || back || uri)) + throw "Can't specify reload and another navigation type"; + if (!back && !forward && !uri && !reload && !waitOnly) + throw "Must specify back or foward or reload or uri"; + if (params.onNavComplete && eventsToListenFor.length == 0) + throw "Can't use onNavComplete when eventsToListenFor == []"; + if (params.preventBFCache && eventsToListenFor.length == 0) + throw "Can't use preventBFCache when eventsToListenFor == []"; + if (params.preventBFCache && waitOnly) + throw "Can't prevent bfcaching when only waiting for events"; + if (waitOnly && typeof(params.onNavComplete) == "undefined") + throw "Must specify onNavComplete when specifying waitForEventsOnly"; + if (waitOnly && (back || forward || reload || uri)) + throw "Can't specify a navigation type when using waitForEventsOnly"; + for (let anEventType of eventsToListenFor) { + let eventFound = false; + if ( (anEventType == "pageshow") && (!gExpectedEvents) ) + eventFound = true; + if (gExpectedEvents) { + for (let anExpectedEvent of gExpectedEvents) { + if (anExpectedEvent.type == anEventType) + eventFound = true; + } + } + if (gUnexpectedEvents) { + for (let anExpectedEventType of gUnexpectedEvents) { + if (anExpectedEventType == anEventType) + eventFound = true; + } + } + if (!eventFound) + throw "Event type " + anEventType + " is specified in " + + "eventsToListenFor, but not in expectedEvents"; + } + + // If the test explicitly sets .eventsToListenFor to [], don't wait for any + // events. + gFinalEvent = eventsToListenFor.length == 0 ? true : false; + + // Add an event listener for each type of event in the .eventsToListenFor + // property of the input parameters. + for (let eventType of eventsToListenFor) { + dump("TEST: registering a listener for " + eventType + " events\n"); + TestWindow.getBrowser().addEventListener(eventType, pageEventListener, + true); + } + + // Perform the specified navigation. + if (back) { + gNavType = NAV_BACK; + TestWindow.getBrowser().goBack(); + } + else if (forward) { + gNavType = NAV_FORWARD; + TestWindow.getBrowser().goForward(); + } + else if (uri) { + gNavType = NAV_URI; + TestWindow.getBrowser().loadURI(uri); + } + else if (reload) { + gNavType = NAV_RELOAD; + TestWindow.getBrowser().reload(); + } + else if (waitOnly) { + gNavType = NAV_NONE; + } + else { + throw "No valid navigation type passed to doPageNavigation!"; + } + + // If we're listening for events and there is an .onNavComplete callback, + // wait for all events to occur, and then call doPageNavigation_complete(). + if (eventsToListenFor.length > 0 && params.onNavComplete) + { + waitForTrue( + function() { return gFinalEvent; }, + function() { + doPageNavigation_complete(eventsToListenFor, params.onNavComplete, + preventBFCache); + } ); + } +} + +/** + * Finish doPageNavigation(), by removing event listeners, adding an unload + * handler if appropriate, and calling the onNavComplete callback. This + * function is called after all the expected events for this navigation have + * occurred. + */ +function doPageNavigation_complete(eventsToListenFor, onNavComplete, + preventBFCache) { + // Unregister our event listeners. + dump("TEST: removing event listeners\n"); + for (let eventType of eventsToListenFor) { + TestWindow.getBrowser().removeEventListener(eventType, pageEventListener, + true); + } + + // If the .preventBFCache property was set, add an empty unload handler to + // prevent the page from being bfcached. + let uri = TestWindow.getBrowser().currentURI.spec; + if (preventBFCache) { + TestWindow.getWindow().addEventListener("unload", function() { + dump("TEST: Called dummy unload function to prevent page from " + + "being bfcached.\n"); + }, true); + + // Save the current uri in an array of uri's which shouldn't be + // stored in the bfcache, for later verification. + if (!(uri in gUrisNotInBFCache)) { + gUrisNotInBFCache.push(uri); + } + } else if (gNavType == NAV_URI) { + // If we're navigating to a uri and .preventBFCache was not + // specified, splice it out of gUrisNotInBFCache if it's there. + gUrisNotInBFCache.forEach( + function(element, index, array) { + if (element == uri) { + array.splice(index, 1); + } + }, this); + } + + // Notify the callback now that we're done. + onNavComplete.call(); +} + +/** + * Allows a test to wait for page navigation events, and notify a + * callback when they've all been received. This works exactly the + * same as doPageNavigation(), except that no navigation is initiated. + */ +function waitForPageEvents(params) { + params.waitForEventsOnly = true; + doPageNavigation(params); +} + +/** + * The event listener which listens for expectedEvents. + */ +function pageEventListener(event) { + try { + dump("TEST: eventListener received a " + event.type + " event for page " + + event.originalTarget.title + ", persisted=" + event.persisted + "\n"); + } catch(e) { + // Ignore any exception. + } + + // If this page shouldn't be in the bfcache because it was previously + // loaded with .preventBFCache, make sure that its pageshow event + // has .persisted = false, even if the test doesn't explicitly test + // for .persisted. + if ( (event.type == "pageshow") && + (gNavType == NAV_BACK || gNavType == NAV_FORWARD) ) { + let uri = TestWindow.getBrowser().currentURI.spec; + if (uri in gUrisNotInBFCache) { + ok(!event.persisted, "pageshow event has .persisted = false, even " + + "though it was loaded with .preventBFCache previously\n"); + } + } + + if (typeof(gUnexpectedEvents) != "undefined") { + is(gUnexpectedEvents.indexOf(event.type), -1, + "Should not get unexpected event " + event.type); + } + + // If no expected events were specified, mark the final event as having been + // triggered when a pageshow event is fired; this will allow + // doPageNavigation() to return. + if ((typeof(gExpectedEvents) == "undefined") && event.type == "pageshow") + { + setTimeout(function() { gFinalEvent = true; }, 0); + return; + } + + // If there are explicitly no expected events, but we receive one, it's an + // error. + if (gExpectedEvents.length == 0) { + ok(false, "Unexpected event (" + event.type + ") occurred"); + return; + } + + // Grab the next expected event, and compare its attributes against the + // actual event. + let expected = gExpectedEvents.shift(); + + is(event.type, expected.type, + "A " + expected.type + " event was expected, but a " + + event.type + " event occurred"); + + if (typeof(expected.title) != "undefined") { + ok(event.originalTarget instanceof HTMLDocument, + "originalTarget for last " + event.type + + " event not an HTMLDocument"); + is(event.originalTarget.title, expected.title, + "A " + event.type + " event was expected for page " + + expected.title + ", but was fired for page " + + event.originalTarget.title); + } + + if (typeof(expected.persisted) != "undefined") { + is(event.persisted, expected.persisted, + "The persisted property of the " + event.type + " event on page " + + event.originalTarget.location + " had an unexpected value"); + } + + if ("visibilityState" in expected) { + is(event.originalTarget.visibilityState, expected.visibilityState, + "The visibilityState property of the document on page " + + event.originalTarget.location + " had an unexpected value"); + } + + if ("hidden" in expected) { + is(event.originalTarget.hidden, expected.hidden, + "The hidden property of the document on page " + + event.originalTarget.location + " had an unexpected value"); + } + + // If we're out of expected events, let doPageNavigation() return. + if (gExpectedEvents.length == 0) + setTimeout(function() { gFinalEvent = true; }, 0); +} + +/** + * End a test. + */ +function finish() { + // Work around bug 467960. + var history = TestWindow.getBrowser().webNavigation.sessionHistory; + history.PurgeHistory(history.count); + + // If the test changed the value of max_total_viewers via a call to + // enableBFCache(), then restore it now. + if (typeof(gOrigMaxTotalViewers) != "undefined") { + var prefs = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Components.interfaces.nsIPrefBranch); + prefs.setIntPref("browser.sessionhistory.max_total_viewers", + gOrigMaxTotalViewers); + } + + // Close the test window and signal the framework that the test is done. + let opener = window.opener; + let SimpleTest = opener.wrappedJSObject.SimpleTest; + + // Wait for the window to be closed before finishing the test + let ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] + .getService(Components.interfaces.nsIWindowWatcher); + ww.registerNotification(function(subject, topic, data) { + if (topic == "domwindowclosed") { + ww.unregisterNotification(arguments.callee); + SimpleTest.waitForFocus(SimpleTest.finish, opener); + } + }); + + window.close(); +} + +/** + * Helper function which waits until another function returns true, or until a + * timeout occurs, and then notifies a callback. + * + * Parameters: + * + * fn: a function which is evaluated repeatedly, and when it turns true, + * the onWaitComplete callback is notified. + * + * onWaitComplete: a callback which will be notified when fn() returns + * true, or when a timeout occurs. + * + * timeout: a timeout, in seconds or ms, after which waitForTrue() will + * fail an assertion and then return, even if the fn function never + * returns true. If timeout is undefined, waitForTrue() will never + * time out. + */ +function waitForTrue(fn, onWaitComplete, timeout) { + var start = new Date().valueOf(); + if (typeof(timeout) != "undefined") { + // If timeoutWait is less than 500, assume it represents seconds, and + // convert to ms. + if (timeout < 500) + timeout *= 1000; + } + + // Loop until the test function returns true, or until a timeout occurs, + // if a timeout is defined. + var intervalid; + intervalid = + setInterval( + function() { + var timeoutHit = false; + if (typeof(timeout) != "undefined") { + timeoutHit = new Date().valueOf() - start >= + timeout ? true : false; + if (timeoutHit) { + ok(false, "Timed out waiting for condition"); + } + } + if (timeoutHit || fn.call()) { + // Stop calling the test function and notify the callback. + clearInterval(intervalid); + onWaitComplete.call(); + } + }, 20); +} + +/** + * Enable or disable the bfcache. + * + * Parameters: + * + * enable: if true, set max_total_viewers to -1 (the default); if false, set + * to 0 (disabled), if a number, set it to that specific number + */ +function enableBFCache(enable) { + var prefs = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Components.interfaces.nsIPrefBranch); + + // If this is the first time the test called enableBFCache(), + // store the original value of max_total_viewers, so it can + // be restored at the end of the test. + if (typeof(gOrigMaxTotalViewers) == "undefined") { + gOrigMaxTotalViewers = + prefs.getIntPref("browser.sessionhistory.max_total_viewers"); + } + + if (typeof(enable) == "boolean") { + if (enable) + prefs.setIntPref("browser.sessionhistory.max_total_viewers", -1); + else + prefs.setIntPref("browser.sessionhistory.max_total_viewers", 0); + } + else if (typeof(enable) == "number") { + prefs.setIntPref("browser.sessionhistory.max_total_viewers", enable); + } +} + +/* + * get http root for local tests. Use a single extractJarToTmp instead of + * extracting for each test. + * Returns a file://path if we have a .jar file + */ +function getHttpRoot() { + var location = window.location.href; + location = getRootDirectory(location); + var jar = getJar(location); + if (jar != null) { + if (gExtractedPath == null) { + var resolved = extractJarToTmp(jar); + gExtractedPath = resolved.path; + } + } else { + return null; + } + return "file://" + gExtractedPath + '/'; +} + +/** + * Returns the full HTTP url for a file in the mochitest docshell test + * directory. + */ +function getHttpUrl(filename) { + var root = getHttpRoot(); + if (root == null) { + root = "http://mochi.test:8888/chrome/docshell/test/chrome/"; + } + return root + filename; +} + +/** + * A convenience object with methods that return the current test window, + * browser, and document. + */ +var TestWindow = {}; +TestWindow.getWindow = function () { + return document.getElementById("content").contentWindow; +} +TestWindow.getBrowser = function () { + return document.getElementById("content"); +} +TestWindow.getDocument = function () { + return document.getElementById("content").contentDocument; +} diff --git a/system/docshell/test/chrome/file_viewsource_forbidden_in_iframe.html b/system/docshell/test/chrome/file_viewsource_forbidden_in_iframe.html new file mode 100644 index 000000000..fdecbbdfe --- /dev/null +++ b/system/docshell/test/chrome/file_viewsource_forbidden_in_iframe.html @@ -0,0 +1,11 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>Test ifranes for view-source forbidden in iframe tests</title> +</head> +<body> + <iframe id="testIframe"></iframe> + <iframe id="refIframe"></iframe> +</body> +</html> diff --git a/system/docshell/test/chrome/gen_template.pl b/system/docshell/test/chrome/gen_template.pl new file mode 100644 index 000000000..5fe9e9ea4 --- /dev/null +++ b/system/docshell/test/chrome/gen_template.pl @@ -0,0 +1,39 @@ +#!/usr/bin/perl + +# This script makes docshell test case templates. It takes one argument: +# +# -b: a bugnumber +# +# For example, this command: +# +# perl gen_template.pl -b 303267 +# +# Writes test case template files test_bug303267.xul and bug303267_window.xul +# to the current directory. + +use FindBin; +use Getopt::Long; +GetOptions("b=i"=> \$bug_number); + +$template = "$FindBin::RealBin/test.template.txt"; + +open(IN,$template) or die("Failed to open input file for reading."); +open(OUT, ">>test_bug" . $bug_number . ".xul") or die("Failed to open output file for appending."); +while((defined(IN)) && ($line = <IN>)) { + $line =~ s/{BUGNUMBER}/$bug_number/g; + print OUT $line; +} +close(IN); +close(OUT); + +$template = "$FindBin::RealBin/window.template.txt"; + +open(IN,$template) or die("Failed to open input file for reading."); +open(OUT, ">>bug" . $bug_number . "_window.xul") or die("Failed to open output file for appending."); +while((defined(IN)) && ($line = <IN>)) { + $line =~ s/{BUGNUMBER}/$bug_number/g; + print OUT $line; +} +close(IN); +close(OUT); + diff --git a/system/docshell/test/chrome/generic.html b/system/docshell/test/chrome/generic.html new file mode 100644 index 000000000..569a78c05 --- /dev/null +++ b/system/docshell/test/chrome/generic.html @@ -0,0 +1,12 @@ +<html> +<head> + <title> + generic page + </title> + </head> +<body> +<div id="div1" style="height: 1000px; border: thin solid black;"> + A generic page which can be used any time a test needs to load an arbitrary page via http. + </div> +</body> +</html> diff --git a/system/docshell/test/chrome/mozFrameType_window.xul b/system/docshell/test/chrome/mozFrameType_window.xul new file mode 100644 index 000000000..aa811c333 --- /dev/null +++ b/system/docshell/test/chrome/mozFrameType_window.xul @@ -0,0 +1,57 @@ +<?xml version="1.0"?> +<!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +<window title="Test mozFrameType attribute" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="runTests();"> + + <html:iframe id="normalFrame"/> + <html:iframe id="typeContentFrame" mozframetype="content"/> + + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + function runTests() { + let opener = window.opener; + let SimpleTest = opener.wrappedJSObject.SimpleTest; + + let Ci = Components.interfaces; + + function getDocShellType(frame) { + return frame.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDocShell) + .QueryInterface(Ci.nsIDocShellTreeItem) + .itemType; + } + + var normalFrame = document.getElementById("normalFrame"); + var typeContentFrame = document.getElementById("typeContentFrame"); + + SimpleTest.is(getDocShellType(normalFrame), Ci.nsIDocShellTreeItem.typeChrome, + "normal iframe in chrome document is typeChrome"); + SimpleTest.is(getDocShellType(typeContentFrame), Ci.nsIDocShellTreeItem.typeContent, + "iframe with mozFrameType='content' in chrome document is typeContent"); + + SimpleTest.executeSoon(function () { + // First focus the parent window and then close this one. + SimpleTest.waitForFocus(function() { + let ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] + .getService(Components.interfaces.nsIWindowWatcher); + ww.registerNotification(function windowObs(subject, topic, data) { + if (topic == "domwindowclosed") { + ww.unregisterNotification(windowObs); + + // Don't start the next test synchronously! + SimpleTest.executeSoon(function() { + SimpleTest.finish(); + }); + } + }); + + window.close(); + }, opener); + }); + } + ]]></script> +</window> + diff --git a/system/docshell/test/chrome/red.png b/system/docshell/test/chrome/red.png Binary files differnew file mode 100644 index 000000000..aa9ce2526 --- /dev/null +++ b/system/docshell/test/chrome/red.png diff --git a/system/docshell/test/chrome/test.template.txt b/system/docshell/test/chrome/test.template.txt new file mode 100644 index 000000000..b7dd5e5c2 --- /dev/null +++ b/system/docshell/test/chrome/test.template.txt @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id={BUGNUMBER}.xul +--> +<window title="Mozilla Bug {BUGNUMBER}" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <title>Test for Bug {BUGNUMBER}</title> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id={BUGNUMBER}"> + Mozilla Bug {BUGNUMBER}</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug {BUGNUMBER} **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug{BUGNUMBER}_window.xul", "bug{BUGNUMBER}", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_allowContentRetargeting.html b/system/docshell/test/chrome/test_allowContentRetargeting.html new file mode 100644 index 000000000..58e838ca0 --- /dev/null +++ b/system/docshell/test/chrome/test_allowContentRetargeting.html @@ -0,0 +1,94 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runNextTest); + +var TEST_URL = "http://mochi.test:8888/tests/docshell/test/chrome/allowContentRetargeting.sjs"; + +var Ci = Components.interfaces; + +function runNextTest() { + var test = tests.shift(); + if (!test) { + SimpleTest.finish(); + return; + } + test(); +} + +var tests = [ + + // Set allowContentRetargeting = false, load a downloadable URL, verify the + // downloadable stops loading. + function basic() { + var iframe = insertIframe(); + docshellForWindow(iframe.contentWindow).allowContentRetargeting = false; + loadIframe(iframe); + }, + + // Set allowContentRetargeting = false on parent docshell, load a downloadable + // URL, verify the downloadable stops loading. + function inherit() { + var docshell = docshellForWindow(window); + docshell.allowContentRetargeting = false; + loadIframe(insertIframe()); + }, +]; + +function docshellForWindow(win) { + return win. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebNavigation). + QueryInterface(Ci.nsIDocShell); +} + +function insertIframe() { + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + return iframe; +} + +function loadIframe(iframe) { + iframe.setAttribute("src", TEST_URL); + docshellForWindow(iframe.contentWindow). + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebProgress). + addProgressListener(progressListener, + Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT); +} + +var progressListener = { + onStateChange: function (webProgress, req, flags, status) { + if (!(flags & Ci.nsIWebProgressListener.STATE_STOP)) + return; + is(Components.isSuccessCode(status), false, + "Downloadable should have failed to load"); + document.querySelector("iframe").remove(); + runNextTest(); + }, + + QueryInterface: function (iid) { + var iids = [ + Ci.nsIWebProgressListener, + Ci.nsISupportsWeakReference, + Ci.nsISupports, + ]; + if (iids.some(function (i) { return iid.equals(i); })) + return this; + throw Components.results.NS_ERROR_NO_INTERFACE; + }, +}; + + </script> +</head> +<body> +<p id="display"> +</p> +</body> +</html> diff --git a/system/docshell/test/chrome/test_bug112564.xul b/system/docshell/test/chrome/test_bug112564.xul new file mode 100644 index 000000000..0706595d0 --- /dev/null +++ b/system/docshell/test/chrome/test_bug112564.xul @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=112564 +--> +<window title="Mozilla Bug 112564" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=112564">Mozilla Bug 112564</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 112564 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug112564_window.xul", "bug112564", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug113934.xul b/system/docshell/test/chrome/test_bug113934.xul new file mode 100644 index 000000000..ba297e035 --- /dev/null +++ b/system/docshell/test/chrome/test_bug113934.xul @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=113934 +--> +<window title="Mozilla Bug 113934" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=113934" + target="_blank">Mozilla Bug 396519</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + window.open("bug113934_window.xul?content", "bug113934", + "chrome,width=800,height=800"); + }); + + ]]></script> +</window> diff --git a/system/docshell/test/chrome/test_bug215405.xul b/system/docshell/test/chrome/test_bug215405.xul new file mode 100644 index 000000000..e934d76ca --- /dev/null +++ b/system/docshell/test/chrome/test_bug215405.xul @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=215405 +--> +<window title="Mozilla Bug 215405" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=215405">Mozilla Bug 215405</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 215405 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug215405_window.xul", "bug215405", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug293235.xul b/system/docshell/test/chrome/test_bug293235.xul new file mode 100644 index 000000000..8a42c0a6e --- /dev/null +++ b/system/docshell/test/chrome/test_bug293235.xul @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=293235.xul +--> +<window title="Mozilla Bug 293235" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=293235"> + Mozilla Bug 293235</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 293235 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug293235_window.xul", "bug293235", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug294258.xul b/system/docshell/test/chrome/test_bug294258.xul new file mode 100644 index 000000000..4658a82de --- /dev/null +++ b/system/docshell/test/chrome/test_bug294258.xul @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=294258.xul +--> +<window title="Mozilla Bug 294258" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=294258"> + Mozilla Bug 294258</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 294258 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug294258_window.xul", "bug294258", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug298622.xul b/system/docshell/test/chrome/test_bug298622.xul new file mode 100644 index 000000000..c3217c7e5 --- /dev/null +++ b/system/docshell/test/chrome/test_bug298622.xul @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=298622.xul +--> +<window title="Mozilla Bug 298622" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=298622"> + Mozilla Bug 298622</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 298622 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug298622_window.xul", "bug298622", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug301397.xul b/system/docshell/test/chrome/test_bug301397.xul new file mode 100644 index 000000000..37fe47993 --- /dev/null +++ b/system/docshell/test/chrome/test_bug301397.xul @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=301397.xul +--> +<window title="Mozilla Bug 301397" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=301397"> + Mozilla Bug 301397</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 301397 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug301397_window.xul", "bug301397", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug303267.xul b/system/docshell/test/chrome/test_bug303267.xul new file mode 100644 index 000000000..f68dbdcd2 --- /dev/null +++ b/system/docshell/test/chrome/test_bug303267.xul @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=303267.xul +--> +<window title="Mozilla Bug 303267" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=303267">Mozilla Bug 303267</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +SimpleTest.expectAssertions(0, 1); + +/** Test for Bug 303267 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug303267_window.xul", "bug303267", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug311007.xul b/system/docshell/test/chrome/test_bug311007.xul new file mode 100644 index 000000000..32f1085f0 --- /dev/null +++ b/system/docshell/test/chrome/test_bug311007.xul @@ -0,0 +1,45 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=311007.xul +--> +<window title="Mozilla Bug 311007" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/MochiKit/packed.js"></script> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=311007"> + Mozilla Bug 311007</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +if (navigator.platform.startsWith("Win")) { + SimpleTest.expectAssertions(0, 1); +} + +/** Test for Bug 311007 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug311007_window.xul", "bug311007", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug321671.xul b/system/docshell/test/chrome/test_bug321671.xul new file mode 100644 index 000000000..46164018b --- /dev/null +++ b/system/docshell/test/chrome/test_bug321671.xul @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=321671.xul +--> +<window title="Mozilla Bug 321671" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=321671"> + Mozilla Bug 321671</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 321671 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug321671_window.xul", "bug321671", + "chrome,width=600,height=600,scrollbars"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug360511.xul b/system/docshell/test/chrome/test_bug360511.xul new file mode 100644 index 000000000..ffa47fa27 --- /dev/null +++ b/system/docshell/test/chrome/test_bug360511.xul @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=360511.xul +--> +<window title="Mozilla Bug 360511" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"> + </script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=360511"> + Mozilla Bug 360511</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 360511 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug360511_window.xul", "bug360511", + "chrome,scrollbars,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug364461.xul b/system/docshell/test/chrome/test_bug364461.xul new file mode 100644 index 000000000..9e45ce971 --- /dev/null +++ b/system/docshell/test/chrome/test_bug364461.xul @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=364461 +--> +<window title="Mozilla Bug 364461" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=364461">Mozilla Bug 364461</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 364461 **/ + +SimpleTest.waitForExplicitFinish(); + +SpecialPowers.pushPrefEnv({ + "set":[["security.data_uri.block_toplevel_data_uri_navigations", false]] +}, runTests); + +function runTests() { + window.open("bug364461_window.xul", "bug364461", + "chrome,width=600,height=600"); +} +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug396519.xul b/system/docshell/test/chrome/test_bug396519.xul new file mode 100644 index 000000000..be1d148b7 --- /dev/null +++ b/system/docshell/test/chrome/test_bug396519.xul @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=396519 +--> +<window title="Mozilla Bug 396519" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=396519" + target="_blank">Mozilla Bug 396519</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 396519 **/ + + SimpleTest.waitForExplicitFinish(); + window.open("bug396519_window.xul", "bug396519", + "chrome,width=600,height=600"); + + ]]></script> +</window> diff --git a/system/docshell/test/chrome/test_bug396649.xul b/system/docshell/test/chrome/test_bug396649.xul new file mode 100644 index 000000000..3554c2f98 --- /dev/null +++ b/system/docshell/test/chrome/test_bug396649.xul @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=396649.xul +--> +<window title="Mozilla Bug 396649" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src= + "chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"> + </script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=396649"> + Mozilla Bug 396649</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 396649 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug396649_window.xul", "bug396649", + "chrome,width=600,height=600,scrollbars"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug428288.html b/system/docshell/test/chrome/test_bug428288.html new file mode 100644 index 000000000..83fcd20c6 --- /dev/null +++ b/system/docshell/test/chrome/test_bug428288.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=428288 +--> +<head> + <title>Test for Bug 428288</title> + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=428288">Mozilla Bug 428288</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe name="target"></iframe> + <a id="crashy" target="target" href="about:blank">crash me</a> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 428288 **/ + +function makeClick() { + var event = document.createEvent("MouseEvents"); + event.initMouseEvent("click", true, true, window, 0, 0,0,0,0, + false, false, false, false, 0, null); + document.getElementById("crashy").dispatchEvent(event); + return true; +} + +ok(makeClick(), "Crashes if bug 428288 is present"); + +</script> +</pre> +</body> +</html> + diff --git a/system/docshell/test/chrome/test_bug449778.xul b/system/docshell/test/chrome/test_bug449778.xul new file mode 100644 index 000000000..48c76c2e2 --- /dev/null +++ b/system/docshell/test/chrome/test_bug449778.xul @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=449778 +--> +<window title="Mozilla Bug 449778" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=449778" + target="_blank">Mozilla Bug 396519</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + window.open("bug449778_window.xul", "bug449778", + "chrome,width=800,height=800"); + }); + + ]]></script> +</window> diff --git a/system/docshell/test/chrome/test_bug449780.xul b/system/docshell/test/chrome/test_bug449780.xul new file mode 100644 index 000000000..fc5231d6b --- /dev/null +++ b/system/docshell/test/chrome/test_bug449780.xul @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=449780 +--> +<window title="Mozilla Bug 449780" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=449780" + target="_blank">Mozilla Bug 396519</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + window.open("bug449780_window.xul", "bug449780", + "chrome,width=800,height=800"); + }); + + ]]></script> +</window> diff --git a/system/docshell/test/chrome/test_bug453650.xul b/system/docshell/test/chrome/test_bug453650.xul new file mode 100644 index 000000000..04acefe6d --- /dev/null +++ b/system/docshell/test/chrome/test_bug453650.xul @@ -0,0 +1,115 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=453650 +--> +<window title="Mozilla Bug 453650" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 453650 **/ + SimpleTest.waitForExplicitFinish(); + + var Ci = Components.interfaces; + var Cr = Components.results; + + var iter = runTests(); + nextTest(); + + function runTests() { + var iframe = document.createElement("iframe"); + iframe.style.width = "300px"; + iframe.style.height = "300px"; + iframe.setAttribute("src", "data:text/html,<h1 id='h'>hello</h1>"); + + document.documentElement.appendChild(iframe); + yield whenLoaded(iframe); + info("iframe loaded"); + + var h1 = iframe.contentDocument.getElementById("h"); + h1.style.width = "400px"; + yield waitForInterruptibleReflow(iframe.docShell); + + h1.style.width = "300px"; + waitForReflow(iframe.docShell); + yield is(300, h1.offsetWidth, "h1 has correct width"); + } + + function waitForInterruptibleReflow(docShell) { + waitForReflow(docShell, true); + } + + function waitForReflow(docShell, interruptible = false) { + function done() { + docShell.removeWeakReflowObserver(observer); + SimpleTest.executeSoon(nextTest); + } + + var observer = { + reflow: function (start, end) { + if (interruptible) { + ok(false, "expected interruptible reflow"); + } else { + ok(true, "observed uninterruptible reflow"); + } + + info("times: " + start + ", " + end); + ok(start <= end, "reflow start time lower than end time"); + done(); + }, + + reflowInterruptible: function (start, end) { + if (!interruptible) { + ok(false, "expected uninterruptible reflow"); + } else { + ok(true, "observed interruptible reflow"); + } + + info("times: " + start + ", " + end); + ok(start <= end, "reflow start time lower than end time"); + done(); + }, + + QueryInterface: function (iid) { + if (Ci.nsIReflowObserver.equals(iid) || + Ci.nsISupportsWeakReference.equals(iid) || + Ci.nsISupports.equals(iid)) + return this; + throw Cr.NS_ERROR_NO_INTERFACE; + }, + }; + + docShell.addWeakReflowObserver(observer); + } + + function whenLoaded(iframe) { + iframe.addEventListener("load", function onLoad() { + iframe.removeEventListener("load", onLoad); + SimpleTest.executeSoon(nextTest); + }); + } + + function nextTest() { + try { + iter.next(); + } catch (e if e instanceof StopIteration) { + SimpleTest.finish(); + } + } + + ]]> + </script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=453650" + target="_blank">Mozilla Bug 453650</a> + </body> +</window> diff --git a/system/docshell/test/chrome/test_bug454235.xul b/system/docshell/test/chrome/test_bug454235.xul new file mode 100644 index 000000000..f9107a186 --- /dev/null +++ b/system/docshell/test/chrome/test_bug454235.xul @@ -0,0 +1,56 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=454235 +--> +<window title="Mozilla Bug 454235" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=454235" + target="_blank">Mozilla Bug 454235</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 454235 **/ +SimpleTest.waitForExplicitFinish(); + +SimpleTest.waitForFocus(doTest); + +function doTest() { + var shownBrowser = document.getElementById("shownBrowser"); + var hiddenBrowser = document.getElementById("hiddenBrowser"); + var offScreenBrowser = document.getElementById("offScreenBrowser"); + var offScreenSubBrowser = offScreenBrowser.contentDocument.getElementById("topBrowser"); + var offScreenBurriedBrowser = offScreenBrowser.contentDocument.getElementById("burriedBrowser"); + + hiddenBrowser.contentWindow.focus(); + ok(!hiddenBrowser.contentDocument.hasFocus(),"hidden browser is visible"); + + offScreenBrowser.docShell.isOffScreenBrowser = true; + offScreenBrowser.contentWindow.focus(); + ok(offScreenBrowser.contentDocument.hasFocus(),"offscreen browser is not visible"); + + offScreenSubBrowser.contentWindow.focus(); + todo(offScreenSubBrowser.contentDocument.hasFocus(),"visible browser in offscreen browser is not visible"); + + offScreenBurriedBrowser.contentWindow.focus(); + ok(!offScreenBurriedBrowser.contentDocument.hasFocus(),"hidden browser in offscreen browser is visible"); + + SimpleTest.finish(); +} + + + + ]]></script> + <box flex="1" style="visibility: hidden; border:5px black solid"> + <browser style="border:5px blue solid" id="hiddenBrowser" src="bug454235-subframe.xul"/> + <browser style="border:5px yellow solid" id="offScreenBrowser" src="bug454235-subframe.xul"/> + </box> +</window> diff --git a/system/docshell/test/chrome/test_bug456980.xul b/system/docshell/test/chrome/test_bug456980.xul new file mode 100644 index 000000000..9f4f97209 --- /dev/null +++ b/system/docshell/test/chrome/test_bug456980.xul @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=456980 +--> +<window title="Mozilla Bug 456980" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=456980" + target="_blank">Mozilla Bug 396519</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + window.open("bug113934_window.xul?chrome", "bug456980", + "chrome,width=800,height=800"); + }); + + ]]></script> +</window> diff --git a/system/docshell/test/chrome/test_bug565388.xul b/system/docshell/test/chrome/test_bug565388.xul new file mode 100644 index 000000000..47b5c07e4 --- /dev/null +++ b/system/docshell/test/chrome/test_bug565388.xul @@ -0,0 +1,83 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=565388 +--> +<window title="Mozilla Bug 565388" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 565388 **/ + SimpleTest.waitForExplicitFinish(); + + var Ci = Components.interfaces; + var Cc = Components.classes; + + var progressListener = { + add: function(docShell, callback) { + this.callback = callback; + this.docShell = docShell; + docShell. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebProgress). + addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_WINDOW); + }, + + finish: function() { + this.docShell. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebProgress). + removeProgressListener(this); + this.callback(); + }, + + onStateChange: function (webProgress, req, flags, status) { + if (req.name.startsWith("data:application/vnd.mozilla.xul")) { + if (flags & Ci.nsIWebProgressListener.STATE_STOP) + this.finish(); + } + }, + + QueryInterface: function(iid) { + if (iid.equals(Components.interfaces.nsIWebProgressListener) || + iid.equals(Components.interfaces.nsISupportsWeakReference)) + return this; + throw Components.results.NS_ERROR_NO_INTERFACE; + } + } + + var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]. + createInstance(Ci.nsIPrincipal); + var webNav = Cc["@mozilla.org/appshell/appShellService;1"]. + getService(Ci.nsIAppShellService). + createWindowlessBrowser(true); + var docShell = webNav. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIDocShell); + docShell.createAboutBlankContentViewer(systemPrincipal); + var win = docShell.contentViewer.DOMDocument.defaultView; + + progressListener.add(docShell, function(){ + is(win.document.documentURI, "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window/>"); + webNav.close(); + SimpleTest.finish(); + }); + + win.location = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window/>"; + + ]]> + </script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=565388" + target="_blank">Mozilla Bug 565388</a> + </body> +</window> diff --git a/system/docshell/test/chrome/test_bug582176.xul b/system/docshell/test/chrome/test_bug582176.xul new file mode 100644 index 000000000..98053b009 --- /dev/null +++ b/system/docshell/test/chrome/test_bug582176.xul @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=582176.xul +--> +<window title="Mozilla Bug 582176" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=582176"> + Mozilla Bug 582176</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 582176 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug582176_window.xul", "bug582176", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug608669.xul b/system/docshell/test/chrome/test_bug608669.xul new file mode 100644 index 000000000..51d6a3b7d --- /dev/null +++ b/system/docshell/test/chrome/test_bug608669.xul @@ -0,0 +1,117 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=608669 +--> +<window title="Mozilla Bug 608669" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=608669" + target="_blank">Mozilla Bug 608669</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + +var gOrigMaxTotalViewers = undefined; +function setCachePref(enabled) { + var prefBranch = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Components.interfaces.nsIPrefBranch); + if (enabled) { + is(typeof gOrigMaxTotalViewers, "undefined", "don't double-enable bfcache"); + prefBranch.setBoolPref("browser.sessionhistory.cache_subframes", true); + gOrigMaxTotalViewers = prefBranch.getIntPref("browser.sessionhistory.max_total_viewers"); + prefBranch.setIntPref("browser.sessionhistory.max_total_viewers", 10); + } + else { + is(typeof gOrigMaxTotalViewers, "number", "don't double-disable bfcache"); + prefBranch.setIntPref("browser.sessionhistory.max_total_viewers", gOrigMaxTotalViewers); + gOrigMaxTotalViewers = undefined; + try { + prefBranch.clearUserPref("browser.sessionhistory.cache_subframes"); + } catch (e) { /* Pref didn't exist, meh */ } + } +} + + +/** Test for Bug 608669 **/ +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(nextTest); + +gen = doTest(); + +function nextTest() { + gen.next(); +} + +function doTest() { + var container = document.getElementById('container'); + + setCachePref(true); + + var notificationCount = 0; + var observer = { + observe: function(aSubject, aTopic, aData) { + is(aTopic, "chrome-document-global-created", + "correct topic"); + is(aData, "null", + "correct data"); + notificationCount++; + } + }; + + var os = Components.classes["@mozilla.org/observer-service;1"]. + getService(Components.interfaces.nsIObserverService); + os.addObserver(observer, "chrome-document-global-created", false); + os.addObserver(observer, "content-document-global-created", false); + + is(notificationCount, 0, "initial count"); + + // create a new iframe + var iframe = document.createElement("iframe"); + container.appendChild(iframe); + iframe.contentWindow.x = "y"; + is(notificationCount, 1, "after created iframe"); + + // Try loading in an iframe + iframe.setAttribute("src", "bug608669.xul"); + iframe.onload = nextTest; + yield undefined; + is(notificationCount, 1, "after first load"); + is(iframe.contentWindow.x, "y", "reused window"); + + // Try loading again in an iframe + iframe.setAttribute("src", "bug608669.xul?x"); + iframe.onload = nextTest; + yield undefined; + is(notificationCount, 2, "after second load"); + is("x" in iframe.contentWindow, false, "didn't reuse window"); + + // Open a new window using window.open + popup = window.open("bug608669.xul", "bug 608669", + "chrome,width=600,height=600"); + popup.onload = nextTest; + yield undefined; + is(notificationCount, 3, "after window.open load"); + popup.close(); + + setCachePref(false); + os.removeObserver(observer, "chrome-document-global-created"); + os.removeObserver(observer, "content-document-global-created"); + SimpleTest.finish(); + yield undefined; +} + + + + ]]></script> + <vbox id="container" flex="1"> + <description>Below will an iframe be added</description> + </vbox> +</window> diff --git a/system/docshell/test/chrome/test_bug662200.xul b/system/docshell/test/chrome/test_bug662200.xul new file mode 100644 index 000000000..8b864c8af --- /dev/null +++ b/system/docshell/test/chrome/test_bug662200.xul @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=662200.xul +--> +<window title="Mozilla Bug 662200" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=662200"> + Mozilla Bug 662200</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 662200 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug662200_window.xul", "bug662200", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug690056.xul b/system/docshell/test/chrome/test_bug690056.xul new file mode 100644 index 000000000..caeed09d3 --- /dev/null +++ b/system/docshell/test/chrome/test_bug690056.xul @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=690056 +--> +<window title="Mozilla Bug 690056" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=690056" + target="_blank">Mozilla Bug 690056</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 690056 **/ +SimpleTest.waitForExplicitFinish(); +window.open("bug690056_window.xul", "bug690056", + "chrome,width=600,height=600"); + ]]> + </script> +</window> diff --git a/system/docshell/test/chrome/test_bug789773.xul b/system/docshell/test/chrome/test_bug789773.xul new file mode 100644 index 000000000..b7a2b3d1c --- /dev/null +++ b/system/docshell/test/chrome/test_bug789773.xul @@ -0,0 +1,71 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=789773 +--> +<window title="Mozilla Bug 789773" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=789773" + target="_blank">Mozilla Bug 789773</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + const Cc = Components.classes; + const Ci = Components.interfaces; + const Cr = Components.results; + const Cu = Components.utils; + + /* Test for Bug 789773. + * + * See comment 50 for the situation we're testing against here. + * + * Note that the failure mode of this test is to hang, and hang the browser on quit. + * This is an unfortunate occurance, but that's why we're testing it. + */ + SimpleTest.waitForExplicitFinish(); + + var calledListenerForBrowserXUL = false; + var testProgressListener = { + START_DOC: Ci.nsIWebProgressListener.STATE_START | Ci.nsIWebProgressListener.STATE_IS_DOCUMENT, + onStateChange: function(wp, req, stateFlags, status) { + if (/browser.xul/.test(req.name)) { + wp.DOMWindow; // Force the lazy creation of a DOM window. + calledListenerForBrowserXUL = true; + } + if (/mozilla.xhtml/.test(req.name) && (stateFlags & Ci.nsIWebProgressListener.STATE_STOP)) + finishTest(); + }, + QueryInterface: function(iid) { + if (iid.equals(Ci.nsISupportsWeakReference) || + iid.equals(Ci.nsIWebProgressListener)) + return this; + throw Cr.NS_ERROR_NO_INTERFACE; + } + } + + // Add our progress listener + var webProgress = Cc['@mozilla.org/docloaderservice;1'].getService(Ci.nsIWebProgress); + webProgress.addProgressListener(testProgressListener, Ci.nsIWebProgress.NOTIFY_STATE_REQUEST); + + // Open the window. + var popup = window.open("about:mozilla", "_blank", "width=640,height=400"); + + // Wait for the window to load. + function finishTest() { + webProgress.removeProgressListener(testProgressListener); + ok(true, "Loaded the popup window without spinning forever in the event loop!"); + ok(calledListenerForBrowserXUL, "Should have called the progress listener for browser.xul"); + popup.close(); + SimpleTest.finish(); + } + + ]]> + </script> +</window> diff --git a/system/docshell/test/chrome/test_bug846906.xul b/system/docshell/test/chrome/test_bug846906.xul new file mode 100644 index 000000000..2003384f0 --- /dev/null +++ b/system/docshell/test/chrome/test_bug846906.xul @@ -0,0 +1,96 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=846906 +--> +<window title="Mozilla Bug 846906" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 846906 **/ + SimpleTest.waitForExplicitFinish(); + + var appShellService = Components.classes["@mozilla.org/appshell/appShellService;1"] + .getService(Components.interfaces.nsIAppShellService); + ok(appShellService, "Should be able to get app shell service"); + + var windowlessBrowser = appShellService.createWindowlessBrowser(); + ok(windowlessBrowser, "Should be able to create windowless browser"); + + ok(windowlessBrowser instanceof Components.interfaces.nsIWindowlessBrowser, + "Windowless browser should implement nsIWindowlessBrowser"); + + var webNavigation = windowlessBrowser.QueryInterface(Components.interfaces.nsIWebNavigation); + ok(webNavigation, "Windowless browser should implement nsIWebNavigation"); + + var interfaceRequestor = windowlessBrowser.QueryInterface(Components.interfaces.nsIInterfaceRequestor); + ok(interfaceRequestor, "Should be able to query interface requestor interface"); + + var docShell = interfaceRequestor.getInterface(Components.interfaces.nsIDocShell); + ok(docShell, "Should be able to get doc shell interface"); + + var document = webNavigation.document; + ok(document, "Should be able to get document"); + + var iframe = document.createElement("iframe"); + ok(iframe, "Should be able to create iframe"); + + iframe.onload = function () { + ok(true, "Should receive initial onload event"); + + iframe.onload = function () { + ok(true, "Should receive onload event"); + + var contentDocument = iframe.contentDocument; + ok(contentDocument, "Should be able to get content document"); + + var div = contentDocument.getElementById("div1"); + ok(div, "Should be able to get element by id"); + + var rect = div.getBoundingClientRect(); + ok(rect, "Should be able to get bounding client rect"); + + // xxx: can we do better than hardcoding these values here? + is(rect.width, 1024); + is(rect.height, 768); + + windowlessBrowser.close(); + + // Once the browser is closed, nsIWebNavigation and + // nsIInterfaceRequestor methods should no longer be accessible. + try { + windowlessBrowser.getInterface(Components.interfaces.nsIDocShell); + ok(false); + } catch (e) { + is(e.result, Components.results.NS_ERROR_NULL_POINTER); + } + + try { + windowlessBrowser.document; + ok(false); + } catch (e) { + is(e.result, Components.results.NS_ERROR_NULL_POINTER); + } + + SimpleTest.finish(); + }; + iframe.setAttribute("src", "http://mochi.test:8888/chrome/docshell/test/chrome/bug846906.html"); + }; + document.documentElement.appendChild(iframe); + + ]]> + </script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=846906" + target="_blank">Mozilla Bug 846906</a> + </body> +</window> diff --git a/system/docshell/test/chrome/test_bug89419.xul b/system/docshell/test/chrome/test_bug89419.xul new file mode 100644 index 000000000..26194c49b --- /dev/null +++ b/system/docshell/test/chrome/test_bug89419.xul @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=89419.xul +--> +<window title="Mozilla Bug 89419" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=89419"> + Mozilla Bug 89419</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 89419 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug89419_window.xul", "bug89419", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_bug909218.html b/system/docshell/test/chrome/test_bug909218.html new file mode 100644 index 000000000..e635fdb11 --- /dev/null +++ b/system/docshell/test/chrome/test_bug909218.html @@ -0,0 +1,127 @@ +<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(test);
+
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+
+// The default flags we will stick on the docShell - every request made by the
+// docShell should include those flags.
+const TEST_FLAGS = Ci.nsIRequest.LOAD_ANONYMOUS |
+ Ci.nsIRequest.LOAD_BYPASS_CACHE |
+ Ci.nsIRequest.INHIBIT_CACHING |
+ Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY;
+
+var TEST_URL = "http://mochi.test:8888/chrome/docshell/test/chrome/bug909218.html";
+
+// These are the requests we expect to see loading TEST_URL into our iframe.
+
+// The test entry-point. The basic outline is:
+// * Create an iframe and set defaultLoadFlags on its docShell.
+// * Add a web progress listener to observe each request as the iframe is
+// loaded, and check that each request has the flags we specified.
+// * Load our test URL into the iframe and wait for the load to complete.
+function test() {
+ var iframe = document.createElement("iframe");
+ document.body.appendChild(iframe);
+ var docShell = docshellForWindow(iframe.contentWindow);
+ // Add our progress listener - when it notices the top-level document is
+ // complete, the test will end.
+ RequestWatcher.init(docShell, SimpleTest.finish);
+ // Set the flags we care about, then load our test URL.
+ docShell.defaultLoadFlags = TEST_FLAGS;
+ iframe.setAttribute("src", TEST_URL);
+}
+
+// an nsIWebProgressListener that checks all requests made by the docShell
+// have the flags we expect.
+RequestWatcher = {
+ init: function(docShell, callback) {
+ this.callback = callback;
+ this.docShell = docShell;
+ docShell.
+ QueryInterface(Ci.nsIInterfaceRequestor).
+ getInterface(Ci.nsIWebProgress).
+ addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_REQUEST |
+ Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
+ // These are the requests we expect to see - initialize each to have a
+ // count of zero.
+ this.requestCounts = {};
+ for (var url of [
+ TEST_URL,
+ // content loaded by the above test html.
+ "http://mochi.test:8888/chrome/docshell/test/chrome/bug909218.js",
+ "http://mochi.test:8888/tests/SimpleTest/test.css",
+ "http://mochi.test:8888/tests/docshell/test/chrome/red.png",
+ // the content of an iframe in the test html.
+ "http://mochi.test:8888/chrome/docshell/test/chrome/generic.html"
+ ]) {
+ this.requestCounts[url] = 0;
+ }
+ },
+
+ // Finalize the test after we detect a completed load. We check we saw the
+ // correct requests and make a callback to exit.
+ finalize: function() {
+ ok(Object.keys(this.requestCounts).length, "we expected some requests");
+ for (var url in this.requestCounts) {
+ var count = this.requestCounts[url];
+ // As we are looking at all request states, we expect more than 1 for
+ // each URL - 0 or 1 would imply something went wrong - >1 just means
+ // multiple states for each request were recorded, which we don't care
+ // about (we do care they all have the correct flags though - but we
+ // do that in onStateChange)
+ ok(count > 1, url + " saw " + count + " requests");
+ }
+ this.docShell.
+ QueryInterface(Ci.nsIInterfaceRequestor).
+ getInterface(Ci.nsIWebProgress).
+ removeProgressListener(this);
+ this.callback();
+ },
+
+ onStateChange: function (webProgress, req, flags, status) {
+ // We are checking requests - if there isn't one, ignore it.
+ if (!req) {
+ return;
+ }
+ // We will usually see requests for 'about:document-onload-blocker' not
+ // have the flag, so we just ignore them.
+ // We also see, eg, resource://gre-resources/loading-image.png, so
+ // skip resource:// URLs too.
+ if (req.name.startsWith("about:") || req.name.startsWith("resource:")) {
+ return;
+ }
+ is(req.loadFlags & TEST_FLAGS, TEST_FLAGS, "request " + req.name + " has the expected flags");
+ this.requestCounts[req.name] += 1;
+ var stopFlags = Ci.nsIWebProgressListener.STATE_STOP |
+ Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
+ if (req.name == TEST_URL && (flags & stopFlags) == stopFlags) {
+ this.finalize();
+ }
+ },
+ QueryInterface: XPCOMUtils.generateQI([
+ Ci.nsIWebProgressListener,
+ Ci.nsISupportsWeakReference,
+ ])
+}
+
+function docshellForWindow(win) {
+ return win.
+ QueryInterface(Ci.nsIInterfaceRequestor).
+ getInterface(Ci.nsIWebNavigation).
+ QueryInterface(Ci.nsIDocShell);
+}
+
+</script>
+</head>
+</html>
diff --git a/system/docshell/test/chrome/test_bug92598.xul b/system/docshell/test/chrome/test_bug92598.xul new file mode 100644 index 000000000..8e81463be --- /dev/null +++ b/system/docshell/test/chrome/test_bug92598.xul @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=92598 +--> +<window title="Mozilla Bug 92598" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=92598">Mozilla Bug 92598</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 92598 **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug92598_window.xul", "bug92598", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_mozFrameType.xul b/system/docshell/test/chrome/test_mozFrameType.xul new file mode 100644 index 000000000..225cd16cc --- /dev/null +++ b/system/docshell/test/chrome/test_mozFrameType.xul @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=769771 +--> +<window title="Test mozFrameType attribute" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +if (navigator.platform.startsWith("Win")) { + SimpleTest.expectAssertions(0, 1); +} + +/** Test for Bug 769771 **/ +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function () { + window.open("mozFrameType_window.xul", "mozFrameType", + "chrome,width=600,height=600"); +}); + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_principalInherit.xul b/system/docshell/test/chrome/test_principalInherit.xul new file mode 100644 index 000000000..87056c63d --- /dev/null +++ b/system/docshell/test/chrome/test_principalInherit.xul @@ -0,0 +1,108 @@ +<?xml version="1.0"?> +<!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=719994 +--> +<window title="Test principal inheriting" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 719994 **/ + +SimpleTest.waitForExplicitFinish(); + +var gFrame; + +// This test file is loaded in a type=content docshell whose principal is +// the system principal. + +// Using data: URIs here instead of javascript: URIs, since javascript: URIs +// fail to load when there's no principal to load them against. This only +// matters when these tests fail (produces better error messages). +var tests = [ + function testInheritFromParent(cb) { + gFrame = document.createElement("iframe"); + loadListener(gFrame, function () { + is(window.inheritedFromParent, true, "load in type=content iframe inherited principal of same type parent"); + cb(); + }); + gFrame.setAttribute("type", "content"); + gFrame.setAttribute("src", "data:text/html,<script>parent.inheritedFromParent = true;</script>"); + document.documentElement.appendChild(gFrame); + }, + function testInheritFromCurrent_system(cb) { + loadListener(gFrame, function () { + is(window.inheritedSystem, undefined, "load in type=content iframe shouldn't inherit system principal from current document"); + cb(); + }, true); + gFrame.setAttribute("src", "data:text/html,<script>parent.inheritedSystem = true;</script>"); + }, + function testInheritFromCreated(cb) { + // Open a new chrome window with a type="content" iframe, so that it has no + // same-type parent. + // Load a javascript: URI in it to ensure that GetInheritedPrincipal will + // force creation of a content viewer. + let xulWinURL = 'data:application/vnd.mozilla.xul+xml,<?xml version="1.0"?>' + + '<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>'; + let newWin = window.openDialog(xulWinURL, "chrome_window", "chrome"); + loadListener(newWin, function () { + let frame = newWin.document.createElement("iframe"); + frame.setAttribute("type", "content"); + frame.setAttribute("src", "javascript:'1';"); + loadListener(frame, function () { + is(frame.contentWindow.document.body.textContent, "1", "content viewer was created"); + SimpleTest.executeSoon(function () { + newWin.close(); + cb(); + }) + }); + newWin.document.documentElement.appendChild(frame); + }); + } +]; + +addLoadEvent(function onLoad() { + ok(Components.stack, "this test must be run with the system principal"); + SimpleTest.executeSoon(nextTest); +}); + +function loadListener(target, func) { + target.addEventListener("load", function lis() { + target.removeEventListener("load", lis, true); + func(); + }, true); +} + +function nextTest() { + if (tests.length) { + let test = tests.shift(); + SimpleTest.executeSoon(function () { + info("running " + test.name); + test(nextTest); + }); + } else + SimpleTest.executeSoon(SimpleTest.finish); +} + +]]> +</script> + +</window> diff --git a/system/docshell/test/chrome/test_private_hidden_window.html b/system/docshell/test/chrome/test_private_hidden_window.html new file mode 100644 index 000000000..3907e5de8 --- /dev/null +++ b/system/docshell/test/chrome/test_private_hidden_window.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=829383 +--> +<head> + <title>Test for Bug 829383</title> + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=829383">Mozilla Bug 829383</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe name="target"></iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); +const Ci = Components.interfaces; +var mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem) + .rootTreeItem + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow); + +// We need to wait for the hidden window to load, but can't access +// an event target for a regular event listener. +var hidden = mainWindow.Services.appShell.hiddenPrivateDOMWindow; +mainWindow.PrivateBrowsingUtils.whenHiddenPrivateWindowReady(function(hidden) { + var iframe = hidden.document.createElement('iframe'); + iframe.src = 'generic.html'; + hidden.document.body.appendChild(iframe); + + var win = mainWindow.OpenBrowserWindow({private: true}); + win.addEventListener("load", function onLoad() { + win.removeEventListener("load", onLoad, false); + win.close(); + win = null; + }, false); +}); + +function observer(aSubject, aTopic, aData) { + is(aTopic, "last-pb-context-exited", "Unexpected observer topic"); + mainWindow.Services.obs.removeObserver(observer, "last-pb-context-exited"); + SimpleTest.finish(); +} +mainWindow.Services.obs.addObserver(observer, "last-pb-context-exited", false); + +</script> +</pre> +</body> +</html> + diff --git a/system/docshell/test/chrome/test_viewsource_forbidden_in_iframe.xul b/system/docshell/test/chrome/test_viewsource_forbidden_in_iframe.xul new file mode 100644 index 000000000..536ca4d03 --- /dev/null +++ b/system/docshell/test/chrome/test_viewsource_forbidden_in_iframe.xul @@ -0,0 +1,180 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin/"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=624883 +--> +<window title="Mozilla Bug 624883" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=624883" + target="_blank">Mozilla Bug 624883</a> + </body> + + <!-- test code goes here --> + <iframe type="content" onload="startTest()" src="file_viewsource_forbidden_in_iframe.html"></iframe> + + <script type="application/javascript"> + <![CDATA[ + + const Ci = Components.interfaces; + const Cu = Components.utils; + + Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + + SimpleTest.waitForExplicitFinish(); + + // We create a promise that will resolve with the error message + // on a network error page load and reject on any other load. + function createNetworkErrorMessagePromise(frame) { + return new Promise(function(resolve, reject) { + + // Error pages do not fire "load" events, so use a progressListener. + var originalDocumentURI = frame.contentDocument.documentURI; + var progressListener = { + onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) { + // Make sure nothing other than an error page is loaded. + if (!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE)) { + reject("location change was not to an error page"); + } + }, + + onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) { + // Wait until the documentURI changes (from about:blank) this should + // be the error page URI. + var documentURI = frame.contentDocument.documentURI; + if (documentURI == originalDocumentURI) { + return; + } + + aWebProgress.removeProgressListener(progressListener, + Ci.nsIWebProgress.NOTIFY_ALL); + var matchArray = /about:neterror\?.*&d=([^&]*)/.exec(documentURI); + if (!matchArray) { + reject("no network error message found in URI") + return; + } + + var errorMsg = matchArray[1]; + resolve(decodeURIComponent(errorMsg)); + }, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, + Ci.nsISupportsWeakReference]) + }; + + frame.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebProgress) + .addProgressListener(progressListener, + Ci.nsIWebProgress.NOTIFY_LOCATION | + Ci.nsIWebProgress.NOTIFY_STATE_REQUEST); + }); + } + + function startTest() { + // Get a reference message that we know will be an unknown protocol message, + // so we can use it for comparisons in the test cases. + var refIframe = window[0].document.getElementById("refIframe"); + var refErrorPromise = createNetworkErrorMessagePromise(refIframe); + + refErrorPromise.then( + function(msg) { + window.refErrorMsg = msg; + var testIframe = window[0].document.getElementById("testIframe"); + + // Run test cases on load of "about:blank", so that the URI always changes + // and we can detect this in our Promise. + testIframe.onload = runNextTestCase; + testIframe.src = "about:blank"; + }, + function(reason) { + ok(false, "Could not get reference error message", reason); + SimpleTest.finish(); + }) + .catch(function(e) { + ok(false, "Unexpected exception thrown getting reference error message", exception); + }); + + refIframe.src = "wibble://example.com"; + } + + function runTestCase(testCase) { + var testIframe = window[0].document.getElementById("testIframe"); + var expectedErrorMsg = window.refErrorMsg.replace("wibble", testCase.expectedProtocolList); + + var testErrorPromise = createNetworkErrorMessagePromise(testIframe); + testErrorPromise.then( + function(actualErrorMsg) { + is(actualErrorMsg, expectedErrorMsg, testCase.desc); + testIframe.src = "about:blank"; + }, + function(reason) { + ok(false, testCase.desc, reason); + testIframe.src = "about:blank"; + }) + .catch(function(e) { + ok(false, testCase.desc + " - unexpected exception thrown", exception); + }); + + testIframe.src = testCase.protocols + "://example.com/!/"; + } + + var testCaseIndex = -1; + testCases = [ + { + desc: "Test 1: view-source should not be allowed in an iframe", + protocols: "view-source:http", + expectedProtocolList: "view-source, http" + }, + { + desc: "Test 2: feed:view-source should not be allowed in an iframe", + protocols: "feed:view-source:http", + expectedProtocolList: "feed, view-source, http" + }, + { + desc: "Test 3: jar:view-source should not be allowed in an iframe", + protocols: "jar:view-source:http", + expectedProtocolList: "jar, view-source, http" + }, + { + desc: "Test 4: pcast:view-source should not be allowed in an iframe", + protocols: "pcast:view-source:http", + expectedProtocolList: "pcast, view-source, http" + }, + { + desc: "Test 5: pcast:feed:view-source should not be allowed in an iframe", + protocols: "pcast:feed:view-source:http", + expectedProtocolList: "pcast, feed, view-source, http" + }, + { + desc: "Test 6: if invalid protocol first should report before view-source", + protocols: "wibble:view-source:http", + // Nothing after the invalid protocol gets set as a proper nested URI, + // so the list stops there. + expectedProtocolList: "wibble" + }, + { + desc: "Test 7: if view-source first should report before invalid protocol", + protocols: "view-source:wibble:http", + expectedProtocolList: "view-source, wibble" + } + ]; + + function runNextTestCase() { + ++testCaseIndex; + if (testCaseIndex == testCases.length) { + SimpleTest.finish(); + return; + } + + runTestCase(testCases[testCaseIndex]); + } + + ]]> + </script> +</window> diff --git a/system/docshell/test/chrome/window.template.txt b/system/docshell/test/chrome/window.template.txt new file mode 100644 index 000000000..a7fb0fac7 --- /dev/null +++ b/system/docshell/test/chrome/window.template.txt @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="{BUGNUMBER}Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug {BUGNUMBER} test"> + + <script type="application/javascript" + src="docshell_helpers.js"> + </script> + + <script type="application/javascript"><![CDATA[ + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + //// + // Generator function for test steps for bug {BUGNUMBER}: + // Description goes here. + // + function testIterator() + { + // Test steps go here. See bug303267_window.xul for an example. + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + + <browser type="content-primary" flex="1" id="content" src="about:blank"/> +</window> diff --git a/system/docshell/test/dummy_page.html b/system/docshell/test/dummy_page.html new file mode 100644 index 000000000..59bf2a5f8 --- /dev/null +++ b/system/docshell/test/dummy_page.html @@ -0,0 +1,6 @@ +<html> +<head> <meta charset="utf-8"> </head> + <body> + just a dummy html file + </body> +</html> diff --git a/system/docshell/test/file_anchor_scroll_after_document_open.html b/system/docshell/test/file_anchor_scroll_after_document_open.html new file mode 100644 index 000000000..7903380ea --- /dev/null +++ b/system/docshell/test/file_anchor_scroll_after_document_open.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<script> + if (location.hash == "#target") { + parent.postMessage("haveHash", "*"); + } else { + document.addEventListener("DOMContentLoaded", function() { + document.open(); + document.write("<!DOCTYPE html><html style='height: 100%'><body style='height: 100%'><div style='height: 200%'></div><div id='target'></div></body></html>"); + document.close(); + // Notify parent via postMessage, since otherwise exceptions will not get + // caught by its onerror handler. + parent.postMessage("doTest", "*"); + }); + } +</script> diff --git a/system/docshell/test/file_bug1151421.html b/system/docshell/test/file_bug1151421.html new file mode 100644 index 000000000..7bb8c8f36 --- /dev/null +++ b/system/docshell/test/file_bug1151421.html @@ -0,0 +1,19 @@ +<html> +<head> +<style> +body, html { + height: 100%; +} +.spacer { + height: 80%; +} +</style> +</head> +<body onload='(parent || opener).childLoad()'> + +<div class="spacer"></div> +<div id="content">content</div> +<div class="spacer"></div> + +</body> +</html> diff --git a/system/docshell/test/file_bug385434_1.html b/system/docshell/test/file_bug385434_1.html new file mode 100644 index 000000000..5c951f1fa --- /dev/null +++ b/system/docshell/test/file_bug385434_1.html @@ -0,0 +1,29 @@ +<!-- +Inner frame for test of bug 385434. +https://bugzilla.mozilla.org/show_bug.cgi?id=385434 +--> +<html> +<head> + <script type="application/javascript"> + function hashchange() { + parent.onIframeHashchange(); + } + + function load() { + parent.onIframeLoad(); + } + + function scroll() { + parent.onIframeScroll(); + } + </script> +</head> + +<body onscroll="scroll()" onload="load()" onhashchange="hashchange()"> +<a href="#link1" id="link1">link1</a> +<!-- Our parent loads us in an iframe with height 100px, so this spacer ensures + that switching between #link1 and #link2 causes us to scroll --> +<div style="height:200px;"></div> +<a href="#link2" id="link2">link2</a> +</body> +</html> diff --git a/system/docshell/test/file_bug385434_2.html b/system/docshell/test/file_bug385434_2.html new file mode 100644 index 000000000..4aa5ef82b --- /dev/null +++ b/system/docshell/test/file_bug385434_2.html @@ -0,0 +1,26 @@ +<!-- +Inner frame for test of bug 385434. +https://bugzilla.mozilla.org/show_bug.cgi?id=385434 +--> +<html> +<head> + <script type="application/javascript"> + function hashchange(e) { + // pass the event back to the parent so it can check its properties. + parent.gSampleEvent = e; + + parent.statusMsg("Hashchange in 2."); + parent.onIframeHashchange(); + } + + function load() { + parent.statusMsg("Loading 2."); + parent.onIframeLoad(); + } + </script> +</head> + +<frameset onload="load()" onhashchange="hashchange(event)"> + <frame src="about:blank" /> +</frameset> +</html> diff --git a/system/docshell/test/file_bug385434_3.html b/system/docshell/test/file_bug385434_3.html new file mode 100644 index 000000000..984b85f1f --- /dev/null +++ b/system/docshell/test/file_bug385434_3.html @@ -0,0 +1,22 @@ +<!-- +Inner frame for test of bug 385434. +https://bugzilla.mozilla.org/show_bug.cgi?id=385434 +--> +<html> +<head> + <script type="application/javascript"> + // Notify our parent if we have a hashchange and once we're done loading. + window.addEventListener("hashchange", parent.onIframeHashchange, false); + + window.addEventListener("DOMContentLoaded", function() { + // This also should trigger a hashchange, becuase the readystate is + // "interactive", not "complete" during DOMContentLoaded. + window.location.hash = "2"; + }, false); + + </script> +</head> + +<body> +</body> +</html> diff --git a/system/docshell/test/file_bug475636.sjs b/system/docshell/test/file_bug475636.sjs new file mode 100644 index 000000000..38da6a6a5 --- /dev/null +++ b/system/docshell/test/file_bug475636.sjs @@ -0,0 +1,90 @@ +jsURL = "javascript:" + escape('window.parent.postMessage("JS uri ran", "*");\ +return \'\ +<script>\ +window.parent.postMessage("Able to access private: " +\ + window.parent.private, "*");\ +</script>\''); +dataURL = "data:text/html," + escape('<!DOCTYPE HTML>\ +<script>\ +try {\ + window.parent.postMessage("Able to access private: " +\ + window.parent.private, "*");\ +}\ +catch (e) {\ + window.parent.postMessage("pass", "*");\ +}\ +</script>'); + +tests = [ +// Plain document should work as normal +'<!DOCTYPE HTML>\ +<script>\ +try {\ + window.parent.private;\ + window.parent.postMessage("pass", "*");\ +}\ +catch (e) {\ + window.parent.postMessage("Unble to access private", "*");\ +}\ +</script>', + +// refresh to plain doc +{ refresh: "file_bug475636.sjs?1", + doc: '<!DOCTYPE HTML>' }, + +// meta-refresh to plain doc +'<!DOCTYPE HTML>\ +<head>\ + <meta http-equiv="refresh" content="0; url=file_bug475636.sjs?1">\ +</head>', + +// refresh to data url +{ refresh: dataURL, + doc: '<!DOCTYPE HTML>' }, + +// meta-refresh to data url +'<!DOCTYPE HTML>\ +<head>\ + <meta http-equiv="refresh" content="0; url=' + dataURL + '">\ +</head>', + +// refresh to js url should not be followed +{ refresh: jsURL, + doc: +'<!DOCTYPE HTML>\ +<script>\ +setTimeout(function() {\ + window.parent.postMessage("pass", "*");\ +}, 2000);\ +</script>' }, + +// meta refresh to js url should not be followed +'<!DOCTYPE HTML>\ +<head>\ + <meta http-equiv="refresh" content="0; url=' + jsURL + '">\ +</head>\ +<script>\ +setTimeout(function() {\ + window.parent.postMessage("pass", "*");\ +}, 2000);\ +</script>' +]; + + +function handleRequest(request, response) +{ + dump("@@@@@@@@@hi there: " + request.queryString + "\n"); + test = tests[parseInt(request.queryString, 10) - 1]; + response.setHeader("Content-Type", "text/html"); + + if (!test) { + response.write('<script>parent.postMessage("done", "*");</script>'); + } + else if (typeof test == "string") { + response.write(test); + } + else if (test.refresh) { + response.setHeader("Refresh", "0; url=" + test.refresh); + response.write(test.doc); + } +} diff --git a/system/docshell/test/file_bug509055.html b/system/docshell/test/file_bug509055.html new file mode 100644 index 000000000..ac30876bb --- /dev/null +++ b/system/docshell/test/file_bug509055.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test inner frame for bug 509055</title> +</head> +<body onhashchange="hashchangeCallback()"> + file_bug509055.html +</body> +</html> diff --git a/system/docshell/test/file_bug511449.html b/system/docshell/test/file_bug511449.html new file mode 100644 index 000000000..637732dbb --- /dev/null +++ b/system/docshell/test/file_bug511449.html @@ -0,0 +1,6 @@ +<!DOCTYPE HTML> +<title>Used in test for bug 511449</title> +<input type="text" id="input"> +<script type="text/javascript"> + document.getElementById("input").focus(); +</script> diff --git a/system/docshell/test/file_bug540462.html b/system/docshell/test/file_bug540462.html new file mode 100644 index 000000000..52d1580c7 --- /dev/null +++ b/system/docshell/test/file_bug540462.html @@ -0,0 +1,16 @@ +<html> + <head> + <script> + //<!-- + function test() { + document.open(); + document.write("<html><body onload='opener.documentWriteLoad(); rel();'><a href='foo.html'>foo</a><script>function rel() { setTimeout('location.reload()', 0); }</script></body></html>"); + document.close(); + } + //--> + </script> + </head> + <body onload="setTimeout('test()', 0)"> + Test for bug 540462 + </body> +</html> diff --git a/system/docshell/test/file_bug580069_1.html b/system/docshell/test/file_bug580069_1.html new file mode 100644 index 000000000..7ab461033 --- /dev/null +++ b/system/docshell/test/file_bug580069_1.html @@ -0,0 +1,8 @@ +<html> +<body onload='parent.page1Load();'> +file_bug580069_1.html + +<form id='form' action='file_bug580069_2.sjs' method='POST'></form> + +</body> +</html> diff --git a/system/docshell/test/file_bug580069_2.sjs b/system/docshell/test/file_bug580069_2.sjs new file mode 100644 index 000000000..0c76c1f16 --- /dev/null +++ b/system/docshell/test/file_bug580069_2.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setHeader("Content-Type", "text/html", false); + response.write('<html><body onload=\'parent.page2Load("' + request.method + '")\'>file_bug580069_2.sjs</body></html>'); +} diff --git a/system/docshell/test/file_bug590573_1.html b/system/docshell/test/file_bug590573_1.html new file mode 100644 index 000000000..850d418bd --- /dev/null +++ b/system/docshell/test/file_bug590573_1.html @@ -0,0 +1,8 @@ +<html> +<body onpopstate='opener.page1Popstate();' onload='opener.page1Load();' + onpageshow='opener.page1PageShow();'> + +<div style='height:10000px' id='div1'>This is a very tall div.</div> + +</body> +</html> diff --git a/system/docshell/test/file_bug590573_2.html b/system/docshell/test/file_bug590573_2.html new file mode 100644 index 000000000..5f9ca22be --- /dev/null +++ b/system/docshell/test/file_bug590573_2.html @@ -0,0 +1,8 @@ +<html> +<body onpopstate='opener.page2Popstate();' onload='opener.page2Load();' + onpageshow='opener.page2PageShow();'> + +<div style='height:300%' id='div2'>The second page also has a big div.</div> + +</body> +</html> diff --git a/system/docshell/test/file_bug598895_1.html b/system/docshell/test/file_bug598895_1.html new file mode 100644 index 000000000..6fbb13a02 --- /dev/null +++ b/system/docshell/test/file_bug598895_1.html @@ -0,0 +1 @@ +<script>window.onload = function() { opener.postMessage('loaded', '*'); }</script><body>Should show</body> diff --git a/system/docshell/test/file_bug598895_2.html b/system/docshell/test/file_bug598895_2.html new file mode 100644 index 000000000..0822c566b --- /dev/null +++ b/system/docshell/test/file_bug598895_2.html @@ -0,0 +1 @@ +<script>window.onload = function() { opener.postMessage('loaded', '*'); }</script><body></body> diff --git a/system/docshell/test/file_bug634834.html b/system/docshell/test/file_bug634834.html new file mode 100644 index 000000000..3ff089745 --- /dev/null +++ b/system/docshell/test/file_bug634834.html @@ -0,0 +1,5 @@ +<html> +<body> +Nothing to see here; just an empty page. +</body> +</html> diff --git a/system/docshell/test/file_bug637644_1.html b/system/docshell/test/file_bug637644_1.html new file mode 100644 index 000000000..6fbb13a02 --- /dev/null +++ b/system/docshell/test/file_bug637644_1.html @@ -0,0 +1 @@ +<script>window.onload = function() { opener.postMessage('loaded', '*'); }</script><body>Should show</body> diff --git a/system/docshell/test/file_bug637644_2.html b/system/docshell/test/file_bug637644_2.html new file mode 100644 index 000000000..0822c566b --- /dev/null +++ b/system/docshell/test/file_bug637644_2.html @@ -0,0 +1 @@ +<script>window.onload = function() { opener.postMessage('loaded', '*'); }</script><body></body> diff --git a/system/docshell/test/file_bug640387.html b/system/docshell/test/file_bug640387.html new file mode 100644 index 000000000..3a939fb41 --- /dev/null +++ b/system/docshell/test/file_bug640387.html @@ -0,0 +1,26 @@ +<html> +<body onhashchange='hashchange()' onload='load()' onpopstate='popstate()'> + +<script> +function hashchange() { + var f = (opener || parent).childHashchange; + if (f) + f(); +} + +function load() { + var f = (opener || parent).childLoad; + if (f) + f(); +} + +function popstate() { + var f = (opener || parent).childPopstate; + if (f) + f(); +} +</script> + +Not much to see here... +</body> +</html> diff --git a/system/docshell/test/file_bug653741.html b/system/docshell/test/file_bug653741.html new file mode 100644 index 000000000..3202b5257 --- /dev/null +++ b/system/docshell/test/file_bug653741.html @@ -0,0 +1,13 @@ +<html> +<body onload='(parent || opener).childLoad()'> + +<div style='height:500px; background:yellow'> +<a id='#top'>Top of the page</a> +</div> + +<div id='bottom'> +<a id='#bottom'>Bottom of the page</a> +</div> + +</body> +</html> diff --git a/system/docshell/test/file_bug660404 b/system/docshell/test/file_bug660404 new file mode 100644 index 000000000..0737a5c4d --- /dev/null +++ b/system/docshell/test/file_bug660404 @@ -0,0 +1,5 @@ +--testingtesting +Content-Type: text/html + +<script>opener.finishTest();</script> +--testingtesting-- diff --git a/system/docshell/test/file_bug660404^headers^ b/system/docshell/test/file_bug660404^headers^ new file mode 100644 index 000000000..5c821f3f4 --- /dev/null +++ b/system/docshell/test/file_bug660404^headers^ @@ -0,0 +1 @@ +Content-Type: multipart/x-mixed-replace; boundary="testingtesting" diff --git a/system/docshell/test/file_bug662170.html b/system/docshell/test/file_bug662170.html new file mode 100644 index 000000000..3202b5257 --- /dev/null +++ b/system/docshell/test/file_bug662170.html @@ -0,0 +1,13 @@ +<html> +<body onload='(parent || opener).childLoad()'> + +<div style='height:500px; background:yellow'> +<a id='#top'>Top of the page</a> +</div> + +<div id='bottom'> +<a id='#bottom'>Bottom of the page</a> +</div> + +</body> +</html> diff --git a/system/docshell/test/file_bug668513.html b/system/docshell/test/file_bug668513.html new file mode 100644 index 000000000..1e43a51e0 --- /dev/null +++ b/system/docshell/test/file_bug668513.html @@ -0,0 +1,107 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test file for Bug 668513</title> +<script> + var SimpleTest = opener.SimpleTest; + var ok = opener.ok; + var is = opener.is; + + function finish() { + SimpleTest.finish(); + close(); + } + + function onload_test() + { + var win = frames[0]; + ok(win.performance, 'Window.performance should be defined'); + ok(win.performance.navigation, 'Window.performance.navigation should be defined'); + var navigation = win.performance && win.performance.navigation; + if (navigation === undefined) + { + // avoid script errors + finish(); + return; + } + + // do this with a timeout to see the visuals of the navigations. + setTimeout("nav_frame();", 100); + } + + var step = 1; + function nav_frame() + { + var navigation_frame = frames[0]; + var navigation = navigation_frame.performance.navigation; + switch (step) + { + case 1: + { + navigation_frame.location.href = 'bug570341_recordevents.html'; + step++; + break; + } + case 2: + { + is(navigation.type, navigation.TYPE_NAVIGATE, + 'Expected window.performance.navigation.type == TYPE_NAVIGATE'); + navigation_frame.history.back(); + step++; + break; + } + case 3: + { + is(navigation.type, navigation.TYPE_BACK_FORWARD, + 'Expected window.performance.navigation.type == TYPE_BACK_FORWARD'); + step++; + navigation_frame.history.forward(); + break; + } + case 4: + { + is(navigation.type, navigation.TYPE_BACK_FORWARD, + 'Expected window.performance.navigation.type == TYPE_BACK_FORWARD'); + navigation_frame.location.href = 'bug668513_redirect.html'; + step++; + break; + } + case 5: + { + is(navigation.type, navigation.TYPE_NAVIGATE, + 'Expected timing.navigation.type as TYPE_NAVIGATE'); + is(navigation.redirectCount, 1, + 'Expected navigation.redirectCount == 1 on an server redirected navigation'); + + var timing = navigation_frame.performance && navigation_frame.performance.timing; + if (timing === undefined) + { + // avoid script errors + finish(); + break; + } + ok(timing.navigationStart > 0, 'navigationStart should be > 0'); + sequence = ['navigationStart', 'redirectStart', 'redirectEnd', 'fetchStart']; + for (var j = 1; j < sequence.length; ++j) { + var prop = sequence[j]; + var prevProp = sequence[j-1]; + ok(timing[prevProp] <= timing[prop], + ['Expected ', prevProp, ' to happen before ', prop, + ', got ', prevProp, ' = ', timing[prevProp], + ', ', prop, ' = ', timing[prop]].join('')); + } + step++; + finish(); + } + default: + break; + } + } +</script> +</head> +<body> +<div id="frames"> +<iframe name="child0" onload="onload_test();" src="navigation/blank.html"></iframe> +</div> +</body> +</html> diff --git a/system/docshell/test/file_bug669671.sjs b/system/docshell/test/file_bug669671.sjs new file mode 100644 index 000000000..b6fd1ec7c --- /dev/null +++ b/system/docshell/test/file_bug669671.sjs @@ -0,0 +1,14 @@ +function handleRequest(request, response) +{ + var count = parseInt(getState('count')); + if (!count || request.queryString == 'countreset') + count = 0; + + setState('count', count + 1 + ''); + + response.setHeader('Content-Type', 'text/html', false); + response.setHeader('Cache-Control', 'max-age=0'); + response.write('<html><body onload="opener.onChildLoad()" ' + + 'onunload="parseInt(\'0\')">' + + count + '</body></html>'); +} diff --git a/system/docshell/test/file_bug680257.html b/system/docshell/test/file_bug680257.html new file mode 100644 index 000000000..ff480e96a --- /dev/null +++ b/system/docshell/test/file_bug680257.html @@ -0,0 +1,16 @@ +<!DOCTYPE HTML> +<html> +<head> + <style type='text/css'> + a { color: black; } + a:target { color: red; } + </style> +</head> + +<body onload='(opener || parent).popupLoaded()'> + +<a id='a' href='#a'>link</a> +<a id='b' href='#b'>link2</a> + +</body> +</html> diff --git a/system/docshell/test/file_bug703855.html b/system/docshell/test/file_bug703855.html new file mode 100644 index 000000000..fe15b6e3d --- /dev/null +++ b/system/docshell/test/file_bug703855.html @@ -0,0 +1,2 @@ +<!DOCTYPE html> +<!-- Just need an empty file here, as long as it's served over HTTP --> diff --git a/system/docshell/test/file_bug728939.html b/system/docshell/test/file_bug728939.html new file mode 100644 index 000000000..1cd52a44e --- /dev/null +++ b/system/docshell/test/file_bug728939.html @@ -0,0 +1,3 @@ +<html> +<body onload="opener.popupLoaded()">file_bug728939</body> +</html> diff --git a/system/docshell/test/file_framedhistoryframes.html b/system/docshell/test/file_framedhistoryframes.html new file mode 100644 index 000000000..314f9c72d --- /dev/null +++ b/system/docshell/test/file_framedhistoryframes.html @@ -0,0 +1,16 @@ +<!DOCTYPE HTML> +<html> +<body> +<iframe id="iframe" src="historyframes.html"></iframe> +<script type="application/javascript"> + +var SimpleTest = window.opener.SimpleTest; +var is = window.opener.is; + +function done() { + window.opener.done(); +} + +</script> +</body> +</html> diff --git a/system/docshell/test/file_pushState_after_document_open.html b/system/docshell/test/file_pushState_after_document_open.html new file mode 100644 index 000000000..97a6954f2 --- /dev/null +++ b/system/docshell/test/file_pushState_after_document_open.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<script> + document.addEventListener("DOMContentLoaded", function() { + document.open(); + document.write("<!DOCTYPE html>New Document here"); + document.close(); + // Notify parent via postMessage, since otherwise exceptions will not get + // caught by its onerror handler. + parent.postMessage("doTest", "*"); + }); +</script> diff --git a/system/docshell/test/historyframes.html b/system/docshell/test/historyframes.html new file mode 100644 index 000000000..30fca2c0a --- /dev/null +++ b/system/docshell/test/historyframes.html @@ -0,0 +1,150 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=602256 +--> +<head> + <title>Test for Bug 602256</title> +</head> +<body onload="SimpleTest.executeSoon(run_test)"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=602256">Mozilla Bug 602256</a> +<div id="content"> + <iframe id="iframe" src="data:text/html,<p%20id='text'>Start</p>"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 602256 **/ + +var testWin = window.opener ? window.opener : window.parent; + +var SimpleTest = testWin.SimpleTest; +function is() { testWin.is.apply(testWin, arguments); } + +var gFrame = null; + +function gState() { + return location.hash.replace(/^#/, ""); +} + +function waitForLoad(aCallback) { + function listener() { + gFrame.removeEventListener("load", listener, false); + SimpleTest.executeSoon(aCallback); + } + + gFrame.addEventListener("load", listener, false); +} + +function loadContent(aURL, aCallback) { + waitForLoad(aCallback); + + gFrame.src = aURL; +} + +function getURL() { + return gFrame.contentDocument.documentURI; +} + +function getContent() { + return gFrame.contentDocument.getElementById("text").textContent; +} + +var START = "data:text/html,<p%20id='text'>Start</p>"; +var URL1 = "data:text/html,<p%20id='text'>Test1</p>"; +var URL2 = "data:text/html,<p%20id='text'>Test2</p>"; + +function run_test() { + window.location.hash = "START"; + + gFrame = document.getElementById("iframe"); + + test_basic_inner_navigation(); +} + +function end_test() { + testWin.done(); +} + +function test_basic_inner_navigation() { + // Navigate the inner frame a few times + loadContent(URL1, function() { + is(getURL(), URL1, "URL should be correct"); + is(getContent(), "Test1", "Page should be correct"); + + loadContent(URL2, function() { + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + // Test that history is working + waitForLoad(function() { + is(getURL(), URL1, "URL should be correct"); + is(getContent(), "Test1", "Page should be correct"); + + waitForLoad(function() { + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + test_state_navigation(); + }); + window.history.forward(); + }); + window.history.back(); + }); + }); +} + +function test_state_navigation() { + window.location.hash = "STATE1"; + + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + window.location.hash = "STATE2"; + + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + window.history.back(); + + is(gState(), "STATE1", "State should be correct after going back"); + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + window.history.forward(); + + is(gState(), "STATE2", "State should be correct after going forward"); + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + window.history.back(); + window.history.back(); + + is(gState(), "START", "State should be correct"); + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + waitForLoad(function() { + is(getURL(), URL1, "URL should be correct"); + is(getContent(), "Test1", "Page should be correct"); + + waitForLoad(function() { + is(gState(), "START", "State should be correct"); + is(getURL(), START, "URL should be correct"); + is(getContent(), "Start", "Page should be correct"); + + end_test(); + }); + + window.history.back(); + + is(gState(), "START", "State should be correct after going back twice"); + }); + + window.history.back(); + is(gState(), "START", "State should be correct"); +} +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/iframesandbox/file_marquee_event_handlers.html b/system/docshell/test/iframesandbox/file_marquee_event_handlers.html new file mode 100644 index 000000000..13ee31ddb --- /dev/null +++ b/system/docshell/test/iframesandbox/file_marquee_event_handlers.html @@ -0,0 +1,17 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>Test marquee attribute event handlers in iframe sandbox</title> +</head> +<body> + <!-- Note that the width here is slightly longer than the contents, to make + sure we bounce and finish very quickly. --> + <marquee loop="2" width="145" behavior="alternate" truespeed scrolldelay="1" + onstart="parent.postMessage(window.name + ' marquee onstart', '*');" + onbounce="parent.postMessage(window.name + ' marquee onbounce', '*');" + onfinish="parent.postMessage(window.name + ' marquee onfinish', '*');"> + Will bounce and finish + </marquee> +</body> +</html> diff --git a/system/docshell/test/iframesandbox/file_other_auxiliary_navigation_by_location.html b/system/docshell/test/iframesandbox/file_other_auxiliary_navigation_by_location.html new file mode 100644 index 000000000..ad24c0f24 --- /dev/null +++ b/system/docshell/test/iframesandbox/file_other_auxiliary_navigation_by_location.html @@ -0,0 +1,15 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>Test window for other auxiliary navigation by location tests</title> +<script> + function onNav() { + opener.postMessage(window.name, "*"); + } + + window.onload = onNav; + window.onhashchange = onNav; +</script> +</head> +</html> diff --git a/system/docshell/test/iframesandbox/file_our_auxiliary_navigation_by_location.html b/system/docshell/test/iframesandbox/file_our_auxiliary_navigation_by_location.html new file mode 100644 index 000000000..978980df2 --- /dev/null +++ b/system/docshell/test/iframesandbox/file_our_auxiliary_navigation_by_location.html @@ -0,0 +1,15 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>Test window for our auxiliary navigation by location tests</title> +<script> + function onNav() { + opener.parent.postMessage(window.name, "*"); + } + + window.onload = onNav; + window.onhashchange = onNav; +</script> +</head> +</html> diff --git a/system/docshell/test/iframesandbox/file_parent_navigation_by_location.html b/system/docshell/test/iframesandbox/file_parent_navigation_by_location.html new file mode 100644 index 000000000..9a2e95fad --- /dev/null +++ b/system/docshell/test/iframesandbox/file_parent_navigation_by_location.html @@ -0,0 +1,18 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>Test window for parent navigation by location tests</title> +<script> + function onNav() { + parent.postMessage(window.name, "*"); + } + + window.onload = onNav; + window.onhashchange = onNav; +</script> +</head> +<body> + <iframe name="childIframe" sandbox="allow-scripts allow-same-origin allow-top-navigation"></iframe> +</body> +</html> diff --git a/system/docshell/test/iframesandbox/file_sibling_navigation_by_location.html b/system/docshell/test/iframesandbox/file_sibling_navigation_by_location.html new file mode 100644 index 000000000..51a52bb8e --- /dev/null +++ b/system/docshell/test/iframesandbox/file_sibling_navigation_by_location.html @@ -0,0 +1,15 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>Test window for sibling navigation by location tests</title> +<script> + function onNav() { + parent.postMessage(window.name, "*"); + } + + window.onload = onNav; + window.onhashchange = onNav; +</script> +</head> +</html> diff --git a/system/docshell/test/iframesandbox/file_top_navigation_by_location.html b/system/docshell/test/iframesandbox/file_top_navigation_by_location.html new file mode 100644 index 000000000..194430f38 --- /dev/null +++ b/system/docshell/test/iframesandbox/file_top_navigation_by_location.html @@ -0,0 +1,20 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>Test window for top navigation by location tests</title> +<script> + function onNav() { + opener.postMessage(window.name, "*"); + } + + window.onload = onNav; + window.onhashchange = onNav; +</script> +</head> +<body> + <iframe name="if1" sandbox="allow-scripts allow-same-origin"></iframe> + <iframe name="if2" sandbox="allow-scripts allow-same-origin allow-top-navigation"></iframe> + <iframe name="if3" sandbox="allow-scripts allow-top-navigation"></iframe> +</body> +</html> diff --git a/system/docshell/test/iframesandbox/file_top_navigation_by_location_exotic.html b/system/docshell/test/iframesandbox/file_top_navigation_by_location_exotic.html new file mode 100644 index 000000000..1c7c6ce29 --- /dev/null +++ b/system/docshell/test/iframesandbox/file_top_navigation_by_location_exotic.html @@ -0,0 +1,26 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>Test window for top navigation by location tests</title> +<script> + function onBlock() { + opener.postMessage({ name: window.name, blocked: true }, '*'); + } + + function onNav() { + opener.postMessage({ name: window.name, blocked: false }, '*'); + } + + function setOwnHref() { + location.href = location.href; + } + + window.onload = onNav; +</script> +</head> +<body> + <iframe name="if1" sandbox="allow-scripts allow-same-origin"></iframe> + <iframe name="if2" sandbox="allow-scripts allow-same-origin allow-top-navigation"></iframe> +</body> +</html> diff --git a/system/docshell/test/iframesandbox/mochitest.ini b/system/docshell/test/iframesandbox/mochitest.ini new file mode 100644 index 000000000..5f6b570e9 --- /dev/null +++ b/system/docshell/test/iframesandbox/mochitest.ini @@ -0,0 +1,24 @@ +[DEFAULT] +support-files = + file_marquee_event_handlers.html + file_other_auxiliary_navigation_by_location.html + file_our_auxiliary_navigation_by_location.html + file_parent_navigation_by_location.html + file_sibling_navigation_by_location.html + file_top_navigation_by_location.html + file_top_navigation_by_location_exotic.html + +[test_child_navigation_by_location.html] +[test_marquee_event_handlers.html] +[test_other_auxiliary_navigation_by_location.html] +tags = openwindow +[test_our_auxiliary_navigation_by_location.html] +tags = openwindow +[test_parent_navigation_by_location.html] +tags = openwindow +[test_sibling_navigation_by_location.html] +tags = openwindow +[test_top_navigation_by_location_exotic.html] +skip-if = android_version == '18' #bug 948948, NS_ERROR_FAILURE from nsWindowWatcher::GetPrompt +[test_top_navigation_by_location.html] +skip-if = android_version == '18' #bug 948948, NS_ERROR_FAILURE from nsWindowWatcher::GetPrompt diff --git a/system/docshell/test/iframesandbox/test_child_navigation_by_location.html b/system/docshell/test/iframesandbox/test_child_navigation_by_location.html new file mode 100644 index 000000000..06605e3cd --- /dev/null +++ b/system/docshell/test/iframesandbox/test_child_navigation_by_location.html @@ -0,0 +1,92 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=785310 +html5 sandboxed iframe should not be able to perform top navigation with scripts allowed +--> +<head> +<meta charset="utf-8"> +<title>Test for Bug 785310 - iframe sandbox child navigation by location tests</title> +<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script> + SimpleTest.waitForExplicitFinish(); + + var testHtml = "<script>function onNav() { parent.parent.postMessage('childIframe', '*'); } window.onload = onNav; window.onhashchange = onNav;<\/script>"; + var testDataUri = "data:text/html," + testHtml; + + function runScriptNavigationTest(testCase) { + window.onmessage = function(event) { + if (event.data != 'childIframe') { + ok(false, "event.data: got '" + event.data + "', expected 'childIframe'"); + } + ok(!testCase.shouldBeBlocked, testCase.desc, "child navigation was NOT blocked"); + runNextTest(); + }; + try { + window["parentIframe"].eval(testCase.script); + } catch(e) { + ok(testCase.shouldBeBlocked, testCase.desc, e.message); + runNextTest(); + } + } + + var testCaseIndex = -1; + testCases = [ + { + desc: "Test 1: cross origin child location.replace should NOT be blocked", + script: "window['crossOriginChildIframe'].location.replace(\"" + testDataUri + "\")", + shouldBeBlocked: false + }, + { + desc: "Test 2: cross origin child location.assign should be blocked", + script: "window['crossOriginChildIframe'].location.assign(\"" + testDataUri + "\")", + shouldBeBlocked: true + }, + { + desc: "Test 3: same origin child location.assign should NOT be blocked", + script: "window['sameOriginChildIframe'].location.assign(\"" + testDataUri + "\")", + shouldBeBlocked: false + }, + { + desc: "Test 4: cross origin child location.href should NOT be blocked", + script: "window['crossOriginChildIframe'].location.href = \"" + testDataUri + "\"", + shouldBeBlocked: false + }, + { + desc: "Test 5: cross origin child location.hash should be blocked", + script: "window['crossOriginChildIframe'].location.hash = 'wibble'", + shouldBeBlocked: true + }, + { + desc: "Test 6: same origin child location.hash should NOT be blocked", + script: "window['sameOriginChildIframe'].location.hash = 'wibble'", + shouldBeBlocked: false + } + ]; + + function runNextTest() { + ++testCaseIndex; + if (testCaseIndex == testCases.length) { + SimpleTest.finish(); + return; + } + + runScriptNavigationTest(testCases[testCaseIndex]); + } + + addLoadEvent(runNextTest); +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=785310">Mozilla Bug 785310</a> +<p id="display"></p> +<div id="content"> +Tests for Bug 785310 +</div> + +<iframe name="parentIframe" sandbox="allow-scripts allow-same-origin" src="data:text/html,<iframe name='sameOriginChildIframe'></iframe><iframe name='crossOriginChildIframe' sandbox='allow-scripts'></iframe>"</iframe> + +</body> +</html> diff --git a/system/docshell/test/iframesandbox/test_marquee_event_handlers.html b/system/docshell/test/iframesandbox/test_marquee_event_handlers.html new file mode 100644 index 000000000..f243e4834 --- /dev/null +++ b/system/docshell/test/iframesandbox/test_marquee_event_handlers.html @@ -0,0 +1,95 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1277475 +html5 sandboxed iframe should not run marquee attribute event handlers without allow-scripts +--> +<head> +<meta charset="utf-8"> +<title>Test for Bug 1277475 - html5 sandboxed iframe should not run marquee attribute event handlers without allow-scripts</title> +<script type="application/javascript" 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=1277475">Mozilla Bug 1277475</a> +<p id="display"></p> +<div id="content">Tests for Bug 1277475</div> + +<iframe id="if1" name="if1" src="file_marquee_event_handlers.html" + sandbox="allow-same-origin allow-forms allow-top-navigation allow-pointer-lock allow-orientation-lock allow-popups allow-modals allow-popups-to-escape-sandbox"> +</iframe> + +<iframe id="if2" name="if2" src="file_marquee_event_handlers.html" + sandbox="allow-scripts"></iframe> + +<script> + SimpleTest.waitForExplicitFinish(); + + var expectedMessages = new Set(); + var numberOfMessagesExpected = 4; + var unexpectedMessages = new Set(); + + window.onmessage = function (event) { + info(event.data + " message received"); + if (event.data.startsWith("if2") || event.data == "if1 chaser") { + expectedMessages.add(event.data); + if (expectedMessages.size == numberOfMessagesExpected) { + checkRecievedMessages(); + } + } else { + unexpectedMessages.add(event.data); + } + } + + function checkRecievedMessages() { + // Check the expected messages explicitly as a cross-check. + ok(expectedMessages.has("if1 chaser"), + "if1 chaser message should have been received"); + ok(expectedMessages.has("if2 marquee onstart"), + "if2 marquee onstart should have run in iframe sandbox with allow-scripts"); + ok(expectedMessages.has("if2 marquee onbounce"), + "if2 marquee onbounce should have run in iframe sandbox with allow-scripts"); + ok(expectedMessages.has("if2 marquee onfinish"), + "if2 marquee onfinish should have run in iframe sandbox with allow-scripts"); + + unexpectedMessages.forEach( + (v) => { + ok(false, v + " should NOT have run in iframe sandbox without allow-scripts") + } + ); + + SimpleTest.finish(); + } + + // If things are working properly the attribute event handlers won't run on + // the marquee in if1, so add our own capturing listeners on its window, so we + // know when they have fired. (These will run as we are not sandboxed.) + var if1FiredEvents = new Set(); + var if1NumberOfEventsExpected = 3; + var if1Win = document.getElementById("if1").contentWindow; + if1Win.addEventListener("start", () => { checkMarqueeEvent("start"); }, true); + if1Win.addEventListener("bounce", () => { checkMarqueeEvent("bounce"); }, true); + if1Win.addEventListener("finish", () => { checkMarqueeEvent("finish"); }, true); + + function checkMarqueeEvent(eventType) { + info("if1 event " + eventType + " fired"); + if1FiredEvents.add(eventType); + if (if1FiredEvents.size == if1NumberOfEventsExpected) { + // Only send the chasing message after a tick of the event loop to allow + // event handlers on the marquee to process. + SimpleTest.executeSoon(sendChasingMessage); + } + } + + function sendChasingMessage() { + // Add our own message listener to if1's window and echo back a chasing + // message to make sure that any messages from incorrectly run marquee + // attribute event handlers should have arrived before it. + if1Win.addEventListener("message", + (e) => { if1Win.parent.postMessage(e.data, "*"); }); + if1Win.postMessage("if1 chaser", "*"); + info("if1 chaser message sent"); + } +</script> +</body> +</html> diff --git a/system/docshell/test/iframesandbox/test_other_auxiliary_navigation_by_location.html b/system/docshell/test/iframesandbox/test_other_auxiliary_navigation_by_location.html new file mode 100644 index 000000000..05c86f0cc --- /dev/null +++ b/system/docshell/test/iframesandbox/test_other_auxiliary_navigation_by_location.html @@ -0,0 +1,80 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=785310 +html5 sandboxed iframe should not be able to perform top navigation with scripts allowed +--> +<head> +<meta charset="utf-8"> +<title>Test for Bug 785310 - iframe sandbox other auxiliary navigation by location tests</title> +<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script> + SimpleTest.waitForExplicitFinish(); + + function runScriptNavigationTest(testCase) { + window.onmessage = function(event) { + if (event.data != "otherWindow") { + ok(false, "event.data: got '" + event.data + "', expected 'otherWindow'"); + } + ok(false, testCase.desc, "auxiliary navigation was NOT blocked"); + runNextTest(); + }; + try { + window["testIframe"].eval(testCase.script); + } catch(e) { + ok(true, testCase.desc, e.message); + runNextTest(); + } + } + + var testCaseIndex = -1; + testCases = [ + { + desc: "Test 1: location.replace on auxiliary NOT opened by us should be blocked", + script: "parent.openedWindow.location.replace('file_other_auxiliary_navigation_by_location.html')" + }, + { + desc: "Test 2: location.assign on auxiliary NOT opened by us should be blocked", + script: "parent.openedWindow.location.assign('file_other_auxiliary_navigation_by_location.html')" + }, + { + desc: "Test 3: location.href on auxiliary NOT opened by us should be blocked", + script: "parent.openedWindow.location.href = 'file_other_auxiliary_navigation_by_location.html'" + }, + { + desc: "Test 4: location.hash on auxiliary NOT opened by us should be blocked", + script: "parent.openedWindow.location.hash = 'wibble'" + } + ]; + + function runNextTest() { + ++testCaseIndex; + if (testCaseIndex == testCases.length) { + openedWindow.close(); + SimpleTest.finish(); + return; + } + + runScriptNavigationTest(testCases[testCaseIndex]); + } + + window.onmessage = runNextTest; + + window.onload = function() { + window.openedWindow = window.open("file_other_auxiliary_navigation_by_location.html", "otherWindow"); + } +</script> + +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=785310">Mozilla Bug 785310</a> +<p id="display"></p> +<div id="content"> +Tests for Bug 785310 +</div> + +<iframe name="testIframe" sandbox="allow-scripts allow-same-origin allow-top-navigation allow-popups"></iframe> +</body> +</html> diff --git a/system/docshell/test/iframesandbox/test_our_auxiliary_navigation_by_location.html b/system/docshell/test/iframesandbox/test_our_auxiliary_navigation_by_location.html new file mode 100644 index 000000000..01b371545 --- /dev/null +++ b/system/docshell/test/iframesandbox/test_our_auxiliary_navigation_by_location.html @@ -0,0 +1,84 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=785310 +html5 sandboxed iframe should not be able to perform top navigation with scripts allowed +--> +<head> +<meta charset="utf-8"> +<title>Test for Bug 785310 - iframe sandbox our auxiliary navigation by location tests</title> +<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script> + SimpleTest.waitForExplicitFinish(); + + function runScriptNavigationTest(testCase) { + window.onmessage = function(event) { + if (event.data != "ourWindow") { + ok(false, "event.data: got '" + event.data + "', expected 'ourWindow'"); + } + ok(!testCase.shouldBeBlocked, testCase.desc, "auxiliary navigation was NOT blocked"); + runNextTest(); + }; + try { + SpecialPowers.wrap(window["testIframe"]).eval(testCase.script); + } catch(e) { + ok(testCase.shouldBeBlocked, testCase.desc, SpecialPowers.wrap(e).message); + runNextTest(); + } + } + + var testCaseIndex = -1; + testCases = [ + { + desc: "Test 1: location.replace on auxiliary opened by us should NOT be blocked", + script: "openedWindow.location.replace('file_our_auxiliary_navigation_by_location.html')", + shouldBeBlocked: false + }, + { + desc: "Test 2: location.assign on auxiliary opened by us should be blocked without allow-same-origin", + script: "openedWindow.location.assign('file_our_auxiliary_navigation_by_location.html')", + shouldBeBlocked: true + }, + { + desc: "Test 3: location.href on auxiliary opened by us should NOT be blocked", + script: "openedWindow.location.href = 'file_our_auxiliary_navigation_by_location.html'", + shouldBeBlocked: false + }, + { + desc: "Test 4: location.hash on auxiliary opened by us should be blocked without allow-same-origin", + script: "openedWindow.location.hash = 'wibble'", + shouldBeBlocked: true + } + ]; + + function runNextTest() { + ++testCaseIndex; + if (testCaseIndex == testCases.length) { + SpecialPowers.wrap(window["testIframe"]).eval("openedWindow.close()"); + SimpleTest.finish(); + return; + } + + runScriptNavigationTest(testCases[testCaseIndex]); + } + + window.onmessage = runNextTest; + + window.onload = function() { + SpecialPowers.wrap(window["testIframe"]).eval("var openedWindow = window.open('file_our_auxiliary_navigation_by_location.html', 'ourWindow')"); + } +</script> + +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=785310">Mozilla Bug 785310</a> +<p id="display"></p> +<div id="content"> +Tests for Bug 785310 +</div> + +<iframe name="testIframe" sandbox="allow-scripts allow-popups"></iframe> +</body> +</html> diff --git a/system/docshell/test/iframesandbox/test_parent_navigation_by_location.html b/system/docshell/test/iframesandbox/test_parent_navigation_by_location.html new file mode 100644 index 000000000..06335cdec --- /dev/null +++ b/system/docshell/test/iframesandbox/test_parent_navigation_by_location.html @@ -0,0 +1,75 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=785310 +html5 sandboxed iframe should not be able to perform top navigation with scripts allowed +--> +<head> +<meta charset="utf-8"> +<title>Test for Bug 785310 - iframe sandbox parent navigation by location tests</title> +<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script> + SimpleTest.waitForExplicitFinish(); + + function runScriptNavigationTest(testCase) { + window.onmessage = function(event) { + if (event.data != "parentIframe") { + ok(false, "event.data: got '" + event.data + "', expected 'parentIframe'"); + } + ok(false, testCase.desc, "parent navigation was NOT blocked"); + runNextTest(); + }; + try { + window["parentIframe"]["childIframe"].eval(testCase.script); + } catch(e) { + ok(true, testCase.desc, e.message); + runNextTest(); + } + } + + var testCaseIndex = -1; + testCases = [ + { + desc: "Test 1: parent.location.replace should be blocked even when sandboxed with allow-same-origin allow-top-navigation", + script: "parent.location.replace('file_parent_navigation_by_location.html')" + }, + { + desc: "Test 2: parent.location.assign should be blocked even when sandboxed with allow-same-origin allow-top-navigation", + script: "parent.location.assign('file_parent_navigation_by_location.html')" + }, + { + desc: "Test 3: parent.location.href should be blocked even when sandboxed with allow-same-origin allow-top-navigation", + script: "parent.location.href = 'file_parent_navigation_by_location.html'" + }, + { + desc: "Test 4: parent.location.hash should be blocked even when sandboxed with allow-same-origin allow-top-navigation", + script: "parent.location.hash = 'wibble'" + } + ]; + + function runNextTest() { + ++testCaseIndex; + if (testCaseIndex == testCases.length) { + SimpleTest.finish(); + return; + } + + runScriptNavigationTest(testCases[testCaseIndex]); + } + + window.onmessage = runNextTest; +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=785310">Mozilla Bug 785310</a> +<p id="display"></p> +<div id="content"> +Tests for Bug 785310 +</div> + +<iframe name="parentIframe" src="file_parent_navigation_by_location.html"></iframe> + +</body> +</html> diff --git a/system/docshell/test/iframesandbox/test_sibling_navigation_by_location.html b/system/docshell/test/iframesandbox/test_sibling_navigation_by_location.html new file mode 100644 index 000000000..a93c1ae0d --- /dev/null +++ b/system/docshell/test/iframesandbox/test_sibling_navigation_by_location.html @@ -0,0 +1,78 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=785310 +html5 sandboxed iframe should not be able to perform top navigation with scripts allowed +--> +<head> +<meta charset="utf-8"> +<title>Test for Bug 785310 - iframe sandbox sibling navigation by location tests</title> +<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script> + SimpleTest.waitForExplicitFinish(); + + function runScriptNavigationTest(testCase) { + window.onmessage = function(event) { + if (event.data != "siblingIframe") { + ok(false, "event.data: got '" + event.data + "', expected 'siblingIframe'"); + } + + ok(false, testCase.desc, "sibling navigation was NOT blocked"); + runNextTest(); + }; + + try { + window["testIframe"].eval(testCase.script); + } catch(e) { + ok(true, testCase.desc, e.message); + runNextTest(); + } + } + + var testCaseIndex = -1; + testCases = [ + { + desc: "Test 1: sibling location.replace should be blocked even when sandboxed with allow-same-origin allow-top-navigation", + script: "parent['siblingIframe'].location.replace('file_sibling_navigation_by_location.html')" + }, + { + desc: "Test 2: sibling location.assign should be blocked even when sandboxed with allow-same-origin allow-top-navigation", + script: "parent['siblingIframe'].location.assign('file_sibling_navigation_by_location.html')" + }, + { + desc: "Test 3: sibling location.href should be blocked even when sandboxed with allow-same-origin allow-top-navigation", + script: "parent['siblingIframe'].location.href = 'file_sibling_navigation_by_location.html'" + }, + { + desc: "Test 4: sibling location.hash should be blocked even when sandboxed with allow-same-origin allow-top-navigation", + script: "parent['siblingIframe'].location.hash = 'wibble'" + } + ]; + + function runNextTest() { + ++testCaseIndex; + if (testCaseIndex == testCases.length) { + SimpleTest.finish(); + return; + } + + runScriptNavigationTest(testCases[testCaseIndex]); + } + + window.onmessage = runNextTest; +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=785310">Mozilla Bug 785310</a> +<p id="display"></p> +<div id="content"> +Tests for Bug 785310 +</div> + +<iframe name="testIframe" sandbox="allow-scripts allow-same-origin allow-top-navigation"></iframe> +<iframe name="siblingIframe" src="file_sibling_navigation_by_location.html"></iframe> + +</body> +</html> diff --git a/system/docshell/test/iframesandbox/test_top_navigation_by_location.html b/system/docshell/test/iframesandbox/test_top_navigation_by_location.html new file mode 100644 index 000000000..3191539a2 --- /dev/null +++ b/system/docshell/test/iframesandbox/test_top_navigation_by_location.html @@ -0,0 +1,167 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=785310 +html5 sandboxed iframe should not be able to perform top navigation with scripts allowed +--> +<head> +<meta charset="utf-8"> +<title>Test for Bug 785310 - iframe sandbox top navigation by location tests</title> +<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script> + SimpleTest.waitForExplicitFinish(); + + var testWin; + + function runScriptNavigationTest(testCase) { + window.onmessage = function(event) { + if (event.data != "newTop") { + ok(false, "event.data: got '" + event.data + "', expected 'newTop'"); + } + ok(!testCase.shouldBeBlocked, testCase.desc, "top navigation was NOT blocked"); + runNextTest(); + }; + try { + SpecialPowers.wrap(testWin[testCase.iframeName]).eval(testCase.script); + } catch(e) { + ok(testCase.shouldBeBlocked, testCase.desc, SpecialPowers.wrap(e).message); + runNextTest(); + } + } + + var testCaseIndex = -1; + testCases = [ + { + desc: "Test 1: top.location.replace should be blocked when sandboxed without allow-top-navigation", + script: "top.location.replace('file_top_navigation_by_location.html')", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 2: top.location.assign should be blocked when sandboxed without allow-top-navigation", + script: "top.location.assign('file_top_navigation_by_location.html')", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 3: top.location.href should be blocked when sandboxed without allow-top-navigation", + script: "top.location.href = 'file_top_navigation_by_location.html'", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 4: top.location.pathname should be blocked when sandboxed without allow-top-navigation", + script: "top.location.pathname = top.location.pathname", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 5: top.location should be blocked when sandboxed without allow-top-navigation", + script: "top.location = 'file_top_navigation_by_location.html'", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 6: top.location.hash should be blocked when sandboxed without allow-top-navigation", + script: "top.location.hash = 'wibble'", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 7: top.location.replace should NOT be blocked when sandboxed with allow-same-origin allow-top-navigation", + script: "top.location.replace('file_top_navigation_by_location.html')", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 8: top.location.assign should NOT be blocked when sandboxed with allow-same-origin allow-top-navigation", + script: "top.location.assign('file_top_navigation_by_location.html')", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 9: top.location.href should NOT be blocked when sandboxed with allow-same-origin allow-top-navigation", + script: "top.location.href = 'file_top_navigation_by_location.html'", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 10: top.location.pathname should NOT be blocked when sandboxed with allow-same-origin allow-top-navigation", + script: "top.location.pathname = top.location.pathname", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 11: top.location should NOT be blocked when sandboxed with allow-same-origin allow-top-navigation", + script: "top.location = 'file_top_navigation_by_location.html'", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 12: top.location.hash should NOT be blocked when sandboxed with allow-same-origin allow-top-navigation", + script: "top.location.hash = 'wibble'", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 13: top.location.replace should NOT be blocked when sandboxed with allow-top-navigation, but without allow-same-origin", + script: "top.location.replace('file_top_navigation_by_location.html')", + iframeName: "if3", + shouldBeBlocked: false + }, + { + desc: "Test 14: top.location.assign should be blocked when sandboxed with allow-top-navigation, but without allow-same-origin", + script: "top.location.assign('file_top_navigation_by_location.html')", + iframeName: "if3", + shouldBeBlocked: true + }, + { + desc: "Test 15: top.location.href should NOT be blocked when sandboxed with allow-top-navigation, but without allow-same-origin", + script: "top.location.href = 'file_top_navigation_by_location.html'", + iframeName: "if3", + shouldBeBlocked: false + }, + { + desc: "Test 16: top.location.pathname should be blocked when sandboxed with allow-top-navigation, but without allow-same-origin", + script: "top.location.pathname = top.location.pathname", + iframeName: "if3", + shouldBeBlocked: true + }, + { + desc: "Test 17: top.location should NOT be blocked when sandboxed with allow-top-navigation, but without allow-same-origin", + script: "top.location = 'file_top_navigation_by_location.html'", + iframeName: "if3", + shouldBeBlocked: false + }, + { + desc: "Test 18: top.location.hash should be blocked when sandboxed with allow-top-navigation, but without allow-same-origin", + script: "top.location.hash = 'wibble'", + iframeName: "if3", + shouldBeBlocked: true + } + ]; + + function runNextTest() { + ++testCaseIndex; + if (testCaseIndex == testCases.length) { + testWin.close(); + SimpleTest.finish(); + return; + } + + runScriptNavigationTest(testCases[testCaseIndex]); + } + + window.onmessage = runNextTest; + testWin = window.open("file_top_navigation_by_location.html", "newTop"); +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=785310">Mozilla Bug 785310</a> +<p id="display"></p> +<div id="content"> +Tests for Bug 785310 +</div> +</body> +</html> diff --git a/system/docshell/test/iframesandbox/test_top_navigation_by_location_exotic.html b/system/docshell/test/iframesandbox/test_top_navigation_by_location_exotic.html new file mode 100644 index 000000000..fcc1f8659 --- /dev/null +++ b/system/docshell/test/iframesandbox/test_top_navigation_by_location_exotic.html @@ -0,0 +1,204 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=785310 +html5 sandboxed iframe should not be able to perform top navigation with scripts allowed +--> +<head> +<meta charset="utf-8"> +<title>Test for Bug 785310 - iframe sandbox top navigation by location via exotic means tests</title> +<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script> + SimpleTest.waitForExplicitFinish(); + + var testWin; + + function runScriptNavigationTest(testCase) { + window.onmessage = function(event) { + if (event.data.name != 'newWindow') { + ok(false, "event.data.name: got '" + event.data.name + "', expected 'newWindow'"); + } + var diag = "top navigation was " + (event.data.blocked ? "" : "NOT ") + "blocked"; + ok((testCase.shouldBeBlocked == event.data.blocked), testCase.desc, diag); + runNextTest(); + }; + try { + testWin[testCase.iframeName].eval(testCase.script); + } catch(e) { + ok(testCase.shouldBeBlocked, testCase.desc, e.message); + runNextTest(); + } + } + + var testCaseIndex = -1; + testCases = [ + { + desc: "Test 1: location.replace.call(top.location, ...) should be blocked when sandboxed without allow-top-navigation", + script: "location.replace.call(top.location, 'file_top_navigation_by_location_exotic.html')", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 2: location.replace.bind(top.location, ...) should be blocked when sandboxed without allow-top-navigation", + script: "location.replace.bind(top.location, 'file_top_navigation_by_location_exotic.html')()", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 3: Function.bind.call(location.replace, top.location, ...) should be blocked when sandboxed without allow-top-navigation", + script: "Function.bind.call(location.replace, top.location, 'file_top_navigation_by_location_exotic.html')()", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 4: location.replace.call(top.location, ...) should NOT be blocked when sandboxed with allow-top-navigation", + script: "location.replace.call(top.location, 'file_top_navigation_by_location_exotic.html')", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 5: location.replace.bind(top.location, ...) should NOT be blocked when sandboxed with allow-top-navigation", + script: "location.replace.bind(top.location, 'file_top_navigation_by_location_exotic.html')()", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 6: Function.bind.call(location.replace, top.location, ...) should NOT be blocked when sandboxed with allow-top-navigation", + script: "Function.bind.call(location.replace, top.location, 'file_top_navigation_by_location_exotic.html')()", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 7: top.location.href, via setTimeout, should be blocked when sandboxed without allow-top-navigation", + script: "setTimeout(function() { try { top.location.href = 'file_top_navigation_by_location_exotic.html' } catch (e) { top.onBlock() } }, 0)", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 8: top.location.href, via setTimeout, should NOT be blocked when sandboxed with allow-top-navigation", + script: "setTimeout(function() { try { top.location.href = 'file_top_navigation_by_location_exotic.html' } catch(e) { top.onBlock() } }, 0)", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 9: top.location.href, via eval, should be blocked when sandboxed without allow-top-navigation", + script: "eval('top.location.href = \"file_top_navigation_by_location_exotic.html\"')", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 10: top.location.href, via eval, should NOT be blocked when sandboxed with allow-top-navigation", + script: "eval('top.location.href = \"file_top_navigation_by_location_exotic.html\"')", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 11: top.location.href, via anonymous function, should be blocked when sandboxed without allow-top-navigation", + script: "(function() { top.location.href = 'file_top_navigation_by_location_exotic.html' })()", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 12: top.location.href, via anonymous function, should NOT be blocked when sandboxed with allow-top-navigation", + script: "(function() { top.location.href = 'file_top_navigation_by_location_exotic.html' })()", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 13: top.location.href, via function inserted in top, should be blocked when sandboxed without allow-top-navigation", + script: "top.doTest = function() { top.location.href = 'file_top_navigation_by_location_exotic.html' }; top.doTest();", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 14: top.location.href, via function inserted in top, should NOT be blocked when sandboxed with allow-top-navigation", + script: "top.doTest = function() { top.location.href = 'file_top_navigation_by_location_exotic.html' }; top.doTest();", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 15: top.location.href, via function inserted in us by top, should NOT be blocked when sandboxed without allow-top-navigation", + script: "top.eval('window[\"if1\"].doTest = function() { top.location.href = \"file_top_navigation_by_location_exotic.html\" };'), doTest();", + iframeName: "if1", + shouldBeBlocked: false + }, + { + desc: "Test 16: top.location.href, via function inserted in top, should NOT be blocked when sandboxed with allow-top-navigation", + script: "top.eval('window[\"if2\"].doTest = function() { top.location.href = \"file_top_navigation_by_location_exotic.html\" };'), doTest();", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 17: top.location.href, via function in top, should NOT be blocked when sandboxed without allow-top-navigation", + script: "top.setOwnHref()", + iframeName: "if1", + shouldBeBlocked: false + }, + { + desc: "Test 18: top.location.href, via function in top, should NOT be blocked when sandboxed with allow-top-navigation", + script: "top.setOwnHref()", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 19: top.location.href, via eval in top, should NOT be blocked when sandboxed without allow-top-navigation", + script: "top.eval('location.href = \"file_top_navigation_by_location_exotic.html\"')", + iframeName: "if1", + shouldBeBlocked: false + }, + { + desc: "Test 20: top.location.href, via eval in top, should NOT be blocked when sandboxed with allow-top-navigation", + script: "top.eval('location.href = \"file_top_navigation_by_location_exotic.html\"')", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 21: top.location.href, via eval in top calling us, should be blocked when sandboxed without allow-top-navigation", + script: "function doTest() { top.location.href = 'file_top_navigation_by_location_exotic.html' } top.eval('window[\"if1\"].doTest()');", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 22: top.location.href, via eval in top calling us, should NOT be blocked when sandboxed with allow-top-navigation", + script: "function doTest() { top.location.href = 'file_top_navigation_by_location_exotic.html' } top.eval('window[\"if2\"].doTest()');", + iframeName: "if2", + shouldBeBlocked: false + }, + { + desc: "Test 23: top.location.href, via function bound to top, should be blocked when sandboxed without allow-top-navigation", + script: "(function() { top.location.href = 'file_top_navigation_by_location_exotic.html' }).bind(top)();", + iframeName: "if1", + shouldBeBlocked: true + }, + { + desc: "Test 24: top.location.href, via function bound to top, should NOT be blocked when sandboxed with allow-top-navigation", + script: "(function() { top.location.href = 'file_top_navigation_by_location_exotic.html' }).bind(top)();", + iframeName: "if2", + shouldBeBlocked: false + } + ]; + + function runNextTest() { + ++testCaseIndex; + if (testCaseIndex == testCases.length) { + testWin.close(); + SimpleTest.finish(); + return; + } + + runScriptNavigationTest(testCases[testCaseIndex]); + } + + window.onmessage = runNextTest; + testWin = window.open('file_top_navigation_by_location_exotic.html', "newWindow"); +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=785310">Mozilla Bug 785310</a> +<p id="display"></p> +<div id="content"> +Tests for Bug 785310 +</div> +</body> +</html> diff --git a/system/docshell/test/mochitest.ini b/system/docshell/test/mochitest.ini new file mode 100644 index 000000000..d2e378928 --- /dev/null +++ b/system/docshell/test/mochitest.ini @@ -0,0 +1,102 @@ +[DEFAULT] +support-files = + bug123696-subframe.html + bug369814.jar + bug369814.zip + bug404548-subframe.html + bug413310-post.sjs + bug413310-subframe.html + bug529119-window.html + bug570341_recordevents.html + bug668513_redirect.html + bug668513_redirect.html^headers^ + bug691547_frame.html + dummy_page.html + file_anchor_scroll_after_document_open.html + file_bug385434_1.html + file_bug385434_2.html + file_bug385434_3.html + file_bug475636.sjs + file_bug509055.html + file_bug540462.html + file_bug580069_1.html + file_bug580069_2.sjs + file_bug598895_1.html + file_bug598895_2.html + file_bug590573_1.html + file_bug590573_2.html + file_bug634834.html + file_bug637644_1.html + file_bug637644_2.html + file_bug640387.html + file_bug653741.html + file_bug660404 + file_bug660404^headers^ + file_bug662170.html + file_bug669671.sjs + file_bug680257.html + file_bug703855.html + file_bug728939.html + file_bug1151421.html + file_pushState_after_document_open.html + historyframes.html + +[test_anchor_scroll_after_document_open.html] +[test_bfcache_plus_hash.html] +[test_bug123696.html] +[test_bug369814.html] +[test_bug384014.html] +[test_bug385434.html] +[test_bug387979.html] +[test_bug402210.html] +[test_bug404548.html] +[test_bug413310.html] +skip-if = true +# Disabled for too many intermittent failures (bug 719186) +[test_bug475636.html] +[test_bug509055.html] +[test_bug511449.html] +skip-if = toolkit != "cocoa" +support-files = file_bug511449.html +[test_bug529119-1.html] +[test_bug529119-2.html] +[test_bug530396.html] +support-files = bug530396-noref.sjs bug530396-subframe.html +[test_bug540462.html] +[test_bug551225.html] +[test_bug570341.html] +[test_bug580069.html] +[test_bug590573.html] +[test_bug598895.html] +skip-if = toolkit == 'android' +[test_bug634834.html] +[test_bug637644.html] +skip-if = toolkit == 'android' +[test_bug640387_1.html] +[test_bug640387_2.html] +[test_bug653741.html] +[test_bug660404.html] +[test_bug662170.html] +[test_bug668513.html] +skip-if = toolkit == 'android' +support-files = file_bug668513.html +[test_bug669671.html] +[test_bug675587.html] +[test_bug680257.html] +[test_bug691547.html] +[test_bug694612.html] +[test_bug703855.html] +[test_bug713825.html] +[test_bug728939.html] +[test_bug797909.html] +[test_bug1045096.html] +[test_bug1121701.html] +[test_bug1151421.html] +[test_bug1186774.html] +[test_forceinheritprincipal_overrule_owner.html] +[test_framedhistoryframes.html] +skip-if = toolkit == 'android' # bug 784321 +support-files = file_framedhistoryframes.html +[test_pushState_after_document_open.html] +[test_windowedhistoryframes.html] +[test_triggeringprincipal_location_seturi.html] diff --git a/system/docshell/test/navigation/NavigationUtils.js b/system/docshell/test/navigation/NavigationUtils.js new file mode 100644 index 000000000..72bea7dde --- /dev/null +++ b/system/docshell/test/navigation/NavigationUtils.js @@ -0,0 +1,215 @@ +/* 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; + +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); + sendMouseEvent({type:"click"}, link.id); +} + +/////////////////////////////////////////////////////////////////////////// +// Functions that call into Mochitest framework +/////////////////////////////////////////////////////////////////////////// + +function isNavigated(wnd, message) { + var result = null; + try { + result = SpecialPowers.wrap(wnd).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); + } +} + +/////////////////////////////////////////////////////////////////////////// +// Functions that require UniversalXPConnect privilege +/////////////////////////////////////////////////////////////////////////// + +function xpcEnumerateContentWindows(callback) { + + var Ci = SpecialPowers.Ci; + var ww = SpecialPowers.Cc["@mozilla.org/embedcomp/window-watcher;1"] + .getService(Ci.nsIWindowWatcher); + var enumerator = ww.getWindowEnumerator(); + + var contentWindows = []; + + while (enumerator.hasMoreElements()) { + var win = enumerator.getNext(); + if (/ChromeWindow/.exec(win)) { + var docshellTreeNode = win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem); + var childCount = docshellTreeNode.childCount; + for (var i = 0; i < childCount; ++i) { + var childTreeNode = docshellTreeNode.getChildAt(i); + + // we're only interested in content docshells + if (SpecialPowers.unwrap(childTreeNode.itemType) != Ci.nsIDocShellTreeItem.typeContent) + continue; + + var webNav = childTreeNode.QueryInterface(Ci.nsIWebNavigation); + contentWindows.push(webNav.document.defaultView); + } + } else { + contentWindows.push(win); + } + } + + while (contentWindows.length > 0) + callback(contentWindows.pop()); +} + +// Note: This only searches for top-level frames with this name. +function xpcGetFramesByName(name) { + var results = []; + + xpcEnumerateContentWindows(function(win) { + if (win.name == name) + results.push(win); + }); + + return results; +} + +function xpcCleanupWindows() { + xpcEnumerateContentWindows(function(win) { + if (win.location && + (win.location.href.endsWith(target_url) || + win.location.href.endsWith(target_popup_url))) { + win.close(); + }); +} + +function xpcWaitForFinishedFrames(callback, numFrames) { + var finishedFrameCount = 0; + function frameFinished() { + finishedFrameCount++; + + if (finishedFrameCount == numFrames) { + clearInterval(frameWaitInterval); + setTimeout(callback, 0); + return; + } + + if (finishedFrameCount > numFrames) + throw "Too many frames loaded."; + } + + var finishedWindows = []; + + function contains(obj, arr) { + for (var i = 0; i < arr.length; i++) { + if (obj === arr[i]) + return true; + } + return false; + } + + function searchForFinishedFrames(win) { + if ((win.location.href.endsWith(target_url) || + win.location.href.endsWith(target_popup_url)) && + win.document && + win.document.body && + (win.document.body.textContent.trim() == body || + win.document.body.textContent.trim() == popup_body) && + win.document.readyState == "complete") { + + var util = win.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIDOMWindowUtils); + var windowId = util.outerWindowID; + if (!contains(windowId, finishedWindows)) { + finishedWindows.push(windowId); + frameFinished(); + } + } + for (var i = 0; i < win.frames.length; i++) + searchForFinishedFrames(win.frames[i]); + } + + function poll() { + try { + // This only gives us UniversalXPConnect for the current stack frame + // We're using setInterval, so the main page's privileges are still normal + xpcEnumerateContentWindows(searchForFinishedFrames); + } catch(ex) { + // We might be accessing windows before they are fully constructed, + // which can throw. We'll find those frames on our next poll(). + } + } + + var frameWaitInterval = setInterval(poll, 500); +} + diff --git a/system/docshell/test/navigation/blank.html b/system/docshell/test/navigation/blank.html new file mode 100644 index 000000000..5360333f1 --- /dev/null +++ b/system/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/system/docshell/test/navigation/browser.ini b/system/docshell/test/navigation/browser.ini new file mode 100644 index 000000000..f25853f89 --- /dev/null +++ b/system/docshell/test/navigation/browser.ini @@ -0,0 +1,12 @@ +[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_bug343515.js] +[browser_test-content-chromeflags.js] +tags = openwindow
\ No newline at end of file diff --git a/system/docshell/test/navigation/browser_bug343515.js b/system/docshell/test/navigation/browser_bug343515.js new file mode 100644 index 000000000..74152b493 --- /dev/null +++ b/system/docshell/test/navigation/browser_bug343515.js @@ -0,0 +1,262 @@ +// 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 = {}; + +// We need to wait until the page from each testcase is fully loaded, +// including all of its descendant iframes. To do that we manually count +// how many load events should happen on that page (one for the toplevel doc +// and one for each subframe) and wait until we receive the expected number +// of events. +function nShotsListener(aElem, aType, aCallback, aCount) { + let count = aCount; + aElem.addEventListener(aType, function listenerCallback() { + if (--count == 0) { + aElem.removeEventListener(aType, listenerCallback, true); + + // aCallback is executed asynchronously, which is handy because load + // events fire before mIsDocumentLoaded is actually set to true. :( + executeSoon(aCallback); + } + }, true); +} + +function oneShotListener(aElem, aType, aCallback) { + nShotsListener(aElem, aType, aCallback, 1); +} + +function waitForPageshow(aBrowser, callback) { + return ContentTask.spawn(aBrowser, null, function* () { + yield ContentTaskUtils.waitForEvent(this, "pageshow"); + }).then(callback); +} + +// Entry point from Mochikit +function test() { + + // Lots of callbacks going on here + waitForExplicitFinish(); + + // Begin the test + step1(); +} + +function step1() { + + // Get a handle on the initial tab + ctx.tab0 = gBrowser.selectedTab; + ctx.tab0Browser = gBrowser.getBrowserForTab(ctx.tab0); + + // Our current tab should be active + ok(ctx.tab0Browser.docShellIsActive, "Tab 0 should be active at test start"); + + // Open a New Tab + ctx.tab1 = gBrowser.addTab(testPath + "bug343515_pg1.html"); + ctx.tab1Browser = gBrowser.getBrowserForTab(ctx.tab1); + oneShotListener(ctx.tab1Browser, "load", step2); +} + +function step2() { + 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 + BrowserTestUtils.switchTab(gBrowser, ctx.tab1).then(() => { + // 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 = gBrowser.addTab(testPath + "bug343515_pg2.html"); + ctx.tab2Browser = gBrowser.getBrowserForTab(ctx.tab2); + + // bug343515_pg2.html consists of a page with two iframes, + // which will therefore generate 3 load events. + nShotsListener(ctx.tab2Browser, "load", step3, 3); + }); +} + +function step3() { + 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"); + ContentTask.spawn(ctx.tab2Browser, null, 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 docshell = content.frames[i].QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell); + + Assert.ok(!docShell.isActive, `Tab2 iframe ${i} should be inactive`); + } + }).then(() => { + // Navigate tab 2 to a different page + ctx.tab2Browser.loadURI(testPath + "bug343515_pg3.html"); + + // bug343515_pg3.html consists of a page with two iframes, one of which + // contains another iframe, so there'll be a total of 4 load events + nShotsListener(ctx.tab2Browser, "load", step4, 4); + }); +} + +function step4() { + function checkTab2Active(expected) { + return ContentTask.spawn(ctx.tab2Browser, expected, function* (expected) { + function isActive(aWindow) { + var docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell); + return docshell.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 + checkTab2Active(false).then(() => { + // Switch to Tab 2 + return BrowserTestUtils.switchTab(gBrowser, ctx.tab2); + }).then(() => { + // 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"); + + return checkTab2Active(true); + }).then(() => { + // Go back + waitForPageshow(ctx.tab2Browser, step5); + ctx.tab2Browser.goBack(); + }); +} + +function step5() { + // 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"); + ContentTask.spawn(ctx.tab2Browser, null, function* () { + for (var i = 0; i < content.frames.length; i++) { + let docshell = content.frames[i].QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell); + + Assert.ok(docShell.isActive, `Tab2 iframe ${i} should be active`); + } + }).then(() => { + // Switch to tab 1 + return BrowserTestUtils.switchTab(gBrowser, ctx.tab1); + }).then(() => { + // Navigate to page 3 + ctx.tab1Browser.loadURI(testPath + "bug343515_pg3.html"); + + // bug343515_pg3.html consists of a page with two iframes, one of which + // contains another iframe, so there'll be a total of 4 load events + nShotsListener(ctx.tab1Browser, "load", step6, 4); + }); +} + +function step6() { + + // Check everything + ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); + ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active"); + ContentTask.spawn(ctx.tab1Browser, null, function* () { + function isActive(aWindow) { + var docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell); + return docshell.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"); + }).then(() => { + ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive"); + return ContentTask.spawn(ctx.tab2Browser, null, function* () { + for (var i = 0; i < content.frames.length; i++) { + let docshell = content.frames[i].QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell); + + Assert.ok(!docShell.isActive, `Tab2 iframe ${i} should be inactive`); + } + }); + }).then(() => { + // Go forward on tab 2 + waitForPageshow(ctx.tab2Browser, step7); + ctx.tab2Browser.goForward(); + }); +} + +function step7() { + function checkBrowser(browser, tabNum, active) { + return ContentTask.spawn(browser, { tabNum, active }, + function* ({ tabNum, active }) { + function isActive(aWindow) { + var docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell); + return docshell.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"); + checkBrowser(ctx.tab1Browser, 1, true).then(() => { + ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive"); + return checkBrowser(ctx.tab2Browser, 2, false); + }).then(() => { + // That's probably enough + allDone(); + }); +} + +function allDone() { + + // Close the tabs we made + gBrowser.removeTab(ctx.tab1); + gBrowser.removeTab(ctx.tab2); + + // Tell the framework we're done + finish(); +} diff --git a/system/docshell/test/navigation/browser_test-content-chromeflags.js b/system/docshell/test/navigation/browser_test-content-chromeflags.js new file mode 100644 index 000000000..64559897c --- /dev/null +++ b/system/docshell/test/navigation/browser_test-content-chromeflags.js @@ -0,0 +1,45 @@ +const TEST_PAGE = `data:text/html,<html><body><a href="about:blank" target="_blank">Test</a></body></html>`; +const CHROME_ALL = Ci.nsIWebBrowserChrome.CHROME_ALL; +const CHROME_REMOTE_WINDOW = Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW; + +/** + * Tests that when we open new browser windows from content they + * get the full browser chrome. + */ +add_task(function* () { + // Make sure that the window.open call will open a new + // window instead of a new tab. + yield new Promise(resolve => { + SpecialPowers.pushPrefEnv({ + "set": [ + ["browser.link.open_newwindow", 2], + ] + }, resolve); + }); + + yield BrowserTestUtils.withNewTab({ + gBrowser, + url: TEST_PAGE + }, function*(browser) { + let openedPromise = BrowserTestUtils.waitForNewWindow(); + BrowserTestUtils.synthesizeMouse("a", 0, 0, {}, browser); + let win = yield openedPromise; + + let chromeFlags = win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem) + .treeOwner + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIXULWindow) + .chromeFlags; + + // In the multi-process case, the new window will have the + // CHROME_REMOTE_WINDOW flag set. + const EXPECTED = gMultiProcessBrowser ? CHROME_ALL | CHROME_REMOTE_WINDOW + : CHROME_ALL; + + is(chromeFlags, EXPECTED, "Window should have opened with all chrome"); + + BrowserTestUtils.closeWindow(win); + }); +}); diff --git a/system/docshell/test/navigation/bug343515_pg1.html b/system/docshell/test/navigation/bug343515_pg1.html new file mode 100644 index 000000000..a8337c7f7 --- /dev/null +++ b/system/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/system/docshell/test/navigation/bug343515_pg2.html b/system/docshell/test/navigation/bug343515_pg2.html new file mode 100644 index 000000000..c5f5665de --- /dev/null +++ b/system/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/system/docshell/test/navigation/bug343515_pg3.html b/system/docshell/test/navigation/bug343515_pg3.html new file mode 100644 index 000000000..fdc79fbf7 --- /dev/null +++ b/system/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/system/docshell/test/navigation/bug343515_pg3_1.html b/system/docshell/test/navigation/bug343515_pg3_1.html new file mode 100644 index 000000000..254164c9f --- /dev/null +++ b/system/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/system/docshell/test/navigation/bug343515_pg3_1_1.html b/system/docshell/test/navigation/bug343515_pg3_1_1.html new file mode 100644 index 000000000..be05b7488 --- /dev/null +++ b/system/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/system/docshell/test/navigation/bug343515_pg3_2.html b/system/docshell/test/navigation/bug343515_pg3_2.html new file mode 100644 index 000000000..7655eb526 --- /dev/null +++ b/system/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/system/docshell/test/navigation/file_bug1300461.html b/system/docshell/test/navigation/file_bug1300461.html new file mode 100644 index 000000000..1ba935046 --- /dev/null +++ b/system/docshell/test/navigation/file_bug1300461.html @@ -0,0 +1,63 @@ +<!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) + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(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(); + opener.is(shistory.requestedIndex, 1, 'check requestedIndex'); + }, + 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.nextTest(); + window.close(); + } + ]; + + function test() { + if (opener) { + opener.info('file_bug1300461.html test ' + opener.testCount); + testSteps[opener.testCount++](); + } + } + </script> + </body> +</html> diff --git a/system/docshell/test/navigation/file_bug1300461_back.html b/system/docshell/test/navigation/file_bug1300461_back.html new file mode 100644 index 000000000..7b187742f --- /dev/null +++ b/system/docshell/test/navigation/file_bug1300461_back.html @@ -0,0 +1,31 @@ +<!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) + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation); + let shistory = webNav.sessionHistory; + 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'); + opener.is(shistory.requestedIndex, -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/system/docshell/test/navigation/file_bug1300461_redirect.html b/system/docshell/test/navigation/file_bug1300461_redirect.html new file mode 100644 index 000000000..979530c5c --- /dev/null +++ b/system/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/system/docshell/test/navigation/file_bug1300461_redirect.html^headers^ b/system/docshell/test/navigation/file_bug1300461_redirect.html^headers^ new file mode 100644 index 000000000..241b89182 --- /dev/null +++ b/system/docshell/test/navigation/file_bug1300461_redirect.html^headers^ @@ -0,0 +1,2 @@ +HTTP 301 Moved Permanently +Location: file_bug1300461_back.html diff --git a/system/docshell/test/navigation/file_bug1379762-1.html b/system/docshell/test/navigation/file_bug1379762-1.html new file mode 100644 index 000000000..e8cd8b30b --- /dev/null +++ b/system/docshell/test/navigation/file_bug1379762-1.html @@ -0,0 +1,32 @@ +<!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 + opener.is(opener.testCount, 0, + "We should only run once; otherwise the loadCount variable makes no sense"); + var loadCount = 0; + onpageshow = function() { + ++opener.testCount; + if (opener.testCount == 1) { + // Navigate forward and then back. + setTimeout(function() { location = "goback.html"; }, 0); + } else if (opener.testCount == 2) { + // Do this async so our load event gets a chance to fire if it plans to + // do it. + setTimeout(function() { + opener.nextTest(); + window.close(); + }); + } + }; + onload = function() { + ++loadCount; + opener.is(loadCount, 1, "Should only get one onload"); + } + </script> +</html> diff --git a/system/docshell/test/navigation/file_bug462076_1.html b/system/docshell/test/navigation/file_bug462076_1.html new file mode 100644 index 000000000..5b7bf2b11 --- /dev/null +++ b/system/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 i = 0; i < randomNumber; ++i) { + makeFrame(i); + } + } + + function checkFrame(evt) { + var ifr = evt.target; + opener.ok(new String(ifr.contentWindow.location).indexOf(ifr.src) >= 0, + "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/system/docshell/test/navigation/file_bug462076_2.html b/system/docshell/test/navigation/file_bug462076_2.html new file mode 100644 index 000000000..813a6d840 --- /dev/null +++ b/system/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 i = 0; i < randomNumber; ++i) { + makeFrame(i); + } + } + + function checkFrame(evt) { + var ifr = evt.target; + opener.ok(new String(ifr.contentWindow.location).indexOf(ifr.src) >= 0, + "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/system/docshell/test/navigation/file_bug462076_3.html b/system/docshell/test/navigation/file_bug462076_3.html new file mode 100644 index 000000000..0079b9cdf --- /dev/null +++ b/system/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 i = 0; i < randomNumber; ++i) { + makeFrame(i); + } + } + + function checkFrame(evt) { + var ifr = evt.target; + opener.ok(new String(ifr.contentWindow.location).indexOf(ifr.src) >= 0, + "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/system/docshell/test/navigation/file_bug508537_1.html b/system/docshell/test/navigation/file_bug508537_1.html new file mode 100644 index 000000000..194165f43 --- /dev/null +++ b/system/docshell/test/navigation/file_bug508537_1.html @@ -0,0 +1,34 @@ +<html> + <head> + <script> + function dynFrameLoad() { + var ifrs = document.getElementsByTagName("iframe"); + opener.ok(new String(ifrs[0].contentWindow.location).indexOf(ifrs[0].src) >= 0, + "Wrong document loaded (1)\n"); + opener.ok(new String(ifrs[1].contentWindow.location).indexOf(ifrs[1].src) >= 0, + "Wrong document loaded (2)\n"); + if (opener && ++opener.testCount == 1) { + window.location = "goback.html"; + } else { + opener.nextTest(); + window.close(); + } + } + + window.addEventListener("load", + function () { + var container = document.getElementById("t1"); + container.addEventListener("load", dynFrameLoad, true); + container.appendChild(container.appendChild(document.getElementById("i1"))); + }, false); + </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/system/docshell/test/navigation/file_bug534178.html b/system/docshell/test/navigation/file_bug534178.html new file mode 100644 index 000000000..8bcedb6fb --- /dev/null +++ b/system/docshell/test/navigation/file_bug534178.html @@ -0,0 +1,31 @@ +<html> + <head> + <script> + + function testDone() { + document.body.removeChild(document.body.firstChild); + 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 transactions should have been removed!"); + opener.nextTest(); + window.close(); + } + 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/system/docshell/test/navigation/file_contentpolicy_block_window.html b/system/docshell/test/navigation/file_contentpolicy_block_window.html new file mode 100644 index 000000000..c51e574e5 --- /dev/null +++ b/system/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/system/docshell/test/navigation/file_document_write_1.html b/system/docshell/test/navigation/file_document_write_1.html new file mode 100644 index 000000000..169046a9b --- /dev/null +++ b/system/docshell/test/navigation/file_document_write_1.html @@ -0,0 +1,19 @@ +<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.nextTest(); + window.close(); + } + </script> + </head> + <body onload="start();"> + <h5>static content</h5> + </body> +</html> diff --git a/system/docshell/test/navigation/file_fragment_handling_during_load.html b/system/docshell/test/navigation/file_fragment_handling_during_load.html new file mode 100644 index 000000000..fbfa0cb38 --- /dev/null +++ b/system/docshell/test/navigation/file_fragment_handling_during_load.html @@ -0,0 +1,24 @@ +<html> + <head> + <script> + var timerID = 0; + function testDone() { + clearTimeout(timerID); + var l = document.body.firstChild.contentWindow.location.href; + opener.is(l, "data:text/html,bar", "Should have loaded a new document"); + opener.nextTest(); + window.close(); + } + function test() { + var ifr = document.getElementsByTagName("iframe")[0]; + ifr.onload = testDone; + ifr.contentWindow.location.hash = "b"; + ifr.contentWindow.location.href = "data:text/html,bar"; + history.back(); + timerID = setTimeout(testDone, 2000); + } + </script> + </head> + <body onload="setTimeout(test, 0)"><iframe src="data:text/html,foo#a"></iframe> + </body> +</html> diff --git a/system/docshell/test/navigation/file_nested_frames.html b/system/docshell/test/navigation/file_nested_frames.html new file mode 100644 index 000000000..f65d8e01b --- /dev/null +++ b/system/docshell/test/navigation/file_nested_frames.html @@ -0,0 +1,28 @@ +<html> + <head> + <script> + function nestedIframeLoaded() { + var tf = document.getElementById("testframe"); + var innerf = tf.contentDocument.getElementsByTagName("iframe")[0]; + if (innerf.contentDocument.documentURI.indexOf("frame0") < 0) { + 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.nextTest(); + window.close(); + } + </script> + </head> + <body> + <iframe id="testframe" src="data:text/html,<iframe onload='parent.nestedIframeLoaded();'></iframe>" onload="frameLoaded()"></iframe> + <script> + </script> + </body> +</html> diff --git a/system/docshell/test/navigation/file_scrollRestoration.html b/system/docshell/test/navigation/file_scrollRestoration.html new file mode 100644 index 000000000..766949d13 --- /dev/null +++ b/system/docshell/test/navigation/file_scrollRestoration.html @@ -0,0 +1,137 @@ +<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.ok(history.scrollRestoration, "auto", "history.scrollRestoration's default value should be 'auto'."); + history.scrollRestoration = "foobar"; + opener.ok(history.scrollRestoration, "auto", "Invalid enum value should not change the value of an attribute."); + history.scrollRestoration = "manual"; + opener.ok(history.scrollRestoration, "manual", "Valid enum value should change the value of an attribute."); + history.scrollRestoration = "auto"; + opener.ok(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. + opener.setTimeout("testWindow.history.back();", 250); + 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() {} // Disable bfcache. + opener.setTimeout("is(testWindow.history.scrollRestoration, 'auto'); testWindow.history.back();", 250); + 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(); + 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(); + 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(); + window.scrollTo(0, 0); + history.forward(); + 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 7: { + oldHistoryObject = event.target.contentWindow.history; + event.target.src = "about:blank"; + break; + } + case 8: { + try { + var sr = 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.nextTest(); + window.close(); + 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/system/docshell/test/navigation/file_shiftReload_and_pushState.html b/system/docshell/test/navigation/file_shiftReload_and_pushState.html new file mode 100644 index 000000000..5a777894b --- /dev/null +++ b/system/docshell/test/navigation/file_shiftReload_and_pushState.html @@ -0,0 +1,29 @@ +<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.nextTest(); + window.close(); + } + } + + window.addEventListener("load", function() { setTimeout(test, 0); }); + </script> + </head> + <body> + <iframe src="frame0.html"></iframe> + <script> + </script> + </body> +</html> diff --git a/system/docshell/test/navigation/file_static_and_dynamic_1.html b/system/docshell/test/navigation/file_static_and_dynamic_1.html new file mode 100644 index 000000000..692a5a9ab --- /dev/null +++ b/system/docshell/test/navigation/file_static_and_dynamic_1.html @@ -0,0 +1,32 @@ +<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(new String(staticFrame.contentWindow.location).indexOf(staticFrame.src) >= 0, + "Wrong document loaded!"); + opener.nextTest(); + window.close(); + } + } + </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/system/docshell/test/navigation/file_triggeringprincipal_frame_1.html b/system/docshell/test/navigation/file_triggeringprincipal_frame_1.html new file mode 100644 index 000000000..1e21e6421 --- /dev/null +++ b/system/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, false); + 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, false); + window.parent.postMessage({triggeringPrincipalURI: 'false'}, '*'); + } + // click the link to navigate the subframe + document.getElementById('testlink').click(); + } +</script> + +</body> +</html> diff --git a/system/docshell/test/navigation/file_triggeringprincipal_frame_2.html b/system/docshell/test/navigation/file_triggeringprincipal_frame_2.html new file mode 100644 index 000000000..ef7cdfc17 --- /dev/null +++ b/system/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/system/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a.html b/system/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a.html new file mode 100644 index 000000000..75b2933c1 --- /dev/null +++ b/system/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/system/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html b/system/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html new file mode 100644 index 000000000..0479f5e1e --- /dev/null +++ b/system/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/system/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_b.html b/system/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_b.html new file mode 100644 index 000000000..e5d40b267 --- /dev/null +++ b/system/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/system/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_base.html b/system/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_base.html new file mode 100644 index 000000000..caa6b275b --- /dev/null +++ b/system/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/system/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_nav.html b/system/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_nav.html new file mode 100644 index 000000000..f4a4d0e63 --- /dev/null +++ b/system/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/system/docshell/test/navigation/file_triggeringprincipal_subframe.html b/system/docshell/test/navigation/file_triggeringprincipal_subframe.html new file mode 100644 index 000000000..0db1349f2 --- /dev/null +++ b/system/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/system/docshell/test/navigation/file_triggeringprincipal_subframe_nav.html b/system/docshell/test/navigation/file_triggeringprincipal_subframe_nav.html new file mode 100644 index 000000000..3bf7097a6 --- /dev/null +++ b/system/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(document).docShell.currentDocumentChannel; + var triggeringPrincipalURI = channel.loadInfo.triggeringPrincipal.URI.asciiSpec; + var loadingPrincipalURI = channel.loadInfo.loadingPrincipal.URI.asciiSpec; + var referrerURI = document.referrer; + window.parent.parent.postMessage({triggeringPrincipalURI, + loadingPrincipalURI, + referrerURI}, '*'); + } +</script> +</body> +</html> diff --git a/system/docshell/test/navigation/file_triggeringprincipal_window_open.html b/system/docshell/test/navigation/file_triggeringprincipal_window_open.html new file mode 100644 index 000000000..d0644a4d5 --- /dev/null +++ b/system/docshell/test/navigation/file_triggeringprincipal_window_open.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<body> +http +</body> +</html> diff --git a/system/docshell/test/navigation/frame0.html b/system/docshell/test/navigation/frame0.html new file mode 100644 index 000000000..93d1c9c82 --- /dev/null +++ b/system/docshell/test/navigation/frame0.html @@ -0,0 +1,3 @@ +<html> + <body>Frame 0</body> +</html> diff --git a/system/docshell/test/navigation/frame1.html b/system/docshell/test/navigation/frame1.html new file mode 100644 index 000000000..4d06c09d1 --- /dev/null +++ b/system/docshell/test/navigation/frame1.html @@ -0,0 +1,3 @@ +<html> + <body>Frame 1</body> +</html> diff --git a/system/docshell/test/navigation/frame2.html b/system/docshell/test/navigation/frame2.html new file mode 100644 index 000000000..7a3b5e0b9 --- /dev/null +++ b/system/docshell/test/navigation/frame2.html @@ -0,0 +1,3 @@ +<html> + <body>Frame 2</body> +</html> diff --git a/system/docshell/test/navigation/frame3.html b/system/docshell/test/navigation/frame3.html new file mode 100644 index 000000000..fd2429387 --- /dev/null +++ b/system/docshell/test/navigation/frame3.html @@ -0,0 +1,3 @@ +<html> + <body>Frame 3</body> +</html> diff --git a/system/docshell/test/navigation/goback.html b/system/docshell/test/navigation/goback.html new file mode 100644 index 000000000..ce2968374 --- /dev/null +++ b/system/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/system/docshell/test/navigation/iframe.html b/system/docshell/test/navigation/iframe.html new file mode 100644 index 000000000..4685fea7b --- /dev/null +++ b/system/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/system/docshell/test/navigation/mochitest.ini b/system/docshell/test/navigation/mochitest.ini new file mode 100644 index 000000000..e2ee307e4 --- /dev/null +++ b/system/docshell/test/navigation/mochitest.ini @@ -0,0 +1,69 @@ +[DEFAULT] +support-files = + NavigationUtils.js + navigation_target_url.html + navigation_target_popup_url.html + blank.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_nested_frames.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 + navigate.html + open.html + parent.html + file_triggeringprincipal_frame_1.html + file_triggeringprincipal_frame_2.html + file_triggeringprincipal_subframe.html + file_triggeringprincipal_subframe_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_bug1300461.html + file_bug1300461_redirect.html + file_bug1300461_redirect.html^headers^ + file_bug1300461_back.html + file_contentpolicy_block_window.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 = (toolkit == 'android') || (!debug && (os == 'mac' || os == 'win')) # Bug 874423 +[test_child.html] +[test_grandchild.html] +[test_not-opener.html] +[test_opener.html] +[test_popup-navigates-children.html] +[test_reserved.html] +skip-if = (toolkit == 'android') || (debug && e10s) #too slow on Android 4.3 aws only; bug 1030403; bug 1263213 for debug e10s +[test_sessionhistory.html] +skip-if = toolkit == 'android' #RANDOM on Android +support-files = file_bug1379762-1.html +[test_sibling-matching-parent.html] +[test_sibling-off-domain.html] +[test_triggeringprincipal_frame_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] diff --git a/system/docshell/test/navigation/navigate.html b/system/docshell/test/navigation/navigate.html new file mode 100644 index 000000000..e686da423 --- /dev/null +++ b/system/docshell/test/navigation/navigate.html @@ -0,0 +1,36 @@ +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <script src="NavigationUtils.js"></script> + <script> + function navigate() { + var arguments = window.location.hash.substring(1).split(","); + var target = arguments[0]; + var mechanism = arguments[1]; + + switch(mechanism) { + case "location": + navigateByLocation(eval(target)); + break; + case "open": + navigateByOpen(target); + break; + case "form": + navigateByForm(target); + break; + case "hyperlink": + navigateByHyperlink(target); + break; + } + } + </script> +</head> +<body onload="navigate();"> +<script> +var arguments = window.location.hash.substring(1).split(","); +var target = arguments[0]; +var mechanism = arguments[1]; +document.write("target=" + target + " mechanism=" + mechanism); +</script> +</body> +</html> diff --git a/system/docshell/test/navigation/navigation_target_popup_url.html b/system/docshell/test/navigation/navigation_target_popup_url.html new file mode 100644 index 000000000..cfe6de009 --- /dev/null +++ b/system/docshell/test/navigation/navigation_target_popup_url.html @@ -0,0 +1 @@ +<html><body>This is a popup</body></html> diff --git a/system/docshell/test/navigation/navigation_target_url.html b/system/docshell/test/navigation/navigation_target_url.html new file mode 100644 index 000000000..a485e8133 --- /dev/null +++ b/system/docshell/test/navigation/navigation_target_url.html @@ -0,0 +1 @@ +<html><body>This frame was navigated.</body></html> diff --git a/system/docshell/test/navigation/open.html b/system/docshell/test/navigation/open.html new file mode 100644 index 000000000..97eb9b76e --- /dev/null +++ b/system/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/system/docshell/test/navigation/parent.html b/system/docshell/test/navigation/parent.html new file mode 100644 index 000000000..74722b8bd --- /dev/null +++ b/system/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/system/docshell/test/navigation/test_bug13871.html b/system/docshell/test/navigation/test_bug13871.html new file mode 100644 index 000000000..e0b563a4a --- /dev/null +++ b/system/docshell/test/navigation/test_bug13871.html @@ -0,0 +1,81 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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> +function runTest() { + navigateByLocation(window0.frames[0]); + navigateByOpen("window1_child0"); + navigateByForm("window2_child0"); + navigateByHyperlink("window3_child0"); + + xpcWaitForFinishedFrames(function() { + 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(); + + xpcCleanupWindows(); + SimpleTest.finish(); + }, 4); +} + +// 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/system/docshell/test/navigation/test_bug270414.html b/system/docshell/test/navigation/test_bug270414.html new file mode 100644 index 000000000..98dcf42f8 --- /dev/null +++ b/system/docshell/test/navigation/test_bug270414.html @@ -0,0 +1,93 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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> +var headerHTML = "<html><head>" + + "<script src='/tests/SimpleTest/EventUtils.js'></scr" + "ipt>" + + "<script src='NavigationUtils.js'></scr" + "ipt>" + + "</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])</scr" + "ipt>"); + 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');</scr" + "ipt>"); + 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');</scr" + "ipt>"); + 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>navigateByHyperlink('child3');</scr" + "ipt>"); + window3.document.write(footerHTML); + window3.document.close(); + } +} + +xpcWaitForFinishedFrames(function() { + isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location."); + isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open."); + isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form."); + isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink."); + + window0.close(); + window1.close(); + window2.close(); + window3.close(); + + xpcCleanupWindows(); + SimpleTest.finish(); +}, 4); + +</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"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/navigation/test_bug278916.html b/system/docshell/test/navigation/test_bug278916.html new file mode 100644 index 000000000..3ad6a9666 --- /dev/null +++ b/system/docshell/test/navigation/test_bug278916.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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 = function () { + document.getElementById("link0").href = target_url; + sendMouseEvent({type:"click"}, "link0"); + + xpcWaitForFinishedFrames(function() { + var array_of_frames = xpcGetFramesByName("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(); + + xpcCleanupWindows(); + SimpleTest.finish(); + }, 1); +} +</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/system/docshell/test/navigation/test_bug279495.html b/system/docshell/test/navigation/test_bug279495.html new file mode 100644 index 000000000..79a169567 --- /dev/null +++ b/system/docshell/test/navigation/test_bug279495.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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 = function () { + document.getElementById("link0").href = target_url; + document.getElementById("link1").href = target_url; + + sendMouseEvent({type:"click"}, "link0"); + sendMouseEvent({type:"click"}, "link1"); + + xpcWaitForFinishedFrames(function() { + countAndClose("window0", 1); + countAndClose("window1", 1); + + xpcCleanupWindows(); + SimpleTest.finish(); + }, 2); +} + +function countAndClose(name, expected_count) { + var array_of_frames = xpcGetFramesByName(name); + is(array_of_frames.length, expected_count, + "Should only open " + expected_count + + " window(s) with name " + name + " using a fancy hyperlink."); + + for (var i=0; i < array_of_frames.length; ++i) + array_of_frames[i].close(); +} +</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/system/docshell/test/navigation/test_bug344861.html b/system/docshell/test/navigation/test_bug344861.html new file mode 100644 index 000000000..f9759751c --- /dev/null +++ b/system/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 type="text/javascript" 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/system/docshell/test/navigation/test_bug386782.html b/system/docshell/test/navigation/test_bug386782.html new file mode 100644 index 000000000..2434963f1 --- /dev/null +++ b/system/docshell/test/navigation/test_bug386782.html @@ -0,0 +1,137 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=386782 +--> +<head> + <title>Test for Bug 386782</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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 pageShowChecker = '<scr' + 'ipt>' + + 'window.addEventListener("pageshow", function(event) {' + + 'window.opener.postMessage({persisted:event.persisted}, "*");' + + '});</scr' + 'ipt>'; + + var gTests = [ + { + // <html><body><p>designModeDocument</p></body></html> + url: "data:text/html;charset=utf-8,<html><head>" + pageShowChecker + "</head><body><p>designModeDocument</p></body></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: "data:text/html;charset=utf-8,<html><head>" + pageShowChecker + "</head><body contentEditable=\"true\"><p>contentEditable</p></body></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 = 'data:text/html;charset=utf-8,SomeOtherDocument'; + SimpleTest.waitForFocus(goBack, gTest.window); + } + + 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/system/docshell/test/navigation/test_bug430624.html b/system/docshell/test/navigation/test_bug430624.html new file mode 100644 index 000000000..9fc92e4cd --- /dev/null +++ b/system/docshell/test/navigation/test_bug430624.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=430624 +--> +<head> + <title>Test for Bug 430624</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" 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; + window.frames[0].location = window.frames[0].location; +} + +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()" src="data:text/html;charset=utf-8,<body contenteditable>contentEditable</body>"></iframe> + +</body> +</html> + diff --git a/system/docshell/test/navigation/test_bug430723.html b/system/docshell/test/navigation/test_bug430723.html new file mode 100644 index 000000000..eb53e0d22 --- /dev/null +++ b/system/docshell/test/navigation/test_bug430723.html @@ -0,0 +1,138 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=430723 +--> +<head> + <title>Test for Bug 430723</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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 gTallRedBoxURI = "data:text/html;charset=utf-8;base64,PGh0bWw%2BPGhlYWQ%2BPHNjcmlwdD53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncGFnZXNob3cnLCBmdW5jdGlvbigpe29wZW5lci5uZXh0VGVzdCgpO30sIGZhbHNlKTs8L3NjcmlwdD48L2hlYWQ%2BPGJvZHk%2BPGRpdiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7IGxlZnQ6MHB4OyB0b3A6MHB4OyB3aWR0aDo1MCU7IGhlaWdodDoxNTAlOyBiYWNrZ3JvdW5kLWNvbG9yOnJlZCI%2BPHA%2BVGhpcyBpcyBhIHZlcnkgdGFsbCByZWQgYm94LjwvcD48L2Rpdj48L2JvZHk%2BPC9odG1sPg%3D%3D"; +// <html><head> +// < script > window.addEventListener("pageshow", function(){opener.nextTest();}, false); < /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> + +var gTallBlueBoxURI = "data:text/html;charset=utf-8;base64,PGh0bWw%2BPGhlYWQ%2BPHNjcmlwdD53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncGFnZXNob3cnLCBmdW5jdGlvbigpe29wZW5lci5uZXh0VGVzdCgpO30sIGZhbHNlKTs8L3NjcmlwdD48L2hlYWQ%2BPGJvZHk%2BPGRpdiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7IGxlZnQ6MHB4OyB0b3A6MHB4OyB3aWR0aDo1MCU7IGhlaWdodDoxNTAlOyBiYWNrZ3JvdW5kLWNvbG9yOmJsdWUiPjxwPlRoaXMgaXMgYSB2ZXJ5IHRhbGwgYmx1ZSBib3guPC9wPjwvZGl2PjwvYm9keT48L2h0bWw%2B"; +// <html><head> +// < script > window.addEventListener("pageshow", function(){opener.nextTest();}, false); < /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> + +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 () { + testWindow.removeEventListener("scroll", arguments.callee, true); + isnot(testWindow.document.body.scrollTop, 0, + "Page1: Ensure we can scroll down."); + SimpleTest.executeSoon(step1_2); + }, true); + sendKey('DOWN', testWindow); + + function step1_2() { + testWindow.addEventListener("scroll", function () { + testWindow.removeEventListener("scroll", arguments.callee, true); + 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; + }, 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 count = 0; + testWindow.addEventListener("scroll", function () { + if (++count < 2) { + SimpleTest.executeSoon(function () { sendKey('DOWN', testWindow); }); + } else { + testWindow.removeEventListener("scroll", arguments.callee, true); + + isnot(testWindow.document.body.scrollTop, 0, + "Page2: Ensure we could scroll."); + + // Navigate backwards. This should fire step3. + testWindow.history.back(); + } + }, 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 () { + testWindow.removeEventListener("scroll", arguments.callee, true); + + isnot(testWindow.document.body.scrollTop, 0, + "Page2Again: Ensure we can still scroll."); + + testWindow.close(); + window.SimpleTest.finish(); + }, true); + sendKey('DOWN', testWindow); +} + +SimpleTest.waitForExplicitFinish(); + +//]]> +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/navigation/test_child.html b/system/docshell/test/navigation/test_child.html new file mode 100644 index 000000000..c43e1a6cf --- /dev/null +++ b/system/docshell/test/navigation/test_child.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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 = function() { + navigateByLocation(frames[0]); + navigateByOpen("child1"); + navigateByForm("child2"); + navigateByHyperlink("child3"); + + xpcWaitForFinishedFrames(function() { + isNavigated(frames[0], "Should be able to navigate off-domain child by setting location."); + isNavigated(frames[1], "Should be able to navigate off-domain child by calling window.open."); + isNavigated(frames[2], "Should be able to navigate off-domain child by submitting form."); + isNavigated(frames[3], "Should be able to navigate off-domain child by targeted hyperlink."); + + xpcCleanupWindows(); + SimpleTest.finish(); + }, 4); +} +</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/system/docshell/test/navigation/test_contentpolicy_block_window.html b/system/docshell/test/navigation/test_contentpolicy_block_window.html new file mode 100644 index 000000000..651be825c --- /dev/null +++ b/system/docshell/test/navigation/test_contentpolicy_block_window.html @@ -0,0 +1,96 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1329288 +--> +<head> + <title>Test for Bug 1329288</title> + <script type="text/javascript" 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. + */ + +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 + QueryInterface: function(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: function(outer, iid) { + return this.QueryInterface(iid); + }, + + // nsIContentPolicy implementation + shouldLoad: function(contentType, contentLocation, requestOrigin, context, mimeTypeGuess, extra) { + + 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: function(contentType, contentLocation, requestOrigin, context, mimeTypeGuess, extra) { + 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/system/docshell/test/navigation/test_grandchild.html b/system/docshell/test/navigation/test_grandchild.html new file mode 100644 index 000000000..439145b3e --- /dev/null +++ b/system/docshell/test/navigation/test_grandchild.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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 = function () { + navigateByLocation(frames[0].frames[0]); + navigateByOpen("child1_child0"); + navigateByForm("child2_child0"); + navigateByHyperlink("child3_child0"); + + xpcWaitForFinishedFrames(function() { + isNavigated(frames[0].frames[0], "Should be able to navigate off-domain grandchild by setting location."); + isNavigated(frames[1].frames[0], "Should be able to navigate off-domain grandchild by calling window.open."); + isNavigated(frames[2].frames[0], "Should be able to navigate off-domain grandchild by submitting form."); + isNavigated(frames[3].frames[0], "Should be able to navigate off-domain grandchild by targeted hyperlink."); + + xpcCleanupWindows(); + SimpleTest.finish(); + }, 4); +} +</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/system/docshell/test/navigation/test_not-opener.html b/system/docshell/test/navigation/test_not-opener.html new file mode 100644 index 000000000..d778f71d9 --- /dev/null +++ b/system/docshell/test/navigation/test_not-opener.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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 = function () { + //navigateByLocation(window0); // Don't have a handle to the window. + navigateByOpen("window1"); + navigateByForm("window2"); + navigateByHyperlink("window3"); + + xpcWaitForFinishedFrames(function() { + is(xpcGetFramesByName("window1").length, 2, "Should not be able to navigate popup's popup by calling window.open."); + is(xpcGetFramesByName("window2").length, 2, "Should not be able to navigate popup's popup by submitting form."); + is(xpcGetFramesByName("window3").length, 2, "Should not be able to navigate popup's popup by targeted hyperlink."); + + //opener0.close(); + opener1.close(); + opener2.close(); + opener3.close(); + + xpcCleanupWindows(); + SimpleTest.finish(); + }, 6); +} + +//opener0 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window0", "_blank", "width=10,height=10"); +opener1 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window1", "_blank", "width=10,height=10"); +opener2 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window2", "_blank", "width=10,height=10"); +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/system/docshell/test/navigation/test_opener.html b/system/docshell/test/navigation/test_opener.html new file mode 100644 index 000000000..bfb1dde9f --- /dev/null +++ b/system/docshell/test/navigation/test_opener.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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 = function () { + navigateByLocation(window0); + navigateByOpen("window1"); + navigateByForm("window2"); + navigateByHyperlink("window3"); + + xpcWaitForFinishedFrames(function() { + isNavigated(window0, "Should be able to navigate popup by setting location."); + isNavigated(window1, "Should be able to navigate popup by calling window.open."); + isNavigated(window2, "Should be able to navigate popup by submitting form."); + isNavigated(window3, "Should be able to navigate popup by targeted hyperlink."); + + window0.close(); + window1.close(); + window2.close(); + window3.close(); + + xpcCleanupWindows(); + SimpleTest.finish(); + }, 4); +} + +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/system/docshell/test/navigation/test_popup-navigates-children.html b/system/docshell/test/navigation/test_popup-navigates-children.html new file mode 100644 index 000000000..692f35713 --- /dev/null +++ b/system/docshell/test/navigation/test_popup-navigates-children.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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> +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"); +} + +xpcWaitForFinishedFrames(function() { + isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location."); + isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open."); + isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form."); + isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink."); + + window0.close(); + window1.close(); + window2.close(); + window3.close(); + + xpcCleanupWindows(); + SimpleTest.finish(); +}, 4); + +</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/system/docshell/test/navigation/test_reserved.html b/system/docshell/test/navigation/test_reserved.html new file mode 100644 index 000000000..b2389078c --- /dev/null +++ b/system/docshell/test/navigation/test_reserved.html @@ -0,0 +1,100 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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); +} + +function testTop() { + window0 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#top,location", "_blank", "width=10,height=10"); + + xpcWaitForFinishedFrames(function() { + isInaccessible(window0, "Should be able to navigate off-domain top by setting location."); + window0.close(); + xpcCleanupWindows(); + + window1 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_top,open", "_blank", "width=10,height=10"); + + xpcWaitForFinishedFrames(function() { + isInaccessible(window1, "Should be able to navigate off-domain top by calling window.open."); + window1.close(); + xpcCleanupWindows(); + + window2 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_top,form", "_blank", "width=10,height=10"); + + xpcWaitForFinishedFrames(function() { + isInaccessible(window2, "Should be able to navigate off-domain top by submitting form."); + window2.close(); + xpcCleanupWindows(); + + window3 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_top,hyperlink", "_blank", "width=10,height=10"); + + xpcWaitForFinishedFrames(function() { + isInaccessible(window3, "Should be able to navigate off-domain top by targeted hyperlink."); + window3.close(); + xpcCleanupWindows(); + + testParent(); + }, 1); + }, 1); + }, 1); + }, 1); +} + +function testParent() { + document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#parent,location"></iframe>'; + + xpcWaitForFinishedFrames(function() { + isAccessible(frames[0], "Should not be able to navigate off-domain parent by setting location."); + xpcCleanupWindows(); + + document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_parent,open"></iframe>'; + + xpcWaitForFinishedFrames(function() { + isAccessible(frames[0], "Should not be able to navigate off-domain parent by calling window.open."); + xpcCleanupWindows(); + + document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_parent,form"></iframe>'; + + xpcWaitForFinishedFrames(function() { + isAccessible(frames[0], "Should not be able to navigate off-domain parent by submitting form."); + xpcCleanupWindows(); + + document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_parent,hyperlink"></iframe>'; + + xpcWaitForFinishedFrames(function() { + isAccessible(frames[0], "Should not be able to navigate off-domain parent by targeted hyperlink."); + xpcCleanupWindows(); + + document.getElementById("frames").innerHTML = ""; + SimpleTest.finish(); + }, 1); + }, 1); + }, 1); + }, 1); +} + +window.onload = function() { + 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/system/docshell/test/navigation/test_sessionhistory.html b/system/docshell/test/navigation/test_sessionhistory.html new file mode 100644 index 000000000..e5978acfa --- /dev/null +++ b/system/docshell/test/navigation/test_sessionhistory.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <title>Test for Bug </title> + <script type="application/javascript" 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=">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug **/ + +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 + "file_bug508537_1.html", // Dynamic frames and forward-back + "file_document_write_1.html", // Session history + document.write + //"file_static_and_dynamic_1.html",// Static and dynamic frames and forward-back + "file_bug534178.html", // Session history transaction clean-up. + "file_fragment_handling_during_load.html", + "file_nested_frames.html", + "file_shiftReload_and_pushState.html", + "file_scrollRestoration.html", + "file_bug1300461.html", + "file_bug1379762-1.html", + ]; +var testCount = 0; // Used by the test files. + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); + +var testWindow; +function nextTest_() { + if (testFiles.length) { + testCount = 0; + testWindow = window.open(testFiles.shift(), "", "width=300,height=300"); + testWindow.onunload = function () { } // to prevent bfcache + } else { + SimpleTest.finish(); + } +} + +function nextTest() { + setTimeout(nextTest_, 0); +} + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/navigation/test_sibling-matching-parent.html b/system/docshell/test/navigation/test_sibling-matching-parent.html new file mode 100644 index 000000000..dc8ec2f90 --- /dev/null +++ b/system/docshell/test/navigation/test_sibling-matching-parent.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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 = 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>'; + + xpcWaitForFinishedFrames(function() { + isNavigated(frames[0], "Should be able to navigate sibling with on-domain parent by setting location."); + isNavigated(frames[1], "Should be able to navigate sibling with on-domain parent by calling window.open."); + isNavigated(frames[2], "Should be able to navigate sibling with on-domain parent by submitting form."); + isNavigated(frames[3], "Should be able to navigate sibling with on-domain parent by targeted hyperlink."); + + xpcCleanupWindows(); + SimpleTest.finish(); + }, 4); +} +</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/system/docshell/test/navigation/test_sibling-off-domain.html b/system/docshell/test/navigation/test_sibling-off-domain.html new file mode 100644 index 000000000..ba7942798 --- /dev/null +++ b/system/docshell/test/navigation/test_sibling-off-domain.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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 = 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>'; + + xpcWaitForFinishedFrames(function() { + 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."); + + xpcCleanupWindows(); + SimpleTest.finish(); + }, 4); +} +</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/system/docshell/test/navigation/test_triggeringprincipal_frame_nav.html b/system/docshell/test/navigation/test_triggeringprincipal_frame_nav.html new file mode 100644 index 000000000..f8f97c678 --- /dev/null +++ b/system/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 type="text/javascript" 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, false); + +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, false); + 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/system/docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html b/system/docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html new file mode 100644 index 000000000..cd6a9c056 --- /dev/null +++ b/system/docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html @@ -0,0 +1,87 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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, false); + + var channel = SpecialPowers.wrap(frameA.contentDocument).docShell.currentDocumentChannel; + var triggeringPrincipal = channel.loadInfo.triggeringPrincipal.URI.asciiSpec; + var loadingPrincipal = channel.loadInfo.loadingPrincipal.URI.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, LOADING_PRINCIPAL_URI, + "LoadingPrincipal for targeted window.open() should be the containing document"); + + SimpleTest.finish(); +} + +function performNavigation() { + frameA.removeEventListener('load', performNavigation, false); + frameA.addEventListener('load', checkResults, false); + + // 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, false); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html b/system/docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html new file mode 100644 index 000000000..7cc6ee97d --- /dev/null +++ b/system/docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html @@ -0,0 +1,70 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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, false); + + var channel = SpecialPowers.wrap(testframe.contentDocument).docShell.currentDocumentChannel; + var triggeringPrincipal = channel.loadInfo.triggeringPrincipal.URI.asciiSpec; + var loadingPrincipal = channel.loadInfo.loadingPrincipal.URI.asciiSpec; + + is(triggeringPrincipal, TRIGGERING_PRINCIPAL_URI, + "TriggeringPrincipal for targeted window.open() should be the principal of the document"); + + is(testframe.contentDocument.referrer, 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, false); + testframe.addEventListener('load', checkResults, false); + win = window.open("file_triggeringprincipal_parent_iframe_window_open_nav.html", "testframe"); +} + +// start the test +SimpleTest.waitForExplicitFinish(); + +testframe.addEventListener('load', performNavigation, false); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/navigation/test_triggeringprincipal_window_open.html b/system/docshell/test/navigation/test_triggeringprincipal_window_open.html new file mode 100644 index 000000000..dbee21777 --- /dev/null +++ b/system/docshell/test/navigation/test_triggeringprincipal_window_open.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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.document).docShell.currentDocumentChannel; + var httpTriggeringPrincipal = httpChannel.loadInfo.triggeringPrincipal.URI.asciiSpec; + var httpLoadingPrincipal = httpChannel.loadInfo.loadingPrincipal; + + is(httpTriggeringPrincipal, TRIGGERING_PRINCIPAL_URI, + "TriggeringPrincipal for window.open(http:) should be the principal of the document"); + + is(httpWin.document.referrer, 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.document).docShell.currentDocumentChannel; + var jsTriggeringPrincipal = jsChannel.loadInfo.triggeringPrincipal.URI.asciiSpec; + var jsLoadingPrincipal = jsChannel.loadInfo.loadingPrincipal; + + is(jsTriggeringPrincipal, 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> diff --git a/system/docshell/test/test_anchor_scroll_after_document_open.html b/system/docshell/test/test_anchor_scroll_after_document_open.html new file mode 100644 index 000000000..93fa4615b --- /dev/null +++ b/system/docshell/test/test_anchor_scroll_after_document_open.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=881487 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 881487</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 881487 **/ + SimpleTest.waitForExplicitFinish(); + // Child needs to invoke us, otherwise our onload will fire before the child + // has done the write/close bit. + var gotOnload = false; + addLoadEvent(function() { + gotOnload = true; + }); + onmessage = function handleMessage(msg) { + if (msg.data == "doTest") { + if (!gotOnload) { + addLoadEvent(function() { handleMessage(msg); }); + return; + } + frames[0].onscroll = function() { + ok(true, "Got a scroll event"); + SimpleTest.finish(); + } + frames[0].location.hash = "#target"; + return; + } + if (msg.data == "haveHash") { + ok(false, "Child got reloaded"); + } else { + ok(false, "Unexpected message"); + } + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=881487">Mozilla Bug 881487</a> +<p id="display"> + <!-- iframe goes here so it can scroll --> +<iframe src="file_anchor_scroll_after_document_open.html"></iframe> +</p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bfcache_plus_hash.html b/system/docshell/test/test_bfcache_plus_hash.html new file mode 100644 index 000000000..30c0b6b50 --- /dev/null +++ b/system/docshell/test/test_bfcache_plus_hash.html @@ -0,0 +1,120 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=646641 +--> +<head> + <title>Test for Bug 646641</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.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=646641">Mozilla Bug 646641</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript;version=1.7"> + +/** Test for Bug 646641 **/ + +/* + * In a popup (because navigating the main frame confuses Mochitest), do the + * following: + * + * * Call history.pushState(). + * * Navigate to a new page. + * * Go back two history entries. + * + * Check that we go back, we retrieve the document from bfcache. + */ + +SimpleTest.waitForExplicitFinish(); + +function debug(msg) { + // Wrap dump so we can turn debug messages on and off easily. + dump(msg + '\n'); +} + +var expectedLoadNum = -1; +function childLoad(n) { + if (n == expectedLoadNum) { + debug('Got load ' + n); + expectedLoadNum = -1; + + // Spin the event loop before calling gGen.next() so the generator runs + // outside the onload handler. This prevents us from encountering all + // sorts of docshell quirks. + // + // (I don't know why I need to wrap gGen.next() in a function, but it + // throws an error otherwise.) + setTimeout(function() { gGen.next() }, 0); + } + else { + debug('Got unexpected load ' + n); + ok(false, 'Got unexpected load ' + n); + } +} + +var expectedPageshowNum = -1; +function childPageshow(n) { + if (n == expectedPageshowNum) { + debug('Got expected pageshow ' + n); + expectedPageshowNum = -1; + ok(true, 'Got expected pageshow ' + n); + setTimeout(function() { gGen.next() }, 0); + } + else { + debug('Got pageshow ' + n); + } + + // Since a pageshow comes along with an onload, don't fail the test if we get + // an unexpected pageshow. +} + +function waitForLoad(n) { + debug('Waiting for load ' + n); + expectedLoadNum = n; +} + +function waitForShow(n) { + debug('Waiting for show ' + n); + expectedPageshowNum = n; +} + +function test() { + var popup = window.open('data:text/html,' + + '<html><body onload="opener.childLoad(1)" ' + + 'onpageshow="opener.childPageshow(1)">' + + 'Popup 1' + + '</body></html>'); + waitForLoad(1); + yield undefined; + + popup.history.pushState('', '', ''); + + popup.location = 'data:text/html,<html><body onload="opener.childLoad(2)">Popup 2</body></html>'; + waitForLoad(2); + yield undefined; + + // Now go back 2. The first page should be retrieved from bfcache. + popup.history.go(-2); + waitForShow(1); + yield undefined; + + popup.close(); + SimpleTest.finish(); + + // Yield once more so we don't throw a StopIteration exception. + yield undefined; +} + +var gGen = test(); +gGen.next(); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug1045096.html b/system/docshell/test/test_bug1045096.html new file mode 100644 index 000000000..8a0b4a223 --- /dev/null +++ b/system/docshell/test/test_bug1045096.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1045096 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1045096</title> + <script type="application/javascript" 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=1045096">Mozilla Bug 1045096</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> + <script type="application/javascript"> + + /** Test for Bug 1045096 **/ + var i = document.createElement('iframe'); + i.src = "javascript:false"; // This is required! + $("content").appendChild(i); + ok(i.contentWindow.performance, "Should have a performance object"); + </script> +</body> +</html> diff --git a/system/docshell/test/test_bug1121701.html b/system/docshell/test/test_bug1121701.html new file mode 100644 index 000000000..8beb2d8d0 --- /dev/null +++ b/system/docshell/test/test_bug1121701.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1121701 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1121701</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 1121701 **/ + + var testUrl1 = "data:text/html,<script>window.onpageshow = function(e) { opener.child1PageShow(e); } <" + "/script>"; + var testUrl2 = "data:text/html,<script>window.onpageshow = function(e) { opener.child2PageShow(e); } <" + "/script>"; + var testWin; + + var page1LoadCount = 0; + function child1PageShow(e) { + ++page1LoadCount; + if (page1LoadCount == 1) { + SimpleTest.executeSoon(function() { + is(e.persisted, false, "Initial page load shouldn't be persisted."); + testWin.document.body.innerHTML = "modified"; + testWin.onpagehide = function(e) { + testWin.onpagehide = null; + ok(e.persisted, "test page 1 should have been persisted"); + is(testWin.document.body.innerHTML, "modified"); + } + testWin.location.href = testUrl2; + }); + } else if (page1LoadCount == 2) { + is(e.persisted, true, "Page load from bfcache should be persisted."); + is(testWin.document.body.innerHTML, "modified"); + testWin.close(); + SimpleTest.finish(); + } + } + + function child2PageShow(e) { + testWin.document.body.innerHTML = "<img>"; + SimpleTest.executeSoon(function() { + testWin.onmessage = function() { + ok(true, "Got message"); + testWin.document.body.firstChild.src = location.href; + } + testWin.onbeforeunload = function() { + testWin.postMessage("foo", "*"); + } + testWin.history.back(); + }); + } + + SimpleTest.waitForExplicitFinish(); + addLoadEvent(function() { + testWin = window.open(testUrl1); + }); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1121701">Mozilla Bug 1121701</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug1151421.html b/system/docshell/test/test_bug1151421.html new file mode 100644 index 000000000..76e34d502 --- /dev/null +++ b/system/docshell/test/test_bug1151421.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1151421 +--> +<head> + <title>Test for Bug 1151421</title> + <script type="application/javascript" 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=1151421">Mozilla Bug 1151421</a> + +<script type="application/javascript"> + +/** Test for Bug 1151421 **/ +SimpleTest.waitForExplicitFinish(); + +function childLoad() { + // Spin the event loop so we leave the onload handler. + SimpleTest.executeSoon(childLoad2); +} + +function childLoad2() { + let cw = iframe.contentWindow; + let content = cw.document.getElementById("content"); + + // Create a function to calculate an invariant. + let topPlusOffset = function() + { + return Math.round(content.getBoundingClientRect().top + cw.pageYOffset); + } + + let initialTPO = topPlusOffset(); + + // Scroll the iframe to various positions, and check the TPO. + // Scrolling down to the bottom will adjust the page offset by a fractional amount. + let positions = [-100, 0.17, 0, 1.5, 10.41, 1e6, 12.1]; + + // Run some tests with scrollTo() and ensure we have the same invariant after scrolling. + positions.forEach(function(pos) { + cw.scrollTo(0, pos); + is(topPlusOffset(), initialTPO, "Top plus offset should remain invariant across scrolling."); + }); + + positions.reverse().forEach(function(pos) { + cw.scrollTo(0, pos); + is(topPlusOffset(), initialTPO, "(reverse) Top plus offset should remain invariant across scrolling."); + }); + + SimpleTest.finish(); +} + +</script> + +<!-- When the iframe loads, it calls childLoad(). --> +<br> +<iframe height='100px' id='iframe' src='file_bug1151421.html'></iframe> + +</body> +</html> diff --git a/system/docshell/test/test_bug1186774.html b/system/docshell/test/test_bug1186774.html new file mode 100644 index 000000000..623e7996b --- /dev/null +++ b/system/docshell/test/test_bug1186774.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1186774 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1186774</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 1186774 **/ + +var child; + +function runTest() { + child = window.open("data:text/html,<div style='height: 9000px;'></div>", "", "width=100,height=100"); + child.onload = function() { + setTimeout(function() { + child.scrollTo(0, 0); + child.history.pushState({}, "initial"); + child.scrollTo(0, 3000); + child.history.pushState({}, "scrolled"); + child.scrollTo(0, 6000); + child.history.back(); + }); + } + + child.onpopstate = function() { + is(Math.round(child.scrollY), 6000, "Shouldn't have scrolled before popstate"); + child.close(); + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1186774">Mozilla Bug 1186774</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug123696.html b/system/docshell/test/test_bug123696.html new file mode 100644 index 000000000..11d14e807 --- /dev/null +++ b/system/docshell/test/test_bug123696.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=123696 +--> +<head> + <title>Test for Bug 123696</title> + <script type="application/javascript" 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=123696">Mozilla Bug 123696</a> +<p id="display"> + <iframe src="bug123696-subframe.html"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 123696 **/ +SimpleTest.waitForExplicitFinish(); + +function finishTest() { + is(window.frames[0].frames[0].document.documentElement.textContent, + "change2", "Reload should have reloaded correctly!"); + SimpleTest.finish(); +} + +function doReload() { + window.frames[0].frameElement.onload = finishTest; + window.frames[0].location.reload(); +} + +addLoadEvent(function() { + window.frames[0].frames[0].frameElement.onload = doReload; + window.frames[0].frames[0].frameElement.src = "javascript:parent.change2()"; +}); + + + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug369814.html b/system/docshell/test/test_bug369814.html new file mode 100644 index 000000000..866771055 --- /dev/null +++ b/system/docshell/test/test_bug369814.html @@ -0,0 +1,211 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=369814 +--> +<head> + <title>Test for Bug 369814</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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=384014">Mozilla Bug 369814</a> + +<p> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Tests for Bug 369814 **/ + +SimpleTest.waitForExplicitFinish(); + +// Because child scripts won't be able to run to tell us they're done, +// we need to just wait for them. Wait this many event loop spins before +// checking the results. +const gLoadEventLoopCount = 100; + +var gCurrentTest; +var gTargetWindow; +var gNumPokes; +var gTestFrame; + +/** + * Called by documents loaded from jar files to indicate that they can access + * this document. + */ +function poke(description) { + ok(false, gCurrentTest['name'] + ": got unexpected poke: " + description); + gNumPokes++; +} + +function loadEvent(window, callback) +{ + var fn = function() { + window.removeEventListener("load", fn, false); + callback(); + }; + window.addEventListener("load", fn, false); +} + +function loadTestTarget(callback) +{ + gTargetWindow = window.open("http://mochi.test:8888", "bug369814target"); + loadEvent(gTargetWindow, callback); +} + +function closeTestTarget() +{ + gTargetWindow.close(); + gTargetWindow = null; +} + +function loadErrorTest(test) +{ + // Give the frame a chance to fail at loading. + // How do detect failure to load? Error pages don't fire load + // events. But we can load another page before the error page and + // then use its unload handler to know when the error page is just + // about loaded; at that point a single trip through the event loop + // should do the trick. + loadEvent(gTestFrame, function() { + gTestFrame.src = test['url']; + }); + gTestFrame.unloading = function() { + gTestFrame.unloading = null; + // Go out to the event loop once so that unload processing finishes and + // the new document is set up. + setTimeout(function() { + // XXX: There doesn't seem to be a reliable check for "got an error," + // but reaching in to an error document will throw an exception + var errorPage; + try { + var item = gTestFrame.contentDocument.getElementById(gCurrentTest['data-iframe']); + errorPage = false; + } catch (e) { + errorPage = true; + } + ok(errorPage, gCurrentTest["name"] + ": should block a suspicious JAR load."); + + finishTest(); + }, 0); + } + var unloadDetector = "data:text/html,<script>window.onunload = function() { frameElement.unloading(); }</" + "script>"; + gTestFrame.src = unloadDetector; +} + +function iframeTest(test) { + gTestFrame.src = test['url']; + loadEvent(gTestFrame, function() { + finishTest(); + }); +} + + +function hitEventLoop(func, times) { + if (times > 0) { + SimpleTest.executeSoon(function() { hitEventLoop(func, times-1); }); + } else { + SimpleTest.executeSoon(func); + } +} + +function refreshTest(test) { + gTestFrame.src = test['url']; + loadEvent(gTestFrame, function() { + // Wait for the frame to try and refresh + // XXX: a "blocked redirect" signal would be needed to get rid of + // this timeout. + hitEventLoop(function() { + finishTest(); + }, gLoadEventLoopCount); + }); +} + +function anchorTest(test) { + loadTestTarget(function() { + gTestFrame.src = test['url']; + loadEvent(gTestFrame, function() { + sendMouseEvent({type:'click'}, 'target', gTestFrame.contentWindow); + sendMouseEvent({type:'click'}, 'notarget', gTestFrame.contentWindow); + + // Give the clicks a chance to load + hitEventLoop(function() { + closeTestTarget(); + finishTest(); + }, gLoadEventLoopCount); + }); + }); +} + +var gTests = [ + { "name" : "iframes.html loaded from non-jar type, pref disabled", + "url" : "jar:http://mochi.test:8888/tests/docshell/test/bug369814.zip!/iframes.html", + "pref" : false, + "pokes" : { }, + "func" : loadErrorTest, + }, + { "name" : "refresh.html loaded from non-jar type, pref enabled", + "url" : "jar:http://mochi.test:8888/tests/docshell/test/bug369814.zip!/refresh.html", + "pref" : true, + "pokes" : { }, + "func" : refreshTest, + }, + { "name" : "iframes.html loaded from non-jar type, pref enabled", + "url" : "jar:http://mochi.test:8888/tests/docshell/test/bug369814.zip!/iframes.html", + "pref" : true, + "pokes" : { }, + "func" : iframeTest, + }, + { "name" : "anchors.html loaded from non-jar type, pref enabled", + "url" : "jar:http://mochi.test:8888/tests/docshell/test/bug369814.zip!/anchors.html", + "pref" : true, + "pokes" : { }, + "func" : anchorTest, + }, +]; + +var gNextTest = 0; + +function runNextTest() +{ + if (gNextTest < gTests.length) { + gCurrentTest = gTests[gNextTest++]; + gNumPokes = 0; + + SpecialPowers.pushPrefEnv({"set": [["network.jar.block-remote-files", false], + ["network.jar.open-unsafe-types", gCurrentTest['pref']]]}, function() { + + // Create a new frame each time, so our restictions on loads in a + // jar:-loaded iframe don't interfere with the test. + if (gTestFrame) { + document.body.removeChild(gTestFrame); + } + gTestFrame = document.createElement("iframe"); + document.body.insertBefore(gTestFrame, $("test")); + + gCurrentTest['func'](gCurrentTest); + }); + } else { + SimpleTest.finish(); + } +} + +function finishTest() +{ + SpecialPowers.pushPrefEnv({"set": [["network.jar.open-unsafe-types", false]]}, function() { + if (gNumPokes == 0) { + ok(true, gCurrentTest["name"] + ": no unexpected pokes"); + } + + runNextTest(); + }); +} + +addLoadEvent(runNextTest); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug384014.html b/system/docshell/test/test_bug384014.html new file mode 100644 index 000000000..1f115a6ec --- /dev/null +++ b/system/docshell/test/test_bug384014.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=384014 +--> +<head> + <title>Test for Bug 384014</title> + <script type="text/javascript" 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=384014">Mozilla Bug 384014</a> +<p id="display"> +<iframe id="f" src="javascript:try { window.x = 'PASS'; s = 'PASS' } catch(e) { s = 'FAIL' } s;"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 384014 **/ +SimpleTest.waitForExplicitFinish(); + +function runTest() { + $("f").onload = function () { + is($("f").contentDocument.documentElement.textContent, "PASS", + "We fail"); + SimpleTest.finish(); + } + + $("f").contentWindow.location.reload(); +} + +addLoadEvent(runTest); + +</script> +</pre> +</body> +</html> + diff --git a/system/docshell/test/test_bug385434.html b/system/docshell/test/test_bug385434.html new file mode 100644 index 000000000..660f522e8 --- /dev/null +++ b/system/docshell/test/test_bug385434.html @@ -0,0 +1,209 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=385434 +--> +<head> + <title>Test for Bug 385434</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" 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=385434">Mozilla Bug 385434</a> +<p id="display"></p> +<div id="content"> + <iframe id="frame" style="height:100px; width:100px; border:0"></iframe> + <div id="status" style="display: none"></div> +</div> +<pre id="test"> +<script type="application/javascript;version=1.7"> + +/** Test for Bug 385434 **/ +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); + +var gNumHashchanges = 0; +var gCallbackOnIframeLoad = false; + +function statusMsg(msg) { + var msgElem = document.createElement("p"); + msgElem.appendChild(document.createTextNode(msg)); + + document.getElementById("status").appendChild(msgElem); +} + +function longWait() { + setTimeout(function() { gGen.next() }, 1000); +} + +// onIframeHashchange, onIframeLoad, and onIframeScroll are all called by the +// content we load into our iframe in order to notify the parent frame of an +// event which was fired. +function onIframeHashchange() { + gNumHashchanges++; + gGen.next(); +} + +function onIframeLoad() { + if (gCallbackOnIframeLoad) { + gCallbackOnIframeLoad = false; + gGen.next(); + } +} + +function onIframeScroll() { + is(gNumHashchanges, 0, "onscroll should fire before onhashchange."); +} + +function enableIframeLoadCallback() { + gCallbackOnIframeLoad = true; +} + +function noEventExpected(msg) { + is(gNumHashchanges, 0, msg); + + // Even if there's an error, set gNumHashchanges to 0 so other tests don't + // fail. + gNumHashchanges = 0; +} + +function eventExpected(msg) { + is(gNumHashchanges, 1, msg); + + // Eat up this event, whether the test above was true or not + gNumHashchanges = 0; +} + +/* + * The hashchange event is dispatched asynchronously, so if we want to observe + * it, we have to yield within run_test(), transferring control back to the + * event loop. + * + * When we're expecting our iframe to observe a hashchange event after we poke + * it, we just yield and wait for onIframeHashchange() to call gGen.next() and + * wake us up. + * + * When we're testing to ensure that the iframe doesn't dispatch a hashchange + * event, we try to hook onto the iframe's load event. We call + * enableIframeLoadCallback(), which causes onIframeLoad() to call gGen.next() + * upon the next observed load. After we get our callback, we check that a + * hashchange didn't occur. + * + * We can't always just wait for page load in order to observe that a + * hashchange didn't happen. In these cases, we call longWait() and yield + * until either a hashchange occurs or longWait's callback is scheduled. This + * is something of a hack; it's entirely possible that longWait won't wait long + * enough, and we won't observe what should have been a failure of the test. + * But it shouldn't happen that good code will randomly *fail* this test. + */ +function run_test() { + /* + * TEST 1 tests that: + * <body onhashchange = ... > works, + * the event is (not) fired at the correct times + */ + var frame = document.getElementById("frame"); + var frameCw = frame.contentWindow; + + enableIframeLoadCallback(); + frameCw.document.location = "file_bug385434_1.html"; + // Wait for the iframe to load and for our callback to fire + yield undefined; + + noEventExpected("No hashchange expected initially."); + + sendMouseEvent({type: "click"}, "link1", frameCw); + yield undefined; + eventExpected("Clicking link1 should trigger a hashchange."); + + sendMouseEvent({type: "click"}, "link1", frameCw); + longWait(); + yield undefined; + // succeed if a hashchange event wasn't triggered while we were waiting + noEventExpected("Clicking link1 again should not trigger a hashchange."); + + sendMouseEvent({type: "click"}, "link2", frameCw); + yield undefined; + eventExpected("Clicking link2 should trigger a hashchange."); + + frameCw.history.go(-1); + yield undefined; + eventExpected("Going back should trigger a hashchange."); + + frameCw.history.go(1); + yield undefined; + eventExpected("Going forward should trigger a hashchange."); + + // window.location has a trailing '#' right now, so we append "link1", not + // "#link1". + frameCw.window.location = frameCw.window.location + "link1"; + yield undefined; + eventExpected("Assigning to window.location should trigger a hashchange."); + + // Set up history in the iframe which looks like: + // file_bug385434_1.html#link1 + // file_bug385434_2.html + // file_bug385434_1.html#foo <-- current page + enableIframeLoadCallback(); + frameCw.window.location = "file_bug385434_2.html"; + yield undefined; + + enableIframeLoadCallback(); + frameCw.window.location = "file_bug385434_1.html#foo"; + yield undefined; + + // Now when we do history.go(-2) on the frame, it *shouldn't* fire a + // hashchange. Although the URIs differ only by their hashes, they belong to + // two different Documents. + frameCw.history.go(-2); + longWait(); + yield undefined; + noEventExpected("Moving between different Documents shouldn't " + + "trigger a hashchange."); + + /* + * TEST 2 tests that: + * <frameset onhashchange = ... > works, + * the event is targeted at the window object + * the event's cancelable, bubbles settings are correct + */ + enableIframeLoadCallback(); + frameCw.document.location = "file_bug385434_2.html"; + yield undefined; + + frameCw.document.location = "file_bug385434_2.html#foo"; + yield undefined; + + eventExpected("frame onhashchange should fire events."); + // iframe should set gSampleEvent + is(gSampleEvent.target, frameCw, + "The hashchange event should be targeted to the window."); + is(gSampleEvent.type, "hashchange", + "Event type should be 'hashchange'."); + is(gSampleEvent.cancelable, false, + "The hashchange event shouldn't be cancelable."); + is(gSampleEvent.bubbles, true, + "The hashchange event should bubble."); + + /* + * TEST 3 tests that: + * hashchange is dispatched if the current document readyState is + * not "complete" (bug 504837). + */ + frameCw.document.location = "file_bug385434_3.html"; + yield undefined; + eventExpected("Hashchange should fire even if the document " + + "hasn't finished loading."); + + SimpleTest.finish(); + yield undefined; +} + +var gGen = run_test(); +gGen.next(); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug387979.html b/system/docshell/test/test_bug387979.html new file mode 100644 index 000000000..9e337e2c2 --- /dev/null +++ b/system/docshell/test/test_bug387979.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=387979 +--> +<head> + <title>Test for Bug 387979</title> + <script type="text/javascript" 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=387979">Mozilla Bug 387979</a> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 387979 **/ +function a(s) { + var r; + try { r = frames[0].document.body; } + catch (e) { r = e; } + is(r instanceof frames[0].HTMLBodyElement, true, + "Can't get body" + s); +} +var p = 0; +function b() { + switch (++p) { + case 1: + frames[0].location = "about:blank"; + break; + case 2: + a("before reload"); + frames[0].location.reload(); + break; + case 3: + a("after reload"); + SimpleTest.finish(); + break; + } +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +<p id="display"> + <iframe onload="b()"></iframe> + <pre id="p">-</pre> +</p> +</body> +</html> + diff --git a/system/docshell/test/test_bug402210.html b/system/docshell/test/test_bug402210.html new file mode 100644 index 000000000..78fa025e0 --- /dev/null +++ b/system/docshell/test/test_bug402210.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<!-- +While working on bug 402210, it came up that the code was doing + +a.href = proto + host + +which technically produces "https:host" instead of "https://host" and +that the code was relying on href's setting having fixup behaviour +for this kind of thing. + +If we rely on it, we might as well test for it, even if it isn't the +problem 402210 was meant to fix. + +https://bugzilla.mozilla.org/show_bug.cgi?id=402210 +--> +<head> + <title>Test for Bug 402210</title> + <script type="text/javascript" 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=402210">Mozilla Bug 402210</a> +<p id="display"> + <a id="testlink">Test Link</a> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function runTest() { + $("testlink").href = "https:example.com"; + is($("testlink").href, "https://example.com/", "Setting href on an anchor tag should fixup missing slashes after https protocol"); + + $("testlink").href = "ftp:example.com"; + is($("testlink").href, "ftp://example.com/", "Setting href on an anchor tag should fixup missing slashes after non-http protocol"); + + SimpleTest.finish(); +} + +addLoadEvent(runTest); +</script> +</pre> +</body> +</html> + diff --git a/system/docshell/test/test_bug404548.html b/system/docshell/test/test_bug404548.html new file mode 100644 index 000000000..edde15c9d --- /dev/null +++ b/system/docshell/test/test_bug404548.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=404548 +--> +<head> + <title>Test for Bug 404548</title> + <script type="text/javascript" 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=404548">Mozilla Bug 404548</a> +<p id="display"> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 404548 **/ +var firstRemoved = false; +var secondHidden = false; + +SimpleTest.waitForExplicitFinish(); + +var w = window.open("bug404548-subframe.html", "", "width=10,height=10"); + +function finishTest() { + is(firstRemoved, true, "Should have removed iframe from the DOM") + is(secondHidden, true, "Should have fired pagehide on second kid"); + w.close(); + SimpleTest.finish(); +} +</script> +</pre> +</body> +</html> + diff --git a/system/docshell/test/test_bug413310.html b/system/docshell/test/test_bug413310.html new file mode 100644 index 000000000..e030c99d8 --- /dev/null +++ b/system/docshell/test/test_bug413310.html @@ -0,0 +1,106 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=413310 +--> +<head> + <title>Test for Bug 413310</title> + <script type="text/javascript" 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=413310">Mozilla Bug 413310</a> +<p id="display"> +<script class="testbody" type="text/javascript"> + +if (navigator.platform.startsWith("Mac")) { + SimpleTest.expectAssertions(0, 2); +} else { + SimpleTest.expectAssertions(0, 1); +} + +/** Test for Bug 413310 **/ + +// NOTE: If we ever make subframes do bfcache stuff, this test will need to be +// modified accordingly! It assumes that subframes do NOT get bfcached. +var onloadCount = 0; + +var step = -1; // One increment will come from the initial subframe onload. + // Note that this script should come before the subframe, + // so that doNextStep is defined when its onload handler fires. + +var textContent; + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(doNextStep); + +function doNextStep() { + ++step; + switch (step) { + case 1: + is(onloadCount, 1, "Loaded initial page"); + is($("i").contentWindow.location.href, + location.href.replace(/test_bug413310.html/, + "bug413310-subframe.html"), + "Unexpected subframe location after initial load"); + $("i").contentDocument.forms[0].submit(); + break; + case 2: + is(onloadCount, 2, "Loaded POST result"); + + is($("i").contentWindow.location.href, + location.href.replace(/test_bug413310.html/, + "bug413310-post.sjs"), + "Unexpected subframe location after POST load"); + + textContent = $("i").contentDocument.body.textContent; + isDeeply(textContent.match(/^POST /), ["POST "], "Not a POST?"); + + $("i").contentWindow.location.hash = "foo"; + setTimeout(doNextStep, 0); + break; + case 3: + is(onloadCount, 2, "Anchor scroll should not fire onload"); + is($("i").contentWindow.location.href, + location.href.replace(/test_bug413310.html/, + "bug413310-post.sjs#foo"), + "Unexpected subframe location after anchor scroll"); + is(textContent, $("i").contentDocument.body.textContent, + "Did a load when scrolling?"); + $("i").contentWindow.location.href = "bug413310-subframe.html";; + break; + case 4: + is(onloadCount, 3, "Done new load"); + is($("i").contentWindow.location.href, + location.href.replace(/test_bug413310.html/, + "bug413310-subframe.html"), + "Unexpected subframe location after new load"); + history.back(); + break; + case 5: + is(onloadCount, 4, + "History traversal didn't fire onload: bfcache issues!"); + is($("i").contentWindow.location.href, + location.href.replace(/test_bug413310.html/, + "bug413310-post.sjs#foo"), + "Unexpected subframe location"); + is(textContent, $("i").contentDocument.body.textContent, + "Did a load when going back?"); + SimpleTest.finish(); + break; + } +} +</script> +<!-- Use a timeout in onload so that we don't do a load immediately inside onload --> +<iframe id="i" src="bug413310-subframe.html" onload="setTimeout(doNextStep, 20)"> +</iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> + diff --git a/system/docshell/test/test_bug475636.html b/system/docshell/test/test_bug475636.html new file mode 100644 index 000000000..eaea3bcb8 --- /dev/null +++ b/system/docshell/test/test_bug475636.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=475636 +Test that refresh to data: URIs don't inherit the principal +--> +<head> + <title>Test for Bug 475636</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="gen.next()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=475636">Mozilla Bug 475636</a> + +<div id="content" style="display: none"> + +</div> +<iframe id=loader></iframe> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> + +SimpleTest.waitForExplicitFinish(); + +gen = runTests(); + +window.private = 42; + +window.addEventListener("message", function(e) { + gen.send(e.data); +}, false); + +var url = "file_bug475636.sjs?"; + +function runTests() { + var loader = document.getElementById('loader'); + for (var testNum = 1; ; ++testNum) { + loader.src = url + testNum; + let res = (yield); + if (res == "done") { + SimpleTest.finish(); + yield undefined; + } + is(res, "pass"); + } +} + + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug509055.html b/system/docshell/test/test_bug509055.html new file mode 100644 index 000000000..be163cafa --- /dev/null +++ b/system/docshell/test/test_bug509055.html @@ -0,0 +1,98 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=509055 +--> +<head> + <title>Test for Bug 509055</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" 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=509055">Mozilla Bug 509055</a> +<p id="display"></p> +<div id="status"></div> +<div id="content"> +</div> +<pre id="test"> +<script type="application/javascript;version=1.7"> + +/** Test for Bug 509055 **/ + +SimpleTest.waitForExplicitFinish(); + +var gGen; + +function shortWait() { + setTimeout(function() { gGen.next(); }, 0, false); +} + +function onChildHashchange(e) { + // gGen might be undefined when we refresh the page, so we have to check here + dump("onChildHashchange() called.\n"); + if(gGen) + gGen.next(); +} + +function onChildLoad(e) { + if(gGen) + gGen.next(); +} + +function runTest() { + var popup = window.open("file_bug509055.html", "popup 0", + "height=200,width=200,location=yes," + + "menubar=yes,status=yes,toolbar=yes,dependent=yes"); + popup.hashchangeCallback = onChildHashchange; + popup.onload = onChildLoad; + dump('Waiting for initial load.\n'); + yield undefined; + + // Without this wait, the change to location.hash below doesn't create a + // SHEntry or enable the back button. + shortWait(); + dump('Got initial load. Spinning event loop.\n'); + yield undefined; + + popup.location.hash = "#1"; + dump('Waiting for hashchange.\n'); + yield undefined; + + popup.history.back(); + dump('Waiting for second hashchange.\n'); + yield undefined; // wait for hashchange + + popup.document.title = "Changed"; + + // Wait for listeners to be notified of the title change. + shortWait(); + dump('Got second hashchange. Spinning event loop.\n'); + yield undefined; + + var sh = SpecialPowers.wrap(popup) + .QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIWebNavigation) + .sessionHistory; + + // Get the title of the inner popup's current SHEntry + var sheTitle = sh.getEntryAtIndex(sh.index, false).title; + is(sheTitle, "Changed", "SHEntry's title should change when we change."); + + popup.close(); + + SimpleTest.executeSoon(SimpleTest.finish); + dump('Final yield.\n'); + yield undefined; +} + +window.addEventListener('load', function() { + gGen = runTest(); + gGen.next(); +}, false); + +</script> + +</body> +</html> + diff --git a/system/docshell/test/test_bug511449.html b/system/docshell/test/test_bug511449.html new file mode 100644 index 000000000..dcea4cf3d --- /dev/null +++ b/system/docshell/test/test_bug511449.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=511449 +--> +<head> + <title>Test for Bug 511449</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/NativeKeyCodes.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=511449">Mozilla Bug 511449</a> +<p id="display"></p> +<div id="status"></div> +<div id="content"> +</div> +<input type="text" id="input"> +<pre id="test"> +<script type="application/javascript;version=1.7"> + +/** Test for Bug 511449 **/ + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); +window.addEventListener('load', runTest, false); + +var win = null; + +function runTest() { + document.getElementById("input").focus(); + win = window.open("file_bug511449.html", ""); + SimpleTest.waitForFocus(runNextTest, win); +} + +function runNextTest() { + var didClose = false; + win.onunload = function() { + didClose = true; + } + synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, MAC_VK_ANSI_W, {metaKey:1}, "w", "w"); + + setTimeout(function () { + ok(didClose, "Cmd+W should have closed the tab"); + if (!didClose) { + win.close(); + } + SimpleTest.finish(); + }, 1000); +} + +</script> + +</body> +</html> diff --git a/system/docshell/test/test_bug529119-1.html b/system/docshell/test/test_bug529119-1.html new file mode 100644 index 000000000..573885dc0 --- /dev/null +++ b/system/docshell/test/test_bug529119-1.html @@ -0,0 +1,95 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test bug 529119</title> +<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); + +var workingURL = "http://mochi.test:8888/tests/docshell/test/bug529119-window.html"; +var faultyURL = "http://some-nonexistent-domain-27489274c892748217cn2384.com/"; + +var w = null; +var phase = 0; +var gotWrongPageOnTryAgainClick = false; + +function pollForPage(f, w) +{ + // Start with polling after a delay, we might mistakenly take the current page + // as an expected one. + window.setTimeout(function() { + var iterationsLeft = 200; + var int = window.setInterval(function() { + iterationsLeft--; + + var haveErrorPage = false; + try { + var title = w.document.title; + } + catch (ex) { + haveErrorPage = true; + } + + if (iterationsLeft == 0 || haveErrorPage) { + window.clearInterval(int); + f(iterationsLeft > 0); + } + }, 100); + }, 1000); +} + +function windowLoaded() +{ + switch (phase) + { + case 0: + /* 2. We have succeededfully loaded a page, now go to a faulty URL */ + window.setTimeout(function() { + w.location.href = faultyURL; + }, 0); + + phase = 1; + + pollForPage(function(succeeded) { + ok(succeeded, "Waiting for error page succeeded"); + + /* 3. now, while we are on the error page, try to reload it, actually + click the "Try Again" button */ + SpecialPowers.wrap(w).location.reload(); + + pollForPage(function(succeeded) { + ok(succeeded, "Waiting for error page succeeded"); + + /* 4-finish, check we are still on the error page */ + is(SpecialPowers.wrap(w).location.href, faultyURL, "Is on an error page"); + isnot(SpecialPowers.wrap(w).location.href, workingURL, "Is not on the previous page"); + is(gotWrongPageOnTryAgainClick, false, + "Must not get www.example.com page on reload of an error page"); + w.close(); + SimpleTest.finish(); + }, w); + }, w); + break; + + case 1: + /* 4-check, we must not get here! */ + gotWrongPageOnTryAgainClick = true; + break; + } +} + +function startTest() +{ + /* 1. load a URL that leads to an error page */ + w = window.open(workingURL); +} + +</script> +</head> +<body onload="startTest();"> +</body> +</html> diff --git a/system/docshell/test/test_bug529119-2.html b/system/docshell/test/test_bug529119-2.html new file mode 100644 index 000000000..fb3d19119 --- /dev/null +++ b/system/docshell/test/test_bug529119-2.html @@ -0,0 +1,90 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test bug 529119</title> +<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); + +var workingURL = "http://mochi.test:8888/tests/docshell/test/bug529119-window.html"; +var faultyURL = "http://some-nonexistent-domain-27489274c892748217cn2384.com/"; + +var w = null; +var phase = 0; +var isWindowLoaded = false; + +function pollForPage(expectErrorPage, f, w) +{ + // Start with polling after a delay, we might mistakenly take the current page + // as an expected one. + window.setTimeout(function() { + var iterationsLeft = 200; + var int = window.setInterval(function() { + iterationsLeft--; + + var haveErrorPage = false; + try { + var title = w.document.title; + } + catch (ex) { + haveErrorPage = true; + } + + if (iterationsLeft == 0 || expectErrorPage == haveErrorPage) { + window.clearInterval(int); + f(iterationsLeft > 0); + } + }, 100); + }, 1000); +} + +function windowLoaded() +{ + // The code under here should only be run once + // The test popup window workingURL was already opened + if (isWindowLoaded) + return; + isWindowLoaded = true; + + /* 2. We have successfully loaded a page, now go to a faulty URL */ + // XXX The test fails when we change the location synchronously + window.setTimeout(function() { + w.location.href = faultyURL; + }, 0); + + pollForPage(true, function(succeeded) { + ok(succeeded, "Waiting for error page succeeded"); + /* 3. now, while we are on the error page, navigate back */ + try { + SpecialPowers.wrap(w).back(); + } + catch(ex) { + ok(false, "w.back() threw " + ex); + } + + pollForPage(false, function(succeeded) { + ok(succeeded, "Waiting for original page succeeded"); + /* 4-finish, check we are back at the original page */ + isnot(SpecialPowers.wrap(w).location.href, faultyURL, "Is on an error page"); + is(SpecialPowers.wrap(w).location.href, workingURL, "Is not on the previous page"); + w.close(); + SimpleTest.finish(); + }, w); + }, w); +} + +function startTest() +{ + /* 1. load a URL that leads to an error page */ + w = window.open(workingURL); +} + +</script> +</head> +<body onload="startTest();"> +</body> +</html> diff --git a/system/docshell/test/test_bug530396.html b/system/docshell/test/test_bug530396.html new file mode 100644 index 000000000..f9fb79b4b --- /dev/null +++ b/system/docshell/test/test_bug530396.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=530396 +--> +<head> + <title>Test for Bug 530396</title> + <script type="application/javascript" src="/MochiKit/packed.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" 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=530396">Mozilla Bug 530396</a> + +<p> + +<iframe id="testFrame" src="http://mochi.test:8888/tests/docshell/test/bug530396-subframe.html"></iframe> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// NOTE: If we ever make subframes do bfcache stuff, this test will need to be +// modified accordingly! It assumes that subframes do NOT get bfcached. +var onloadCount = 0; + +var step = 0; + +var gTestFrame = document.getElementById('testFrame'); + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); +addLoadEvent(doNextStep); + +function doNextStep() { + ++step; + switch (step) { + case 1: + is(onloadCount, 1, "Loaded initial page"); + sendMouseEvent({type: "click"}, "target2", gTestFrame.contentWindow); + window.setTimeout(doNextStep, 1000); + break; + + case 2: + is(onloadCount, 1, "opener must be null"); + sendMouseEvent({type: "click"}, "target1", gTestFrame.contentWindow); + break; + + case 3: + is(onloadCount, 2, "don't send referrer with rel=referrer"); + SimpleTest.finish(); + break; + } +} +</script> +</pre> +</html> diff --git a/system/docshell/test/test_bug540462.html b/system/docshell/test/test_bug540462.html new file mode 100644 index 000000000..65447114f --- /dev/null +++ b/system/docshell/test/test_bug540462.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=540462 +--> +<head> + <title>Test for Bug 540462</title> + <script type="application/javascript" 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=540462">Mozilla Bug 540462</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 540462 **/ + +var win; +function runTest() { + win = window.open("file_bug540462.html", "", "width=100,height=100"); +} + +var dwlCount = 0; +var originalURL; +function documentWriteLoad() { + if (++dwlCount == 1) { + originalURL = win.document.body.firstChild.href; + } else if (dwlCount == 2) { + is(win.document.body.firstChild.href, originalURL, "Wrong href!"); + win.close(); + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug551225.html b/system/docshell/test/test_bug551225.html new file mode 100644 index 000000000..00dc5e076 --- /dev/null +++ b/system/docshell/test/test_bug551225.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=551225 +--> +<head> + <title>Test for Bug 551225</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" 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=551225">Mozilla Bug 551225</a> + +<script type="application/javascript;version=1.7"> + +/** Test for Bug 551225 **/ + +obj = { + a: new Date('1/1/2000'), + b: /^foo$/, + c: 'bar' +}; + +history.replaceState(obj, '', ''); +is(history.state.a.toString(), new Date('1/1/2000').toString(), 'Date object.'); +is(history.state.b.toString(), '/^foo$/', 'Regex'); +is(history.state.c, 'bar', 'Other state'); + +</script> +</body> +</html> diff --git a/system/docshell/test/test_bug570341.html b/system/docshell/test/test_bug570341.html new file mode 100644 index 000000000..d09afa4bd --- /dev/null +++ b/system/docshell/test/test_bug570341.html @@ -0,0 +1,142 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=570341 +--> +<head> + <title>Test for Bug 570341</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script> + var start = Date.now(); + var moments = {}; + + var unload = 0; + var wasEnabled = true; + + function collectMoments() { + var win = frames[0]; + var timing = (win.performance && win.performance.timing) || {}; + for (var p in timing) { + moments[p] = timing[p]; + } + for (var p in win) { + if (p.substring(0,9) == '_testing_') { + moments[p.substring(9)] = win[p]; + } + } + moments['evt_unload'] = unload; + return moments; + } + + function showSequence(node){ + while(node.firstChild) { + node.removeChild(node.firstChild); + } + var sequence = []; + for (var p in moments) { + sequence.push(p); + } + sequence.sort(function(a, b){ + return moments[a] - moments[b]; + }); + table = document.createElement('table'); + node.appendChild(table); + row = document.createElement('tr'); + table.appendChild(row); + cell = document.createElement('td'); + row.appendChild(cell); + cell.appendChild(document.createTextNode('start')); + cell = document.createElement('td'); + row.appendChild(cell); + cell.appendChild(document.createTextNode(start)); + for (var i = 0; i < sequence.length; ++i) { + var prop = sequence[i]; + row = document.createElement('tr'); + table.appendChild(row); + cell = document.createElement('td'); + row.appendChild(cell); + cell.appendChild(document.createTextNode(prop)); + cell = document.createElement('td'); + row.appendChild(cell); + cell.appendChild(document.createTextNode(moments[prop])); + } + } + + function checkValues(){ + var win = frames[0]; + ok(win.performance, + 'window.performance is missing or not accessible for frame'); + ok(!win.performance || win.performance.timing, + 'window.performance.timing is missing or not accessible for frame'); + collectMoments(); + + var sequences = [ + ['navigationStart', 'unloadEventStart', 'unloadEventEnd'], + ['navigationStart', 'fetchStart', 'domainLookupStart', 'domainLookupEnd', + 'connectStart', 'connectEnd', 'requestStart', 'responseStart', 'responseEnd'], + ['responseStart', 'domLoading', 'domInteractive', 'domComplete'], + ['domContentLoadedEventStart', 'domContentLoadedEventEnd', + 'loadEventStart', 'loadEventEnd'] + ] + + for (var i = 0; i < sequences.length; ++i) { + var seq = sequences[i]; + for (var j = 0; j < seq.length; ++j) { + var prop = seq[j]; + if (j > 0) { + var prevProp = seq[j-1]; + ok(moments[prevProp] <= moments[prop], + ['Expected ', prevProp, ' to happen before ', prop, + ', got ', prevProp, ' = ', moments[prevProp], + ', ', prop, ' = ', moments[prop]].join('')); + } + } + } + + SimpleTest.finish() + } + +window.onload = function() { + var win = frames[0]; + win.addEventListener('unload', function(){ + unload = Date.now(); + }, true); + var seenLoad = 0; + win.addEventListener('load', function (){ + seenLoad = Date.now(); + }, true); + frames[0].location = 'bug570341_recordevents.html' + var interval = setInterval(function () { + // time constants here are arbitrary, chosen to allow the test to pass + var stopPolling = (win.performance && win.performance.loadEventEnd) || + (seenLoad && Date.now() >= seenLoad + 3000) || + Date.now() >= start + 30000; + if (stopPolling) { + clearInterval(interval); + checkValues(); + } else if (win._testing_evt_load) { + seenLoad = Date.now(); + } + }, 100); +} +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=570341">Mozilla Bug 570341</a> +<div id="frames"> +<iframe name="child0" src="navigation/blank.html"></iframe> +</div> +<button type="button" onclick="showSequence(document.getElementById('display'))"> + Show Events</button> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug580069.html b/system/docshell/test/test_bug580069.html new file mode 100644 index 000000000..70d3b4a3e --- /dev/null +++ b/system/docshell/test/test_bug580069.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=580069 +--> +<head> + <title>Test for Bug 580069</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" 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=580069">Mozilla Bug 580069</a> + +<iframe id='iframe' src='file_bug580069_1.html'></iframe> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var iframe = document.getElementById('iframe'); +var iframeCw = iframe.contentWindow; + +// Called when file_bug580069_1.html loads. +function page1Load() { + // This should cause us to load file 2. + dump('page1Load\n'); + iframeCw.document.getElementById('form').submit(); +} + +// Called when file_bug580069_2.html loads. +var page2Loads = 0; +function page2Load(method) { + + dump("iframe's location is: " + iframeCw.location + ", method is " + method + "\n"); + + if (page2Loads == 0) { + is(method, "POST", "Method for first load should be POST."); + iframeCw.history.replaceState('', '', '?replaced'); + + // This refresh shouldn't pop up the "are you sure you want to refresh a page + // with POST data?" dialog. If it does, this test will hang and fail, and + // we'll see 'Refreshing iframe...' at the end of the test log. + dump('Refreshing iframe...\n'); + iframeCw.location.reload(); + } + else if (page2Loads == 1) { + is(method, "GET", "Method for second load should be GET."); + is(iframeCw.location.search, "?replaced", "Wrong search on iframe after refresh."); + SimpleTest.finish(); + } + else { + ok(false, "page2Load should only be called twice."); + } + + page2Loads++; +} +</script> + +</body> +</html> diff --git a/system/docshell/test/test_bug590573.html b/system/docshell/test/test_bug590573.html new file mode 100644 index 000000000..e218140ea --- /dev/null +++ b/system/docshell/test/test_bug590573.html @@ -0,0 +1,232 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=590573 +--> +<head> + <title>Test for Bug 590573</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" 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=590573">Mozilla Bug 590573</a> + +<script type='application/javascript;version=1.7'> +SimpleTest.waitForExplicitFinish(); + +// Listen to the first callback, since this indicates that the page loaded. +var page1LoadCallbackEnabled = true; +function page1Load() +{ + if (page1LoadCallbackEnabled) { + page1LoadCallbackEnabled = false; + dump('Got page1 load.\n'); + pageLoad(); + } + else { + dump('Ignoring page1 load.\n'); + } +} + +var page1PopstateCallbackEnabled = false; +function page1Popstate() +{ + if (page1PopstateCallbackEnabled) { + page1PopstateCallbackEnabled = false; + dump('Got page1 popstate.\n'); + pageLoad(); + } + else { + dump('Ignoring page1 popstate.\n'); + } +} + +var page1PageShowCallbackEnabled = false; +function page1PageShow() +{ + if (page1PageShowCallbackEnabled) { + page1PageShowCallbackEnabled = false; + dump('Got page1 pageshow.\n'); + pageLoad(); + } + else { + dump('Ignoring page1 pageshow.\n'); + } +} + +var page2LoadCallbackEnabled = false; +function page2Load() +{ + if (page2LoadCallbackEnabled) { + page2LoadCallbackEnabled = false; + dump('Got page2 popstate.\n'); + pageLoad(); + } + else { + dump('Ignoring page2 popstate.\n'); + } +} + +var page2PopstateCallbackEnabled = false; +function page2Popstate() +{ + if (page2PopstateCallbackEnabled) { + page2PopstateCallbackEnabled = false; + dump('Got page2 popstate.\n'); + pageLoad(); + } + else { + dump('Ignoring page2 popstate.\n'); + } +} + +var page2PageShowCallbackEnabled = false; +function page2PageShow() +{ + if (page2PageShowCallbackEnabled) { + page2PageShowCallbackEnabled = false; + dump('Got page2 pageshow.\n'); + pageLoad(); + } + else { + dump('Ignoring page2 pageshow.\n'); + } +} + +function dumpSHistory(theWindow) +{ + let sh = SpecialPowers.wrap(theWindow).QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIWebNavigation) + .sessionHistory; + if (!sh) { + dump(" window has no shistory.\n"); + return; + } + + dump(" count: " + sh.count + "\n"); + dump(" index: " + sh.index + "\n"); + dump(" requestedIndex: " + sh.requestedIndex + "\n"); + + for (let i = 0; i < sh.count; i++) { + let shentry = sh.getEntryAtIndex(i, false); + dump(" " + i + ": " + shentry.URI.spec + '\n'); + shentry.QueryInterface(SpecialPowers.Ci.nsISHContainer); + for (let j = 0; j < shentry.childCount; j++) { + let child = shentry.GetChildAt(j); + dump(" child " + j + ": " + child.URI.spec + '\n'); + } + } + + return sh; +} + +var popup = window.open('file_bug590573_1.html'); + +var gTestContinuation = null; +var loads = 0; +function pageLoad() +{ + loads++; + dump('pageLoad(loads=' + loads + ', page location=' + popup.location + ')\n'); + + dumpSHistory(window); + + if (!gTestContinuation) { + gTestContinuation = testBody(); + } + var ret = gTestContinuation.next(); + if (ret.done) { + SimpleTest.finish(); + } +} + +function* testBody() +{ + is(popup.scrollY, 0, "test 1"); + popup.scroll(0, 100); + + popup.history.pushState('', '', '?pushed'); + is(Math.round(popup.scrollY), 100, "test 2"); + popup.scroll(0, 200); // set state-2's position to 200 + + popup.history.back(); + is(Math.round(popup.scrollY), 100, "test 3"); + popup.scroll(0, 150); // set original page's position to 150 + + popup.history.forward(); + is(Math.round(popup.scrollY), 200, "test 4"); + + popup.history.back(); + is(Math.round(popup.scrollY), 150, "test 5"); + + popup.history.forward(); + is(Math.round(popup.scrollY), 200, "test 6"); + + // At this point, the history looks like: + // PATH POSITION + // file_bug590573_1.html 150 <-- oldest + // file_bug590573_1.html?pushed 200 <-- newest, current + + // Now test that the scroll position is persisted when we have real + // navigations involved. First, we need to spin the event loop so that the + // navigation doesn't replace our current history entry. + + setTimeout(pageLoad, 0); + yield; + + page2LoadCallbackEnabled = true; + popup.location = 'file_bug590573_2.html'; + yield; + + ok(popup.location.href.match('file_bug590573_2.html$'), + "Location was " + popup.location + + " but should end with file_bug590573_2.html"); + + is(popup.scrollY, 0, "test 7"); + popup.scroll(0, 300); + + // We need to spin the event loop again before we go back, otherwise the + // scroll positions don't get updated properly. + setTimeout(pageLoad, 0); + yield; + + page1PageShowCallbackEnabled = true; + popup.history.back(); + yield; + + // Spin the event loop again so that we get the right scroll positions. + setTimeout(pageLoad, 0); + yield; + + is(popup.location.search, "?pushed"); + ok(popup.document.getElementById('div1'), 'page should have div1.'); + + is(Math.round(popup.scrollY), 200, "test 8"); + + popup.history.back(); + is(Math.round(popup.scrollY), 150, "test 9"); + popup.history.forward(); + + is(Math.round(popup.scrollY), 200, "test 10"); + + // Spin one last time... + setTimeout(pageLoad, 0); + yield; + + page2PageShowCallbackEnabled = true; + popup.history.forward(); + yield; + + // Bug 821821, on Android tegras we get 299 instead of 300 sometimes + if (popup.scrollY >= 299 && popup.scrollY <= 300) { + is(1, 1, "test 11"); + } else { + is(1, 0, "test 11, got " + popup.scrollY + " for popup.scrollY instead of 299|300"); + } + popup.close(); +} +</script> + +</body> +</html> diff --git a/system/docshell/test/test_bug598895.html b/system/docshell/test/test_bug598895.html new file mode 100644 index 000000000..5cc74e42c --- /dev/null +++ b/system/docshell/test/test_bug598895.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=598895 +--> +<head> + <title>Test for Bug 598895</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.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=598895">Mozilla Bug 598895</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 598895 **/ +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { +var win1 = window.open(); +win1.document.body.textContent = "Should show"; + +var windowsLoaded = 0; + +window.onmessage = function (ev) { + is(ev.data, "loaded", "Message should be 'loaded'"); + if (++windowsLoaded == 2) { + var one = snapshotWindow(win1); + var two = snapshotWindow(win2); + var three = snapshotWindow(win3); + win1.close(); + win2.close(); + win3.close(); + ok(compareSnapshots(one, two, true)[0], "Popups should look identical"); + ok(compareSnapshots(one, three, false)[0], "Popups should not look identical"); + + SimpleTest.finish(); + } +} + +var win2 = window.open("file_bug598895_1.html"); +var win3 = window.open("file_bug598895_2.html"); +}); +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug634834.html b/system/docshell/test/test_bug634834.html new file mode 100644 index 000000000..88f068518 --- /dev/null +++ b/system/docshell/test/test_bug634834.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=634834 +--> +<head> + <title>Test for Bug 634834</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" 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=634834">Mozilla Bug 634834</a> + +<script type='application/javascript;version=1.7'> +SimpleTest.waitForExplicitFinish(); + +function iframe_loaded() { + var loadedAfterPushstate = false; + $('iframe').onload = function() { + loadedAfterPushstate = true; + } + + var obj = { name: 'name' }; + obj.__defineGetter__('a', function() { + $('iframe').contentWindow.location = 'http://example.com'; + + // Wait until we've loaded example.com. + do { + var r = new XMLHttpRequest(); + r.open("GET", location.href, false); + r.overrideMimeType("text/plain"); + try { r.send(null); } + catch (e) {} + } while (!loadedAfterPushstate); + }); + + try { + $('iframe').contentWindow.history.pushState(obj, ''); + ok(false, 'pushState should throw exception.'); + } + catch(e) { + ok(true, 'pushState threw an exception.'); + } + SimpleTest.finish(); +} + +</script> + +<iframe id='iframe' src='file_bug634834.html' onload='iframe_loaded()'></iframe> + +</body> +</html> diff --git a/system/docshell/test/test_bug637644.html b/system/docshell/test/test_bug637644.html new file mode 100644 index 000000000..4192fae22 --- /dev/null +++ b/system/docshell/test/test_bug637644.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=637644 +--> +<head> + <title>Test for Bug 637644</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.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=637644">Mozilla Bug 637644</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 637644 **/ +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { +var win1 = window.open("", "", "height=500,width=500"); +win1.document.body.textContent = "Should show"; + +var windowsLoaded = 0; + +window.onmessage = function (ev) { + is(ev.data, "loaded", "Message should be 'loaded'"); + if (++windowsLoaded == 2) { + var one = snapshotWindow(win1); + var two = snapshotWindow(win2); + var three = snapshotWindow(win3); + win1.close(); + win2.close(); + win3.close(); + ok(compareSnapshots(one, two, true)[0], "Popups should look identical"); + ok(compareSnapshots(one, three, false)[0], "Popups should not look identical"); + + SimpleTest.finish(); + } +} + +var win2 = window.open("file_bug637644_1.html", "", "height=500,width=500"); +var win3 = window.open("file_bug637644_2.html", "", "height=500,width=500"); +}); +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug640387_1.html b/system/docshell/test/test_bug640387_1.html new file mode 100644 index 000000000..e324787d4 --- /dev/null +++ b/system/docshell/test/test_bug640387_1.html @@ -0,0 +1,109 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=640387 +--> +<head> + <title>Test for Bug 640387</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" 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=640387">Mozilla Bug 640387</a> + +<script type='application/javascript;version=1.7'> +SimpleTest.waitForExplicitFinish(); + +function test() { + /* Spin the event loop so we get out of the onload handler. */ + SimpleTest.executeSoon(function() { gGen.next() }); + yield undefined; + + popup.history.pushState('', '', '#hash1'); + popup.history.pushState('', '', '#hash2'); + + // Now the history looks like: + // file_bug640387.html + // file_bug640387.html#hash1 + // file_bug640387.html#hash2 <-- current + + // Going back should trigger a hashchange, which will wake us up from the + // yield. + popup.history.back(); + yield undefined; + ok(true, 'Got first hashchange.'); + + // Going back should wake us up again. + popup.history.back(); + yield undefined; + ok(true, 'Got second hashchange.'); + + // Now the history looks like: + // file_bug640387.html <-- current + // file_bug640387.html#hash1 + // file_bug640387.html#hash2 + + // Going forward should trigger a hashchange. + popup.history.forward(); + yield undefined; + ok(true, 'Got third hashchange.'); + + // Now modify the history so it looks like: + // file_bug640387.html + // file_bug640387.html#hash1 + // file_bug640387.html#hash1 <-- current + popup.history.pushState('', '', '#hash1'); + + // Now when we go back, we should not get a hashchange. Instead, wait for a + // popstate. We need to asynchronously go back because popstate is fired + // sync. + gHashchangeExpected = false; + gCallbackOnPopstate = true; + SimpleTest.executeSoon(function() { popup.history.back() }); + yield undefined; + ok(true, 'Got popstate.'); + gCallbackOnPopstate = false; + + // Spin the event loop so hashchange has a chance to fire, if it's going to. + SimpleTest.executeSoon(function() { gGen.next() }); + yield undefined; + + popup.close(); + SimpleTest.finish(); + yield undefined; +} + +gGen = null; +function childLoad() { + gGen = test(); + gGen.next(); +} + +gHashchangeExpected = true; +function childHashchange() { + if (gHashchangeExpected) { + gGen.next(); + } + else { + ok(false, "Got hashchange when we weren't expecting one."); + } +} + +gCallbackOnPopstate = false; +function childPopstate() { + if (gCallbackOnPopstate) { + gGen.next(); + } +} + +/* We need to run this test in a popup, because navigating an iframe + * back/forwards tends to cause intermittent orange. */ +popup = window.open('file_bug640387.html'); + +/* Control now flows up to childLoad(), called once the popup loads. */ + +</script> + +</body> +</html> diff --git a/system/docshell/test/test_bug640387_2.html b/system/docshell/test/test_bug640387_2.html new file mode 100644 index 000000000..00c27fdda --- /dev/null +++ b/system/docshell/test/test_bug640387_2.html @@ -0,0 +1,90 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=640387 +--> +<head> + <title>Test for Bug 640387</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" 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=640387">Mozilla Bug 640387</a> + +<!-- Test that, when going from + + http://example.com/#foo + +to + + http://example.com/ + +via a non-history load, we do a true load, rather than a scroll. --> + +<script type='application/javascript;version=1.7'> +SimpleTest.waitForExplicitFinish(); + +callbackOnLoad = false; +function childLoad() { + if (callbackOnLoad) { + callbackOnLoad = false; + gGen.next(); + } +} + +errorOnHashchange = false; +callbackOnHashchange = false; +function childHashchange() { + if (errorOnHashchange) { + ok(false, 'Got unexpected hashchange.'); + } + if (callbackOnHashchange) { + callbackOnHashchange = false; + gGen.next(); + } +} + +function run_test() { + var iframe = $('iframe').contentWindow; + + ok(true, 'Got first load'); + + // Spin the event loop so we exit the onload handler. + SimpleTest.executeSoon(function() { gGen.next() }); + yield undefined; + + let origLocation = iframe.location + ''; + callbackOnHashchange = true; + iframe.location.hash = '#1'; + // Wait for a hashchange event. + yield undefined; + + ok(true, 'Got hashchange.'); + + iframe.location = origLocation; + // This should produce a load event and *not* a hashchange, because the + // result of the load is a different document than we had previously. + callbackOnLoad = true; + errorOnHashchange = true; + yield undefined; + + ok(true, 'Got final load.'); + + // Spin the event loop to give hashchange a chance to fire, if it's going to. + SimpleTest.executeSoon(function() { gGen.next() }); + yield undefined; + + SimpleTest.finish(); + yield undefined; +} + +callbackOnLoad = true; +gGen = run_test(); + +</script> + +<iframe id='iframe' src='file_bug640387.html'></iframe> + +</body> +</html> diff --git a/system/docshell/test/test_bug653741.html b/system/docshell/test/test_bug653741.html new file mode 100644 index 000000000..a1faf5e2d --- /dev/null +++ b/system/docshell/test/test_bug653741.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=653741 +--> +<head> + <title>Test for Bug 653741</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.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=653741">Mozilla Bug 653741</a> + +<script type="application/javascript;version=1.7"> + +/** Test for Bug 653741 **/ +SimpleTest.waitForExplicitFinish(); + +function childLoad() { + // Spin the event loop so we leave the onload handler. + SimpleTest.executeSoon(childLoad2); +} + +function childLoad2() { + let cw = $('iframe').contentWindow; + + // Save the Y offset. For sanity's sake, make sure it's not 0, because we + // should be at the bottom of the page! + let origYOffset = Math.round(cw.pageYOffset); + ok(origYOffset != 0, 'Original Y offset is not 0.'); + + // Scroll the iframe to the top, then navigate to #bottom again. + cw.scrollTo(0, 0); + + // Our current location is #bottom, so this should scroll us down to the + // bottom again. + cw.location = cw.location + ''; + + is(Math.round(cw.pageYOffset), origYOffset, 'Correct offset after reloading page.'); + SimpleTest.finish(); +} + +</script> + +<iframe height='100px' id='iframe' src='file_bug653741.html#bottom'></iframe> + +</body> +</html> diff --git a/system/docshell/test/test_bug660404.html b/system/docshell/test/test_bug660404.html new file mode 100644 index 000000000..df45793a9 --- /dev/null +++ b/system/docshell/test/test_bug660404.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=660404 +--> +<head> + <title>Test for Bug 660404</title> + <script type="application/javascript" 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=660404">Mozilla Bug 660404</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 660404 **/ +SimpleTest.waitForExplicitFinish(); + +var w; + +function continueTest() { + // Do this async so the load event can finish firing + SimpleTest.executeSoon(function() { + w.onpagehide = function(ev) { + is(ev.persisted, true, "Should be bfcached when navigating to multipart"); + } + w.location.href = "file_bug660404"; + }); +} + +function finishTest() { + is(w.document.documentElement.textContent, "opener.finishTest();"); + is(w.document.documentElement.innerHTML, "<head><script>opener.finishTest();</"+"script></head>"); + w.close(); + SimpleTest.finish(); +} + +// Have to open a new window, since there's no bfcache in subframes +w = window.open("data:text/html,<script>window.onload = function() { opener.continueTest(); }</"+"script>"); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug662170.html b/system/docshell/test/test_bug662170.html new file mode 100644 index 000000000..0e626fed4 --- /dev/null +++ b/system/docshell/test/test_bug662170.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=662170 +--> +<head> + <title>Test for Bug 662170</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.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=662170">Mozilla Bug 662170</a> + +<script type="application/javascript;version=1.7"> + +/** Test for Bug 662170 **/ +SimpleTest.waitForExplicitFinish(); + +function childLoad() { + // Spin the event loop so we leave the onload handler. + SimpleTest.executeSoon(childLoad2); +} + +function childLoad2() { + let cw = $('iframe').contentWindow; + + // When we initially load the page, we should be at the top. + is(cw.pageYOffset, 0, 'Initial Y offset should be 0.'); + + // Scroll the iframe to the bottom. + cw.scrollTo(0, 300); + + // Did we actually scroll somewhere? + isnot(Math.round(cw.pageYOffset), 0, 'Y offset should be non-zero after scrolling.'); + + // Now load file_bug662170.html#, which should take us to the top of the + // page. + cw.location = cw.location + '#'; + + is(cw.pageYOffset, 0, 'Correct Y offset after loading #.'); + SimpleTest.finish(); +} + +</script> + +<!-- When the iframe loads, it calls childLoad(). --> +<iframe height='100px' id='iframe' src='file_bug662170.html'></iframe> + +</body> +</html> diff --git a/system/docshell/test/test_bug668513.html b/system/docshell/test/test_bug668513.html new file mode 100644 index 000000000..78df4b135 --- /dev/null +++ b/system/docshell/test/test_bug668513.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=668513 +--> +<head> + <title>Test for Bug 668513</title> + <script type="application/javascript" 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=668513">Mozilla Bug 668513</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +if (navigator.platform.startsWith("Linux")) { + SimpleTest.expectAssertions(0, 1); +} + +SimpleTest.waitForExplicitFinish(); +window.open("file_bug668513.html"); +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug669671.html b/system/docshell/test/test_bug669671.html new file mode 100644 index 000000000..6070ecc82 --- /dev/null +++ b/system/docshell/test/test_bug669671.html @@ -0,0 +1,146 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=669671 +--> +<head> + <title>Test for Bug 669671</title> + <script type="application/javascript" 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=669671">Mozilla Bug 669671</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript;version=1.7"> + +/** + * Test for Bug 669671. + * + * This is a bit complicated. We have a script, file_bug669671.sjs, which counts + * how many times it's loaded and returns that count in the body of an HTML + * document. For brevity, call this page X. + * + * X is sent with Cache-Control: max-age=0 and can't be bfcached (it has an + * onunload handler). Our test does the following in a popup: + * + * 1) Load X?pushed, to prime the cache. + * 2) Navigate to X. + * 3) Call pushState and navigate from X to X?pushed. + * 4) Navigate to X?navigated. + * 5) Go back (to X?pushed). + * + * We do all this work so we can check that in step 5, we fetch X?pushed from + * the network -- we shouldn't use our cached copy, because of the + * cache-control header X sends. + * + * Then we go back and repeat the whole process but call history.replaceState + * instead of pushState. And for good measure, we test once more, this time + * modifying only the hash of the URI using replaceState. In this case, we + * *should* load from the cache. + * + **/ +SimpleTest.requestLongerTimeout(2); +SimpleTest.waitForExplicitFinish(); + +function onChildLoad() +{ + SimpleTest.executeSoon(function() { gGen.next() }); +} + +var _loadCount = 0; +function checkPopupLoadCount() +{ + is(popup.document.body.innerHTML, _loadCount + '', 'Load count'); + + // We normally want to increment _loadCount here. But if the test fails + // because we didn't do a load we should have, let's not cause a cascade of + // failures by incrementing _loadCount. + var origCount = _loadCount; + if (popup.document.body.innerHTML >= _loadCount + '') + _loadCount++; + return origCount; +} + +function test() +{ + // Step 0 - Make sure the count is reset to 0 in case of reload + popup.location = 'file_bug669671.sjs?countreset'; + yield; + is(popup.document.body.innerHTML, '0', + 'Load count should be reset to 0'); + + // Step 1 - The popup's body counts how many times we've requested the + // resource. This is the first time we've requested it, so it should be '0'. + checkPopupLoadCount(); + + // Step 2 - We'll get another onChildLoad when this finishes. + popup.location = 'file_bug669671.sjs'; + yield undefined; + + // Step 3 - Call pushState and change the URI back to ?pushed. + checkPopupLoadCount(); + popup.history.pushState('', '', '?pushed'); + + // Step 4 - Navigate away. This should trigger another onChildLoad. + popup.location = 'file_bug669671.sjs?navigated-1'; + yield undefined; + + // Step 5 - Go back. This should result in another onload (because the file is + // not in bfcache) and should be the fourth time we've requested the sjs file. + checkPopupLoadCount(); + SpecialPowers.wrap(popup).back(); + yield undefined; + + // This is the check which was failing before we fixed the bug. + checkPopupLoadCount(); + + popup.close(); + + // Do the whole thing again, but with replaceState. + popup = window.open('file_bug669671.sjs?replaced'); + yield undefined; + checkPopupLoadCount(); + popup.location = 'file_bug669671.sjs'; + yield undefined; + checkPopupLoadCount(); + popup.history.replaceState('', '', '?replaced'); + popup.location = 'file_bug669671.sjs?navigated-2'; + yield undefined; + checkPopupLoadCount(); + SpecialPowers.wrap(popup).back(); + yield undefined; + checkPopupLoadCount(); + popup.close(); + + // Once more, with feeling. Notice that we don't have to prime the cache + // with an extra load here, because X and X#hash share the same cache entry. + popup = window.open('file_bug669671.sjs?hash-test'); + yield undefined; + var initialCount = checkPopupLoadCount(); + popup.history.replaceState('', '', '#hash'); + popup.location = 'file_bug669671.sjs?navigated-3'; + yield undefined; + checkPopupLoadCount(); + SpecialPowers.wrap(popup).back(); + yield undefined; + is(popup.document.body.innerHTML, initialCount + '', + 'Load count (should be cached)'); + popup.close(); + + SimpleTest.finish(); + yield undefined; +} + +// This will call into onChildLoad once it loads. +var popup = window.open('file_bug669671.sjs?pushed'); + +var gGen = test(); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug675587.html b/system/docshell/test/test_bug675587.html new file mode 100644 index 000000000..9a283d3ac --- /dev/null +++ b/system/docshell/test/test_bug675587.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=675587 +--> +<head> + <title>Test for Bug 675587</title> + <script type="application/javascript" 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=675587">Mozilla Bug 675587</a> +<p id="display"> + <iframe src="data:text/html,<script>location.hash='';</script>#hash"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 675587 **/ +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { + is(window.frames[0].location.href, + "data:text/html,<script>location.hash='';</" + "script>#", + "Should have the right href"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug680257.html b/system/docshell/test/test_bug680257.html new file mode 100644 index 000000000..bf7c32d11 --- /dev/null +++ b/system/docshell/test/test_bug680257.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=680257 +--> +<head> + <title>Test for Bug 680257</title> + <script type="application/javascript" 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=680257">Mozilla Bug 680257</a> + +<script type="application/javascript;version=1.7"> + +SimpleTest.waitForExplicitFinish(); + +var popup = window.open('file_bug680257.html'); + +// The popup will call into popupLoaded() once it loads. +function popupLoaded() { + // runTests() needs to be called from outside popupLoaded's onload handler. + // Otherwise, the navigations we do in runTests won't create new SHEntries. + SimpleTest.executeSoon(runTests); +} + +function runTests() { + checkPopupLinkStyle(false, 'Initial'); + + popup.location.hash = 'a'; + checkPopupLinkStyle(true, 'After setting hash'); + + popup.history.back(); + checkPopupLinkStyle(false, 'After going back'); + + popup.history.forward(); + checkPopupLinkStyle(true, 'After going forward'); + + popup.close(); + SimpleTest.finish(); +} + +function checkPopupLinkStyle(isTarget, desc) { + var link = popup.document.getElementById('a'); + var style = popup.getComputedStyle(link); + var color = style.getPropertyValue('color'); + + // Color is red if isTarget, black otherwise. + if (isTarget) { + is(color, 'rgb(255, 0, 0)', desc); + } + else { + is(color, 'rgb(0, 0, 0)', desc); + } +} + +</script> +</body> +</html> diff --git a/system/docshell/test/test_bug691547.html b/system/docshell/test/test_bug691547.html new file mode 100644 index 000000000..9bf4f1004 --- /dev/null +++ b/system/docshell/test/test_bug691547.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=691547 +--> +<head> + <title>Test for Bug 691547</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"> + var navStart = 0; + var beforeReload = 0; + function onContentLoad() { + var frame = frames[0]; + if (!navStart) { + // First time we perform navigation in subframe. The bug is that + // load in subframe causes timing.navigationStart to be recorded + // as if it was a start of the next navigation. + var innerFrame = frame.frames[0]; + navStart = frame.performance.timing.navigationStart; + innerFrame.location = 'bug570341_recordevents.html'; + // Let's wait a bit so the difference is clear anough. + setTimeout(reload, 3000); + } + else { + // Content reloaded, time to check. We are allowing a huge time slack, + // in case clock is imprecise. If we have a bug, the difference is + // expected to be about the timeout value set above. + var diff = frame.performance.timing.navigationStart - beforeReload; + ok(diff >= -200, + 'navigationStart should be set after reload request. ' + + 'Measured difference: ' + diff + ' (should be positive)'); + SimpleTest.finish(); + } + } + function reload() { + var frame = frames[0]; + ok(navStart == frame.performance.timing.navigationStart, + 'navigationStart should not change when frame loads.'); + beforeReload = Date.now(); + frame.location.reload(); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=570341">Mozilla Bug 570341</a> +<div id="frames"> +<iframe name="frame0" id="frame0" src="bug691547_frame.html" onload="onContentLoad()"></iframe> +</div> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug694612.html b/system/docshell/test/test_bug694612.html new file mode 100644 index 000000000..85c240146 --- /dev/null +++ b/system/docshell/test/test_bug694612.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=694612 +--> +<head> + <title>Test for Bug 694612</title> + <script type="application/javascript" 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=694612">Mozilla Bug 694612</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 694612 **/ +SimpleTest.waitForExplicitFinish(); +</script> +<object type="text/html" + data="data:text/html,<script>parent.isnot(performance, null, 'should have performance API in an <object>'); parent.SimpleTest.finish();</script>"> +</object> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug703855.html b/system/docshell/test/test_bug703855.html new file mode 100644 index 000000000..0804f70bc --- /dev/null +++ b/system/docshell/test/test_bug703855.html @@ -0,0 +1,79 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=703855 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 703855</title> + <script type="application/javascript" 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=703855">Mozilla Bug 703855</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="f" src="file_bug703855.html"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 703855 **/ + +SimpleTest.waitForExplicitFinish(); + +var timingAttributes = [ + 'connectEnd', + 'connectStart', + 'domComplete', + 'domContentLoadedEventEnd', + 'domContentLoadedEventStart', + 'domInteractive', + 'domLoading', + 'domainLookupEnd', + 'domainLookupStart', + 'fetchStart', + 'loadEventEnd', + 'loadEventStart', + 'navigationStart', + 'redirectEnd', + 'redirectStart', + 'requestStart', + 'responseEnd', + 'responseStart', + 'unloadEventEnd', + 'unloadEventStart' +]; +var originalTiming = {}; + +function runTest() { + var timing = $("f").contentWindow.performance.timing; + for (i in timingAttributes) { + originalTiming[timingAttributes[i]] = timing[timingAttributes[i]]; + } + + var doc = $("f").contentDocument; + doc.open(); + doc.write("<!DOCTYPE html>"); + doc.close(); + + SimpleTest.executeSoon(function() { + var newTiming = $("f").contentWindow.performance.timing; + for (var i in timingAttributes) { + is(timing[timingAttributes[i]], originalTiming[timingAttributes[i]], + "document.open should not affect value of " + timingAttributes[i]); + } + SimpleTest.finish(); + }); +} + +addLoadEvent(function() { + SimpleTest.executeSoon(runTest); +}); + + + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug713825.html b/system/docshell/test/test_bug713825.html new file mode 100644 index 000000000..5f30dd0b6 --- /dev/null +++ b/system/docshell/test/test_bug713825.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=713825 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 713825</title> + <script type="application/javascript" 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=713825">Mozilla Bug 713825</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** + * Test for Bug 713825 + * test that nsIDocCharset still works backward compatibly + */ +var Ci = SpecialPowers.Ci; +var docShell = SpecialPowers.wrap(window).QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebNavigation). + QueryInterface(Ci.nsIDocShell); + +var charset1 = docShell.charset; +var charset2 = docShell.QueryInterface(Ci.nsIDocCharset).charset; +var charset3 = SpecialPowers.wrap(window).QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIDocCharset).charset; + +/* if we get here without throwing and the three charsets are equal, all is OK */ +is(charset1, charset2, "QI'd nsIDocCharset.charset should equal nsIDocShell.charset"); +is(charset1, charset3, "getInterface'd nsIDocCharset.charset should equal nsIDocShell.charset"); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_bug728939.html b/system/docshell/test/test_bug728939.html new file mode 100644 index 000000000..c29f18668 --- /dev/null +++ b/system/docshell/test/test_bug728939.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=728939 +--> +<head> + <title>Test for Bug 728939</title> + <script type="application/javascript" 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=728939">Mozilla Bug 728939</a> + +<script type="application/javascript;version=1.7"> + +SimpleTest.waitForExplicitFinish(); + +// Called when the popup finishes loading. +function popupLoaded() { + popup.location.hash = '#foo'; + is(popup.document.URL, popup.location.href, 'After hashchange.'); + + popup.history.pushState('', '', 'bar'); + is(popup.document.URL, popup.location.href, 'After pushState.'); + + popup.history.replaceState('', '', 'baz'); + is(popup.document.URL, popup.location.href, 'After replaceState.'); + + popup.close(); + SimpleTest.finish(); +} + +var popup = window.open('file_bug728939.html'); + +</script> +</body> +</html> diff --git a/system/docshell/test/test_bug797909.html b/system/docshell/test/test_bug797909.html new file mode 100644 index 000000000..a47aa0c6d --- /dev/null +++ b/system/docshell/test/test_bug797909.html @@ -0,0 +1,66 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=797909 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 797909</title> + <script type="application/javascript" 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=797909">Mozilla Bug 797909</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + /** Test for Bug 797909 **/ + + SimpleTest.waitForExplicitFinish(); + + function runTest() { + iframe = document.getElementById("ifr"); + try { + var iframeDoc = iframe.contentWindow.document; + ok(false, "Should have thrown an exception"); + } catch (ex) { + ok(true, "Got an exception"); + } + + iframe = document.createElement("iframe"); + // set sandbox attribute + iframe.sandbox = "allow-scripts"; + // and then insert into the doc + document.body.appendChild(iframe); + + try { + var iframeDoc = iframe.contentWindow.document; + ok(false, "Should have thrown an exception"); + } catch (ex) { + ok(true, "Got an exception"); + } + + iframe = document.createElement("iframe"); + // set sandbox attribute + iframe.sandbox = "allow-same-origin"; + // and then insert into the doc + document.body.appendChild(iframe); + + try { + var iframeDoc = iframe.contentWindow.document; + ok(true, "Shouldn't have thrown an exception"); + } catch (ex) { + ok(false, "Got an unexpected exception"); + } + + SimpleTest.finish(); + } + +</script> +</pre> +<iframe id="ifr" sandbox = "allow-scripts"></iframe> +</body> +</html> diff --git a/system/docshell/test/test_forceinheritprincipal_overrule_owner.html b/system/docshell/test/test_forceinheritprincipal_overrule_owner.html new file mode 100644 index 000000000..b3a48d7ea --- /dev/null +++ b/system/docshell/test/test_forceinheritprincipal_overrule_owner.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<script type="text/javascript"> + +var channel = SpecialPowers.wrap(document).docShell.currentDocumentChannel; +var loadInfo = channel.loadInfo; + +// 1) perform some sanity checks +var triggeringPrincipal = channel.loadInfo.triggeringPrincipal.URI.asciiSpec; +var loadingPrincipal = channel.loadInfo.loadingPrincipal.URI.asciiSpec; +var principalToInherit = channel.loadInfo.principalToInherit.URI.asciiSpec; + +ok(triggeringPrincipal.startsWith("http://mochi.test:8888/"), + "initial triggeringPrincipal correct"); +ok(loadingPrincipal.startsWith("http://mochi.test:8888/"), + "initial loadingPrincipal correct"); +ok(principalToInherit.startsWith("http://mochi.test:8888/"), + "initial principalToInherit correct"); + +// reset principals on the loadinfo +loadInfo.resetPrincipalsToNullPrincipal(); + +// 2) verify loadInfo contains the correct principals +var triggeringPrincipal = channel.loadInfo.triggeringPrincipal; +var loadingPrincipal = channel.loadInfo.loadingPrincipal; +var principalToInherit = channel.loadInfo.principalToInherit; + +ok(triggeringPrincipal.isNullPrincipal, + "triggeringPrincipal after resetting correct"); +ok(loadingPrincipal.isNullPrincipal, + "triggeringPrincipal after resetting correct"); +ok(triggeringPrincipal.isNullPrincipal, + "principalToInherit after resetting correct"); + +// 3) verify that getChannelResultPrincipal returns right principal +var resultPrincipal = SpecialPowers.Services.scriptSecurityManager + .getChannelResultPrincipal(channel); + +ok(resultPrincipal.isNullPrincipal, + "resultPrincipal after resetting correct"); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_framedhistoryframes.html b/system/docshell/test/test_framedhistoryframes.html new file mode 100644 index 000000000..916a6229d --- /dev/null +++ b/system/docshell/test/test_framedhistoryframes.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=602256 +--> +<head> + <title>Test for Bug 602256</title> + <script type="application/javascript" 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=602256">Mozilla Bug 602256</a> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 602256 **/ + +SimpleTest.waitForExplicitFinish(); +var win = window.open("file_framedhistoryframes.html"); + +function done() { + win.close(); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_pushState_after_document_open.html b/system/docshell/test/test_pushState_after_document_open.html new file mode 100644 index 000000000..51ba1050c --- /dev/null +++ b/system/docshell/test/test_pushState_after_document_open.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=957479 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 957479</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 957479 **/ + SimpleTest.waitForExplicitFinish(); + // Child needs to invoke us, otherwise our onload will fire before the child + // has done the write/close bit. + onmessage = function doTest() { + is(frames[0].location.pathname, "/tests/docshell/test/file_pushState_after_document_open.html", "Should have the right path here"); + is(frames[0].location.hash, "", "Should have the right hash here"); + frames[0].history.pushState({}, '', frames[0].document.URL + "#foopy"); + is(frames[0].location.pathname, "/tests/docshell/test/file_pushState_after_document_open.html", "Pathname should not have changed"); + is(frames[0].location.hash, "#foopy", "Hash should have changed"); + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=957479">Mozilla Bug 957479</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe src="file_pushState_after_document_open.html"></iframe> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/system/docshell/test/test_triggeringprincipal_location_seturi.html b/system/docshell/test/test_triggeringprincipal_location_seturi.html new file mode 100644 index 000000000..3b0c7bac5 --- /dev/null +++ b/system/docshell/test/test_triggeringprincipal_location_seturi.html @@ -0,0 +1,102 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<script type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +const SAME_ORIGIN_URI = "http://mochi.test:8888/tests/docshell/test/dummy_page.html"; +const CROSS_ORIGIN_URI = "http://example.com/tests/docshell/test/dummy_page.html"; +const NUMBER_OF_TESTS = 3; +let testCounter = 0; + +function checkFinish() { + testCounter++; + if (testCounter < NUMBER_OF_TESTS) { + return; + } + SimpleTest.finish(); +} + +// ---- test 1 ---- + +let myFrame1 = document.createElement("iframe"); +myFrame1.src = SAME_ORIGIN_URI; +myFrame1.addEventListener("load", checkLoadFrame1); +document.documentElement.appendChild(myFrame1); + +function checkLoadFrame1() { + myFrame1.removeEventListener('load', checkLoadFrame1, false); + // window.location.href is no longer cross-origin accessible in gecko. + is(SpecialPowers.wrap(myFrame1.contentWindow).location.href, SAME_ORIGIN_URI, + "initial same origin dummy loaded into frame1"); + + SpecialPowers.wrap(myFrame1.contentWindow).location.hash = "#bar"; + is(SpecialPowers.wrap(myFrame1.contentWindow).location.href, SAME_ORIGIN_URI + "#bar", + "initial same origin dummy#bar loaded into iframe1"); + + myFrame1.addEventListener("load", checkNavFrame1); + myFrame1.src = CROSS_ORIGIN_URI; +} + +function checkNavFrame1() { + myFrame1.removeEventListener('load', checkNavFrame1, false); + is(SpecialPowers.wrap(myFrame1.contentWindow).location.href, CROSS_ORIGIN_URI, + "cross origin dummy loaded into frame1"); + + myFrame1.addEventListener("load", checkBackNavFrame1); + myFrame1.src = SAME_ORIGIN_URI + "#bar"; +} + +function checkBackNavFrame1() { + myFrame1.removeEventListener('load', checkBackNavFrame1, false); + is(SpecialPowers.wrap(myFrame1.contentWindow).location.href, SAME_ORIGIN_URI + "#bar", + "navagiating back to same origin dummy for frame1"); + checkFinish(); +} + +// ---- test 2 ---- + +let myFrame2 = document.createElement("iframe"); +myFrame2.src = "about:blank"; +myFrame2.addEventListener("load", checkLoadFrame2); +document.documentElement.appendChild(myFrame2); + +function checkLoadFrame2() { + myFrame2.removeEventListener('load', checkLoadFrame2, false); + is(SpecialPowers.wrap(myFrame2.contentWindow).location.href, "about:blank", + "initial about:blank frame loaded"); + + myFrame2.contentWindow.location.hash = "#foo"; + is(SpecialPowers.wrap(myFrame2.contentWindow).location.href, "about:blank#foo", + "about:blank#foo frame loaded"); + + myFrame2.addEventListener('load', checkHistoryFrame2); + myFrame2.src = "about:blank"; +} + +function checkHistoryFrame2() { + myFrame2.removeEventListener('load', checkHistoryFrame2, false); + is(SpecialPowers.wrap(myFrame2.contentWindow).location.href, "about:blank", + "about:blank frame loaded again"); + checkFinish(); +} + +// ---- test 3 ---- + +let myFrame3 = document.createElement("frame"); +document.documentElement.appendChild(myFrame3); +myFrame3.contentWindow.location.hash = "#foo"; + +is(myFrame3.contentWindow.location.href, "about:blank#foo", + "created history entry with about:blank#foo"); +checkFinish(); + +</script> +</body> +</html> diff --git a/system/docshell/test/test_windowedhistoryframes.html b/system/docshell/test/test_windowedhistoryframes.html new file mode 100644 index 000000000..d27987beb --- /dev/null +++ b/system/docshell/test/test_windowedhistoryframes.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=602256 +--> +<head> + <title>Test for Bug 602256</title> + <script type="application/javascript" 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=602256">Mozilla Bug 602256</a> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 602256 **/ + +SimpleTest.waitForExplicitFinish(); + +function done() { + subWin.close(); + SimpleTest.finish(); +} + +var subWin = window.open("historyframes.html", "_blank"); + +</script> +</pre> +</body> +</html> diff --git a/system/docshell/test/unit/head_docshell.js b/system/docshell/test/unit/head_docshell.js new file mode 100644 index 000000000..a5c7546c0 --- /dev/null +++ b/system/docshell/test/unit/head_docshell.js @@ -0,0 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cr = Components.results; + +var dirSvc = Cc["@mozilla.org/file/directory_service;1"]. + getService(Ci.nsIProperties); +var profileDir = do_get_profile(); diff --git a/system/docshell/test/unit/test_bug414201_jfif.js b/system/docshell/test/unit/test_bug414201_jfif.js new file mode 100644 index 000000000..6a689ec08 --- /dev/null +++ b/system/docshell/test/unit/test_bug414201_jfif.js @@ -0,0 +1,27 @@ +/* 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/. */ + +/* + * Test for bug 414201 + */ + +function run_test() +{ + var ms = Components.classes["@mozilla.org/mime;1"].getService(Components.interfaces.nsIMIMEService); + + /* Test a few common image types to make sure that they get the right extension */ + var types = { + "image/jpeg": ["jpg", "jpeg"], /* accept either */ + "image/gif": ["gif"], + "image/png": ["png"] + }; + + /* Check whether the primary extension is what we'd expect */ + for (var mimetype in types) { + var exts = types[mimetype]; + var primary = ms.getFromTypeAndExtension(mimetype, null).primaryExtension.toLowerCase(); + + do_check_true (exts.indexOf(primary) != -1); + } +} diff --git a/system/docshell/test/unit/test_bug442584.js b/system/docshell/test/unit/test_bug442584.js new file mode 100644 index 000000000..174bdb7e3 --- /dev/null +++ b/system/docshell/test/unit/test_bug442584.js @@ -0,0 +1,30 @@ +var prefetch = Cc["@mozilla.org/prefetch-service;1"]. + getService(Ci.nsIPrefetchService); +var ios = Cc["@mozilla.org/network/io-service;1"]. + getService(Ci.nsIIOService); +var prefs = Cc["@mozilla.org/preferences-service;1"]. + getService(Ci.nsIPrefBranch); + +function run_test() { + // Fill up the queue + prefs.setBoolPref("network.prefetch-next", true); + for (var i = 0; i < 5; i++) { + var uri = ios.newURI("http://localhost/" + i, null, null); + prefetch.prefetchURI(uri, uri, null, true); + } + + // Make sure the queue has items in it... + do_check_true(prefetch.hasMoreElements()); + + // Now disable the pref to force the queue to empty... + prefs.setBoolPref("network.prefetch-next", false); + do_check_false(prefetch.hasMoreElements()); + + // Now reenable the pref, and add more items to the queue. + prefs.setBoolPref("network.prefetch-next", true); + for (var i = 0; i < 5; i++) { + var uri = ios.newURI("http://localhost/" + i, null, null); + prefetch.prefetchURI(uri, uri, null, true); + } + do_check_true(prefetch.hasMoreElements()); +} diff --git a/system/docshell/test/unit/test_nsDefaultURIFixup.js b/system/docshell/test/unit/test_nsDefaultURIFixup.js new file mode 100644 index 000000000..371bdea17 --- /dev/null +++ b/system/docshell/test/unit/test_nsDefaultURIFixup.js @@ -0,0 +1,93 @@ +var urifixup = Cc["@mozilla.org/docshell/urifixup;1"]. + getService(Ci.nsIURIFixup); +var prefs = Cc["@mozilla.org/preferences-service;1"]. + getService(Ci.nsIPrefBranch); + +var pref = "browser.fixup.typo.scheme"; + +var data = [ + { + // ttp -> http. + wrong: 'ttp://www.example.com/', + fixed: 'http://www.example.com/', + }, + { + // ttps -> https. + wrong: 'ttps://www.example.com/', + fixed: 'https://www.example.com/', + }, + { + // tps -> https. + wrong: 'tps://www.example.com/', + fixed: 'https://www.example.com/', + }, + { + // ps -> https. + wrong: 'ps://www.example.com/', + fixed: 'https://www.example.com/', + }, + { + // ile -> file. + wrong: 'ile:///this/is/a/test.html', + fixed: 'file:///this/is/a/test.html', + }, + { + // le -> file. + wrong: 'le:///this/is/a/test.html', + fixed: 'file:///this/is/a/test.html', + }, + { + // Valid should not be changed. + wrong: 'https://example.com/this/is/a/test.html', + fixed: 'https://example.com/this/is/a/test.html', + }, + { + // Unmatched should not be changed. + wrong: 'whatever://this/is/a/test.html', + fixed: 'whatever://this/is/a/test.html', + }, +]; + +var len = data.length; + +function run_test() { + run_next_test(); +} + +// Make sure we fix what needs fixing when there is no pref set. +add_task(function test_unset_pref_fixes_typos() { + prefs.clearUserPref(pref); + for (let i = 0; i < len; ++i) { + let item = data[i]; + let result = + urifixup.createFixupURI(item.wrong, + urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS).spec; + do_check_eq(result, item.fixed); + } +}); + +// Make sure we don't do anything when the pref is explicitly +// set to false. +add_task(function test_false_pref_keeps_typos() { + prefs.setBoolPref(pref, false); + for (let i = 0; i < len; ++i) { + let item = data[i]; + let result = + urifixup.createFixupURI(item.wrong, + urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS).spec; + do_check_eq(result, item.wrong); + } +}); + +// Finally, make sure we still fix what needs fixing if the pref is +// explicitly set to true. +add_task(function test_true_pref_fixes_typos() { + prefs.setBoolPref(pref, true); + for (let i = 0; i < len; ++i) { + let item = data[i]; + let result = + urifixup.createFixupURI(item.wrong, + urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS).spec; + do_check_eq(result, item.fixed); + } +}); diff --git a/system/docshell/test/unit/test_nsDefaultURIFixup_info.js b/system/docshell/test/unit/test_nsDefaultURIFixup_info.js new file mode 100644 index 000000000..748aaab93 --- /dev/null +++ b/system/docshell/test/unit/test_nsDefaultURIFixup_info.js @@ -0,0 +1,622 @@ +var urifixup = Cc["@mozilla.org/docshell/urifixup;1"]. + getService(Ci.nsIURIFixup); + +Components.utils.import("resource://gre/modules/Services.jsm"); + +var prefList = ["browser.fixup.typo.scheme", "keyword.enabled", + "browser.fixup.domainwhitelist.whitelisted"]; +for (let pref of prefList) { + Services.prefs.setBoolPref(pref, true); +} + +const kSearchEngineID = "test_urifixup_search_engine"; +const kSearchEngineURL = "http://www.example.org/?search={searchTerms}"; +Services.search.addEngineWithDetails(kSearchEngineID, "", "", "", "get", + kSearchEngineURL); + +var oldDefaultEngine = Services.search.defaultEngine; +Services.search.defaultEngine = Services.search.getEngineByName(kSearchEngineID); + +var selectedName = Services.search.defaultEngine.name; +do_check_eq(selectedName, kSearchEngineID); + +const kForceHostLookup = "browser.fixup.dns_first_for_single_words"; +do_register_cleanup(function() { + if (oldDefaultEngine) { + Services.search.defaultEngine = oldDefaultEngine; + } + let engine = Services.search.getEngineByName(kSearchEngineID); + if (engine) { + Services.search.removeEngine(engine); + } + Services.prefs.clearUserPref("keyword.enabled"); + Services.prefs.clearUserPref("browser.fixup.typo.scheme"); + Services.prefs.clearUserPref(kForceHostLookup); +}); + +var flagInputs = [ + urifixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP, + urifixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI, + urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS, +]; + +flagInputs.concat([ + flagInputs[0] | flagInputs[1], + flagInputs[1] | flagInputs[2], + flagInputs[0] | flagInputs[2], + flagInputs[0] | flagInputs[1] | flagInputs[2] +]); + +/* + The following properties are supported for these test cases: + { + input: "", // Input string, required + fixedURI: "", // Expected fixedURI + alternateURI: "", // Expected alternateURI + keywordLookup: false, // Whether a keyword lookup is expected + protocolChange: false, // Whether a protocol change is expected + inWhitelist: false, // Whether the input host is in the whitelist + affectedByDNSForSingleHosts: false, // Whether the input host could be a host, but is normally assumed to be a keyword query + } +*/ +var testcases = [ { + input: "http://www.mozilla.org", + fixedURI: "http://www.mozilla.org/", + }, { + input: "http://127.0.0.1/", + fixedURI: "http://127.0.0.1/", + }, { + input: "file:///foo/bar", + fixedURI: "file:///foo/bar", + }, { + input: "://www.mozilla.org", + fixedURI: "http://www.mozilla.org/", + protocolChange: true, + }, { + input: "www.mozilla.org", + fixedURI: "http://www.mozilla.org/", + protocolChange: true, + }, { + input: "http://mozilla/", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + }, { + input: "http://test./", + fixedURI: "http://test./", + alternateURI: "http://www.test./", + }, { + input: "127.0.0.1", + fixedURI: "http://127.0.0.1/", + protocolChange: true, + }, { + input: "1.2.3.4/", + fixedURI: "http://1.2.3.4/", + protocolChange: true, + }, { + input: "1.2.3.4/foo", + fixedURI: "http://1.2.3.4/foo", + protocolChange: true, + }, { + input: "1.2.3.4:8000", + fixedURI: "http://1.2.3.4:8000/", + protocolChange: true, + }, { + input: "1.2.3.4:8000/", + fixedURI: "http://1.2.3.4:8000/", + protocolChange: true, + }, { + input: "1.2.3.4:8000/foo", + fixedURI: "http://1.2.3.4:8000/foo", + protocolChange: true, + }, { + input: "192.168.10.110", + fixedURI: "http://192.168.10.110/", + protocolChange: true, + }, { + input: "192.168.10.110/123", + fixedURI: "http://192.168.10.110/123", + protocolChange: true, + }, { + input: "192.168.10.110/123foo", + fixedURI: "http://192.168.10.110/123foo", + protocolChange: true, + }, { + input: "192.168.10.110:1234/123", + fixedURI: "http://192.168.10.110:1234/123", + protocolChange: true, + }, { + input: "192.168.10.110:1234/123foo", + fixedURI: "http://192.168.10.110:1234/123foo", + protocolChange: true, + }, { + input: "1.2.3", + fixedURI: "http://1.2.0.3/", + protocolChange: true, + }, { + input: "1.2.3/", + fixedURI: "http://1.2.0.3/", + protocolChange: true, + }, { + input: "1.2.3/foo", + fixedURI: "http://1.2.0.3/foo", + protocolChange: true, + }, { + input: "1.2.3/123", + fixedURI: "http://1.2.0.3/123", + protocolChange: true, + }, { + input: "1.2.3:8000", + fixedURI: "http://1.2.0.3:8000/", + protocolChange: true, + }, { + input: "1.2.3:8000/", + fixedURI: "http://1.2.0.3:8000/", + protocolChange: true, + }, { + input: "1.2.3:8000/foo", + fixedURI: "http://1.2.0.3:8000/foo", + protocolChange: true, + }, { + input: "1.2.3:8000/123", + fixedURI: "http://1.2.0.3:8000/123", + protocolChange: true, + }, { + input: "http://1.2.3", + fixedURI: "http://1.2.0.3/", + }, { + input: "http://1.2.3/", + fixedURI: "http://1.2.0.3/", + }, { + input: "http://1.2.3/foo", + fixedURI: "http://1.2.0.3/foo", + }, { + input: "[::1]", + fixedURI: "http://[::1]/", + alternateURI: "http://[::1]/", + protocolChange: true, + }, { + input: "[::1]/", + fixedURI: "http://[::1]/", + alternateURI: "http://[::1]/", + protocolChange: true, + }, { + input: "[::1]:8000", + fixedURI: "http://[::1]:8000/", + alternateURI: "http://[::1]:8000/", + protocolChange: true, + }, { + input: "[::1]:8000/", + fixedURI: "http://[::1]:8000/", + alternateURI: "http://[::1]:8000/", + protocolChange: true, + }, { + input: "[[::1]]/", + keywordLookup: true, + protocolChange: true, + }, { + input: "[fe80:cd00:0:cde:1257:0:211e:729c]", + fixedURI: "http://[fe80:cd00:0:cde:1257:0:211e:729c]/", + alternateURI: "http://[fe80:cd00:0:cde:1257:0:211e:729c]/", + protocolChange: true, + }, { + input: "[64:ff9b::8.8.8.8]", + fixedURI: "http://[64:ff9b::8.8.8.8]/", + protocolChange: true + }, { + input: "[64:ff9b::8.8.8.8]/~moz", + fixedURI: "http://[64:ff9b::8.8.8.8]/~moz", + protocolChange: true + }, { + input: "[::1][::1]", + keywordLookup: true, + protocolChange: true + }, { + input: "[::1][100", + fixedURI: null, + alternateURI: null, + keywordLookup: true, + protocolChange: true + }, { + input: "[::1]]", + keywordLookup: true, + protocolChange: true + }, { + input: "1234", + fixedURI: "http://0.0.4.210/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "host/foo.txt", + fixedURI: "http://host/foo.txt", + alternateURI: "http://www.host.com/foo.txt", + protocolChange: true, + }, { + input: "mozilla", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "test.", + fixedURI: "http://test./", + alternateURI: "http://www.test./", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: ".test", + fixedURI: "http://.test/", + alternateURI: "http://www..test/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "mozilla is amazing", + keywordLookup: true, + protocolChange: true, + }, { + input: "search ?mozilla", + keywordLookup: true, + protocolChange: true, + }, { + input: "mozilla .com", + keywordLookup: true, + protocolChange: true, + }, { + input: "what if firefox?", + keywordLookup: true, + protocolChange: true, + }, { + input: "london's map", + keywordLookup: true, + protocolChange: true, + }, { + input: "mozilla ", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: " mozilla ", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "mozilla \\", + keywordLookup: true, + protocolChange: true, + }, { + input: "mozilla \\ foo.txt", + keywordLookup: true, + protocolChange: true, + }, { + input: "mozilla \\\r foo.txt", + keywordLookup: true, + protocolChange: true, + }, { + input: "mozilla\n", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "mozilla \r\n", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "moz\r\nfirefox\nos\r", + fixedURI: "http://mozfirefoxos/", + alternateURI: "http://www.mozfirefoxos.com/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "moz\r\n firefox\n", + keywordLookup: true, + protocolChange: true, + }, { + input: "", + keywordLookup: true, + protocolChange: true, + }, { + input: "[]", + keywordLookup: true, + protocolChange: true, + }, { + input: "http://whitelisted/", + fixedURI: "http://whitelisted/", + alternateURI: "http://www.whitelisted.com/", + inWhitelist: true, + }, { + input: "café.local", + fixedURI: "http://café.local/", + alternateURI: "http://www.café.local/", + protocolChange: true + }, { + input: "47.6182,-122.830", + fixedURI: "http://47.6182,-122.830/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "-47.6182,-23.51", + fixedURI: "http://-47.6182,-23.51/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "-22.14,23.51-", + fixedURI: "http://-22.14,23.51-/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "32.7", + fixedURI: "http://32.0.0.7/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "5+2", + fixedURI: "http://5+2/", + alternateURI: "http://www.5+2.com/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "5/2", + fixedURI: "http://0.0.0.5/2", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: "moz ?.::%27", + keywordLookup: true, + protocolChange: true + }, { + input: "mozilla.com/?q=search", + fixedURI: "http://mozilla.com/?q=search", + alternateURI: "http://www.mozilla.com/?q=search", + protocolChange: true + }, { + input: "mozilla.com?q=search", + fixedURI: "http://mozilla.com/?q=search", + alternateURI: "http://www.mozilla.com/?q=search", + protocolChange: true + }, { + input: "mozilla.com ?q=search", + keywordLookup: true, + protocolChange: true + }, { + input: "mozilla.com.?q=search", + fixedURI: "http://mozilla.com./?q=search", + protocolChange: true + }, { + input: "mozilla.com'?q=search", + fixedURI: "http://mozilla.com'/?q=search", + alternateURI: "http://www.mozilla.com'/?q=search", + protocolChange: true + }, { + input: "mozilla.com':search", + keywordLookup: true, + protocolChange: true + }, { + input: "[mozilla]", + keywordLookup: true, + protocolChange: true + }, { + input: "':?", + fixedURI: "http://'/?", + alternateURI: "http://www.'.com/?", + keywordLookup: true, + protocolChange: true, + }, { + input: "a?.com", + fixedURI: "http://a/?.com", + alternateURI: "http://www.a.com/?.com", + protocolChange: true, + }, { + input: "?'.com", + keywordLookup: true, + protocolChange: true, + }, { + input: "' ?.com", + keywordLookup: true, + protocolChange: true + }, { + input: "?mozilla", + keywordLookup: true, + protocolChange: true, + }, { + input: "??mozilla", + keywordLookup: true, + protocolChange: true, + }, { + input: "mozilla/", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + protocolChange: true, + }, { + input: "mozilla", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + protocolChange: true, + keywordLookup: true, + affectedByDNSForSingleHosts: true, + }, { + input: "mozilla5/2", + fixedURI: "http://mozilla5/2", + alternateURI: "http://www.mozilla5.com/2", + protocolChange: true, + }, { + input: "mozilla/foo", + fixedURI: "http://mozilla/foo", + alternateURI: "http://www.mozilla.com/foo", + protocolChange: true, + }, { + input: "mozilla\\", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByDNSForSingleHosts: true, + }, { + input: " \t mozilla.org/\t \t ", + fixedURI: "http://mozilla.org/", + alternateURI: "http://www.mozilla.org/", + protocolChange: true, + }, { + input: " moz\ti\tlla.org ", + keywordLookup: true, + }]; + +if (Services.appinfo.OS.toLowerCase().startsWith("win")) { + testcases.push({ + input: "C:\\some\\file.txt", + fixedURI: "file:///C:/some/file.txt", + protocolChange: true, + }); + testcases.push({ + input: "//mozilla", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + protocolChange: true, + }); +} else { + testcases.push({ + input: "/some/file.txt", + fixedURI: "file:///some/file.txt", + protocolChange: true, + }); + testcases.push({ + input: "//mozilla", + fixedURI: "file:////mozilla", + protocolChange: true, + }); +} + +function sanitize(input) { + return input.replace(/\r|\n/g, "").trim(); +} + + +var gSingleWordHostLookup = false; +function run_test() { + // Only keywordlookup things should be affected by requiring a DNS lookup for single-word hosts: + do_print("Check only keyword lookup testcases should be affected by requiring DNS for single hosts"); + let affectedTests = testcases.filter(t => !t.keywordLookup && t.affectedByDNSForSingleHosts); + if (affectedTests.length) { + for (let testcase of affectedTests) { + do_print("Affected: " + testcase.input); + } + } + do_check_eq(affectedTests.length, 0); + do_single_test_run(); + gSingleWordHostLookup = true; + do_single_test_run(); +} + +function do_single_test_run() { + Services.prefs.setBoolPref(kForceHostLookup, gSingleWordHostLookup); + + let relevantTests = gSingleWordHostLookup ? testcases.filter(t => t.keywordLookup) : + testcases; + + for (let { input: testInput, + fixedURI: expectedFixedURI, + alternateURI: alternativeURI, + keywordLookup: expectKeywordLookup, + protocolChange: expectProtocolChange, + inWhitelist: inWhitelist, + affectedByDNSForSingleHosts: affectedByDNSForSingleHosts, + } of relevantTests) { + + // Explicitly force these into a boolean + expectKeywordLookup = !!expectKeywordLookup; + expectProtocolChange = !!expectProtocolChange; + inWhitelist = !!inWhitelist; + affectedByDNSForSingleHosts = !!affectedByDNSForSingleHosts; + + expectKeywordLookup = expectKeywordLookup && (!affectedByDNSForSingleHosts || !gSingleWordHostLookup); + + for (let flags of flagInputs) { + let info; + let fixupURIOnly = null; + try { + fixupURIOnly = urifixup.createFixupURI(testInput, flags); + } catch (ex) { + do_print("Caught exception: " + ex); + do_check_eq(expectedFixedURI, null); + } + + try { + info = urifixup.getFixupURIInfo(testInput, flags); + } catch (ex) { + // Both APIs should return an error in the same cases. + do_print("Caught exception: " + ex); + do_check_eq(expectedFixedURI, null); + do_check_eq(fixupURIOnly, null); + continue; + } + + do_print("Checking \"" + testInput + "\" with flags " + flags + + " (host lookup for single words: " + (gSingleWordHostLookup ? "yes" : "no") + ")"); + + // Both APIs should then also be using the same spec. + do_check_eq(!!fixupURIOnly, !!info.preferredURI); + if (fixupURIOnly) + do_check_eq(fixupURIOnly.spec, info.preferredURI.spec); + + let isFileURL = expectedFixedURI && expectedFixedURI.startsWith("file"); + + // Check the fixedURI: + let makeAlternativeURI = flags & urifixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI; + if (makeAlternativeURI && alternativeURI != null) { + do_check_eq(info.fixedURI.spec, alternativeURI); + } else { + do_check_eq(info.fixedURI && info.fixedURI.spec, expectedFixedURI); + } + + // Check booleans on input: + let couldDoKeywordLookup = flags & urifixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP; + do_check_eq(!!info.keywordProviderName, couldDoKeywordLookup && expectKeywordLookup); + do_check_eq(info.fixupChangedProtocol, expectProtocolChange); + do_check_eq(info.fixupCreatedAlternateURI, makeAlternativeURI && alternativeURI != null); + + // Check the preferred URI + if (couldDoKeywordLookup) { + if (expectKeywordLookup) { + if (!inWhitelist) { + let urlparamInput = encodeURIComponent(sanitize(testInput)).replace(/%20/g, "+"); + // If the input starts with `?`, then info.preferredURI.spec will omit it + // In order to test this behaviour, remove `?` only if it is the first character + if (urlparamInput.startsWith("%3F")) { + urlparamInput = urlparamInput.replace("%3F", ""); + } + let searchURL = kSearchEngineURL.replace("{searchTerms}", urlparamInput); + let spec = info.preferredURI.spec.replace(/%27/g, "'"); + do_check_eq(spec, searchURL); + } else { + do_check_eq(info.preferredURI, null); + } + } else { + do_check_eq(info.preferredURI.spec, info.fixedURI.spec); + } + } else { + // In these cases, we should never be doing a keyword lookup and + // the fixed URI should be preferred: + do_check_eq(info.preferredURI.spec, info.fixedURI.spec); + } + do_check_eq(sanitize(testInput), info.originalInput); + } + } +} diff --git a/system/docshell/test/unit/test_nsDefaultURIFixup_search.js b/system/docshell/test/unit/test_nsDefaultURIFixup_search.js new file mode 100644 index 000000000..c84452b5d --- /dev/null +++ b/system/docshell/test/unit/test_nsDefaultURIFixup_search.js @@ -0,0 +1,117 @@ +var urifixup = Cc["@mozilla.org/docshell/urifixup;1"]. + getService(Ci.nsIURIFixup); +Components.utils.import("resource://gre/modules/Services.jsm"); +Components.utils.import("resource://gre/modules/AppConstants.jsm"); + +Services.prefs.setBoolPref("keyword.enabled", true); + +const kSearchEngineID = "test_urifixup_search_engine"; +const kSearchEngineURL = "http://www.example.org/?search={searchTerms}"; +Services.search.addEngineWithDetails(kSearchEngineID, "", "", "", "get", + kSearchEngineURL); + +var oldDefaultEngine = Services.search.defaultEngine; +Services.search.defaultEngine = Services.search.getEngineByName(kSearchEngineID); + +var selectedName = Services.search.defaultEngine.name; +do_check_eq(selectedName, kSearchEngineID); + +do_register_cleanup(function() { + if (oldDefaultEngine) { + Services.search.defaultEngine = oldDefaultEngine; + } + let engine = Services.search.getEngineByName(kSearchEngineID); + if (engine) { + Services.search.removeEngine(engine); + } + Services.prefs.clearUserPref("keyword.enabled"); +}); + +var isWin = AppConstants.platform == "win"; + +var data = [ + { + // Valid should not be changed. + wrong: 'https://example.com/this/is/a/test.html', + fixed: 'https://example.com/this/is/a/test.html', + }, + { + // Unrecognized protocols should be changed. + wrong: 'whatever://this/is/a/test.html', + fixed: kSearchEngineURL.replace("{searchTerms}", encodeURIComponent('whatever://this/is/a/test.html')), + }, + + // The following tests check that when a user:password is present in the URL + // `user:` isn't treated as an unknown protocol thus leaking the user and + // password to the search engine. + { + wrong: 'user:pass@example.com/this/is/a/test.html', + fixed: 'http://user:pass@example.com/this/is/a/test.html', + }, + { + wrong: 'user@example.com:8080/this/is/a/test.html', + fixed: 'http://user@example.com:8080/this/is/a/test.html', + }, + { + wrong: 'https:pass@example.com/this/is/a/test.html', + fixed: 'https://pass@example.com/this/is/a/test.html', + }, + { + wrong: 'user:pass@example.com:8080/this/is/a/test.html', + fixed: 'http://user:pass@example.com:8080/this/is/a/test.html', + }, + { + wrong: 'http:user:pass@example.com:8080/this/is/a/test.html', + fixed: 'http://user:pass@example.com:8080/this/is/a/test.html', + }, + { + wrong: 'ttp:user:pass@example.com:8080/this/is/a/test.html', + fixed: 'http://user:pass@example.com:8080/this/is/a/test.html', + }, + { + wrong: 'gobbledygook:user:pass@example.com:8080/this/is/a/test.html', + fixed: 'http://gobbledygook:user%3Apass@example.com:8080/this/is/a/test.html', + }, + { + wrong: 'user:@example.com:8080/this/is/a/test.html', + fixed: 'http://user@example.com:8080/this/is/a/test.html', + }, + { + wrong: '//user:pass@example.com:8080/this/is/a/test.html', + fixed: (isWin ? "http:" : "file://") + '//user:pass@example.com:8080/this/is/a/test.html', + }, + { + wrong: '://user:pass@example.com:8080/this/is/a/test.html', + fixed: 'http://user:pass@example.com:8080/this/is/a/test.html', + }, + { + wrong: 'whatever://this/is/a@b/test.html', + fixed: kSearchEngineURL.replace("{searchTerms}", encodeURIComponent('whatever://this/is/a@b/test.html')), + }, +]; + +var extProtocolSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"] + .getService(Ci.nsIExternalProtocolService); + +if (extProtocolSvc && extProtocolSvc.externalProtocolHandlerExists("mailto")) { + data.push({ + wrong: "mailto:foo@bar.com", + fixed: "mailto:foo@bar.com" + }); +} + +function run_test() { + run_next_test(); +} + +var len = data.length; +// Make sure we fix what needs fixing +add_task(function test_fix_unknown_schemes() { + for (let i = 0; i < len; ++i) { + let item = data[i]; + let result = + urifixup.createFixupURI(item.wrong, + urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS).spec; + do_check_eq(result, item.fixed); + } +}); diff --git a/system/docshell/test/unit/test_nsIDownloadHistory.js b/system/docshell/test/unit/test_nsIDownloadHistory.js new file mode 100644 index 000000000..2030f0702 --- /dev/null +++ b/system/docshell/test/unit/test_nsIDownloadHistory.js @@ -0,0 +1,68 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const NS_DOWNLOADHISTORY_CID = "{2ee83680-2af0-4bcb-bfa0-c9705f6554f1}"; + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyGetter(this, "Services", function() { + Components.utils.import("resource://gre/modules/Services.jsm"); + return Services; +}); + +function testLinkVistedObserver() +{ + const NS_LINK_VISITED_EVENT_TOPIC = "link-visited"; + var ios = Cc["@mozilla.org/network/io-service;1"]. + getService(Ci.nsIIOService); + var testURI = ios.newURI("http://google.com/", null, null); + + var gh = Cc["@mozilla.org/browser/global-history;2"]. + getService(Ci.nsIGlobalHistory2); + do_check_false(gh.isVisited(testURI)); + + var topicReceived = false; + var obs = { + observe: function tlvo_observe(aSubject, aTopic, aData) + { + if (NS_LINK_VISITED_EVENT_TOPIC == aTopic) { + do_check_eq(testURI, aSubject); + topicReceived = true; + } + } + }; + + var os = Cc["@mozilla.org/observer-service;1"]. + getService(Ci.nsIObserverService); + os.addObserver(obs, NS_LINK_VISITED_EVENT_TOPIC, false); + + var dh = Components.classesByID[NS_DOWNLOADHISTORY_CID]. + getService(Ci.nsIDownloadHistory); + dh.addDownload(testURI); + do_check_true(topicReceived); + do_check_true(gh.isVisited(testURI)); +} + +var tests = [testLinkVistedObserver]; + +function run_test() +{ + // Not everyone uses/defines an nsGlobalHistory* service. Especially if + // MOZ_PLACES is not defined. If getService fails, then abort gracefully. + try { + Cc["@mozilla.org/browser/global-history;2"]. + getService(Ci.nsIGlobalHistory2); + } + catch (ex) { + return; + } + + // Needed to properly setup and shutdown the profile. + do_get_profile(); + + for (var i = 0; i < tests.length; i++) + tests[i](); + + cleanup(); +} diff --git a/system/docshell/test/unit/test_pb_notification.js b/system/docshell/test/unit/test_pb_notification.js new file mode 100644 index 000000000..82018f585 --- /dev/null +++ b/system/docshell/test/unit/test_pb_notification.js @@ -0,0 +1,23 @@ +if (typeof Cc === "undefined") + Cc = Components.classes; +if (typeof Ci === "undefined") + Ci = Components.interfaces; + +function destroy_transient_docshell() { + var docshell = Cc["@mozilla.org/docshell;1"].createInstance(Ci.nsIDocShell); + docshell.setOriginAttributes({privateBrowsingId : 1}); + do_test_pending(); + do_timeout(0, Components.utils.forceGC); +} + +function run_test() { + var obs = { + observe: function(aSubject, aTopic, aData) { + do_check_eq(aTopic, "last-pb-context-exited"); + do_test_finished(); + } + }; + var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); + os.addObserver(obs, "last-pb-context-exited", false); + destroy_transient_docshell(); +} diff --git a/system/docshell/test/unit/test_privacy_transition.js b/system/docshell/test/unit/test_privacy_transition.js new file mode 100644 index 000000000..829e25c3c --- /dev/null +++ b/system/docshell/test/unit/test_privacy_transition.js @@ -0,0 +1,23 @@ +var gNotifications = 0; + +var observer = { + QueryInterface: function(iid) { + if (Ci.nsIPrivacyTransitionObserver.equals(iid) || + Ci.nsISupportsWeakReference.equals(iid) || + Ci.nsISupports.equals(iid)) + return this; + throw Cr.NS_ERROR_NO_INTERFACE; + }, + + privateModeChanged: function(enabled) { + gNotifications++; + } +} + +function run_test() { + var docshell = Cc["@mozilla.org/docshell;1"].createInstance(Ci.nsIDocShell); + docshell.addWeakPrivacyTransitionObserver(observer); + docshell.setOriginAttributes({ privateBrowsingId : 1 }); + docshell.setOriginAttributes({ privateBrowsingId : 0 }); + do_check_eq(gNotifications, 2); +}
\ No newline at end of file diff --git a/system/docshell/test/unit/test_setUsePrivateBrowsing.js b/system/docshell/test/unit/test_setUsePrivateBrowsing.js new file mode 100644 index 000000000..739186895 --- /dev/null +++ b/system/docshell/test/unit/test_setUsePrivateBrowsing.js @@ -0,0 +1,65 @@ +"use strict"; + +const {utils: Cu} = Components; + +Cu.import("resource://gre/modules/AppConstants.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +add_task(function*() { + let webNav = Services.appShell.createWindowlessBrowser(false); + + let loadContext = webNav.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsILoadContext); + + let docShell = webNav.getInterface(Ci.nsIDocShell); + + equal(loadContext.usePrivateBrowsing, false, "Should start out in non-private mode"); + + loadContext.usePrivateBrowsing = true; + equal(loadContext.usePrivateBrowsing, true, + "Should be able to change to private mode prior to a document load"); + + loadContext.usePrivateBrowsing = false; + equal(loadContext.usePrivateBrowsing, false, + "Should be able to change to non-private mode prior to a document load"); + + let oa = docShell.getOriginAttributes(); + + oa.privateBrowsingId = 1; + docShell.setOriginAttributes(oa); + + equal(loadContext.usePrivateBrowsing, true, + "Should be able to change origin attributes prior to a document load"); + + oa.privateBrowsingId = 0; + docShell.setOriginAttributes(oa); + + equal(loadContext.usePrivateBrowsing, false, + "Should be able to change origin attributes prior to a document load"); + + webNav.loadURI("data:text/html,", webNav.LOAD_FLAGS_NONE, null, null, null); + + // Return to the event loop so the load can begin. + yield new Promise(do_execute_soon); + + // This causes a failed assertion rather than an exception on debug + // builds. + if (!AppConstants.DEBUG) { + Assert.throws(() => { loadContext.usePrivateBrowsing = true; }, + /NS_ERROR_FAILURE/, + "Should not be able to change private browsing state after initial load has started"); + + oa.privateBrowsingId = 1; + Assert.throws(() => { docShell.setOriginAttributes(oa); }, + /NS_ERROR_FAILURE/, + "Should not be able to change origin attributes after initial load has started"); + + equal(loadContext.usePrivateBrowsing, false, + "Should not be able to change private browsing state after initial load has started"); + + loadContext.usePrivateBrowsing = false; + ok(true, "Should be able to set usePrivateBrowsing to its current value even after initial load"); + } + + webNav.close(); +}); diff --git a/system/docshell/test/unit/xpcshell.ini b/system/docshell/test/unit/xpcshell.ini new file mode 100644 index 000000000..ce8ec8b63 --- /dev/null +++ b/system/docshell/test/unit/xpcshell.ini @@ -0,0 +1,17 @@ +[DEFAULT] +head = head_docshell.js +tail = + +[test_bug414201_jfif.js] +[test_bug442584.js] +[test_nsDefaultURIFixup.js] +[test_nsDefaultURIFixup_search.js] +skip-if = os == 'android' +[test_nsDefaultURIFixup_info.js] +skip-if = os == 'android' +[test_nsIDownloadHistory.js] +[test_pb_notification.js] +# Bug 751575: unrelated JS changes cause timeouts on random platforms +skip-if = true +[test_privacy_transition.js] +[test_setUsePrivateBrowsing.js] diff --git a/system/docshell/test/unit_ipc/test_pb_notification_ipc.js b/system/docshell/test/unit_ipc/test_pb_notification_ipc.js new file mode 100644 index 000000000..1517a479f --- /dev/null +++ b/system/docshell/test/unit_ipc/test_pb_notification_ipc.js @@ -0,0 +1,20 @@ +var Cc = Components.classes; +var Ci = Components.interfaces; + +function run_test() { + var notifications = 0; + var obs = { + observe: function(aSubject, aTopic, aData) { + do_check_eq(aTopic, "last-pb-context-exited"); + notifications++; + } + }; + var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); + os.addObserver(obs, "last-pb-context-exited", false); + + run_test_in_child("../unit/test_pb_notification.js", + function() { + do_check_eq(notifications, 1); + do_test_finished(); + }); +}
\ No newline at end of file diff --git a/system/docshell/test/unit_ipc/xpcshell.ini b/system/docshell/test/unit_ipc/xpcshell.ini new file mode 100644 index 000000000..7a2df27c0 --- /dev/null +++ b/system/docshell/test/unit_ipc/xpcshell.ini @@ -0,0 +1,8 @@ +[DEFAULT] +head = +tail = +skip-if = toolkit == 'android' + +[test_pb_notification_ipc.js] +# Bug 751575: Perma-fails with: command timed out: 1200 seconds without output +skip-if = true |