зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1267289 - add more URL bar tests and fix issue with error pages, r=mikedeboer,mconley
This adds tests for issues brought up in bug 231393, bug 264610, bug 302575 and bug 1129564, all of which fed into the current implementation of userTypedClear/userTypedValue. I intend to move us away from userTypedClear, but I'm keen not to regress any of these issues, so I'm adding automated tests to ensure that doesn't happen. MozReview-Commit-ID: 1up2MIXzkzG --HG-- extra : rebase_source : 4d37f13895b8c7e7aba5331664718582c6b2136c
This commit is contained in:
Родитель
bfa6750d68
Коммит
1d863b1c09
|
@ -51,6 +51,8 @@ support-files =
|
|||
[browser_urlbarEnter.js]
|
||||
[browser_urlbarEnterAfterMouseOver.js]
|
||||
skip-if = os == "linux" # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
|
||||
[browser_urlbarHashChangeProxyState.js]
|
||||
[browser_urlbarKeepStateAcrossTabSwitches.js]
|
||||
[browser_urlbarRevert.js]
|
||||
[browser_urlbarSearchSingleWordNotification.js]
|
||||
[browser_urlbarSearchSuggestions.js]
|
||||
|
@ -67,6 +69,7 @@ support-files =
|
|||
searchSuggestionEngine.sjs
|
||||
[browser_urlbarStop.js]
|
||||
[browser_urlbarTrimURLs.js]
|
||||
[browser_urlbarUpdateForDomainCompletion.js]
|
||||
[browser_urlbar_autoFill_backspaced.js]
|
||||
[browser_urlbar_blanking.js]
|
||||
support-files =
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Check that navigating through both the URL bar and using in-page hash- or ref-
|
||||
* based links and back or forward navigation updates the URL bar and identity block correctly.
|
||||
*/
|
||||
add_task(function* () {
|
||||
let baseURL = "https://example.org/browser/browser/base/content/test/urlbar/dummy_page.html";
|
||||
let url = baseURL + "#foo";
|
||||
yield BrowserTestUtils.withNewTab({ gBrowser, url }, function(browser) {
|
||||
let identityBox = document.getElementById("identity-box");
|
||||
let expectedURL = url;
|
||||
|
||||
let verifyURLBarState = testType => {
|
||||
is(gURLBar.textValue, expectedURL, "URL bar visible value should be correct " + testType);
|
||||
is(gURLBar.value, expectedURL, "URL bar value should be correct " + testType);
|
||||
ok(identityBox.classList.contains("verifiedDomain"), "Identity box should know we're doing SSL " + testType);
|
||||
is(gURLBar.getAttribute("pageproxystate"), "valid", "URL bar is in valid page proxy state");
|
||||
};
|
||||
|
||||
verifyURLBarState("at the beginning");
|
||||
|
||||
let locationChangePromise;
|
||||
let resolveLocationChangePromise;
|
||||
let expectURL = url => {
|
||||
expectedURL = url;
|
||||
locationChangePromise = new Promise(r => resolveLocationChangePromise = r);
|
||||
};
|
||||
let wpl = {
|
||||
onLocationChange(wpl, request, location, flags) {
|
||||
is(location.spec, expectedURL, "Got the expected URL");
|
||||
resolveLocationChangePromise();
|
||||
},
|
||||
};
|
||||
gBrowser.addProgressListener(wpl);
|
||||
|
||||
expectURL(baseURL + "#foo");
|
||||
gURLBar.select();
|
||||
EventUtils.sendKey("return");
|
||||
|
||||
yield locationChangePromise;
|
||||
verifyURLBarState("after hitting enter on the same URL a second time");
|
||||
|
||||
expectURL(baseURL + "#bar");
|
||||
gURLBar.value = expectedURL;
|
||||
gURLBar.select();
|
||||
EventUtils.sendKey("return");
|
||||
|
||||
yield locationChangePromise;
|
||||
verifyURLBarState("after a URL bar hash navigation");
|
||||
|
||||
expectURL(baseURL + "#foo");
|
||||
yield ContentTask.spawn(browser, null, function() {
|
||||
let a = content.document.createElement("a");
|
||||
a.href = "#foo";
|
||||
a.textContent = "Foo Link";
|
||||
content.document.body.appendChild(a);
|
||||
a.click();
|
||||
});
|
||||
|
||||
yield locationChangePromise;
|
||||
verifyURLBarState("after a page link hash navigation");
|
||||
|
||||
expectURL(baseURL + "#bar");
|
||||
gBrowser.goBack();
|
||||
|
||||
yield locationChangePromise;
|
||||
verifyURLBarState("after going back");
|
||||
|
||||
expectURL(baseURL + "#foo");
|
||||
gBrowser.goForward();
|
||||
|
||||
yield locationChangePromise;
|
||||
verifyURLBarState("after going forward");
|
||||
|
||||
expectURL(baseURL + "#foo");
|
||||
gURLBar.select();
|
||||
EventUtils.sendKey("return");
|
||||
|
||||
yield locationChangePromise;
|
||||
verifyURLBarState("after hitting enter on the same URL");
|
||||
|
||||
gBrowser.removeProgressListener(wpl);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Check that initial secure loads that swap remoteness
|
||||
* get the correct page icon when finished.
|
||||
*/
|
||||
add_task(function* () {
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
|
||||
// NB: CPOW usage because new tab pages can be preloaded, in which case no
|
||||
// load events fire.
|
||||
yield BrowserTestUtils.waitForCondition(() => !tab.linkedBrowser.contentDocument.hidden)
|
||||
let url = "https://example.org/browser/browser/base/content/test/urlbar/dummy_page.html#foo";
|
||||
gURLBar.value = url;
|
||||
gURLBar.select();
|
||||
EventUtils.sendKey("return");
|
||||
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
|
||||
|
||||
is(gURLBar.textValue, url, "URL bar visible value should be correct when the page loads from about:newtab");
|
||||
is(gURLBar.value, url, "URL bar value should be correct when the page loads from about:newtab");
|
||||
let identityBox = document.getElementById("identity-box");
|
||||
ok(identityBox.classList.contains("verifiedDomain"),
|
||||
"Identity box should know we're doing SSL when the page loads from about:newtab");
|
||||
is(gURLBar.getAttribute("pageproxystate"), "valid",
|
||||
"URL bar is in valid page proxy state when SSL page with hash loads from about:newtab");
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Verify user typed text remains in the URL bar when tab switching, even when
|
||||
* loads fail.
|
||||
*/
|
||||
add_task(function* () {
|
||||
let input = "i-definitely-dont-exist.example.com";
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
|
||||
// NB: CPOW usage because new tab pages can be preloaded, in which case no
|
||||
// load events fire.
|
||||
yield BrowserTestUtils.waitForCondition(() => !tab.linkedBrowser.contentDocument.hidden)
|
||||
let errorPageLoaded = BrowserTestUtils.waitForErrorPage(tab.linkedBrowser);
|
||||
gURLBar.value = input;
|
||||
gURLBar.select();
|
||||
EventUtils.sendKey("return");
|
||||
yield errorPageLoaded;
|
||||
is(gURLBar.textValue, input, "Text is still in URL bar");
|
||||
yield BrowserTestUtils.switchTab(gBrowser, tab.previousSibling);
|
||||
yield BrowserTestUtils.switchTab(gBrowser, tab);
|
||||
is(gURLBar.textValue, input, "Text is still in URL bar after tab switch");
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
/**
|
||||
* Invalid URIs fail differently (that is, immediately, in the loadURI call)
|
||||
* if keyword searches are turned off. Test that this works, too.
|
||||
*/
|
||||
add_task(function* () {
|
||||
let input = "To be or not to be-that is the question";
|
||||
yield new Promise(resolve => SpecialPowers.pushPrefEnv({set: [["keyword.enabled", false]]}, resolve));
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
|
||||
// NB: CPOW usage because new tab pages can be preloaded, in which case no
|
||||
// load events fire.
|
||||
yield BrowserTestUtils.waitForCondition(() => !tab.linkedBrowser.contentDocument.hidden)
|
||||
let errorPageLoaded = BrowserTestUtils.waitForErrorPage(tab.linkedBrowser);
|
||||
gURLBar.value = input;
|
||||
gURLBar.select();
|
||||
EventUtils.sendKey("return");
|
||||
yield errorPageLoaded;
|
||||
is(gURLBar.textValue, input, "Text is still in URL bar");
|
||||
is(tab.linkedBrowser.userTypedValue, input, "Text still stored on browser");
|
||||
yield BrowserTestUtils.switchTab(gBrowser, tab.previousSibling);
|
||||
yield BrowserTestUtils.switchTab(gBrowser, tab);
|
||||
is(gURLBar.textValue, input, "Text is still in URL bar after tab switch");
|
||||
is(tab.linkedBrowser.userTypedValue, input, "Text still stored on browser");
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Disable keyword.enabled (so no keyword search), and check that when you type in
|
||||
* "example" and hit enter, the browser loads and the URL bar is updated accordingly.
|
||||
*/
|
||||
add_task(function* () {
|
||||
yield new Promise(resolve => SpecialPowers.pushPrefEnv({set: [["keyword.enabled", false]]}, resolve));
|
||||
yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, function* (browser) {
|
||||
gURLBar.value = "example";
|
||||
gURLBar.select();
|
||||
let loadPromise = BrowserTestUtils.browserLoaded(browser, false, url => url == "http://www.example.com/");
|
||||
EventUtils.sendKey("return");
|
||||
yield loadPromise;
|
||||
is(gURLBar.textValue, "www.example.com");
|
||||
});
|
||||
});
|
|
@ -815,11 +815,14 @@ var SessionStoreInternal = {
|
|||
} else {
|
||||
// If the user was typing into the URL bar when we crashed, but hadn't hit
|
||||
// enter yet, then we just need to write that value to the URL bar without
|
||||
// loading anything. This must happen after the load, since it will clear
|
||||
// loading anything. This must happen after the load, as the load will clear
|
||||
// userTypedValue.
|
||||
let tabData = TabState.collect(tab);
|
||||
if (tabData.userTypedValue && !tabData.userTypedClear) {
|
||||
browser.userTypedValue = tabData.userTypedValue;
|
||||
if (data.didStartLoad) {
|
||||
browser.userTypedClear++;
|
||||
}
|
||||
win.URLBarSetURI();
|
||||
}
|
||||
|
||||
|
@ -2527,7 +2530,6 @@ var SessionStoreInternal = {
|
|||
tabState.index = historyIndex + 1;
|
||||
tabState.index = Math.max(1, Math.min(tabState.index, tabState.entries.length));
|
||||
} else {
|
||||
tabState.userTypedValue = null;
|
||||
options.loadArguments = recentLoadArguments;
|
||||
}
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ var MessageListener = {
|
|||
sendAsyncMessage("SessionStore:restoreTabContentComplete", {epoch, isRemotenessUpdate});
|
||||
});
|
||||
|
||||
sendAsyncMessage("SessionStore:restoreTabContentStarted", {epoch});
|
||||
sendAsyncMessage("SessionStore:restoreTabContentStarted", {epoch, didStartLoad});
|
||||
|
||||
if (!didStartLoad) {
|
||||
// Pretend that the load succeeded so that event handlers fire correctly.
|
||||
|
|
|
@ -528,6 +528,8 @@ this.BrowserTestUtils = {
|
|||
* event is the expected one, or false if it should be ignored and
|
||||
* listening should continue. If not specified, the first event with
|
||||
* the specified name resolves the returned promise.
|
||||
* @param {bool} wantsUntrusted [optional]
|
||||
* Whether to accept untrusted events
|
||||
*
|
||||
* @note Because this function is intended for testing, any error in checkFn
|
||||
* will cause the returned promise to be rejected instead of waiting for
|
||||
|
@ -535,12 +537,15 @@ this.BrowserTestUtils = {
|
|||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
waitForContentEvent(browser, eventName, capture, checkFn) {
|
||||
let parameters = { eventName,
|
||||
capture,
|
||||
checkFnSource: checkFn ? checkFn.toSource() : null };
|
||||
waitForContentEvent(browser, eventName, capture = false, checkFn, wantsUntrusted = false) {
|
||||
let parameters = {
|
||||
eventName,
|
||||
capture,
|
||||
checkFnSource: checkFn ? checkFn.toSource() : null,
|
||||
wantsUntrusted,
|
||||
};
|
||||
return ContentTask.spawn(browser, parameters,
|
||||
function({ eventName, capture, checkFnSource }) {
|
||||
function({ eventName, capture, checkFnSource, wantsUntrusted }) {
|
||||
let checkFn;
|
||||
if (checkFnSource) {
|
||||
checkFn = eval(`(() => (${checkFnSource}))()`);
|
||||
|
@ -557,11 +562,44 @@ this.BrowserTestUtils = {
|
|||
}
|
||||
removeEventListener(eventName, listener, capture);
|
||||
completion();
|
||||
}, capture);
|
||||
}, capture, wantsUntrusted);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Like browserLoaded, but waits for an error page to appear.
|
||||
* This explicitly deals with cases where the browser is not currently remote and a
|
||||
* remoteness switch will occur before the error page is loaded, which is tricky
|
||||
* because error pages don't fire 'regular' load events that we can rely on.
|
||||
*
|
||||
* @param {xul:browser} browser
|
||||
* A xul:browser.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves When an error page has been loaded in the browser.
|
||||
*/
|
||||
waitForErrorPage(browser) {
|
||||
let waitForLoad = () =>
|
||||
this.waitForContentEvent(browser, "AboutNetErrorLoad", false, null, true);
|
||||
|
||||
let win = browser.ownerDocument.defaultView;
|
||||
let tab = win.gBrowser.getTabForBrowser(browser);
|
||||
if (!tab || browser.isRemoteBrowser || !win.gMultiProcessBrowser) {
|
||||
return waitForLoad();
|
||||
}
|
||||
|
||||
// We're going to switch remoteness when loading an error page. We need to be
|
||||
// quite careful in order to make sure we're adding the listener in time to
|
||||
// get this event:
|
||||
return new Promise((resolve, reject) => {
|
||||
tab.addEventListener("TabRemotenessChange", function onTRC() {
|
||||
tab.removeEventListener("TabRemotenessChange", onTRC);
|
||||
waitForLoad().then(resolve, reject);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Versions of EventUtils.jsm synthesizeMouse functions that synthesize a
|
||||
* mouse event in a child process and return promises that resolve when the
|
||||
|
|
Загрузка…
Ссылка в новой задаче