summaryrefslogtreecommitdiffstats
path: root/comm/mail/test/browser/composition/browser_spelling.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/test/browser/composition/browser_spelling.js')
-rw-r--r--comm/mail/test/browser/composition/browser_spelling.js311
1 files changed, 311 insertions, 0 deletions
diff --git a/comm/mail/test/browser/composition/browser_spelling.js b/comm/mail/test/browser/composition/browser_spelling.js
new file mode 100644
index 0000000000..86a1ba9c84
--- /dev/null
+++ b/comm/mail/test/browser/composition/browser_spelling.js
@@ -0,0 +1,311 @@
+/* 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/. */
+
+var { close_compose_window, open_compose_new_mail } = ChromeUtils.import(
+ "resource://testing-common/mozmill/ComposeHelpers.jsm"
+);
+var { maybeOnSpellCheck } = ChromeUtils.importESModule(
+ "resource://testing-common/AsyncSpellCheckTestHelper.sys.mjs"
+);
+
+async function checkMisspelledWords(editor, ...words) {
+ await new Promise(resolve => maybeOnSpellCheck({ editor }, resolve));
+
+ let selection = editor.selectionController.getSelection(
+ Ci.nsISelectionController.SELECTION_SPELLCHECK
+ );
+ Assert.equal(
+ selection.rangeCount,
+ words.length,
+ "correct number of misspellings"
+ );
+ for (let i = 0; i < words.length; i++) {
+ Assert.equal(selection.getRangeAt(i).toString(), words[i]);
+ }
+ return selection;
+}
+
+add_task(async function () {
+ // Install en-NZ dictionary.
+
+ let dictionary = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+ dictionary.initWithPath(getTestFilePath("data/en_NZ"));
+
+ let hunspell = Cc["@mozilla.org/spellchecker/engine;1"].getService(
+ Ci.mozISpellCheckingEngine
+ );
+ hunspell.addDirectory(dictionary);
+
+ // Open a compose window and write a message.
+
+ let cwc = open_compose_new_mail();
+ let composeWindow = cwc.window;
+ let composeDocument = composeWindow.document;
+
+ cwc.window.document.getElementById("msgSubject").focus();
+ EventUtils.sendString(
+ "I went to the harbor in an aluminium boat",
+ cwc.window
+ );
+ cwc.window.document.getElementById("messageEditor").focus();
+ EventUtils.sendString("I maneuvered to the center.\n", cwc.window);
+ cwc.window.document.getElementById("messageEditor").focus();
+ EventUtils.sendString(
+ "The sky was the colour of ochre and the stars shone like jewelry.\n",
+ cwc.window
+ );
+
+ // Check initial spelling.
+
+ let subjectEditor = composeDocument.getElementById("msgSubject").editor;
+ let editorBrowser = composeWindow.GetCurrentEditorElement();
+ let bodyEditor = composeWindow.GetCurrentEditor();
+ let saveButton = composeDocument.getElementById("button-save");
+
+ await checkMisspelledWords(subjectEditor, "aluminium");
+ await checkMisspelledWords(bodyEditor, "colour", "ochre");
+
+ // Check menu items are displayed correctly.
+
+ let shownPromise, hiddenPromise;
+ let contextMenu = composeDocument.getElementById("msgComposeContext");
+ let contextMenuEnabled = composeDocument.getElementById("spellCheckEnable");
+ let optionsMenu = composeDocument.getElementById("optionsMenu");
+ let optionsMenuEnabled = composeDocument.getElementById(
+ "menu_inlineSpellCheck"
+ );
+
+ if (AppConstants.platform != "macosx") {
+ shownPromise = BrowserTestUtils.waitForEvent(optionsMenu, "popupshown");
+ EventUtils.synthesizeMouseAtCenter(optionsMenu, {}, composeWindow);
+ await shownPromise;
+ Assert.equal(
+ optionsMenuEnabled.getAttribute("checked"),
+ "true",
+ "options menu item is checked"
+ );
+ hiddenPromise = BrowserTestUtils.waitForEvent(optionsMenu, "popuphidden");
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, composeWindow);
+ await hiddenPromise;
+ }
+
+ shownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "body",
+ { type: "contextmenu" },
+ editorBrowser
+ );
+ await shownPromise;
+ Assert.equal(
+ contextMenuEnabled.getAttribute("checked"),
+ "true",
+ "context menu item is checked"
+ );
+
+ // Disable the spell checker.
+
+ hiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
+ contextMenu.activateItem(contextMenuEnabled);
+ await hiddenPromise;
+
+ await checkMisspelledWords(subjectEditor);
+ await checkMisspelledWords(bodyEditor);
+
+ // Save the message. The spell checking state shouldn't change.
+
+ EventUtils.synthesizeMouseAtCenter(saveButton, {}, composeWindow);
+ // Clicking the button sets gWindowLocked to true synchronously, so if
+ // gWindowLocked is false, we know that saving has completed.
+ await TestUtils.waitForCondition(
+ () => !composeWindow.gWindowLocked,
+ "window unlocked after saving"
+ );
+
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(resolve => setTimeout(resolve, 500));
+
+ await checkMisspelledWords(subjectEditor);
+ await checkMisspelledWords(bodyEditor);
+
+ // Check menu items are displayed correctly.
+
+ if (AppConstants.platform != "macosx") {
+ shownPromise = BrowserTestUtils.waitForEvent(optionsMenu, "popupshown");
+ EventUtils.synthesizeMouseAtCenter(optionsMenu, {}, composeWindow);
+ await shownPromise;
+ Assert.ok(
+ !optionsMenuEnabled.hasAttribute("checked"),
+ "options menu item is not checked"
+ );
+ hiddenPromise = BrowserTestUtils.waitForEvent(optionsMenu, "popuphidden");
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, composeWindow);
+ await hiddenPromise;
+ }
+
+ shownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "body",
+ { type: "contextmenu" },
+ editorBrowser
+ );
+ await shownPromise;
+ Assert.equal(
+ contextMenuEnabled.getAttribute("checked"),
+ "false",
+ "context menu item is not checked"
+ );
+
+ // Enable the spell checker.
+
+ hiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
+ contextMenu.activateItem(contextMenuEnabled);
+ await hiddenPromise;
+
+ await checkMisspelledWords(subjectEditor, "aluminium");
+ await checkMisspelledWords(bodyEditor, "colour", "ochre");
+
+ // Save the message. The spell checking state shouldn't change.
+
+ EventUtils.synthesizeMouseAtCenter(saveButton, {}, composeWindow);
+ // Clicking the button sets gWindowLocked to true synchronously, so if
+ // gWindowLocked is false, we know that saving has completed.
+ await TestUtils.waitForCondition(
+ () => !composeWindow.gWindowLocked,
+ "window unlocked after saving"
+ );
+
+ await checkMisspelledWords(subjectEditor, "aluminium");
+ await checkMisspelledWords(bodyEditor, "colour", "ochre");
+
+ // Add language.
+
+ let statusButton = composeDocument.getElementById("languageStatusButton");
+ let languageList = composeDocument.getElementById("languageMenuList");
+
+ shownPromise = BrowserTestUtils.waitForEvent(languageList, "popupshown");
+ EventUtils.synthesizeMouseAtCenter(statusButton, {}, composeWindow);
+ await shownPromise;
+
+ Assert.equal(languageList.childElementCount, 4);
+ Assert.equal(languageList.children[0].value, "en-NZ");
+ Assert.equal(languageList.children[0].getAttribute("checked"), "false");
+ Assert.equal(languageList.children[1].value, "en-US");
+ Assert.equal(languageList.children[1].getAttribute("checked"), "true");
+ Assert.equal(languageList.children[2].localName, "menuseparator");
+ Assert.equal(
+ languageList.children[3].dataset.l10nId,
+ "spell-add-dictionaries"
+ );
+
+ hiddenPromise = BrowserTestUtils.waitForEvent(languageList, "popuphidden");
+ languageList.activateItem(languageList.children[0]);
+ await TestUtils.waitForCondition(
+ () => languageList.children[0].getAttribute("checked") == "true",
+ "en-NZ menu item checked"
+ );
+ await TestUtils.waitForCondition(
+ () => composeWindow.gActiveDictionaries.has("en-NZ"),
+ "en-NZ added to dictionaries"
+ );
+ languageList.hidePopup();
+ await hiddenPromise;
+
+ Assert.deepEqual(
+ [...composeWindow.gActiveDictionaries],
+ ["en-US", "en-NZ"],
+ "correct dictionaries active"
+ );
+ await checkMisspelledWords(subjectEditor);
+ await checkMisspelledWords(bodyEditor);
+
+ // Remove language.
+
+ shownPromise = BrowserTestUtils.waitForEvent(languageList, "popupshown");
+ EventUtils.synthesizeMouseAtCenter(statusButton, {}, composeWindow);
+ await shownPromise;
+
+ Assert.equal(languageList.childElementCount, 4);
+ Assert.equal(languageList.children[0].value, "en-NZ");
+ Assert.equal(languageList.children[0].getAttribute("checked"), "true");
+ Assert.equal(languageList.children[1].value, "en-US");
+ Assert.equal(languageList.children[1].getAttribute("checked"), "true");
+ Assert.equal(languageList.children[2].localName, "menuseparator");
+ Assert.equal(
+ languageList.children[3].dataset.l10nId,
+ "spell-add-dictionaries"
+ );
+
+ hiddenPromise = BrowserTestUtils.waitForEvent(languageList, "popuphidden");
+ languageList.activateItem(languageList.children[1]);
+ await TestUtils.waitForCondition(
+ () => !languageList.children[1].hasAttribute("checked"),
+ "en-US menu item unchecked"
+ );
+ await TestUtils.waitForCondition(
+ () => !composeWindow.gActiveDictionaries.has("en-US"),
+ "en-US removed from dictionaries"
+ );
+ languageList.hidePopup();
+ await hiddenPromise;
+
+ Assert.deepEqual(
+ [...composeWindow.gActiveDictionaries],
+ ["en-NZ"],
+ "correct dictionaries active"
+ );
+ await checkMisspelledWords(subjectEditor, "harbor");
+ let words = await checkMisspelledWords(
+ bodyEditor,
+ "maneuvered",
+ "center",
+ "jewelry"
+ );
+
+ // Check that opening the context menu on a spelling error works as expected.
+
+ let box = words.getRangeAt(1).getBoundingClientRect();
+ shownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
+ BrowserTestUtils.synthesizeMouseAtPoint(
+ box.left + box.width / 2,
+ box.top + box.height / 2,
+ { type: "contextmenu" },
+ editorBrowser
+ );
+ await shownPromise;
+
+ let menuItem = composeDocument.getElementById("spellCheckNoSuggestions");
+ Assert.ok(BrowserTestUtils.is_hidden(menuItem));
+
+ let suggestions = contextMenu.querySelectorAll(".spell-suggestion");
+ Assert.greater(suggestions.length, 0);
+ Assert.equal(suggestions[0].value, "centre");
+
+ for (let id of [
+ "spellCheckAddSep",
+ "spellCheckAddToDictionary",
+ "spellCheckIgnoreWord",
+ "spellCheckSuggestionsSeparator",
+ ]) {
+ menuItem = composeDocument.getElementById(id);
+ Assert.ok(BrowserTestUtils.is_visible(menuItem));
+ }
+
+ hiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
+ contextMenu.activateItem(suggestions[0]);
+ await hiddenPromise;
+
+ await checkMisspelledWords(bodyEditor, "maneuvered", "jewelry");
+ await SpecialPowers.spawn(editorBrowser, [], () => {
+ Assert.ok(
+ content.document.body.textContent.startsWith(
+ "I maneuvered to the centre."
+ )
+ );
+ });
+
+ // Clean up.
+
+ close_compose_window(cwc);
+ hunspell.removeDirectory(dictionary);
+});