chromium/chrome/test/data/webui/chromeos/settings/os_printing_page/cups_printer_landing_page_test.ts

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'chrome://os-settings/lazy_load.js';

import {CupsPrinterInfo, CupsPrintersBrowserProxyImpl, CupsPrintersEntryManager, PrinterListEntry, PrinterSettingsUserAction, PrinterStatusReason, PrinterStatusSeverity, PrinterType, SettingsCupsEditPrinterDialogElement, SettingsCupsEnterprisePrintersElement, SettingsCupsNearbyPrintersElement, SettingsCupsPrintersElement, SettingsCupsPrintersEntryElement, SettingsCupsSavedPrintersElement} from 'chrome://os-settings/lazy_load.js';
import {CrInputElement, CrSearchableDropDownElement, CrToastElement, Router, routes, settingMojom} from 'chrome://os-settings/os_settings.js';
import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js';
import {webUIListenerCallback} from 'chrome://resources/js/cr.js';
import {getDeepActiveElement} from 'chrome://resources/js/util.js';
import {NetworkStateProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js';
import {ConnectionStateType, NetworkType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js';
import {IronIconElement} from 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {assertEquals, assertFalse, assertNotReached, assertNull, assertStringContains, assertTrue} from 'chrome://webui-test/chai_assert.js';
import {isVisible} from 'chrome://webui-test/chromeos/test_util.js';
import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';

import {FakeMetricsPrivate} from '../fake_metrics_private.js';

import {createCupsPrinterInfo, createPrinterListEntry, getPrinterEntries} from './cups_printer_test_utils.js';
import {TestCupsPrintersBrowserProxy} from './test_cups_printers_browser_proxy.js';

const arrowUpEvent = new KeyboardEvent(
    'keydown', {cancelable: true, key: 'ArrowUp', keyCode: 38});

const arrowDownEvent = new KeyboardEvent(
    'keydown', {cancelable: true, key: 'ArrowDown', keyCode: 40});

const arrowLeftEvent = new KeyboardEvent(
    'keydown', {cancelable: true, key: 'ArrowLeft', keyCode: 37});

const arrowRightEvent = new KeyboardEvent(
    'keydown', {cancelable: true, key: 'ArrowRight', keyCode: 39});

function clickButton(button: HTMLButtonElement): void {
  assertFalse(button.disabled);
  button.click();
  flush();
}

function initializeEditDialog(page: HTMLElement):
    SettingsCupsEditPrinterDialogElement {
  const editDialog =
      page.shadowRoot!.querySelector<SettingsCupsEditPrinterDialogElement>(
          '#editPrinterDialog');
  assertTrue(!!editDialog);

  // Edit dialog will reset |ppdModel| when |ppdManufacturer| is set. Must
  // set values separately.
  editDialog.set('pendingPrinter_.ppdManufacturer', 'make');
  editDialog.set('pendingPrinter_.ppdModel', 'model');

  // Initializing |activePrinter| in edit dialog will set
  // |needsReconfigured_| to true. Reset it so that any changes afterwards
  // mimics user input.
  editDialog.set('needsReconfigured_', false);

  return editDialog;
}

function verifyErrorToastMessage(
    expectedMessage: string, toast: CrToastElement): void {
  assertTrue(toast.open);
  assertEquals(expectedMessage, toast.textContent?.trim());
}

/**
 * Helper function that verifies that |printerList| matches the printers in
 * |entryList|.
 */
function verifyPrintersList(
    entryList: NodeListOf<SettingsCupsPrintersEntryElement>,
    printerList: CupsPrinterInfo[]): void {
  for (let index = 0; index < printerList.length; ++index) {
    const entryInfo = entryList[index]!.printerEntry.printerInfo;
    const printerInfo = printerList[index];
    assertTrue(!!printerInfo);
    assertEquals(printerInfo.printerName, entryInfo.printerName);
    assertEquals(printerInfo.printerAddress, entryInfo.printerAddress);
    assertEquals(printerInfo.printerId, entryInfo.printerId);
    assertEquals(entryList.length, printerList.length);
  }
}

/**
 * Helper function to verify that printers in |printerListEntries| that contain
 * |searchTerm| are not in |hiddenEntries|.
 */
function verifyFilteredPrinters(
    printerEntryListTestElement: Element, searchTerm: string): void {
  const printerListEntries: SettingsCupsPrintersEntryElement[] =
      Array.from(printerEntryListTestElement.querySelectorAll(
          'settings-cups-printers-entry'));
  const hiddenEntries: SettingsCupsPrintersEntryElement[] =
      Array.from(printerEntryListTestElement.querySelectorAll(
          'settings-cups-printers-entry[hidden]'));

  printerListEntries.forEach(entry => {
    if (hiddenEntries.indexOf(entry) === -1) {
      assertStringContains(
          entry.printerEntry.printerInfo.printerName.toLowerCase(),
          searchTerm.toLowerCase());
    }
  });
}

/**
 * Helper function to verify that the actual visible printers match the
 * expected printer list.
 */
function verifyVisiblePrinters(
    printerEntryListTestElement: Element,
    expectedVisiblePrinters: PrinterListEntry[]): void {
  const actualPrinterList: SettingsCupsPrintersEntryElement[] =
      Array.from(printerEntryListTestElement.querySelectorAll(
          'settings-cups-printers-entry:not([hidden])'));

  assertEquals(expectedVisiblePrinters.length, actualPrinterList.length);
  for (let i = 0; i < expectedVisiblePrinters.length; i++) {
    const expectedPrinter = expectedVisiblePrinters[i]!.printerInfo;
    const actualPrinter = actualPrinterList[i]!.printerEntry.printerInfo;

    assertEquals(expectedPrinter.printerName, actualPrinter.printerName);
    assertEquals(expectedPrinter.printerAddress, actualPrinter.printerAddress);
    assertEquals(expectedPrinter.printerId, actualPrinter.printerId);
  }
}

/**
 * Helper function to verify that printers are hidden accordingly if they do not
 * match the search query. Also checks if the no search results section is shown
 * when appropriate.
 */
function verifySearchQueryResults(
    printersElement: Element, expectedVisiblePrinters: PrinterListEntry[],
    searchTerm: string): void {
  const printerEntryListTestElement =
      printersElement.shadowRoot!.querySelector('#printerEntryList');
  assertTrue(!!printerEntryListTestElement);
  verifyVisiblePrinters(printerEntryListTestElement, expectedVisiblePrinters);
  verifyFilteredPrinters(printerEntryListTestElement, searchTerm);

  const noSearchResults =
      printersElement.shadowRoot!.querySelector<HTMLElement>(
          '#no-search-results');
  assertTrue(!!noSearchResults);

  if (expectedVisiblePrinters.length) {
    assertTrue(noSearchResults.hidden);
  } else {
    assertFalse(noSearchResults.hidden);
  }
}

/**
 * Removes a saved printer located at |index|.
 */
async function removePrinter(
    cupsPrintersBrowserProxy: TestCupsPrintersBrowserProxy,
    savedPrintersElement: HTMLElement, index: number): Promise<void> {
  const printerList = cupsPrintersBrowserProxy.printerList.printerList;
  const savedPrinterEntries = getPrinterEntries(savedPrintersElement);

  const button =
      savedPrinterEntries[index]!.shadowRoot!.querySelector<HTMLButtonElement>(
          '.icon-more-vert');
  assertTrue(!!button);
  clickButton(button);
  const removeButton =
      savedPrintersElement.shadowRoot!.querySelector<HTMLButtonElement>(
          '#removeButton');
  assertTrue(!!removeButton);
  clickButton(removeButton);

  await cupsPrintersBrowserProxy.whenCalled('removeCupsPrinter');
  // Simulate removing the printer from |cupsPrintersBrowserProxy|.
  printerList.splice(index, 1);

  // Simulate saved printer changes.
  webUIListenerCallback(
      'on-saved-printers-changed', cupsPrintersBrowserProxy.printerList);
  flush();
}

/**
 * Removes all saved printers through recursion.
 */
async function removeAllPrinters(
    cupsPrintersBrowserProxy: TestCupsPrintersBrowserProxy,
    savedPrintersElement: HTMLElement): Promise<void> {
  const printerList = cupsPrintersBrowserProxy.printerList.printerList;

  if (!printerList.length) {
    return;
  }

  await removePrinter(
      cupsPrintersBrowserProxy, savedPrintersElement, 0 /* index */);
  await flushTasks();
  await removeAllPrinters(cupsPrintersBrowserProxy, savedPrintersElement);
}

suite('CupsSavedPrintersTests', () => {
  let page: SettingsCupsPrintersElement;
  let savedPrintersElement: SettingsCupsSavedPrintersElement;
  let cupsPrintersBrowserProxy: TestCupsPrintersBrowserProxy;
  let printerList: CupsPrinterInfo[];

  setup(() => {
    cupsPrintersBrowserProxy = new TestCupsPrintersBrowserProxy();
    Router.getInstance().navigateTo(routes.CUPS_PRINTERS);
  });

  teardown(() => {
    cupsPrintersBrowserProxy.reset();
    page.remove();
    savedPrintersElement.remove();
    CupsPrintersEntryManager.resetForTesting();
  });


  function createCupsPrinterPage(printers: CupsPrinterInfo[]): void {
    printerList = printers;
    // |cupsPrinterBrowserProxy| needs to have a list of saved printers before
    // initializing the landing page.
    cupsPrintersBrowserProxy.printerList = {printerList: printerList};
    CupsPrintersBrowserProxyImpl.setInstanceForTesting(
        cupsPrintersBrowserProxy);

    page = document.createElement('settings-cups-printers');
    document.body.appendChild(page);
    assertTrue(!!page);

    flush();
  }

  function addNewSavedPrinter(printer: CupsPrinterInfo): void {
    printerList.push(printer);
    updateSavedPrinters();
  }

  function removeSavedPrinter(id: string): void {
    const idx = printerList.findIndex(p => p.printerId === id);
    printerList.splice(idx, 1);
    updateSavedPrinters();
  }

  function updateSavedPrinters(): void {
    cupsPrintersBrowserProxy.printerList = {printerList};
    webUIListenerCallback(
        'on-saved-printers-changed', cupsPrintersBrowserProxy.printerList);
    flush();
  }

  test('SavedPrintersSuccessfullyPopulates', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    // List component contained by CupsSavedPrinters.
    const printerListEntries = getPrinterEntries(savedPrintersElement);
    verifyPrintersList(printerListEntries, printerList);
  });

  test('SuccessfullyRemoveMultipleSavedPrinters', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    await removeAllPrinters(cupsPrintersBrowserProxy, savedPrintersElement);
    const entryList = getPrinterEntries(savedPrintersElement);
    verifyPrintersList(entryList, printerList);
  });

  test('HideSavedPrintersWhenEmpty', async () => {
    // List component contained by CupsSavedPrinters.
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const savedPrinterEntries = getPrinterEntries(savedPrintersElement);
    verifyPrintersList(savedPrinterEntries, printerList);
    assertTrue(!!page.shadowRoot!.querySelector('#savedPrinters'));
    await removeAllPrinters(cupsPrintersBrowserProxy, savedPrintersElement);
    assertTrue(isVisible(page.shadowRoot!.querySelector('#noSavedPrinters')));
    assertEquals(0, getPrinterEntries(savedPrintersElement).length);
  });

  test('UpdateSavedPrinter', async () => {
    const expectedName = 'edited name';

    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const savedPrinterEntries = getPrinterEntries(savedPrintersElement);
    // Update the printer name of the first entry.
    const button =
        savedPrinterEntries[0]!.shadowRoot!.querySelector<HTMLButtonElement>(
            '.icon-more-vert');
    assertTrue(!!button);
    clickButton(button);
    const editButton =
        savedPrintersElement.shadowRoot!.querySelector<HTMLButtonElement>(
            '#editButton');
    assertTrue(!!editButton);
    clickButton(editButton);
    flush();
    const editDialog = initializeEditDialog(page);
    // Change name of printer and save the change.
    const nameField = editDialog.shadowRoot!.querySelector<CrInputElement>(
        '.printer-name-input');
    assertTrue(!!nameField);
    nameField.value = expectedName;
    nameField.dispatchEvent(
        new CustomEvent('input', {bubbles: true, composed: true}));
    flush();
    const actionButton =
        editDialog.shadowRoot!.querySelector<HTMLButtonElement>(
            '.action-button');
    assertTrue(!!actionButton);
    clickButton(actionButton);
    await cupsPrintersBrowserProxy.whenCalled('updateCupsPrinter');
    assertEquals(expectedName, editDialog.activePrinter.printerName);
    // Mimic changes to |cupsPrintersBrowserProxy.printerList|.
    printerList[0]!.printerName = expectedName;
    verifyPrintersList(savedPrinterEntries, printerList);
  });

  test('ReconfigureSavedPrinter', async () => {
    const expectedName = 'edited name';
    const expectedAddress = '1.1.1.1';

    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const savedPrinterEntries = getPrinterEntries(savedPrintersElement);
    // Edit the first entry.
    const button =
        savedPrinterEntries[0]!.shadowRoot!.querySelector<HTMLButtonElement>(
            '.icon-more-vert');
    assertTrue(!!button);
    clickButton(button);
    const editButton =
        savedPrintersElement.shadowRoot!.querySelector<HTMLButtonElement>(
            '#editButton');
    assertTrue(!!editButton);
    clickButton(editButton);
    flush();
    const editDialog = initializeEditDialog(page);
    const nameField = editDialog.shadowRoot!.querySelector<CrInputElement>(
        '.printer-name-input');
    assertTrue(!!nameField);
    nameField.value = expectedName;
    nameField.dispatchEvent(
        new CustomEvent('input', {bubbles: true, composed: true}));
    const addressField =
        editDialog.shadowRoot!.querySelector<CrInputElement>('#printerAddress');
    assertTrue(!!addressField);
    addressField.value = expectedAddress;
    addressField.dispatchEvent(
        new CustomEvent('input', {bubbles: true, composed: true}));
    const cancelButton =
        editDialog.shadowRoot!.querySelector<HTMLButtonElement>(
            '.cancel-button');
    assertTrue(!!cancelButton);
    assertFalse(cancelButton.hidden);
    const actionButton =
        editDialog.shadowRoot!.querySelector<HTMLButtonElement>(
            '.action-button');
    assertTrue(!!actionButton);
    assertFalse(actionButton.hidden);
    flush();
    clickButton(actionButton);
    await cupsPrintersBrowserProxy.whenCalled('reconfigureCupsPrinter');
    assertEquals(expectedName, editDialog.activePrinter.printerName);
    assertEquals(expectedAddress, editDialog.activePrinter.printerAddress);
    // Mimic changes to |cupsPrintersBrowserProxy.printerList|.
    printerList[0]!.printerName = expectedName;
    printerList[0]!.printerAddress = expectedAddress;
    verifyPrintersList(savedPrinterEntries, printerList);
  });

  test('SavedPrintersSearchTermFiltersCorrectPrinters', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const printerListEntries = getPrinterEntries(savedPrintersElement);
    verifyPrintersList(printerListEntries, printerList);
    let searchTerm = 'google';
    savedPrintersElement.searchTerm = searchTerm;
    flush();
    // Filtering "google" should result in one visible entry and two
    // hidden entries.
    verifySearchQueryResults(
        savedPrintersElement,
        [createPrinterListEntry('google', '4', 'id4', PrinterType.SAVED)],
        searchTerm);
    // Change the search term and assert that entries are filtered
    // correctly. Filtering "test" should result in three visible entries
    // and one hidden entry.
    searchTerm = 'test';
    savedPrintersElement.searchTerm = searchTerm;
    flush();
    verifySearchQueryResults(
        savedPrintersElement,
        [
          createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
          createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
        ],
        searchTerm);
    // Add more printers and assert that they are correctly filtered.
    addNewSavedPrinter(createCupsPrinterInfo('test3', '3', 'id3'));
    addNewSavedPrinter(createCupsPrinterInfo('google2', '6', 'id6'));
    flush();
    verifySearchQueryResults(
        savedPrintersElement,
        [
          createPrinterListEntry('test3', '3', 'id3', PrinterType.SAVED),
          createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
          createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
        ],
        searchTerm);
  });

  test('SavedPrintersNoSearchFound', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const printerListEntries = getPrinterEntries(savedPrintersElement);
    verifyPrintersList(printerListEntries, printerList);
    let searchTerm = 'google';
    savedPrintersElement.searchTerm = searchTerm;
    flush();
    // Filtering "google" should result in one visible entry and three
    // hidden entries.
    verifySearchQueryResults(
        savedPrintersElement,
        [createPrinterListEntry('google', '4', 'id4', PrinterType.SAVED)],
        searchTerm);
    // Change search term to something that has no matches.
    searchTerm = 'noSearchFound';
    savedPrintersElement.searchTerm = searchTerm;
    flush();
    verifySearchQueryResults(savedPrintersElement, [], searchTerm);
    // Change search term back to "google" and verify that the No search
    // found message is no longer there.
    searchTerm = 'google';
    savedPrintersElement.searchTerm = searchTerm;
    flush();
    verifySearchQueryResults(
        savedPrintersElement,
        [createPrinterListEntry('google', '4', 'id4', PrinterType.SAVED)],
        searchTerm);
  });

  test('NavigateSavedPrintersList', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const printerEntryList =
        savedPrintersElement.shadowRoot!.querySelector<HTMLElement>(
            '#printerEntryList');
    assertTrue(!!printerEntryList);
    const printerListEntries = getPrinterEntries(savedPrintersElement);
    printerEntryList.focus();
    printerEntryList.dispatchEvent(arrowDownEvent);
    flush();
    assertEquals(printerListEntries[1], getDeepActiveElement());
    printerEntryList.dispatchEvent(arrowDownEvent);
    flush();
    assertEquals(printerListEntries[2], getDeepActiveElement());
    printerEntryList.dispatchEvent(arrowUpEvent);
    flush();
    assertEquals(printerListEntries[1], getDeepActiveElement());
    printerEntryList.dispatchEvent(arrowUpEvent);
    flush();
    assertEquals(printerListEntries[0], getDeepActiveElement());
  });

  test('Deep link to saved printers', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
      createCupsPrinterInfo('test3', '3', 'id3'),
    ]);

    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');

    const params = new URLSearchParams();
    params.append('settingId', settingMojom.Setting.kSavedPrinters.toString());
    Router.getInstance().navigateTo(routes.CUPS_PRINTERS, params);

    flush();

    const savedPrinters =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    const printerEntry = savedPrinters &&
        savedPrinters.shadowRoot!.querySelector('settings-cups-printers-entry');
    const deepLinkElement = printerEntry &&
        printerEntry.shadowRoot!.querySelector<HTMLElement>('#moreActions');
    assertTrue(!!deepLinkElement);
    await waitAfterNextRender(deepLinkElement);
    const activeDeepLink = getDeepActiveElement();
    assertEquals(
        deepLinkElement, activeDeepLink,
        'First saved printer menu button should be focused for settingId=1401.');
  });

  test('SavedPrintersStatusUpdates', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
      createCupsPrinterInfo('test3', '3', 'id3'),
    ]);

    cupsPrintersBrowserProxy.addPrinterStatus(
        'id1', PrinterStatusReason.NO_ERROR, PrinterStatusSeverity.ERROR);
    cupsPrintersBrowserProxy.addPrinterStatus(
        'id2', PrinterStatusReason.PRINTER_UNREACHABLE,
        PrinterStatusSeverity.ERROR);

    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    await flushTasks();

    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;

    // The printer statuses should be added to the cache once fetched.
    const printerStatusReasonCache =
        savedPrintersElement.getPrinterStatusReasonCacheForTesting();
    assertTrue(printerStatusReasonCache.has('id1'));
    assertTrue(printerStatusReasonCache.has('id2'));
    assertFalse(printerStatusReasonCache.has('id3'));

    // For each of the 3 saved printers verify it gets the correct printer
    // icon based on the printer status previously set.
    const printerListEntries = getPrinterEntries(savedPrintersElement);
    assertEquals(3, printerListEntries.length);
    for (const entry of printerListEntries) {
      let expectedPrinterIcon;
      switch (entry.printerEntry.printerInfo.printerId) {
        case 'id1':
          expectedPrinterIcon = 'os-settings:printer-status-illo-green';
          break;
        case 'id2':
          expectedPrinterIcon = 'os-settings:printer-status-illo-red';
          break;
        case 'id3':
          expectedPrinterIcon = 'os-settings:printer-status-illo-grey';
          break;
        default:
          assertNotReached();
      }
      const printerStatusIcon =
          entry.shadowRoot!.querySelector<IronIconElement>(
              '#printerStatusIcon');
      assertTrue(!!printerStatusIcon);
      assertEquals(expectedPrinterIcon, printerStatusIcon.icon);
    }

    // Removing the printers should also remove their cache entry.
    await removeAllPrinters(cupsPrintersBrowserProxy, savedPrintersElement);
    assertFalse(printerStatusReasonCache.has('id1'));
    assertFalse(printerStatusReasonCache.has('id2'));
  });

  // Verify the printer statuses received from the 'local-printers-updated'
  // event are added to the printer status cache.
  test('LocalPrintersUpdatedPrinterStatusCache', async () => {
    createCupsPrinterPage([]);
    await flushTasks();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;

    const id1 = 'id1';
    const printer1 = createCupsPrinterInfo('test1', '1', id1);
    printer1.printerStatus = {
      printerId: id1,
      statusReasons: [
        {
          reason: PrinterStatusReason.PRINTER_UNREACHABLE,
          severity: PrinterStatusSeverity.ERROR,
        },
      ],
      timestamp: 0,
    };
    const id2 = 'id2';
    const printer2 = createCupsPrinterInfo('test2', '2', id2);
    printer2.printerStatus = {
      printerId: id2,
      statusReasons: [
        {
          reason: PrinterStatusReason.LOW_ON_INK,
          severity: PrinterStatusSeverity.ERROR,
        },
      ],
      timestamp: 0,
    };
    // Printer3 has an undefined printer status so it shouldn't be added to the
    // cache.
    const id3 = 'id3';
    const printer3 = createCupsPrinterInfo('test3', '3', id3);
    printer3.printerStatus = {
      printerId: '',
      statusReasons: [],
      timestamp: 0,
    };

    // The printer status cache should initialize empty.
    const printerStatusReasonCache =
        savedPrintersElement.getPrinterStatusReasonCacheForTesting();
    assertFalse(printerStatusReasonCache.has(id1));
    assertFalse(printerStatusReasonCache.has(id2));
    assertFalse(printerStatusReasonCache.has(id3));

    // Trigger the observer and expect the printer statuses to be extracted then
    // added to the cache.
    webUIListenerCallback('local-printers-updated', [printer1, printer2]);
    await flushTasks();
    assertTrue(printerStatusReasonCache.has(id1));
    assertTrue(printerStatusReasonCache.has(id2));
    assertFalse(printerStatusReasonCache.has(id3));
  });

  test('ShowMoreButtonIsInitiallyHiddenAndANewPrinterIsAdded', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const printerEntryListTestElement =
        savedPrintersElement.shadowRoot!.querySelector('#printerEntryList');
    assertTrue(!!printerEntryListTestElement);
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('google', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
    ]);
    // Assert that the Show more button is hidden because printer list
    // length is <= 3.
    assertNull(
        savedPrintersElement.shadowRoot!.querySelector('#show-more-container'));
    // Newly added printers will always be visible and inserted to the
    // top of the list.
    addNewSavedPrinter(createCupsPrinterInfo('test3', '3', 'id3'));
    const expectedVisiblePrinters = [
      createPrinterListEntry('test3', '3', 'id3', PrinterType.SAVED),
      createPrinterListEntry('google', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
    ];
    verifyVisiblePrinters(printerEntryListTestElement, expectedVisiblePrinters);
    // Assert that the Show more button is still hidden because all newly
    // added printers are visible.
    assertNull(
        savedPrintersElement.shadowRoot!.querySelector('#show-more-container'));
  });

  test('PressShowMoreButton', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
      createCupsPrinterInfo('test3', '3', 'id3'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const printerEntryListTestElement =
        savedPrintersElement.shadowRoot!.querySelector('#printerEntryList');
    assertTrue(!!printerEntryListTestElement);
    // There are 4 total printers but only 3 printers are visible and 1 is
    // hidden underneath the Show more section.
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('google', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
    ]);
    // Assert that the Show more button is shown since printer list length
    // is > 3.
    assertTrue(!!savedPrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));
    const showMoreIcon =
        savedPrintersElement.shadowRoot!.querySelector<HTMLButtonElement>(
            '#show-more-icon');
    assertTrue(!!showMoreIcon);
    // Click on the Show more button.
    clickButton(showMoreIcon);
    assertNull(
        savedPrintersElement.shadowRoot!.querySelector('#show-more-container'));
    // Clicking on the Show more button reveals all hidden printers.
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('google', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
      createPrinterListEntry('test3', '3', 'id3', PrinterType.SAVED),
    ]);
  });

  test('ShowMoreButtonIsInitiallyShownAndWithANewPrinterAdded', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
      createCupsPrinterInfo('test3', '3', 'id3'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const printerEntryListTestElement =
        savedPrintersElement.shadowRoot!.querySelector('#printerEntryList');
    assertTrue(!!printerEntryListTestElement);
    // There are 4 total printers but only 3 printers are visible and 1 is
    // hidden underneath the Show more section.
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('google', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
    ]);
    // Assert that the Show more button is shown since printer list length
    // is > 3.
    assertTrue(!!savedPrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));
    // Newly added printers will always be visible.
    addNewSavedPrinter(createCupsPrinterInfo('test5', '5', 'id5'));
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('test5', '5', 'id5', PrinterType.SAVED),
      createPrinterListEntry('google', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
    ]);
    // Assert that the Show more button is still shown.
    assertTrue(!!savedPrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));

    // Verify all printers are visible after the Show more button is pressed.
    const showMoreIcon =
        savedPrintersElement.shadowRoot!.querySelector<HTMLButtonElement>(
            '#show-more-icon');
    assertTrue(!!showMoreIcon);
    clickButton(showMoreIcon);
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('test5', '5', 'id5', PrinterType.SAVED),
      createPrinterListEntry('google', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
      createPrinterListEntry('test3', '3', 'id3', PrinterType.SAVED),
    ]);
  });

  test('ShowMoreButtonIsShownAndRemovePrinters', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '3', 'id3'),
      createCupsPrinterInfo('google2', '4', 'id4'),
      createCupsPrinterInfo('google3', '5', 'id5'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const printerEntryListTestElement =
        savedPrintersElement.shadowRoot!.querySelector('#printerEntryList');
    assertTrue(!!printerEntryListTestElement);
    // There are 5 total printers but only 3 printers are visible and 2
    // are hidden underneath the Show more section.
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('google', '3', 'id3', PrinterType.SAVED),
      createPrinterListEntry('google2', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('google3', '5', 'id5', PrinterType.SAVED),
    ]);
    // Assert that the Show more button is shown since printer list length
    // is > 3.
    assertTrue(!!savedPrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));
    // Simulate removing 'google' printer.
    removeSavedPrinter('id3');
    // Printer list has 4 elements now, but since the list is still
    // collapsed we should still expect only 3 elements to be visible.
    // Since printers were initially alphabetically sorted, we should
    // expect 'test1' to be the next visible printer.
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('google2', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('google3', '5', 'id5', PrinterType.SAVED),
      createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
    ]);
    assertTrue(!!savedPrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));
    // Simulate removing 'google2' printer.
    removeSavedPrinter('id4');
    // Printer list has 3 elements now, the Show more button should be
    // hidden.
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('google3', '5', 'id5', PrinterType.SAVED),
      createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
    ]);
    assertNull(
        savedPrintersElement.shadowRoot!.querySelector('#show-more-container'));
  });

  test('ShowMoreButtonIsShownAndSearchQueryFiltersCorrectly', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '3', 'id3'),
      createCupsPrinterInfo('google2', '4', 'id4'),
      createCupsPrinterInfo('google3', '5', 'id5'),
      createCupsPrinterInfo('google4', '6', 'id6'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const printerEntryListTestElement =
        savedPrintersElement.shadowRoot!.querySelector('#printerEntryList');
    assertTrue(!!printerEntryListTestElement);
    // There are 6 total printers but only 3 printers are visible and 3
    // are hidden underneath the Show more section.
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('google', '3', 'id3', PrinterType.SAVED),
      createPrinterListEntry('google2', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('google3', '5', 'id5', PrinterType.SAVED),
    ]);
    // Assert that the Show more button is shown since printer list length
    // is > 3.
    assertTrue(!!savedPrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));
    // Set search term to 'google' and expect 4 visible printers.
    let searchTerm = 'google';
    savedPrintersElement.searchTerm = searchTerm;
    flush();
    verifySearchQueryResults(
        savedPrintersElement,
        [
          createPrinterListEntry('google', '3', 'id3', PrinterType.SAVED),
          createPrinterListEntry('google2', '4', 'id4', PrinterType.SAVED),
          createPrinterListEntry('google3', '5', 'id5', PrinterType.SAVED),
          createPrinterListEntry('google4', '6', 'id6', PrinterType.SAVED),
        ],
        searchTerm);
    // Having a search term should hide the Show more button.
    assertNull(
        savedPrintersElement.shadowRoot!.querySelector('#show-more-container'));
    // Search for a term with no matching printers. Expect Show more
    // button to still be hidden.
    searchTerm = 'noSearchFound';
    savedPrintersElement.searchTerm = searchTerm;
    flush();
    verifySearchQueryResults(savedPrintersElement, [], searchTerm);
    assertNull(
        savedPrintersElement.shadowRoot!.querySelector('#show-more-container'));
    // Change search term and expect new set of visible printers.
    searchTerm = 'test';
    savedPrintersElement.searchTerm = searchTerm;
    flush();
    verifySearchQueryResults(
        savedPrintersElement,
        [
          createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
          createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
        ],
        searchTerm);
    assertNull(
        savedPrintersElement.shadowRoot!.querySelector('#show-more-container'));
    // Remove the search term and expect the collapsed list to appear
    // again.
    searchTerm = '';
    savedPrintersElement.searchTerm = searchTerm;
    flush();
    const expectedVisiblePrinters = [
      createPrinterListEntry('google', '3', 'id3', PrinterType.SAVED),
      createPrinterListEntry('google2', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('google3', '5', 'id5', PrinterType.SAVED),
    ];
    verifySearchQueryResults(
        savedPrintersElement, expectedVisiblePrinters, searchTerm);
    verifyVisiblePrinters(printerEntryListTestElement, expectedVisiblePrinters);
    assertTrue(!!savedPrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));
  });

  test('ShowMoreButtonAddAndRemovePrinters', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('google', '3', 'id3'),
      createCupsPrinterInfo('google2', '4', 'id4'),
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    const printerEntryListTestElement =
        savedPrintersElement.shadowRoot!.querySelector('#printerEntryList');
    assertTrue(!!printerEntryListTestElement);
    // There are 4 total printers but only 3 printers are visible and 1 is
    // hidden underneath the Show more section.
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('google', '3', 'id3', PrinterType.SAVED),
      createPrinterListEntry('google2', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
    ]);
    // Assert that the Show more button is shown since printer list length
    // is > 3.
    assertTrue(!!savedPrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));
    // Add a new printer and expect it to be at the top of the list.
    addNewSavedPrinter(createCupsPrinterInfo('newPrinter', '5', 'id5'));
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('newPrinter', '5', 'id5', PrinterType.SAVED),
      createPrinterListEntry('google', '3', 'id3', PrinterType.SAVED),
      createPrinterListEntry('google2', '4', 'id4', PrinterType.SAVED),
      createPrinterListEntry('test1', '1', 'id1', PrinterType.SAVED),
    ]);
    assertTrue(!!savedPrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));
    // Now simulate removing printer 'test1'.
    removeSavedPrinter('id1');
    // If the number of visible printers is > 3, removing printers will
    // decrease the number of visible printers until there are only 3
    // visible printers. In this case, we remove 'test1' and now only
    // have 3 visible printers and 1 hidden printer: 'test2'.
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('newPrinter', '5', 'id5', PrinterType.SAVED),
      createPrinterListEntry('google', '3', 'id3', PrinterType.SAVED),
      createPrinterListEntry('google2', '4', 'id4', PrinterType.SAVED),
    ]);
    assertTrue(!!savedPrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));
    // Remove another printer and assert that we still have 3 visible
    // printers but now 'test2' is our third visible printer.
    removeSavedPrinter('id4');
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('newPrinter', '5', 'id5', PrinterType.SAVED),
      createPrinterListEntry('google', '3', 'id3', PrinterType.SAVED),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.SAVED),
    ]);
    // Printer list length is <= 3, Show more button should be hidden.
    assertNull(
        savedPrintersElement.shadowRoot!.querySelector('#show-more-container'));
  });

  test('RecordUserActionMetric', async () => {
    const fakeMetricsPrivate = new FakeMetricsPrivate();
    chrome.metricsPrivate = fakeMetricsPrivate;

    createCupsPrinterPage([
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-saved-printers');
    assertTrue(!!element);
    savedPrintersElement = element;
    await removePrinter(
        cupsPrintersBrowserProxy, savedPrintersElement, /*index=*/ 0);
    assertEquals(
        1,
        fakeMetricsPrivate.countMetricValue(
            'Printing.CUPS.SettingsUserAction',
            PrinterSettingsUserAction.REMOVE_PRINTER));
    // Click the next printer's Edit button then verify the action is
    // recorded.
    const savedPrinterEntries = getPrinterEntries(savedPrintersElement);
    const button =
        savedPrinterEntries[0]!.shadowRoot!.querySelector<HTMLButtonElement>(
            '.icon-more-vert');
    assertTrue(!!button);
    clickButton(button);
    const editButton =
        savedPrintersElement.shadowRoot!.querySelector<HTMLButtonElement>(
            '#editButton');
    assertTrue(!!editButton);
    clickButton(editButton);
    assertEquals(
        1,
        fakeMetricsPrivate.countMetricValue(
            'Printing.CUPS.SettingsUserAction',
            PrinterSettingsUserAction.EDIT_PRINTER));
  });
});

