Bug 1893277 - build initial UI for turning on scheduled backups. r=backup-reviewers,firefox-desktop-core-reviewers ,fluent-reviewers,mconley

backup-settings changes:
- adds a new button in the Backup section of about:preferences / about:settings
- shows the turn on dialog after pressing the button

Turn on dialog behaviour (implemented):
- pressing the cancel will close the dialog
- pressing the confirm button will set the pref browser.backup.scheduled.enabled=true and close the dialog
- pressing the passwords checkbox will show more options

Turn on dialog behaviour (not implemented):
- requiring a password for the backup (see Bug 1895981)
- modifying the save location and showing a file picker (see Bug 1895943)

Other changes:
- tests for backup-settings and the turn on dialog
- Storybook template for the turn on dialog

Lo-fi Figma designs: https://www.figma.com/design/vNbX4c0ws0L1qr0mxpKvsW/Fx-Backup?node-id=147-4558&t=PYLY0QMN1n8GR9vW-0

Differential Revision: https://phabricator.services.mozilla.com/D209769
This commit is contained in:
kpatenio 2024-05-17 17:36:33 +00:00
parent 421acc9093
commit a39846bf34
18 changed files with 721 additions and 13 deletions

View file

@ -3052,6 +3052,8 @@ pref("browser.mailto.prompt.os", true);
// Pref to initialize the BackupService soon after startup.
pref("browser.backup.enabled", true);
// Pref to control whether scheduled backups run or not.
pref("browser.backup.scheduled.enabled", false);
// Pref to control the visibility of the backup section in about:preferences
pref("browser.backup.preferences.ui.enabled", false);
// The number of SQLite database pages to backup per step.

View file

@ -439,6 +439,7 @@ let JSWINDOWACTORS = {
esModuleURI: "resource:///actors/BackupUIChild.sys.mjs",
events: {
"BackupUI:InitWidget": { wantUntrusted: true },
"BackupUI:ScheduledBackupsConfirm": { wantUntrusted: true },
},
},
matches: ["about:preferences*", "about:settings*"],

View file

