chrome-devtools-frontend
Version:
Chrome DevTools UI
269 lines (229 loc) • 8.21 kB
text/typescript
// Copyright 2021 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.
import {dispatchKeyDownEvent, renderElementIntoDOM} from '../../../testing/DOMHelpers.js';
import * as Buttons from './buttons.js';
describe('Button', () => {
const iconName = 'file-image';
function renderButton(
data: Buttons.Button.ButtonData = {
variant: Buttons.Button.Variant.PRIMARY,
},
text = 'Button'): Buttons.Button.Button {
const button = new Buttons.Button.Button();
button.data = data;
// Toolbar and round buttons do not take text, and error if you try to set any.
if (data.variant !== Buttons.Button.Variant.TOOLBAR && data.variant !== Buttons.Button.Variant.ICON) {
button.innerText = text;
}
renderElementIntoDOM(button);
return button;
}
function testClick(
data: Buttons.Button.ButtonData = {
variant: Buttons.Button.Variant.PRIMARY,
disabled: false,
},
expectedClickCount = 1): void {
const button = renderButton(data);
let clicks = 0;
button.onclick = () => clicks++;
const innerButton = button.shadowRoot?.querySelector('button') as HTMLButtonElement;
assert.instanceOf(innerButton, HTMLButtonElement);
innerButton.click();
dispatchKeyDownEvent(innerButton, {
key: 'Enter',
});
assert.strictEqual(clicks, expectedClickCount);
}
it('changes to `disabled` state are reflect in the property', () => {
const button = renderButton();
button.disabled = false;
assert.isFalse(button.disabled);
button.disabled = true;
assert.isTrue(button.disabled);
});
describe('focus', () => {
it('correctly focuses the <button> element in the shadow DOM', () => {
const button = renderButton();
button.focus();
assert.isTrue(button.shadowRoot!.querySelector('button')!.hasFocus());
});
});
describe('hasFocus', () => {
it('correctly reflects the focus state of the button', () => {
const button = renderButton();
button.focus();
assert.isTrue(button.hasFocus());
});
});
it('primary button can be clicked', () => {
testClick({
variant: Buttons.Button.Variant.PRIMARY,
});
});
it('disabled primary button cannot be clicked', () => {
testClick(
{
variant: Buttons.Button.Variant.PRIMARY,
disabled: true,
},
0);
});
it('secondary button can be clicked', () => {
testClick({
variant: Buttons.Button.Variant.OUTLINED,
});
});
it('disabled secondary button cannot be clicked', () => {
testClick(
{
variant: Buttons.Button.Variant.OUTLINED,
disabled: true,
},
0);
});
it('toolbar button can be clicked', () => {
testClick({
variant: Buttons.Button.Variant.TOOLBAR,
iconName,
});
});
it('disabled toolbar button cannot be clicked', () => {
testClick(
{
variant: Buttons.Button.Variant.TOOLBAR,
iconName,
disabled: true,
},
0);
});
it('gets the no additional classes set for the inner button if only text is provided', () => {
const button = renderButton();
const innerButton = button.shadowRoot?.querySelector('button') as HTMLButtonElement;
assert.isNotOk(innerButton.classList.contains('text-with-icon'));
assert.isNotOk(innerButton.classList.contains('only-icon'));
});
it('gets title set', () => {
const button = renderButton({
variant: Buttons.Button.Variant.PRIMARY,
title: 'Custom',
});
const innerButton = button.shadowRoot?.querySelector('button') as HTMLButtonElement;
assert.strictEqual(innerButton.title, 'Custom');
button.title = 'Custom2';
assert.strictEqual(innerButton.title, 'Custom2');
});
it('gets the text-with-icon class set for the inner button if text and icon is provided', () => {
const button = renderButton(
{
variant: Buttons.Button.Variant.PRIMARY,
iconName,
},
'text');
const innerButton = button.shadowRoot?.querySelector('button') as HTMLButtonElement;
assert.isTrue(innerButton.classList.contains('text-with-icon'));
assert.isNotOk(innerButton.classList.contains('only-icon'));
});
it('gets the only-icon class set for the inner button if only icon is provided', () => {
const button = renderButton(
{
variant: Buttons.Button.Variant.PRIMARY,
iconName,
},
'');
const innerButton = button.shadowRoot?.querySelector('button') as HTMLButtonElement;
assert.isNotOk(innerButton.classList.contains('text-with-icon'));
assert.isTrue(innerButton.classList.contains('only-icon'));
});
it('gets the `small` class set for the inner button if size === SMALL', () => {
const button = renderButton(
{
variant: Buttons.Button.Variant.PRIMARY,
size: Buttons.Button.Size.SMALL,
},
'');
const innerButton = button.shadowRoot?.querySelector('button') as HTMLButtonElement;
assert.isTrue(innerButton.classList.contains('small'));
});
it('does not get the `small` class set for the inner button if size === MEDIUM', () => {
const button = renderButton(
{
variant: Buttons.Button.Variant.PRIMARY,
iconName,
},
'');
const innerButton = button.shadowRoot?.querySelector('button') as HTMLButtonElement;
assert.isFalse(innerButton.classList.contains('small'));
});
it('devtools-button width should not expand its content\'s width', () => {
const button = new Buttons.Button.Button();
button.data = {variant: Buttons.Button.Variant.PRIMARY};
button.textContent = 'test';
const fullWidthContainer = document.createElement('div');
fullWidthContainer.style.width = '400px';
fullWidthContainer.style.height = '400px';
fullWidthContainer.style.display = 'flex';
fullWidthContainer.style.flexDirection = 'column';
fullWidthContainer.appendChild(button);
renderElementIntoDOM(fullWidthContainer);
const buttonWidth = button.getBoundingClientRect().width;
const fullWidthContainerWidth = fullWidthContainer.getBoundingClientRect().width;
assert.isBelow(buttonWidth, fullWidthContainerWidth);
assert.isAbove(buttonWidth, 0);
const buttonHeight = button.getBoundingClientRect().height;
const bigContainerHeight = fullWidthContainer.getBoundingClientRect().height;
assert.isBelow(buttonHeight, bigContainerHeight);
assert.isAbove(buttonHeight, 0);
});
describe('in forms', () => {
function renderForm(data: Buttons.Button.ButtonData = {
variant: Buttons.Button.Variant.PRIMARY,
}) {
const form = document.createElement('form');
const input = document.createElement('input');
const button = new Buttons.Button.Button();
const reference = {
submitCount: 0,
form,
button,
input,
};
form.onsubmit = (event: Event) => {
event.preventDefault();
reference.submitCount++;
};
button.data = data;
button.innerText = 'button';
form.append(input);
form.append(button);
renderElementIntoDOM(form);
return reference;
}
it('submits a form with button[type=submit]', () => {
const state = renderForm({
variant: Buttons.Button.Variant.PRIMARY,
type: 'submit',
});
state.button.click();
assert.strictEqual(state.submitCount, 1);
});
it('does not submit a form with button[type=button]', () => {
const state = renderForm({
variant: Buttons.Button.Variant.PRIMARY,
type: 'button',
});
state.button.click();
assert.strictEqual(state.submitCount, 0);
});
it('resets a form with button[type=reset]', () => {
const state = renderForm({
variant: Buttons.Button.Variant.PRIMARY,
type: 'reset',
});
state.input.value = 'test';
state.button.click();
assert.strictEqual(state.input.value, '');
});
});
});