Private/Elements.ps1
function Get-MonocleElementId { [CmdletBinding()] param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [OpenQA.Selenium.IWebElement] $Element ) return (Get-MonocleElementAttribute -Element $Element -Name 'meta-monocle-id') } function Set-MonocleElementId { [CmdletBinding()] param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [OpenQA.Selenium.IWebElement] $Element, [Parameter(Mandatory=$true)] [string] $Id ) return (Set-MonocleElementAttribute -Element $Element -Name 'meta-monocle-id' -Value $Id) } function Get-MonocleElementInternal { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [ValidateSet('Id', 'Tag', 'XPath', 'Selector')] [string] $FilterType, [Parameter()] [string] $Id, [Parameter()] [string] $TagName, [Parameter()] [string] $AttributeName, [Parameter()] [string] $AttributeValue, [Parameter()] [string] $ElementValue, [Parameter()] [string] $XPath, [Parameter()] [string] $Selector, [Parameter()] [int] $Timeout = 0, [switch] $NoThrow ) if ($Timeout -le 0) { $Timeout = Get-MonocleTimeout } $seconds = 0 while ($true) { try { switch ($FilterType.ToLowerInvariant()) { 'id' { return (Get-MonocleElementById -Id $Id -NoThrow:$NoThrow) } 'tag' { if ([string]::IsNullOrWhiteSpace($AttributeName)) { return (Get-MonocleElementByTagName -TagName $TagName -ElementValue $ElementValue -NoThrow:$NoThrow) } else { return (Get-MonocleElementByTagName -TagName $TagName -AttributeName $AttributeName -AttributeValue $AttributeValue -ElementValue $ElementValue -NoThrow:$NoThrow) } } 'xpath' { return (Get-MonocleElementByXPath -XPath $XPath -NoThrow:$NoThrow) } 'selector' { return (Get-MonocleElementBySelector -Selector $Selector -NoThrow:$NoThrow) } } } catch { $seconds++ if ($seconds -ge $Timeout) { throw $_.Exception } Start-Sleep -Seconds 1 } } } function Get-MonocleElementById { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string] $Id, [switch] $NoThrow ) Write-Verbose -Message "Finding element with identifier '$Id'" $element = $Browser.FindElementsById($Id) | Select-Object -First 1 # if no element by ID, try by first named element if ($null -eq $element) { Write-Verbose -Message "Finding element with name '$Id'" $element = $Browser.FindElementsByName($Id) | Select-Object -First 1 } # throw error if can't find element if (($null -eq $element) -and !$NoThrow) { throw "Element with ID/Name of '$Id' not found" } return @{ Element = $element Id = "<[@id=$($Id)]>" } } function Get-MonocleElementByTagName { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string] $TagName, [Parameter(Mandatory=$true, ParameterSetName='Attribute')] [string] $AttributeName, [Parameter(Mandatory=$true, ParameterSetName='Attribute')] [string] $AttributeValue, [Parameter()] [string] $ElementValue, [switch] $NoThrow ) # get all elements for the tag Write-Verbose -Message "Finding element with tag <$TagName>" $elements = $Browser.FindElementsByTagName($TagName) $id = $TagName.ToLowerInvariant() # if we have attribute info, attempt to get an element if ($PSCmdlet.ParameterSetName -ieq 'Attribute') { Write-Verbose -Message "Filtering $($elements.Length) elements by attribute '$AttributeName' with value '$AttributeValue'" $found = $false $justFirst = [string]::IsNullOrWhiteSpace($ElementValue) # find elements with the correct attribue name/value $elements = @(foreach ($element in $elements) { if ($element.GetAttribute($AttributeName) -inotmatch $AttributeValue) { continue } $found = $true $element if ($found -and $justFirst) { break } }) # throw error if can't find element if (($null -eq ($elements | Select-Object -First 1)) -and !$NoThrow) { throw "Element <$TagName> with attribute '$AttributeName' and value of '$AttributeValue' not found" } $id += "[@$($AttributeName)=$($AttributeValue)]" } if (![string]::IsNullOrWhiteSpace($ElementValue)) { Write-Verbose -Message "Filtering $($elements.Length) elements with tag <$TagName>, and value '$ElementValue'" $element = $elements | Where-Object { $_.Text -imatch $ElementValue } Select-Object -First 1 # throw error if can't find element if (($null -eq $element) -and !$noThrow) { throw "Element <$TagName> with value of '$ElementValue' not found" } $id += "=$($ElementValue)" } else { $element = ($elements | Select-Object -First 1) } return @{ Element = $element Id = "<$($id)>" } } function Get-MonocleElementByXPath { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string] $XPath, [switch] $NoThrow ) Write-Verbose -Message "Finding element with XPath '$XPath'" $element = @($Browser.FindElementsByXPath($XPath)) | Select-Object -First 1 # throw error if can't find element if (($null -eq $element) -and !$NoThrow) { throw "Element with XPath of '$XPath' not found" } return @{ Element = $element Id = "<$($XPath)>" } } function Get-MonocleElementBySelector { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string] $Selector, [switch] $NoThrow ) Write-Verbose -Message "Finding element with selector '$Selector'" $element = Invoke-MonocleJavaScript -Script 'return document.querySelector(arguments[0])' -Arguments $Selector # throw error if can't find element if (($null -eq $element) -and !$NoThrow) { throw "Element with selector of '$Selector' not found" } return @{ Element = $element Id = "<$($Selector)>" } } |