Files
webawesome/src/components/button/button.test.ts

269 lines
9.9 KiB
TypeScript
Raw Normal View History

2023-09-08 13:45:49 -04:00
import '../../../dist/webawesome.js';
2022-04-19 09:30:17 -04:00
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
2023-06-22 10:56:24 -04:00
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests.js';
import sinon from 'sinon';
2023-09-08 13:45:49 -04:00
import type WaButton from './button.js';
2023-09-05 12:01:19 -04:00
const variants = ['brand', 'success', 'neutral', 'warning', 'danger'];
2022-03-24 08:03:14 -04:00
2023-09-08 13:45:49 -04:00
describe('<wa-button>', () => {
2022-03-24 08:03:14 -04:00
describe('accessibility tests', () => {
variants.forEach(variant => {
it(`should be accessible when variant is "${variant}"`, async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button variant="${variant}"> Button Label </wa-button> `);
2022-03-24 08:03:14 -04:00
await expect(el).to.be.accessible();
});
});
});
2022-03-24 07:48:03 -04:00
describe('when provided no parameters', () => {
it('passes accessibility test', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button>Button Label</wa-button> `);
2022-03-24 07:48:03 -04:00
await expect(el).to.be.accessible();
});
it('default values are set correctly', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button>Button Label</wa-button> `);
expect(el.title).to.equal('');
2023-09-08 13:45:49 -04:00
expect(el.variant).to.equal('neutral');
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);
});
it('should render as a <button>', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button>Button Label</wa-button> `);
expect(el.shadowRoot!.querySelector('button')).to.exist;
expect(el.shadowRoot!.querySelector('a')).not.to.exist;
});
it('should not have a spinner present', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button>Button Label</wa-button> `);
expect(el.shadowRoot!.querySelector('wa-spinner')).not.to.exist;
});
it('should not have a caret present', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button>Button Label</wa-button> `);
2022-11-17 09:35:44 -05:00
expect(el.shadowRoot?.querySelector('[part~="caret"]')).not.to.exist;
});
});
describe('when disabled', () => {
it('passes accessibility test', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button disabled>Button Label</wa-button> `);
await expect(el).to.be.accessible();
});
it('should disable the native <button> when rendering a <button>', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button disabled>Button Label</wa-button> `);
expect(el.shadowRoot!.querySelector('button[disabled]')).to.exist;
});
it('should not disable the native <a> when rendering an <a>', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button href="some/path" disabled>Button Label</wa-button> `);
expect(el.shadowRoot!.querySelector('a[disabled]')).not.to.exist;
});
});
2022-11-30 15:43:36 -05:00
it('should have title if title attribute is set', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button title="Test"></wa-button> `);
const button = el.shadowRoot!.querySelector<HTMLButtonElement>('[part~="base"]')!;
expect(button.title).to.equal('Test');
});
describe('when loading', () => {
it('should have a spinner present', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button loading>Button Label</wa-button> `);
expect(el.shadowRoot!.querySelector('wa-spinner')).to.exist;
});
});
describe('when caret', () => {
it('should have a caret present', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button caret>Button Label</wa-button> `);
2022-11-17 09:35:44 -05:00
expect(el.shadowRoot!.querySelector('[part~="caret"]')).to.exist;
});
});
describe('when href is present', () => {
it('should render as an <a>', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button href="some/path">Button Label</wa-button> `);
expect(el.shadowRoot!.querySelector('a')).to.exist;
expect(el.shadowRoot!.querySelector('button')).not.to.exist;
});
2023-02-16 12:15:59 -05:00
it('should render a link with rel="noreferrer noopener" when target is set and rel is not', async () => {
2023-10-12 15:03:38 -04:00
const el = await fixture<WaButton>(html`
<wa-button href="https://example.com/" target="_blank">Link</wa-button>
`);
2023-02-16 12:15:59 -05:00
const link = el.shadowRoot!.querySelector('a')!;
expect(link?.getAttribute('rel')).to.equal('noreferrer noopener');
});
it('should render a link with rel="" when a target is provided and rel is empty', async () => {
2023-10-12 15:03:38 -04:00
const el = await fixture<WaButton>(html`
<wa-button href="https://example.com/" target="_blank" rel="">Link</wa-button>
`);
2023-02-16 12:15:59 -05:00
const link = el.shadowRoot!.querySelector('a')!;
expect(link?.getAttribute('rel')).to.equal('');
});
it(`should render a link with a custom rel when a custom rel is provided`, async () => {
2023-10-12 15:03:38 -04:00
const el = await fixture<WaButton>(html`
<wa-button href="https://example.com/" target="_blank" rel="1">Link</wa-button>
`);
2023-02-16 12:15:59 -05:00
const link = el.shadowRoot!.querySelector('a')!;
expect(link?.getAttribute('rel')).to.equal('1');
});
});
2022-03-11 11:28:34 -05:00
describe('when submitting a form', () => {
it('should submit when the button is inside the form', async () => {
const form = await fixture<HTMLFormElement>(html`
2022-09-21 10:30:23 -04:00
<form action="" method="post">
2023-09-08 13:45:49 -04:00
<wa-button type="submit">Submit</wa-button>
2022-03-11 11:28:34 -05:00
</form>
`);
2023-09-08 13:45:49 -04:00
const button = form.querySelector<WaButton>('wa-button')!;
2022-03-11 11:28:34 -05:00
const handleSubmit = sinon.spy((event: SubmitEvent) => event.preventDefault());
form.addEventListener('submit', handleSubmit);
button.click();
expect(handleSubmit).to.have.been.calledOnce;
});
it('should submit when the button is outside the form and has a form attribute', async () => {
const el = await fixture(html`
<div>
2022-09-21 10:30:23 -04:00
<form id="a" action="" method="post"></form>
2023-09-08 13:45:49 -04:00
<wa-button type="submit" form="a">Submit</wa-button>
2022-03-11 11:28:34 -05:00
</div>
`);
const form = el.querySelector<HTMLFormElement>('form')!;
2023-09-08 13:45:49 -04:00
const button = el.querySelector<WaButton>('wa-button')!;
2022-03-11 11:28:34 -05:00
const handleSubmit = sinon.spy((event: SubmitEvent) => event.preventDefault());
form.addEventListener('submit', handleSubmit);
button.click();
expect(handleSubmit).to.have.been.calledOnce;
});
it('should override form attributes when formaction, formmethod, formnovalidate, and formtarget are used inside a form', async () => {
const form = await fixture(html`
2022-09-21 10:30:23 -04:00
<form id="a" action="foo" method="post" target="_self">
2023-09-08 13:45:49 -04:00
<wa-button type="submit" form="a" formaction="bar" formmethod="get" formtarget="_blank" formnovalidate>
2022-03-11 11:28:34 -05:00
Submit
2023-09-08 13:45:49 -04:00
</wa-button>
2022-03-11 11:28:34 -05:00
</form>
`);
2023-09-08 13:45:49 -04:00
const button = form.querySelector<WaButton>('wa-button')!;
2022-03-11 11:28:34 -05:00
const handleSubmit = sinon.spy((event: SubmitEvent) => {
submitter = event.submitter as HTMLButtonElement;
event.preventDefault();
});
let submitter!: HTMLButtonElement;
form.addEventListener('submit', handleSubmit);
button.click();
expect(handleSubmit).to.have.been.calledOnce;
expect(submitter.formAction.endsWith('/bar')).to.be.true;
expect(submitter.formMethod).to.equal('get');
expect(submitter.formTarget).to.equal('_blank');
expect(submitter.formNoValidate).to.be.true;
});
it('should override form attributes when formaction, formmethod, formnovalidate, and formtarget are used outside a form', async () => {
const el = await fixture(html`
<div>
2022-09-21 10:30:23 -04:00
<form id="a" action="foo" method="post" target="_self"></form>
2023-09-08 13:45:49 -04:00
<wa-button type="submit" form="a" formaction="bar" formmethod="get" formtarget="_blank" formnovalidate>
2022-03-11 11:28:34 -05:00
Submit
2023-09-08 13:45:49 -04:00
</wa-button>
2022-03-11 11:28:34 -05:00
</div>
`);
const form = el.querySelector<HTMLFormElement>('form')!;
2023-09-08 13:45:49 -04:00
const button = el.querySelector<WaButton>('wa-button')!;
2022-03-11 11:28:34 -05:00
const handleSubmit = sinon.spy((event: SubmitEvent) => {
submitter = event.submitter as HTMLButtonElement;
event.preventDefault();
});
let submitter!: HTMLButtonElement;
form.addEventListener('submit', handleSubmit);
button.click();
expect(handleSubmit).to.have.been.calledOnce;
expect(submitter.formAction.endsWith('/bar')).to.be.true;
expect(submitter.formMethod).to.equal('get');
expect(submitter.formTarget).to.equal('_blank');
expect(submitter.formNoValidate).to.be.true;
});
});
2022-04-19 09:30:17 -04:00
describe('when using methods', () => {
2023-09-08 13:45:49 -04:00
it('should emit wa-focus and wa-blur when the button is focused and blurred', async () => {
const el = await fixture<WaButton>(html` <wa-button>Button</wa-button> `);
2022-04-19 09:30:17 -04:00
const focusHandler = sinon.spy();
const blurHandler = sinon.spy();
2023-09-08 13:45:49 -04:00
el.addEventListener('wa-focus', focusHandler);
el.addEventListener('wa-blur', blurHandler);
2022-04-19 09:30:17 -04:00
el.focus();
await waitUntil(() => focusHandler.calledOnce);
el.blur();
await waitUntil(() => blurHandler.calledOnce);
expect(focusHandler).to.have.been.calledOnce;
expect(blurHandler).to.have.been.calledOnce;
});
it('should emit a click event when calling click()', async () => {
2023-09-08 13:45:49 -04:00
const el = await fixture<WaButton>(html` <wa-button></wa-button> `);
2022-04-19 09:30:17 -04:00
const clickHandler = sinon.spy();
el.addEventListener('click', clickHandler);
el.click();
await waitUntil(() => clickHandler.calledOnce);
expect(clickHandler).to.have.been.calledOnce;
});
});
runFormControlBaseTests({
2023-09-08 13:45:49 -04:00
tagName: 'wa-button',
variantName: 'type="button"',
2023-09-08 13:45:49 -04:00
init: (control: WaButton) => {
control.type = 'button';
}
});
runFormControlBaseTests({
2023-09-08 13:45:49 -04:00
tagName: 'wa-button',
variantName: 'type="submit"',
2023-09-08 13:45:49 -04:00
init: (control: WaButton) => {
control.type = 'submit';
}
});
runFormControlBaseTests({
2023-09-08 13:45:49 -04:00
tagName: 'wa-button',
variantName: 'href="xyz"',
2023-09-08 13:45:49 -04:00
init: (control: WaButton) => {
control.href = 'some-url';
}
});
});