summaryrefslogtreecommitdiffstats
path: root/browser/components/preferences/tests/browser_basic_rebuild_fonts_test.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/preferences/tests/browser_basic_rebuild_fonts_test.js')
-rw-r--r--browser/components/preferences/tests/browser_basic_rebuild_fonts_test.js235
1 files changed, 235 insertions, 0 deletions
diff --git a/browser/components/preferences/tests/browser_basic_rebuild_fonts_test.js b/browser/components/preferences/tests/browser_basic_rebuild_fonts_test.js
new file mode 100644
index 0000000000..bacda8a6b4
--- /dev/null
+++ b/browser/components/preferences/tests/browser_basic_rebuild_fonts_test.js
@@ -0,0 +1,235 @@
+add_task(async function () {
+ await openPreferencesViaOpenPreferencesAPI("general", { leaveOpen: true });
+ await gBrowser.contentWindow.gMainPane._selectDefaultLanguageGroupPromise;
+ await TestUtils.waitForCondition(
+ () => !gBrowser.contentWindow.Preferences.updateQueued
+ );
+
+ let doc = gBrowser.contentDocument;
+ let contentWindow = gBrowser.contentWindow;
+ var langGroup = Services.prefs.getComplexValue(
+ "font.language.group",
+ Ci.nsIPrefLocalizedString
+ ).data;
+ is(
+ contentWindow.Preferences.get("font.language.group").value,
+ langGroup,
+ "Language group should be set correctly."
+ );
+
+ let defaultFontType = Services.prefs.getCharPref("font.default." + langGroup);
+ let fontFamilyPref = "font.name." + defaultFontType + "." + langGroup;
+ let fontFamily = Services.prefs.getCharPref(fontFamilyPref);
+ let fontFamilyField = doc.getElementById("defaultFont");
+ is(fontFamilyField.value, fontFamily, "Font family should be set correctly.");
+
+ function dispatchMenuItemCommand(menuItem) {
+ const cmdEvent = doc.createEvent("xulcommandevent");
+ cmdEvent.initCommandEvent(
+ "command",
+ true,
+ true,
+ contentWindow,
+ 0,
+ false,
+ false,
+ false,
+ false,
+ 0,
+ null,
+ 0
+ );
+ menuItem.dispatchEvent(cmdEvent);
+ }
+
+ /**
+ * Return a promise that resolves when the fontFamilyPref changes.
+ *
+ * Font prefs are the only ones whose form controls set "delayprefsave",
+ * which delays the pref change when a user specifies a new value
+ * for the pref. Thus, in order to confirm that the pref gets changed
+ * when the test selects a new value in a font field, we need to await
+ * the change. Awaiting this function does so for fontFamilyPref.
+ */
+ function fontFamilyPrefChanged() {
+ return new Promise(resolve => {
+ const observer = {
+ observe(aSubject, aTopic, aData) {
+ // Check for an exact match to avoid the ambiguity of nsIPrefBranch's
+ // prefix-matching algorithm for notifying pref observers.
+ if (aData == fontFamilyPref) {
+ Services.prefs.removeObserver(fontFamilyPref, observer);
+ resolve();
+ }
+ },
+ };
+ Services.prefs.addObserver(fontFamilyPref, observer);
+ });
+ }
+
+ const menuItems = fontFamilyField.querySelectorAll("menuitem");
+ ok(menuItems.length > 1, "There are multiple font menuitems.");
+ ok(menuItems[0].selected, "The first (default) font menuitem is selected.");
+
+ dispatchMenuItemCommand(menuItems[1]);
+ ok(menuItems[1].selected, "The second font menuitem is selected.");
+
+ await fontFamilyPrefChanged();
+ fontFamily = Services.prefs.getCharPref(fontFamilyPref);
+ is(fontFamilyField.value, fontFamily, "The font family has been updated.");
+
+ dispatchMenuItemCommand(menuItems[0]);
+ ok(
+ menuItems[0].selected,
+ "The first (default) font menuitem is selected again."
+ );
+
+ await fontFamilyPrefChanged();
+ fontFamily = Services.prefs.getCharPref(fontFamilyPref);
+ is(fontFamilyField.value, fontFamily, "The font family has been updated.");
+
+ let defaultFontSize = Services.prefs.getIntPref(
+ "font.size.variable." + langGroup
+ );
+ let fontSizeField = doc.getElementById("defaultFontSize");
+ is(
+ fontSizeField.value,
+ "" + defaultFontSize,
+ "Font size should be set correctly."
+ );
+
+ let promiseSubDialogLoaded = promiseLoadSubDialog(
+ "chrome://browser/content/preferences/dialogs/fonts.xhtml"
+ );
+ doc.getElementById("advancedFonts").click();
+ let win = await promiseSubDialogLoaded;
+ doc = win.document;
+
+ // Simulate a dumb font backend.
+ win.FontBuilder._enumerator = {
+ _list: ["MockedFont1", "MockedFont2", "MockedFont3"],
+ _defaultFont: null,
+ EnumerateFontsAsync(lang, type) {
+ return Promise.resolve(this._list);
+ },
+ EnumerateAllFontsAsync() {
+ return Promise.resolve(this._list);
+ },
+ getDefaultFont() {
+ return this._defaultFont;
+ },
+ getStandardFamilyName(name) {
+ return name;
+ },
+ };
+ win.FontBuilder._allFonts = null;
+ win.FontBuilder._langGroupSupported = false;
+
+ let langGroupElement = win.Preferences.get("font.language.group");
+ let selectLangsField = doc.getElementById("selectLangs");
+ let serifField = doc.getElementById("serif");
+ let armenian = "x-armn";
+ let western = "x-western";
+
+ // Await rebuilding of the font lists, which happens asynchronously in
+ // gFontsDialog._selectLanguageGroup. Testing code needs to call this
+ // function and await its resolution after changing langGroupElement's value
+ // (or doing anything else that triggers a call to _selectLanguageGroup).
+ function fontListsRebuilt() {
+ return win.gFontsDialog._selectLanguageGroupPromise;
+ }
+
+ langGroupElement.value = armenian;
+ await fontListsRebuilt();
+ selectLangsField.value = armenian;
+ is(serifField.value, "", "Font family should not be set.");
+
+ let armenianSerifElement = win.Preferences.get("font.name.serif.x-armn");
+
+ langGroupElement.value = western;
+ await fontListsRebuilt();
+ selectLangsField.value = western;
+
+ // Simulate a font backend supporting language-specific enumeration.
+ // NB: FontBuilder has cached the return value from EnumerateAllFonts(),
+ // so _allFonts will always have 3 elements regardless of subsequent
+ // _list changes.
+ win.FontBuilder._enumerator._list = ["MockedFont2"];
+
+ langGroupElement.value = armenian;
+ await fontListsRebuilt();
+ selectLangsField.value = armenian;
+ is(
+ serifField.value,
+ "",
+ "Font family should still be empty for indicating using 'default' font."
+ );
+
+ langGroupElement.value = western;
+ await fontListsRebuilt();
+ selectLangsField.value = western;
+
+ // Simulate a system that has no fonts for the specified language.
+ win.FontBuilder._enumerator._list = [];
+
+ langGroupElement.value = armenian;
+ await fontListsRebuilt();
+ selectLangsField.value = armenian;
+ is(serifField.value, "", "Font family should not be set.");
+
+ // Setting default font to "MockedFont3". Then, when serifField.value is
+ // empty, it should indicate using "MockedFont3" but it shouldn't be saved
+ // to "MockedFont3" in the pref. It should be resolved at runtime.
+ win.FontBuilder._enumerator._list = [
+ "MockedFont1",
+ "MockedFont2",
+ "MockedFont3",
+ ];
+ win.FontBuilder._enumerator._defaultFont = "MockedFont3";
+ langGroupElement.value = armenian;
+ await fontListsRebuilt();
+ selectLangsField.value = armenian;
+ is(
+ serifField.value,
+ "",
+ "Font family should be empty even if there is a default font."
+ );
+
+ armenianSerifElement.value = "MockedFont2";
+ serifField.value = "MockedFont2";
+ is(
+ serifField.value,
+ "MockedFont2",
+ 'Font family should be "MockedFont2" for now.'
+ );
+
+ langGroupElement.value = western;
+ await fontListsRebuilt();
+ selectLangsField.value = western;
+ is(serifField.value, "", "Font family of other language should not be set.");
+
+ langGroupElement.value = armenian;
+ await fontListsRebuilt();
+ selectLangsField.value = armenian;
+ is(
+ serifField.value,
+ "MockedFont2",
+ "Font family should not be changed even after switching the language."
+ );
+
+ // If MochedFont2 is removed from the system, the value should be treated
+ // as empty (i.e., 'default' font) after rebuilding the font list.
+ win.FontBuilder._enumerator._list = ["MockedFont1", "MockedFont3"];
+ win.FontBuilder._enumerator._allFonts = ["MockedFont1", "MockedFont3"];
+ serifField.removeAllItems(); // This will cause rebuilding the font list from available fonts.
+ langGroupElement.value = armenian;
+ await fontListsRebuilt();
+ selectLangsField.value = armenian;
+ is(
+ serifField.value,
+ "",
+ "Font family should become empty due to the font uninstalled."
+ );
+
+ gBrowser.removeCurrentTab();
+});