chromium/chrome/test/data/webui/chromeos/ash_common/cr_elements/cr_tabs_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.

// clang-format off
import 'chrome://resources/ash/common/cr_elements/cr_tabs/cr_tabs.js';

import {CrTabsElement} from 'chrome://resources/ash/common/cr_elements/cr_tabs/cr_tabs.js';
import {keyDownOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
import {assertEquals, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
import {eventToPromise} from 'chrome://webui-test/test_util.js';
import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
// clang-format on

suite('cr_tabs_test', function() {
  let tabs: CrTabsElement;

  setup(() => {
    document.body.innerHTML = window.trustedTypes!.emptyHTML;
    tabs = document.createElement('cr-tabs');
    tabs.tabNames = ['tab1', 'tab2', 'tab3'];
    tabs.tabIcons = ['chrome://icon1.png'];
    document.body.appendChild(tabs);
    return flushTasks();
  });

  function getTabElement(index: number): HTMLElement {
    return tabs.shadowRoot!.querySelector(`.tab:nth-of-type(${index + 1})`)!;
  }

  async function checkUiChange(
      uiChange: Function, initialSelection: number, expectedSelection: number) {
    tabs.selected = initialSelection;
    if (initialSelection === expectedSelection) {
      uiChange();
    } else {
      const wait = eventToPromise('selected-changed', tabs);
      uiChange();
      await wait;
    }
    assertEquals(expectedSelection, tabs.selected);
    const tabElement = getTabElement(expectedSelection);
    assertTrue(!!tabElement);
    assertTrue(tabElement.classList.contains('selected'));
    assertEquals('0', tabElement.getAttribute('tabindex'));
    const notSelected =
        tabs.shadowRoot!.querySelectorAll('.tab:not(.selected)');
    assertEquals(2, notSelected.length);
    notSelected.forEach(tab => {
      assertEquals('-1', tab.getAttribute('tabindex'));
    });
  }

  async function checkKey(
      key: string, initialSelection: number, expectedSelection: number) {
    await checkUiChange(
        () => keyDownOn(tabs, 0, [], key), initialSelection, expectedSelection);
  }

  async function checkClickTab(
      initialSelection: number, expectedSelection: number) {
    await checkUiChange(
        () => getTabElement(expectedSelection).click(), initialSelection,
        expectedSelection);
  }

  test('check CSS classes, aria-selected and tabindex for a tab', () => {
    const tab = getTabElement(0);
    assertEquals(1, tab.classList.length);
    assertEquals('false', tab.getAttribute('aria-selected'));
    assertEquals('-1', tab.getAttribute('tabindex'));
    tabs.selected = 0;
    assertEquals(2, tab.classList.length);
    assertTrue(tab.classList.contains('selected'));
    assertEquals('true', tab.getAttribute('aria-selected'));
    assertEquals('0', tab.getAttribute('tabindex'));
    tabs.selected = 1;
    assertEquals(1, tab.classList.length);
    assertEquals('false', tab.getAttribute('aria-selected'));
    assertEquals('-1', tab.getAttribute('tabindex'));
  });

  test('tab icons are optional', () => {
    const tab0 = getTabElement(0);
    const tabIcon0 = tab0.querySelector('.tab-icon')!;
    assertNotEquals('none', getComputedStyle(tabIcon0).display);

    const tab1 = getTabElement(1);
    const tabIcon1 = tab1.querySelector('.tab-icon')!;
    assertEquals('none', getComputedStyle(tabIcon1).display);
  });

  test('right/left pressed, selection changes and event fires', async () => {
    await checkKey('ArrowRight', 0, 1);
    await checkKey('ArrowRight', 1, 2);
    // Check that the selection wraps.
    await checkKey('ArrowRight', 2, 0);

    await checkKey('ArrowLeft', 2, 1);
    await checkKey('ArrowLeft', 1, 0);
    // Check that the selection wraps.
    await checkKey('ArrowLeft', 0, 2);

    await checkKey('Home', 0, 0);
    await checkKey('Home', 1, 0);
    await checkKey('Home', 2, 0);
    await checkKey('End', 0, 2);
    await checkKey('End', 1, 2);
    await checkKey('End', 2, 2);
  });

  test('clicking on tabs, selection changes and event fires', async () => {
    await checkClickTab(0, 0);
    await checkClickTab(1, 0);
    await checkClickTab(2, 0);
    await checkClickTab(0, 1);
    await checkClickTab(1, 1);
    await checkClickTab(2, 1);
    await checkClickTab(0, 2);
    await checkClickTab(1, 2);
    await checkClickTab(2, 2);
  });
});