Revision control

Copy as Markdown

Other Tools

# 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/.
import json
import os.path
from marionette_harness import MarionetteTestCase
here = os.path.dirname(__file__)
# Account prefs, so that a compose window can be opened.
COMPOSE_PREFS = {
"mail.account.account1.identities": "id1",
"mail.account.account1.server": "server1",
"mail.accountmanager.accounts": "account1",
"mail.accountmanager.defaultaccount": "account1",
"mail.identity.id1.fullName": "Marionette",
"mail.identity.id1.useremail": "marionette@invalid",
"mail.identity.id1.valid": True,
"mail.server.server1.hostname": "localhost",
"mail.server.server1.login_at_startup": False,
"mail.server.server1.type": "pop3",
}
class TestCollapsedToolbarMigration(MarionetteTestCase):
"""
Tests that the legacy collapsed="true"/"false" values, as written by
Thunderbird 9 to 60, are rewritten to the values the current code persists,
since the presence of *any* value for that attribute now collapses the
toolbar.
"""
# The toolbars are near the end of messengercompose.xhtml, so wait for the
# compose window to be ready before looking for them.
get_collapsed_attributes = """
const [resolve] = arguments;
function finish() {
resolve([
document.getElementById("composeToolbar2").getAttribute("collapsed"),
document.getElementById("compose-toolbar-menubar2").getAttribute("collapsed"),
]);
}
if (window.composeEditorReady) {
finish();
} else {
window.addEventListener("compose-editor-ready", finish, { once: true });
}
"""
get_xulstore_value = """
const [url, id] = arguments;
if (!Services.xulStore.hasValue(url, id, "collapsed")) {
return null;
}
return Services.xulStore.getValue(url, id, "collapsed");
"""
get_pref_value = """
return Services.prefs.getIntPref("mail.ui-rdf.version", -1);
"""
def test_no_xulstore_update(self):
"""
The XUL store has no value when migration happens. Nothing is written
and the toolbars should be visible, because that's the default.
"""
self.subtest(61, None, [None, None], None)
def test_xulstore_false_no_update(self):
"""
The XUL store value is false and migration doesn't happen. The toolbars
should be collapsed, because they have a value for the collapsed
attribute, even though that value is "false".
"""
self.subtest(62, "false", ["false", "false"], "false")
def test_xulstore_false_update(self):
"""
The XUL store value is false when migration happens. It should become
"-moz-missing\n" and the toolbars should be visible.
"""
self.subtest(61, "false", [None, None], "-moz-missing\n")
def test_xulstore_true_update(self):
"""
The XUL store value is true when migration happens. It should be
normalized to "" and the toolbars should stay collapsed.
"""
self.subtest(61, "true", ["", ""], "")
def test_xulstore_missing_update(self):
"""
The XUL store value is already "-moz-missing\n", as written by the
current code for a visible toolbar, or by a user working around this bug
by toggling the setting. It must be left alone, so the toolbars stay
visible.
"""
self.subtest(61, "-moz-missing\n", [None, None], "-moz-missing\n")
def test_xulstore_empty_update(self):
"""
The XUL store value is already "", as written by the current code for a
collapsed toolbar. It must be left alone, so the toolbars stay collapsed.
"""
self.subtest(61, "", ["", ""], "")
def subtest(
self,
migration_version,
xulstore_value,
expected_attribute_values,
expected_xulstore_value,
):
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
self.marionette.set_prefs(COMPOSE_PREFS)
self.marionette.quit(in_app=True)
# Set the migration pref to a number lower than the migration we're
# testing, without clobbering the account prefs written on shutdown.
prefs_path = os.path.join(self.marionette.profile_path, "prefs.js")
with open(prefs_path, "a") as prefs_file:
prefs_file.write(f"""user_pref("mail.ui-rdf.version", {migration_version});\n""")
# Write a xulstore.json file with the collapsed attribute set.
xulstore_path = os.path.join(self.marionette.profile_path, "xulstore.json")
if xulstore_value is None:
xulstore_data = {COMPOSE_WINDOW: {}}
else:
xulstore_data = {
COMPOSE_WINDOW: {
"composeToolbar2": {"collapsed": xulstore_value},
"compose-toolbar-menubar2": {"collapsed": xulstore_value},
},
MESSENGER_WINDOW: {"mail-bar3": {"collapsed": xulstore_value}},
MESSAGE_WINDOW: {"mail-bar3": {"collapsed": xulstore_value}},
}
with open(xulstore_path, "w") as xulstore_file:
json.dump(xulstore_data, xulstore_file)
# Start the application with a compose window, check the state.
self.marionette.instance.app_args = ["mailto:test@invalid"]
try:
self.marionette.start_session()
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
for url, id in (
(COMPOSE_WINDOW, "composeToolbar2"),
(COMPOSE_WINDOW, "compose-toolbar-menubar2"),
(MESSENGER_WINDOW, "mail-bar3"),
(MESSAGE_WINDOW, "mail-bar3"),
):
self.assertEqual(
expected_xulstore_value,
self.marionette.execute_script(self.get_xulstore_value, [url, id]),
f"XUL store value for {id} in {url}",
)
self.assertTrue(self.marionette.execute_script(self.get_pref_value) >= 62)
handles = self.marionette.chrome_window_handles
self.assertEqual(2, len(handles))
self.marionette.switch_to_window(handles[1], True)
self.assertEqual("msgcompose", self.marionette.get_window_type())
self.assertEqual(
expected_attribute_values,
self.marionette.execute_async_script(self.get_collapsed_attributes),
)
finally:
for key in COMPOSE_PREFS:
self.marionette.clear_pref(key)
self.marionette.instance.app_args = []
self.marionette.quit(in_app=True)