diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index 4937e8944762..d642c943e7e7 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -57,6 +57,7 @@ support-files = file_bug970276_popup2.html file_bug970276_favicon1.ico file_bug970276_favicon2.ico + file_documentnavigation_frameset.html file_dom_notifications.html file_double_close_tab.html file_favicon_change.html @@ -287,6 +288,7 @@ skip-if = e10s # Bug 1071623 [browser_discovery.js] [browser_double_close_tab.js] skip-if = e10s +[browser_documentnavigation.js] [browser_duplicateIDs.js] [browser_drag.js] skip-if = true # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638. diff --git a/browser/base/content/test/general/browser_documentnavigation.js b/browser/base/content/test/general/browser_documentnavigation.js new file mode 100644 index 000000000000..7f72affe120c --- /dev/null +++ b/browser/base/content/test/general/browser_documentnavigation.js @@ -0,0 +1,266 @@ +/* + * This test checks that focus is adjusted properly in a browser when pressing F6 and Shift+F6. + * There are additional tests in dom/tests/mochitest/chrome/test_focus_docnav.xul which test + * non-browser cases. + */ + +let testPage1 = "data:text/html,"; +let testPage2 = "data:text/html,"; +let testPage3 = "data:text/html,"; + +let fm = Services.focus; + +function* expectFocusOnF6(backward, expectedDocument, expectedElement, onContent, desc) +{ + let focusChangedInChildResolver = null; + let focusPromise = onContent ? new Promise(resolve => focusChangedInChildResolver = resolve) : + BrowserTestUtils.waitForEvent(window, "focus", true); + + function focusChangedListener(msg) { + let expected = expectedDocument; + if (!expectedElement.startsWith("html")) { + expected += "," + expectedElement; + } + + is(msg.data.details, expected, desc + " child focus matches"); + focusChangedInChildResolver(); + } + + if (onContent) { + messageManager.addMessageListener("BrowserTest:FocusChanged", focusChangedListener); + + yield ContentTask.spawn(gBrowser.selectedBrowser, { expectedElementId: expectedElement }, function* (arg) { + let expectedElement = content.document.getElementById(arg.expectedElementId); + if (!expectedElement) { + // Element not found, so look in the child frames. + for (let f = 0; f < content.frames.length; f++) { + if (content.frames[f].document.getElementById(arg.expectedElementId)) { + expectedElement = content.frames[f].document; + break; + } + } + } + else if (expectedElement.localName == "html") { + expectedElement = expectedElement.ownerDocument; + } + + if (!expectedElement) { + sendSyncMessage("BrowserTest:FocusChanged", + { details : "expected element " + arg.expectedElementId + " not found" }); + return; + } + + expectedElement.addEventListener("focus", function focusReceived() { + expectedElement.removeEventListener("focus", focusReceived, true); + + const fm = Components.classes["@mozilla.org/focus-manager;1"]. + getService(Components.interfaces.nsIFocusManager); + let details = fm.focusedWindow.document.documentElement.id; + if (fm.focusedElement) { + details += "," + fm.focusedElement.id; + } + + sendSyncMessage("BrowserTest:FocusChanged", { details : details }); + }, true); + }); + } + + EventUtils.synthesizeKey("VK_F6", { shiftKey: backward }); + yield focusPromise; + + if (typeof expectedElement == "string") { + expectedElement = fm.focusedWindow.document.getElementById(expectedElement); + } + + if (gMultiProcessBrowser && onContent) { + expectedDocument = "main-window"; + expectedElement = gBrowser.selectedBrowser; + } + + is(fm.focusedWindow.document.documentElement.id, expectedDocument, desc + " document matches"); + is(fm.focusedElement, expectedElement, desc + " element matches"); + + if (onContent) { + messageManager.removeMessageListener("BrowserTest:FocusChanged", focusChangedListener); + } +} + +// Load a page and navigate between it and the chrome window. +add_task(function* () +{ + let page1Promise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + gBrowser.selectedBrowser.loadURI(testPage1); + yield page1Promise; + + // When the urlbar is focused, pressing F6 should focus the root of the content page. + gURLBar.focus(); + yield* expectFocusOnF6(false, "html1", "html1", + true, "basic focus content page"); + + // When the content is focused, pressing F6 should focus the urlbar. + yield* expectFocusOnF6(false, "main-window", gURLBar.inputField, + false, "basic focus content page urlbar"); + + // When a button in content is focused, pressing F6 should focus the urlbar. + yield* expectFocusOnF6(false, "html1", "html1", + true, "basic focus content page with button focused"); + + return ContentTask.spawn(gBrowser.selectedBrowser, { }, function* () { + return content.document.getElementById("button1").focus(); + }); + + yield* expectFocusOnF6(false, "main-window", gURLBar.inputField, + false, "basic focus content page with button focused urlbar"); + + // The document root should be focused, not the button + yield* expectFocusOnF6(false, "html1", "html1", + true, "basic focus again content page with button focused"); + + // Check to ensure that the root element is focused + let match = yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* () { + return content.document.activeElement == content.document.documentElement; + }); + ok(match, "basic focus again content page with button focused child root is focused"); +}); + +// Open a second tab. Document focus should skip the background tab. +add_task(function* () +{ + yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage2); + + yield* expectFocusOnF6(false, "main-window", gURLBar.inputField, + false, "basic focus content page and second tab urlbar"); + yield* expectFocusOnF6(false, "html2", "html2", + true, "basic focus content page with second tab"); + + yield BrowserTestUtils.removeTab(gBrowser.selectedTab); +}); + +// Shift+F6 should navigate backwards. There's only one document here so the effect +// is the same. +add_task(function* () +{ + gURLBar.focus(); + yield* expectFocusOnF6(true, "html1", "html1", + true, "back focus content page"); + yield* expectFocusOnF6(true, "main-window", gURLBar.inputField, + false, "back focus content page urlbar"); +}); + +// Open the sidebar and navigate between the sidebar, content and top-level window +add_task(function* () +{ + let sidebar = document.getElementById("sidebar"); + + let loadPromise = BrowserTestUtils.waitForEvent(sidebar, "load", true); + SidebarUI.toggle('viewBookmarksSidebar'); + yield loadPromise; + + + gURLBar.focus(); + yield* expectFocusOnF6(false, "bookmarksPanel", + sidebar.contentDocument.getElementById("search-box").inputField, + false, "focus with sidebar open sidebar"); + yield* expectFocusOnF6(false, "html1", "html1", + true, "focus with sidebar open content"); + yield* expectFocusOnF6(false, "main-window", gURLBar.inputField, + false, "focus with sidebar urlbar"); + + // Now go backwards + yield* expectFocusOnF6(true, "html1", "html1", + true, "back focus with sidebar open content"); + yield* expectFocusOnF6(true, "bookmarksPanel", + sidebar.contentDocument.getElementById("search-box").inputField, + false, "back focus with sidebar open sidebar"); + yield* expectFocusOnF6(true, "main-window", gURLBar.inputField, + false, "back focus with sidebar urlbar"); + + SidebarUI.toggle('viewBookmarksSidebar'); +}); + +// Navigate when the downloads panel is open +add_task(function* () +{ + yield pushPrefs(["accessibility.tabfocus", 7]); + + let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown", true); + EventUtils.synthesizeMouseAtCenter(document.getElementById("downloads-button"), { }); + yield popupShownPromise; + + gURLBar.focus(); + yield* expectFocusOnF6(false, "main-window", document.getElementById("downloadsHistory"), + false, "focus with downloads panel open panel"); + yield* expectFocusOnF6(false, "html1", "html1", + true, "focus with downloads panel open"); + yield* expectFocusOnF6(false, "main-window", gURLBar.inputField, + false, "focus downloads panel open urlbar"); + + // Now go backwards + yield* expectFocusOnF6(true, "html1", "html1", + true, "back focus with downloads panel open"); + yield* expectFocusOnF6(true, "main-window", document.getElementById("downloadsHistory"), + false, "back focus with downloads panel open"); + yield* expectFocusOnF6(true, "main-window", gURLBar.inputField, + false, "back focus downloads panel open urlbar"); + + let downloadsPopup = document.getElementById("downloadsPanel"); + let popupHiddenPromise = BrowserTestUtils.waitForEvent(downloadsPopup, "popuphidden", true); + downloadsPopup.hidePopup(); + yield popupHiddenPromise; +}); + +// Navigation with a contenteditable body +add_task(function* () +{ + yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage3); + + // The body should be focused when it is editable, not the root. + gURLBar.focus(); + yield* expectFocusOnF6(false, "html3", "body3", + true, "focus with contenteditable body"); + yield* expectFocusOnF6(false, "main-window", gURLBar.inputField, + false, "focus with contenteditable body urlbar"); + + // Now go backwards + + yield* expectFocusOnF6(false, "html3", "body3", + true, "back focus with contenteditable body"); + yield* expectFocusOnF6(false, "main-window", gURLBar.inputField, + false, "back focus with contenteditable body urlbar"); + + yield BrowserTestUtils.removeTab(gBrowser.selectedTab); +}); + +// Navigation with a frameset loaded +add_task(function* () +{ + yield BrowserTestUtils.openNewForegroundTab(gBrowser, + "http://mochi.test:8888/browser/browser/base/content/test/general/file_documentnavigation_frameset.html"); + + gURLBar.focus(); + yield* expectFocusOnF6(false, "htmlframe1", "htmlframe1", + true, "focus on frameset frame 0"); + yield* expectFocusOnF6(false, "htmlframe2", "htmlframe2", + true, "focus on frameset frame 1"); + yield* expectFocusOnF6(false, "htmlframe3", "htmlframe3", + true, "focus on frameset frame 2"); + yield* expectFocusOnF6(false, "htmlframe4", "htmlframe4", + true, "focus on frameset frame 3"); + yield* expectFocusOnF6(false, "main-window", gURLBar.inputField, + false, "focus on frameset frame urlbar"); + + yield* expectFocusOnF6(true, "htmlframe4", "htmlframe4", + true, "back focus on frameset frame 3"); + yield* expectFocusOnF6(true, "htmlframe3", "htmlframe3", + true, "back focus on frameset frame 2"); + yield* expectFocusOnF6(true, "htmlframe2", "htmlframe2", + true, "back focus on frameset frame 1"); + yield* expectFocusOnF6(true, "htmlframe1", "htmlframe1", + true, "back focus on frameset frame 0"); + yield* expectFocusOnF6(true, "main-window", gURLBar.inputField, + false, "back focus on frameset frame urlbar"); + + yield BrowserTestUtils.removeTab(gBrowser.selectedTab); +}); + +// XXXndeakin add tests for browsers inside of panels diff --git a/browser/base/content/test/general/file_documentnavigation_frameset.html b/browser/base/content/test/general/file_documentnavigation_frameset.html new file mode 100644 index 000000000000..beb01addfc56 --- /dev/null +++ b/browser/base/content/test/general/file_documentnavigation_frameset.html @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/dom/tests/mochitest/chrome/window_focus_docnav.xul b/dom/tests/mochitest/chrome/window_focus_docnav.xul index b51ae340cded..d2b6e50fef75 100644 --- a/dom/tests/mochitest/chrome/window_focus_docnav.xul +++ b/dom/tests/mochitest/chrome/window_focus_docnav.xul @@ -9,13 +9,13 @@ - - - + + + @@ -62,11 +62,11 @@ function runTests(panel, popupCount) var childwin = document.getElementById("browser").contentWindow; if (popupCount) { + next(window, document.getElementById("p1textbox").inputField, "First into popup 1 with " + popupCount); + if (popupCount == 2) { next(window, document.getElementById("p2textbox").inputField, "First into popup 2 with " + popupCount); } - - next(window, document.getElementById("p1textbox").inputField, "First into popup 1 with " + popupCount); } next(childwin.frames[0], childwin.frames[0].document.documentElement, "First with " + popupCount); @@ -74,11 +74,11 @@ function runTests(panel, popupCount) previous(childwin.frames[0], childwin.frames[0].document.documentElement, "Second back with " + popupCount); if (popupCount) { - previous(window, document.getElementById("p1textbox").inputField, "First back from popup 1 with " + popupCount); - if (popupCount == 2) { previous(window, document.getElementById("p2textbox").inputField, "First back from popup 2 with " + popupCount); } + + previous(window, document.getElementById("p1textbox").inputField, "First back from popup 1 with " + popupCount); } previous(window, document.getElementById("textbox").inputField, "First back with " + popupCount);