Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
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;
let langGroup = Services.locale.fontLanguageGroup;
let defaultFontType = Services.prefs.getCharPref("font.default." + langGroup);
let fontFamilyPref = "font.name." + defaultFontType + "." + langGroup;
let fontFamily = Services.prefs.getCharPref(fontFamilyPref);
let fontsGroup = doc.querySelector('setting-group[groupid="fonts"]');
ok(fontsGroup, "Fonts setting-group exists");
let mozSelect = fontsGroup.querySelector("#defaultFont");
ok(mozSelect, "defaultFont moz-select exists");
is(mozSelect.localName, "moz-select", "Control is a moz-select");
is(mozSelect.value, fontFamily, "Font family should be set correctly.");
function fontFamilyPrefChanged() {
return new Promise(resolve => {
const observer = {
observe(aSubject, aTopic, aData) {
if (aData == fontFamilyPref) {
Services.prefs.removeObserver(fontFamilyPref, observer);
resolve();
}
},
};
Services.prefs.addObserver(fontFamilyPref, observer);
});
}
let selectEl = mozSelect.inputEl;
let options = [...selectEl.options];
Assert.greater(options.length, 1, "There are multiple font options.");
is(selectEl.selectedIndex, 0, "The first (default) font option is selected.");
let prefChangePromise = fontFamilyPrefChanged();
let pickerOpened = BrowserTestUtils.waitForSelectPopupShown(window);
mozSelect.focus();
EventUtils.synthesizeKey(" ", {}, contentWindow);
await pickerOpened;
EventUtils.synthesizeKey("KEY_ArrowDown", {}, contentWindow);
EventUtils.synthesizeKey("KEY_Enter", {}, contentWindow);
await prefChangePromise;
fontFamily = Services.prefs.getCharPref(fontFamilyPref);
is(mozSelect.value, fontFamily, "The font family has been updated.");
is(selectEl.selectedIndex, 1, "The second font option is now selected.");
prefChangePromise = fontFamilyPrefChanged();
pickerOpened = BrowserTestUtils.waitForSelectPopupShown(window);
mozSelect.focus();
EventUtils.synthesizeKey(" ", {}, contentWindow);
await pickerOpened;
EventUtils.synthesizeKey("KEY_ArrowUp", {}, contentWindow);
EventUtils.synthesizeKey("KEY_Enter", {}, contentWindow);
await prefChangePromise;
fontFamily = Services.prefs.getCharPref(fontFamilyPref);
is(mozSelect.value, fontFamily, "The font family has been updated.");
is(
selectEl.selectedIndex,
0,
"The first (default) font option is selected again."
);
let defaultFontSize = Services.prefs.getIntPref(
"font.size.variable." + langGroup
);
let sizeSelect = fontsGroup.querySelector("#defaultFontSize");
ok(sizeSelect, "defaultFontSize moz-select exists");
is(sizeSelect.localName, "moz-select", "Size control is a moz-select");
is(
sizeSelect.value,
String(defaultFontSize),
"Font size should be set correctly."
);
let advancedButton = fontsGroup.querySelector("#advancedFonts");
ok(advancedButton, "advancedFonts button exists");
let promiseSubDialogLoaded = promiseLoadSubDialog(
"chrome://browser/content/preferences/dialogs/fonts.xhtml"
);
advancedButton.click();
let win = await promiseSubDialogLoaded;
doc = win.document;
// Simulate a dumb font backend.
win.FontBuilder._enumerator = {
_list: ["MockedFont1", "MockedFont2", "MockedFont3"],
_defaultFont: null,
EnumerateFontsAsync() {
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();
});