Backed out 2 changesets (bug 1864896) for causing node failures. CLOSED TREE
[gecko.git] / browser / components / preferences / tests / browser_basic_rebuild_fonts_test.js
blob51998db5a95d1aa42a7ee98ef1ea850871750496
1 add_task(async function () {
2   await openPreferencesViaOpenPreferencesAPI("general", { leaveOpen: true });
3   await gBrowser.contentWindow.gMainPane._selectDefaultLanguageGroupPromise;
4   await TestUtils.waitForCondition(
5     () => !gBrowser.contentWindow.Preferences.updateQueued
6   );
8   let doc = gBrowser.contentDocument;
9   let contentWindow = gBrowser.contentWindow;
10   var langGroup = Services.prefs.getComplexValue(
11     "font.language.group",
12     Ci.nsIPrefLocalizedString
13   ).data;
14   is(
15     contentWindow.Preferences.get("font.language.group").value,
16     langGroup,
17     "Language group should be set correctly."
18   );
20   let defaultFontType = Services.prefs.getCharPref("font.default." + langGroup);
21   let fontFamilyPref = "font.name." + defaultFontType + "." + langGroup;
22   let fontFamily = Services.prefs.getCharPref(fontFamilyPref);
23   let fontFamilyField = doc.getElementById("defaultFont");
24   is(fontFamilyField.value, fontFamily, "Font family should be set correctly.");
26   function dispatchMenuItemCommand(menuItem) {
27     const cmdEvent = doc.createEvent("xulcommandevent");
28     cmdEvent.initCommandEvent(
29       "command",
30       true,
31       true,
32       contentWindow,
33       0,
34       false,
35       false,
36       false,
37       false,
38       0,
39       null,
40       0
41     );
42     menuItem.dispatchEvent(cmdEvent);
43   }
45   /**
46    * Return a promise that resolves when the fontFamilyPref changes.
47    *
48    * Font prefs are the only ones whose form controls set "delayprefsave",
49    * which delays the pref change when a user specifies a new value
50    * for the pref.  Thus, in order to confirm that the pref gets changed
51    * when the test selects a new value in a font field, we need to await
52    * the change.  Awaiting this function does so for fontFamilyPref.
53    */
54   function fontFamilyPrefChanged() {
55     return new Promise(resolve => {
56       const observer = {
57         observe(aSubject, aTopic, aData) {
58           // Check for an exact match to avoid the ambiguity of nsIPrefBranch's
59           // prefix-matching algorithm for notifying pref observers.
60           if (aData == fontFamilyPref) {
61             Services.prefs.removeObserver(fontFamilyPref, observer);
62             resolve();
63           }
64         },
65       };
66       Services.prefs.addObserver(fontFamilyPref, observer);
67     });
68   }
70   const menuItems = fontFamilyField.querySelectorAll("menuitem");
71   Assert.greater(menuItems.length, 1, "There are multiple font menuitems.");
72   ok(menuItems[0].selected, "The first (default) font menuitem is selected.");
74   dispatchMenuItemCommand(menuItems[1]);
75   ok(menuItems[1].selected, "The second font menuitem is selected.");
77   await fontFamilyPrefChanged();
78   fontFamily = Services.prefs.getCharPref(fontFamilyPref);
79   is(fontFamilyField.value, fontFamily, "The font family has been updated.");
81   dispatchMenuItemCommand(menuItems[0]);
82   ok(
83     menuItems[0].selected,
84     "The first (default) font menuitem is selected again."
85   );
87   await fontFamilyPrefChanged();
88   fontFamily = Services.prefs.getCharPref(fontFamilyPref);
89   is(fontFamilyField.value, fontFamily, "The font family has been updated.");
91   let defaultFontSize = Services.prefs.getIntPref(
92     "font.size.variable." + langGroup
93   );
94   let fontSizeField = doc.getElementById("defaultFontSize");
95   is(
96     fontSizeField.value,
97     "" + defaultFontSize,
98     "Font size should be set correctly."
99   );
101   let promiseSubDialogLoaded = promiseLoadSubDialog(
102     "chrome://browser/content/preferences/dialogs/fonts.xhtml"
103   );
104   doc.getElementById("advancedFonts").click();
105   let win = await promiseSubDialogLoaded;
106   doc = win.document;
108   // Simulate a dumb font backend.
109   win.FontBuilder._enumerator = {
110     _list: ["MockedFont1", "MockedFont2", "MockedFont3"],
111     _defaultFont: null,
112     EnumerateFontsAsync(lang, type) {
113       return Promise.resolve(this._list);
114     },
115     EnumerateAllFontsAsync() {
116       return Promise.resolve(this._list);
117     },
118     getDefaultFont() {
119       return this._defaultFont;
120     },
121     getStandardFamilyName(name) {
122       return name;
123     },
124   };
125   win.FontBuilder._allFonts = null;
126   win.FontBuilder._langGroupSupported = false;
128   let langGroupElement = win.Preferences.get("font.language.group");
129   let selectLangsField = doc.getElementById("selectLangs");
130   let serifField = doc.getElementById("serif");
131   let armenian = "x-armn";
132   let western = "x-western";
134   // Await rebuilding of the font lists, which happens asynchronously in
135   // gFontsDialog._selectLanguageGroup.  Testing code needs to call this
136   // function and await its resolution after changing langGroupElement's value
137   // (or doing anything else that triggers a call to _selectLanguageGroup).
138   function fontListsRebuilt() {
139     return win.gFontsDialog._selectLanguageGroupPromise;
140   }
142   langGroupElement.value = armenian;
143   await fontListsRebuilt();
144   selectLangsField.value = armenian;
145   is(serifField.value, "", "Font family should not be set.");
147   let armenianSerifElement = win.Preferences.get("font.name.serif.x-armn");
149   langGroupElement.value = western;
150   await fontListsRebuilt();
151   selectLangsField.value = western;
153   // Simulate a font backend supporting language-specific enumeration.
154   // NB: FontBuilder has cached the return value from EnumerateAllFonts(),
155   // so _allFonts will always have 3 elements regardless of subsequent
156   // _list changes.
157   win.FontBuilder._enumerator._list = ["MockedFont2"];
159   langGroupElement.value = armenian;
160   await fontListsRebuilt();
161   selectLangsField.value = armenian;
162   is(
163     serifField.value,
164     "",
165     "Font family should still be empty for indicating using 'default' font."
166   );
168   langGroupElement.value = western;
169   await fontListsRebuilt();
170   selectLangsField.value = western;
172   // Simulate a system that has no fonts for the specified language.
173   win.FontBuilder._enumerator._list = [];
175   langGroupElement.value = armenian;
176   await fontListsRebuilt();
177   selectLangsField.value = armenian;
178   is(serifField.value, "", "Font family should not be set.");
180   // Setting default font to "MockedFont3".  Then, when serifField.value is
181   // empty, it should indicate using "MockedFont3" but it shouldn't be saved
182   // to "MockedFont3" in the pref.  It should be resolved at runtime.
183   win.FontBuilder._enumerator._list = [
184     "MockedFont1",
185     "MockedFont2",
186     "MockedFont3",
187   ];
188   win.FontBuilder._enumerator._defaultFont = "MockedFont3";
189   langGroupElement.value = armenian;
190   await fontListsRebuilt();
191   selectLangsField.value = armenian;
192   is(
193     serifField.value,
194     "",
195     "Font family should be empty even if there is a default font."
196   );
198   armenianSerifElement.value = "MockedFont2";
199   serifField.value = "MockedFont2";
200   is(
201     serifField.value,
202     "MockedFont2",
203     'Font family should be "MockedFont2" for now.'
204   );
206   langGroupElement.value = western;
207   await fontListsRebuilt();
208   selectLangsField.value = western;
209   is(serifField.value, "", "Font family of other language should not be set.");
211   langGroupElement.value = armenian;
212   await fontListsRebuilt();
213   selectLangsField.value = armenian;
214   is(
215     serifField.value,
216     "MockedFont2",
217     "Font family should not be changed even after switching the language."
218   );
220   // If MochedFont2 is removed from the system, the value should be treated
221   // as empty (i.e., 'default' font) after rebuilding the font list.
222   win.FontBuilder._enumerator._list = ["MockedFont1", "MockedFont3"];
223   win.FontBuilder._enumerator._allFonts = ["MockedFont1", "MockedFont3"];
224   serifField.removeAllItems(); // This will cause rebuilding the font list from available fonts.
225   langGroupElement.value = armenian;
226   await fontListsRebuilt();
227   selectLangsField.value = armenian;
228   is(
229     serifField.value,
230     "",
231     "Font family should become empty due to the font uninstalled."
232   );
234   gBrowser.removeCurrentTab();