Зачем нам нужно приводить экземпляр WebDriver к типу JavascriptExecutor перед вызовом метода executeScript?

JavascriptExecutor — это интерфейс, который предоставляет некоторый код по умолчанию для метода executeScript.

RemoteWebDriver реализует этот интерфейс и переопределяет метод следующим образом:

@Override
    public Object executeScript(String script, Object... args) {...}

Когда мы создаем экземпляр WebDriver, мы используем такой экземпляр, как FireFoxDriver или ChromeDriver. Эти методы наследуют родительский метод executeScript.

Тем не менее, всякий раз, когда мы хотим вызвать executeScript, мы никогда не вызываем этот метод непосредственно из объекта драйвера, например:

driver.executeScript(...)

Вместо этого мы всегда сначала приводим его к интерфейсу, а затем вызываем.

Вот пример кода:

WebDriver driver = new FirefoxDriver();
JavascriptExecutor executor =(JavascriptExecutor)driver;
executor.executeScript("window.location.href = 'https://google.com';");  

Зачем нам нужно приводить драйвер к JavascriptExecutor? Почему мы не можем просто вызвать driver.executeScript вместо этого? В качестве альтернативы, мы могли бы вместо этого преобразовать его в RemoteWebDriver?

Что вы подразумеваете под "родительскими методами"? WebDriver не продлевается JavaScriptExecutor. И что вы подразумеваете под «не определено в этом интерфейсе»? Это прямо здесь.

chrylis -cautiouslyoptimistic- 12.05.2022 16:25

@chrylis-cautiouslyoptimistic- Реализация выполняется классом RemoteWebDriver. Но это по-прежнему не меняет того факта, что мы приводим драйвер ChromeDriver/FireFox к родительскому типу.

Mugen 12.05.2022 18:30

Смотрите мой комментарий здесь: stackoverflow.com/questions/70397713/…

pcalkins 12.05.2022 20:28

в основном тип (интерфейс - это в основном тип) веб-драйвера не гарантирует метод javascriptexecutor... некоторые драйверы могут фактически не реализовывать его. (хотя я не могу придумать ни одного, который не... может быть, драйверы appium или winium?)

pcalkins 12.05.2022 22:07

@pcalkins Не должно иметь значения, реализует ли его дочерний класс или нет (например, appium). Этот интерфейс уже реализован родительским RemoteWebDriver, что означает, что этот метод виден дочернему экземпляру. Я не вижу причин, по которым мы постоянно приводим типы перед вызовом метода интерфейса.

Mugen 13.05.2022 07:04

да, это может быть скорее устаревшая вещь ... но, поскольку вы уже выполнили приведение к WebDriver, неизвестно, будет ли оно доступно, пока вы не приведете тип. Если вы используете только один драйвер в своем коде, вы можете с самого начала просто привести его к FirefoxDriver. (на самом деле вы бы не выполняли кастинг в этот момент, просто сохраняя тип как FirefoxDriver...) Архитектура, вероятно, изменится по мере того, как все больше драйверов будут соответствовать стандарту W3C.

pcalkins 13.05.2022 20:04

@pcalkins Ваш ответ правильный. Не могли бы вы поставить это как ответ на этот вопрос? Я думаю, что это ответ. Спасибо!

Mugen 14.05.2022 08:44
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
7
45
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Мы приводим типы, потому что наш код обычно использует тип webdriver, который является интерфейсом и не включает метод executeScript.

Когда вы передаете драйвер как тип "webdriver", классы предполагают, что он имеет только методы интерфейса WebDriver. Вы также можете привести его к типу Chromedriver, но тот же код не будет работать для Geckodriver или других типов.

Кредиты pcalkins для этого ответа.

Следовательно, вы передаете его интерфейсу JavascriptExecutor, чтобы код оставался универсальным, чтобы он работал с Geckodriver/Chromedriver и т. д. В качестве альтернативы вы также можете привести его к RemoteWebDriver, и он все равно будет работать. Но это более читабельно, если привести к JavascriptExecutor.

Вот диаграмма архитектуры, которая прекрасно это объясняет. Кредиты qacult.com для этого изображения.

hierarchy of Selenium classes

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