test_migration_wizard.html (69413B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>Basic tests for the Migration Wizard component</title> 6 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 7 <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> 8 <script src="head-common.js"></script> 9 <script 10 src="chrome://browser/content/migration/migration-wizard.mjs" 11 type="module" 12 ></script> 13 <link 14 rel="stylesheet" 15 href="chrome://mochikit/content/tests/SimpleTest/test.css" 16 /> 17 <script> 18 /* import-globals-from ../head-common.js */ 19 20 "use strict"; 21 22 const { BrowserTestUtils } = ChromeUtils.importESModule( 23 "resource://testing-common/BrowserTestUtils.sys.mjs" 24 ); 25 26 const MIGRATOR_PROFILE_INSTANCES = [ 27 { 28 key: "some-browser-0", 29 type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, 30 displayName: "Some Browser 0", 31 resourceTypes: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS", "EXTENSIONS"], 32 profile: { id: "person-2", name: "Person 2" }, 33 hasPermissions: true, 34 }, 35 { 36 key: "some-browser-1", 37 type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, 38 displayName: "Some Browser 1", 39 resourceTypes: ["HISTORY", "BOOKMARKS"], 40 profile: null, 41 hasPermissions: true, 42 }, 43 ]; 44 45 let gWiz = null; 46 let gShadowRoot = null; 47 let gDeck = null; 48 49 /** 50 * Returns the .resource-progress-group div for a particular resource 51 * type. 52 * 53 * @param {string} displayedResourceType 54 * One of the constants belonging to 55 * MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES. 56 * @returns {Element} 57 */ 58 function getResourceGroup(displayedResourceType) { 59 return gShadowRoot.querySelector( 60 `.resource-progress-group[data-resource-type="${displayedResourceType}"]` 61 ); 62 } 63 64 add_setup(async function() { 65 gWiz = document.getElementById("test-wizard"); 66 gShadowRoot = gWiz.openOrClosedShadowRoot; 67 gDeck = gShadowRoot.querySelector("#wizard-deck"); 68 }); 69 70 /** 71 * Tests that the MigrationWizard:RequestState event is fired when the 72 * <migration-wizard> is added to the DOM if the auto-request-state attribute 73 * is set, and then ensures that the starting page is correct. 74 * 75 * This also tests that the MigrationWizard:RequestState is not fired automatically 76 * if the auto-request-state attribute is not set, but is then fired upon calling 77 * requestState(). 78 * 79 * This uses a dynamically created <migration-wizard> instead of the one already 80 * in the content div to make sure that the init event is captured. 81 */ 82 add_task(async function test_init_event() { 83 const REQUEST_STATE_EVENT = "MigrationWizard:RequestState"; 84 85 let wiz = document.createElement("migration-wizard"); 86 wiz.toggleAttribute("auto-request-state", true); 87 let content = document.getElementById("content"); 88 let promise = new Promise(resolve => { 89 content.addEventListener(REQUEST_STATE_EVENT, resolve, { 90 once: true, 91 }); 92 }); 93 content.appendChild(wiz); 94 await promise; 95 ok(true, `Saw ${REQUEST_STATE_EVENT} event.`); 96 let shadowRoot = wiz.openOrClosedShadowRoot; 97 let deck = shadowRoot.querySelector("#wizard-deck"); 98 is( 99 deck.selectedViewName, 100 "page-loading", 101 "Should have the loading page selected" 102 ); 103 wiz.remove(); 104 105 wiz.toggleAttribute("auto-request-state", false); 106 let sawEvent = false; 107 let handler = () => { 108 sawEvent = true; 109 }; 110 content.addEventListener(REQUEST_STATE_EVENT, handler); 111 content.appendChild(wiz); 112 ok(!sawEvent, `Should not have seen ${REQUEST_STATE_EVENT} event.`); 113 content.removeEventListener(REQUEST_STATE_EVENT, handler); 114 115 promise = new Promise(resolve => { 116 content.addEventListener(REQUEST_STATE_EVENT, resolve, { 117 once: true, 118 }); 119 }); 120 wiz.requestState(); 121 await promise; 122 ok(true, `Saw ${REQUEST_STATE_EVENT} event.`); 123 wiz.remove(); 124 }); 125 126 /** 127 * Tests that the wizard can show a list of browser and profiles. 128 */ 129 add_task(async function test_selection() { 130 gWiz.setState({ 131 page: MigrationWizardConstants.PAGES.SELECTION, 132 migrators: MIGRATOR_PROFILE_INSTANCES, 133 showImportAll: false, 134 }); 135 136 let selector = gShadowRoot.querySelector("#browser-profile-selector"); 137 let preamble = gShadowRoot.querySelector(".resource-selection-preamble"); 138 ok(!isHidden(preamble), "preamble should shown."); 139 140 let panelList = gShadowRoot.querySelector("panel-list"); 141 is(panelList.childElementCount, 2, "Should have two child elements"); 142 143 let resourceTypeList = gShadowRoot.querySelector("#resource-type-list"); 144 let details = gShadowRoot.querySelector("details"); 145 ok(details.open, "Details should be open"); 146 147 // Test that the resource type checkboxes are shown or hidden depending on 148 // which resourceTypes are included with the MigratorProfileInstance. 149 for (let migratorInstance of MIGRATOR_PROFILE_INSTANCES) { 150 synthesizeMouseAtCenter(selector, {}, gWiz.ownerGlobal); 151 await new Promise(resolve => { 152 gShadowRoot 153 .querySelector("panel-list") 154 .addEventListener("shown", resolve, { once: true }); 155 }); 156 let panelItem = gShadowRoot.querySelector( 157 `panel-item[key="${migratorInstance.key}"]` 158 ); 159 ok(panelItem, "Should find panel-item."); 160 panelItem.click(); 161 162 is( 163 selector.querySelector("#migrator-name").textContent, 164 migratorInstance.displayName, 165 "Selector should show display name" 166 ); 167 let profileName = selector.querySelector("#profile-name"); 168 169 if (migratorInstance.profile) { 170 ok(!isHidden(profileName), "Profile name element should be displayed."); 171 is( 172 profileName.textContent, 173 migratorInstance.profile.name, 174 "Selector should show profile name" 175 ); 176 } else { 177 ok(isHidden(profileName), "Profile name element should be hidden."); 178 is(profileName.textContent, ""); 179 } 180 181 for (let resourceType of getChoosableResourceTypes()) { 182 let node = resourceTypeList.querySelector( 183 `label[data-resource-type="${resourceType}"]` 184 ); 185 186 if (migratorInstance.resourceTypes.includes(resourceType)) { 187 ok(!isHidden(node), `Selection for ${resourceType} should be shown.`); 188 ok( 189 node.control.checked, 190 `Checkbox for ${resourceType} should be checked.` 191 ); 192 } else { 193 ok(isHidden(node), `Selection for ${resourceType} should be hidden.`); 194 ok( 195 !node.control.checked, 196 `Checkbox for ${resourceType} should be unchecked.` 197 ); 198 } 199 } 200 } 201 202 let selectAll = gShadowRoot.querySelector("#select-all"); 203 let summary = gShadowRoot.querySelector("summary"); 204 ok(isHidden(selectAll), "Selection for select-all should be hidden."); 205 ok(isHidden(summary), "Summary should be hidden."); 206 ok(!isHidden(details), "Details should be shown."); 207 }); 208 209 /** 210 * Tests the migration wizard with no resources 211 */ 212 add_task(async function test_no_resources() { 213 gWiz.setState({ 214 page: MigrationWizardConstants.PAGES.SELECTION, 215 migrators: [{ 216 key: "some-browser-0", 217 type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, 218 displayName: "Some Browser 0 with no resources", 219 resourceTypes: [], 220 profile: { id: "person-1", name: "Person 1" }, 221 hasPermissions: true, 222 }], 223 showImportAll: false, 224 }); 225 226 let noResourcesFound = gShadowRoot.querySelector(".no-resources-found"); 227 let hideOnErrorEls = gShadowRoot.querySelectorAll(".hide-on-error"); 228 ok( 229 !isHidden(noResourcesFound), 230 "Error message of no reasources should be shown." 231 ); 232 for (let hideOnErrorEl of hideOnErrorEls) { 233 ok(isHidden(hideOnErrorEl), "Item should be hidden."); 234 } 235 }); 236 237 /** 238 * Tests variant 2 of the migration wizard 239 */ 240 add_task(async function test_selection_variant_2() { 241 gWiz.setState({ 242 page: MigrationWizardConstants.PAGES.SELECTION, 243 migrators: MIGRATOR_PROFILE_INSTANCES, 244 showImportAll: true, 245 }); 246 247 let preamble = gShadowRoot.querySelector(".resource-selection-preamble"); 248 ok(isHidden(preamble), "preamble should be hidden."); 249 250 let selector = gShadowRoot.querySelector("#browser-profile-selector"); 251 synthesizeMouseAtCenter(selector, {}, gWiz.ownerGlobal); 252 await new Promise(resolve => { 253 let panelList = gShadowRoot.querySelector("panel-list"); 254 if (panelList) { 255 panelList.addEventListener("shown", resolve, { once: true }); 256 } 257 }); 258 259 let panelItems = gShadowRoot.querySelectorAll("panel-list > panel-item"); 260 is(panelItems.length, 2, "Should have two panel items"); 261 262 let details = gShadowRoot.querySelector("details"); 263 ok(!details.open, "Details should be closed"); 264 details.open = true; 265 266 for (let i = 0; i < panelItems.length; i++) { 267 let migratorInstance = MIGRATOR_PROFILE_INSTANCES[i]; 268 let panelItem = panelItems[i]; 269 panelItem.click(); 270 for (let resourceType of getChoosableResourceTypes()) { 271 let node = gShadowRoot.querySelector( 272 `#resource-type-list label[data-resource-type="${resourceType}"]` 273 ); 274 if (migratorInstance.resourceTypes.includes(resourceType)) { 275 ok(!isHidden(node), `Selection for ${resourceType} should be shown.`); 276 ok( 277 node.control.checked, 278 `Checkbox for ${resourceType} should be checked.` 279 ); 280 } else { 281 ok(isHidden(node), `Selection for ${resourceType} should be hidden.`); 282 ok( 283 !node.control.checked, 284 `Checkbox for ${resourceType} should be unchecked.` 285 ); 286 } 287 } 288 } 289 290 let selectAll = gShadowRoot.querySelector("#select-all"); 291 let summary = gShadowRoot.querySelector("summary"); 292 ok(!isHidden(selectAll), "Selection for select-all should be shown."); 293 ok(selectAll.control.checked, "Checkbox for select-all should be checked."); 294 ok(!isHidden(summary), "Summary should be shown."); 295 ok(!isHidden(details), "Details should be shown."); 296 297 let selectAllCheckbox = gShadowRoot.querySelector(".select-all-checkbox"); 298 selectAllCheckbox.checked = true; 299 selectAllCheckbox.dispatchEvent(new CustomEvent("change")); 300 let resourceLabels = gShadowRoot.querySelectorAll("label[data-resource-type]"); 301 for (let resourceLabel of resourceLabels) { 302 if (resourceLabel.hidden) { 303 ok( 304 !resourceLabel.control.checked, 305 `Hidden checkbox for ${resourceLabel.dataset.resourceType} should be unchecked.` 306 307 ); 308 } else { 309 ok( 310 resourceLabel.control.checked, 311 `Visible checkbox for ${resourceLabel.dataset.resourceType} should be checked.` 312 ); 313 } 314 } 315 316 let selectedDataHeader = gShadowRoot.querySelector(".selected-data-header"); 317 let selectedData = gShadowRoot.querySelector(".selected-data"); 318 319 let bookmarks = gShadowRoot.querySelector("#bookmarks"); 320 let history = gShadowRoot.querySelector("#history"); 321 322 let selectedDataUpdated = BrowserTestUtils.waitForEvent( 323 gWiz, 324 "MigrationWizard:ResourcesUpdated" 325 ); 326 bookmarks.control.checked = true; 327 history.control.checked = true; 328 bookmarks.dispatchEvent(new CustomEvent("change")); 329 330 ok(bookmarks.control.checked, "Bookmarks should be checked"); 331 ok(history.control.checked, "History should be checked"); 332 333 await selectedDataUpdated; 334 335 is( 336 selectedData.textContent, 337 "Bookmarks and history", 338 "Testing if selected-data reflects the selected resources." 339 ); 340 341 is( 342 selectedDataHeader.dataset.l10nId, 343 "migration-all-available-data-label", 344 "Testing if selected-data-header reflects the selected resources" 345 ); 346 347 let importButton = gShadowRoot.querySelector("#import"); 348 349 ok( 350 !importButton.disabled, 351 "Testing if import button is enabled when at least one resource is selected." 352 ); 353 354 let importButtonUpdated = BrowserTestUtils.waitForEvent( 355 gWiz, 356 "MigrationWizard:ResourcesUpdated" 357 ); 358 359 selectAllCheckbox.checked = false; 360 selectAllCheckbox.dispatchEvent(new CustomEvent("change", { bubbles: true })); 361 await importButtonUpdated; 362 363 ok( 364 importButton.disabled, 365 "Testing if import button is disabled when no resources are selected." 366 ); 367 }); 368 369 /** 370 * Tests variant 2 of the migration wizard when there's a single resource 371 * item. 372 */ 373 add_task(async function test_selection_variant_2_single_item() { 374 let resourcesUpdated = BrowserTestUtils.waitForEvent( 375 gWiz, 376 "MigrationWizard:ResourcesUpdated" 377 ); 378 gWiz.setState({ 379 page: MigrationWizardConstants.PAGES.SELECTION, 380 migrators: [{ 381 key: "some-browser-0", 382 type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, 383 displayName: "Some Browser 0 with a single resource", 384 resourceTypes: ["HISTORY"], 385 profile: { id: "person-1", name: "Person 1" }, 386 hasPermissions: true, 387 }, { 388 key: "some-browser-1", 389 type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, 390 displayName: "Some Browser 1 with a two resources", 391 resourceTypes: ["HISTORY", "BOOKMARKS"], 392 profile: { id: "person-2", name: "Person 2" }, 393 hasPermissions: true, 394 }], 395 showImportAll: true, 396 }); 397 await resourcesUpdated; 398 399 let selectAll = gShadowRoot.querySelector("#select-all"); 400 let summary = gShadowRoot.querySelector("summary"); 401 let details = gShadowRoot.querySelector("details"); 402 ok(!details.open, "Details should be closed"); 403 details.open = true; 404 405 ok(isHidden(selectAll), "Selection for select-all should be hidden."); 406 ok(!isHidden(summary), "Summary should be shown."); 407 ok(!isHidden(details), "Details should be shown."); 408 409 resourcesUpdated = BrowserTestUtils.waitForEvent( 410 gWiz, 411 "MigrationWizard:ResourcesUpdated" 412 ); 413 let browser1Item = gShadowRoot.querySelector("panel-item[key='some-browser-1']"); 414 browser1Item.click(); 415 await resourcesUpdated; 416 417 ok(!isHidden(selectAll), "Selection for select-all should be shown."); 418 ok(!isHidden(summary), "Summary should be shown."); 419 ok(!isHidden(details), "Details should be shown."); 420 }); 421 422 /** 423 * Tests that the Select All checkbox is checked if all non-hidden resource 424 * types are checked, and unchecked otherwise. 425 */ 426 add_task(async function test_selection_variant_2_select_all() { 427 gWiz.setState({ 428 page: MigrationWizardConstants.PAGES.SELECTION, 429 migrators: MIGRATOR_PROFILE_INSTANCES, 430 showImportAll: true, 431 }); 432 433 let details = gShadowRoot.querySelector("details"); 434 ok(!details.open, "Details should be closed"); 435 details.open = true; 436 437 let selectAll = gShadowRoot.querySelector("#select-all"); 438 ok(selectAll.control.checked, "Select all should be checked by default"); 439 440 let bookmarksResourceLabel = gShadowRoot.querySelector( 441 "label[data-resource-type='BOOKMARKS']" 442 ); 443 ok(bookmarksResourceLabel.control.checked, "Bookmarks should be checked"); 444 445 bookmarksResourceLabel.control.click(); 446 ok(!bookmarksResourceLabel.control.checked, "Bookmarks should no longer be checked"); 447 ok(!selectAll.control.checked, "Select all should not longer be checked"); 448 449 bookmarksResourceLabel.control.click(); 450 ok(bookmarksResourceLabel.control.checked, "Bookmarks should be checked again"); 451 ok(selectAll.control.checked, "Select all should be checked"); 452 }); 453 454 /** 455 * Tests that the wizard can show partial progress during migration. 456 */ 457 add_task(async function test_partial_progress() { 458 const BOOKMARKS_SUCCESS_STRING = "Some bookmarks success string"; 459 gWiz.setState({ 460 page: MigrationWizardConstants.PAGES.PROGRESS, 461 key: "chrome", 462 progress: { 463 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { 464 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 465 message: BOOKMARKS_SUCCESS_STRING, 466 }, 467 // Don't include PASSWORDS to check that it's hidden. 468 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.HISTORY]: { 469 value: MigrationWizardConstants.PROGRESS_VALUE.LOADING, 470 }, 471 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS]: { 472 value: MigrationWizardConstants.PROGRESS_VALUE.LOADING, 473 }, 474 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.FORMDATA]: { 475 value: MigrationWizardConstants.PROGRESS_VALUE.LOADING, 476 }, 477 }, 478 }); 479 is( 480 gDeck.selectedViewName, 481 "page-progress", 482 "Should have the progress page selected" 483 ); 484 485 // Bookmarks 486 let bookmarksGroup = getResourceGroup( 487 MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS 488 ); 489 ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible"); 490 let progressIcon = bookmarksGroup.querySelector(".progress-icon"); 491 is( 492 progressIcon.getAttribute("state"), 493 "success", 494 "Progress should be completed" 495 ); 496 is( 497 bookmarksGroup.querySelector(".message-text").textContent, 498 BOOKMARKS_SUCCESS_STRING 499 ); 500 501 // Passwords 502 let passwordsGroup = getResourceGroup( 503 MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.PASSWORDS 504 ); 505 ok(isHidden(passwordsGroup), "Passwords group should be hidden"); 506 507 // History 508 let historyGroup = getResourceGroup( 509 MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.HISTORY 510 ); 511 ok(!isHidden(historyGroup), "History group should be visible"); 512 progressIcon = historyGroup.querySelector(".progress-icon"); 513 is( 514 progressIcon.getAttribute("state"), 515 "loading", 516 "Progress should be still be underway" 517 ); 518 is(historyGroup.querySelector(".message-text").textContent.trim(), ""); 519 520 // Extensions 521 let extensionsGroup = getResourceGroup(MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS); 522 ok(!isHidden(extensionsGroup), "Extensions group should be visible"); 523 progressIcon = extensionsGroup.querySelector(".progress-icon"); 524 is( 525 progressIcon.getAttribute("state"), 526 "loading", 527 "Progress should be still be underway" 528 ); 529 is(extensionsGroup.querySelector("a.message-text").textContent.trim(), ""); 530 is(extensionsGroup.querySelector("span.message-text").textContent.trim(), ""); 531 532 // Form Data 533 let formDataGroup = getResourceGroup( 534 MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.FORMDATA 535 ); 536 ok(!isHidden(formDataGroup), "Form data group should be visible"); 537 progressIcon = formDataGroup.querySelector(".progress-icon"); 538 is( 539 progressIcon.getAttribute("state"), 540 "loading", 541 "Progress should be still be underway" 542 ); 543 is(formDataGroup.querySelector(".message-text").textContent.trim(), ""); 544 545 // With progress still being underway, the header should be using the 546 // in progress string. 547 let header = gShadowRoot.querySelector("#progress-header"); 548 is( 549 header.getAttribute("data-l10n-id"), 550 "migration-wizard-progress-header", 551 "Should be showing in-progress header string" 552 ); 553 554 let progressPage = gShadowRoot.querySelector("div[name='page-progress']"); 555 let doneButton = progressPage.querySelector(".done-button"); 556 ok(isHidden(doneButton), "Done button should be hidden"); 557 let cancelButton = progressPage.querySelector(".cancel-close"); 558 ok(!isHidden(cancelButton), "Cancel button should be visible"); 559 ok(cancelButton.disabled, "Cancel button should be disabled"); 560 }); 561 562 /** 563 * Tests that the wizard can show completed migration progress. 564 */ 565 add_task(async function test_completed_progress() { 566 const BOOKMARKS_SUCCESS_STRING = "Some bookmarks success string"; 567 const PASSWORDS_SUCCESS_STRING = "Some passwords success string"; 568 const FORMDATA_SUCCESS_STRING = "Some formdata string"; 569 const EXTENSIONS_SUCCESS_STRING = "Some extensions string"; 570 const EXTENSIONS_SUCCESS_HREF = "about:addons"; 571 gWiz.setState({ 572 page: MigrationWizardConstants.PAGES.PROGRESS, 573 key: "chrome", 574 progress: { 575 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { 576 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 577 message: BOOKMARKS_SUCCESS_STRING, 578 }, 579 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.PASSWORDS]: { 580 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 581 message: PASSWORDS_SUCCESS_STRING, 582 }, 583 // Don't include HISTORY to check that it's hidden. 584 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS]: { 585 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 586 message: EXTENSIONS_SUCCESS_STRING, 587 }, 588 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.FORMDATA]: { 589 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 590 message: FORMDATA_SUCCESS_STRING, 591 }, 592 }, 593 }); 594 is( 595 gDeck.selectedViewName, 596 "page-progress", 597 "Should have the progress page selected" 598 ); 599 600 // Bookmarks 601 let bookmarksGroup = getResourceGroup( 602 MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS 603 ); 604 ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible"); 605 let progressIcon = bookmarksGroup.querySelector(".progress-icon"); 606 is( 607 progressIcon.getAttribute("state"), 608 "success", 609 "Progress should be completed" 610 ); 611 is( 612 bookmarksGroup.querySelector(".message-text").textContent, 613 BOOKMARKS_SUCCESS_STRING 614 ); 615 616 // Passwords 617 let passwordsGroup = getResourceGroup( 618 MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.PASSWORDS 619 ); 620 ok(!isHidden(passwordsGroup), "Passwords group should be visible"); 621 progressIcon = passwordsGroup.querySelector(".progress-icon"); 622 is( 623 progressIcon.getAttribute("state"), 624 "success", 625 "Progress should be completed" 626 ); 627 is( 628 passwordsGroup.querySelector(".message-text").textContent, 629 PASSWORDS_SUCCESS_STRING 630 ); 631 632 // History 633 let historyGroup = getResourceGroup( 634 MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.HISTORY 635 ); 636 ok(isHidden(historyGroup), "History group should be hidden"); 637 638 // Extensions 639 let extensionsDataGroup = getResourceGroup(MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS); 640 ok(!isHidden(extensionsDataGroup), "Extensions data group should be visible"); 641 progressIcon = extensionsDataGroup.querySelector(".progress-icon"); 642 is( 643 progressIcon.getAttribute("state"), 644 "success", 645 "Progress should be completed" 646 ); 647 is( 648 extensionsDataGroup.querySelector("a.message-text").textContent, 649 EXTENSIONS_SUCCESS_STRING 650 ); 651 is( 652 extensionsDataGroup.querySelector("a.message-text").href, 653 EXTENSIONS_SUCCESS_HREF 654 ) 655 // Form Data 656 let formDataGroup = getResourceGroup( 657 MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.FORMDATA 658 ); 659 ok(!isHidden(formDataGroup), "Form data group should be visible"); 660 progressIcon = formDataGroup.querySelector(".progress-icon"); 661 is( 662 progressIcon.getAttribute("state"), 663 "success", 664 "Progress should be completed" 665 ); 666 is( 667 formDataGroup.querySelector(".message-text").textContent, 668 FORMDATA_SUCCESS_STRING 669 ); 670 671 // With progress being complete, the header should be using the completed 672 // migration string. 673 let header = gShadowRoot.querySelector("#progress-header"); 674 is( 675 header.getAttribute("data-l10n-id"), 676 "migration-wizard-progress-done-header", 677 "Should be showing completed migration header string" 678 ); 679 680 let progressPage = gShadowRoot.querySelector("div[name='page-progress']"); 681 let doneButton = progressPage.querySelector(".done-button"); 682 ok(!isHidden(doneButton), "Done button should be visible and enabled"); 683 let cancelButton = progressPage.querySelector(".cancel-close"); 684 ok(isHidden(cancelButton), "Cancel button should be hidden"); 685 }); 686 687 add_task(async function test_extension_partial_success() { 688 const EXTENSIONS_INFO_STRING = "Extensions info string"; 689 const EXTENSIONS_INFO_HREF = "about:addons"; 690 const EXTENSIONS_SUPPORT_STRING = "extensions support string"; 691 const EXTENSIONS_SUPPORT_HREF = "about:blank"; 692 693 gWiz.setState({ 694 page: MigrationWizardConstants.PAGES.PROGRESS, 695 key: "chrome", 696 progress: { 697 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS]: { 698 value: MigrationWizardConstants.PROGRESS_VALUE.INFO, 699 message: EXTENSIONS_INFO_STRING, 700 linkText: EXTENSIONS_SUPPORT_STRING, 701 linkURL: EXTENSIONS_SUPPORT_HREF, 702 } 703 } 704 }); 705 is( 706 gDeck.selectedViewName, 707 "page-progress", 708 "Should have the progress page selected" 709 ); 710 711 let extensionsGroup = getResourceGroup(MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS); 712 ok(!isHidden(extensionsGroup), "Extensions group should be visible"); 713 let progressIcon = extensionsGroup.querySelector(".progress-icon"); 714 is( 715 progressIcon.getAttribute("state"), 716 "info", 717 "Progress should be completed, in info state" 718 ); 719 is( 720 extensionsGroup.querySelector("a.message-text").textContent, 721 EXTENSIONS_INFO_STRING 722 ); 723 is( 724 extensionsGroup.querySelector("a.message-text").href, 725 EXTENSIONS_INFO_HREF 726 ); 727 is( 728 extensionsGroup.querySelector("a.message-text").target, 729 "_blank" 730 ); 731 is( 732 extensionsGroup.querySelector(".support-text").textContent, 733 EXTENSIONS_SUPPORT_STRING 734 ); 735 is( 736 extensionsGroup.querySelector(".support-text").href, 737 EXTENSIONS_SUPPORT_HREF 738 ); 739 is( 740 extensionsGroup.querySelector(".support-text").target, 741 "_blank" 742 ); 743 744 // With progress being complete, the header should be using the completed 745 // migration string. 746 let header = gShadowRoot.querySelector("#progress-header"); 747 is( 748 header.getAttribute("data-l10n-id"), 749 "migration-wizard-progress-done-header", 750 "Should be showing completed migration header string" 751 ); 752 753 let progressPage = gShadowRoot.querySelector("div[name='page-progress']"); 754 let doneButton = progressPage.querySelector(".done-button"); 755 ok(!isHidden(doneButton), "Done button should be visible and enabled"); 756 let cancelButton = progressPage.querySelector(".cancel-close"); 757 ok(isHidden(cancelButton), "Cancel button should be hidden"); 758 }); 759 760 add_task(async function test_extension_error() { 761 const EXTENSIONS_ERROR_STRING = "Extensions error string"; 762 const EXTENSIONS_SUPPORT_STRING = "extensions support string"; 763 const EXTENSIONS_SUPPORT_HREF = "about:blank"; 764 765 gWiz.setState({ 766 page: MigrationWizardConstants.PAGES.PROGRESS, 767 key: "chrome", 768 progress: { 769 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS]: { 770 value: MigrationWizardConstants.PROGRESS_VALUE.WARNING, 771 message: EXTENSIONS_ERROR_STRING, 772 linkText: EXTENSIONS_SUPPORT_STRING, 773 linkURL: EXTENSIONS_SUPPORT_HREF, 774 } 775 } 776 }); 777 is( 778 gDeck.selectedViewName, 779 "page-progress", 780 "Should have the progress page selected" 781 ); 782 783 let extensionsGroup = getResourceGroup(MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS); 784 ok(!isHidden(extensionsGroup), "Extensions group should be visible"); 785 let progressIcon = extensionsGroup.querySelector(".progress-icon"); 786 is(progressIcon.getAttribute("state"), "warning"); 787 is( 788 extensionsGroup.querySelector("a.message-text").textContent, 789 "" 790 ); 791 is( 792 extensionsGroup.querySelector("span.message-text").textContent, 793 EXTENSIONS_ERROR_STRING 794 ); 795 is( 796 extensionsGroup.querySelector(".support-text").textContent, 797 EXTENSIONS_SUPPORT_STRING 798 ); 799 is( 800 extensionsGroup.querySelector(".support-text").href, 801 EXTENSIONS_SUPPORT_HREF 802 ); 803 is( 804 extensionsGroup.querySelector(".support-text").target, 805 "_blank" 806 ); 807 808 // With progress being complete, the header should be using the completed 809 // migration string. 810 let header = gShadowRoot.querySelector("#progress-header"); 811 is( 812 header.getAttribute("data-l10n-id"), 813 "migration-wizard-progress-done-with-warnings-header", 814 "Should be showing completed migration header string" 815 ); 816 817 let progressPage = gShadowRoot.querySelector("div[name='page-progress']"); 818 let doneButton = progressPage.querySelector(".done-button"); 819 ok(!isHidden(doneButton), "Done button should be visible and enabled"); 820 let cancelButton = progressPage.querySelector(".cancel-close"); 821 ok(isHidden(cancelButton), "Cancel button should be hidden"); 822 }); 823 824 /** 825 * Tests that the wizard can show partial progress during file migration. 826 */ 827 add_task(async function test_partial_file_progress() { 828 const PASSWORDS_SUCCESS_STRING = "Some passwords success string"; 829 const TITLE = "Partial progress"; 830 831 gWiz.setState({ 832 page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS, 833 title: "Partial progress", 834 progress: { 835 [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_FROM_FILE]: { 836 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 837 message: PASSWORDS_SUCCESS_STRING, 838 }, 839 [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: { 840 value: MigrationWizardConstants.PROGRESS_VALUE.LOADING, 841 }, 842 }, 843 }); 844 845 is( 846 gDeck.selectedViewName, 847 "page-file-import-progress", 848 "Should have the file progress page selected" 849 ); 850 851 let header = gShadowRoot.querySelector("#file-import-progress-header"); 852 is(header.textContent, TITLE, "Title is set correctly."); 853 854 let passwordsFromFileGroup = getResourceGroup( 855 MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_FROM_FILE 856 ); 857 ok(!isHidden(passwordsFromFileGroup), "Passwords from file group should be visible"); 858 let progressIcon = passwordsFromFileGroup.querySelector(".progress-icon"); 859 is( 860 progressIcon.getAttribute("state"), 861 "success", 862 "Progress should be completed" 863 ); 864 is( 865 passwordsFromFileGroup.querySelector(".message-text").textContent, 866 PASSWORDS_SUCCESS_STRING 867 ); 868 869 let passwordsUpdatedGroup = getResourceGroup( 870 MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED 871 ); 872 ok(isHidden(passwordsUpdatedGroup), "Passwords updated group should be hidden"); 873 874 let passwordsNewGroup = getResourceGroup( 875 MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW 876 ); 877 ok(!isHidden(passwordsNewGroup), "Passwords new group should be visible"); 878 progressIcon = passwordsNewGroup.querySelector(".progress-icon"); 879 is( 880 progressIcon.getAttribute("state"), 881 "loading", 882 "Progress should be still be underway" 883 ); 884 is(passwordsNewGroup.querySelector(".message-text").textContent.trim(), ""); 885 886 let progressPage = gShadowRoot.querySelector("div[name='page-file-import-progress']"); 887 let doneButton = progressPage.querySelector(".done-button"); 888 ok(isHidden(doneButton), "Done button should be hidden"); 889 let cancelButton = progressPage.querySelector(".cancel-close"); 890 ok(!isHidden(cancelButton), "Cancel button should be visible"); 891 ok(cancelButton.disabled, "Cancel button should be disabled"); 892 }); 893 894 /** 895 * Tests that the wizard can show completed migration progress. 896 */ 897 add_task(async function test_completed_file_progress() { 898 const PASSWORDS_NEW_SUCCESS_STRING = "2 added"; 899 const PASSWORDS_UPDATED_SUCCESS_STRING = "5 updated"; 900 const TITLE = "Done doing file import"; 901 902 gWiz.setState({ 903 page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS, 904 title: TITLE, 905 progress: { 906 [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: { 907 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 908 message: PASSWORDS_NEW_SUCCESS_STRING, 909 }, 910 [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED]: { 911 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 912 message: PASSWORDS_UPDATED_SUCCESS_STRING, 913 }, 914 }, 915 }); 916 is( 917 gDeck.selectedViewName, 918 "page-file-import-progress", 919 "Should have the file progress page selected" 920 ); 921 922 let header = gShadowRoot.querySelector("#file-import-progress-header"); 923 is(header.textContent, TITLE, "Title is set correctly."); 924 925 let passwordsNewGroup = getResourceGroup( 926 MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW 927 ); 928 ok(!isHidden(passwordsNewGroup), "Passwords new group should be visible"); 929 let progressIcon = passwordsNewGroup.querySelector(".progress-icon"); 930 is( 931 progressIcon.getAttribute("state"), 932 "success", 933 "Progress should be completed" 934 ); 935 is( 936 passwordsNewGroup.querySelector(".message-text").textContent, 937 PASSWORDS_NEW_SUCCESS_STRING 938 ); 939 940 let passwordsUpdatedGroup = getResourceGroup( 941 MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED 942 ); 943 ok(!isHidden(passwordsUpdatedGroup), "Passwords updated group should be visible"); 944 progressIcon = passwordsUpdatedGroup.querySelector(".progress-icon"); 945 is( 946 progressIcon.getAttribute("state"), 947 "success", 948 "Progress should be completed" 949 ); 950 is( 951 passwordsUpdatedGroup.querySelector(".message-text").textContent, 952 PASSWORDS_UPDATED_SUCCESS_STRING 953 ); 954 955 let passwordsFromFileGroup = getResourceGroup( 956 MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_FROM_FILE 957 ); 958 ok(isHidden(passwordsFromFileGroup), "Passwords from file group should be hidden"); 959 960 let progressPage = gShadowRoot.querySelector("div[name='page-file-import-progress']"); 961 let doneButton = progressPage.querySelector(".done-button"); 962 ok(!isHidden(doneButton), "Done button should be visible and enabled"); 963 let cancelButton = progressPage.querySelector(".cancel-close"); 964 ok(isHidden(cancelButton), "Cancel button should be hidden"); 965 }); 966 967 /** 968 * Tests that the buttons that dismiss the wizard when embedded in 969 * a dialog are only visible when in dialog mode, and dispatch a 970 * MigrationWizard:Close event when clicked. 971 */ 972 add_task(async function test_dialog_mode_close() { 973 gWiz.toggleAttribute("dialog-mode", true); 974 gWiz.setState({ 975 page: MigrationWizardConstants.PAGES.SELECTION, 976 migrators: MIGRATOR_PROFILE_INSTANCES, 977 }); 978 979 // For now, there's only a single .cancel-close button, so let's just test 980 // that one. Let's make this test fail if there are multiple so that we can 981 // then update this test to switch to the right pages to test those buttons 982 // too. 983 let buttons = gShadowRoot.querySelectorAll(".cancel-close:not([disabled])"); 984 ok( 985 buttons.length, 986 "This test expects at least one enabled .cancel-close button" 987 ); 988 let button = buttons[0]; 989 ok( 990 !isHidden(button), 991 ".cancel-close button should be visible in dialog mode." 992 ); 993 let closeEvent = BrowserTestUtils.waitForEvent(gWiz, "MigrationWizard:Close"); 994 button.click(); 995 await closeEvent; 996 997 gWiz.toggleAttribute("dialog-mode", false); 998 ok( 999 isHidden(button), 1000 ".cancel-close button should be hidden when not in dialog mode." 1001 ); 1002 }); 1003 1004 /** 1005 * Internet Explorer and Edge refer to bookmarks as "favorites", 1006 * and we change our labels to suit when either of those browsers are 1007 * selected as the migration source. This test tests that behavior in the 1008 * selection page. 1009 */ 1010 add_task(async function test_ie_edge_favorites_selection() { 1011 gWiz.setState({ 1012 page: MigrationWizardConstants.PAGES.SELECTION, 1013 migrators: MIGRATOR_PROFILE_INSTANCES, 1014 showImportAll: false, 1015 }); 1016 1017 let bookmarksCheckboxLabel = gShadowRoot.querySelector("#bookmarks"); 1018 let span = bookmarksCheckboxLabel.querySelector("span[default-data-l10n-id]"); 1019 ok(span, "The bookmarks selection span has a default-data-l10n-id attribute"); 1020 is( 1021 span.getAttribute("data-l10n-id"), 1022 span.getAttribute("default-data-l10n-id"), 1023 "Should be showing the default string for bookmarks" 1024 ); 1025 1026 // Now test when in Variant 2, for the string in the <summary>. 1027 let selectedDataUpdated = BrowserTestUtils.waitForEvent( 1028 gWiz, 1029 "MigrationWizard:ResourcesUpdated" 1030 ); 1031 1032 gWiz.setState({ 1033 page: MigrationWizardConstants.PAGES.SELECTION, 1034 migrators: MIGRATOR_PROFILE_INSTANCES, 1035 showImportAll: true, 1036 }); 1037 1038 await selectedDataUpdated; 1039 1040 let summary = gShadowRoot.querySelector("summary"); 1041 ok( 1042 summary.textContent.toLowerCase().includes("bookmarks"), 1043 "Summary should include the string 'bookmarks'" 1044 ); 1045 1046 for (let key of MigrationWizardConstants.USES_FAVORITES) { 1047 gWiz.setState({ 1048 page: MigrationWizardConstants.PAGES.SELECTION, 1049 migrators: [{ 1050 key, 1051 displayName: "Legacy Microsoft Browser", 1052 resourceTypes: ["BOOKMARKS"], 1053 profile: null, 1054 hasPermissions: true, 1055 }], 1056 showImportAll: false, 1057 }); 1058 1059 is( 1060 span.getAttribute("data-l10n-id"), 1061 span.getAttribute("ie-edge-data-l10n-id"), 1062 "Should be showing the IE/Edge string for bookmarks" 1063 ); 1064 1065 // Now test when in Variant 2, for the string in the <summary>. 1066 selectedDataUpdated = BrowserTestUtils.waitForEvent( 1067 gWiz, 1068 "MigrationWizard:ResourcesUpdated" 1069 ); 1070 1071 gWiz.setState({ 1072 page: MigrationWizardConstants.PAGES.SELECTION, 1073 migrators: [{ 1074 key, 1075 displayName: "Legacy Microsoft Browser", 1076 resourceTypes: ["BOOKMARKS"], 1077 profile: null, 1078 hasPermissions: true, 1079 }], 1080 showImportAll: true, 1081 }); 1082 1083 await selectedDataUpdated; 1084 1085 ok( 1086 summary.textContent.toLowerCase().includes("favorites"), 1087 "Summary should include the string 'favorites'" 1088 ); 1089 } 1090 }); 1091 1092 /** 1093 * Internet Explorer and Edge refer to bookmarks as "favorites", 1094 * and we change our labels to suit when either of those browsers are 1095 * selected as the migration source. This test tests that behavior in the 1096 * progress page 1097 */ 1098 add_task(async function test_ie_edge_favorites_progress() { 1099 gWiz.setState({ 1100 page: MigrationWizardConstants.PAGES.PROGRESS, 1101 key: "chrome", 1102 progress: { 1103 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { 1104 inProgress: false, 1105 message: "A string from the parent", 1106 }, 1107 }, 1108 }); 1109 1110 let bookmarksGroup = getResourceGroup( 1111 MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS 1112 ); 1113 let span = bookmarksGroup.querySelector("span[default-data-l10n-id]"); 1114 ok(span, "Should have found a span with default-data-l10n-id"); 1115 is( 1116 span.getAttribute("data-l10n-id"), 1117 span.getAttribute("default-data-l10n-id"), 1118 "Should be using the default string." 1119 ); 1120 1121 1122 for (let key of MigrationWizardConstants.USES_FAVORITES) { 1123 gWiz.setState({ 1124 page: MigrationWizardConstants.PAGES.PROGRESS, 1125 key, 1126 progress: { 1127 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { 1128 inProgress: false, 1129 message: "A string from the parent", 1130 }, 1131 }, 1132 }); 1133 1134 is( 1135 span.getAttribute("data-l10n-id"), 1136 span.getAttribute("ie-edge-data-l10n-id"), 1137 "Should be showing the IE/Edge string for bookmarks" 1138 ); 1139 } 1140 }); 1141 1142 /** 1143 * Tests that the button shown in either the browser migration success or 1144 * file migration success pages is a "continue" button rather than a 1145 * "done" button. 1146 */ 1147 add_task(async function test_embedded_continue_button() { 1148 gWiz.toggleAttribute("dialog-mode", false); 1149 gWiz.setState({ 1150 page: MigrationWizardConstants.PAGES.PROGRESS, 1151 key: "chrome", 1152 progress: { 1153 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { 1154 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 1155 message: "A string from the parent", 1156 }, 1157 }, 1158 }); 1159 1160 let progressPage = gShadowRoot.querySelector("div[name='page-progress']"); 1161 let cancelButton = progressPage.querySelector(".cancel-close"); 1162 ok(isHidden(cancelButton), "Cancel button should be hidden"); 1163 let doneButton = progressPage.querySelector(".done-button"); 1164 ok(isHidden(doneButton), "Done button should be hidden when embedding"); 1165 let continueButton = progressPage.querySelector(".continue-button"); 1166 ok(!isHidden(continueButton), "Continue button should be displayed"); 1167 1168 let content = document.getElementById("content"); 1169 1170 let promise = new Promise(resolve => { 1171 content.addEventListener("MigrationWizard:Close", resolve, { 1172 once: true, 1173 }); 1174 }); 1175 continueButton.click(); 1176 await promise; 1177 ok( 1178 true, 1179 "Clicking on the Continue button sent the MigrationWizard:Close event." 1180 ); 1181 1182 gWiz.setState({ 1183 page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS, 1184 title: "Done importing file data", 1185 progress: { 1186 [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: { 1187 inProgress: false, 1188 message: "Some message", 1189 }, 1190 [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED]: { 1191 inProgress: false, 1192 message: "Some other", 1193 }, 1194 }, 1195 }); 1196 1197 progressPage = gShadowRoot.querySelector("div[name='page-file-import-progress']"); 1198 cancelButton = progressPage.querySelector(".cancel-close"); 1199 ok(isHidden(cancelButton), "Cancel button should be hidden"); 1200 doneButton = progressPage.querySelector(".done-button"); 1201 ok(isHidden(doneButton), "Done button should be hidden when embedding"); 1202 continueButton = progressPage.querySelector(".continue-button"); 1203 ok(!isHidden(continueButton), "Continue button should be displayed"); 1204 1205 promise = new Promise(resolve => { 1206 content.addEventListener("MigrationWizard:Close", resolve, { 1207 once: true, 1208 }); 1209 }); 1210 continueButton.click(); 1211 await promise; 1212 ok( 1213 true, 1214 "Clicking on the Continue button sent the MigrationWizard:Close event." 1215 ); 1216 1217 gWiz.toggleAttribute("dialog-mode", true); 1218 }); 1219 1220 /** 1221 * Tests that if a progress update comes down which puts a resource from 1222 * being done to loading, that the status message is cleared. 1223 */ 1224 add_task(async function test_clear_status_message_when_in_progress() { 1225 const STRING_TO_CLEAR = "This string should get cleared"; 1226 gWiz.toggleAttribute("dialog-mode", false); 1227 gWiz.setState({ 1228 page: MigrationWizardConstants.PAGES.PROGRESS, 1229 key: "chrome", 1230 progress: { 1231 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { 1232 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 1233 message: STRING_TO_CLEAR, 1234 }, 1235 }, 1236 }); 1237 1238 let bookmarksGroup = getResourceGroup( 1239 MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS 1240 ); 1241 ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible"); 1242 let progressIcon = bookmarksGroup.querySelector(".progress-icon"); 1243 is( 1244 progressIcon.getAttribute("state"), 1245 "success", 1246 "Progress should be completed" 1247 ); 1248 is( 1249 bookmarksGroup.querySelector(".message-text").textContent, 1250 STRING_TO_CLEAR 1251 ); 1252 1253 gWiz.setState({ 1254 page: MigrationWizardConstants.PAGES.PROGRESS, 1255 key: "chrome", 1256 progress: { 1257 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.BOOKMARKS]: { 1258 value: MigrationWizardConstants.PROGRESS_VALUE.LOADING, 1259 message: "", 1260 }, 1261 }, 1262 }); 1263 1264 ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible"); 1265 is( 1266 progressIcon.getAttribute("state"), 1267 "loading", 1268 "Progress should be still be underway" 1269 ); 1270 is( 1271 bookmarksGroup.querySelector(".message-text").textContent.trim(), 1272 "" 1273 ); 1274 }); 1275 1276 /** 1277 * Tests that if a file progress update comes down which puts a resource 1278 * from being done to loading, that the status message is cleared. 1279 * 1280 * This is extremely similar to the above test, except that it's for progress 1281 * updates for file resources. 1282 */ 1283 add_task(async function test_clear_status_message_when_in_file_progress() { 1284 const STRING_TO_CLEAR = "This string should get cleared"; 1285 gWiz.toggleAttribute("dialog-mode", false); 1286 gWiz.setState({ 1287 page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS, 1288 key: "chrome", 1289 progress: { 1290 [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: { 1291 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 1292 message: STRING_TO_CLEAR, 1293 }, 1294 }, 1295 }); 1296 1297 let passwordsGroup = getResourceGroup( 1298 MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW 1299 ); 1300 ok(!isHidden(passwordsGroup), "Passwords group should be visible"); 1301 let progressIcon = passwordsGroup.querySelector(".progress-icon"); 1302 is( 1303 progressIcon.getAttribute("state"), 1304 "success", 1305 "Progress should be completed" 1306 ); 1307 is( 1308 passwordsGroup.querySelector(".message-text").textContent, 1309 STRING_TO_CLEAR 1310 ); 1311 1312 gWiz.setState({ 1313 page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS, 1314 key: "chrome", 1315 progress: { 1316 [MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: { 1317 value: MigrationWizardConstants.PROGRESS_VALUE.LOADING, 1318 message: "", 1319 }, 1320 }, 1321 }); 1322 1323 ok(!isHidden(passwordsGroup), "Passwords group should be visible"); 1324 is( 1325 progressIcon.getAttribute("state"), 1326 "loading", 1327 "Progress should be still be underway" 1328 ); 1329 is( 1330 passwordsGroup.querySelector(".message-text").textContent.trim(), 1331 "" 1332 ); 1333 }); 1334 1335 /** 1336 * Tests that the migration wizard can be put into the selection page after 1337 * a file migrator error and show an error message. 1338 */ 1339 add_task(async function test_file_migrator_error() { 1340 const FILE_MIGRATOR_KEY = "some-file-migrator"; 1341 const FILE_IMPORT_ERROR_MESSAGE = "This is an error message"; 1342 const MIGRATORS = [ 1343 { 1344 key: "some-browser-0", 1345 type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, 1346 displayName: "Some Browser 0", 1347 resourceTypes: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS"], 1348 profile: { id: "person-2", name: "Person 2" }, 1349 hasPermissions: true, 1350 }, 1351 { 1352 key: "some-browser-1", 1353 type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, 1354 displayName: "Some Browser 1", 1355 resourceTypes: ["HISTORY", "BOOKMARKS"], 1356 profile: null, 1357 hasPermissions: true, 1358 }, 1359 { 1360 key: FILE_MIGRATOR_KEY, 1361 type: MigrationWizardConstants.MIGRATOR_TYPES.FILE, 1362 displayName: "Some File Migrator", 1363 resourceTypes: [], 1364 }, 1365 ]; 1366 1367 gWiz.setState({ 1368 page: MigrationWizardConstants.PAGES.SELECTION, 1369 migrators: MIGRATORS, 1370 showImportAll: true, 1371 migratorKey: "some-file-migrator", 1372 fileImportErrorMessage: FILE_IMPORT_ERROR_MESSAGE, 1373 }); 1374 1375 let errorMessageContainer = gShadowRoot.querySelector(".file-import-error"); 1376 ok(!isHidden(errorMessageContainer), "Error message should be shown."); 1377 let errorText = gShadowRoot.querySelector("#file-import-error-message").textContent; 1378 is(errorText, FILE_IMPORT_ERROR_MESSAGE); 1379 1380 gWiz.setState({ 1381 page: MigrationWizardConstants.PAGES.SELECTION, 1382 migrators: MIGRATORS, 1383 showImportAll: true, 1384 }); 1385 1386 ok(isHidden(errorMessageContainer), "Error message should be hidden."); 1387 errorText = gShadowRoot.querySelector("#file-import-error-message").textContent; 1388 is(errorText, ""); 1389 }); 1390 1391 /** 1392 * Tests that the variant of the wizard can be forced via 1393 * attributes on the migration-wizard element. 1394 */ 1395 add_task(async function force_show_import_all() { 1396 gWiz.setState({ 1397 page: MigrationWizardConstants.PAGES.SELECTION, 1398 migrators: MIGRATOR_PROFILE_INSTANCES, 1399 showImportAll: true, 1400 }); 1401 1402 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1403 let details = gShadowRoot.querySelector("details"); 1404 ok( 1405 selectionPage.hasAttribute("show-import-all"), 1406 "Should be paying attention to showImportAll=true on state object" 1407 ); 1408 ok(!details.open, "Details collapsed by default"); 1409 1410 gWiz.setState({ 1411 page: MigrationWizardConstants.PAGES.SELECTION, 1412 migrators: MIGRATOR_PROFILE_INSTANCES, 1413 showImportAll: false, 1414 }); 1415 1416 ok( 1417 !selectionPage.hasAttribute("show-import-all"), 1418 "Should be paying attention to showImportAll=false on state object" 1419 ); 1420 ok(details.open, "Details expanded by default"); 1421 1422 gWiz.setAttribute("force-show-import-all", "false"); 1423 gWiz.setState({ 1424 page: MigrationWizardConstants.PAGES.SELECTION, 1425 migrators: MIGRATOR_PROFILE_INSTANCES, 1426 showImportAll: true, 1427 }); 1428 ok( 1429 !selectionPage.hasAttribute("show-import-all"), 1430 "Should be paying attention to force-show-import-all=false on DOM node" 1431 ); 1432 ok(details.open, "Details expanded by default"); 1433 1434 gWiz.setAttribute("force-show-import-all", "true"); 1435 gWiz.setState({ 1436 page: MigrationWizardConstants.PAGES.SELECTION, 1437 migrators: MIGRATOR_PROFILE_INSTANCES, 1438 showImportAll: false, 1439 }); 1440 ok( 1441 selectionPage.hasAttribute("show-import-all"), 1442 "Should be paying attention to force-show-import-all=true on DOM node" 1443 ); 1444 ok(!details.open, "Details collapsed by default"); 1445 1446 gWiz.removeAttribute("force-show-import-all"); 1447 }); 1448 1449 /** 1450 * Tests that for non-Safari migrators without permissions, we show 1451 * the appropriate message and the button for getting permissions. 1452 */ 1453 add_task(async function no_permissions() { 1454 const SOME_FAKE_PERMISSION_PATH = "/some/fake/path"; 1455 1456 gWiz.setState({ 1457 page: MigrationWizardConstants.PAGES.SELECTION, 1458 migrators: [{ 1459 key: "some-browser-0", 1460 type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, 1461 displayName: "Some Browser 0 with no permissions", 1462 resourceTypes: [], 1463 profile: null, 1464 hasPermissions: false, 1465 permissionsPath: SOME_FAKE_PERMISSION_PATH, 1466 }], 1467 showImportAll: false, 1468 }); 1469 1470 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1471 ok(selectionPage.hasAttribute("no-permissions"), "no-permissions attribute set."); 1472 1473 let resourceList = gShadowRoot.querySelector(".resource-selection-details"); 1474 ok(isHidden(resourceList), "Resources list is hidden."); 1475 1476 let importButton = gShadowRoot.querySelector("#import"); 1477 ok(isHidden(importButton), "Import button hidden."); 1478 let noPermissionsMessage = gShadowRoot.querySelector(".no-permissions-message"); 1479 ok(!isHidden(noPermissionsMessage), "No permissions message shown."); 1480 let getPermissionButton = gShadowRoot.querySelector("#get-permissions"); 1481 ok(!isHidden(getPermissionButton), "Get permissions button shown."); 1482 1483 let step2 = gShadowRoot.querySelector(".migration-no-permissions-instructions-step2"); 1484 ok(step2.hasAttribute("data-l10n-args")); 1485 is(JSON.parse(step2.getAttribute("data-l10n-args")).permissionsPath, SOME_FAKE_PERMISSION_PATH); 1486 1487 gWiz.setState({ 1488 page: MigrationWizardConstants.PAGES.SELECTION, 1489 migrators: MIGRATOR_PROFILE_INSTANCES, 1490 showImportAll: false, 1491 }); 1492 1493 ok(!selectionPage.hasAttribute("no-permissions"), "no-permissions attribute set to false."); 1494 ok(!isHidden(resourceList), "Resources list is shown."); 1495 ok(!isHidden(importButton), "Import button is shown."); 1496 ok(isHidden(noPermissionsMessage), "No permissions message hidden."); 1497 ok(isHidden(getPermissionButton), "Get permissions button hidden."); 1498 }); 1499 1500 /** 1501 * Tests that for the Safari migrator without permissions, we show the 1502 * normal resources list and impor tbutton instead of the no permissions 1503 * message. Safari has a special flow where permissions are requested 1504 * only after resource selection has occurred. 1505 */ 1506 add_task(async function no_permissions_safari() { 1507 const SOME_FAKE_PERMISSION_PATH = "/some/fake/safari/path"; 1508 1509 gWiz.setState({ 1510 page: MigrationWizardConstants.PAGES.SELECTION, 1511 migrators: [{ 1512 key: "safari", 1513 type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER, 1514 displayName: "Safari with no permissions", 1515 resourceTypes: ["HISTORY", "BOOKMARKS"], 1516 profile: null, 1517 hasPermissions: false, 1518 permissionsPath: SOME_FAKE_PERMISSION_PATH, 1519 }], 1520 showImportAll: false, 1521 }); 1522 1523 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1524 ok(!selectionPage.hasAttribute("no-permissions"), "no-permissions attribute not set."); 1525 1526 let resourceList = gShadowRoot.querySelector(".resource-selection-details"); 1527 ok(!isHidden(resourceList), "Resources list is shown."); 1528 1529 let importButton = gShadowRoot.querySelector("#import"); 1530 ok(!isHidden(importButton), "Import button shown."); 1531 let noPermissionsMessage = gShadowRoot.querySelector(".no-permissions-message"); 1532 ok(isHidden(noPermissionsMessage), "No permissions message hidden."); 1533 let getPermissionButton = gShadowRoot.querySelector("#get-permissions"); 1534 ok(isHidden(getPermissionButton), "Get permissions button hiddne."); 1535 }); 1536 1537 add_task(async function hide_option_expander_subtitle() { 1538 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1539 gWiz.setAttribute("hide-option-expander-subtitle", "true"); 1540 let subtitle = selectionPage.querySelector("#resource-selection-summary > .selected-data"); 1541 1542 gWiz.setState({ 1543 page: MigrationWizardConstants.PAGES.SELECTION, 1544 migrators: MIGRATOR_PROFILE_INSTANCES, 1545 }); 1546 1547 ok(gWiz.hasAttribute("hide-option-expander-subtitle"), "hide option expander subtitle attribute is present on migration wizard"); 1548 1549 ok(isHidden(subtitle), "subtitle is hidden"); 1550 1551 gWiz.removeAttribute("hide-option-expander-subtitle"); 1552 }); 1553 1554 add_task(async function update_option_expander_title_string() { 1555 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1556 1557 let title = selectionPage.querySelector(".selected-data-header"); 1558 gWiz.setAttribute("option-expander-title-string", "test"); 1559 gWiz.setState({ 1560 page: MigrationWizardConstants.PAGES.SELECTION, 1561 migrators: MIGRATOR_PROFILE_INSTANCES, 1562 }); 1563 1564 await BrowserTestUtils.waitForMutationCondition( 1565 title, 1566 {childList: true}, 1567 () => title.textContent == "test" 1568 ) 1569 is(title.textContent, "test", "resource selection expander subtitle has been changed"); 1570 1571 gWiz.removeAttribute("option-expander-title-string"); 1572 gWiz.setState({ 1573 page: MigrationWizardConstants.PAGES.SELECTION, 1574 migrators: MIGRATOR_PROFILE_INSTANCES, 1575 }); 1576 1577 await BrowserTestUtils.waitForMutationCondition( 1578 title, 1579 {childList: true}, 1580 () => title.textContent != "test" 1581 ) 1582 isnot(title.textContent, "test", "resource selection expander subtitle was reverted"); 1583 }); 1584 1585 add_task(async function hide_select_all_checkbox() { 1586 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1587 1588 let selectAll = selectionPage.querySelector("#select-all"); 1589 gWiz.setAttribute("hide-select-all", true); 1590 gWiz.setState({ 1591 page: MigrationWizardConstants.PAGES.SELECTION, 1592 migrators: MIGRATOR_PROFILE_INSTANCES, 1593 }); 1594 1595 ok(isHidden(selectAll), "select all is not displayed"); 1596 1597 gWiz.removeAttribute("hide-select-all"); 1598 }); 1599 1600 add_task(async function update_import_button_string() { 1601 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1602 gWiz.setAttribute("import-button-string", "test"); 1603 let button = selectionPage.querySelector(".migration-import-button"); 1604 1605 gWiz.setState({ 1606 page: MigrationWizardConstants.PAGES.SELECTION, 1607 migrators: MIGRATOR_PROFILE_INSTANCES, 1608 }); 1609 1610 is(button.textContent, "test", "button text is expected"); 1611 1612 gWiz.removeAttribute("import-button-string"); 1613 }); 1614 1615 add_task(async function update_checkbox_margins() { 1616 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1617 1618 gWiz.setAttribute("checkbox-margin-inline", "27px 42px"); 1619 gWiz.setAttribute("checkbox-margin-block", "42px 27px"); 1620 1621 gWiz.setState({ 1622 page: MigrationWizardConstants.PAGES.SELECTION, 1623 migrators: MIGRATOR_PROFILE_INSTANCES, 1624 }); 1625 1626 let checkboxLabels = selectionPage.querySelectorAll(".resource-type-label"); 1627 for(let label of checkboxLabels) { 1628 let computedStyle = getComputedStyle(label); 1629 let marginInline = computedStyle.getPropertyValue("margin-inline"); 1630 let marginBlock = computedStyle.getPropertyValue("margin-block"); 1631 is(marginInline, "27px 42px", "margin inline is set to expected value"); 1632 is(marginBlock, "42px 27px", "margin block is set to expected value"); 1633 } 1634 1635 gWiz.removeAttribute("checkbox-margin-inline"); 1636 gWiz.removeAttribute("checkbox-margin-block"); 1637 }); 1638 1639 add_task(async function update_import_button_class() { 1640 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1641 let importButton = selectionPage.querySelector("#import"); 1642 1643 gWiz.setAttribute("import-button-class", "primary"); 1644 1645 gWiz.setState({ 1646 page: MigrationWizardConstants.PAGES.SELECTION, 1647 migrators: MIGRATOR_PROFILE_INSTANCES, 1648 }); 1649 1650 ok(importButton.classList.contains("primary"), "import button has the primary class"); 1651 1652 gWiz.removeAttribute("import-button-class"); 1653 }); 1654 1655 add_task(async function update_header_font_size() { 1656 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1657 let header = selectionPage.querySelector("h1"); 1658 1659 gWiz.setAttribute("header-font-size", "24px"); 1660 1661 gWiz.setState({ 1662 page: MigrationWizardConstants.PAGES.SELECTION, 1663 migrators: MIGRATOR_PROFILE_INSTANCES, 1664 }); 1665 let computedStyle = getComputedStyle(header); 1666 1667 is(computedStyle.getPropertyValue("font-size"), "24px", "header font size is changed to correct value"); 1668 gWiz.removeAttribute("header-font-size"); 1669 }); 1670 1671 add_task(async function update_header_margin_block() { 1672 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1673 let header = selectionPage.querySelector("h1"); 1674 1675 gWiz.setAttribute("header-margin-block", "20px 30px"); 1676 1677 gWiz.setState({ 1678 page: MigrationWizardConstants.PAGES.SELECTION, 1679 migrators: MIGRATOR_PROFILE_INSTANCES, 1680 }); 1681 let computedStyle = getComputedStyle(header); 1682 1683 is(computedStyle.getPropertyValue("margin-block"), "20px 30px", "header margin block is changed to correct value"); 1684 gWiz.removeAttribute("header-margin-block"); 1685 }); 1686 1687 add_task(async function update_header_string() { 1688 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1689 let header = selectionPage.querySelector("h1"); 1690 1691 gWiz.setAttribute("selection-header-string", "test string"); 1692 1693 gWiz.setState({ 1694 page: MigrationWizardConstants.PAGES.SELECTION, 1695 migrators: MIGRATOR_PROFILE_INSTANCES, 1696 }); 1697 1698 is(header.textContent, "test string", "header text content is changed to correct value"); 1699 gWiz.removeAttribute("selection-header-string"); 1700 }); 1701 1702 add_task(async function update_subheader_font_size() { 1703 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1704 let subheader = selectionPage.querySelector("h1"); 1705 1706 gWiz.setAttribute("subheader-font-size", "24px"); 1707 1708 gWiz.setState({ 1709 page: MigrationWizardConstants.PAGES.SELECTION, 1710 migrators: MIGRATOR_PROFILE_INSTANCES, 1711 }); 1712 let computedStyle = getComputedStyle(subheader); 1713 1714 is(computedStyle.getPropertyValue("font-size"), "24px", "subheader font size is changed to correct value"); 1715 gWiz.removeAttribute("subheader-font-size"); 1716 }); 1717 1718 add_task(async function update_subheader_margin_block() { 1719 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1720 let subheader = selectionPage.querySelector("h1"); 1721 1722 gWiz.setAttribute("subheader-margin-block", "20px 30px"); 1723 1724 gWiz.setState({ 1725 page: MigrationWizardConstants.PAGES.SELECTION, 1726 migrators: MIGRATOR_PROFILE_INSTANCES, 1727 }); 1728 let computedStyle = getComputedStyle(subheader); 1729 1730 is(computedStyle.getPropertyValue("margin-block"), "20px 30px", "subheader margin block is changed to correct value"); 1731 gWiz.removeAttribute("subheader-margin-block"); 1732 }); 1733 1734 add_task(async function update_subheader_string() { 1735 let selectionPage = gShadowRoot.querySelector("div[name='page-selection']"); 1736 let subheader = selectionPage.querySelector(".migration-wizard-subheader"); 1737 1738 gWiz.setAttribute("selection-subheader-string", "test string"); 1739 1740 gWiz.setState({ 1741 page: MigrationWizardConstants.PAGES.SELECTION, 1742 migrators: MIGRATOR_PROFILE_INSTANCES, 1743 }); 1744 1745 is(subheader.textContent, "test string", "subheader text content is changed to correct value"); 1746 1747 gWiz.removeAttribute("selection-subheader-string"); 1748 gWiz.setState({ 1749 page: MigrationWizardConstants.PAGES.SELECTION, 1750 migrators: MIGRATOR_PROFILE_INSTANCES, 1751 }); 1752 1753 ok(isHidden(subheader), "subheader is hidden") 1754 }); 1755 1756 add_task(async function update_data_import_success_string() { 1757 let progressPage = gShadowRoot.querySelector("div[name='page-progress']"); 1758 let header = progressPage.querySelector("h1"); 1759 1760 gWiz.setAttribute("data-import-complete-success-string", "test string"); 1761 1762 gWiz.setState({ 1763 page: MigrationWizardConstants.PAGES.PROGRESS, 1764 key: "chrome", 1765 progress: { 1766 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS]: { 1767 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 1768 }, 1769 [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.FORMDATA]: { 1770 value: MigrationWizardConstants.PROGRESS_VALUE.SUCCESS, 1771 }, 1772 }, 1773 }); 1774 1775 is(header.textContent, "test string", "import success header text content is changed to correct value"); 1776 gWiz.removeAttribute("data-import-complete-success-string"); 1777 }); 1778 </script> 1779 </head> 1780 <body> 1781 <p id="display"></p> 1782 <div id="content"> 1783 <migration-wizard id="test-wizard" dialog-mode=""></migration-wizard> 1784 </div> 1785 <pre id="test"></pre> 1786 </body> 1787 </html>