Selenium + Node.js:是否可以监听重复发生的事件?
Selenium + Node.js: is it possible to listen for reoccurring events?
我正在一个由 AJAX/REST API 调用大量支持的站点上工作,这些调用在 completion/failure.
上广播事件
我想要完成的是监听这些文档事件并触发 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",要么阻止代码继续,这会触发事件。
多亏了 co-worker,我们找到了解决方法:
- 使用 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);
`);
- 使用
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 );
- 查询创建的元素和return它的数据返回给Selenium
return driver.executeScript(`
return document.getElementById('${target}').innerHTML;
`).then(( data )=>{
return data;
});
- 将其全部放入测试中并尝试一下。
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 存在时。
我正在一个由 AJAX/REST API 调用大量支持的站点上工作,这些调用在 completion/failure.
上广播事件我想要完成的是监听这些文档事件并触发 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",要么阻止代码继续,这会触发事件。
多亏了 co-worker,我们找到了解决方法:
- 使用 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);
`);
- 使用
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 );
- 查询创建的元素和return它的数据返回给Selenium
return driver.executeScript(`
return document.getElementById('${target}').innerHTML;
`).then(( data )=>{
return data;
});
- 将其全部放入测试中并尝试一下。
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 存在时。