diff options
Diffstat (limited to 'toolkit/content/tests/browser/browser_findbar.js')
-rw-r--r-- | toolkit/content/tests/browser/browser_findbar.js | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/toolkit/content/tests/browser/browser_findbar.js b/toolkit/content/tests/browser/browser_findbar.js new file mode 100644 index 000000000..1ab06f632 --- /dev/null +++ b/toolkit/content/tests/browser/browser_findbar.js @@ -0,0 +1,249 @@ +XPCOMUtils.defineLazyModuleGetter(this, "Promise", + "resource://gre/modules/Promise.jsm"); +Components.utils.import("resource://gre/modules/Timer.jsm", this); + +const TEST_PAGE_URI = "data:text/html;charset=utf-8,The letter s."; +// Using 'javascript' schema to bypass E10SUtils.canLoadURIInProcess, because +// it does not allow 'data:' URI to be loaded in the parent process. +const E10S_PARENT_TEST_PAGE_URI = "javascript:document.write('The letter s.');"; + +/** + * Makes sure that the findbar hotkeys (' and /) event listeners + * are added to the system event group and do not get blocked + * by calling stopPropagation on a keypress event on a page. + */ +add_task(function* test_hotkey_event_propagation() { + info("Ensure hotkeys are not affected by stopPropagation."); + + // Opening new tab + let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI); + let browser = gBrowser.getBrowserForTab(tab); + let findbar = gBrowser.getFindBar(); + + // Pressing these keys open the findbar. + const HOTKEYS = ["/", "'"]; + + // Checking if findbar appears when any hotkey is pressed. + for (let key of HOTKEYS) { + is(findbar.hidden, true, "Findbar is hidden now."); + gBrowser.selectedTab = tab; + yield SimpleTest.promiseFocus(gBrowser.selectedBrowser); + yield BrowserTestUtils.sendChar(key, browser); + is(findbar.hidden, false, "Findbar should not be hidden."); + yield closeFindbarAndWait(findbar); + } + + // Stop propagation for all keyboard events. + let frameScript = () => { + const stopPropagation = e => e.stopImmediatePropagation(); + let window = content.document.defaultView; + window.removeEventListener("keydown", stopPropagation); + window.removeEventListener("keypress", stopPropagation); + window.removeEventListener("keyup", stopPropagation); + }; + + let mm = browser.messageManager; + mm.loadFrameScript("data:,(" + frameScript.toString() + ")();", false); + + // Checking if findbar still appears when any hotkey is pressed. + for (let key of HOTKEYS) { + is(findbar.hidden, true, "Findbar is hidden now."); + gBrowser.selectedTab = tab; + yield SimpleTest.promiseFocus(gBrowser.selectedBrowser); + yield BrowserTestUtils.sendChar(key, browser); + is(findbar.hidden, false, "Findbar should not be hidden."); + yield closeFindbarAndWait(findbar); + } + + gBrowser.removeTab(tab); +}); + +add_task(function* test_not_found() { + info("Check correct 'Phrase not found' on new tab"); + + let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI); + + // Search for the first word. + yield promiseFindFinished("--- THIS SHOULD NEVER MATCH ---", false); + let findbar = gBrowser.getFindBar(); + is(findbar._findStatusDesc.textContent, findbar._notFoundStr, + "Findbar status text should be 'Phrase not found'"); + + gBrowser.removeTab(tab); +}); + +add_task(function* test_found() { + let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI); + + // Search for a string that WILL be found, with 'Highlight All' on + yield promiseFindFinished("S", true); + ok(!gBrowser.getFindBar()._findStatusDesc.textContent, + "Findbar status should be empty"); + + gBrowser.removeTab(tab); +}); + +// Setting first findbar to case-sensitive mode should not affect +// new tab find bar. +add_task(function* test_tabwise_case_sensitive() { + let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI); + let findbar1 = gBrowser.getFindBar(); + + let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI); + let findbar2 = gBrowser.getFindBar(); + + // Toggle case sensitivity for first findbar + findbar1.getElement("find-case-sensitive").click(); + + gBrowser.selectedTab = tab1; + + // Not found for first tab. + yield promiseFindFinished("S", true); + is(findbar1._findStatusDesc.textContent, findbar1._notFoundStr, + "Findbar status text should be 'Phrase not found'"); + + gBrowser.selectedTab = tab2; + + // But it didn't affect the second findbar. + yield promiseFindFinished("S", true); + ok(!findbar2._findStatusDesc.textContent, "Findbar status should be empty"); + + gBrowser.removeTab(tab1); + gBrowser.removeTab(tab2); +}); + +/** + * Navigating from a web page (for example mozilla.org) to an internal page + * (like about:addons) might trigger a change of browser's remoteness. + * 'Remoteness change' means that rendering page content moves from child + * process into the parent process or the other way around. + * This test ensures that findbar properly handles such a change. + */ +add_task(function* test_reinitialization_at_remoteness_change() { + // This test only makes sence in e10s evironment. + if (!gMultiProcessBrowser) { + info("Skipping this test because of non-e10s environment."); + return; + } + + info("Ensure findbar re-initialization at remoteness change."); + + // Load a remote page and trigger findbar construction. + let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI); + let browser = gBrowser.getBrowserForTab(tab); + let findbar = gBrowser.getFindBar(); + + // Findbar should operate normally. + yield promiseFindFinished("z", false); + is(findbar._findStatusDesc.textContent, findbar._notFoundStr, + "Findbar status text should be 'Phrase not found'"); + + yield promiseFindFinished("s", false); + ok(!findbar._findStatusDesc.textContent, "Findbar status should be empty"); + + // Moving browser into the parent process and reloading sample data. + ok(browser.isRemoteBrowser, "Browser should be remote now."); + yield promiseRemotenessChange(tab, false); + yield BrowserTestUtils.loadURI(browser, E10S_PARENT_TEST_PAGE_URI); + ok(!browser.isRemoteBrowser, "Browser should not be remote any more."); + + // Findbar should keep operating normally after remoteness change. + yield promiseFindFinished("z", false); + is(findbar._findStatusDesc.textContent, findbar._notFoundStr, + "Findbar status text should be 'Phrase not found'"); + + yield promiseFindFinished("s", false); + ok(!findbar._findStatusDesc.textContent, "Findbar status should be empty"); + + yield BrowserTestUtils.removeTab(tab); +}); + +/** + * Ensure that the initial typed characters aren't lost immediately after + * opening the find bar. + */ +add_task(function* () { + // This test only makes sence in e10s evironment. + if (!gMultiProcessBrowser) { + info("Skipping this test because of non-e10s environment."); + return; + } + + let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI); + let browser = tab.linkedBrowser; + + ok(!gFindBarInitialized, "findbar isn't initialized yet"); + + let findBar = gFindBar; + let initialValue = findBar._findField.value; + + EventUtils.synthesizeKey("f", { accelKey: true }, window); + + let promises = [ + BrowserTestUtils.sendChar("a", browser), + BrowserTestUtils.sendChar("b", browser), + BrowserTestUtils.sendChar("c", browser) + ]; + + isnot(document.activeElement, findBar._findField.inputField, + "findbar is not yet focused"); + is(findBar._findField.value, initialValue, "still has initial find query"); + + yield Promise.all(promises); + is(document.activeElement, findBar._findField.inputField, + "findbar is now focused"); + is(findBar._findField.value, "abc", "abc fully entered as find query"); + + yield BrowserTestUtils.removeTab(tab); +}); + +function promiseFindFinished(searchText, highlightOn) { + let deferred = Promise.defer(); + + let findbar = gBrowser.getFindBar(); + findbar.startFind(findbar.FIND_NORMAL); + let highlightElement = findbar.getElement("highlight"); + if (highlightElement.checked != highlightOn) + highlightElement.click(); + executeSoon(() => { + findbar._findField.value = searchText; + + let resultListener; + // When highlighting is on the finder sends a second "FOUND" message after + // the search wraps. This causes timing problems with e10s. waitMore + // forces foundOrTimeout wait for the second "FOUND" message before + // resolving the promise. + let waitMore = highlightOn; + let findTimeout = setTimeout(() => foundOrTimedout(null), 2000); + let foundOrTimedout = function(aData) { + if (aData !== null && waitMore) { + waitMore = false; + return; + } + if (aData === null) + info("Result listener not called, timeout reached."); + clearTimeout(findTimeout); + findbar.browser.finder.removeResultListener(resultListener); + deferred.resolve(); + } + + resultListener = { + onFindResult: foundOrTimedout + }; + findbar.browser.finder.addResultListener(resultListener); + findbar._find(); + }); + + return deferred.promise; +} + +function promiseRemotenessChange(tab, shouldBeRemote) { + return new Promise((resolve) => { + let browser = gBrowser.getBrowserForTab(tab); + tab.addEventListener("TabRemotenessChange", function listener() { + tab.removeEventListener("TabRemotenessChange", listener); + resolve(); + }); + gBrowser.updateBrowserRemoteness(browser, shouldBeRemote); + }); +} |