Skip to content

Commit

Permalink
Button tests (shoelace-style#667)
Browse files Browse the repository at this point in the history
* initial button tests and setup helpers

* fix as many linting errors as I could

* switch back to regular fixtures

* test(button|button-group|divider|format-bytes) add tests for more components

* add tests for format util components

* finish format-number tests

* remove unnecessary ignore
  • Loading branch information
michaelwarren1106 authored Mar 11, 2022
1 parent 99e746b commit 3144c45
Show file tree
Hide file tree
Showing 7 changed files with 681 additions and 0 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ examples
node_modules
src/react
scripts

87 changes: 87 additions & 0 deletions src/components/button-group/button-group.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { expect, fixture, html, elementUpdated } from '@open-wc/testing';
import type SlButtonGroup from './button-group';

describe('<sl-button-group>', () => {

describe('defaults ', () => {
it('passes accessibility test', async () => {
const group = await fixture<SlButtonGroup>(html` <sl-button-group>
<sl-button>Button 1 Label</sl-button>
<sl-button>Button 2 Label</sl-button>
<sl-button>Button 3 Label</sl-button>
</sl-button-group> `);
await expect(group).to.be.accessible();
});

it('default label empty', async () => {
const group = await fixture<SlButtonGroup>(html` <sl-button-group>
<sl-button>Button 1 Label</sl-button>
<sl-button>Button 2 Label</sl-button>
<sl-button>Button 3 Label</sl-button>
</sl-button-group> `);
expect(group.label).to.equal('');
});
});

describe('slotted button classes', () => {

it('slotted buttons have the right classes applied based on their order', async () => {
const group = await fixture<SlButtonGroup>(html` <sl-button-group>
<sl-button>Button 1 Label</sl-button>
<sl-button>Button 2 Label</sl-button>
<sl-button>Button 3 Label</sl-button>
</sl-button-group> `);

const allButtons = group.querySelectorAll('sl-button');
const hasGroupClass = Array.from(allButtons).every((button) => button.classList.contains('sl-button-group__button'));
expect(hasGroupClass).to.be.true;

expect(allButtons[0]).to.have.class('sl-button-group__button--first');
expect(allButtons[1]).to.have.class('sl-button-group__button--inner');
expect(allButtons[2]).to.have.class('sl-button-group__button--last');

});
});

describe('focus and blur events', () => {
it('toggles focus class to slotted buttons on focus/blur', async () => {
const group = await fixture<SlButtonGroup>(html` <sl-button-group>
<sl-button>Button 1 Label</sl-button>
<sl-button>Button 2 Label</sl-button>
<sl-button>Button 3 Label</sl-button>
</sl-button-group> `);


const allButtons = group.querySelectorAll('sl-button');
allButtons[0].dispatchEvent(new FocusEvent('focusin', { bubbles: true }));

await elementUpdated(allButtons[0]);
expect(allButtons[0].classList.contains('sl-button-group__button--focus')).to.be.true;

allButtons[0].dispatchEvent(new FocusEvent('focusout', { bubbles: true }));
await elementUpdated(allButtons[0]);
expect(allButtons[0].classList.contains('sl-button-group__button--focus')).not.to.be.true;
});
});

describe('mouseover and mouseout events', () => {
it('toggles hover class to slotted buttons on mouseover/mouseout', async () => {
const group = await fixture<SlButtonGroup>(html` <sl-button-group>
<sl-button>Button 1 Label</sl-button>
<sl-button>Button 2 Label</sl-button>
<sl-button>Button 3 Label</sl-button>
</sl-button-group> `);

const allButtons = group.querySelectorAll('sl-button');

allButtons[0].dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
await elementUpdated(allButtons[0]);
expect(allButtons[0].classList.contains('sl-button-group__button--hover')).to.be.true;

allButtons[0].dispatchEvent(new MouseEvent('mouseout', { bubbles: true }));
await elementUpdated(allButtons[0]);
expect(allButtons[0].classList.contains('sl-button-group__button--hover')).not.to.be.true;
});
});

});
109 changes: 109 additions & 0 deletions src/components/button/button.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { expect, fixture, html } from '@open-wc/testing';
import sinon from 'sinon';
import type SlButton from './button';

describe('<sl-button>', () => {

describe('when provided no parameters', () => {

it('passes accessibility test', async () => {
const el = await fixture<SlButton>(html` <sl-button>Button Label</sl-button> `);
await expect(el).to.be.accessible();
});

it('default values are set correctly', async () => {
const el = await fixture<SlButton>(html` <sl-button>Button Label</sl-button> `);

expect(el.variant).to.equal('default');
expect(el.size).to.equal('medium');
expect(el.disabled).to.equal(false);
expect(el.caret).to.equal(false);
expect(el.loading).to.equal(false);
expect(el.outline).to.equal(false);
expect(el.pill).to.equal(false);
expect(el.circle).to.equal(false);
});

it('should render as a <button>', async () => {
const el = await fixture<SlButton>(html` <sl-button>Button Label</sl-button> `);
expect(el.shadowRoot!.querySelector('button')).to.exist;
expect(el.shadowRoot!.querySelector('a')).not.to.exist;
});

it('should not have a spinner present', async () => {
const el = await fixture<SlButton>(html` <sl-button>Button Label</sl-button> `);
expect(el.shadowRoot!.querySelector('sl-spinner')).not.to.exist;
});

it('should not have a caret present', async () => {
const el = await fixture<SlButton>(html` <sl-button>Button Label</sl-button> `);
expect(el.shadowRoot?.querySelector('[part="caret"]')).not .to.exist;
});
});

describe('when disabled', () => {

it('passes accessibility test', async () => {
const el = await fixture<SlButton>(html` <sl-button disabled>Button Label</sl-button> `);
await expect(el).to.be.accessible();
});

it('should disable the native <button> when rendering a <button>', async () => {
const el = await fixture<SlButton>(html` <sl-button disabled>Button Label</sl-button> `);
expect(el.shadowRoot!.querySelector('button[disabled]')).to.exist;
});

it('should not disable the native <a> when rendering an <a>', async () => {
const el = await fixture<SlButton>(html` <sl-button href="some/path" disabled>Button Label</sl-button> `);
expect(el.shadowRoot!.querySelector('a[disabled]')).not.to.exist;
});

it('should not bubble up clicks', async () => {
const button = await fixture<SlButton>(html` <sl-button disabled>Button Label</sl-button> `);
const handleClick = sinon.spy();
button.addEventListener('click', handleClick);
button.click();

expect(handleClick).not.to.have.been.called;

button.shadowRoot!.querySelector('button')!.click();
expect(handleClick).not.to.have.been.called;

const buttonLink = await fixture<SlButton>(html` <sl-button href="some/path" disabled>Button Label</sl-button> `);
buttonLink.addEventListener('click', handleClick);
buttonLink.click();

expect(handleClick).not.to.have.been.called;

buttonLink.shadowRoot!.querySelector('a')!.click();
expect(handleClick).not.to.have.been.called;
});
});

describe('when loading', () => {

it('should have a spinner present', async () => {
const el = await fixture<SlButton>(html` <sl-button loading>Button Label</sl-button> `);
expect(el.shadowRoot!.querySelector('sl-spinner')).to.exist;
});

});

describe('when caret', () => {

it('should have a caret present', async () => {
const el = await fixture<SlButton>(html` <sl-button caret>Button Label</sl-button> `);
expect(el.shadowRoot!.querySelector('[part="caret"]')).to.exist;
});

});

describe('when href is present', () => {

it('should render as an <a>', async () => {
const el = await fixture<SlButton>(html` <sl-button href="some/path">Button Label</sl-button> `);
expect(el.shadowRoot!.querySelector('a')).to.exist;
expect(el.shadowRoot!.querySelector('button')).not.to.exist;
});
});
});
36 changes: 36 additions & 0 deletions src/components/divider/divider.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
import type SlDivider from './divider';

describe('<sl-divider>', () => {

describe('defaults ', () => {
it('passes accessibility test', async () => {
const el = await fixture<SlDivider>(html` <sl-divider></sl-divider> `);
await expect(el).to.be.accessible();
});

it('default properties', async () => {
const el = await fixture<SlDivider>(html` <sl-divider></sl-divider> `);

expect(el.vertical).to.be.false;
expect(el.getAttribute('role')).to.equal('separator');
expect(el.getAttribute('aria-orientation')).to.equal('horizontal');
});
});

describe('vertical property change ', () => {

it('aria-orientation is updated', async () => {
const el = await fixture<SlDivider>(html` <sl-divider></sl-divider> `);

el.vertical = true;
await elementUpdated(el);

expect(el.getAttribute('aria-orientation')).to.equal('vertical');
});
});




});
125 changes: 125 additions & 0 deletions src/components/format-bytes/format-bytes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { expect, fixture, html, elementUpdated } from '@open-wc/testing';
import type SlFormatBytes from './format-bytes';

describe('<sl-format-bytes>', () => {

describe('defaults ', () => {

it('default properties', async () => {
const el = await fixture<SlFormatBytes>(html` <sl-format-bytes></sl-format-bytes> `);

expect(el.value).to.equal(0);
expect(el.unit).to.equal('byte');
expect(el.display).to.equal('short');
expect(el.lang).to.be.undefined;
});
});

describe('bytes', () => {

const results = [
{
value: 12,
short: '12 byte',
long: '12 bytes',
narrow: '12B',
},
{
value: 1200,
short: '1.2 kB',
long: '1.2 kilobytes',
narrow: '1.2kB',
},
{
value: 1200000,
short: '1.2 MB',
long: '1.2 megabytes',
narrow: '1.2MB',
},
{
value: 1200000000,
short: '1.2 GB',
long: '1.2 gigabytes',
narrow: '1.2GB',
}
];


results.forEach((expected) => {
it('bytes : display formats', async () => {
const el = await fixture<SlFormatBytes>(html` <sl-format-bytes></sl-format-bytes> `);
// short
el.value = expected.value;
await elementUpdated(el);
expect(el.shadowRoot?.textContent).to.equal(expected.short);

// long
el.display = 'long';
el.value = expected.value;
await elementUpdated(el);
expect(el.shadowRoot?.textContent).to.equal(expected.long);

// narrow
el.display = 'narrow';
el.value = expected.value;
await elementUpdated(el);
expect(el.shadowRoot?.textContent).to.equal(expected.narrow);
});
});

});

describe('bits', () => {
const results = [
{
value: 12,
short: '12 bit',
long: '12 bits',
narrow: '12bit',
},
{
value: 1200,
short: '1.2 kb',
long: '1.2 kilobits',
narrow: '1.2kb',
},
{
value: 1200000,
short: '1.2 Mb',
long: '1.2 megabits',
narrow: '1.2Mb',
},
{
value: 1200000000,
short: '1.2 Gb',
long: '1.2 gigabits',
narrow: '1.2Gb',
}
];


results.forEach((expected) => {
it('bits : display formats', async () => {
const el = await fixture<SlFormatBytes>(html` <sl-format-bytes unit="bit"></sl-format-bytes> `);
// short
el.value = expected.value;
await elementUpdated(el);
expect(el.shadowRoot?.textContent).to.equal(expected.short);

// long
el.display = 'long';
el.value = expected.value;
await elementUpdated(el);
expect(el.shadowRoot?.textContent).to.equal(expected.long);

// narrow
el.display = 'narrow';
el.value = expected.value;
await elementUpdated(el);
expect(el.shadowRoot?.textContent).to.equal(expected.narrow);
});
});

});

});
Loading

0 comments on commit 3144c45

Please sign in to comment.