diff options
Diffstat (limited to 'browser/components/translation/test/browser_translation_infobar.js')
-rw-r--r-- | browser/components/translation/test/browser_translation_infobar.js | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/browser/components/translation/test/browser_translation_infobar.js b/browser/components/translation/test/browser_translation_infobar.js new file mode 100644 index 000000000..c16b3939c --- /dev/null +++ b/browser/components/translation/test/browser_translation_infobar.js @@ -0,0 +1,216 @@ +/* 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); +var {Translation} = tmp; + +const kShowUIPref = "browser.translation.ui.show"; + +function waitForCondition(condition, nextTest, errorMsg) { + var tries = 0; + var interval = setInterval(function() { + if (tries >= 30) { + ok(false, errorMsg); + moveOn(); + } + var conditionPassed; + try { + conditionPassed = condition(); + } catch (e) { + ok(false, e + "\n" + e.stack); + conditionPassed = false; + } + if (conditionPassed) { + moveOn(); + } + tries++; + }, 100); + var moveOn = function() { clearInterval(interval); nextTest(); }; +} + +var TranslationStub = { + translate: function(aFrom, aTo) { + this.state = Translation.STATE_TRANSLATING; + this.translatedFrom = aFrom; + this.translatedTo = aTo; + }, + + _reset: function() { + this.translatedFrom = ""; + this.translatedTo = ""; + }, + + failTranslation: function() { + this.state = Translation.STATE_ERROR; + this._reset(); + }, + + finishTranslation: function() { + this.showTranslatedContent(); + this.state = Translation.STATE_TRANSLATED; + this._reset(); + } +}; + +function showTranslationUI(aDetectedLanguage) { + let browser = gBrowser.selectedBrowser; + Translation.documentStateReceived(browser, {state: Translation.STATE_OFFER, + originalShown: true, + detectedLanguage: aDetectedLanguage}); + let ui = browser.translationUI; + for (let name of ["translate", "_reset", "failTranslation", "finishTranslation"]) + ui[name] = TranslationStub[name]; + return ui.notificationBox.getNotificationWithValue("translation"); +} + +function hasTranslationInfoBar() { + return !!gBrowser.getNotificationBox().getNotificationWithValue("translation"); +} + +function test() { + waitForExplicitFinish(); + + Services.prefs.setBoolPref(kShowUIPref, true); + let tab = gBrowser.addTab(); + gBrowser.selectedTab = tab; + tab.linkedBrowser.addEventListener("load", function onload() { + tab.linkedBrowser.removeEventListener("load", onload, true); + TranslationStub.browser = gBrowser.selectedBrowser; + registerCleanupFunction(function () { + gBrowser.removeTab(tab); + Services.prefs.clearUserPref(kShowUIPref); + }); + run_tests(() => { + finish(); + }); + }, true); + + content.location = "data:text/plain,test page"; +} + +function checkURLBarIcon(aExpectTranslated = false) { + is(!PopupNotifications.getNotification("translate"), aExpectTranslated, + "translate icon " + (aExpectTranslated ? "not " : "") + "shown"); + is(!!PopupNotifications.getNotification("translated"), aExpectTranslated, + "translated icon " + (aExpectTranslated ? "" : "not ") + "shown"); +} + +function run_tests(aFinishCallback) { + info("Show an info bar saying the current page is in French"); + let notif = showTranslationUI("fr"); + is(notif.state, Translation.STATE_OFFER, "the infobar is offering translation"); + is(notif._getAnonElt("detectedLanguage").value, "fr", "The detected language is displayed"); + checkURLBarIcon(); + + info("Click the 'Translate' button"); + notif._getAnonElt("translate").click(); + is(notif.state, Translation.STATE_TRANSLATING, "the infobar is in the translating state"); + ok(!!notif.translation.translatedFrom, "Translation.translate has been called"); + is(notif.translation.translatedFrom, "fr", "from language correct"); + is(notif.translation.translatedTo, Translation.defaultTargetLanguage, "from language correct"); + checkURLBarIcon(); + + info("Make the translation fail and check we are in the error state."); + notif.translation.failTranslation(); + is(notif.state, Translation.STATE_ERROR, "infobar in the error state"); + checkURLBarIcon(); + + info("Click the try again button"); + notif._getAnonElt("tryAgain").click(); + is(notif.state, Translation.STATE_TRANSLATING, "infobar in the translating state"); + ok(!!notif.translation.translatedFrom, "Translation.translate has been called"); + is(notif.translation.translatedFrom, "fr", "from language correct"); + is(notif.translation.translatedTo, Translation.defaultTargetLanguage, "from language correct"); + checkURLBarIcon(); + + info("Make the translation succeed and check we are in the 'translated' state."); + notif.translation.finishTranslation(); + is(notif.state, Translation.STATE_TRANSLATED, "infobar in the translated state"); + checkURLBarIcon(true); + + info("Test 'Show original' / 'Show Translation' buttons."); + // First check 'Show Original' is visible and 'Show Translation' is hidden. + ok(!notif._getAnonElt("showOriginal").hidden, "'Show Original' button visible"); + ok(notif._getAnonElt("showTranslation").hidden, "'Show Translation' button hidden"); + // Click the button. + notif._getAnonElt("showOriginal").click(); + // Check that the url bar icon shows the original content is displayed. + checkURLBarIcon(); + // And the 'Show Translation' button is now visible. + ok(notif._getAnonElt("showOriginal").hidden, "'Show Original' button hidden"); + ok(!notif._getAnonElt("showTranslation").hidden, "'Show Translation' button visible"); + // Click the 'Show Translation' button + notif._getAnonElt("showTranslation").click(); + // Check that the url bar icon shows the page is translated. + checkURLBarIcon(true); + // Check that the 'Show Original' button is visible again. + ok(!notif._getAnonElt("showOriginal").hidden, "'Show Original' button visible"); + ok(notif._getAnonElt("showTranslation").hidden, "'Show Translation' button hidden"); + + info("Check that changing the source language causes a re-translation"); + let from = notif._getAnonElt("fromLanguage"); + from.value = "es"; + from.doCommand(); + is(notif.state, Translation.STATE_TRANSLATING, "infobar in the translating state"); + ok(!!notif.translation.translatedFrom, "Translation.translate has been called"); + is(notif.translation.translatedFrom, "es", "from language correct"); + is(notif.translation.translatedTo, Translation.defaultTargetLanguage, "to language correct"); + // We want to show the 'translated' icon while re-translating, + // because we are still displaying the previous translation. + checkURLBarIcon(true); + notif.translation.finishTranslation(); + checkURLBarIcon(true); + + info("Check that changing the target language causes a re-translation"); + let to = notif._getAnonElt("toLanguage"); + to.value = "pl"; + to.doCommand(); + is(notif.state, Translation.STATE_TRANSLATING, "infobar in the translating state"); + ok(!!notif.translation.translatedFrom, "Translation.translate has been called"); + is(notif.translation.translatedFrom, "es", "from language correct"); + is(notif.translation.translatedTo, "pl", "to language correct"); + checkURLBarIcon(true); + notif.translation.finishTranslation(); + checkURLBarIcon(true); + + // Cleanup. + notif.close(); + + info("Reopen the info bar to check that it's possible to override the detected language."); + notif = showTranslationUI("fr"); + is(notif.state, Translation.STATE_OFFER, "the infobar is offering translation"); + is(notif._getAnonElt("detectedLanguage").value, "fr", "The detected language is displayed"); + // Change the language and click 'Translate' + notif._getAnonElt("detectedLanguage").value = "ja"; + notif._getAnonElt("translate").click(); + is(notif.state, Translation.STATE_TRANSLATING, "the infobar is in the translating state"); + ok(!!notif.translation.translatedFrom, "Translation.translate has been called"); + is(notif.translation.translatedFrom, "ja", "from language correct"); + notif.close(); + + info("Reopen to check the 'Not Now' button closes the notification."); + notif = showTranslationUI("fr"); + is(hasTranslationInfoBar(), true, "there's a 'translate' notification"); + notif._getAnonElt("notNow").click(); + is(hasTranslationInfoBar(), false, "no 'translate' notification after clicking 'not now'"); + + info("Reopen to check the url bar icon closes the notification."); + notif = showTranslationUI("fr"); + is(hasTranslationInfoBar(), true, "there's a 'translate' notification"); + PopupNotifications.getNotification("translate").anchorElement.click(); + is(hasTranslationInfoBar(), false, "no 'translate' notification after clicking the url bar icon"); + + info("Check that clicking the url bar icon reopens the info bar"); + checkURLBarIcon(); + // Clicking the anchor element causes a 'showing' event to be sent + // asynchronously to our callback that will then show the infobar. + PopupNotifications.getNotification("translate").anchorElement.click(); + waitForCondition(hasTranslationInfoBar, () => { + ok(hasTranslationInfoBar(), "there's a 'translate' notification"); + aFinishCallback(); + }, "timeout waiting for the info bar to reappear"); +} |