Search code examples
powershellselenium4

Waiting for elements with PowerShell and Selenium 4


I am working on updating some PowerShell code that previously worked with Selenium 3.141. I have the following code snippet:

Add-Type -LiteralPath "$seleniumPath\lib\net48\WebDriver.dll"
Add-Type -LiteralPath "$seleniumPath\lib\net48\WebDriver.Support.dll"
$url = "https://<webpage.com>"
$options = New-Object OpenQA.Selenium.Chrome.ChromeOptions
$options.AddArgument("--disable-gpu")
$driver = New-Object OpenQA.Selenium.Chrome.ChromeDriver($options)
[OpenQA.Selenium.Support.UI.WebDriverWait]$wait = New-Object OpenQA.Selenium.Support.UI.WebDriverWait ($driver, [System.TimeSpan]::FromSeconds(60))

$driver.Navigate().GoToURL($url)
$driver.FindElementById("username")
$wait.Until([OpenQA.Selenium.Support.UI.ExpectedConditions]::ElementExists([OpenQA.Selenium.By]::Id('username')))

With Selenium 4.0, FindElementById no longer works:

Unable to find type [OpenQA.Selenium.Support.UI.ExpectedConditions].

As far as I can tell, OpenQA.Selenium.Support.UI.ExpectedConditions exists in WebDriver.Support, right?

Looking around for alternatives, I found SeleniumExtras.WaitHelpers, but that maybe only works with .netstandard2.1?


Solution

  • In the end, this worked for me:

    Add-Type -LiteralPath "$seleniumPath\lib\net48\WebDriver.dll"
    Add-Type -LiteralPath "$seleniumPath\lib\net48\WebDriver.Support.dll"
    $url = "https://<webpage.com>"
    $options = New-Object OpenQA.Selenium.Chrome.ChromeOptions
    $options.AddArgument("--disable-gpu")
    $driver = New-Object OpenQA.Selenium.Chrome.ChromeDriver($options)
    [OpenQA.Selenium.Support.UI.WebDriverWait]$wait = New-Object OpenQA.Selenium.Support.UI.WebDriverWait ($driver, [System.TimeSpan]::FromSeconds(60))
    
    $driver.Navigate().GoToURL($url)
    $driver.FindElementById("username")
    
    $wait.Until([System.Func[OpenQA.Selenium.IWebDriver, System.Boolean]] { param($driver) Try { $driver.FindElement([OpenQA.Selenium.By]::Id('username')) } Catch { $null } })
    

    If you want to return the element object instead of a boolean value, you can just change "System.Boolean" (on the last line) to "OpenQA.Selenium.IWebElement".