【问题标题】:Selenium + Node.js: is it possible to listen for reoccurring events?Selenium + Node.js:是否可以监听重复事件?
【发布时间】:2018-03-13 20:35:09
【问题描述】:

我正在开发一个由 AJAX/REST API 调用提供强大支持的网站,它会在完成/失败时广播事件。

我想要完成的是侦听这些文档事件并在 Selenium (Node.js) 中触发一个函数——现在我正在接受console.log()——并让该侦听器运行以报告任何新出现的“customEvent”

我的最新实现如下所示:

driver = await new Builder().forBrowser('chrome').build();
await driver.get('http://www.google.com/');

...

driver.executeScript(`
  document.addEventListener("customEvent", (e) => {
    return e;
  })`).
then( (e) => { console.log( e ); } );

我也试过executeAsyncScript()

我遇到的问题:

  • 此代码只想运行一次(不会保持打开状态)
  • 它要么没有捕捉到“customEvent”,要么阻止代码继续,这会触发事件。

【问题讨论】:

    标签: javascript node.js selenium event-listener


    【解决方案1】:

    感谢一位同事,我们找到了一个变通的解决方案:

    1. 使用 Selenium 的 .executeScript()
      • 在加载的站点中创建一个 HTML DIV(具有特定 ID),
      • 将事件监听器添加到由 Selenium 的驱动程序创建的文档元素中
      • 使用从事件中捕获的数据填充创建的 DIV
    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. 使用driver.wait(until.elementLocated(By.id(''))) 引用在步骤#1 中声明的DIV id
      • 这将确保 selenium 暂停,直到以浏览器的 JS 速度创建某些内容
    trackEvent.start('customEvent', 'testTarget');
    await driver.wait(until.elementLocated(By.id('testTarget')));
    let testEvent = await trackEvent.stop('testTarget');
    console.log( testEvent );
    
    1. 查询创建的元素并将其数据返回给 Selenium
    return driver.executeScript(`
        return document.getElementById('${target}').innerHTML;
    `).then(( data )=>{
        return data;
    });
    
    1. 将其全部放入测试中并尝试一下。
    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;
            });
        } 
    };
    

    有了这一切,selenium 并没有试图同时做两件事。 Selenium 正在运行它的测试,并且网站(它创建的)正在为我们监听事件。

    唯一的暂停是 Selenium 等待由我们的 executeScript JS 创建的新 DIV 的存在。

    【讨论】:

    • 你试过这个实时数据吗?这种方式附加的元素将被频繁更新,因此我认为 Selenium 应该监听该元素的事件,而不是使用 getElementById。
    猜你喜欢
    • 2018-08-17
    • 1970-01-01
    • 2019-04-02
    • 2020-06-24
    • 2018-03-18
    • 2018-11-12
    • 2020-08-06
    • 2012-07-08
    • 1970-01-01
    相关资源
    最近更新 更多