diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /docshell/test/browser | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'docshell/test/browser')
89 files changed, 3047 insertions, 0 deletions
diff --git a/docshell/test/browser/browser.ini b/docshell/test/browser/browser.ini new file mode 100644 index 000000000..9211092a4 --- /dev/null +++ b/docshell/test/browser/browser.ini @@ -0,0 +1,93 @@ +[DEFAULT] +support-files = + 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 + +[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] diff --git a/docshell/test/browser/browser_bug1206879.js b/docshell/test/browser/browser_bug1206879.js new file mode 100644 index 000000000..1276f6428 --- /dev/null +++ b/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/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js b/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js new file mode 100644 index 000000000..a4b4645e8 --- /dev/null +++ b/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/docshell/test/browser/browser_bug134911.js b/docshell/test/browser/browser_bug134911.js new file mode 100644 index 000000000..aa54cfd1a --- /dev/null +++ b/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/docshell/test/browser/browser_bug234628-1.js b/docshell/test/browser/browser_bug234628-1.js new file mode 100644 index 000000000..bfb4d3708 --- /dev/null +++ b/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/docshell/test/browser/browser_bug234628-10.js b/docshell/test/browser/browser_bug234628-10.js new file mode 100644 index 000000000..7dbe805c4 --- /dev/null +++ b/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/docshell/test/browser/browser_bug234628-11.js b/docshell/test/browser/browser_bug234628-11.js new file mode 100644 index 000000000..fc597f5c0 --- /dev/null +++ b/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/docshell/test/browser/browser_bug234628-2.js b/docshell/test/browser/browser_bug234628-2.js new file mode 100644 index 000000000..638e223c0 --- /dev/null +++ b/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/docshell/test/browser/browser_bug234628-3.js b/docshell/test/browser/browser_bug234628-3.js new file mode 100644 index 000000000..51aca7ec8 --- /dev/null +++ b/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/docshell/test/browser/browser_bug234628-4.js b/docshell/test/browser/browser_bug234628-4.js new file mode 100644 index 000000000..fe7f1545f --- /dev/null +++ b/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/docshell/test/browser/browser_bug234628-5.js b/docshell/test/browser/browser_bug234628-5.js new file mode 100644 index 000000000..a37f14b8d --- /dev/null +++ b/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/docshell/test/browser/browser_bug234628-6.js b/docshell/test/browser/browser_bug234628-6.js new file mode 100644 index 000000000..7d2d92531 --- /dev/null +++ b/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/docshell/test/browser/browser_bug234628-7.js b/docshell/test/browser/browser_bug234628-7.js new file mode 100644 index 000000000..0bafd67e7 --- /dev/null +++ b/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/docshell/test/browser/browser_bug234628-8.js b/docshell/test/browser/browser_bug234628-8.js new file mode 100644 index 000000000..40a0c6946 --- /dev/null +++ b/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/docshell/test/browser/browser_bug234628-9.js b/docshell/test/browser/browser_bug234628-9.js new file mode 100644 index 000000000..72da65e80 --- /dev/null +++ b/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/docshell/test/browser/browser_bug349769.js b/docshell/test/browser/browser_bug349769.js new file mode 100644 index 000000000..76d4e0f28 --- /dev/null +++ b/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/docshell/test/browser/browser_bug388121-1.js b/docshell/test/browser/browser_bug388121-1.js new file mode 100644 index 000000000..7da617594 --- /dev/null +++ b/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/docshell/test/browser/browser_bug388121-2.js b/docshell/test/browser/browser_bug388121-2.js new file mode 100644 index 000000000..6c050d971 --- /dev/null +++ b/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/docshell/test/browser/browser_bug420605.js b/docshell/test/browser/browser_bug420605.js new file mode 100644 index 000000000..f07d45e93 --- /dev/null +++ b/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/docshell/test/browser/browser_bug422543.js b/docshell/test/browser/browser_bug422543.js new file mode 100644 index 000000000..0655a17b7 --- /dev/null +++ b/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/docshell/test/browser/browser_bug441169.js b/docshell/test/browser/browser_bug441169.js new file mode 100644 index 000000000..015115793 --- /dev/null +++ b/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/docshell/test/browser/browser_bug503832.js b/docshell/test/browser/browser_bug503832.js new file mode 100644 index 000000000..66904cbae --- /dev/null +++ b/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/docshell/test/browser/browser_bug554155.js b/docshell/test/browser/browser_bug554155.js new file mode 100644 index 000000000..efc74a1c1 --- /dev/null +++ b/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/docshell/test/browser/browser_bug655270.js b/docshell/test/browser/browser_bug655270.js new file mode 100644 index 000000000..275245df8 --- /dev/null +++ b/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/docshell/test/browser/browser_bug655273.js b/docshell/test/browser/browser_bug655273.js new file mode 100644 index 000000000..3acb6ddd5 --- /dev/null +++ b/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/docshell/test/browser/browser_bug670318.js b/docshell/test/browser/browser_bug670318.js new file mode 100644 index 000000000..a73639cab --- /dev/null +++ b/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/docshell/test/browser/browser_bug673467.js b/docshell/test/browser/browser_bug673467.js new file mode 100644 index 000000000..10139a48c --- /dev/null +++ b/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/docshell/test/browser/browser_bug852909.js b/docshell/test/browser/browser_bug852909.js new file mode 100644 index 000000000..5e2374c43 --- /dev/null +++ b/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/docshell/test/browser/browser_bug92473.js b/docshell/test/browser/browser_bug92473.js new file mode 100644 index 000000000..d1c4aebdb --- /dev/null +++ b/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/docshell/test/browser/browser_loadDisallowInherit.js b/docshell/test/browser/browser_loadDisallowInherit.js new file mode 100644 index 000000000..71789890f --- /dev/null +++ b/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/docshell/test/browser/browser_loadURI.js b/docshell/test/browser/browser_loadURI.js new file mode 100644 index 000000000..a68e1c2de --- /dev/null +++ b/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/docshell/test/browser/browser_multiple_pushState.js b/docshell/test/browser/browser_multiple_pushState.js new file mode 100644 index 000000000..5c2f5aef4 --- /dev/null +++ b/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/docshell/test/browser/browser_onbeforeunload_navigation.js b/docshell/test/browser/browser_onbeforeunload_navigation.js new file mode 100644 index 000000000..d2feb69d4 --- /dev/null +++ b/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/docshell/test/browser/browser_search_notification.js b/docshell/test/browser/browser_search_notification.js new file mode 100644 index 000000000..b0a4571e5 --- /dev/null +++ b/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/docshell/test/browser/browser_tab_touch_events.js b/docshell/test/browser/browser_tab_touch_events.js new file mode 100644 index 000000000..615983f61 --- /dev/null +++ b/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/docshell/test/browser/browser_timelineMarkers-01.js b/docshell/test/browser/browser_timelineMarkers-01.js new file mode 100644 index 000000000..59eeb57db --- /dev/null +++ b/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/docshell/test/browser/browser_timelineMarkers-02.js b/docshell/test/browser/browser_timelineMarkers-02.js new file mode 100644 index 000000000..34142760e --- /dev/null +++ b/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/docshell/test/browser/browser_timelineMarkers-03.js b/docshell/test/browser/browser_timelineMarkers-03.js new file mode 100644 index 000000000..b104367c1 --- /dev/null +++ b/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/docshell/test/browser/browser_timelineMarkers-04.js b/docshell/test/browser/browser_timelineMarkers-04.js new file mode 100644 index 000000000..fdee867e7 --- /dev/null +++ b/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/docshell/test/browser/browser_timelineMarkers-05.js b/docshell/test/browser/browser_timelineMarkers-05.js new file mode 100644 index 000000000..0130c58d9 --- /dev/null +++ b/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/docshell/test/browser/browser_timelineMarkers-frame-02.js b/docshell/test/browser/browser_timelineMarkers-frame-02.js new file mode 100644 index 000000000..83750395d --- /dev/null +++ b/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/docshell/test/browser/browser_timelineMarkers-frame-03.js b/docshell/test/browser/browser_timelineMarkers-frame-03.js new file mode 100644 index 000000000..cf5f150ad --- /dev/null +++ b/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/docshell/test/browser/browser_timelineMarkers-frame-04.js b/docshell/test/browser/browser_timelineMarkers-frame-04.js new file mode 100644 index 000000000..427312993 --- /dev/null +++ b/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/docshell/test/browser/browser_timelineMarkers-frame-05.js b/docshell/test/browser/browser_timelineMarkers-frame-05.js new file mode 100644 index 000000000..713f0e560 --- /dev/null +++ b/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/docshell/test/browser/browser_ua_emulation.js b/docshell/test/browser/browser_ua_emulation.js new file mode 100644 index 000000000..94a602d4b --- /dev/null +++ b/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/docshell/test/browser/browser_uriFixupAlternateRedirects.js b/docshell/test/browser/browser_uriFixupAlternateRedirects.js new file mode 100644 index 000000000..f5a00a2df --- /dev/null +++ b/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/docshell/test/browser/browser_uriFixupIntegration.js b/docshell/test/browser/browser_uriFixupIntegration.js new file mode 100644 index 000000000..e041e1f67 --- /dev/null +++ b/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/docshell/test/browser/favicon_bug655270.ico b/docshell/test/browser/favicon_bug655270.ico Binary files differnew file mode 100644 index 000000000..d44438903 --- /dev/null +++ b/docshell/test/browser/favicon_bug655270.ico diff --git a/docshell/test/browser/file_bug1046022.html b/docshell/test/browser/file_bug1046022.html new file mode 100644 index 000000000..2de68cb43 --- /dev/null +++ b/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/docshell/test/browser/file_bug1206879.html b/docshell/test/browser/file_bug1206879.html new file mode 100644 index 000000000..5313902a9 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-1-child.html b/docshell/test/browser/file_bug234628-1-child.html new file mode 100644 index 000000000..c36197ac4 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-1.html b/docshell/test/browser/file_bug234628-1.html new file mode 100644 index 000000000..11c523ccd --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-10-child.xhtml b/docshell/test/browser/file_bug234628-10-child.xhtml new file mode 100644 index 000000000..cccf6f2bc --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-10.html b/docshell/test/browser/file_bug234628-10.html new file mode 100644 index 000000000..78b8f0035 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-11-child.xhtml b/docshell/test/browser/file_bug234628-11-child.xhtml new file mode 100644 index 000000000..11ef668b0 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-11-child.xhtml^headers^ b/docshell/test/browser/file_bug234628-11-child.xhtml^headers^ new file mode 100644 index 000000000..30fb30405 --- /dev/null +++ b/docshell/test/browser/file_bug234628-11-child.xhtml^headers^ @@ -0,0 +1 @@ +Content-Type: application/xhtml+xml; charset=utf-8 diff --git a/docshell/test/browser/file_bug234628-11.html b/docshell/test/browser/file_bug234628-11.html new file mode 100644 index 000000000..21c5b733e --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-2-child.html b/docshell/test/browser/file_bug234628-2-child.html new file mode 100644 index 000000000..0acd2e0b2 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-2.html b/docshell/test/browser/file_bug234628-2.html new file mode 100644 index 000000000..a87d29e12 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-3-child.html b/docshell/test/browser/file_bug234628-3-child.html new file mode 100644 index 000000000..a6ad83231 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-3.html b/docshell/test/browser/file_bug234628-3.html new file mode 100644 index 000000000..8caab6040 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-4-child.html b/docshell/test/browser/file_bug234628-4-child.html new file mode 100644 index 000000000..f0e7c2c05 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-4.html b/docshell/test/browser/file_bug234628-4.html new file mode 100644 index 000000000..013757901 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-5-child.html b/docshell/test/browser/file_bug234628-5-child.html Binary files differnew file mode 100644 index 000000000..a650552f6 --- /dev/null +++ b/docshell/test/browser/file_bug234628-5-child.html diff --git a/docshell/test/browser/file_bug234628-5.html b/docshell/test/browser/file_bug234628-5.html new file mode 100644 index 000000000..987e6420b --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-6-child.html b/docshell/test/browser/file_bug234628-6-child.html Binary files differnew file mode 100644 index 000000000..52c37f259 --- /dev/null +++ b/docshell/test/browser/file_bug234628-6-child.html diff --git a/docshell/test/browser/file_bug234628-6-child.html^headers^ b/docshell/test/browser/file_bug234628-6-child.html^headers^ new file mode 100644 index 000000000..bfdcf487f --- /dev/null +++ b/docshell/test/browser/file_bug234628-6-child.html^headers^ @@ -0,0 +1 @@ +Content-Type: text/html; charset=utf-16be diff --git a/docshell/test/browser/file_bug234628-6.html b/docshell/test/browser/file_bug234628-6.html new file mode 100644 index 000000000..9d7fc580c --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-7-child.html b/docshell/test/browser/file_bug234628-7-child.html new file mode 100644 index 000000000..c761ace10 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-7-child.html^headers^ b/docshell/test/browser/file_bug234628-7-child.html^headers^ new file mode 100644 index 000000000..2d1c08b9e --- /dev/null +++ b/docshell/test/browser/file_bug234628-7-child.html^headers^ @@ -0,0 +1 @@ +Content-Type: text/html; charset=utf-8 diff --git a/docshell/test/browser/file_bug234628-7.html b/docshell/test/browser/file_bug234628-7.html new file mode 100644 index 000000000..7cb506096 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-8-child.html b/docshell/test/browser/file_bug234628-8-child.html new file mode 100644 index 000000000..254e0fb2b --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-8.html b/docshell/test/browser/file_bug234628-8.html new file mode 100644 index 000000000..b44e91801 --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-9-child.html b/docshell/test/browser/file_bug234628-9-child.html new file mode 100644 index 000000000..a86b14d7e --- /dev/null +++ b/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/docshell/test/browser/file_bug234628-9.html b/docshell/test/browser/file_bug234628-9.html Binary files differnew file mode 100644 index 000000000..8a469da3a --- /dev/null +++ b/docshell/test/browser/file_bug234628-9.html diff --git a/docshell/test/browser/file_bug420605.html b/docshell/test/browser/file_bug420605.html new file mode 100644 index 000000000..8424b92f8 --- /dev/null +++ b/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/docshell/test/browser/file_bug422543_script.js b/docshell/test/browser/file_bug422543_script.js new file mode 100644 index 000000000..cd69df1ec --- /dev/null +++ b/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/docshell/test/browser/file_bug503832.html b/docshell/test/browser/file_bug503832.html new file mode 100644 index 000000000..338631c8a --- /dev/null +++ b/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/docshell/test/browser/file_bug655270.html b/docshell/test/browser/file_bug655270.html new file mode 100644 index 000000000..0c08d982b --- /dev/null +++ b/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/docshell/test/browser/file_bug670318.html b/docshell/test/browser/file_bug670318.html new file mode 100644 index 000000000..4cd9b454a --- /dev/null +++ b/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/docshell/test/browser/file_bug852909.pdf b/docshell/test/browser/file_bug852909.pdf Binary files differnew file mode 100644 index 000000000..89066463f --- /dev/null +++ b/docshell/test/browser/file_bug852909.pdf diff --git a/docshell/test/browser/file_bug852909.png b/docshell/test/browser/file_bug852909.png Binary files differnew file mode 100644 index 000000000..c7510d388 --- /dev/null +++ b/docshell/test/browser/file_bug852909.png diff --git a/docshell/test/browser/file_multiple_pushState.html b/docshell/test/browser/file_multiple_pushState.html new file mode 100644 index 000000000..c58a1a71b --- /dev/null +++ b/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/docshell/test/browser/frame-head.js b/docshell/test/browser/frame-head.js new file mode 100644 index 000000000..5cb3b1513 --- /dev/null +++ b/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/docshell/test/browser/head.js b/docshell/test/browser/head.js new file mode 100644 index 000000000..24ca8f45b --- /dev/null +++ b/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/docshell/test/browser/print_postdata.sjs b/docshell/test/browser/print_postdata.sjs new file mode 100644 index 000000000..4175a2480 --- /dev/null +++ b/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/docshell/test/browser/redirect_to_example.sjs b/docshell/test/browser/redirect_to_example.sjs new file mode 100644 index 000000000..eef5e49f4 --- /dev/null +++ b/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/docshell/test/browser/test-form_sjis.html b/docshell/test/browser/test-form_sjis.html new file mode 100644 index 000000000..91c375dee --- /dev/null +++ b/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/docshell/test/browser/timelineMarkers-04.html b/docshell/test/browser/timelineMarkers-04.html new file mode 100644 index 000000000..829998387 --- /dev/null +++ b/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> + |