mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 04:09:12 +00:00
add validation tests; fixes #1065
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { aTimeout, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
|
||||
import { expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
|
||||
import { sendKeys } from '@web/test-runner-commands';
|
||||
import sinon from 'sinon';
|
||||
import { clickOnElement } from '../../internal/test';
|
||||
import type SlCheckbox from './checkbox';
|
||||
|
||||
describe('<sl-checkbox>', () => {
|
||||
@@ -48,8 +49,7 @@ describe('<sl-checkbox>', () => {
|
||||
|
||||
it('should be valid by default', async () => {
|
||||
const el = await fixture<SlCheckbox>(html` <sl-checkbox></sl-checkbox> `);
|
||||
|
||||
expect(el.invalid).to.be.false;
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
});
|
||||
|
||||
it('should emit sl-change and sl-input when clicked', async () => {
|
||||
@@ -139,25 +139,35 @@ describe('<sl-checkbox>', () => {
|
||||
expect(formData!.get('a')).to.equal('on');
|
||||
});
|
||||
|
||||
it('should show a constraint validation error when setCustomValidity() is called', async () => {
|
||||
const form = await fixture<HTMLFormElement>(html`
|
||||
<form>
|
||||
<sl-checkbox name="a" value="1" checked></sl-checkbox>
|
||||
<sl-button type="submit">Submit</sl-button>
|
||||
</form>
|
||||
`);
|
||||
const button = form.querySelector('sl-button')!;
|
||||
const checkbox = form.querySelector('sl-checkbox')!;
|
||||
const submitHandler = sinon.spy((event: SubmitEvent) => event.preventDefault());
|
||||
it('should be invalid when setCustomValidity() is called with a non-empty value', async () => {
|
||||
const checkbox = await fixture<HTMLFormElement>(html` <sl-checkbox></sl-checkbox> `);
|
||||
|
||||
// Submitting the form after setting custom validity should not trigger the handler
|
||||
checkbox.setCustomValidity('Invalid selection');
|
||||
form.addEventListener('submit', submitHandler);
|
||||
button.click();
|
||||
await checkbox.updateComplete;
|
||||
|
||||
await aTimeout(100);
|
||||
expect(checkbox.checkValidity()).to.be.false;
|
||||
expect(checkbox.checkValidity()).to.be.false;
|
||||
expect(checkbox.hasAttribute('data-invalid')).to.be.true;
|
||||
expect(checkbox.hasAttribute('data-valid')).to.be.false;
|
||||
expect(checkbox.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(checkbox.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
expect(submitHandler).to.not.have.been.called;
|
||||
await clickOnElement(checkbox);
|
||||
await checkbox.updateComplete;
|
||||
|
||||
expect(checkbox.hasAttribute('data-user-invalid')).to.be.true;
|
||||
expect(checkbox.hasAttribute('data-user-valid')).to.be.false;
|
||||
});
|
||||
|
||||
it('should be invalid when required and unchecked', async () => {
|
||||
const checkbox = await fixture<HTMLFormElement>(html` <sl-checkbox required></sl-checkbox> `);
|
||||
expect(checkbox.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should be valid when required and checked', async () => {
|
||||
const checkbox = await fixture<HTMLFormElement>(html` <sl-checkbox required checked></sl-checkbox> `);
|
||||
expect(checkbox.checkValidity()).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -352,4 +352,62 @@ describe('<sl-color-picker>', () => {
|
||||
expect(colorPicker.value).to.equal('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using constraint validation', () => {
|
||||
it('should be valid by default', async () => {
|
||||
const el = await fixture<SlColorPicker>(html` <sl-color-picker></sl-color-picker> `);
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
});
|
||||
|
||||
it('should be invalid when required and empty', async () => {
|
||||
const el = await fixture<SlColorPicker>(html` <sl-input required></sl-input> `);
|
||||
expect(el.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should be invalid when required and disabled is removed', async () => {
|
||||
const el = await fixture<SlColorPicker>(html` <sl-input disabled required></sl-input> `);
|
||||
el.disabled = false;
|
||||
await el.updateComplete;
|
||||
expect(el.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should receive the correct validation attributes ("states") when valid', async () => {
|
||||
const el = await fixture<SlColorPicker>(html` <sl-input required value="a"></sl-input> `);
|
||||
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
expect(el.hasAttribute('data-required')).to.be.true;
|
||||
expect(el.hasAttribute('data-optional')).to.be.false;
|
||||
expect(el.hasAttribute('data-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-valid')).to.be.true;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
el.focus();
|
||||
await sendKeys({ press: 'b' });
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.true;
|
||||
});
|
||||
|
||||
it('should receive the correct validation attributes ("states") when invalid', async () => {
|
||||
const el = await fixture<SlColorPicker>(html` <sl-input required></sl-input> `);
|
||||
|
||||
expect(el.hasAttribute('data-required')).to.be.true;
|
||||
expect(el.hasAttribute('data-optional')).to.be.false;
|
||||
expect(el.hasAttribute('data-invalid')).to.be.true;
|
||||
expect(el.hasAttribute('data-valid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
el.focus();
|
||||
await sendKeys({ press: 'a' });
|
||||
await sendKeys({ press: 'Backspace' });
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.true;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -85,38 +85,73 @@ describe('<sl-input>', () => {
|
||||
it('should focus the input when clicking on the label', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input label="Name"></sl-input> `);
|
||||
const label = el.shadowRoot!.querySelector('[part~="form-control-label"]')!;
|
||||
const submitHandler = sinon.spy();
|
||||
const focusHandler = sinon.spy();
|
||||
|
||||
el.addEventListener('sl-focus', submitHandler);
|
||||
el.addEventListener('sl-focus', focusHandler);
|
||||
(label as HTMLLabelElement).click();
|
||||
await waitUntil(() => submitHandler.calledOnce);
|
||||
await waitUntil(() => focusHandler.calledOnce);
|
||||
|
||||
expect(submitHandler).to.have.been.calledOnce;
|
||||
expect(focusHandler).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
describe('when using constraint validation', () => {
|
||||
it('should be valid by default', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input></sl-input> `);
|
||||
expect(el.invalid).to.be.false;
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
});
|
||||
|
||||
it('should be invalid when required and empty', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input required></sl-input> `);
|
||||
expect(el.reportValidity()).to.be.false;
|
||||
expect(el.invalid).to.be.true;
|
||||
});
|
||||
|
||||
it('should be invalid when the pattern does not match', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input pattern="^test" value="fail"></sl-input> `);
|
||||
expect(el.invalid).to.be.true;
|
||||
expect(el.reportValidity()).to.be.false;
|
||||
expect(el.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should be invalid when required and disabled is removed', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input disabled required></sl-input> `);
|
||||
el.disabled = false;
|
||||
await el.updateComplete;
|
||||
expect(el.invalid).to.be.true;
|
||||
expect(el.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should receive the correct validation attributes ("states") when valid', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input required value="a"></sl-input> `);
|
||||
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
expect(el.hasAttribute('data-required')).to.be.true;
|
||||
expect(el.hasAttribute('data-optional')).to.be.false;
|
||||
expect(el.hasAttribute('data-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-valid')).to.be.true;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
el.focus();
|
||||
await el.updateComplete;
|
||||
await sendKeys({ press: 'b' });
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.true;
|
||||
});
|
||||
|
||||
it('should receive the correct validation attributes ("states") when invalid', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input required></sl-input> `);
|
||||
|
||||
expect(el.hasAttribute('data-required')).to.be.true;
|
||||
expect(el.hasAttribute('data-optional')).to.be.false;
|
||||
expect(el.hasAttribute('data-invalid')).to.be.true;
|
||||
expect(el.hasAttribute('data-valid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
el.focus();
|
||||
await el.updateComplete;
|
||||
await sendKeys({ press: 'a' });
|
||||
await sendKeys({ press: 'Backspace' });
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.true;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -167,6 +202,26 @@ describe('<sl-input>', () => {
|
||||
expect(keydownHandler).to.have.been.calledOnce;
|
||||
expect(submitHandler).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('should be invalid when setCustomValidity() is called with a non-empty value', async () => {
|
||||
const input = await fixture<HTMLFormElement>(html` <sl-input></sl-input> `);
|
||||
|
||||
input.setCustomValidity('Invalid selection');
|
||||
await input.updateComplete;
|
||||
|
||||
expect(input.checkValidity()).to.be.false;
|
||||
expect(input.hasAttribute('data-invalid')).to.be.true;
|
||||
expect(input.hasAttribute('data-valid')).to.be.false;
|
||||
expect(input.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(input.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
input.focus();
|
||||
await sendKeys({ type: 'test' });
|
||||
await input.updateComplete;
|
||||
|
||||
expect(input.hasAttribute('data-user-invalid')).to.be.true;
|
||||
expect(input.hasAttribute('data-user-valid')).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when resetting a form', () => {
|
||||
@@ -261,7 +316,7 @@ describe('<sl-input>', () => {
|
||||
await el.updateComplete;
|
||||
});
|
||||
|
||||
it('should not emit sl-change or sl-input when calling setRangeText()', async () => {
|
||||
it('should not emit sl-change or sl-input when calling setinputText()', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input value="hi there"></sl-input> `);
|
||||
|
||||
el.addEventListener('sl-change', () => expect.fail('sl-change should not be emitted'));
|
||||
@@ -277,21 +332,21 @@ describe('<sl-input>', () => {
|
||||
describe('when type="number"', () => {
|
||||
it('should be valid when the value is within the boundary of a step', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input type="number" step=".5" value="1.5"></sl-input> `);
|
||||
expect(el.invalid).to.be.false;
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
});
|
||||
|
||||
it('should be invalid when the value is not within the boundary of a step', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input type="number" step=".5" value="1.25"></sl-input> `);
|
||||
expect(el.invalid).to.be.true;
|
||||
expect(el.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should update validity when step changes', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input type="number" step=".5" value="1.5"></sl-input> `);
|
||||
expect(el.invalid).to.be.false;
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
|
||||
el.step = 1;
|
||||
await el.updateComplete;
|
||||
expect(el.invalid).to.be.true;
|
||||
expect(el.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should increment by step when stepUp() is called', async () => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { aTimeout, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
|
||||
import { sendKeys } from '@web/test-runner-commands';
|
||||
import sinon from 'sinon';
|
||||
import { clickOnElement } from '../../internal/test';
|
||||
import type SlRadio from '../radio/radio';
|
||||
import type SlRadioGroup from './radio-group';
|
||||
|
||||
@@ -14,7 +15,7 @@ describe('<sl-radio-group>', () => {
|
||||
</sl-radio-group>
|
||||
`);
|
||||
|
||||
expect(radioGroup.invalid).to.be.true;
|
||||
expect(radioGroup.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should become valid when an option is checked', async () => {
|
||||
@@ -28,7 +29,7 @@ describe('<sl-radio-group>', () => {
|
||||
radioGroup.value = '1';
|
||||
await radioGroup.updateComplete;
|
||||
|
||||
expect(radioGroup.invalid).to.be.false;
|
||||
expect(radioGroup.checkValidity()).to.be.true;
|
||||
});
|
||||
|
||||
it(`should be valid when required and one radio is checked`, async () => {
|
||||
@@ -40,7 +41,7 @@ describe('<sl-radio-group>', () => {
|
||||
</sl-radio-group>
|
||||
`);
|
||||
|
||||
expect(el.reportValidity()).to.be.true;
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
});
|
||||
|
||||
it(`should be invalid when required and no radios are checked`, async () => {
|
||||
@@ -52,7 +53,7 @@ describe('<sl-radio-group>', () => {
|
||||
</sl-radio-group>
|
||||
`);
|
||||
|
||||
expect(el.reportValidity()).to.be.false;
|
||||
expect(el.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it(`should be valid when required and a different radio is checked`, async () => {
|
||||
@@ -64,7 +65,7 @@ describe('<sl-radio-group>', () => {
|
||||
</sl-radio-group>
|
||||
`);
|
||||
|
||||
expect(el.reportValidity()).to.be.true;
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
});
|
||||
|
||||
it(`should be invalid when custom validity is set`, async () => {
|
||||
@@ -78,15 +79,64 @@ describe('<sl-radio-group>', () => {
|
||||
|
||||
el.setCustomValidity('Error');
|
||||
|
||||
expect(el.reportValidity()).to.be.false;
|
||||
expect(el.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should receive the correct validation attributes ("states") when valid', async () => {
|
||||
const radioGroup = await fixture<SlRadioGroup>(html`
|
||||
<sl-radio-group value="1" required>
|
||||
<sl-radio value="1"></sl-radio>
|
||||
<sl-radio value="2"></sl-radio>
|
||||
</sl-radio-group>
|
||||
`);
|
||||
const secondRadio = radioGroup.querySelectorAll('sl-radio')[1];
|
||||
|
||||
expect(radioGroup.checkValidity()).to.be.true;
|
||||
expect(radioGroup.hasAttribute('data-required')).to.be.true;
|
||||
expect(radioGroup.hasAttribute('data-optional')).to.be.false;
|
||||
expect(radioGroup.hasAttribute('data-invalid')).to.be.false;
|
||||
expect(radioGroup.hasAttribute('data-valid')).to.be.true;
|
||||
expect(radioGroup.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(radioGroup.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
await clickOnElement(secondRadio);
|
||||
await secondRadio.updateComplete;
|
||||
|
||||
expect(radioGroup.checkValidity()).to.be.true;
|
||||
expect(radioGroup.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(radioGroup.hasAttribute('data-user-valid')).to.be.true;
|
||||
});
|
||||
|
||||
it('should receive the correct validation attributes ("states") when invalid', async () => {
|
||||
const radioGroup = await fixture<SlRadioGroup>(html`
|
||||
<sl-radio-group required>
|
||||
<sl-radio value="1"></sl-radio>
|
||||
<sl-radio value="2"></sl-radio>
|
||||
</sl-radio-group>
|
||||
`);
|
||||
const secondRadio = radioGroup.querySelectorAll('sl-radio')[1];
|
||||
|
||||
expect(radioGroup.hasAttribute('data-required')).to.be.true;
|
||||
expect(radioGroup.hasAttribute('data-optional')).to.be.false;
|
||||
expect(radioGroup.hasAttribute('data-invalid')).to.be.true;
|
||||
expect(radioGroup.hasAttribute('data-valid')).to.be.false;
|
||||
expect(radioGroup.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(radioGroup.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
await clickOnElement(secondRadio);
|
||||
radioGroup.value = '';
|
||||
await radioGroup.updateComplete;
|
||||
|
||||
expect(radioGroup.hasAttribute('data-user-invalid')).to.be.true;
|
||||
expect(radioGroup.hasAttribute('data-user-valid')).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
it('should show a constraint validation error when setCustomValidity() is called', async () => {
|
||||
const form = await fixture<HTMLFormElement>(html`
|
||||
<form>
|
||||
<sl-radio-group>
|
||||
<sl-radio id="radio-1" name="a" value="1" checked></sl-radio>
|
||||
<sl-radio-group value="1">
|
||||
<sl-radio id="radio-1" name="a" value="1"></sl-radio>
|
||||
<sl-radio id="radio-2" name="a" value="2"></sl-radio>
|
||||
</sl-radio-group>
|
||||
<sl-button type="submit">Submit</sl-button>
|
||||
|
||||
@@ -20,7 +20,7 @@ describe('<sl-range>', () => {
|
||||
expect(el.label).to.equal('');
|
||||
expect(el.helpText).to.equal('');
|
||||
expect(el.disabled).to.be.false;
|
||||
expect(el.invalid).to.be.false;
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
expect(el.min).to.equal(0);
|
||||
expect(el.max).to.equal(100);
|
||||
expect(el.step).to.equal(1);
|
||||
@@ -137,6 +137,27 @@ describe('<sl-range>', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when submitting a form', () => {
|
||||
it('should be invalid when setCustomValidity() is called with a non-empty value', async () => {
|
||||
const range = await fixture<HTMLFormElement>(html` <sl-range></sl-range> `);
|
||||
|
||||
range.setCustomValidity('Invalid selection');
|
||||
await range.updateComplete;
|
||||
|
||||
expect(range.checkValidity()).to.be.false;
|
||||
expect(range.hasAttribute('data-invalid')).to.be.true;
|
||||
expect(range.hasAttribute('data-valid')).to.be.false;
|
||||
expect(range.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(range.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
await clickOnElement(range);
|
||||
await range.updateComplete;
|
||||
|
||||
expect(range.hasAttribute('data-user-invalid')).to.be.true;
|
||||
expect(range.hasAttribute('data-user-valid')).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when serializing', () => {
|
||||
it('should serialize its name and value with FormData', async () => {
|
||||
const form = await fixture<HTMLFormElement>(html` <form><sl-range name="a" value="1"></sl-range></form> `);
|
||||
|
||||
@@ -241,6 +241,59 @@ describe('<sl-select>', () => {
|
||||
el.requestSubmit();
|
||||
expect(select.shadowRoot!.activeElement).to.equal(select.displayInput);
|
||||
});
|
||||
|
||||
it('should receive the correct validation attributes ("states") when valid', async () => {
|
||||
const el = await fixture<SlSelect>(html`
|
||||
<sl-select label="Select one" required value="option-1">
|
||||
<sl-option value="option-1">Option 1</sl-option>
|
||||
<sl-option value="option-2">Option 2</sl-option>
|
||||
<sl-option value="option-3">Option 3</sl-option>
|
||||
</sl-select>
|
||||
`);
|
||||
const secondOption = el.querySelectorAll('sl-option')[1]!;
|
||||
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
expect(el.hasAttribute('data-required')).to.be.true;
|
||||
expect(el.hasAttribute('data-optional')).to.be.false;
|
||||
expect(el.hasAttribute('data-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-valid')).to.be.true;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
await el.show();
|
||||
await clickOnElement(secondOption);
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.true;
|
||||
});
|
||||
|
||||
it('should receive the correct validation attributes ("states") when invalid', async () => {
|
||||
const el = await fixture<SlSelect>(html`
|
||||
<sl-select label="Select one" required>
|
||||
<sl-option value="option-1">Option 1</sl-option>
|
||||
<sl-option value="option-2">Option 2</sl-option>
|
||||
<sl-option value="option-3">Option 3</sl-option>
|
||||
</sl-select>
|
||||
`);
|
||||
const secondOption = el.querySelectorAll('sl-option')[1]!;
|
||||
|
||||
expect(el.hasAttribute('data-required')).to.be.true;
|
||||
expect(el.hasAttribute('data-optional')).to.be.false;
|
||||
expect(el.hasAttribute('data-invalid')).to.be.true;
|
||||
expect(el.hasAttribute('data-valid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
await el.show();
|
||||
await clickOnElement(secondOption);
|
||||
el.value = '';
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.true;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when serializing', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
|
||||
import { aTimeout, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
|
||||
import { sendKeys } from '@web/test-runner-commands';
|
||||
import sinon from 'sinon';
|
||||
import type SlSwitch from './switch';
|
||||
@@ -38,7 +38,7 @@ describe('<sl-switch>', () => {
|
||||
it('should be valid by default', async () => {
|
||||
const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `);
|
||||
|
||||
expect(el.invalid).to.be.false;
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
});
|
||||
|
||||
it('should emit sl-change and sl-input when clicked', async () => {
|
||||
@@ -103,7 +103,7 @@ describe('<sl-switch>', () => {
|
||||
expect(el.checked).to.be.false;
|
||||
});
|
||||
|
||||
it('should not emit sl-change or sl-input when checked is set by javascript', async () => {
|
||||
it('should not emit sl-change or sl-input when checked is set by JavaScript', async () => {
|
||||
const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `);
|
||||
el.addEventListener('sl-change', () => expect.fail('sl-change incorrectly emitted'));
|
||||
el.addEventListener('sl-input', () => expect.fail('sl-change incorrectly emitted'));
|
||||
@@ -113,26 +113,80 @@ describe('<sl-switch>', () => {
|
||||
await el.updateComplete;
|
||||
});
|
||||
|
||||
it('should submit "on" when no value is provided', async () => {
|
||||
const form = await fixture<HTMLFormElement>(html`
|
||||
<form>
|
||||
<sl-switch name="a" checked></sl-switch>
|
||||
<sl-button type="submit">Submit</sl-button>
|
||||
</form>
|
||||
`);
|
||||
const button = form.querySelector('sl-button')!;
|
||||
const submitHandler = sinon.spy((event: SubmitEvent) => {
|
||||
formData = new FormData(form);
|
||||
event.preventDefault();
|
||||
describe('when submitting a form', () => {
|
||||
it('should submit the correct value when a value is provided', async () => {
|
||||
const form = await fixture<HTMLFormElement>(html`
|
||||
<form>
|
||||
<sl-switch name="a" value="1" checked></sl-switch>
|
||||
<sl-button type="submit">Submit</sl-button>
|
||||
</form>
|
||||
`);
|
||||
const button = form.querySelector('sl-button')!;
|
||||
const submitHandler = sinon.spy((event: SubmitEvent) => {
|
||||
formData = new FormData(form);
|
||||
event.preventDefault();
|
||||
});
|
||||
let formData: FormData;
|
||||
|
||||
form.addEventListener('submit', submitHandler);
|
||||
button.click();
|
||||
|
||||
await waitUntil(() => submitHandler.calledOnce);
|
||||
|
||||
expect(formData!.get('a')).to.equal('1');
|
||||
});
|
||||
let formData: FormData;
|
||||
|
||||
form.addEventListener('submit', submitHandler);
|
||||
button.click();
|
||||
it('should submit "on" when no value is provided', async () => {
|
||||
const form = await fixture<HTMLFormElement>(html`
|
||||
<form>
|
||||
<sl-switch name="a" checked></sl-switch>
|
||||
<sl-button type="submit">Submit</sl-button>
|
||||
</form>
|
||||
`);
|
||||
const button = form.querySelector('sl-button')!;
|
||||
const submitHandler = sinon.spy((event: SubmitEvent) => {
|
||||
formData = new FormData(form);
|
||||
event.preventDefault();
|
||||
});
|
||||
let formData: FormData;
|
||||
|
||||
await waitUntil(() => submitHandler.calledOnce);
|
||||
form.addEventListener('submit', submitHandler);
|
||||
button.click();
|
||||
|
||||
expect(formData!.get('a')).to.equal('on');
|
||||
await waitUntil(() => submitHandler.calledOnce);
|
||||
|
||||
expect(formData!.get('a')).to.equal('on');
|
||||
});
|
||||
|
||||
it('should show a constraint validation error when setCustomValidity() is called', async () => {
|
||||
const form = await fixture<HTMLFormElement>(html`
|
||||
<form>
|
||||
<sl-switch name="a" value="1" checked></sl-switch>
|
||||
<sl-button type="submit">Submit</sl-button>
|
||||
</form>
|
||||
`);
|
||||
const button = form.querySelector('sl-button')!;
|
||||
const slSwitch = form.querySelector('sl-switch')!;
|
||||
const submitHandler = sinon.spy((event: SubmitEvent) => event.preventDefault());
|
||||
|
||||
// Submitting the form after setting custom validity should not trigger the handler
|
||||
slSwitch.setCustomValidity('Invalid selection');
|
||||
form.addEventListener('submit', submitHandler);
|
||||
button.click();
|
||||
await aTimeout(100);
|
||||
|
||||
expect(submitHandler).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('should be invalid when required and unchecked', async () => {
|
||||
const slSwitch = await fixture<HTMLFormElement>(html` <sl-switch required></sl-switch> `);
|
||||
expect(slSwitch.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should be valid when required and checked', async () => {
|
||||
const slSwitch = await fixture<HTMLFormElement>(html` <sl-switch required checked></sl-switch> `);
|
||||
expect(slSwitch.checkValidity()).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when resetting a form', () => {
|
||||
|
||||
@@ -108,13 +108,13 @@ describe('<sl-textarea>', () => {
|
||||
it('should be valid by default', async () => {
|
||||
const el = await fixture<SlTextarea>(html` <sl-textarea></sl-textarea> `);
|
||||
|
||||
expect(el.invalid).to.be.false;
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
});
|
||||
|
||||
it('should be invalid when required and empty', async () => {
|
||||
const el = await fixture<SlTextarea>(html` <sl-textarea required></sl-textarea> `);
|
||||
|
||||
expect(el.invalid).to.be.true;
|
||||
expect(el.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should be invalid when required and after removing disabled ', async () => {
|
||||
@@ -123,14 +123,53 @@ describe('<sl-textarea>', () => {
|
||||
el.disabled = false;
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.invalid).to.be.true;
|
||||
expect(el.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should be invalid when required and disabled is removed', async () => {
|
||||
const el = await fixture<SlTextarea>(html` <sl-textarea disabled required></sl-textarea> `);
|
||||
el.disabled = false;
|
||||
await el.updateComplete;
|
||||
expect(el.invalid).to.be.true;
|
||||
expect(el.checkValidity()).to.be.false;
|
||||
});
|
||||
|
||||
it('should receive the correct validation attributes ("states") when valid', async () => {
|
||||
const el = await fixture<SlTextarea>(html` <sl-textarea required value="a"></sl-textarea> `);
|
||||
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
expect(el.hasAttribute('data-required')).to.be.true;
|
||||
expect(el.hasAttribute('data-optional')).to.be.false;
|
||||
expect(el.hasAttribute('data-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-valid')).to.be.true;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
el.focus();
|
||||
await sendKeys({ press: 'b' });
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.checkValidity()).to.be.true;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.true;
|
||||
});
|
||||
|
||||
it('should receive the correct validation attributes ("states") when invalid', async () => {
|
||||
const el = await fixture<SlTextarea>(html` <sl-textarea required></sl-textarea> `);
|
||||
|
||||
expect(el.hasAttribute('data-required')).to.be.true;
|
||||
expect(el.hasAttribute('data-optional')).to.be.false;
|
||||
expect(el.hasAttribute('data-invalid')).to.be.true;
|
||||
expect(el.hasAttribute('data-valid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.false;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
|
||||
el.focus();
|
||||
await sendKeys({ press: 'a' });
|
||||
await sendKeys({ press: 'Backspace' });
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.hasAttribute('data-user-invalid')).to.be.true;
|
||||
expect(el.hasAttribute('data-user-valid')).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user