Search code examples
javascriptjsdom

How to create `oninput` event on input[text] element with jsdom?


This my jsdom setup. I want to test oninput event for input[text] element. How can trigger oninput event? Because just setting element.value do not trigger this event.

const jsdom = require("jsdom");
    const { JSDOM } = jsdom;      
    suiteSetup(() => {
        return JSDOM.fromFile("./views/index.html", {
          runScripts: "dangerously",
          resources: "usable"
        }).then(dom => {
          global.dom = dom
          global.window = dom.window;
          global.document = dom.window.document;
        });
    });

Solution

  • As per this answer, you can create an Event object and use it to trigger the input event by executing the JS.

    Since you are using JSDOM, you can do that in the context of the page through eval.

    const jsdom = require('jsdom');
    const { JSDOM } = jsdom;
    
    const dom = new JSDOM(
        `<!DOCTYPE html>
            <meta charset="utf-8">
            <title>Test</title>
            <input>
            <p>Hello world</p>
    
            <script>
                document.querySelector("input").addEventListener("input", event =>
                    document.querySelector("p").textContent = event.target.value
                );
            </script>`,
        {
            runScripts: 'dangerously',
            resources: 'usable',
        }
    );
    
    dom.window.eval(`
        const input = document.querySelector("input");
        input.value = "New value";
        const event = new Event('input', {
            bubbles: true,
            cancelable: true
        });
        input.dispatchEvent(event);
    `);
    
    console.log(dom.serialize());