diff options
Diffstat (limited to 'browser/components/migration/tests/chrome')
-rw-r--r-- | browser/components/migration/tests/chrome/chrome.ini | 4 | ||||
-rw-r--r-- | browser/components/migration/tests/chrome/test_migration_wizard.html | 1154 |
2 files changed, 1158 insertions, 0 deletions
diff --git a/browser/components/migration/tests/chrome/chrome.ini b/browser/components/migration/tests/chrome/chrome.ini new file mode 100644 index 0000000000..2df25e8304 --- /dev/null +++ b/browser/components/migration/tests/chrome/chrome.ini @@ -0,0 +1,4 @@ +[DEFAULT] +skip-if = os == 'android' + +[test_migration_wizard.html] diff --git a/browser/components/migration/tests/chrome/test_migration_wizard.html b/browser/components/migration/tests/chrome/test_migration_wizard.html new file mode 100644 index 0000000000..7f3f4ab9a9 --- /dev/null +++ b/browser/components/migration/tests/chrome/test_migration_wizard.html @@ -0,0 +1,1154 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <title>Basic tests for the Migration Wizard 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/migration/migration-wizard.mjs" + type="module" + ></script> + <link + rel="stylesheet" + href="chrome://mochikit/content/tests/SimpleTest/test.css" + /> + <script> + "use strict"; + + const { MigrationWizardConstants } = ChromeUtils.importESModule( + "chrome://browser/content/migration/migration-wizard-constants.mjs" + ); + + const { BrowserTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/BrowserTestUtils.sys.mjs" + ); + + const MIGRATOR_PROFILE_INSTANCES = [ + { + key: "some-browser-0", + type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, + displayName: "Some Browser 0", + resourceTypes: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS"], + profile: { id: "person-2", name: "Person 2" }, + }, + { + key: "some-browser-1", + type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, + displayName: "Some Browser 1", + resourceTypes: ["HISTORY", "BOOKMARKS"], + profile: null, + }, + ]; + + let gWiz = null; + let gShadowRoot = null; + let gDeck = null; + + /** + * Returns the .resource-progress-group div for a particular resource + * type. + * + * @param {string} displayedResourceType + * One of the constants belonging to + * MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES. + * @returns {Element} + */ + function getResourceGroup(displayedResourceType) { + return gShadowRoot.querySelector( + `.resource-progress-group[data-resource-type="${displayedResourceType}"]` + ); + } + + add_setup(async function() { + gWiz = document.getElementById("test-wizard"); + gShadowRoot = gWiz.openOrClosedShadowRoot; + gDeck = gShadowRoot.querySelector("#wizard-deck"); + }); + + /** + * Tests that the MigrationWizard:RequestState event is fired when the + * <migration-wizard> is added to the DOM if the auto-request-state attribute + * is set, and then ensures that the starting page is correct. + * + * This also tests that the MigrationWizard:RequestState is not fired automatically + * if the auto-request-state attribute is not set, but is then fired upon calling + * requestState(). + * + * This uses a dynamically created <migration-wizard> instead of the one already + * in the content div to make sure that the init event is captured. + */ + add_task(async function test_init_event() { + const REQUEST_STATE_EVENT = "MigrationWizard:RequestState"; + + let wiz = document.createElement("migration-wizard"); + wiz.toggleAttribute("auto-request-state", true); + let panelList = document.createElement("panel-list"); + wiz.appendChild(panelList); + let content = document.getElementById("content"); + let promise = new Promise(resolve => { + content.addEventListener(REQUEST_STATE_EVENT, resolve, { + once: true, + }); + }); + content.appendChild(wiz); + await promise; + ok(true, `Saw ${REQUEST_STATE_EVENT} event.`); + let shadowRoot = wiz.openOrClosedShadowRoot; + let deck = shadowRoot.querySelector("#wizard-deck"); + is( + deck.selectedViewName, + "page-loading", + "Should have the loading page selected" + ); + wiz.remove(); + + wiz.toggleAttribute("auto-request-state", false); + let sawEvent = false; + let handler = () => { + sawEvent = true; + }; + content.addEventListener(REQUEST_STATE_EVENT, handler); + content.appendChild(wiz); + ok(!sawEvent, `Should not have seen ${REQUEST_STATE_EVENT} event.`); + content.removeEventListener(REQUEST_STATE_EVENT, handler); + + promise = new Promise(resolve => { + content.addEventListener(REQUEST_STATE_EVENT, resolve, { + once: true, + }); + }); + wiz.requestState(); + await promise; + ok(true, `Saw ${REQUEST_STATE_EVENT} event.`); + wiz.remove(); + }); + + /** + * Tests that the wizard can show a list of browser and profiles. + */ + add_task(async function test_selection() { + gWiz.setState({ + page: MigrationWizardConstants.PAGES.SELECTION, + migrators: MIGRATOR_PROFILE_INSTANCES, + showImportAll: false, + }); + + let selector = gShadowRoot.querySelector("#browser-profile-selector"); + let preamble = gShadowRoot.querySelector(".resource-selection-preamble"); + ok(!isHidden(preamble), "preamble should shown."); + + let panelList = gWiz.querySelector("panel-list"); + is(panelList.childElementCount, 2, "Should have two child elements"); + + let resourceTypeList = gShadowRoot.querySelector("#resource-type-list"); + let details = gShadowRoot.querySelector("details"); + ok(details.open, "Details should be open"); + + // Test that the resource type checkboxes are shown or hidden depending on + // which resourceTypes are included with the MigratorProfileInstance. + for (let migratorInstance of MIGRATOR_PROFILE_INSTANCES) { + selector.click(); + await new Promise(resolve => { + gWiz + .querySelector("panel-list") + .addEventListener("shown", resolve, { once: true }); + }); + let panelItem = gWiz.querySelector( + `panel-item[key="${migratorInstance.key}"]` + ); + ok(panelItem, "Should find panel-item."); + panelItem.click(); + + is( + selector.querySelector("#migrator-name").textContent, + migratorInstance.displayName, + "Selector should show display name" + ); + let profileName = selector.querySelector("#profile-name"); + + if (migratorInstance.profile) { + ok(!isHidden(profileName), "Profile name element should be displayed."); + is( + profileName.textContent, + migratorInstance.profile.name, + "Selector should show profile name" + ); + } else { + ok(isHidden(profileName), "Profile name element should be hidden."); + is(profileName.textContent, ""); + } + + for (let resourceType in MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES) { + let node = resourceTypeList.querySelector( + `label[data-resource-type="${resourceType}"]` + ); + + if (migratorInstance.resourceTypes.includes(resourceType)) { + ok(!isHidden(node), `Selection for ${resourceType} should be shown.`); + ok( + node.control.checked, + `Checkbox for ${resourceType} should be checked.` + ); + } else { + ok(isHidden(node), `Selection for ${resourceType} should be hidden.`); + ok( + !node.control.checked, + `Checkbox for ${resourceType} should be unchecked.` + ); + } + } + } + + let selectAll = gShadowRoot.querySelector("#select-all"); + let summary = gShadowRoot.querySelector("summary"); + ok(isHidden(selectAll), "Selection for select-all should be hidden."); + ok(isHidden(summary), "Summary should be hidden."); + ok(!isHidden(details), "Details should be shown."); + }); + + /** + * Tests the migration wizard with no resources + */ + add_task(async function test_no_resources() { + gWiz.setState({ + page: MigrationWizardConstants.PAGES.SELECTION, + migrators: [{ + key: "some-browser-0", + type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, + displayName: "Some Browser 0 with no resources", + resourceTypes: [], + profile: { id: "person-1", name: "Person 1" }, + }], + showImportAll: false, + }); + + let noResourcesFound = gShadowRoot.querySelector(".no-resources-found"); + let hideOnErrorEls = gShadowRoot.querySelectorAll(".hide-on-error"); + ok( + !isHidden(noResourcesFound), + "Error message of no reasources should be shown." + ); + for (let hideOnErrorEl of hideOnErrorEls) { + ok(isHidden(hideOnErrorEl), "Item should be hidden."); + } + }); + + /** + * Tests variant 2 of the migration wizard + */ + add_task(async function test_selection_variant_2() { + gWiz.setState({ + page: MigrationWizardConstants.PAGES.SELECTION, + migrators: MIGRATOR_PROFILE_INSTANCES, + showImportAll: true, + }); + + let preamble = gShadowRoot.querySelector(".resource-selection-preamble"); + ok(isHidden(preamble), "preamble should be hidden."); + + let selector = gShadowRoot.querySelector("#browser-profile-selector"); + selector.click(); + await new Promise(resolve => { + let panelList = gWiz.querySelector("panel-list"); + if (panelList) { + panelList.addEventListener("shown", resolve, { once: true }); + } + }); + + let panelItems = gWiz.querySelectorAll("panel-list > panel-item"); + is(panelItems.length, 2, "Should have two panel items"); + + let details = gShadowRoot.querySelector("details"); + ok(!details.open, "Details should be closed"); + details.open = true; + + for (let i = 0; i < panelItems.length; i++) { + let migratorInstance = MIGRATOR_PROFILE_INSTANCES[i]; + let panelItem = panelItems[i]; + panelItem.click(); + for (let resourceType in MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES) { + let node = gShadowRoot.querySelector( + `#resource-type-list label[data-resource-type="${resourceType}"]` + ); + if (migratorInstance.resourceTypes.includes(resourceType)) { + ok(!isHidden(node), `Selection for ${resourceType} should be shown.`); + ok( + node.control.checked, + `Checkbox for ${resourceType} should be checked.` + ); + } else { + ok(isHidden(node), `Selection for ${resourceType} should be hidden.`); + ok( + !node.control.checked, + `Checkbox for ${resourceType} should be unchecked.` + ); + } + } + } + + let selectAll = gShadowRoot.querySelector("#select-all"); + let summary = gShadowRoot.querySelector("summary"); + ok(!isHidden(selectAll), "Selection for select-all should be shown."); + ok(selectAll.control.checked, "Checkbox for select-all should be checked."); + ok(!isHidden(summary), "Summary should be shown."); + ok(!isHidden(details), "Details should be shown."); + + let selectAllCheckbox = gShadowRoot.querySelector(".select-all-checkbox"); + selectAllCheckbox.checked = true; + selectAllCheckbox.dispatchEvent(new CustomEvent("change")); + let resourceLabels = gShadowRoot.querySelectorAll("label[data-resource-type]"); + for (let resourceLabel of resourceLabels) { + if (resourceLabel.hidden) { + ok( + !resourceLabel.control.checked, + `Hidden checkbox for ${resourceLabel.dataset.resourceType} should be unchecked.` + + ); + } else { + ok( + resourceLabel.control.checked, + `Visible checkbox for ${resourceLabel.dataset.resourceType} should be checked.` + ); + } + } + + let selectedDataHeader = gShadowRoot.querySelector(".selected-data-header"); + let selectedData = gShadowRoot.querySelector(".selected-data"); + + let bookmarks = gShadowRoot.querySelector("#bookmarks"); + let history = gShadowRoot.querySelector("#history"); + + let selectedDataUpdated = BrowserTestUtils.waitForEvent( + gWiz, + "MigrationWizard:ResourcesUpdated" + ); + bookmarks.control.checked = true; + history.control.checked = true; + bookmarks.dispatchEvent(new CustomEvent("change")); + + ok(bookmarks.control.checked, "Bookmarks should be checked"); + ok(history.control.checked, "History should be checked"); + + await selectedDataUpdated; + + is( + selectedData.textContent, + "Bookmarks and history", + "Testing if selected-data reflects the selected resources." + ); + + is( + selectedDataHeader.dataset.l10nId, + "migration-all-available-data-label", + "Testing if selected-data-header reflects the selected resources" + ); + + let importButton = gShadowRoot.querySelector("#import"); + + ok( + !importButton.disabled, + "Testing if import button is enabled when at least one resource is selected." + ); + + let importButtonUpdated = BrowserTestUtils.waitForEvent( + gWiz, + "MigrationWizard:ResourcesUpdated" + ); + + selectAllCheckbox.checked = false; + selectAllCheckbox.dispatchEvent(new CustomEvent("change", { bubbles: true })); + await importButtonUpdated; + + ok( + importButton.disabled, + "Testing if import button is disabled when no resources are selected." + ); + }); + + /** + * Tests variant 2 of the migration wizard when there's a single resource + * item. + */ + add_task(async function test_selection_variant_2_single_item() { + let resourcesUpdated = BrowserTestUtils.waitForEvent( + gWiz, + "MigrationWizard:ResourcesUpdated" + ); + gWiz.setState({ + page: MigrationWizardConstants.PAGES.SELECTION, + migrators: [{ + key: "some-browser-0", + type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, + displayName: "Some Browser 0 with a single resource", + resourceTypes: ["HISTORY"], + profile: { id: "person-1", name: "Person 1" }, + }, { + key: "some-browser-1", + type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, + displayName: "Some Browser 1 with a two resources", + resourceTypes: ["HISTORY", "BOOKMARKS"], + profile: { id: "person-2", name: "Person 2" }, + }], + showImportAll: true, + }); + await resourcesUpdated; + + let selectAll = gShadowRoot.querySelector("#select-all"); + let summary = gShadowRoot.querySelector("summary"); + let details = gShadowRoot.querySelector("details"); + ok(!details.open, "Details should be closed"); + details.open = true; + + ok(isHidden(selectAll), "Selection for select-all should be hidden."); + ok(!isHidden(summary), "Summary should be shown."); + ok(!isHidden(details), "Details should be shown."); + + resourcesUpdated = BrowserTestUtils.waitForEvent( + gWiz, + "MigrationWizard:ResourcesUpdated" + ); + let browser1Item = gWiz.querySelector("panel-item[key='some-browser-1']"); + browser1Item.click(); + await resourcesUpdated; + + ok(!isHidden(selectAll), "Selection for select-all should be shown."); + ok(!isHidden(summary), "Summary should be shown."); + ok(!isHidden(details), "Details should be shown."); + }); + + /** + * Tests that the Select All checkbox is checked if all non-hidden resource + * types are checked, and unchecked otherwise. + */ + add_task(async function test_selection_variant_2_select_all() { + gWiz.setState({ + page: MigrationWizardConstants.PAGES.SELECTION, + migrators: MIGRATOR_PROFILE_INSTANCES, + showImportAll: true, + }); + + let details = gShadowRoot.querySelector("details"); + ok(!details.open, "Details should be closed"); + details.open = true; + + let selectAll = gShadowRoot.querySelector("#select-all"); + ok(selectAll.control.checked, "Select all should be checked by default"); + + let bookmarksResourceLabel = gShadowRoot.querySelector( + "label[data-resource-type='BOOKMARKS']" + ); + ok(bookmarksResourceLabel.control.checked, "Bookmarks should be checked"); + + bookmarksResourceLabel.control.click(); + ok(!bookmarksResourceLabel.control.checked, "Bookmarks should no longer be checked"); + ok(!selectAll.control.checked, "Select all should not longer be checked"); + + bookmarksResourceLabel.control.click(); + ok(bookmarksResourceLabel.control.checked, "Bookmarks should be checked again"); + ok(selectAll.control.checked, "Select all should be checked"); + }); + + /** + * Tests that the wizard can show partial progress during migration. + */ + add_task(async function test_partial_progress() { + const BOOKMARKS_SUCCESS_STRING = "Some bookmarks success string"; + gWiz.setState({ + page: MigrationWizardConstants.PAGES.PROGRESS, + key: "chrome", + progress: { + [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { + inProgress: false, + message: BOOKMARKS_SUCCESS_STRING, + }, + // Don't include PASSWORDS to check that it's hidden. + [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.HISTORY]: { + inProgress: true, + }, + [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.FORMDATA]: { + inProgress: true, + }, + }, + }); + is( + gDeck.selectedViewName, + "page-progress", + "Should have the progress page selected" + ); + + // Bookmarks + let bookmarksGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS + ); + ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible"); + let progressIcon = bookmarksGroup.querySelector(".progress-icon"); + ok( + progressIcon.classList.contains("completed"), + "Progress should be completed" + ); + is( + bookmarksGroup.querySelector(".success-text").textContent, + BOOKMARKS_SUCCESS_STRING + ); + + // Passwords + let passwordsGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.PASSWORDS + ); + ok(isHidden(passwordsGroup), "Passwords group should be hidden"); + + // History + let historyGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.HISTORY + ); + ok(!isHidden(historyGroup), "History group should be visible"); + progressIcon = historyGroup.querySelector(".progress-icon"); + ok( + !progressIcon.classList.contains("completed"), + "Progress should be still be underway" + ); + is(historyGroup.querySelector(".success-text").textContent.trim(), ""); + + // Form Data + let formDataGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.FORMDATA + ); + ok(!isHidden(formDataGroup), "Form data group should be visible"); + progressIcon = formDataGroup.querySelector(".progress-icon"); + ok( + !progressIcon.classList.contains("completed"), + "Progress should be still be underway" + ); + is(formDataGroup.querySelector(".success-text").textContent.trim(), ""); + + // With progress still being underway, the header should be using the + // in progress string. + let header = gShadowRoot.querySelector("#progress-header"); + is( + header.getAttribute("data-l10n-id"), + "migration-wizard-progress-header", + "Should be showing in-progress header string" + ); + + let progressPage = gShadowRoot.querySelector("div[name='page-progress']"); + let doneButton = progressPage.querySelector(".done-button"); + ok(isHidden(doneButton), "Done button should be hidden"); + let cancelButton = progressPage.querySelector(".cancel-close"); + ok(!isHidden(cancelButton), "Cancel button should be visible"); + ok(cancelButton.disabled, "Cancel button should be disabled"); + }); + + /** + * Tests that the wizard can show completed migration progress. + */ + add_task(async function test_completed_progress() { + const BOOKMARKS_SUCCESS_STRING = "Some bookmarks success string"; + const PASSWORDS_SUCCESS_STRING = "Some passwords success string"; + const FORMDATA_SUCCESS_STRING = "Some formdata string"; + gWiz.setState({ + page: MigrationWizardConstants.PAGES.PROGRESS, + key: "chrome", + progress: { + [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { + inProgress: false, + message: BOOKMARKS_SUCCESS_STRING, + }, + [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.PASSWORDS]: { + inProgress: false, + message: PASSWORDS_SUCCESS_STRING, + }, + // Don't include HISTORY to check that it's hidden. + [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.FORMDATA]: { + inProgress: false, + message: FORMDATA_SUCCESS_STRING, + }, + }, + }); + is( + gDeck.selectedViewName, + "page-progress", + "Should have the progress page selected" + ); + + // Bookmarks + let bookmarksGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS + ); + ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible"); + let progressIcon = bookmarksGroup.querySelector(".progress-icon"); + ok( + progressIcon.classList.contains("completed"), + "Progress should be completed" + ); + is( + bookmarksGroup.querySelector(".success-text").textContent, + BOOKMARKS_SUCCESS_STRING + ); + + // Passwords + let passwordsGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.PASSWORDS + ); + ok(!isHidden(passwordsGroup), "Passwords group should be visible"); + progressIcon = passwordsGroup.querySelector(".progress-icon"); + ok( + progressIcon.classList.contains("completed"), + "Progress should be completed" + ); + is( + passwordsGroup.querySelector(".success-text").textContent, + PASSWORDS_SUCCESS_STRING + ); + + // History + let historyGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.HISTORY + ); + ok(isHidden(historyGroup), "History group should be hidden"); + + // Form Data + let formDataGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.FORMDATA + ); + ok(!isHidden(formDataGroup), "Form data group should be visible"); + progressIcon = formDataGroup.querySelector(".progress-icon"); + ok( + progressIcon.classList.contains("completed"), + "Progress should be completed" + ); + is( + formDataGroup.querySelector(".success-text").textContent, + FORMDATA_SUCCESS_STRING + ); + + // With progress being complete, the header should be using the completed + // migration string. + let header = gShadowRoot.querySelector("#progress-header"); + is( + header.getAttribute("data-l10n-id"), + "migration-wizard-progress-done-header", + "Should be showing completed migration header string" + ); + + let progressPage = gShadowRoot.querySelector("div[name='page-progress']"); + let doneButton = progressPage.querySelector(".done-button"); + ok(!isHidden(doneButton), "Done button should be visible and enabled"); + let cancelButton = progressPage.querySelector(".cancel-close"); + ok(isHidden(cancelButton), "Cancel button should be hidden"); + }); + + /** + * Tests that the wizard can show partial progress during file migration. + */ + add_task(async function test_partial_file_progress() { + const PASSWORDS_SUCCESS_STRING = "Some passwords success string"; + const TITLE = "Partial progress"; + + gWiz.setState({ + page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS, + title: "Partial progress", + progress: { + [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_FROM_FILE]: { + inProgress: false, + message: PASSWORDS_SUCCESS_STRING, + }, + [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: { + inProgress: true, + }, + }, + }); + + is( + gDeck.selectedViewName, + "page-file-import-progress", + "Should have the file progress page selected" + ); + + let header = gShadowRoot.querySelector("#file-import-progress-header"); + is(header.textContent, TITLE, "Title is set correctly."); + + let passwordsFromFileGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_FROM_FILE + ); + ok(!isHidden(passwordsFromFileGroup), "Passwords from file group should be visible"); + let progressIcon = passwordsFromFileGroup.querySelector(".progress-icon"); + ok( + progressIcon.classList.contains("completed"), + "Progress should be completed" + ); + is( + passwordsFromFileGroup.querySelector(".success-text").textContent, + PASSWORDS_SUCCESS_STRING + ); + + let passwordsUpdatedGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED + ); + ok(isHidden(passwordsUpdatedGroup), "Passwords updated group should be hidden"); + + let passwordsNewGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW + ); + ok(!isHidden(passwordsNewGroup), "Passwords new group should be visible"); + progressIcon = passwordsNewGroup.querySelector(".progress-icon"); + ok( + !progressIcon.classList.contains("completed"), + "Progress should be still be underway" + ); + is(passwordsNewGroup.querySelector(".success-text").textContent.trim(), ""); + + let progressPage = gShadowRoot.querySelector("div[name='page-file-import-progress']"); + let doneButton = progressPage.querySelector(".done-button"); + ok(isHidden(doneButton), "Done button should be hidden"); + let cancelButton = progressPage.querySelector(".cancel-close"); + ok(!isHidden(cancelButton), "Cancel button should be visible"); + ok(cancelButton.disabled, "Cancel button should be disabled"); + }); + + /** + * Tests that the wizard can show completed migration progress. + */ + add_task(async function test_completed_file_progress() { + const PASSWORDS_NEW_SUCCESS_STRING = "2 added"; + const PASSWORDS_UPDATED_SUCCESS_STRING = "5 updated"; + const TITLE = "Done doing file import"; + + gWiz.setState({ + page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS, + title: TITLE, + progress: { + [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: { + inProgress: false, + message: PASSWORDS_NEW_SUCCESS_STRING, + }, + [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED]: { + inProgress: false, + message: PASSWORDS_UPDATED_SUCCESS_STRING, + }, + }, + }); + is( + gDeck.selectedViewName, + "page-file-import-progress", + "Should have the file progress page selected" + ); + + let header = gShadowRoot.querySelector("#file-import-progress-header"); + is(header.textContent, TITLE, "Title is set correctly."); + + let passwordsNewGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW + ); + ok(!isHidden(passwordsNewGroup), "Passwords new group should be visible"); + let progressIcon = passwordsNewGroup.querySelector(".progress-icon"); + ok( + progressIcon.classList.contains("completed"), + "Progress should be completed" + ); + is( + passwordsNewGroup.querySelector(".success-text").textContent, + PASSWORDS_NEW_SUCCESS_STRING + ); + + let passwordsUpdatedGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED + ); + ok(!isHidden(passwordsUpdatedGroup), "Passwords updated group should be visible"); + progressIcon = passwordsUpdatedGroup.querySelector(".progress-icon"); + ok( + progressIcon.classList.contains("completed"), + "Progress should be completed" + ); + is( + passwordsUpdatedGroup.querySelector(".success-text").textContent, + PASSWORDS_UPDATED_SUCCESS_STRING + ); + + let passwordsFromFileGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_FROM_FILE + ); + ok(isHidden(passwordsFromFileGroup), "Passwords from file group should be hidden"); + + let progressPage = gShadowRoot.querySelector("div[name='page-file-import-progress']"); + let doneButton = progressPage.querySelector(".done-button"); + ok(!isHidden(doneButton), "Done button should be visible and enabled"); + let cancelButton = progressPage.querySelector(".cancel-close"); + ok(isHidden(cancelButton), "Cancel button should be hidden"); + }); + + /** + * Tests that the buttons that dismiss the wizard when embedded in + * a dialog are only visible when in dialog mode, and dispatch a + * MigrationWizard:Close event when clicked. + */ + add_task(async function test_dialog_mode_close() { + gWiz.toggleAttribute("dialog-mode", true); + gWiz.setState({ + page: MigrationWizardConstants.PAGES.SELECTION, + migrators: MIGRATOR_PROFILE_INSTANCES, + }); + + // For now, there's only a single .cancel-close button, so let's just test + // that one. Let's make this test fail if there are multiple so that we can + // then update this test to switch to the right pages to test those buttons + // too. + let buttons = gShadowRoot.querySelectorAll(".cancel-close:not([disabled])"); + ok( + buttons.length, + "This test expects at least one enabled .cancel-close button" + ); + let button = buttons[0]; + ok( + !isHidden(button), + ".cancel-close button should be visible in dialog mode." + ); + let closeEvent = BrowserTestUtils.waitForEvent(gWiz, "MigrationWizard:Close"); + synthesizeMouseAtCenter(button, {}); + await closeEvent; + + gWiz.toggleAttribute("dialog-mode", false); + ok( + isHidden(button), + ".cancel-close button should be hidden when not in dialog mode." + ); + }); + + /** + * Internet Explorer and Edge refer to bookmarks as "favorites", + * and we change our labels to suit when either of those browsers are + * selected as the migration source. This test tests that behavior in the + * selection page. + */ + add_task(async function test_ie_edge_favorites_selection() { + gWiz.setState({ + page: MigrationWizardConstants.PAGES.SELECTION, + migrators: MIGRATOR_PROFILE_INSTANCES, + showImportAll: false, + }); + + let bookmarksCheckboxLabel = gShadowRoot.querySelector("#bookmarks"); + let span = bookmarksCheckboxLabel.querySelector("span[default-data-l10n-id]"); + ok(span, "The bookmarks selection span has a default-data-l10n-id attribute"); + is( + span.getAttribute("data-l10n-id"), + span.getAttribute("default-data-l10n-id"), + "Should be showing the default string for bookmarks" + ); + + // Now test when in Variant 2, for the string in the <summary>. + let selectedDataUpdated = BrowserTestUtils.waitForEvent( + gWiz, + "MigrationWizard:ResourcesUpdated" + ); + + gWiz.setState({ + page: MigrationWizardConstants.PAGES.SELECTION, + migrators: MIGRATOR_PROFILE_INSTANCES, + showImportAll: true, + }); + + await selectedDataUpdated; + + let summary = gShadowRoot.querySelector("summary"); + ok( + summary.textContent.toLowerCase().includes("bookmarks"), + "Summary should include the string 'bookmarks'" + ); + + for (let key of MigrationWizardConstants.USES_FAVORITES) { + gWiz.setState({ + page: MigrationWizardConstants.PAGES.SELECTION, + migrators: [{ + key, + displayName: "Legacy Microsoft Browser", + resourceTypes: ["BOOKMARKS"], + profile: null, + }], + showImportAll: false, + }); + + is( + span.getAttribute("data-l10n-id"), + span.getAttribute("ie-edge-data-l10n-id"), + "Should be showing the IE/Edge string for bookmarks" + ); + + // Now test when in Variant 2, for the string in the <summary>. + selectedDataUpdated = BrowserTestUtils.waitForEvent( + gWiz, + "MigrationWizard:ResourcesUpdated" + ); + + gWiz.setState({ + page: MigrationWizardConstants.PAGES.SELECTION, + migrators: [{ + key, + displayName: "Legacy Microsoft Browser", + resourceTypes: ["BOOKMARKS"], + profile: null, + }], + showImportAll: true, + }); + + await selectedDataUpdated; + + ok( + summary.textContent.toLowerCase().includes("favorites"), + "Summary should include the string 'favorites'" + ); + } + }); + + /** + * Internet Explorer and Edge refer to bookmarks as "favorites", + * and we change our labels to suit when either of those browsers are + * selected as the migration source. This test tests that behavior in the + * progress page + */ + add_task(async function test_ie_edge_favorites_progress() { + gWiz.setState({ + page: MigrationWizardConstants.PAGES.PROGRESS, + key: "chrome", + progress: { + [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { + inProgress: false, + message: "A string from the parent", + }, + }, + }); + + let bookmarksGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS + ); + let span = bookmarksGroup.querySelector("span[default-data-l10n-id]"); + ok(span, "Should have found a span with default-data-l10n-id"); + is( + span.getAttribute("data-l10n-id"), + span.getAttribute("default-data-l10n-id"), + "Should be using the default string." + ); + + + for (let key of MigrationWizardConstants.USES_FAVORITES) { + gWiz.setState({ + page: MigrationWizardConstants.PAGES.PROGRESS, + key, + progress: { + [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { + inProgress: false, + message: "A string from the parent", + }, + }, + }); + + is( + span.getAttribute("data-l10n-id"), + span.getAttribute("ie-edge-data-l10n-id"), + "Should be showing the IE/Edge string for bookmarks" + ); + } + }); + + /** + * Tests that the button shown in either the browser migration success or + * file migration success pages is a "continue" button rather than a + * "done" button. + */ + add_task(async function test_embedded_continue_button() { + gWiz.toggleAttribute("dialog-mode", false); + gWiz.setState({ + page: MigrationWizardConstants.PAGES.PROGRESS, + key: "chrome", + progress: { + [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { + inProgress: false, + message: "A string from the parent", + }, + }, + }); + + let progressPage = gShadowRoot.querySelector("div[name='page-progress']"); + let cancelButton = progressPage.querySelector(".cancel-close"); + ok(isHidden(cancelButton), "Cancel button should be hidden"); + let doneButton = progressPage.querySelector(".done-button"); + ok(isHidden(doneButton), "Done button should be hidden when embedding"); + let continueButton = progressPage.querySelector(".continue-button"); + ok(!isHidden(continueButton), "Continue button should be displayed"); + + let content = document.getElementById("content"); + + let promise = new Promise(resolve => { + content.addEventListener("MigrationWizard:Close", resolve, { + once: true, + }); + }); + continueButton.click(); + await promise; + ok( + true, + "Clicking on the Continue button sent the MigrationWizard:Close event." + ); + + gWiz.setState({ + page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS, + title: "Done importing file data", + progress: { + [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: { + inProgress: false, + message: "Some message", + }, + [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED]: { + inProgress: false, + message: "Some other", + }, + }, + }); + + progressPage = gShadowRoot.querySelector("div[name='page-file-import-progress']"); + cancelButton = progressPage.querySelector(".cancel-close"); + ok(isHidden(cancelButton), "Cancel button should be hidden"); + doneButton = progressPage.querySelector(".done-button"); + ok(isHidden(doneButton), "Done button should be hidden when embedding"); + continueButton = progressPage.querySelector(".continue-button"); + ok(!isHidden(continueButton), "Continue button should be displayed"); + + promise = new Promise(resolve => { + content.addEventListener("MigrationWizard:Close", resolve, { + once: true, + }); + }); + continueButton.click(); + await promise; + ok( + true, + "Clicking on the Continue button sent the MigrationWizard:Close event." + ); + + gWiz.toggleAttribute("dialog-mode", true); + }); + + /** + * Tests that if a progress update comes down which puts a resource from + * being done to being back "inProgress", that the status message is + * cleared. + */ + add_task(async function test_clear_status_message_when_in_progress() { + const STRING_TO_CLEAR = "This string should get cleared"; + gWiz.toggleAttribute("dialog-mode", false); + gWiz.setState({ + page: MigrationWizardConstants.PAGES.PROGRESS, + key: "chrome", + progress: { + [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { + inProgress: false, + message: STRING_TO_CLEAR, + }, + }, + }); + + let bookmarksGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS + ); + ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible"); + let progressIcon = bookmarksGroup.querySelector(".progress-icon"); + ok( + progressIcon.classList.contains("completed"), + "Progress should be completed" + ); + is( + bookmarksGroup.querySelector(".success-text").textContent, + STRING_TO_CLEAR + ); + + gWiz.setState({ + page: MigrationWizardConstants.PAGES.PROGRESS, + key: "chrome", + progress: { + [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { + inProgress: true, + message: "", + }, + }, + }); + + ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible"); + ok( + !progressIcon.classList.contains("completed"), + "Progress should still be underway" + ); + is( + bookmarksGroup.querySelector(".success-text").textContent.trim(), + "" + ); + }); + + /** + * Tests that if a file progress update comes down which puts a resource + * from being done to being back "inProgress", that the status message is + * cleared. + * + * This is extremely similar to the above test, except that it's for progress + * updates for file resources. + */ + add_task(async function test_clear_status_message_when_in_file_progress() { + const STRING_TO_CLEAR = "This string should get cleared"; + gWiz.toggleAttribute("dialog-mode", false); + gWiz.setState({ + page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS, + key: "chrome", + progress: { + [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: { + inProgress: false, + message: STRING_TO_CLEAR, + }, + }, + }); + + let passwordsGroup = getResourceGroup( + MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW + ); + ok(!isHidden(passwordsGroup), "Passwords group should be visible"); + let progressIcon = passwordsGroup.querySelector(".progress-icon"); + ok( + progressIcon.classList.contains("completed"), + "Progress should be completed" + ); + is( + passwordsGroup.querySelector(".success-text").textContent, + STRING_TO_CLEAR + ); + + gWiz.setState({ + page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS, + key: "chrome", + progress: { + [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: { + inProgress: true, + message: "", + }, + }, + }); + + ok(!isHidden(passwordsGroup), "Passwords group should be visible"); + ok( + !progressIcon.classList.contains("completed"), + "Progress should still be underway" + ); + is( + passwordsGroup.querySelector(".success-text").textContent.trim(), + "" + ); + }); + </script> + </head> + <body> + <p id="display"></p> + <div id="content"> + <migration-wizard id="test-wizard" dialog-mode=""> + <panel-list></panel-list> + </migration-wizard> + </div> + <pre id="test"></pre> + </body> +</html> |