Skip to content Skip to sidebar Skip to footer

Selenium + Node.js: Is It Possible To Listen For Reoccurring Events?

I am working on a site that is heavily powered by AJAX/REST API calls, which broadcast events on completion/failure. What I am trying to accomplish is to listen for these document

Solution 1:

Thanks to a co-worker, we have found a workaround solution:

  1. Use Selenium's .executeScript()
    • Create an HTML DIV (with a specific ID) in the loaded site,
    • Add the event listener to the document element created by Selenium's driver
    • Populate the created DIV with the data captured from the event
driver.executeScript(`
    var emptyDiv = document.createElement('div');
        emptyDiv.id = '${target}';
        emptyDiv.style.display = 'none';
    function _trackEvent(e){
        var target = document.getElementById('${target}');
        if( !target ){ document.body.appendChild( emptyDiv ); }
        target.innerHTML += JSON.stringify(e.detail);
    }
    document.addEventListener("${name}", _trackEvent);
`);
  1. Use driver.wait(until.elementLocated(By.id(''))) referencing the DIV id declared in step #1
    • This will make sure selenium pauses until something has been created at the browser's JS speed
trackEvent.start('customEvent', 'testTarget');
await driver.wait(until.elementLocated(By.id('testTarget')));
let testEvent = await trackEvent.stop('testTarget');
console.log( testEvent );
  1. Query the created element and return its data back to Selenium
return driver.executeScript(`
    return document.getElementById('${target}').innerHTML;
`).then(( data )=>{
    return data;
});
  1. Drop it all into the tests and try it out.
const trackEvent = {
    start  : ( name, target ) => {
        driver.executeScript(`
            var emptyDiv = document.createElement('div');
                emptyDiv.id = '${target}';
                emptyDiv.style.display = 'none';
            function _trackEvent(e){
                var target = document.getElementById('${target}');
                if( !target ){ document.body.appendChild( emptyDiv ); }
                target.innerHTML += JSON.stringify(e.detail);
            }
            document.addEventListener("${name}", _trackEvent);
        `);
    },
    stop  : ( target ) => {
        return driver.executeScript(`
            return document.getElementById('${target}').innerHTML;
        `).then(( data )=>{
            return data;
        });
    } 
};

With all of this, selenium is not trying to do two things at once. Selenium is running its tests and the website (that it spun up) is listening for the event(s) for us.

The only pause is when Selenium waits for the existence of the new DIV that is created by our executeScript JS.

Post a Comment for "Selenium + Node.js: Is It Possible To Listen For Reoccurring Events?"