Selenium + Node.js:是否可以监听重复发生的事件?

时间:2018-03-13 20:35:10

标签: javascript node.js selenium event-listener

我正在开发一个由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”,要么阻止代码继续,这会触发事件。

1 个答案:

答案 0 :(得分:0)

感谢同事,我们找到了一种解决方案:

  1. 使用Selenium的.executeScript()
    • 在已加载的网站中创建HTML DIV(具有特定ID)
    • 将事件侦听器添加到由Selenium的驱动程序
    • 创建的文档元素中
    • 使用从事件中捕获的数据填充创建的DIV
  2. 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速度创建了某些内容
    2. trackEvent.start('customEvent', 'testTarget');
      await driver.wait(until.elementLocated(By.id('testTarget')));
      let testEvent = await trackEvent.stop('testTarget');
      console.log( testEvent );
      
      1. 查询创建的元素并将其数据返回Selenium
      2. return driver.executeScript(`
            return document.getElementById('${target}').innerHTML;
        `).then(( data )=>{
            return data;
        });
        
        1. 将所有内容放入测试中并试用。
        2. 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等待我们的executeScript JS创建的新DIV的存在。