@ -4,7 +4,9 @@
import * as DefaultBackupResources from "resource:///modules/backup/BackupResources.sys.mjs";
import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
const SCHEDULED_BACKUPS_ENABLED_PREF_NAME = "browser.backup.scheduled.enabled";
const lazy = {};
ChromeUtils.defineLazyGetter(lazy, "logConsole", function () {
@ -33,6 +35,19 @@ ChromeUtils.defineLazyGetter(lazy, "ZipWriter", () =>
Components.Constructor("@mozilla.org/zipwriter;1", "nsIZipWriter", "open")
);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
"scheduledBackupsPref",
SCHEDULED_BACKUPS_ENABLED_PREF_NAME,
false,
function onUpdateScheduledBackups(_pref, _prevVal, newVal) {
let bs = BackupService.get();
if (bs) {
bs.onUpdateScheduledBackups(newVal);
}
}
);
/**
* The BackupService class orchestrates the scheduling and creation of profile
* backups. It also does most of the heavy lifting for the restoration of a
@ -94,7 +109,11 @@ export class BackupService extends EventTarget {
*
* @type {object}
*/
#_state = { backupInProgress: false };
#_state = {
backupFilePath: "Documents", // TODO: make save location configurable (bug 1895943)
backupInProgress: false,
scheduledBackupsEnabled: lazy.scheduledBackupsPref,
};
/**
* A Promise that will resolve once the postRecovery steps are done. It will
@ -844,6 +863,35 @@ export class BackupService extends EventTarget {
}
}
/**
* Sets browser.backup.scheduled.enabled to true or false.
*
* @param { boolean } shouldEnableScheduledBackups true if scheduled backups should be enabled. Else, false.
*/
setScheduledBackups(shouldEnableScheduledBackups) {
Services.prefs.setBoolPref(
SCHEDULED_BACKUPS_ENABLED_PREF_NAME,
shouldEnableScheduledBackups
);
}
/**
* Updates scheduledBackupsEnabled in the backup service state. Should be called every time
* the value for browser.backup.scheduled.enabled changes.
*
* @param {boolean} isScheduledBackupsEnabled True if scheduled backups are enabled. Else false.
*/
onUpdateScheduledBackups(isScheduledBackupsEnabled) {
if (this.#_state.scheduledBackupsEnabled != isScheduledBackupsEnabled) {
lazy.logConsole.debug(
"Updating scheduled backups",
isScheduledBackupsEnabled
);
this.#_state.scheduledBackupsEnabled = isScheduledBackupsEnabled;
this.stateUpdate();
}
}
/**
* Take measurements of the current profile state for Telemetry.
*

View file

@ -13,20 +13,24 @@ export class BackupUIChild extends JSWindowActorChild {
#inittedWidgets = new WeakSet();
/**
* Handles BackupUI:InitWidget custom events fired by widgets that want to
* register with BackupUIChild. Firing this event sends a message to the
* parent to request the BackupService state which will result in a
* `backupServiceState` property of the widget to be set when that state is
* received. Subsequent state updates will also cause that state property to
* be set.
* Handles custom events fired by widgets that want to register with
* BackupUIChild.
*
* @param {Event} event
* The BackupUI:InitWidget custom event that the widget fired.
* The custom event that the widget fired.
*/
handleEvent(event) {
/**
* BackupUI:InitWidget sends a message to the parent to request the BackupService state
* which will result in a `backupServiceState` property of the widget to be set when that
* state is received. Subsequent state updates will also cause that state property to
* be set.
*/
if (event.type == "BackupUI:InitWidget") {
this.#inittedWidgets.add(event.target);
this.sendAsyncMessage("RequestState");
} else if (event.type == "BackupUI:ScheduledBackupsConfirm") {
this.sendAsyncMessage("ScheduledBackupsConfirm");
}
}

View file

@ -69,6 +69,8 @@ export class BackupUIParent extends JSWindowActorParent {
receiveMessage(message) {
if (message.name == "RequestState") {
this.sendState();
} else if (message.name == "ScheduledBackupsConfirm") {
this.#bs.setScheduledBackups(true);
}
}

View file

@ -0,0 +1,7 @@
/* 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 https://mozilla.org/MPL/2.0/. */
#turn-on-scheduled-backups-dialog {
width: 27.8rem;
}

View file

