Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Как вызвать JavascriptExecutor в Listener'ах

webdriver
java
javascript
Теги: #<Tag:0x00007f7b621589e0> #<Tag:0x00007f7b62158760> #<Tag:0x00007f7b621585d0>

(Александр Чечулин) #1

Добрый день,

У меня задача вызвать JS до загрузки страницы.
Решил использовать методы Listener’a “beforeNavigateTo” и “beforeClickOn”

Но когда я пишу

((JavascriptExecutor) WebDriver ).executeScript()

Он ругается на WebDriver, как можно ему (методу) передать активный WebDriver? И вообще возможно ли?


(Антон) #2

Для этого использовали самописную фабрику по мотивам вот этой:

https://github.com/barancev/webdriver-extensions/tree/master/webdriver-factory


(Stan) #3

А как можно выполнить жс, когда страница не загружена страница? Магии не существует :slight_smile: Или вы просто неправильно выразились?


(Антон) #4

Я коряво прочитал :slight_smile: Показалось проблема передать именно драйвер в листенер, а не выполнить JS до загрузки :slight_smile:


(Дмитрий Жарий) #5

А какова цель такого действия?

Если вам действительно нужно выполнить JavaScript в момент загрузки, то я бы рекомендовал следующее:

  1. Самый правильный вариант: договорится с разработчиками и попросить их вставить нужный файл
  2. Использовать прокси-сервер, например, Fiddler через FiddlerScript может модифицировать страницу на лету, так что браузер получит уже модифицированную версию.

(Александр Чечулин) #6

Цель действия:
Данный JS считает количество незавершенных запросов к серверу, и на основе него я проверяю можно работать со страницей или еще подождать.

Обычные средства Selenium по ожиданиям не дают нужного результата.

По написанию JS руководствовался http://qnimate.com/monitoring-ajax-requests/

P.S. Есть ли другой вариант решения проблемы, кроме как использовать Listener’ы?


(Дмитрий Жарий) #7

Обычные средства Selenium по ожиданиям не дают нужного результата.

Ну, бывает конечно, но с хаками я бы не стал торопится.
Раз вы пишете на Джаве, поэкспериментируйте со Селенидой (http://selenide.org/), в которой элементы ожидаются по умолчанию.

Если вы все таки решитесь применить ваш хак, то вам нужно вставить свой код первым в head страницы, так что мой предыдущий совет с прокси сервером остается в силе.

Используя этот хак вы должны быть на 100.00% быть уверенным, что он ничего не ломает в самом приложении и не провоцирует ухудшения перформанса во всех поддерживаемых браузерах.


(Sergey Korol) #8

Как пробовали ждать средствами селениума?


(Александр Чечулин) #9

было два метода:

public WebElement findElement(WebElement element){
        try{
            Thread.sleep(150);
            for(int i=0;i<=10000;i++){
                if(!element.isDisplayed()){
                    Thread.sleep(101);
                }else {
                    Thread.sleep(151);
                    return element;
                    }
            }
        } catch (Exception e) { }
        return element;
    }

и

public final void isElementAvailable(By element){
    int timeoutRepeats = MerchantCabinetConfiguration.getTimeoutRetries();
    int timeoutIntervalSeconds = MerchantCabinetConfiguration.getTimeoutIntervalSeconds();
    for(int repeat=0; repeat<timeoutRepeats; repeat++){
        if(checkElement(element)){break;}
        try {
            Thread.sleep(timeoutIntervalSeconds * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

    }
public final boolean checkElement(By element){
    if (driver.findElement(element).isEnabled()) {return true;}
    else {return false;}
}

но оба работают не стабильно


(Остап Олексин) #10

Эты методы не являются средствами Selenium. Почитайте о implicit и explicit waits - http://xpinjection.com/2013/04/04/waits-and-timeouts-in-webdriver/
Вам скорее всего нужен explicit wait, типа этого:
WebDriverWait wait = new WebDriverWait(this.driver, time); wait.until(ExpectedConditions.visibilityOf(element);
или
WebDriverWait wait = new WebDriverWait(this.driver, time); wait.until(ExpectedConditions.elementToBeClickable(element);


(Sergey Korol) #11

С этого и надо было начинать, не вводя комьюнити в заблуждение, что мол все перепробовали…
Воспользуйтесь советом @Ostap_Oleksyn для начала. Если не поможет, можно написать кастомный ExpectedCondition, который будет ждать завершения активности jQuery.

П.С. Подобные темы уже не раз обсуждались на данном ресурсе.


(Александр Чечулин) #12

Спасибо, попробовал этот метод.
Работает стабильно.

Тему можно закрывать