Зависает выполнение скрипта ExecuteAsyncScript в IJavaScriptExecutor

На веб странице удается начать кнопку только используя IJavaScriptExecutor. Кнопка нажимается и все отлично но код дальше не выполняется. И потом WebDriverTimeoutException : script timeout.

Почему залипает код, и что с ним можно сделать? На локатор сильно не обращайте внимание.

public void JSexecutor()
{
    var elem = _driver.FindElement(By.XPath("//button[@class='button-play button2 button2_rounded button2_w-icon local-icon-theme-white page-artist__play button-play__type_artist']"));
    IJavaScriptExecutor js = (IJavaScriptExecutor)_driver;
    js.ExecuteAsyncScript("arguments[0].click();",elem); //Происходит нажатие и код виснет      
}

Пробовал сделать повторный клик на этот же элемент путем дублирования кода но тоже не привело к успеху.


Ответы (1 шт):

Автор решения: aepot

Собственно у вас работает так, как и должно.

Для того, чтобы понять, почему оно записает, надо уловить разницу между ExecuteScript и ExecuteAsyncScript.

Первый просто выполняет скрипт.

js.ExecuteScript("arguments[0].click();", elem);

Сделайте так, и проблема решена.

ExecuteAsyncScript предназначен для выполнения асинхронных скриптов, то есть тех, которые завершаются раньше, чем будут получены необходимые данные, например AJAX запрос. Самый простой пример, это вызов с задержкой.

object response = js.ExecuteAsyncScript(
    "var callback = arguments[arguments.length - 1];" + // колбэк передается как последний аргумент
    "setTimeout(() => { arguments[0].click(); callback('success'); }, 5000);"
    , elem);
Debug.WriteLine(response);

Очевидно, что такой скрипт вы не сможете выполнить и получить строчку success с помощью простого ExecuteScript.

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

_driver.Manage().Timeouts().SetScriptTimeout(TimeSpan.FromSeconds(5));
→ Ссылка