import { expect, fixture as _fixture, html, oneEvent, aTimeout, unsafeStatic, defineCE, } from '@open-wc/testing'; import { spy } from 'sinon'; import { LionField } from '@lion/form-core'; import { LionFieldset } from '@lion/fieldset'; import '@lion/form-core/define'; import '@lion/fieldset/define'; import '@lion/form/define'; /** * @typedef {import('../src/LionForm').LionForm} LionForm * @typedef {import('@lion/core').TemplateResult} TemplateResult */ const fixture = /** @type {(arg: TemplateResult) => Promise} */ (_fixture); const childTagString = defineCE( class extends LionField { get slots() { return { input: () => document.createElement('input'), }; } }, ); const childTag = unsafeStatic(childTagString); describe('', () => { it('is an instance of LionFieldSet', async () => { const el = await fixture(html`
`); expect(el).to.be.instanceOf(LionFieldset); }); it('relies on the native form for its accessible role', async () => { const el = await fixture(html`
`); expect(el.getAttribute('role')).to.be.null; }); it('has a custom reset that gets triggered by native reset', async () => { const withDefaults = await fixture(html`
<${childTag} name="firstName" .modelValue="${'Foo'}">
`); const resetButton = /** @type {HTMLInputElement} */ (withDefaults.querySelector( 'input[type=reset]', )); withDefaults.formElements.firstName.modelValue = 'updatedFoo'; expect(withDefaults.modelValue).to.deep.equal({ firstName: 'updatedFoo', }); withDefaults.reset(); expect(withDefaults.modelValue).to.deep.equal({ firstName: 'Foo', }); // use button withDefaults.formElements.firstName.modelValue = 'updatedFoo'; expect(withDefaults.modelValue).to.deep.equal({ firstName: 'updatedFoo', }); resetButton.click(); expect(withDefaults.modelValue).to.deep.equal({ firstName: 'Foo', }); }); it('dispatches reset events', async () => { const el = await fixture(html`
<${childTag} name="firstName" .modelValue="${'Foo'}">
`); setTimeout(() => el.reset()); const resetEv = await oneEvent(el, 'reset'); expect(resetEv).to.be.instanceOf(Event); expect(resetEv.type).to.equal('reset'); expect(resetEv.target).to.equal(el); expect(resetEv.bubbles).to.be.true; expect(resetEv.composed).to.be.false; }); it('works with the native submit event (triggered via a button)', async () => { const submitSpy = spy(); const el = await fixture(html`
`); const button = /** @type {HTMLButtonElement} */ (el.querySelector('button')); button.click(); expect(submitSpy.callCount).to.equal(1); }); it('dispatches submit events', async () => { const el = await fixture(html`
`); const button = /** @type {HTMLButtonElement} */ (el.querySelector('button')); setTimeout(() => button.click()); const submitEv = await oneEvent(el, 'submit'); expect(submitEv).to.be.instanceOf(Event); expect(submitEv.type).to.equal('submit'); expect(submitEv.target).to.equal(el); expect(submitEv.bubbles).to.be.true; expect(submitEv.composed).to.be.false; }); it('redispatches a submit event on the native form node when calling submit() imperatively', async () => { const nativeFormSubmitEventSpy = spy(); const el = await fixture(html`
`); const submitSpy = spy(el, 'submit'); const submitGroupSpy = spy(el, 'submitGroup'); el.submit(); expect(submitSpy.calledOnce).to.be.true; expect(nativeFormSubmitEventSpy.calledOnce).to.be.true; expect(submitGroupSpy.calledOnce).to.be.true; }); it('handles internal submit handler before dispatch', async () => { const el = await fixture(html`
`); const button = /** @type {HTMLButtonElement} */ (el.querySelector('button')); const internalHandlerSpy = spy(el, 'submitGroup'); const dispatchSpy = spy(el, 'dispatchEvent'); await aTimeout(0); button.click(); expect(internalHandlerSpy).to.be.calledBefore(dispatchSpy); }); it('handles internal submit handler before dispatch', async () => { const el = await fixture(html`
`); const button = /** @type {HTMLButtonElement} */ (el.querySelector('button')); const internalHandlerSpy = spy(el, 'submitGroup'); const dispatchSpy = spy(el, 'dispatchEvent'); button.click(); expect(dispatchSpy.args[0][0].type).to.equal('submit'); expect(internalHandlerSpy).to.be.calledBefore(dispatchSpy); }); it('handles internal reset handler before dispatch', async () => { const el = await fixture(html`
`); const button = /** @type {HTMLButtonElement} */ (el.querySelector('button')); const internalHandlerSpy = spy(el, 'resetGroup'); const dispatchSpy = spy(el, 'dispatchEvent'); button.click(); expect(dispatchSpy.args[0][0].type).to.equal('reset'); expect(internalHandlerSpy).to.be.calledBefore(dispatchSpy); }); });