Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: os == 'linux' && os_version == '22.04' && arch == 'x86_64' && display == 'wayland'
- This test runs only with pattern: buildapp == 'browser'
- Manifest: browser/components/backup/tests/marionette/manifest.toml
# 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 os
import sys
import tempfile
from pathlib import Path
import mozfile
sys.path.append(os.fspath(Path(__file__).parents[0]))
from backup_test_base import BackupTestBase
class BackupLegacyToSelectableTest(BackupTestBase):
"""
Tests that a backup created from a legacy profile (without selectable
profiles enabled) can be successfully recovered in an environment where
selectable profiles ARE enabled.
This verifies that stale selectable profile prefs in the backup are
overwritten with correct values during recovery.
"""
def test_backup_legacy_to_selectable(self):
self.logger.info("=== Test: Legacy -> Selectable ===")
self.logger.info("Step 1: Creating legacy backup with stale prefs")
profile_name = self.register_profile_and_restart()
self._cleanups.append({"profile_name": profile_name})
self.set_prefs({
"browser.profiles.enabled": False,
"browser.profiles.created": False,
"toolkit.profiles.storeID": "stale-legacy-store-id",
"test.legacy.backup.pref": "test-value",
})
self.marionette.restart(clean=False, in_app=True)
self._archive_path = self.create_backup()
self._cleanups.append({"path": self._archive_path})
self.assertTrue(
os.path.exists(self._archive_path), "Backup archive should exist"
)
self.logger.info(f"Legacy backup created at: {self._archive_path}")
self.logger.info("Step 2: Switching to new selectable profile environment")
self.marionette.quit()
self.marionette.instance.switch_profile()
self.marionette.start_session()
self.marionette.set_context("chrome")
recovery_profile_name = self.register_profile_and_restart()
self._cleanups.append({"profile_name": recovery_profile_name})
self.logger.info(f"Created recovery profile: {recovery_profile_name}")
selectable_info = self.setup_selectable_profile()
original_store_id = selectable_info["store_id"]
self.assertIsNotNone(original_store_id, "storeID should be set")
self.logger.info(f"Recovery environment storeID: {original_store_id}")
self.logger.info("Step 3: Recovering legacy backup into selectable environment")
self._recovery_path = os.path.join(
tempfile.gettempdir(), "legacy-to-selectable-recovery"
)
mozfile.remove(self._recovery_path)
self._cleanups.append({"path": self._recovery_path})
recovery_result = self.recover_backup(self._archive_path, self._recovery_path)
self._new_profile_path = recovery_result["path"]
self._new_profile_id = recovery_result["id"]
self._cleanups.append({"path": self._new_profile_path})
self.logger.info(
f"Recovery complete. New profile path: {self._new_profile_path}, id: {self._new_profile_id}"
)
self.logger.info("Step 4: Launching recovered profile and verifying prefs")
self.marionette.quit()
intermediate_profile = self.marionette.instance.profile
self.marionette.instance.profile = self._new_profile_path
self.marionette.start_session()
self.marionette.set_context("chrome")
self.wait_for_post_recovery()
self.logger.info("Post-recovery complete")
self.init_selectable_profile_service()
store_id = self.get_store_id()
self.assertEqual(
store_id,
original_store_id,
"Recovered profile should have the same storeID as profile group",
)
self.logger.info(f"Verified storeID matches: {store_id}")
prefs = self.run_code(
"""
return {
enabled: Services.prefs.getBoolPref("browser.profiles.enabled", false),
created: Services.prefs.getBoolPref("browser.profiles.created", false),
};
"""
)
self.assertTrue(
prefs["enabled"],
"browser.profiles.enabled should be true (not stale false from backup)",
)
self.assertTrue(
prefs["created"],
"browser.profiles.created should be true (not stale false from backup)",
)
self.logger.info("Verified prefs are correct (not stale values from backup)")
self.logger.info("Step 5: Cleaning up")
self.marionette.quit()
self.marionette.instance.profile = intermediate_profile
self.marionette.start_session()
self.marionette.set_context("chrome")
self.cleanup_selectable_profiles()
self.logger.info("=== Test: Legacy -> Selectable PASSED ===")