summaryrefslogtreecommitdiffstats
path: root/browser/components/translation/test/browser_translation_exceptions.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/translation/test/browser_translation_exceptions.js')
-rw-r--r--browser/components/translation/test/browser_translation_exceptions.js327
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();
+ }
+}
+
+];