Here is an example of a test I wrote for a Stimulus controller. The part I don’t love is all the manual/imperative event firing so I’m considering writing a few helper functions to clean that up if possible. The test is written using the Jest testing framework and jsdom to create some DOM in the test.
import mountDOM from 'jsdom-mount';
import {Application as StimulusApp} from 'stimulus';
import LinkBuilderController from '../link-builder';
describe('LinkBuilderController', () => {
beforeEach(() => {
mountDOM(`
<div data-controller="linkBuilder">
<input id="link" type="text" value="https://www.example.com/?ref=1234" data-target="linkBuilder.link" readonly>
<input id="foo" type="text" value="" data-target="linkBuilder.param" data-param-key="foo" data-action="input->linkBuilder#update">
<input id="bar" type="text" value="" data-target="linkBuilder.param" data-param-key="bar" data-action="input->linkBuilder#update">
</div>
`);
const stimulusApp = StimulusApp.start();
stimulusApp.register('linkBuilder', LinkBuilderController);
});
describe('#update', () => {
it('adds params to the initial url when you type into any param field', () => {
const linkElem = document.getElementById('link');
const fooElem = document.getElementById('foo');
const barElem = document.getElementById('bar');
const inputEvent = new Event('input');
fooElem.value = 'fooValue';
fooElem.dispatchEvent(inputEvent);
barElem.value = 'barValue';
barElem.dispatchEvent(inputEvent);
expect(linkElem.value).toEqual('https://www.example.com/?ref=1234&bar=barValue&foo=fooValue');
});
it('cleans up params that have a falsey value', () => {
const linkElem = document.getElementById('link');
const fooElem = document.getElementById('foo');
const barElem = document.getElementById('bar');
const inputEvent = new Event('input');
fooElem.value = 'newValue';
fooElem.dispatchEvent(inputEvent);
fooElem.value = '';
fooElem.dispatchEvent(inputEvent);
barElem.value = 'barValue';
barElem.dispatchEvent(inputEvent);
expect(linkElem.value).toEqual('https://www.example.com/?ref=1234&bar=barValue');
});
});
});