suite('CupsNearbyPrintersTests', () => {
  let page: SettingsCupsPrintersElement;
  let nearbyPrintersElement: SettingsCupsNearbyPrintersElement;
  let cupsPrintersBrowserProxy: TestCupsPrintersBrowserProxy;
  let printerEntryListTestElement: HTMLElement;
  let wifi1: NetworkStateProperties;


  setup(() => {
    cupsPrintersBrowserProxy = new TestCupsPrintersBrowserProxy();

    CupsPrintersBrowserProxyImpl.setInstanceForTesting(
        cupsPrintersBrowserProxy);

    // Simulate internet connection.
    wifi1 = OncMojo.getDefaultNetworkState(NetworkType.kWiFi, 'wifi1');
    wifi1.connectionState = ConnectionStateType.kOnline;

    Router.getInstance().navigateTo(routes.CUPS_PRINTERS);

    page = document.createElement('settings-cups-printers');
    document.body.appendChild(page);
    assertTrue(!!page);
    page.onActiveNetworksChanged([wifi1]);

    flush();
  });

  teardown(() => {
    cupsPrintersBrowserProxy.reset();
    page.remove();
    nearbyPrintersElement.remove();
  });

  test('nearbyPrintersSuccessfullyPopulates', async () => {
    const automaticPrinterList = [
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ];
    const discoveredPrinterList = [
      createCupsPrinterInfo('test3', '3', 'id3'),
      createCupsPrinterInfo('test4', '4', 'id4'),
    ];

    await flushTasks();
    const element =
        page.shadowRoot!.querySelector('settings-cups-nearby-printers');
    assertTrue(!!element);
    nearbyPrintersElement = element;
    // Assert that no printers have been detected.
    let nearbyPrinterEntries = getPrinterEntries(nearbyPrintersElement);
    assertEquals(0, nearbyPrinterEntries.length);
    // Simuluate finding nearby printers.
    webUIListenerCallback(
        'on-nearby-printers-changed', automaticPrinterList,
        discoveredPrinterList);
    flush();
    nearbyPrinterEntries = getPrinterEntries(nearbyPrintersElement);
    const expectedPrinterList: CupsPrinterInfo[] =
        automaticPrinterList.concat(discoveredPrinterList);
    verifyPrintersList(nearbyPrinterEntries, expectedPrinterList);
  });

  test('nearbyPrintersSortOrderAutoFirstThenDiscovered', async () => {
    const discoveredPrinterA =
        createCupsPrinterInfo('printerNameA', 'printerAddress1', 'printerId1');
    const discoveredPrinterB =
        createCupsPrinterInfo('printerNameB', 'printerAddress2', 'printerId2');
    const discoveredPrinterC =
        createCupsPrinterInfo('printerNameC', 'printerAddress3', 'printerId3');
    const autoPrinterD =
        createCupsPrinterInfo('printerNameD', 'printerAddress4', 'printerId4');
    const autoPrinterE =
        createCupsPrinterInfo('printerNameE', 'printerAddress5', 'printerId5');
    const autoPrinterF =
        createCupsPrinterInfo('printerNameF', 'printerAddress6', 'printerId6');

    // Add printers in a non-alphabetical order to test sorting.
    const automaticPrinterList = [autoPrinterF, autoPrinterD, autoPrinterE];
    const discoveredPrinterList =
        [discoveredPrinterC, discoveredPrinterA, discoveredPrinterB];

    // Expected sort order is to sort automatic printers first then
    // sort discovered printers
    const expectedPrinterList = [
      autoPrinterD,
      autoPrinterE,
      autoPrinterF,
      discoveredPrinterA,
      discoveredPrinterB,
      discoveredPrinterC,
    ];

    await flushTasks();
    const element =
        page.shadowRoot!.querySelector('settings-cups-nearby-printers');
    assertTrue(!!element);
    nearbyPrintersElement = element;
    // Simuluate finding nearby printers.
    webUIListenerCallback(
        'on-nearby-printers-changed', automaticPrinterList,
        discoveredPrinterList);
    flush();
    const nearbyPrinterEntries = getPrinterEntries(nearbyPrintersElement);
    verifyPrintersList(nearbyPrinterEntries, expectedPrinterList);
  });

  test('addingAutomaticPrinterIsSuccessful', async () => {
    const automaticPrinterList = [createCupsPrinterInfo('test1', '1', 'id1')];
    const discoveredPrinterList: CupsPrinterInfo[] = [];

    let addButton = null;

    await flushTasks();
    const element =
        page.shadowRoot!.querySelector('settings-cups-nearby-printers');
    assertTrue(!!element);
    nearbyPrintersElement = element;
    // Simuluate finding nearby printers.
    webUIListenerCallback(
        'on-nearby-printers-changed', automaticPrinterList,
        discoveredPrinterList);
    flush();
    // Requery and assert that the newly detected printer automatic
    // printer has the correct button.
    const nearbyPrinterEntries = getPrinterEntries(nearbyPrintersElement);
    assertEquals(1, nearbyPrinterEntries.length);
    assertTrue(!!nearbyPrinterEntries[0]!.shadowRoot!.querySelector(
        '.save-printer-button'));
    // Add an automatic printer and assert that that the toast
    // notification is shown.
    addButton =
        nearbyPrinterEntries[0]!.shadowRoot!.querySelector<HTMLButtonElement>(
            '.save-printer-button');
    assertTrue(!!addButton);
    clickButton(addButton);
    // Add button should be disabled during setup.
    assertTrue(addButton.disabled);
    await cupsPrintersBrowserProxy.whenCalled('addDiscoveredPrinter');
    assertFalse(addButton.disabled);
    const expectedToastMessage =
        'Added ' + automaticPrinterList[0]!.printerName;
    const errorToast =
        page.shadowRoot!.querySelector<CrToastElement>('#errorToast');
    assertTrue(!!errorToast);
    verifyErrorToastMessage(expectedToastMessage, errorToast);
  });

  test('NavigateNearbyPrinterList', async () => {
    const discoveredPrinterList = [
      createCupsPrinterInfo('first', '3', 'id3'),
      createCupsPrinterInfo('second', '4', 'id4'),
      createCupsPrinterInfo('third', '2', 'id5'),
    ];
    await flushTasks();
    const element =
        page.shadowRoot!.querySelector('settings-cups-nearby-printers');
    assertTrue(!!element);
    // Block so that FocusRowBehavior.attached can run.
    await waitAfterNextRender(element);
    nearbyPrintersElement = element;
    // Simuluate finding nearby printers.
    webUIListenerCallback(
        'on-nearby-printers-changed', [], discoveredPrinterList);
    flush();
    // Wait one more time to ensure that async setup in FocusRowBehavior has
    // executed.
    await waitAfterNextRender(nearbyPrintersElement);
    const nearbyPrinterEntries = getPrinterEntries(nearbyPrintersElement);
    const printerEntryList =
        nearbyPrintersElement.shadowRoot!.querySelector('#printerEntryList');
    assertTrue(!!printerEntryList);
    const entry =
        nearbyPrinterEntries[0]!.shadowRoot!.querySelector<HTMLElement>(
            '#entry');
    assertTrue(!!entry);
    entry.focus();
    assertEquals(
        nearbyPrinterEntries[0]!.shadowRoot!.querySelector('#entry'),
        getDeepActiveElement());
    // Ensure that we can navigate through items in a row
    getDeepActiveElement()?.dispatchEvent(arrowRightEvent);
    assertEquals(
        nearbyPrinterEntries[0]!.shadowRoot!.querySelector(
            '#setupPrinterButton'),
        getDeepActiveElement());
    getDeepActiveElement()?.dispatchEvent(arrowLeftEvent);
    assertEquals(
        nearbyPrinterEntries[0]!.shadowRoot!.querySelector('#entry'),
        getDeepActiveElement());
    // Ensure that we can navigate through printer rows
    printerEntryList.dispatchEvent(arrowDownEvent);
    assertEquals(
        nearbyPrinterEntries[1]!.shadowRoot!.querySelector('#entry'),
        getDeepActiveElement());
    printerEntryList.dispatchEvent(arrowDownEvent);
    assertEquals(
        nearbyPrinterEntries[2]!.shadowRoot!.querySelector('#entry'),
        getDeepActiveElement());
    printerEntryList.dispatchEvent(arrowUpEvent);
    assertEquals(
        nearbyPrinterEntries[1]!.shadowRoot!.querySelector('#entry'),
        getDeepActiveElement());
    printerEntryList.dispatchEvent(arrowUpEvent);
    assertEquals(
        nearbyPrinterEntries[0]!.shadowRoot!.querySelector('#entry'),
        getDeepActiveElement());
  });

  test('addingDiscoveredPrinterIsSuccessful', async () => {
    const automaticPrinterList: CupsPrinterInfo[] = [];
    const discoveredPrinterList = [createCupsPrinterInfo('test3', '3', 'id3')];

    let manufacturerDialog = null;
    let setupButton = null;

    await flushTasks();
    const element =
        page.shadowRoot!.querySelector('settings-cups-nearby-printers');
    assertTrue(!!element);
    nearbyPrintersElement = element;
    // Simuluate finding nearby printers.
    webUIListenerCallback(
        'on-nearby-printers-changed', automaticPrinterList,
        discoveredPrinterList);
    flush();
    // Requery and assert that a newly detected discovered printer has
    // the correct icon button.
    const nearbyPrinterEntries = getPrinterEntries(nearbyPrintersElement);
    assertEquals(1, nearbyPrinterEntries.length);
    assertTrue(!!nearbyPrinterEntries[0]!.shadowRoot!.querySelector(
        '#setupPrinterButton'));
    // Force a failure with adding a discovered printer.
    cupsPrintersBrowserProxy.setAddDiscoveredPrinterFailure(
        discoveredPrinterList[0]!);
    // Assert that clicking on the setup button shows the advanced
    // configuration dialog.
    setupButton =
        nearbyPrinterEntries[0]!.shadowRoot!.querySelector<HTMLButtonElement>(
            '#setupPrinterButton');
    assertTrue(!!setupButton);
    clickButton(setupButton);
    // Setup button should be disabled during setup.
    assertTrue(setupButton.disabled);
    await cupsPrintersBrowserProxy.whenCalled('addDiscoveredPrinter');
    assertFalse(setupButton.disabled);
    flush();
    const addDialog = page.shadowRoot!.querySelector('#addPrinterDialog');
    assertTrue(!!addDialog);
    manufacturerDialog = addDialog.shadowRoot!.querySelector(
        'add-printer-manufacturer-model-dialog');
    assertTrue(!!manufacturerDialog);
    await cupsPrintersBrowserProxy.whenCalled(
        'getCupsPrinterManufacturersList');
    const addButton =
        manufacturerDialog.shadowRoot!.querySelector<HTMLButtonElement>(
            '#addPrinterButton');
    assertTrue(!!addButton);
    assertTrue(addButton.disabled);
    // Populate the manufacturer and model fields to enable the Add
    // button.
    const manufacturerDropdown =
        manufacturerDialog.shadowRoot!
            .querySelector<CrSearchableDropDownElement>(
                '#manufacturerDropdown');
    assertTrue(!!manufacturerDropdown);
    manufacturerDropdown.value = 'make';
    const modelDropdown =
        manufacturerDialog.shadowRoot!
            .querySelector<CrSearchableDropDownElement>('#modelDropdown');
    assertTrue(!!modelDropdown);
    modelDropdown.value = 'model';
    clickButton(addButton);
    await cupsPrintersBrowserProxy.whenCalled('addCupsPrinter');
    // Assert that the toast notification is shown and has the expected
    // message when adding a discovered printer.
    const expectedToastMessage =
        'Added ' + discoveredPrinterList[0]!.printerName;
    const errorToast =
        page.shadowRoot!.querySelector<CrToastElement>('#errorToast');
    assertTrue(!!errorToast);
    verifyErrorToastMessage(expectedToastMessage, errorToast);
  });

  test('NetworkConnectedButNoInternet', async () => {
    // Simulate connecting to a network with no internet connection.
    wifi1.connectionState = ConnectionStateType.kConnected;
    page.onActiveNetworksChanged([wifi1]);
    flush();

    await flushTasks();
    // We require internet to be able to add a new printer. Connecting to
    // a network without connectivity should be equivalent to not being
    // connected to a network.
    assertTrue(!!page.shadowRoot!.querySelector('#cloudOffIcon'));
    assertTrue(!!page.shadowRoot!.querySelector('#connectionMessage'));
    const addManualPrinterButton =
        page.shadowRoot!.querySelector<HTMLButtonElement>(
            '#addManualPrinterButton');
    assertTrue(!!addManualPrinterButton);
    assertTrue(addManualPrinterButton.disabled);
  });

  test('checkNetworkConnection', async () => {
    // Simulate disconnecting from a network.
    wifi1.connectionState = ConnectionStateType.kNotConnected;
    page.onActiveNetworksChanged([wifi1]);
    flush();

    await flushTasks();
    // Expect offline text to show up when no internet is
    // connected.
    assertTrue(!!page.shadowRoot!.querySelector('#cloudOffIcon'));
    assertTrue(!!page.shadowRoot!.querySelector('#connectionMessage'));
    const addManualPrinterButton =
        page.shadowRoot!.querySelector<HTMLButtonElement>(
            '#addManualPrinterButton');
    assertTrue(!!addManualPrinterButton);
    assertTrue(addManualPrinterButton.disabled);
    // Simulate connecting to a network with connectivity.
    wifi1.connectionState = ConnectionStateType.kOnline;
    page.onActiveNetworksChanged([wifi1]);
    flush();
    await flushTasks();
    const automaticPrinterList = [
      createCupsPrinterInfo('test1', '1', 'id1'),
      createCupsPrinterInfo('test2', '2', 'id2'),
    ];
    const discoveredPrinterList = [
      createCupsPrinterInfo('test3', '3', 'id3'),
      createCupsPrinterInfo('test4', '4', 'id4'),
    ];
    // Simuluate finding nearby printers.
    webUIListenerCallback(
        'on-nearby-printers-changed', automaticPrinterList,
        discoveredPrinterList);
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-nearby-printers');
    assertTrue(!!element);
    nearbyPrintersElement = element;
    const listElement =
        nearbyPrintersElement.shadowRoot!.querySelector<HTMLElement>(
            '#printerEntryList');
    assertTrue(!!listElement);
    printerEntryListTestElement = listElement;
    const nearbyPrinterEntries = getPrinterEntries(nearbyPrintersElement);
    const expectedPrinterList =
        automaticPrinterList.concat(discoveredPrinterList);
    verifyPrintersList(nearbyPrinterEntries, expectedPrinterList);
  });

  test('NearbyPrintersSearchTermFiltersCorrectPrinters', async () => {
    const discoveredPrinterList = [
      createCupsPrinterInfo('test1', 'printerAddress1', 'printerId1'),
      createCupsPrinterInfo('test2', 'printerAddress2', 'printerId2'),
      createCupsPrinterInfo('google', 'printerAddress3', 'printerId3'),
    ];

    await flushTasks();
    const element =
        page.shadowRoot!.querySelector('settings-cups-nearby-printers');
    assertTrue(!!element);
    nearbyPrintersElement = element;
    const listElement =
        nearbyPrintersElement.shadowRoot!.querySelector<HTMLElement>(
            '#printerEntryList');
    assertTrue(!!listElement);
    printerEntryListTestElement = listElement;
    // Simuluate finding nearby printers.
    webUIListenerCallback(
        'on-nearby-printers-changed', [], discoveredPrinterList);
    flush();
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry(
          'google', 'printerAddress3', 'printerId3', PrinterType.DISCOVERED),
      createPrinterListEntry(
          'test1', 'printerAddress1', 'printerId1', PrinterType.DISCOVERED),
      createPrinterListEntry(
          'test2', 'printerAddress2', 'printerId2', PrinterType.DISCOVERED),
    ]);
    let searchTerm = 'google';
    nearbyPrintersElement.searchTerm = searchTerm;
    flush();
    // Filtering "google" should result in one visible entry and two hidden
    // entries.
    verifySearchQueryResults(
        nearbyPrintersElement,
        [createPrinterListEntry(
            'google', 'printerAddress3', 'printerId3', PrinterType.DISCOVERED)],
        searchTerm);
    // Filtering "test" should result in two visible entries and one hidden
    // entry.
    searchTerm = 'test';
    nearbyPrintersElement.searchTerm = searchTerm;
    flush();
    verifySearchQueryResults(
        nearbyPrintersElement,
        [
          createPrinterListEntry(
              'test1', 'printerAddress1', 'printerId1', PrinterType.DISCOVERED),
          createPrinterListEntry(
              'test2', 'printerAddress2', 'printerId2', PrinterType.DISCOVERED),
        ],
        searchTerm);
    // Add more printers and assert that they are correctly filtered.
    discoveredPrinterList.push(
        createCupsPrinterInfo('test3', 'printerAddress4', 'printerId4'));
    discoveredPrinterList.push(
        createCupsPrinterInfo('google2', 'printerAddress5', 'printerId5'));
    // Simuluate finding nearby printers.
    webUIListenerCallback(
        'on-nearby-printers-changed', [], discoveredPrinterList);
    flush();
    verifySearchQueryResults(
        nearbyPrintersElement,
        [
          createPrinterListEntry(
              'test1', 'printerAddress1', 'printerId1', PrinterType.DISCOVERED),
          createPrinterListEntry(
              'test2', 'printerAddress2', 'printerId2', PrinterType.DISCOVERED),
          createPrinterListEntry(
              'test3', 'printerAddress4', 'printerId4', PrinterType.DISCOVERED),
        ],
        searchTerm);
  });

  test('NearbyPrintersNoSearchFound', async () => {
    const discoveredPrinterList = [
      createCupsPrinterInfo('test1', 'printerAddress1', 'printerId1'),
      createCupsPrinterInfo('google', 'printerAddress2', 'printerId2'),
    ];

    await flushTasks();
    const element =
        page.shadowRoot!.querySelector('settings-cups-nearby-printers');
    assertTrue(!!element);
    nearbyPrintersElement = element;
    const listElement =
        nearbyPrintersElement.shadowRoot!.querySelector<HTMLElement>(
            '#printerEntryList');
    assertTrue(!!listElement);
    printerEntryListTestElement = listElement;
    // Simuluate finding nearby printers.
    webUIListenerCallback(
        'on-nearby-printers-changed', [], discoveredPrinterList);
    flush();
    let searchTerm = 'google';
    nearbyPrintersElement.searchTerm = searchTerm;
    flush();
    // Set the search term and filter out the printers. Filtering "google"
    // should result in one visible entry and one hidden entries.
    verifySearchQueryResults(
        nearbyPrintersElement,
        [createPrinterListEntry(
            'google', 'printerAddress2', 'printerId2', PrinterType.DISCOVERED)],
        searchTerm);
    // Change search term to something that has no matches.
    searchTerm = 'noSearchFound';
    nearbyPrintersElement.searchTerm = searchTerm;
    flush();
    verifySearchQueryResults(nearbyPrintersElement, [], searchTerm);
    // Change search term back to "google" and verify that the No search found
    // message is no longer there.
    searchTerm = 'google';
    nearbyPrintersElement.searchTerm = searchTerm;
    flush();
    verifySearchQueryResults(
        nearbyPrintersElement,
        [createPrinterListEntry(
            'google', 'printerAddress2', 'printerId2', PrinterType.DISCOVERED)],
        searchTerm);
  });
});

