blob: 79a05df1f2b576eafc2f72a1ccd5f6a4d2422b43 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// 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/cr_elements/cr_icon_button/cr_icon_button.m.js';
import 'chrome://resources/cr_elements/icons.m.js';
import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
import {downAndUp, pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
import {eventToPromise, flushTasks} from 'chrome://webui-test/test_util.js';
// clang-format on
suite('cr-icon-button', function() {
let button: CrIconButtonElement;
function press(key: string) {
button.dispatchEvent(new KeyboardEvent('keydown', {key}));
button.dispatchEvent(new KeyboardEvent('keyup', {key}));
}
setup(async () => {
document.body.innerHTML = '';
button = document.createElement('cr-icon-button');
document.body.appendChild(button);
await flushTasks();
});
test('enabled/disabled', () => {
assertEquals('0', button.getAttribute('tabindex'));
assertEquals('false', button.getAttribute('aria-disabled'));
button.disabled = true;
assertEquals('-1', button.getAttribute('tabindex'));
assertEquals('true', button.getAttribute('aria-disabled'));
});
test('iron-icon is created, reused and removed based on |ironIcon|', () => {
assertFalse(!!button.shadowRoot!.querySelector('iron-icon'));
button.ironIcon = 'icon-key';
assertTrue(!!button.shadowRoot!.querySelector('iron-icon'));
button.shadowRoot!.querySelector('iron-icon')!.icon = 'icon-key';
button.ironIcon = 'another-icon-key';
assertEquals(1, button.shadowRoot!.querySelectorAll('iron-icon').length);
button.shadowRoot!.querySelector('iron-icon')!.icon = 'another-icon-key';
button.ironIcon = '';
assertFalse(!!button.shadowRoot!.querySelector('iron-icon'));
});
test('iron-icon children svg and img elements have role set to none', () => {
button.ironIcon = 'cr:clear';
assertTrue(!!button.shadowRoot);
const ironIcons = button.shadowRoot!.querySelectorAll('iron-icon');
assertEquals(1, ironIcons.length);
const iconChildren = ironIcons[0]!.shadowRoot!.querySelectorAll('svg, img');
assertEquals(1, iconChildren.length);
assertEquals(iconChildren[0]!.getAttribute('role'), 'none');
});
test('enter emits click event', async () => {
const wait = eventToPromise('click', button);
pressAndReleaseKeyOn(button, -1, [], 'Enter');
await wait;
});
test('space emits click event', async () => {
const wait = eventToPromise('click', button);
pressAndReleaseKeyOn(button, -1, [], ' ');
await wait;
});
test('space up does not click without space down', () => {
let clicked = false;
button.addEventListener('click', () => {
clicked = true;
}, {once: true});
button.dispatchEvent(new KeyboardEvent('keyup', {key: ' '}));
assertFalse(clicked);
press(' ');
assertTrue(clicked);
});
test('space up events will not result in one click if loses focus', () => {
let clicked = false;
button.addEventListener('click', () => {
clicked = true;
}, {once: true});
button.dispatchEvent(new KeyboardEvent('keydown', {key: ' '}));
button.dispatchEvent(new Event('blur'));
button.dispatchEvent(new KeyboardEvent('keyup', {key: ' '}));
assertFalse(clicked);
press(' ');
assertTrue(clicked);
});
test('disabled prevents UI and programmatic clicks', async () => {
let clickCount = 0;
const clickHandler = () => {
clickCount++;
};
button.addEventListener('click', clickHandler);
button.disabled = true;
await flushTasks();
pressAndReleaseKeyOn(button, -1, [], 'Enter');
pressAndReleaseKeyOn(button, -1, [], ' ');
downAndUp(button);
button.click();
await flushTasks();
assertEquals(0, clickCount);
button.disabled = false;
await flushTasks();
pressAndReleaseKeyOn(button, -1, [], 'Enter');
pressAndReleaseKeyOn(button, -1, [], ' ');
downAndUp(button);
button.click();
await flushTasks();
assertEquals(4, clickCount);
button.removeEventListener('click', clickHandler);
});
test('when tabindex is -1, it stays -1', async () => {
document.body.innerHTML =
'<cr-icon-button custom-tab-index="-1"></cr-icon-button>';
await flushTasks();
button = document.body.querySelector('cr-icon-button')!;
assertEquals('-1', button.getAttribute('tabindex'));
button.disabled = true;
assertEquals('-1', button.getAttribute('tabindex'));
button.disabled = false;
assertEquals('-1', button.getAttribute('tabindex'));
});
test('tabindex update', async () => {
document.body.innerHTML = '<cr-icon-button></cr-icon-button>';
button = document.body.querySelector('cr-icon-button')!;
assertEquals('0', button.getAttribute('tabindex'));
button.customTabIndex = 1;
assertEquals('1', button.getAttribute('tabindex'));
});
test('multiple iron icons', () => {
button.ironIcon = 'icon1,icon2';
const elements = button.shadowRoot!.querySelectorAll('iron-icon');
assertEquals(2, elements.length);
assertEquals('icon1', elements[0]!.icon);
assertEquals('icon2', elements[1]!.icon);
});
});