@ -5,6 +5,9 @@
import { html } from "chrome://global/content/vendor/lit.all.mjs";
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
// eslint-disable-next-line import/no-unassigned-import
import "chrome://browser/content/backup/turn-on-scheduled-backups.mjs";
/**
* The widget for managing the BackupService that is embedded within the main
* document of about:settings / about:preferences.
@ -14,14 +17,24 @@ export default class BackupSettings extends MozLitElement {
backupServiceState: { type: Object },
};
static get queries() {
return {
scheduledBackupsButtonEl: "#backup-toggle-scheduled-button",
turnOnScheduledBackupsDialogEl: "#turn-on-scheduled-backups-dialog",
turnOnScheduledBackupsEl: "turn-on-scheduled-backups",
};
}
/**
* Creates a BackupSettings instance and sets the initial default
* Creates a BackupPreferences instance and sets the initial default
* state.
*/
constructor() {
super();
this.backupServiceState = {
backupFilePath: "Documents", // TODO: make save location configurable (bug 1895943)
backupInProgress: false,
scheduledBackupsEnabled: false,
};
}
@ -34,13 +47,68 @@ export default class BackupSettings extends MozLitElement {
this.dispatchEvent(
new CustomEvent("BackupUI:InitWidget", { bubbles: true })
);
this.addEventListener("scheduledBackupsCancel", this);
this.addEventListener("scheduledBackupsConfirm", this);
}
handleEvent(event) {
switch (event.type) {
case "scheduledBackupsConfirm":
this.turnOnScheduledBackupsDialogEl.close();
this.dispatchEvent(
new CustomEvent("BackupUI:ScheduledBackupsConfirm", {
bubbles: true,
composed: true,
})
);
break;
case "scheduledBackupsCancel":
this.turnOnScheduledBackupsDialogEl.close();
break;
}
}
handleShowScheduledBackups() {
if (
!this.backupServiceState.scheduledBackupsEnabled &&
this.turnOnScheduledBackupsDialogEl
) {
this.turnOnScheduledBackupsDialogEl.showModal();
}
}
turnOnScheduledBackupsDialogTemplate() {
return html`<dialog id="turn-on-scheduled-backups-dialog">
<turn-on-scheduled-backups
.backupFilePath=${this.backupServiceState.backupFilePath}
></turn-on-scheduled-backups>
</dialog>`;
}
render() {
return html`<div>
Backup in progress:
${this.backupServiceState.backupInProgress ? "Yes" : "No"}
</div>`;
return html`<link
rel="stylesheet"
href="chrome://browser/skin/preferences/preferences.css"
/>
<link
rel="stylesheet"
href="chrome://browser/content/backup/backup-settings.css"
/>
<div id="scheduled-backups">
<div>
Backup in progress:
${this.backupServiceState.backupInProgress ? "Yes" : "No"}
</div>
${this.turnOnScheduledBackupsDialogTemplate()}
<moz-button
id="backup-toggle-scheduled-button"
@click=${this.handleShowScheduledBackups}
data-l10n-id="settings-data-backup-toggle"
></moz-button>
</div>`;
}
}

View file

