Во-первых, чтобы обратиться к очевидному
Я видел миллион и один вопрос по этому поводу с главной целью dupe: Как я могу вернуть ответ от асинхронного вызова? Этоне удовлетворяет моим потребностям, потому что
A: Я знаю, что мне уже нужен асинхронный java-скрипт и что я хочу использовать функции обратного вызова.Мне нужны подробности о том, КАК правильно их реализовать в конкретных условиях (в Selenium с использованием JavascriptExecutor и т. Д.), Которые я не смог найти из других вопросов
B: этот вопрос более специфичен для Ajax, что делает его чрезвычайносмущает меня, чтобы получить что-нибудь от этого.
C: это больше о лучшем способе ожидания завершения асинхронных вызовов, подобных этому
Что я сделал, кроме исследования переполнения стека
Я также обращался ко многимвеб-сайты, в том числе: https://www.sitepoint.com/callbacks-javascript/, которые дали мне некоторое базовое представление о том, как реализованы обратные вызовы, и я реализовал один правильно, я также нашел этот сайт https://javapapers.com/ajax/getting-started-with-ajax-using-java/, который дал мне базовое понимание одного способа, о котором я могу думать«ждать» выполнения асинхронной функции javascript, то есть пересылать данные ajax обратно в мой код, когда функция, наконец, будет выполнена.
Какую кроличью нору вы пробили?
Я хочу сделать простой скрипт, чтобы определить, вызывает ли данный веб-элемент перезагрузку страницы.Для этого мне нужно событие загрузки страницы.Я исследовал некоторое время и нашел (через несколько вопросов здесь) JavascriptExecutor и событие загрузки.Я пытался их реализовать, и я наивно думал, что это будет легким ответом.Первоначально я пытался вернуть результат добавления прослушивателя событий, когда впервые попытался реализовать это.Затем я понял, что это глупо, поэтому мне нужно было получить какое-то возвращаемое значение, я пытался пару часов возвращать различные части скрипта прослушивателя добавления событий, прежде чем понял, что использовал неправильный подход и думал о проблеме неправильно.Затем я провел исследование асинхронного JavaScript, потому что, задавая вопросы об NPE из моего предыдущего подхода, я понял, что это такое, как он используется, а затем я наткнулся на функции обратного вызова.После публикации этого и проведения дополнительных исследований я правильно реализовал простую функцию асинхронного обратного вызова.Теперь мне просто нужно правильно дождаться его завершения, прежде чем двигаться вперед, чтобы я знал, что страница полностью загружена.
всеобъемлющее описание того, что я делаю
У меня отключена темаосновной.Эта тема нажимает на веб-элемент.У веб-элемента, по которому щелкнули, есть 3 основных случая, для которых я хочу задокументировать / пометить:
- щелчок по нему не перезагружает страницу и не перемещается / удаляется (локаторы остаются прежними)
- нажатие на нее не перезагружает страницу, но локаторы элементов (например, 'id' удаляются или изменяются)
- нажатие веб-элемента вызывает перезагрузку страницы
InДля того чтобы задокументировать эти три случая, мне нужны флаги, событие загрузки и исключение устаревшей ссылки, и я хочу тайм-аут, если оба эти события не произошли вовремя.Если происходит загрузка, то мы знаем ее случай 3, в случае устаревшей ссылки это происходит, но загрузка не происходит.
Получить флаг для устаревшего эталонного дела было легко, его уже в Selenium.Проблема в флаге для события загрузки.Чтобы пометить это, мне нужно что-то, что я могу запустить в JavaScriptExecutor, который затем передает данные через функции асинхронного обратного вызова и, возможно, ajax (или какой-то другой метод, который я открыт для предложений) в java.Эти данные могут быть простыми числами, если я могу получить какое-то сообщение из javascript, сообщающее моему java, что оно выполнило свою асинхронную работу.Я реализовал функцию обратного вызова в моем коде, но мне нужно получить данные из JavaScript в Java.Кроме того, действительно сложно проверить синтаксис / ошибки в javascript, потому что я не могу просто проверить саму строку сценария JavaScript как свою собственную программу (до сих пор мне приходилось использовать бесплатные онлайн-редакторы, которые не так хороши).
Код, о котором идет речь
//initialize a wait object and set a default timeout (the value is ten
//seconds)
WebDriverWait wait = new WebDriverWait(driver,timeoutSeconds);
try{
//wait until stalereference exception is thrown (unless timeout
//is exceeded)
wait.until(ExpectedConditions.stalenessOf(webElement));
//define the test function with a callback inside it. Prints 2
//to a page on page reload event only if the webelement went
//stale
String script = "function test(arg,callback) {callback(arg);}" +
"function Return(arg){document.write(arg);}" +
"var a = 2;" +
"window.addEventListener('load', test(a,Return));";
//TODO change this fucntionality to use ajax or some other good
//method to say "hey I'm done executing!" to the java code
//execute the script to add the event listener
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript(script);
//flag the state of this Thread
}
//Timeout was exceeded so the page doesn't change on click
catch (TimeoutException e){
//here I set a 'page didn't change' flag
}
Примечания по коду / то, что мне нужно для кода
Единственное, что требуется для выполнения этого, должен быть веб-элемент, драйверобъект и, возможно, некоторые операторы печати, чтобы быть «флаги».Я использовал chrome-драйвер driver
, потому что мне нравится chrome, и я использую поле вопроса в качестве webElement
(и, конечно, удаляя мои комментарии).Мой стиль и синтаксис, вероятно, грязный, но на данный момент это всего лишь тестовый код, и я хочу, чтобы он работал.То, что я хочу, это в основном
InsideCallback.POST(somedata) to java
Но в коде, который работает (или заменяет) мой текущий тестовый код.Я знаю, что, поскольку он асинхронный, я не хочу опрашивать возвращаемый результат (что противоречит цели всей асинхронности).Я просто не знаю, как сказать «когда эта функция на другом языке возвращает свои вещи» в коде.К сожалению, у меня нет конкретной ошибки с трассировкой стека, потому что это больше о том, что НЕ в коде.Я чувствую, что на правильном пути, но мне нужно знать, является ли Ajax правильным путем.Проблема в том, что работающие примеры этого кажутся сложными и могут занять некоторое время, поэтому я хочу знать, во что я ввязываюсь.
EDIT 1
Обновлен код, поэтому в нем не должно быть синтаксических ошибок, вызывающих трассировку / сбой стека, все работало нормально, когда я пытался это сделать, только неправильное сочетание скобок и синтаксис аргументов.Мне все еще не хватает способа фактически вызвать функцию обратного вызова, но я собираюсь продолжать пытаться исследовать ее.
Редактировать 2
ОК Я наконец-то достаточно понял синтаксис javascript и получил его такчто функция обратного вызова Eventlistener работает.У меня есть печать 2 на страницу на перезагрузку.Просто и легко.Теперь мне просто нужно изменить эту функциональность, чтобы ссылаться на мой javacode и установить какой-то простой флаг.(обновил код, чтобы при запуске он работал намного лучше).Обновлен порядок кода, чтобы более точно соответствовать желаемому поведению.Необходимо добавить staleReferenceException, ДО того как будет добавлен eventListener для события onload. В противном случае события onload запускаются преждевременно для желаемого поведения.
Edit 3
Обновлен вопрос, чтобы более точно отражать заголовок / текущий статус исследования.