Selenium – Powershell – ожидание элемента не работает

Я пытаюсь реализовать увеличенный период ожидания для элементов. Однако похоже, что ни увеличенное время ожидания (60 секунд), ни значение по умолчанию (10) не распознаются. Загрузка сайта занимает где-то полторы секунды, но я сразу получаю ошибку, что первый искомый мной элемент не может быть найден.

cls
$workingPath = "D:\Dev\Selenium"
$env:PATH += ";$workingPath"
Add-Type -Path "$($workingPath)\lib\netstandard2.0\WebDriver.dll"
Add-Type -Path "$($workingPath)\lib\netstandard2.0\WebDriver.Support.dll"

$chromeOptions = New-Object OpenQA.Selenium.Chrome.ChromeOptions
$chromeOptions.AddArgument('start-maximized')
$chromeOptions.AddArgument('disable-gpu')
$chromeOptions.AddArgument('ignore-certificate-errors')
$chromeDriver = New-Object OpenQA.Selenium.Chrome.ChromeDriver($workingPath, $chromeOptions)

[OpenQA.Selenium.Support.UI.WebDriverWait]$wait = New-Object OpenQA.Selenium.Support.UI.WebDriverWait ($chromeDriver, [System.TimeSpan]::FromSeconds(60))

$SiteUrl = "http://192.168.27.10"
$chromeDriver.Navigate().GoToURL($siteURL)

$username = $ChromeDriver.FindElement([OpenQA.Selenium.By]::Id('loginUsername-inputEl'))
$wait.Until([System.Func[OpenQA.Selenium.IWebDriver, OpenQA.Selenium.IWebElement]] { param($chromeDriver)Try { $username } Catch { $null } })

Насколько я знаю, вышеизложенное «должно» работать. Однако после загрузки сайта ожидание элемента не происходит, и выдается следующая ошибка:

Exception calling "FindElement" with "1" argument(s): "no such element: Unable to locate element: {"method":"css selector","selector":"#loginUsername\-inputEl"}
  (Session info: chrome=123.0.6312.123); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception"
At line:18 char:1
+ $username = $ChromeDriver.FindElement([OpenQA.Selenium.By]::Id('login ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : NoSuchElementException

Я могу подтвердить, что время ожидания действительно увеличивается до 60 секунд, запустив $wait:

$wait

Timeout  PollingInterval  Message
-------  ---------------  -------
00:01:00 00:00:00.5000000 

Возможно, я делаю что-то неправильно; Я не уверен. Какие-либо предложения??

похоже, что вы ожидаете элемент после попытки найти элемент (должны перевернуть строки ожидания и имени пользователя)

Andrew Ryan 17.04.2024 06:05
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
117
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Ваш текущий код не имеет особого смысла. Вы ждете первого результата звонка FindElement() вместо того, чтобы повторно звонить FindElement().

Я думаю, что вызов FindElement должен находиться внутри блока скрипта, вызываемого $wait.Until():

$script:username = $null

# In this Func type, the first type relates to the parameter of the script block
# and the second type relates to its return value.
$null = $wait.Until( [Func[OpenQA.Selenium.IWebDriver, Boolean]] { param($chromeDriver)

    try {
        $script:username = $chromeDriver.FindElement([OpenQA.Selenium.By]::Id('loginUsername-inputEl'))
        $true  # As there was no exception, exit the wait loop
    }
    catch { 
        $false  # Exception occurred, need to wait another time
    } 
})

# For debugging, output the value of the variable after the wait loop has finished
$script:username

Примечание:

  • Я использую переменную в области скрипта, потому что блок скрипта, вызываемый $wait.Until(), запускается в новой области и не может напрямую изменять переменные в родительской области (он может только читать их из-за динамической области действия PowerShell ). Есть и другие варианты, например использование ссылки или Set-Variable -Scope 1, которые вы, возможно, захотите изучить.

Эй, это отлично работает! Единственное изменение, которое мне пришлось внести, — это удалить OpenQA.Selenium.IWebElement из System.Func и вставить System.Boolean. Это произошло потому, что: Исключение, вызывающее «Until» с аргументами «1»: «Невозможно преобразовать значение «False» в тип «OpenQA.Selenium.IWebElement». Ошибка: «Недопустимое приведение из «System.Boolean» в «OpenQA. Selenium.IWebElement'."" В противном случае спасибо. Я думаю, что моя главная проблема заключалась в не совсем понимании правильного способа реализации тайм-аута. Теперь мне нужно расширить область действия остальных моих элементов.

sbagnato 17.04.2024 15:29

Ооо, раздел комментариев никогда не форматируется должным образом, извините. Несмотря ни на что, еще раз спасибо

sbagnato 17.04.2024 15:30

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

Santiago Squarzon 17.04.2024 19:34

@SantiagoSquarzon Вы абсолютно правы, спасибо!

zett42 18.04.2024 12:02

Какого черта это метод, чтобы каждый раз писать «True»? Я попробовал установить значение null, но это не сработало. Я полагаю, есть способ предотвратить это?

sbagnato 20.04.2024 03:01

@sbagnato Попробуйте $null = $wait.Until(.... Я считаю, что функция возвращает либо значение из блока скрипта, либо свой собственный статус. Любые неназначенные возвращаемые значения неявно выводятся PowerShell, что иногда может вызывать головную боль. При присвоении поддельной переменной $null возвращаемое значение фактически отбрасывается.

zett42 21.04.2024 22:16

Хороший звонок; это сделало это.

sbagnato 22.04.2024 13:07

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