diff --git a/.build.ps1 b/.build.ps1 index a9b06a0..081b62c 100644 --- a/.build.ps1 +++ b/.build.ps1 @@ -12,7 +12,7 @@ Task 'Selenium' { $packages = @{ 'Selenium.WebDriver' = '3.141.0' 'Selenium.Support' = '3.141.0' - 'Selenium.WebDriver.ChromeDriver' = '78.0.3904.10500' + 'Selenium.WebDriver.ChromeDriver' = '80.0.3987.1600' 'Selenium.WebDriver.IEDriver' = '3.150.1' 'Selenium.WebDriver.GeckoDriver' = '0.26.0' } diff --git a/README.md b/README.md index b7debf9..ec3cc10 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ The following is a list of available functions in Monocle: * Submit-MonocleForm * Test-MonocleElement * Test-MonocleElementAttribute +* Wait-MonocleElement * Wait-MonocleUrl * Wait-MonocleUrlDifferent * Wait-MonocleValue diff --git a/examples/youtube.ps1 b/examples/youtube.ps1 index c3d0f62..b7bce41 100644 --- a/examples/youtube.ps1 +++ b/examples/youtube.ps1 @@ -1,22 +1,24 @@ -#$path = Split-Path -Parent -Path (Split-Path -Parent -Path $MyInvocation.MyCommand.Path) -#$path = "$($path)/src/Monocle.psm1" -#Import-Module $path -Force -ErrorAction Stop -Import-Module -Name Monocle -Force -ErrorAction Stop +$path = Split-Path -Parent -Path (Split-Path -Parent -Path $MyInvocation.MyCommand.Path) +$path = "$($path)/src/Monocle.psm1" +Import-Module $path -Force -ErrorAction Stop +#Import-Module -Name Monocle -Force -ErrorAction Stop # Create a browser object -$browser = New-MonocleBrowser -Type Chrome +#$browser = New-MonocleBrowser -Type Firefox # Monocle runs commands in web flows, for easy disposal and test tracking # Each flow needs a name -Start-MonocleFlow -Name 'Load YouTube' -Browser $browser -ScriptBlock { +Start-MonocleFlow -Name 'Load YouTube' <#-Browser $browser#> -ScriptBlock { # Tell the browser which URL to navigate to, will sleep while page is loading Set-MonocleUrl -Url 'https://www.youtube.com' # Sets the search bar element to the passed value to query - Get-MonocleElement -Id 'search_query' | Set-MonocleElementValue -Value 'Beerus Madness (Extended)' + Get-MonocleElement -Selector 'input[name=search_query]' | Set-MonocleElementValue -Value 'Beerus Madness (Extended)' + #Get-MonocleElement -Id 'search_query' | Set-MonocleElementValue -Value 'Beerus Madness (Extended)' # Tells the browser to click the search button + Wait-MonocleElement -Id 'search-icon-legacy' Get-MonocleElement -Id 'search-icon-legacy' | Invoke-MonocleElementClick # Though all commands sleep when the page is busy, some buttons use javascript @@ -35,5 +37,5 @@ Start-MonocleFlow -Name 'Load YouTube' -Browser $browser -ScriptBlock { } -CloseBrowser -ScreenshotOnFail -# or close the browser manually: +# or close the browser manually if not using default: #Close-MonocleBrowser -Browser $browser \ No newline at end of file diff --git a/src/Monocle.psd1 b/src/Monocle.psd1 index ace1455..b8f7590 100644 --- a/src/Monocle.psd1 +++ b/src/Monocle.psd1 @@ -11,7 +11,7 @@ RootModule = 'Monocle.psm1' # Version number of this module. - ModuleVersion = '1.1.2' + ModuleVersion = '1.2.0' # ID used to uniquely identify this module GUID = '9dc3c8a1-664d-4253-a5d2-920250d3a15f' diff --git a/src/Private/Elements.ps1 b/src/Private/Elements.ps1 index 7e0a78a..f595a6d 100644 --- a/src/Private/Elements.ps1 +++ b/src/Private/Elements.ps1 @@ -31,7 +31,7 @@ function Get-MonocleElementInternal [CmdletBinding()] param ( [Parameter(Mandatory=$true)] - [ValidateSet('Id', 'Tag', 'XPath')] + [ValidateSet('Id', 'Tag', 'XPath', 'Selector')] [string] $FilterType, @@ -59,11 +59,22 @@ function Get-MonocleElementInternal [string] $XPath, + [Parameter()] + [string] + $Selector, + + [Parameter()] + [int] + $Timeout = 0, + [switch] $NoThrow ) - $timeout = Get-MonocleTimeout + if ($Timeout -le 0) { + $Timeout = Get-MonocleTimeout + } + $seconds = 0 while ($true) { @@ -85,12 +96,16 @@ function Get-MonocleElementInternal 'xpath' { return (Get-MonocleElementByXPath -XPath $XPath -NoThrow:$NoThrow) } + + 'selector' { + return (Get-MonocleElementBySelector -Selector $Selector -NoThrow:$NoThrow) + } } } catch { $seconds++ - if ($seconds -ge $timeout) { + if ($seconds -ge $Timeout) { throw $_.Exception } @@ -238,4 +253,30 @@ function Get-MonocleElementByXPath 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)>" + } } \ No newline at end of file diff --git a/src/Public/Elements.ps1 b/src/Public/Elements.ps1 index 57c2711..52c46da 100644 --- a/src/Public/Elements.ps1 +++ b/src/Public/Elements.ps1 @@ -192,7 +192,11 @@ function Test-MonocleElement [Parameter(ParameterSetName='XPath')] [string] - $XPath + $XPath, + + [Parameter(ParameterSetName='Selector')] + [string] + $Selector ) $result = $null @@ -205,13 +209,63 @@ function Test-MonocleElement -AttributeName $AttributeName ` -AttributeValue $AttributeValue ` -ElementValue $ElementValue ` - -XPath $XPath + -XPath $XPath ` + -Selector $Selector } catch { } return (($null -ne $result) -and ($null -ne $result.Element)) } +function Wait-MonocleElement +{ + [CmdletBinding(DefaultParameterSetName='Id')] + param ( + [Parameter(Mandatory=$true, ParameterSetName='Id')] + [string] + $Id, + + [Parameter(Mandatory=$true, ParameterSetName='Tag')] + [string] + $TagName, + + [Parameter(ParameterSetName='Tag')] + [string] + $AttributeName, + + [Parameter(ParameterSetName='Tag')] + [string] + $AttributeValue, + + [Parameter(ParameterSetName='Tag')] + [string] + $ElementValue, + + [Parameter(ParameterSetName='XPath')] + [string] + $XPath, + + [Parameter(ParameterSetName='Selector')] + [string] + $Selector, + + [Parameter()] + [int] + $Timeout = 600 + ) + + Get-MonocleElementInternal ` + -FilterType $PSCmdlet.ParameterSetName ` + -Id $Id ` + -TagName $TagName ` + -AttributeName $AttributeName ` + -AttributeValue $AttributeValue ` + -ElementValue $ElementValue ` + -XPath $XPath ` + -Selector $Selector ` + -Timeout $Timeout | Out-Null +} + function Get-MonocleElement { [CmdletBinding(DefaultParameterSetName='Id')] @@ -239,7 +293,11 @@ function Get-MonocleElement [Parameter(ParameterSetName='XPath')] [string] - $XPath + $XPath, + + [Parameter(ParameterSetName='Selector')] + [string] + $Selector ) # attempt to get the monocle element @@ -250,7 +308,8 @@ function Get-MonocleElement -AttributeName $AttributeName ` -AttributeValue $AttributeValue ` -ElementValue $ElementValue ` - -XPath $XPath + -XPath $XPath ` + -Selector $Selector # set the meta id on the element Set-MonocleElementId -Element $result.Element -Id $result.Id diff --git a/src/Public/Flow.ps1 b/src/Public/Flow.ps1 index 19e29a9..e489e03 100644 --- a/src/Public/Flow.ps1 +++ b/src/Public/Flow.ps1 @@ -69,9 +69,9 @@ function Start-MonocleFlow [string] $ScreenshotPath, - [Parameter(Mandatory=$true)] + [Parameter()] [OpenQA.Selenium.Remote.RemoteWebDriver] - $Browser, + $Browser = $null, [Parameter(ParameterSetName='Screenshot')] [switch] @@ -84,6 +84,12 @@ function Start-MonocleFlow # set the output depth $env:MONOCLE_OUTPUT_DEPTH = '1' + # if no browser, set chrome as default + if ($null -eq $Browser) { + $CloseBrowser = $true + $Browser = New-MonocleBrowser -Type Chrome + } + # invoke the logic try { Write-MonocleHost -Message "`nFlow: $Name" -NoIndent diff --git a/src/lib/Browsers/linux/chromedriver b/src/lib/Browsers/linux/chromedriver index eeecd35..b362f8f 100644 Binary files a/src/lib/Browsers/linux/chromedriver and b/src/lib/Browsers/linux/chromedriver differ diff --git a/src/lib/Browsers/mac/chromedriver b/src/lib/Browsers/mac/chromedriver index 4ff3bcc..df7565d 100644 Binary files a/src/lib/Browsers/mac/chromedriver and b/src/lib/Browsers/mac/chromedriver differ diff --git a/src/lib/Browsers/win/chromedriver.exe b/src/lib/Browsers/win/chromedriver.exe index ec9ce29..d419a51 100644 Binary files a/src/lib/Browsers/win/chromedriver.exe and b/src/lib/Browsers/win/chromedriver.exe differ