Selenium + Node.js: можно ли отслеживать повторяющиеся события?

Я работаю над сайтом, который сильно зависит от вызовов API AJAX / REST, которые транслируют события при завершении / сбое.

То, что я пытаюсь выполнить, - это прослушивать эти события документа и запускать функцию в Selenium (Node.js) - прямо сейчас я выбираю console.info() - и держать этот слушатель включенным, чтобы сообщать о любых новых случаях " 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.info( e ); } );

Еще пробовал executeAsyncScript()

Проблемы, с которыми я сталкиваюсь:

  • Этот код просто хочет запустить один раз (не остается открытым)
  • Он либо не улавливает «customEvent», либо блокирует продолжение кода, что могло бы вызвать событие.
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
901
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Благодаря коллеге мы нашли обходное решение:

  1. Используйте Selenium .executeScript ()
    • Создайте HTML DIV (с определенным идентификатором) на загруженном сайте,
    • Добавьте прослушиватель событий в элемент документа, созданный драйвером 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(''))), ссылаясь на идентификатор DIV, объявленный на шаге # 1
    • Это гарантирует, что селен приостанавливается, пока что-то не будет создано со скоростью JS браузера.
trackEvent.start('customEvent', 'testTarget');
await driver.wait(until.elementLocated(By.id('testTarget')));
let testEvent = await trackEvent.stop('testTarget');
console.info( 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 ожидает существования нового DIV, созданного нашим executeScript JS.

Вы пробовали это для живых данных? Таким образом, добавленный элемент будет часто обновляться, и, следовательно, вместо использования getElementById, я думаю, Selenium должен прослушивать события этого элемента.

ALalavi 13.11.2020 13:27

Другие вопросы по теме