suite('CupsEnterprisePrintersTests', () => {
  let page: SettingsCupsPrintersElement;
  let enterprisePrintersElement: SettingsCupsEnterprisePrintersElement;
  let printerEntryListTestElement: HTMLElement;
  let cupsPrintersBrowserProxy: TestCupsPrintersBrowserProxy;
  let printerList: CupsPrinterInfo[];

  setup(() => {
    cupsPrintersBrowserProxy = new TestCupsPrintersBrowserProxy();
    Router.getInstance().navigateTo(routes.CUPS_PRINTERS);
  });

  teardown(() => {
    cupsPrintersBrowserProxy.reset();
    page.remove();
    enterprisePrintersElement.remove();
  });


  function createCupsPrinterPage(printers: CupsPrinterInfo[]) {
    printerList = printers;
    // |cupsPrinterBrowserProxy| needs to have a list of printers before
    // initializing the landing page.
    cupsPrintersBrowserProxy.printerList = {printerList: printerList};
    CupsPrintersBrowserProxyImpl.setInstanceForTesting(
        cupsPrintersBrowserProxy);

    page = document.createElement('settings-cups-printers');
    document.body.appendChild(page);
    assertTrue(!!page);

    flush();
  }

  // Verifies that enterprise printers are correctly shown on the OS settings
  // page.
  test('EnterprisePrinters', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('test1', '1', 'id1', /*isManaged=*/ true),
      createCupsPrinterInfo('test2', '2', 'id2', /*isManaged=*/ true),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsEnterprisePrintersList');
    // Wait for saved printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-enterprise-printers');
    assertTrue(!!element);
    enterprisePrintersElement = element;
    const listElement =
        enterprisePrintersElement.shadowRoot!.querySelector<HTMLElement>(
            '#printerEntryList');
    assertTrue(!!listElement);
    printerEntryListTestElement = listElement;
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('test1', '1', 'id1', PrinterType.ENTERPRISE),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.ENTERPRISE),
    ]);
  });

  // Verifies that enterprise printers are not editable.
  test('EnterprisePrinterDialog', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('test1', '1', 'id1', true),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsEnterprisePrintersList');
    // Wait for enterprise printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-enterprise-printers');
    assertTrue(!!element);
    enterprisePrintersElement = element;
    const enterprisePrinterEntries:
        NodeListOf<SettingsCupsPrintersEntryElement> =
            getPrinterEntries(enterprisePrintersElement);
    // Users are not allowed to remove enterprise printers.
    const removeButton =
        enterprisePrintersElement.shadowRoot!.querySelector<HTMLButtonElement>(
            '#removeButton');
    assertTrue(!!removeButton);
    assertTrue(removeButton.disabled);
    const button = enterprisePrinterEntries[0]!.shadowRoot!
                       .querySelector<HTMLButtonElement>('.icon-more-vert');
    assertTrue(!!button);
    clickButton(button);
    const viewButton =
        enterprisePrintersElement.shadowRoot!.querySelector<HTMLButtonElement>(
            '#viewButton');
    assertTrue(!!viewButton);
    clickButton(viewButton);
    flush();
    const editDialog: SettingsCupsEditPrinterDialogElement =
        initializeEditDialog(page);
    const nameField = editDialog.shadowRoot!.querySelector<CrInputElement>(
        '.printer-name-input');
    assertTrue(!!nameField);
    assertEquals('test1', nameField.value);
    assertTrue(nameField.readonly);
    const printerAddress =
        editDialog.shadowRoot!.querySelector<CrInputElement>('#printerAddress');
    assertTrue(!!printerAddress);
    assertTrue(printerAddress.readonly);
    const selectElement =
        editDialog.shadowRoot!.querySelector<HTMLSelectElement>('.md-select');
    assertTrue(!!selectElement);
    assertTrue(selectElement.disabled);
    const printerQueue =
        editDialog.shadowRoot!.querySelector<CrInputElement>('#printerQueue');
    assertTrue(!!printerQueue);
    assertTrue(printerQueue.readonly);
    const printerPPDManufacturer =
        editDialog.shadowRoot!.querySelector<CrSearchableDropDownElement>(
            '#printerPPDManufacturer');
    assertTrue(!!printerPPDManufacturer);
    assertTrue(printerPPDManufacturer.readonly);
    // The "specify PDD" section should be hidden.
    const browseButton =
        editDialog.shadowRoot!.querySelector<HTMLButtonElement>(
            '.browse-button');
    assertTrue(!!browseButton);
    const parentElement = browseButton.parentElement;
    assertTrue(!!parentElement);
    assertTrue(parentElement.hidden);
    const ppdLabel =
        editDialog.shadowRoot!.querySelector<HTMLElement>('#ppdLabel');
    assertTrue(!!ppdLabel);
    assertTrue(ppdLabel.hidden);
    // Save and Cancel buttons should be hidden. Close button should be
    // visible.
    const cancelButton =
        editDialog.shadowRoot!.querySelector<HTMLButtonElement>(
            '.cancel-button');
    assertTrue(!!cancelButton);
    assertTrue(cancelButton.hidden);
    const actionButton =
        editDialog.shadowRoot!.querySelector<HTMLButtonElement>(
            '.action-button');
    assertTrue(!!actionButton);
    assertTrue(actionButton.hidden);
    const closeButton = editDialog.shadowRoot!.querySelector<HTMLButtonElement>(
        '.close-button');
    assertTrue(!!closeButton);
    assertFalse(closeButton.hidden);
  });

  test('PressShowMoreButton', async () => {
    createCupsPrinterPage([
      createCupsPrinterInfo('test1', '1', 'id1', true),
      createCupsPrinterInfo('test2', '2', 'id2', true),
      createCupsPrinterInfo('test3', '3', 'id3', true),
      createCupsPrinterInfo('test4', '4', 'id4', true),
    ]);
    await cupsPrintersBrowserProxy.whenCalled('getCupsEnterprisePrintersList');
    // Wait for enterprise printers to populate.
    flush();
    const element =
        page.shadowRoot!.querySelector('settings-cups-enterprise-printers');
    assertTrue(!!element);
    enterprisePrintersElement = element;
    const printerEntryListTestElement =
        enterprisePrintersElement.shadowRoot!.querySelector(
            '#printerEntryList');
    assertTrue(!!printerEntryListTestElement);
    // There are 4 total printers but only 3 printers are visible and 1 is
    // hidden underneath the Show more section.
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('test1', '1', 'id1', PrinterType.ENTERPRISE),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.ENTERPRISE),
      createPrinterListEntry('test3', '3', 'id3', PrinterType.ENTERPRISE),
    ]);
    // Assert that the Show more button is shown since printer list length
    // is > 3.
    assertTrue(!!enterprisePrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));

    const showMoreIcon =
        enterprisePrintersElement.shadowRoot!.querySelector<HTMLButtonElement>(
            '#show-more-icon');
    assertTrue(!!showMoreIcon);
    // Click on the Show more button.
    clickButton(showMoreIcon);
    assertNull(enterprisePrintersElement.shadowRoot!.querySelector(
        '#show-more-container'));
    // Clicking on the Show more button reveals all hidden printers.
    verifyVisiblePrinters(printerEntryListTestElement, [
      createPrinterListEntry('test1', '1', 'id1', PrinterType.ENTERPRISE),
      createPrinterListEntry('test2', '2', 'id2', PrinterType.ENTERPRISE),
      createPrinterListEntry('test3', '3', 'id3', PrinterType.ENTERPRISE),
      createPrinterListEntry('test4', '4', 'id4', PrinterType.ENTERPRISE),
    ]);
  });
});