@ -6,6 +6,9 @@
import { html } from "lit.all.mjs";
import "./backup-settings.mjs";
window.MozXULElement.insertFTLIfNeeded("locales-preview/backupSettings.ftl");
window.MozXULElement.insertFTLIfNeeded("branding/brand.ftl");
export default {
title: "Domain-specific UI Widgets/Backup/Backup Settings",
component: "backup-settings",
@ -19,13 +22,17 @@ const Template = ({ backupServiceState }) => html`
export const BackingUpNotInProgress = Template.bind({});
BackingUpNotInProgress.args = {
backupServiceState: {
backupFilePath: "Documents",
backupInProgress: false,
scheduledBackupsEnabled: false,
},
};
export const BackingUpInProgress = Template.bind({});
BackingUpInProgress.args = {
backupServiceState: {
backupFilePath: "Documents",
backupInProgress: true,
scheduledBackupsEnabled: false,
},
};

View file

@ -0,0 +1,109 @@
/* 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 https://mozilla.org/MPL/2.0/. */
@import url("chrome://global/skin/in-content/common.css");
:host {
--margin-inline-start-checkbox-content: calc(var(--checkbox-margin-inline) + var(--checkbox-size));
}
#backup-turn-on-scheduled-wrapper {
display: grid;
grid-template-areas:
"header"
"content"
"button-group";
grid-template-rows: auto auto auto;
line-height: 1.5;
#backup-turn-on-scheduled-header {
grid-area: header;
font-size: var(--font-size-large);
font-weight: var(--font-weight);
margin: 0;
}
& fieldset {
border: none;
margin: 0;
padding: 0;
}
#backup-turn-on-scheduled-content {
display: flex;
flex-direction: column;
grid-area: content;
margin-block-start: var(--space-small);
margin-block-end: var(--space-large);
row-gap: var(--space-large);
}
#all-controls {
display: flex;
flex-direction: column;
row-gap: var(--space-xlarge);
}
#backup-location-controls {
display: flex;
flex-direction: column;
row-gap: var(--space-xsmall);
#backup-location-filepicker {
display: flex;
column-gap: var(--space-small);
align-items: center;
}
#backup-location-filepicker-input {
margin: 0;
flex: 1;
}
}
#sensitive-data-controls {
display: flex;
flex-direction: column;
row-gap: var(--space-large);
#sensitive-data-checkbox-label {
display: flex;
gap: var(--checkbox-margin-inline);
align-items: center;
}
#sensitive-data-checkbox-label > input {
margin: 0;
}
#sensitive-data-checkbox {
display: flex;
flex-direction: column;
row-gap: var(--space-xsmall);
}
#sensitive-data-checkbox > span {
margin-inline-start: var(--margin-inline-start-checkbox-content);
}
}
#passwords {
display: flex;
flex-direction: column;
margin-inline-start: var(--margin-inline-start-checkbox-content);
& > #new-password-label, #repeat-password-label {
display: flex;
flex-direction: column;
}
& > #new-password-label > input, #repeat-password-label > input {
margin-inline-start: 0px;
}
}
#backup-turn-on-scheduled-button-group {
grid-area: button-group;
}
}

View file

@ -0,0 +1,212 @@
/* 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 { html } from "chrome://global/content/vendor/lit.all.mjs";
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
/**
* The widget for showing available options when users want to turn on
* scheduled backups.
*/
export default class TurnOnScheduledBackups extends MozLitElement {
static properties = {
backupFilePath: { type: String },
showPasswordOptions: { type: Boolean, reflect: true },
};
static get queries() {
return {
cancelButtonEl: "#backup-turn-on-scheduled-cancel-button",
confirmButtonEl: "#backup-turn-on-scheduled-confirm-button",
passwordOptionsCheckboxEl: "#sensitive-data-checkbox-input",
passwordOptionsExpandedEl: "#passwords",
recommendedFolderInputEl: "#backup-location-filepicker-input",
};
}
constructor() {
super();
this.backupFilePath = null;
this.showPasswordOptions = false;
}
/**
* Dispatches the BackupUI:InitWidget custom event upon being attached to the
* DOM, which registers with BackupUIChild for BackupService state updates.
*/
connectedCallback() {
super.connectedCallback();
this.dispatchEvent(
new CustomEvent("BackupUI:InitWidget", { bubbles: true })
);
}
handleChooseLocation() {
// TODO: show file picker (bug 1895943)
}
handleCancel() {
this.dispatchEvent(
new CustomEvent("scheduledBackupsCancel", {
bubbles: true,
composed: true,
})
);
this.showPasswordOptions = false;
this.passwordOptionsCheckboxEl.checked = false;
}
handleConfirm() {
/**
* TODO:
* We should pass save location to BackupUIParent here (bug 1895943).
* If encryption is enabled via this dialog, ensure a password is set and pass it to BackupUIParent (bug 1895981).
* Before confirmation, verify passwords match and FxA format rules (bug 1896772).
*/
this.dispatchEvent(
new CustomEvent("scheduledBackupsConfirm", {
bubbles: true,
composed: true,
})
);
this.showPasswordOptions = false;
this.passwordOptionsCheckboxEl.checked = false;
}
handleTogglePasswordOptions() {
this.showPasswordOptions = this.passwordOptionsCheckboxEl?.checked;
}
allOptionsTemplate() {
return html`
<fieldset id="all-controls">
<fieldset id="backup-location-controls">
<label
id="backup-location-label"
for="backup-location-filepicker-input"
data-l10n-id="turn-on-scheduled-backups-location-label"
></label>
<!-- TODO: show folder icon (bug 1895943) -->
<div id="backup-location-filepicker">
<input
id="backup-location-filepicker-input"
type="text"
readonly
data-l10n-id="turn-on-scheduled-backups-location-default-folder"
data-l10n-args=${JSON.stringify({
recommendedFolder: this.backupFilePath,
})}
data-l10n-attrs="value"
/>
<moz-button
id="backup-location-filepicker-button"
@click=${this.handleChooseLocation}
data-l10n-id="turn-on-scheduled-backups-location-choose-button"
aria-controls="backup-location-filepicker-input"
></moz-button>
</div>
</fieldset>
<fieldset id="sensitive-data-controls">
<div id="sensitive-data-checkbox">
<label
id="sensitive-data-checkbox-label"
for="sensitive-data-checkbox-input"
aria-controls="passwords"
aria-expanded=${this.showPasswordOptions}
>
<input
id="sensitive-data-checkbox-input"
value=${this.showPasswordOptions}
@click=${this.handleTogglePasswordOptions}
type="checkbox"
/>
<span
id="sensitive-data-checkbox-span"
data-l10n-id="turn-on-scheduled-backups-encryption-label"
></span>
</label>
<span
class="text-deemphasized"
data-l10n-id="turn-on-scheduled-backups-encryption-description"
></span>
</div>
${this.showPasswordOptions ? this.passwordOptionsTemplate() : null}
</fieldset>
</fieldset>
`;
}
passwordOptionsTemplate() {
return html`
<fieldset id="passwords">
<label id="new-password-label" for="new-password-input">
<span id="new-password-span" data-l10n-id="turn-on-scheduled-backups-encryption-create-password-label"></span>
<input type="password" id="new-password-input"/>
</label>
<label id="repeat-password-label" for="repeat-password-input">
<span id="repeat-password-span" data-l10n-id="turn-on-scheduled-backups-encryption-repeat-password-label"></span>
<input type="password" id="repeat-password-input"/>
</label>
</fieldset>
</fieldset>`;
}
contentTemplate() {
return html`
<div
id="backup-turn-on-scheduled-wrapper"
aria-labelledby="backup-turn-on-scheduled-header"
aria-describedby="backup-turn-on-scheduled-description"
>
<h1
id="backup-turn-on-scheduled-header"
data-l10n-id="turn-on-scheduled-backups-header"
></h1>
<main id="backup-turn-on-scheduled-content">
<div id="backup-turn-on-scheduled-description">
<span
id="backup-turn-on-scheduled-description-span"
data-l10n-id="turn-on-scheduled-backups-description"
></span>
<a
id="backup-turn-on-scheduled-learn-more-link"
is="moz-support-link"
support-page="todo-backup"
data-l10n-id="turn-on-scheduled-backups-support-link"
></a>
</div>
${this.allOptionsTemplate()}
</main>
<moz-button-group id="backup-turn-on-scheduled-button-group">
<moz-button
id="backup-turn-on-scheduled-cancel-button"
@click=${this.handleCancel}
data-l10n-id="turn-on-scheduled-backups-cancel-button"
></moz-button>
<moz-button
id="backup-turn-on-scheduled-confirm-button"
@click=${this.handleConfirm}
type="primary"
data-l10n-id="turn-on-scheduled-backups-confirm-button"
></moz-button>
</moz-button-group>
</div>
`;
}
render() {
return html`
<link
rel="stylesheet"
href="chrome://browser/content/backup/turn-on-scheduled-backups.css"
/>
${this.contentTemplate()}
`;
}
}
customElements.define("turn-on-scheduled-backups", TurnOnScheduledBackups);

View file

@ -0,0 +1,30 @@
/* 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/. */
// eslint-disable-next-line import/no-unresolved
import { html } from "lit.all.mjs";
import "chrome://global/content/elements/moz-card.mjs";
import "./turn-on-scheduled-backups.mjs";
window.MozXULElement.insertFTLIfNeeded("locales-preview/backupSettings.ftl");
window.MozXULElement.insertFTLIfNeeded("branding/brand.ftl");
export default {
title: "Domain-specific UI Widgets/Backup/Turn On Scheduled Backups",
component: "turn-on-scheduled-backups",
argTypes: {},
};
const Template = ({ backupFilePath }) => html`
<moz-card style="width: 27.8rem;">
<turn-on-scheduled-backups
.backupFilePath=${backupFilePath}
></turn-on-scheduled-backups>
</moz-card>
`;
export const RecommendedFolder = Template.bind({});
RecommendedFolder.args = {
backupFilePath: "Documents",
};

View file

@ -8,4 +8,7 @@ browser.jar:
content/browser/backup/debug.js (content/debug.js)
#endif
content/browser/backup/BackupManifest.1.schema.json (content/BackupManifest.1.schema.json)
content/browser/backup/backup-settings.css (content/backup-settings.css)
content/browser/backup/backup-settings.mjs (content/backup-settings.mjs)
content/browser/backup/turn-on-scheduled-backups.css (content/turn-on-scheduled-backups.css)
content/browser/backup/turn-on-scheduled-backups.mjs (content/turn-on-scheduled-backups.mjs)

View file

@ -2,6 +2,7 @@
prefs = [
"browser.backup.enabled=true",
"browser.backup.preferences.ui.enabled=true",
"browser.backup.scheduled.enabled=false",
]
["browser_settings.js"]

View file

@ -38,3 +38,51 @@ add_task(async function test_preferences_visibility() {
await SpecialPowers.popPrefEnv();
});
/**
* Tests that the turn on scheduled backups dialog can set
* browser.backup.scheduled.enabled to true from the settings page.
*/
add_task(async function test_turn_on_scheduled_backups_confirm() {
await BrowserTestUtils.withNewTab("about:preferences", async browser => {
let settings = browser.contentDocument.querySelector("backup-settings");
await settings.updateComplete;
let turnOnButton = settings.scheduledBackupsButtonEl;
Assert.ok(
turnOnButton,
"Button to turn on scheduled backups should be found"
);
turnOnButton.click();
await settings.updateComplete;
let turnOnScheduledBackups = settings.turnOnScheduledBackupsEl;
Assert.ok(
turnOnScheduledBackups,
"turn-on-scheduled-backups should be found"
);
let confirmButton = turnOnScheduledBackups.confirmButtonEl;
let promise = BrowserTestUtils.waitForEvent(
window,
"scheduledBackupsConfirm"
);
Assert.ok(confirmButton, "Confirm button should be found");
confirmButton.click();
await promise;
await settings.updateComplete;
let scheduledPrefVal = Services.prefs.getBoolPref(
"browser.backup.scheduled.enabled"
);
Assert.ok(scheduledPrefVal, "Scheduled backups pref should be true");
});
});

View file

@ -1,4 +1,9 @@
[DEFAULT]
prefs = [
"browser.backup.scheduled.enabled=false",
]
skip-if = ["os == 'android'"]
["test_backup_settings.html"]
["test_turn_on_scheduled_backups.html"]

View file

@ -31,6 +31,41 @@
settings.remove();
});
/**
* Tests that the dialog for turning on scheduled backups can be displayed
* from settings, or hidden if cancelled.
*/
add_task(async function test_turnOnScheduledBackupsDialog() {
let settings = document.getElementById("test-backup-settings");
settings.backupServiceState = {
scheduledBackupsEnabled: false,
}
await settings.updateComplete;
let turnOnButton = settings.scheduledBackupsButtonEl;
let dialog = settings.turnOnScheduledBackupsDialogEl;
ok(turnOnButton, "Button to turn on scheduled backups should be found");
ok(!dialog.open, "Dialog should not be open");
turnOnButton.click();
await settings.updateComplete;
ok(dialog?.open, "Dialog should be open");
let turnOnScheduledBackups = dialog.querySelector("turn-on-scheduled-backups");
ok(turnOnScheduledBackups, "turn-on-scheduled-backups should be found");
let cancelButton = turnOnScheduledBackups.shadowRoot.getElementById("backup-turn-on-scheduled-cancel-button");
ok(cancelButton, "Cancel button should be found");
cancelButton.click();
await settings.updateComplete;
ok(!dialog.open, "Dialog should not be open");
});
</script>
</head>
<body>

View file

@ -0,0 +1,96 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Tests for the turn-on-scheduled-backups component</title>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script
src="chrome://browser/content/backup/turn-on-scheduled-backups.mjs"
type="module"
></script>
<link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<script>
const { BrowserTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/BrowserTestUtils.sys.mjs"
);
/**
* Tests that adding a turn-on-scheduled-backups element to the DOM causes it to
* fire a BackupUI:InitWidget event.
*/
add_task(async function test_initWidget() {
let turnOnScheduledBackups = document.createElement("turn-on-scheduled-backups");
let content = document.getElementById("content");
let sawInitWidget = BrowserTestUtils.waitForEvent(content, "BackupUI:InitWidget");
content.appendChild(turnOnScheduledBackups);
await sawInitWidget;
ok(true, "Saw BackupUI:InitWidget");
turnOnScheduledBackups.remove();
});
/**
* Tests that pressing the confirm button will dispatch the expected events.
*/
add_task(async function test_confirm() {
let turnOnScheduledBackups = document.getElementById("test-turn-on-scheduled-backups");
let confirmButton = turnOnScheduledBackups.confirmButtonEl;
ok(confirmButton, "Confirm button should be found");
let content = document.getElementById("content");
let promise = BrowserTestUtils.waitForEvent(content, "scheduledBackupsConfirm");
confirmButton.click()
await promise;
ok(true, "Detected event after selecting the confirm button");
})
/**
* Tests that pressing the cancel button will dispatch the expected events.
*/
add_task(async function test_cancel() {
let turnOnScheduledBackups = document.getElementById("test-turn-on-scheduled-backups");
let cancelButton = turnOnScheduledBackups.cancelButtonEl;
ok(cancelButton, "Cancel button should be found");
let content = document.getElementById("content");
let promise = BrowserTestUtils.waitForEvent(content, "scheduledBackupsCancel");
cancelButton.click()
await promise;
ok(true, "Detected event after selecting the cancel button");
})
/**
* Tests that selecting the checkbox for enabling backup encryption will show more
* options to configure the password needed for encryption.
*/
add_task(async function test_expandedPasswords() {
let turnOnScheduledBackups = document.getElementById("test-turn-on-scheduled-backups");
let passwordsCheckbox = turnOnScheduledBackups.passwordOptionsCheckboxEl;
ok(passwordsCheckbox, "Passwords checkbox should be found");
ok(!turnOnScheduledBackups.passwordOptionsExpandedEl, "Passwords expanded options should not be found");
passwordsCheckbox.click();
await turnOnScheduledBackups.updateComplete;
ok(turnOnScheduledBackups.passwordOptionsExpandedEl, "Passwords expanded options should be found");
})
</script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
<turn-on-scheduled-backups id="test-turn-on-scheduled-backups"></turn-on-scheduled-backups>
</div>
<pre id="test"></pre>
</body>
</html>

View file

@ -3,3 +3,33 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
settings-data-backup-header = Backup
settings-data-backup-toggle = Manage backup
## These strings are displayed in a modal when users want to turn on scheduled backups.
turn-on-scheduled-backups-header = Turn on backup
turn-on-scheduled-backups-description = { -brand-short-name } will create a snapshot of your data every 60 minutes. You can restore it if theres a problem or you get a new device.
turn-on-scheduled-backups-support-link = What will be backed up?
# "Location" refers to the save location or a folder where users want backups stored.
turn-on-scheduled-backups-location-label = Location
# Variables:
# $recommendedFolder (String) - Name of the recommended folder for saving backups
turn-on-scheduled-backups-location-default-folder =
.value = { $recommendedFolder } (recommended)
turn-on-scheduled-backups-location-choose-button =
{ PLATFORM() ->
[macos] Choose…
*[other] Browse…
}
turn-on-scheduled-backups-encryption-label = Back up your sensitive data
turn-on-scheduled-backups-encryption-description = Back up your passwords, payment methods, and cookies with encryption.
turn-on-scheduled-backups-encryption-create-password-label = Password
# Users will be prompted to re-type a password, to ensure that the password is entered correctly.
turn-on-scheduled-backups-encryption-repeat-password-label = Repeat password
turn-on-scheduled-backups-cancel-button = Cancel
turn-on-scheduled-backups-confirm-button = Turn on backup
##