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