diff options
Diffstat (limited to 'browser/components/translation/test/browser_translation_exceptions.js')
-rw-r--r-- | browser/components/translation/test/browser_translation_exceptions.js | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/browser/components/translation/test/browser_translation_exceptions.js b/browser/components/translation/test/browser_translation_exceptions.js new file mode 100644 index 000000000..bf6875768 --- /dev/null +++ b/browser/components/translation/test/browser_translation_exceptions.js @@ -0,0 +1,327 @@ +/* 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/. */ + +// tests the translation infobar, using a fake 'Translation' implementation. + +var tmp = {}; +Cu.import("resource:///modules/translation/Translation.jsm", tmp); +Cu.import("resource://gre/modules/Promise.jsm", tmp); +var {Translation, Promise} = tmp; + +const kLanguagesPref = "browser.translation.neverForLanguages"; +const kShowUIPref = "browser.translation.ui.show"; + +function test() { + waitForExplicitFinish(); + + Services.prefs.setBoolPref(kShowUIPref, true); + let tab = gBrowser.addTab(); + gBrowser.selectedTab = tab; + registerCleanupFunction(function () { + gBrowser.removeTab(tab); + Services.prefs.clearUserPref(kShowUIPref); + }); + tab.linkedBrowser.addEventListener("load", function onload() { + tab.linkedBrowser.removeEventListener("load", onload, true); + Task.spawn(function* () { + for (let test of gTests) { + info(test.desc); + yield test.run(); + } + }).then(finish, ex => { + ok(false, "Unexpected Exception: " + ex); + finish(); + }); + }, true); + + content.location = "http://example.com/"; +} + +function getLanguageExceptions() { + let langs = Services.prefs.getCharPref(kLanguagesPref); + return langs ? langs.split(",") : []; +} + +function getDomainExceptions() { + let results = []; + let enumerator = Services.perms.enumerator; + while (enumerator.hasMoreElements()) { + let perm = enumerator.getNext().QueryInterface(Ci.nsIPermission); + + if (perm.type == "translate" && + perm.capability == Services.perms.DENY_ACTION) + results.push(perm.principal); + } + + return results; +} + +function getInfoBar() { + let deferred = Promise.defer(); + let infobar = + gBrowser.getNotificationBox().getNotificationWithValue("translation"); + + if (!infobar) { + deferred.resolve(); + } else { + // Wait for all animations to finish + Promise.all(infobar.getAnimations().map(animation => animation.finished)) + .then(() => deferred.resolve(infobar)); + } + + return deferred.promise; +} + +function openPopup(aPopup) { + let deferred = Promise.defer(); + + aPopup.addEventListener("popupshown", function popupShown() { + aPopup.removeEventListener("popupshown", popupShown); + deferred.resolve(); + }); + + aPopup.focus(); + // One down event to open the popup. + EventUtils.synthesizeKey("VK_DOWN", + { altKey: !navigator.platform.includes("Mac") }); + + return deferred.promise; +} + +function waitForWindowLoad(aWin) { + let deferred = Promise.defer(); + + aWin.addEventListener("load", function onload() { + aWin.removeEventListener("load", onload, true); + deferred.resolve(); + }, true); + + return deferred.promise; +} + + +var gTests = [ + +{ + desc: "clean exception lists at startup", + run: function checkNeverForLanguage() { + is(getLanguageExceptions().length, 0, + "we start with an empty list of languages to never translate"); + is(getDomainExceptions().length, 0, + "we start with an empty list of sites to never translate"); + } +}, + +{ + desc: "never for language", + run: function* checkNeverForLanguage() { + // Show the infobar for example.com and fr. + Translation.documentStateReceived(gBrowser.selectedBrowser, + {state: Translation.STATE_OFFER, + originalShown: true, + detectedLanguage: "fr"}); + let notif = yield getInfoBar(); + ok(notif, "the infobar is visible"); + let ui = gBrowser.selectedBrowser.translationUI; + let uri = gBrowser.selectedBrowser.currentURI; + ok(ui.shouldShowInfoBar(uri, "fr"), + "check shouldShowInfoBar initially returns true"); + + // Open the "options" drop down. + yield openPopup(notif._getAnonElt("options")); + ok(notif._getAnonElt("options").getAttribute("open"), + "the options menu is open"); + + // Check that the item is not disabled. + ok(!notif._getAnonElt("neverForLanguage").disabled, + "The 'Never translate <language>' item isn't disabled"); + + // Click the 'Never for French' item. + notif._getAnonElt("neverForLanguage").click(); + notif = yield getInfoBar(); + ok(!notif, "infobar hidden"); + + // Check this has been saved to the exceptions list. + let langs = getLanguageExceptions(); + is(langs.length, 1, "one language in the exception list"); + is(langs[0], "fr", "correct language in the exception list"); + ok(!ui.shouldShowInfoBar(uri, "fr"), + "the infobar wouldn't be shown anymore"); + + // Reopen the infobar. + PopupNotifications.getNotification("translate").anchorElement.click(); + notif = yield getInfoBar(); + // Open the "options" drop down. + yield openPopup(notif._getAnonElt("options")); + ok(notif._getAnonElt("neverForLanguage").disabled, + "The 'Never translate French' item is disabled"); + + // Cleanup. + Services.prefs.setCharPref(kLanguagesPref, ""); + notif.close(); + } +}, + +{ + desc: "never for site", + run: function* checkNeverForSite() { + // Show the infobar for example.com and fr. + Translation.documentStateReceived(gBrowser.selectedBrowser, + {state: Translation.STATE_OFFER, + originalShown: true, + detectedLanguage: "fr"}); + let notif = yield getInfoBar(); + ok(notif, "the infobar is visible"); + let ui = gBrowser.selectedBrowser.translationUI; + let uri = gBrowser.selectedBrowser.currentURI; + ok(ui.shouldShowInfoBar(uri, "fr"), + "check shouldShowInfoBar initially returns true"); + + // Open the "options" drop down. + yield openPopup(notif._getAnonElt("options")); + ok(notif._getAnonElt("options").getAttribute("open"), + "the options menu is open"); + + // Check that the item is not disabled. + ok(!notif._getAnonElt("neverForSite").disabled, + "The 'Never translate site' item isn't disabled"); + + // Click the 'Never for French' item. + notif._getAnonElt("neverForSite").click(); + notif = yield getInfoBar(); + ok(!notif, "infobar hidden"); + + // Check this has been saved to the exceptions list. + let sites = getDomainExceptions(); + is(sites.length, 1, "one site in the exception list"); + is(sites[0].origin, "http://example.com", "correct site in the exception list"); + ok(!ui.shouldShowInfoBar(uri, "fr"), + "the infobar wouldn't be shown anymore"); + + // Reopen the infobar. + PopupNotifications.getNotification("translate").anchorElement.click(); + notif = yield getInfoBar(); + // Open the "options" drop down. + yield openPopup(notif._getAnonElt("options")); + ok(notif._getAnonElt("neverForSite").disabled, + "The 'Never translate French' item is disabled"); + + // Cleanup. + Services.perms.remove(makeURI("http://example.com"), "translate"); + notif.close(); + } +}, + +{ + desc: "language exception list", + run: function* checkLanguageExceptions() { + // Put 2 languages in the pref before opening the window to check + // the list is displayed on load. + Services.prefs.setCharPref(kLanguagesPref, "fr,de"); + + // Open the translation exceptions dialog. + let win = openDialog("chrome://browser/content/preferences/translation.xul", + "Browser:TranslationExceptions", + "", null); + yield waitForWindowLoad(win); + + // Check that the list of language exceptions is loaded. + let getById = win.document.getElementById.bind(win.document); + let tree = getById("languagesTree"); + let remove = getById("removeLanguage"); + let removeAll = getById("removeAllLanguages"); + is(tree.view.rowCount, 2, "The language exceptions list has 2 items"); + ok(remove.disabled, "The 'Remove Language' button is disabled"); + ok(!removeAll.disabled, "The 'Remove All Languages' button is enabled"); + + // Select the first item. + tree.view.selection.select(0); + ok(!remove.disabled, "The 'Remove Language' button is enabled"); + + // Click the 'Remove' button. + remove.click(); + is(tree.view.rowCount, 1, "The language exceptions now contains 1 item"); + is(getLanguageExceptions().length, 1, "One exception in the pref"); + + // Clear the pref, and check the last item is removed from the display. + Services.prefs.setCharPref(kLanguagesPref, ""); + is(tree.view.rowCount, 0, "The language exceptions list is empty"); + ok(remove.disabled, "The 'Remove Language' button is disabled"); + ok(removeAll.disabled, "The 'Remove All Languages' button is disabled"); + + // Add an item and check it appears. + Services.prefs.setCharPref(kLanguagesPref, "fr"); + is(tree.view.rowCount, 1, "The language exceptions list has 1 item"); + ok(remove.disabled, "The 'Remove Language' button is disabled"); + ok(!removeAll.disabled, "The 'Remove All Languages' button is enabled"); + + // Click the 'Remove All' button. + removeAll.click(); + is(tree.view.rowCount, 0, "The language exceptions list is empty"); + ok(remove.disabled, "The 'Remove Language' button is disabled"); + ok(removeAll.disabled, "The 'Remove All Languages' button is disabled"); + is(Services.prefs.getCharPref(kLanguagesPref), "", "The pref is empty"); + + win.close(); + } +}, + +{ + desc: "domains exception list", + run: function* checkDomainExceptions() { + // Put 2 exceptions before opening the window to check the list is + // displayed on load. + let perms = Services.perms; + perms.add(makeURI("http://example.org"), "translate", perms.DENY_ACTION); + perms.add(makeURI("http://example.com"), "translate", perms.DENY_ACTION); + + // Open the translation exceptions dialog. + let win = openDialog("chrome://browser/content/preferences/translation.xul", + "Browser:TranslationExceptions", + "", null); + yield waitForWindowLoad(win); + + // Check that the list of language exceptions is loaded. + let getById = win.document.getElementById.bind(win.document); + let tree = getById("sitesTree"); + let remove = getById("removeSite"); + let removeAll = getById("removeAllSites"); + is(tree.view.rowCount, 2, "The sites exceptions list has 2 items"); + ok(remove.disabled, "The 'Remove Site' button is disabled"); + ok(!removeAll.disabled, "The 'Remove All Sites' button is enabled"); + + // Select the first item. + tree.view.selection.select(0); + ok(!remove.disabled, "The 'Remove Site' button is enabled"); + + // Click the 'Remove' button. + remove.click(); + is(tree.view.rowCount, 1, "The site exceptions now contains 1 item"); + is(getDomainExceptions().length, 1, "One exception in the permissions"); + + // Clear the permissions, and check the last item is removed from the display. + perms.remove(makeURI("http://example.org"), "translate"); + perms.remove(makeURI("http://example.com"), "translate"); + is(tree.view.rowCount, 0, "The site exceptions list is empty"); + ok(remove.disabled, "The 'Remove Site' button is disabled"); + ok(removeAll.disabled, "The 'Remove All Site' button is disabled"); + + // Add an item and check it appears. + perms.add(makeURI("http://example.com"), "translate", perms.DENY_ACTION); + is(tree.view.rowCount, 1, "The site exceptions list has 1 item"); + ok(remove.disabled, "The 'Remove Site' button is disabled"); + ok(!removeAll.disabled, "The 'Remove All Sites' button is enabled"); + + // Click the 'Remove All' button. + removeAll.click(); + is(tree.view.rowCount, 0, "The site exceptions list is empty"); + ok(remove.disabled, "The 'Remove Site' button is disabled"); + ok(removeAll.disabled, "The 'Remove All Sites' button is disabled"); + is(getDomainExceptions().length, 0, "No exceptions in the permissions"); + + win.close(); + } +} + +]; |