Quamotion.PowerShell.psm1
$prefix = "http://localhost:17894/wd/hub" $headers = @{"Content-Type" = "application/json" } $findElementDelayMilliseconds = 100 $findElementMaxAttempts = 50 $currentSessionId = $null <# .SYNOPSIS Connects to a remote WebDriver instance. .DESCRIPTION Connects to a remote WebDriver instance. The commands are forwared to the given remote url. .PARAMETER at The url of the remote WebDriver instance. .EXAMPLE ConnectTo-Quamotion -at http://qmwdjpn.quamotion.mobi/wd/hub #> function ConnectTo-Quamotion { param ([string] $at) $script:prefix = $at } function Get-WebDriverStatus { (Invoke-WebDriverRestMethod "$prefix/status" -Method Get).value } function New-DeveloperProfile { param ([string] $accountName, [string] $accountPassword, [string] $password, [string] $outFile) $createDeveloperProfileRequest = @{ AccountName = $accountName; AccountPassword = $accountPassword; Password = $password; } Invoke-WebDriverRestMethod "$prefix/quamotion/developercenter/profile" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $createDeveloperProfileRequest))) -Headers $headers -Method Put -OutFile $outFile } <# .SYNOPSIS Imports a folder containing the developer disks into the Quamotion WebDriver. .PARAMETER developerDiskImageDirectory A directory which, for each version of iOS you plan to support, contains a folder containing the developer disk image for that version and the signature for that developer disk image. .EXAMPLE Import-DeveloperDisks /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS #> function Import-DeveloperDisks { param ( [Parameter(Mandatory=$true, Position = 1)] [string] $developerDiskImageDirectory) $directories = Get-ChildItem $developerDiskImageDirectory -Directory Foreach ($directory in $directories) { $developerDiskImage = Join-Path $directory.FullName "DeveloperDiskImage.dmg" $developerDiskSignature = Join-Path $directory.FullName "DeveloperDiskImage.dmg.signature" if ((Test-Path $developerDiskImage) -and (Test-Path $developerDiskSignature)) { Write-Information "Uploading developer disk images in folder $directory)" Add-DeveloperDisk -developerDiskImage $developerDiskImage -developerDiskSignature $developerDiskSignature } else { Write-Warning "The folder $directory did not contain a DeveloperDiskImage.dmg and DeveloperDiskImage.dmg.signature file, skipping" } } } <# .SYNOPSIS Adds a developer disk to the Quamotion WebDriver. .PARAMETER developerDiskImage The developer disk image. Developer disk images are usually named DeveloperDiskImage.dmg .PARAMETER developerDiskSignature The signature file for the developer disk image. Signature files are usually named DeveloperDiskImage.dmg.signature .EXAMPLE Add-DeveloperDisk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS/11.0/DeveloperDiskImage.dmg /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS/11.0/DeveloperDiskImage.dmg.signature #> function Add-DeveloperDisk { param ( [Parameter(Mandatory=$true, Position = 1)] [string] $developerDiskImage, [Parameter(Mandatory=$true, Position = 2)] [string] $developerDiskSignature ) if (-not (Test-Path $developerDiskImage) -or -not (Test-Path $developerDiskSignature)) { Write-Error "Could not upload the developer disk because the file $developerDiskImage or $developerDiskSignature does not exist." return } try { Add-Type -AssemblyName System.Net.Http $client = New-Object System.Net.Http.HttpClient $content = New-Object System.Net.Http.MultipartFormDataContent $diskName = (Get-Item $developerDiskImage).Name $diskSignatureName = (Get-Item $developerDiskSignature).Name $diskStream = [System.IO.File]::OpenRead((Get-Item($developerDiskImage)).FullName) $diskSignature = [System.IO.File]::ReadAllBytes((Get-Item($developerDiskSignature)).FullName) $diskStreamContent = New-Object System.Net.Http.StreamContent $diskStream $diskSignatureContent = New-Object System.Net.Http.ByteArrayContent -ArgumentList @(,$diskSignature) $c = $content.Add($diskStreamContent, $diskName, $diskName) $c = $content.Add($diskSignatureContent, $diskSignatureName, $diskSignatureName) $result = $client.PostAsync("$prefix/quamotion/ios/developerDisk", $content).Result $c = $result.EnsureSuccessStatusCode() } catch { Write-Error "An error occurred while uploading $developerDiskImage and signature $developerDiskSignature" } finally { if ($diskStream) { $diskStream.Dispose() } if ($diskSignatureStream) { $diskSignatureStream.Dispose() } } } <# .SYNOPSIS Adds a developer profile to the Quamotion WebDriver .PARAMETER developerProfile The developer profile you want to add. .PARAMETER developerDiskSignature The password for the developer profile you want to add .EXAMPLE Add-DeveloperProfile company.developerprofile securepassword #> function Add-DeveloperProfile { param ( [Parameter(Mandatory=$true, Position = 1)] [string] $developerProfile, [Parameter(Mandatory=$true, Position = 2)] [string] $password ) if (-not (Test-Path $developerProfile)) { Write-Error "Could not upload the developer profile because the file $developerProfile does not exist." return } try { Add-Type -AssemblyName System.Net.Http $client = New-Object System.Net.Http.HttpClient $content = New-Object System.Net.Http.MultipartFormDataContent $passwordContent = New-Object System.Net.Http.StringContent $password $profileStream = [System.IO.File]::OpenRead($developerProfile) $profileStreamContent = New-Object System.Net.Http.StreamContent $profileStream $c = $content.Add($passwordContent, "password") $c = $content.Add($profileStreamContent, "profile", "profile") $result = $client.PostAsync("$prefix/quamotion/ios/developerProfile", $content).Result $c = $result.EnsureSuccessStatusCode() } catch { Write-Error "An error occurred while uploading $developerProfile" } finally { $profileStream.Dispose() } } <# .SYNOPSIS Lists all iOS developer certificates available to Quamotion WebDriver .EXAMPLE Get-DeveloperCertificate #> function Get-DeveloperCertificate { return (Invoke-WebDriverRestMethod "$prefix/quamotion/ios/certificates" -Method Get) } <# .SYNOPSIS Lists all iOS prvisioning profiles available to Quamotion WebDriver .EXAMPLE Get-ProvisioningProfile #> function Get-ProvisioningProfile { return (Invoke-WebDriverRestMethod "$prefix/quamotion/ios/provisioningProfiles" -Method Get) } <# .SYNOPSIS Uploads a license for the Quamotion WebDriver. .PARAMETER license The license file. .EXAMPLE Add-License quamotion.license #> function Add-License { param ( [Parameter(Mandatory=$true, Position = 1)] [string] $license ) if (-not (Test-Path $license) ) { Write-Error "Could not upload the license because the file $license does not exist." return } try { Add-Type -AssemblyName System.Net.Http $client = New-Object System.Net.Http.HttpClient $content = New-Object System.Net.Http.MultipartFormDataContent # Use -Force to support hidden files (e.g. wildcard .license files are considered # hidden on Linux) $licenseStream = [System.IO.File]::OpenRead((Get-Item $license -Force).FullName) $licenseContent = New-Object System.Net.Http.StreamContent $licenseStream $c = $content.Add($licenseContent, "files", "quamotion.license") $result = $client.PostAsync("$prefix/quamotion/license", $content).Result $c = $result.EnsureSuccessStatusCode() } catch { Throw # Write-Error "An error occurred while uploading $license" } finally { if ($licenseStream) { $licenseStream.Dispose() } } } <# .SYNOPSIS List sessions on a device based on the application type and status. .DESCRIPTION List sessions on a device based on the application type and status. .PARAMETER SessionId The device id. (Optional) the application type (Native, Web, Device, All). (Optional) The session status (Unknown, Creating, Deploying, DeployFailed, Running, Stopping, StopFailed, All). .EXAMPLE Get-DeviceSessions -deviceId FUH7N16709007219 #> Function Get-DeviceSessions { param ( [string] $deviceId, [string] $applicationType = 'All', [string] $status = 'All') return Get-Sessions | Where-Object {$_.Device.uniqueId -eq $deviceid -and ($_.Status -eq $status -or $status -eq 'All') -and ($_.Capabilities.applicationType -eq $applicationType -or $applicationType -eq 'All')} } <# .SYNOPSIS Retrieve the current window handle. .DESCRIPTION Retrieve the current window handle. Returns: The current window handle. NoSuchWindow - If the currently selected window has been closed. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Get-WindowHandle #> function Get-WindowHandle { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId return (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/window_handle").value } <# .SYNOPSIS Retrieve the list of all window handles available to the session. .DESCRIPTION Retrieve the list of all window handles available to the session. Returns: A list of window handles. The order in which the window handles are returned is arbitrary. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Get-WindowHandles #> function Get-WindowHandles { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId return (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/window_handles").value } <# .SYNOPSIS Gets the size of the current window. .DESCRIPTION Gets the size of the current window. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Get-WindowSize #> function Get-WindowSize { param([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId return (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/window/size").value } <# .SYNOPSIS Change focus to another window. .DESCRIPTION Change focus to another window. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER windowName The window to change focus to. .EXAMPLE Set-Window "Native" #> function Set-Window { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [string] $windowName) Test-SessionId $sessionId $setWindowRequest = @{ Name = $windowName; } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/window" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $setWindowRequest))) -Headers $headers -Method Post } <# .SYNOPSIS Close the current window. .DESCRIPTION Close the current window. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Close-Window #> function Close-Window { param ( [string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId Invoke-WebDriverRestMethod "$prefix/session/$sessionId/window" -Method Delete } <# .SYNOPSIS Get the current page source. .DESCRIPTION Get the current page source. Returns: the current page source. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Get-Source #> function Get-Source { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId return (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/source").value } <# .SYNOPSIS Navigate to a new URL. .DESCRIPTION Navigate to a new URL. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER url The URL to navigate to. .EXAMPLE Navigate-To -url "http:\\quamotion.mobi" #> function Navigate-To { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [string] $url) Test-SessionId $sessionId $elementRequest = @{ url = $url; } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/url" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $elementRequest))) -Headers $headers -Method Post } <# .SYNOPSIS Reloads the current webpage. .DESCRIPTION Reloads the current webpage optionally ignoring the cache. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER ignoreCache If true, browser cache is ignored (as if the user pressed Shift+refresh). .EXAMPLE Reload-Page #> function Reload-Page { param ([string] $sessionId = $script:currentSessionId, [bool] $ignoreCache = $true) Test-SessionId $sessionId $reloadRequest = @{ ignoreCache = $ignoreCache; } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/refresh" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $reloadRequest))) -Headers $headers -Method Post } <# .SYNOPSIS Retrieve the URL of the current page. .DESCRIPTION Retrieve the URL of the current page. Returns: the current url. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Get-Url #> function Get-Url { param ( [string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId $url = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/url" -Headers $headers -Method Get).value return $url } <# .SYNOPSIS Search for the top element in the current window on position (x, y). .DESCRIPTION Search for the top element in the current window on position (x, y). The coordinates are expressed in pixels and measured from the top left corner. Returns: the element on position (x, y) .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER x The x coordinate .PARAMETER y the y coordinate .EXAMPLE Find-ElementByCoordinate -x 200 -y 500 #> function Find-ElementByCoordinate { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [int] $x, [Parameter(Mandatory=$true, Position = 2)] [int] $y) Test-SessionId $sessionId $elementRequest = @{ x = $x; y = $y; } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/elementByCoordinates" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $elementRequest))) -Headers $headers -Method Post } <# .SYNOPSIS Search for a element whose identifier matches the given value. .DESCRIPTION Search for element whose identifier attribute matches the given value. Returns: the first element whose identifier attribute matches the given value. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER id The indentifier of the element to search. .EXAMPLE Find-ElementById -id 123456 #> function Find-ElementById { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [string] $id) Test-SessionId $sessionId $elementRequest = @{ using = "id"; value = $id; } $element = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/elements" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $elementRequest))) -Headers $headers -Method Post).value if($element.Length -gt 1) { Write-Warning "More than one element has element id: $id" } Write-Verbose "Element $($id): $element[0].ELEMENT" return $element[0].ELEMENT } <# .SYNOPSIS Search for all elements whose identifier matches the given value. .DESCRIPTION Search for all elements whose identifier attribute matches the given value. Returns: all elements whose identifier attribute matches the given value. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER id The indentifier of the element to search. .EXAMPLE Find-ElementsById -id 123456 #> function Find-ElementsById { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [string] $id) Test-SessionId $sessionId $elementRequest = @{ using = "id"; value = $id; } $elements = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/elements" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $elementRequest))) -Headers $headers -Method Post).value return $elements } <# .SYNOPSIS Go back, if possible. .DESCRIPTION Go back, if possible. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Go-Back #> function Go-Back { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId Write-Verbose "Clicking back button" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/back" -Headers $headers -Method Post } <# .SYNOPSIS Go to the home screen .DESCRIPTION Go to the home screen (only for Full Device Automation sessions) .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Go-ToHomeScreen #> function Go-ToHomeScreen { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId Invoke-WebDriverRestMethod "$prefix/session/$sessionId/wda/homescreen" -Headers $headers -Method Post } <# .SYNOPSIS Tests whether elements exist matching the given xpath. .DESCRIPTION Tests whether elements exist matching the given xpath. Test-Elements does not take the implicit timeout into account. Returns: $true or $false depending on the existens of the element. Throws exception when the element is not found because there is a popup present. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER xpath The xpath for which to test the element. .PARAMETER ignoreVisibility (Optional) indicates whether non visible elements should be taken into account. .EXAMPLE Test-Elements -xpath "*[@marked='login']" #> function Test-Elements { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1, ParameterSetname = "xpath")] [string] $xpath, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [LocatorStrategy] $using, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [string] $value, [Parameter(Mandatory=$false)] [bool] $ignoreVisibility = $false) Test-SessionId $sessionId if($xpath) { $elementRequest = @{ using = "xpath"; value = $xpath; ignoreVisibility = $ignoreVisibility; } } else { $elementRequest = @{ using = $using; value = $value; ignoreVisibility = $ignoreVisibility; } } try { $response = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/elements" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $elementRequest))) -Headers $headers -Method Post) $element = $response.value return $element.Length -gt 0 } catch { # check if there is an alert obstructing the call If(($_.Exception.GetType() -eq [WebDriverException]) -and $_.Exception.Status -eq 7) { return $false } Else { throw $_ } } } <# .SYNOPSIS Tests whether an element exist matching the given xpath .DESCRIPTION Tests whether an element exist matching the given xpath Returns: $true or $false depending on the existens of the element. Throws exception when the element is not found because there is a popup present. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER xpath The xpath for which to test the element. .PARAMETER ignoreVisibility (Optional) indicates whether non visible elements should be taken into account. .EXAMPLE Test-Element -xpath "*[@marked='login']" #> function Test-Element { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1, ParameterSetname = "xpath")] [string] $xpath, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [LocatorStrategy] $using, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [string] $value, [Parameter(Mandatory=$false)] [bool] $ignoreVisibility = $false) Test-SessionId $sessionId if($xpath) { $elementRequest = @{ using = "xpath"; value = $xpath; ignoreVisibility = $ignoreVisibility; } } else { $elementRequest = @{ using = $using; value = $value; ignoreVisibility = $ignoreVisibility; } } try { $response = (Invoke-WebDriverRestMethod “$prefix/session/$sessionId/element” -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $elementRequest))) -Headers $headers -Method Post) $element = $response.value return $element -ne $null } catch { # Did we find elements? If(($_.Exception.GetType() -eq [WebDriverException]) -and $_.Exception.Status -eq 7) { return $false } Else { throw $_ } } } <# .SYNOPSIS Search for all elements whose xpath matches the given value. .DESCRIPTION Search for all elements whose xpath attribute matches the given value. Returns: all elements whose xpath attribute matches the given value. Throws exception when there is a popup present. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER xpath The xpath used to locate elements. .PARAMETER ignoreVisibility (Optional) indicates whether non visible elements should be taken into account. .PARAMETER parentElement (Optional) limits the search to only descendants of this element. .EXAMPLE Find-Elements -xpath "*[@marked='login']" #> function Find-Elements { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1, ParameterSetname = "xpath")] [string] $xpath, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [LocatorStrategy] $using, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [string] $value, [Parameter(Mandatory=$false)] [bool] $ignoreVisibility = $false, [Parameter(Mandatory=$false)] [string] $parentElement = $null) Test-SessionId $sessionId if($xpath) { $elementRequest = @{ using = "xpath"; value = $xpath; ignoreVisibility = $ignoreVisibility; } } else { $elementRequest = @{ using = $using; value = $value; ignoreVisibility = $ignoreVisibility; } } Try { if ($parentElement) { $path = "$prefix/session/$sessionId/element/$parentElement/elements" } else { $path = "$prefix/session/$sessionId/elements" } } catch { If(($_.Exception.GetType() -eq [WebDriverException]) -and $_.Exception.Status -eq 7) { return @() } Else { throw $_ } } Try { $elements = (Invoke-WebDriverRestMethod $path -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $elementRequest))) -Headers $headers -Method Post).value return $elements } catch { # check if there is an alert obstructing the call If(($_.Exception.GetType() -eq [WebDriverException]) -and $_.Exception.Status -eq 7) { return @() } Else { throw $_ } } } <# .SYNOPSIS Search for an element whose xpath matches the given value. .DESCRIPTION Search for an element whose xpath attribute matches the given value. Returns: the first element whose xpath attribute matches the given value. This method will wait for the element to appear on your application during the amount of time specified by Set-Timeout. Throws an exception there is no element found matching the given xpath. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER xpath The xpath used to locate elements. .PARAMETER ignoreVisibility (Optional) indicates whether non visible elements should be taken into account. .PARAMETER parentElement (Optional) limits the search to only descendants of this element. .EXAMPLE Find-Element -xpath "*[@marked='login']" #> function Find-Element { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1, ParameterSetName = "xpath")] [string] $xpath, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [LocatorStrategy] $using, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [string] $value, [Parameter(Mandatory=$false)] [bool] $ignoreVisibility = $false, [Parameter(Mandatory=$false)] [string] $parentElement = $null) Test-SessionId $sessionId if($xpath) { $elementRequest = @{ using = "xpath"; value = $xpath; ignoreVisibility = $ignoreVisibility; } } else { $elementRequest = @{ using = $using; value = $value; ignoreVisibility = $ignoreVisibility; } } if ($parentElement) { $path = "$prefix/session/$sessionId/element/$parentElement/element" } else { $path = "$prefix/session/$sessionId/element" } $response = (Invoke-WebDriverRestMethod $path -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $elementRequest))) -Headers $headers -Method Post).value $element = $response.ELEMENT Write-Verbose "Element $xpath has ID $element" return $element } <# .SYNOPSIS Double clicks on the first element whose locator matches the given value. .DESCRIPTION Double clicks on the first element whose locator matches the given value. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER xpath The xpath used to locate the element. .PARAMETER Marked The marked attribute value used to locate the element. .PARAMETER Class The class attribute value used to locate the element. .EXAMPLE DoubleClick-Element -xpath "*[@marked='login']" DoubleClick-Element -marked "login" DoubleClick-Element -class "UIView" #> function DoubleClick-Element { param ( [Parameter(ParameterSetName = "ElementId")] [Parameter(ParameterSetName = "Marked")] [Parameter(ParameterSetName = "XPath")] [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, ParameterSetName = "ElementId", ValueFromPipeline=$True)] [string] $elementId, [Parameter(Mandatory=$true, ParameterSetName = "XPath")] [string] $xpath, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [LocatorStrategy] $using, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [string] $value, [Parameter(Mandatory=$true, ParameterSetName = "Marked")] [string] $marked) Test-SessionId $sessionId if ($elementId) { $id = $elementId } elseif ($xpath) { Write-Verbose "Clicking on element $xpath" $id = Find-Element -sessionId $sessionId -xpath $xpath } elseif ($marked) { Write-Verbose "Clicking on element marked $marked" $id = Find-Element -sessionId $sessionId -xpath "*[@marked='$marked']" } Else{ Write-Verbose "Clicking on element with value $value using $using" $id = Find-Element -sessionId $sessionId -value $value -using $using } if ($id -And $id -ne $null -And $id -ne "") { $doubleClickRequest = @{ element = $id } Write-Verbose "Double click on element $id" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/touch/doubleclick" -Headers $headers -Body (ConvertTo-Json $doubleClickRequest) -Method Post } else { Report-Status -message "No matching element found." -succes $false } } <# .SYNOPSIS Clicks on the first element whose locator matches the given value. .DESCRIPTION Clicks on the first element whose locator matches the given value. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER xpath The xpath used to locate elements. .PARAMETER Marked The marked attribute value used to locate elements. .PARAMETER Class The class attribute value used to locate elements. .EXAMPLE Click-Element -xpath "*[@marked='login']" Click-Element -marked "login" Click-Element -class "UIView" #> function Click-Element { param ( [Parameter(ParameterSetName = "ElementId")] [Parameter(ParameterSetName = "Marked")] [Parameter(ParameterSetName = "XPath")] [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, ParameterSetName = "ElementId", ValueFromPipeline=$True)] [string] $elementId, [Parameter(Mandatory=$true, ParameterSetName = "XPath")] [string] $xpath, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [LocatorStrategy] $using, [Parameter(Mandatory=$true, ParameterSetName = "explicit")] [string] $value, [Parameter(Mandatory=$true, ParameterSetName = "Marked")] [string] $marked) Test-SessionId $sessionId if ($elementId) { Write-Verbose "Clicking on element $elementId" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/click" -Headers $headers -Method Post } else { if ($xpath) { Write-Verbose "Clicking on element $xpath" $id = Find-Element -sessionId $sessionId -xpath $xpath } elseif ($marked) { Write-Verbose "Clicking on element marked $marked" $id = Find-Element -sessionId $sessionId -xpath "*[@marked='$marked']" } Else{ Write-Verbose "Clicking on element with value $value using $using" $id = Find-Element -sessionId $sessionId -value $value -using $using } if ($id -And $id -ne $null -And $id -ne "") { Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$id/click" -Headers $headers -Method Post } else { Report-Status -message "No element found for $xpath" -succes $false } } } function Submit-Element { param ( [Parameter(ParameterSetName = "ElementId")] [Parameter(ParameterSetName = "Marked")] [Parameter(ParameterSetName = "XPath")] [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, ParameterSetName = "ElementId", ValueFromPipeline=$True)] [string] $elementId, [Parameter(Mandatory=$true, ParameterSetName = "XPath")] [string] $xpath) Test-SessionId $sessionId if ($elementId) { Write-Verbose "Clicking on element $elementId" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/submit" -Headers $headers -Method Post } elseif ($xpath) { Write-Verbose "Clicking on element $xpath" $id = Find-Element -sessionId $sessionId -xpath $xpath Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$id/submit" -Headers $headers -Method Post } } <# .SYNOPSIS Gets the value of an element property. .DESCRIPTION Gets the value of an element property. Returns: the value of the property .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The identifier of the element to query. .PARAMETER property The property name to query. .EXAMPLE Get-ElementProperty 12345 "Text" Find-Element "login" | Get-ElementProperty "Text" #> function Get-ElementProperty { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1, ValueFromPipeline)] [string] $elementId, [Parameter(Mandatory=$true, Position = 2)] [string] $property) begin { Test-SessionId $sessionId } Process { $text = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/property/$property" -Headers $headers -Method Get).value $text } } <# .SYNOPSIS Gets all property names of an element. .DESCRIPTION Gets all property names of an element. Returns: all property names of an element. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The identifier of the element to query. .EXAMPLE Get-ElementProperties 12345 Find-Element "login" | Get-ElementProperties #> function Get-ElementProperties { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1, ValueFromPipeline)] [string] $elementId) Test-SessionId $sessionId $text = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/property" -Headers $headers -Method Get).value return $text } <# .SYNOPSIS Gets the text value of an element. .DESCRIPTION Gets the text value of an element. Returns: the text value of an element. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The identifier of the element to query. .EXAMPLE Find-Element "login" | Get-ElementText #> function Get-ElementText { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1, ValueFromPipeline)] [string] $elementId) Test-SessionId $sessionId $text = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/text" -Headers $headers -Method Get).value return $text } function Get-MapMarkers { param ( [string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId $markers = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/map/markers" -Headers $headers -Method Get).value return $markers } function Get-MapBounds { param ( [string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId $bounds = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/map/bounds" -Headers $headers -Method Get).value return $bounds } function Get-MapCenter { param ( [string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId $position = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/map/center" -Headers $headers -Method Get).value return $position } function Get-MapZoom { param ( [string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId $zoom = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/map/zoom" -Headers $headers -Method Get).value return $zoom } function Set-MapZoom { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [int] $level) Test-SessionId $sessionId Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/map/zoom" -Headers $headers -Body (ConvertTo-Json $level) -Method Post } function Set-MapCenter { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [double] $latitude, [Parameter(Mandatory=$true, Position = 2)] [double] $longitude) Test-SessionId $sessionId $position = @{ latitude = $latitude; longitude = $longitude; } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/map/center" -Headers $headers -Body (ConvertTo-Json $position) -Method Post return $zoom } <# .SYNOPSIS Gets the bounds of an element. .DESCRIPTION Gets the bounds of an element. Returns: a rectangle reprenting the outer bounds of an element. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The identifier of the element to query. .EXAMPLE Find-Element "login" | Get-ElementRectangle #> function Get-ElementRectangle { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [string] $elementId) Test-SessionId $sessionId $rectangle = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/rect" -Headers $headers -Method Get).value $displayed = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/displayed" -Headers $headers -Method Get).value return @{ X = $rectangle.X; Y = $rectangle.Y; Width = $rectangle.Width; Height = $rectangle.Height; Displayed = $displayed; } } <# .SYNOPSIS Performs a long click on the first element whose locator matches the given value. .DESCRIPTION Performs a long click on the first element whose locator matches the given value. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The identifier of the element to click. .EXAMPLE Find-Element -marked "Login" | LongClick-Element #> function LongClick-Element { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [string] $elementId) Test-SessionId $sessionId $flickRequest = @{ element = $elementId } Write-Verbose "Long clicking on element $elementId" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/touch/longclick" -Headers $headers -Body (ConvertTo-Json $flickRequest) -Method Post } <# .SYNOPSIS Performs a flick based on coordinates. .DESCRIPTION Performs a flick based on coordinates. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The identifier of the element. .PARAMETER x x coordinate of the start point relative from the element .PARAMETER y y coordinate of the start point relative from the element .PARAMETER xoffset the horizontal distance to flick .PARAMETER xoffset the vertical distance to flick .PARAMETER speed the speed of the flick movement .EXAMPLE Flick-Coordinate -elementId 12244 -x 100 -y 100 -xoffset 0 -yoffset -300 #> function Flick-Coordinate { param ( [Parameter(ParameterSetName = "ElementId")] [Parameter(ParameterSetName = "Marked")] [Parameter(ParameterSetName = "XPath")] [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, ParameterSetName = "ElementId", ValueFromPipeline=$True)] [string] $elementId, [Parameter(Mandatory=$true, ParameterSetName = "XPath")] [string] $xpath, [Parameter(Mandatory=$true, ParameterSetName = "Marked")] [string] $marked, [Parameter(Mandatory=$true)] [int] $x, [Parameter(Mandatory=$true)] [int] $y, [Parameter(Mandatory=$true)] [int] $xoffset, [Parameter(Mandatory=$true)] [int] $yoffset, [Parameter(Mandatory=$true)] [int] $speed) Test-SessionId $sessionId if ($elementId) { Write-Verbose "Flick on element $elementId" $id = $elementId } elseif ($xpath) { Write-Verbose "Flick on element $xpath" $id = Find-Element -sessionId $sessionId -xpath $xpath } else { Write-Verbose "Flick on element marked $marked" $id = Find-Element -sessionId $sessionId -xpath "*[@marked='$marked']" } $flickRequest = @{ element = $id; xCoordinate = $x; yCoordinate = $y; yoffset = $yoffset; xoffset = $xoffset; speed = $speed; } Write-Verbose "Flicking on element $elementId" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/touch/flick" -Headers $headers -Body (ConvertTo-Json $flickRequest) -Method Post } <# .SYNOPSIS Performs a flick on an element. .DESCRIPTION Performs a flick on an element identified by one of the available locators. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId (id locator) The identifier of the element. .PARAMETER xpath (xpath locator) The xpath of the element .PARAMETER marked (marked locator) The marked expression of the element .PARAMETER direction the direction to flick .PARAMETER delta the distance to flick .PARAMETER speed the speed of the flick movement .EXAMPLE Flick-ElementByDirection -marked "login" -direction left -speed 30 #> function Flick-ElementByDirection { param ( [Parameter(ParameterSetName = "ElementId")] [Parameter(ParameterSetName = "Marked")] [Parameter(ParameterSetName = "XPath")] [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, ParameterSetName = "ElementId", ValueFromPipeline=$True)] [string] $elementId, [Parameter(Mandatory=$true, ParameterSetName = "XPath")] [string] $xpath, [Parameter(Mandatory=$true, ParameterSetName = "Marked")] [string] $marked, [Parameter(Mandatory=$true)] [int] $speed, [ValidateSet("up", "down", "left", "right")] [Parameter(Mandatory=$true)] [string] $direction, [int] $delta) Test-SessionId $sessionId if ($elementId) { Write-Verbose "Flick on element $elementId" $id = $elementId } elseif ($xpath) { Write-Verbose "Flick on element $xpath" $id = Find-Element -sessionId $sessionId -xpath $xpath } else { Write-Verbose "Flick on element marked $marked" $id = Find-Element -sessionId $sessionId -xpath "*[@marked='$marked']" } $flickRequest = @{ element = $id; speed = $speed; direction = $direction; delta = $delta } Write-Verbose "Flicking on element $elementId" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/touch/flick" -Headers $headers -Body (ConvertTo-Json $flickRequest) -Method Post } <# .SYNOPSIS Performs a flick on an element. .DESCRIPTION Performs a flick on an element identified by one of the available locators. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId (id locator) The identifier of the element. .PARAMETER xpath (xpath locator) The xpath of the element .PARAMETER marked (marked locator) The marked expression of the element .PARAMETER xOffset the horizontal distance to flick .PARAMETER yOffset the vertical distance to flick .PARAMETER speed the speed of the flick movement .EXAMPLE Flick-Element -marked "login" -xoffset 0 -yoffset -300 -speed 30 #> function Flick-ElementByOffset { param ( [Parameter(ParameterSetName = "ElementId")] [Parameter(ParameterSetName = "Marked")] [Parameter(ParameterSetName = "XPath")] [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, ParameterSetName = "ElementId", ValueFromPipeline=$True)] [string] $elementId, [Parameter(Mandatory=$true, ParameterSetName = "XPath")] [string] $xpath, [Parameter(Mandatory=$true, ParameterSetName = "Marked")] [string] $marked, [Parameter(Mandatory=$true)] [int] $xOffset, [Parameter(Mandatory=$true)] [int] $yOffset, [Parameter(Mandatory=$true)] [int] $speed) Test-SessionId $sessionId if ($elementId) { Write-Verbose "Flick on element $elementId" $id = $elementId } elseif ($xpath) { Write-Verbose "Flick on element $xpath" $id = Find-Element -sessionId $sessionId -xpath $xpath } else { Write-Verbose "Flick on element marked $marked" $id = Find-Element -sessionId $sessionId -xpath "*[@marked='$marked']" } $flickRequest = @{ element = $id; yoffset = $yOffset; xoffset = $xOffset; speed = $speed; } Write-Verbose "Flicking on element $elementId" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/touch/flick" -Headers $headers -Body (ConvertTo-Json $flickRequest) -Method Post } <# .SYNOPSIS Performs a click on a coordinate. .DESCRIPTION Performs a click on a coordinate. The coordinate is measured from the top left corner of the screen. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER x x coordinate of the start point relative from the element .PARAMETER y y coordinate of the start point relative from the element s.EXAMPLE Click-Coordinate -x 100 -y 100 #> function Click-Coordinate { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [int] $x, [Parameter(Mandatory=$true, Position = 2)] [int] $y) Test-SessionId $sessionId $clickRequest = @{ y = $y; x = $x; } Write-Verbose "Clicking on coodinate ($x, $y)" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/touch/clickByCoordinate" -Headers $headers -Body (ConvertTo-Json $clickRequest) -Method Post } <# .SYNOPSIS Send a sequence of key strokes to the active element. .DESCRIPTION Send a sequence of key strokes to the active element. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER text The keys sequence to be sent. .EXAMPLE Enter-Text "Quamotion" #> function Enter-Text { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [string] $text) Test-SessionId $sessionId $keysRequest = @{ value = @($text); } Write-Verbose "Typing $text" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/keys" -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $keysRequest))) -Method Post } function Set-ElementProperty { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1, ValueFromPipeline)] [string] $elementId, [Parameter(Mandatory=$true, Position = 2)] [string] $propertyName, [Parameter(Mandatory=$true, Position = 3)] [object] $propertyValue) Test-SessionId $sessionId $request = @{ propertyName = $propertyName; propertyValue = $propertyValue; } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/property" -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $request))) -Method Post } function Perform-Operation { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1, ValueFromPipeline)] [string] $elementId, [Parameter(Mandatory=$true, Position = 2)] [string] $operation, [Parameter(Mandatory=$true, Position = 3)] [object[]] $arguments) Test-SessionId $sessionId $request = @{ operation = $operation; args = $arguments; } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/perform" -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $request))) -Method Post } <# .SYNOPSIS Gets the current session identifier. .DESCRIPTION Gets the current session identifier. Returns: the current session identifiers .EXAMPLE Get-CurrentSessionId #> function Get-CurrentSessionId { return $script:currentSessionId } <# .SYNOPSIS Sets the current session identifier. .DESCRIPTION Sets the current session identifier. .PARAMETER sessionId The identifier of the session to be used. .EXAMPLE Set-CurrentSessionId -sessionId "e68ef189-cd1b-4def-a1e2-1b4e1f1526df" #> function Set-CurrentSessionId { param ( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName)] [string] $sessionId) $script:currentSessionId = $sessionId } <# .SYNOPSIS Create a new session. .DESCRIPTION Create a new session. The session will install and launch the application on the device. .PARAMETER deviceId The identifier of the device to be used. This identifier can be queried by perfoming the Get-Device commmand or by clicking on the device in the frontend. .PARAMETER appId The identifier of the application to be used. This identifier can be queried by perfoming the Get-App commmand or by clicking on the application in the frontend. .PARAMETER appVersion The version of the application to be used. The version can be queried by perfoming the Get-App commmand or by clicking on the application in the frontend. .PARAMETER appVersion The version of the application to be used. The version can be queried by perfoming the Get-App commmand or by clicking on the application in the frontend. .PARAMETER clearAppSettings Indicates whether the application settions should be cleared before installing the application. .PARAMETER reinstallApplication Indicates whether the application should reinstalled. .PARAMETER reuseExistingSession Indicates whether an existing session should be reused. A session is only reused when the appId, appVersion and deviceId are equal .EXAMPLE New-Session -appId demo.quamotion.Acquaint -appVersion "1.51" -deviceId $iPhone6 -reuseExistingSession $true #> function New-Session { param ( [Parameter(Mandatory=$false)] [string] $appVersion = $null, [Parameter(Mandatory=$false)] [bool] $clearAppSettings = $false, [Parameter(Mandatory=$false)] [bool] $reinstallApplication = $false, [Parameter(Mandatory=$false)] [bool] $reuseExistingSession = $false, [Parameter(Mandatory=$false)] [bool] $recordingPrestart = $false, [Parameter(Mandatory=$false)] [bool] $takesScreenshot = $true) DynamicParam { # Create the dictionary for all the parameters $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary ## Device Id # Set the dynamic parameters' name $DeviceIdParameterName = 'deviceId' # Create the collection of attributes $DeviceIdAttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] # Create and set the parameters' attributes $DeviceIdParameterAttribute = New-Object System.Management.Automation.ParameterAttribute $DeviceIdParameterAttribute.Mandatory = $true # Add the attributes to the attributes collection $DeviceIdAttributeCollection.Add($DeviceIdParameterAttribute) # Generate and set the ValidateSet $devices = Get-Device $DeviceIdArrSet = $devices | Select-Object -ExpandProperty uniqueId $DeviceIdValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($DeviceIdArrSet) # Add the ValidateSet to the attributes collection $DeviceIdAttributeCollection.Add($DeviceIdValidateSetAttribute) # Create and return the dynamic parameter $DeviceIdRuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($DeviceIdParameterName, [string], $DeviceIdAttributeCollection) $RuntimeParameterDictionary.Add($DeviceIdParameterName, $DeviceIdRuntimeParameter) ## AppId # Set the dynamic parameters' name $AppIdParameterName = 'appId' # Create the collection of attributes $AppIdAttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] # Create and set the parameters' attributes $AppIdParameterAttribute = New-Object System.Management.Automation.ParameterAttribute $AppIdParameterAttribute.Mandatory = $true # Add the attributes to the attributes collection $AppIdAttributeCollection.Add($AppIdParameterAttribute) # Generate and set the ValidateSet $apps = Get-App $AppIdArrSet = $apps | Select-Object -ExpandProperty AppId $AppIdValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($AppIdArrSet) # Add the ValidateSet to the attributes collection $AppIdAttributeCollection.Add($AppIdValidateSetAttribute) # Create and return the dynamic parameter $AppIdRuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($AppIdParameterName, [string], $AppIdAttributeCollection) $RuntimeParameterDictionary.Add($AppIdParameterName, $AppIdRuntimeParameter) return $RuntimeParameterDictionary } begin { # Bind the parameter to a friendly variable $deviceId = $PsBoundParameters[$DeviceIdParameterName] $appId = $PsBoundParameters[$AppIdParameterName] } process { if(!$appVersion) { $sessionRequest = @{ RequiredCapabilities = @{ deviceId = $deviceId; applicationType = "Native"; appId = $appId; clearApplicationSettings = $clearAppSettings; reinstallApplication = $reinstallApplication; recordingPrestart = $recordingPrestart; reuseExistingSession = $reuseExistingSession; takesScreenshot = $takesScreenshot; } } } else { $sessionRequest = @{ RequiredCapabilities = @{ deviceId = $deviceId; applicationType = "Native"; appId = $appId; appVersion = $appVersion; clearApplicationSettings = $clearAppSettings; reinstallApplication = $reinstallApplication; recordingPrestart = $recordingPrestart; reuseExistingSession = $reuseExistingSession; takesScreenshot = $takesScreenshot; } } } $createSessionResponse = Invoke-WebDriverRestMethod "$prefix/session" -Headers $headers -Body (ConvertTo-Json $sessionRequest) -Method Post $sessionId = $createSessionResponse.sessionId # Wait for the session to start while (-not (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/isReady").value) { # Get detailed status information $status = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/status").value # Break this loop if Status is DeployFailed or be stuck forever if($status.Status -eq "DeployFailed") { Throw "Deploy session failed: $($status.StatusMessage)" } # Filter duplicate messages in the output, unless verbose flag is set if(($statusOld -ne $status.Status) -or ($statusMessageOld -ne $status.StatusMessage)) { Write-Host "The session $($sessionId) is $($status.Status): $($status.StatusMessage)" $statusOld = $status.Status $statusMessageOld = $status.StatusMessage } else { Write-Verbose "The session $($sessionId) is $($status.Status): $($status.StatusMessage)" } Start-Sleep -Milliseconds 1000 } if ($script:currentSessionId -ne $null) { Write-Warning "Overriding the currently set default session" } else { Write-Information "Using this session as your default session" } $script:currentSessionId = $sessionId return $sessionId } } <# .SYNOPSIS Removes a session .DESCRIPTION Removes a session. The application is closed. .PARAMETER sessionId (Optional) The identifier of the session to be used. .EXAMPLE Remove-Session #> function Remove-Session { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId Invoke-WebDriverRestMethod "$prefix/session/$sessionId" -Method Delete $script:currentSessionId = $null } <# .SYNOPSIS Gets all active session .DESCRIPTION Gets all active sessions Returns: all active sessions .EXAMPLE Get-Sessions #> function Get-Sessions { return (Invoke-WebDriverRestMethod -Uri "$prefix/sessions").value } function Get-EndPoints { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId $endPoints = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/endPoints" -Headers $headers -Method Get).value return $endPoints } function New-WebSession { param ( [Parameter(Mandatory=$true)] [string] $deviceId, [bool] $clearAppSettings = $false, [Parameter(Mandatory=$false)] [bool] $takesScreenshot = $true) $sessionRequest = @{ RequiredCapabilities = @{ deviceId = $deviceId; applicationType = "Web"; clearApplicationSettings = $clearAppSettings; takesScreenshot = $takesScreenshot; } } $createSessionResponse = Invoke-WebDriverRestMethod "$prefix/session" -Headers $headers -Body (ConvertTo-Json $sessionRequest) -Method Post $sessionId = $createSessionResponse.sessionId # Wait for the session to start while (-not (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/isReady").value) { # Get detailed status information $status = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/status").value # Break this loop if Status is DeployFailed or be stuck forever if($status.Status -eq "DeployFailed") { Throw "Deploy session failed: $($status.StatusMessage)" } # Filter duplicate messages in the output, unless verbose flag is set if(($statusOld -ne $status.Status) -or ($statusMessageOld -ne $status.StatusMessage)) { Write-Host "The session $($sessionId) is $($status.Status): $($status.StatusMessage)" $statusOld = $status.Status $statusMessageOld = $status.StatusMessage } else { Write-Verbose "The session $($sessionId) is $($status.Status): $($status.StatusMessage)" } Start-Sleep -Milliseconds 1000 } if ($script:currentSessionId -ne $null) { Write-Warning "Overriding the currently set default session" } else { Write-Information "Using this session as your default session" } $script:currentSessionId = $sessionId return $sessionId } <# .SYNOPSIS Starts a session which allows you to automate the entire device. .DESCRIPTION Starts a session which allows you to automate the entire device. .EXAMPLE New-DeviceSession "device-udid-here" #> function New-DeviceSession { param ( [Parameter(Mandatory=$false)] [bool] $reuseExistingSession = $false, [Parameter(Mandatory=$false)] [bool] $takesScreenshot = $true ) DynamicParam { # Create the dictionary for all the parameters $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary ## Device Id # Set the dynamic parameters' name $DeviceIdParameterName = 'deviceId' # Create the collection of attributes $DeviceIdAttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] # Create and set the parameters' attributes $DeviceIdParameterAttribute = New-Object System.Management.Automation.ParameterAttribute $DeviceIdParameterAttribute.Mandatory = $true # Add the attributes to the attributes collection $DeviceIdAttributeCollection.Add($DeviceIdParameterAttribute) # Generate and set the ValidateSet $devices = Get-Device $DeviceIdArrSet = $devices | Select-Object -ExpandProperty uniqueId $DeviceIdValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($DeviceIdArrSet) # Add the ValidateSet to the attributes collection $DeviceIdAttributeCollection.Add($DeviceIdValidateSetAttribute) # Create and return the dynamic parameter $DeviceIdRuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($DeviceIdParameterName, [string], $DeviceIdAttributeCollection) $RuntimeParameterDictionary.Add($DeviceIdParameterName, $DeviceIdRuntimeParameter) return $RuntimeParameterDictionary } begin { # Bind the parameter to a friendly variable $deviceId = $PsBoundParameters[$DeviceIdParameterName] } process { $sessionRequest = @{ RequiredCapabilities = @{ deviceId = $deviceId; applicationType = "Device"; reuseExistingSession = $reuseExistingSession; takesScreenshot = $takesScreenshot; } } $createSessionResponse = Invoke-WebDriverRestMethod "$prefix/session" -Headers $headers -Body (ConvertTo-Json $sessionRequest) -Method Post $sessionId = $createSessionResponse.sessionId # Wait for the session to start while (-not (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/isReady").value) { # Get detailed status information $status = (Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/status").value # Break this loop if Status is DeployFailed or be stuck forever if($status.Status -eq "DeployFailed") { Throw "Deploy session failed: $($status.StatusMessage)" } # Filter duplicate messages in the output, unless verbose flag is set if(($statusOld -ne $status.Status) -or ($statusMessageOld -ne $status.StatusMessage)) { Write-Host "The session $($sessionId) is $($status.Status): $($status.StatusMessage)" $statusOld = $status.Status $statusMessageOld = $status.StatusMessage } else { Write-Verbose "The session $($sessionId) is $($status.Status): $($status.StatusMessage)" } Start-Sleep -Milliseconds 1000 } if ($script:currentSessionId -ne $null) { Write-Warning "Overriding the currently set default session" } else { Write-Information "Using this session as your default session" } $script:currentSessionId = $sessionId return $sessionId } } <# .SYNOPSIS Adds an application to the application repository .DESCRIPTION Adds an application to the application repository .EXAMPLE Add-App -path "c:\apps\quamotion.apk" #> function Add-App { param ([string] $path) Add-Type -AssemblyName System.Net.Http $fullPath = Resolve-Path $path if(-not (Test-Path $fullPath)) { Throw "The file at $fullPath could not be found" } $ContentType = "application/octet-stream" $fileBin = [IO.File]::ReadAllBytes($fullPath) $fileName = Split-Path $path -leaf $boundary = [guid]::NewGuid().ToString() $httpClientHandler = New-Object System.Net.Http.HttpClientHandler $httpClient = New-Object System.Net.Http.Httpclient $httpClientHandler $packageFileStream = New-Object System.IO.FileStream @($fullPath, [System.IO.FileMode]::Open) $contentDispositionHeaderValue = New-Object System.Net.Http.Headers.ContentDispositionHeaderValue "form-data" $contentDispositionHeaderValue.Name = "name" $contentDispositionHeaderValue.FileName = (Split-Path $path -leaf) $streamContent = New-Object System.Net.Http.StreamContent $packageFileStream $streamContent.Headers.ContentDisposition = $contentDispositionHeaderValue $streamContent.Headers.ContentType = New-Object System.Net.Http.Headers.MediaTypeHeaderValue $ContentType $content = New-Object System.Net.Http.MultipartFormDataContent $content.Add($streamContent) $result = $httpClient.PostAsync("$prefix/quamotion/app", $content).Result $response = $result.Content.ReadAsStringAsync().Result $response = ConvertFrom-Json $response if($result.StatusCode -eq "200") { return $response } else { Write-Error("Adding app Failed: " + $response) } } <# .SYNOPSIS Gets all applications in the application repository. .DESCRIPTION Gets all applications in the application repository. .EXAMPLE Get-App #> function Get-App { return (Invoke-WebDriverRestMethod -Uri "$prefix/quamotion/app") } <# .SYNOPSIS Gets all available devices. .DESCRIPTION Gets all available devices .EXAMPLE Get-Device #> function Get-Device { param ([string] $deviceId) if ($deviceId) { return (Invoke-WebDriverRestMethod -Uri "$prefix/quamotion/device/$deviceId") } else { return (Invoke-WebDriverRestMethod -Uri "$prefix/quamotion/device") } } <# .SYNOPSIS Waits until a particular device is available before continuing to run. .DESCRIPTION The Wait-Device cmdlet suspends execution of a script or function until a particular device is available. Execution resumes when the device is detected. To cancel the wait, press CTRL+C. .PARAMETER deviceId The identifier of the device for which to wait. .PARAMETER timeout Specifies the maximum time, in seconds, that Wait-Devices waits for the event to become available. The default, -1, waits indefinitely. The timing starts when you submit the Wait-Device command. If the specified time is exceeded, the wait ends and the command prompt returns, even if the device is not available. No error message is displayed. .EXAMPLE Wait-Device -deviceId 9e8438ab23a10a20cd2d4d8d9616b405d008344f #> function Wait-Device { param ( [Parameter(Mandatory=$true)] [string] $deviceId, [int] $timeout = -1) if ($timeout > -1) { $endDate = (Get-Date).AddSeconds($timeout) } else { $endDate = [System.DateTime]::MaxValue } $device = $null do { try { $device = Get-Device -deviceId $deviceId } catch { # The device is not available, sleep. Start-Sleep -Milliseconds 250 } } while (!$device -and $endDate -gt (Get-Date)) } function Get-DeviceRotation { param ( [Parameter(Mandatory=$true)] [string] $deviceId) Invoke-WebDriverRestMethod -Uri "$prefix/quamotion/device/$deviceId/rotation" } function Install-App { param ( [Parameter(Mandatory=$true)] [string] $deviceId, [Parameter(Mandatory=$true)] [string] $appId, [Parameter(Mandatory=$false)] [string] $appVersion) if($appVersion) { Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/app/$appId/$appVersion" -TimeoutSec 3600 -Method Post } else { Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/app/$appId" -TimeoutSec 3600 -Method Post } } <# .SYNOPSIS Gets all installed applications on the device. .DESCRIPTION Gets all installed applications on the device. .PARAMETER deviceId The identifier of the device. .EXAMPLE Get-InstalledApp -deviceId $iPhone6 #> function Get-InstalledApp { param ( [Parameter(Mandatory=$true)] [string] $deviceId) $apps = (Invoke-WebDriverRestMethod -Uri "$prefix/quamotion/device/$deviceId/app" -TimeoutSec 3600 -Method Get) return $apps } <# .SYNOPSIS Gets the version of an installed application. .DESCRIPTION Gets the version of an installed application. .PARAMETER deviceId The identifier of the device. .PARAMETER appId The identifier of the application. .EXAMPLE Get-InstalledAppVersion -deviceId $iPhone6 -appId "mobi.quamotion.Acquaint" #> function Get-AppVersion { param ( [Parameter(Mandatory=$true)] [string] $deviceId, [Parameter(Mandatory=$true)] [string] $appId) $version = (Invoke-WebDriverRestMethod -Uri "$prefix/quamotion/device/$deviceId/app/$appId/version" -TimeoutSec 3600 -Method Get) return $version } <# .SYNOPSIS Lists all processes which are running on a device. .DESCRIPTION Lists all processes which are running on a device. .PARAMETER deviceId The identifier of the device on which to list all the processes which are running. .EXAMPLE Get-DeviceProcess -deviceId $iPhone6 #> function Get-DeviceProcess { param ( [Parameter(Mandatory=$true)] [string] $deviceId) $apps = (Invoke-WebDriverRestMethod -Uri "$prefix/quamotion/device/$deviceId/process" -TimeoutSec 3600 -Method Get) return $apps } <# .SYNOPSIS Stops a processing running on a device. .DESCRIPTION Stops a process running on a device. .PARAMETER deviceId The device on which the process is running. .PARAMETER appId The process ID of the process to stop. .EXAMPLE Stop-DeviceProcess -deviceId $iPhone6 -processId 604 #> function Stop-DeviceProcess { param ( [Parameter(Mandatory=$true)] [string] $deviceId, [Parameter(Mandatory=$true)] [int] $processId ) Invoke-WebDriverRestMethod "$prefix/quamotion/device/$deviceId/process/$processId" -Headers $headers -Method Delete } <# .SYNOPSIS Stops an application running on a device. .DESCRIPTION Stops an application running on a device. .PARAMETER deviceId The device on which the application is running. .PARAMETER appId The application ID of the application to stop. .EXAMPLE Stop-InstalledApp -deviceId $iPhone6 -appId mobi.quamotion.Acquaint #> function Stop-InstalledApp { param ( [Parameter(Mandatory=$true)] [string] $deviceId, [Parameter(Mandatory=$true)] [string] $appId ) Invoke-WebDriverRestMethod "$prefix/quamotion/device/$deviceId/app/$appId/kill?strict" -Headers $headers -Method Post } <# .SYNOPSIS Uninstalls an application from a device. .DESCRIPTION Uninstalls an application from a device. .PARAMETER deviceId The identifier of the device. .PARAMETER appId The identifier of the application. .EXAMPLE Uninstall-App -deviceId $iPhone6 -appId "demo.quamotion.Acquaint" #> function Uninstall-App { param ( [Parameter(Mandatory=$true)] [string] $deviceId, [Parameter(Mandatory=$true)] [string] $appId) Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/app/$appId" -TimeoutSec 3600 -Method Delete } <# .SYNOPSIS Gets the orientiation of a device. .DESCRIPTION Gets the orientiation of the device used in a session. Returns: the orientation of the device. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Get-Orientation #> function Get-Orientation { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId return (Invoke-WebDriverWebRequest -Uri "$prefix/session/$sessionId/orientation" -TimeoutSec 3600 -Method Get).Content } <# .SYNOPSIS Sets the orientiation of a device. .DESCRIPTION Sets the orientiation of the device used in a session. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Get-Orientation #> function Set-Orientation { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [string] $orientation) Test-SessionId $sessionId $orientationRequest = @{ orientation = $orientation } Write-Verbose "Setting orientation to $orientation" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/orientation" -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $orientationRequest))) -Method Post } function Set-DeviceOrientation { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [double] $alpha, [Parameter(Mandatory=$true, Position = 2)] [double] $beta, [Parameter(Mandatory=$true, Position = 3)] [double] $gamma) Test-SessionId $sessionId $deviceOrientationRequest = @{ alpha = $alpha beta = $beta gamma = $gamma } Write-Verbose "Setting device orientation to ($alpha, $beta, $gamma)" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/deviceOrientation" -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $deviceOrientationRequest))) -Method Post } function Reset-DeviceOrientation { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId Write-Verbose "Setting device orientation to ($alpha, $beta, $gamma)" Invoke-WebDriverRestMethod "$prefix/session/$sessionId/deviceOrientation" -Headers $headers -Method Delete } <# .SYNOPSIS Accepts the visible alert window. .DESCRIPTION Accepts the visible alert window. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Accept-Alert #> function Accept-Alert { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId $response = Invoke-WebDriverRestMethod -Uri "$prefix/session/$sessionId/accept_alert" -TimeoutSec 3600 -Method Post } <# .SYNOPSIS Dismiss the visible alert window. .DESCRIPTION Dismiss the visible alert window. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Dismiss-Alert #> function Dismiss-Alert { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId $response = Invoke-WebDriverRestMethod -Uri "$prefix/session/$sessionId/dismiss_alert" -TimeoutSec 3600 -Method Post } <# .SYNOPSIS Clicks on an alert button. .DESCRIPTION Clicks on an alert button. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER button The name of the button to click .EXAMPLE Click-AlertButton -button "Ok" #> function Click-AlertButton { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory = $true, Position = 1)] [string] $button) Test-SessionId $sessionId Invoke-WebDriverRestMethod -Uri "$prefix/session/$sessionId/alert/click/$button" -TimeoutSec 3600 -Method Post } <# .SYNOPSIS Gets all buttons of the visible alert window. .DESCRIPTION Gets all buttons of the visible alert window. Returns: all available button names. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Get-AlertButtons #> function Get-AlertButtons { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId (Invoke-WebDriverRestMethod -Uri "$prefix/session/$sessionId/alert/buttons" -TimeoutSec 3600 -Method Get).value } <# .SYNOPSIS Report a status message. .DESCRIPTION Report a status message. The message will appear in the test-log. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER success Indicates whether the status is success or failure .PARAMETER message The message. .EXAMPLE report_status -success $false "Something went wrong" #> function Report-Status { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true)] [bool] $success, [Parameter(Mandatory=$true)] [string] $message) Test-SessionId $sessionId $reportStatusRequest = @{ Success = $success; Message = $message; } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/report_status" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $reportStatusRequest))) -Headers $headers -Method Post } <# .SYNOPSIS Dismisses an open keyboard .DESCRIPTION Dismisses an open keyboard .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Dismiss-Keyboard #> function Dismiss-Keyboard { param ( [string] $sessionId = $script:currentSessionId ) Test-SessionId $sessionId Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/dismissKeyboard" -Headers $headers -Method Post } <# .SYNOPSIS Searches for an element matching a given locator value. .DESCRIPTION Searches for an element matching the locator value. Returns: the first element matching the locator value. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER xpath (xpath locator) The value for the xpath locator .PARAMETER class (class locator) The value for the class locator .PARAMETER marked (Marked locator) The value for the marked locator .EXAMPLE Find-ElementFlex -marked "Login" Find-ElementFlex -xpath "*[@marked='Login']" Find-ElementFlex -class "UIView" #> function Find-ElementFlex { param ( [Parameter(ParameterSetName = "Marked")] [Parameter(ParameterSetName = "XPath")] [Parameter(ParameterSetName = "Class")] [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, ParameterSetName = "XPath")] [string] $xpath, [Parameter(Mandatory=$true, ParameterSetName = "Class")] [string] $class, [Parameter(Mandatory=$true, ParameterSetName = "Marked")] [string] $marked) Test-SessionId $sessionId if ($xpath) { return Find-Element -sessionId $sessionId -xpath $xpath } elseif($marked) { return Find-Element -sessionId $sessionId -xpath "//*[@marked='$marked']" } elseif($class) { Write-Verbose "Finding element //$class" return Find-Element -sessionId $sessionId -xpath "//$class" } } <# .SYNOPSIS Scrolls until the element is visible .DESCRIPTION Scrolls until the element is visible. Currently only implemented for Full Device Automation. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The identifier of the element to become visible. .EXAMPLE Scroll-ToVisible -elementId $element #> function Scroll-ToVisible { param ( [string] $sessionId = $script:currentSessionId, [string] $elementId) Test-SessionId $sessionId Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/quamotion/scrollToVisible" -Headers $headers -Method Post } <# .SYNOPSIS Scrolls until an element with a matching locator value is visible .DESCRIPTION Scrolls until an element with a matching locator value is visible. Note that the element should already be loaded. Please use the ScollDown-To or ScrollUp-To commands if the application generates the list dynamically. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The identifier of the scroll view. .PARAMETER marked (marked locator) The value for the marked locator .PARAMETER xpath (xpath locator) The value for the xpath locator .EXAMPLE Scroll-To -elementId $scrollView -marked "John" #> function Scroll-To { param ( [string] $sessionId = $script:currentSessionId, [string] $elementId, [string] $marked, [string] $xpath) Test-SessionId $sessionId if($marked) { $scrollToRequest = @{ using = "xpath"; value = "//*[@marked='$marked']"; } } else { $scrollToRequest = @{ using = "xpath"; value = $xpath; } } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/quamotion/scrollTo" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $scrollToRequest))) -Headers $headers -Method Post } <# .SYNOPSIS Scrolls down until an element with a matching xpath is visible .DESCRIPTION Scrolls down until an element with a matching xpath is visible .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The identifier of the scroll view. .PARAMETER xpath (marked locator) The value for the marked locator .EXAMPLE ScrollDown-To -elementId $scrollView -xpath "*[@marked='John']" #> function ScrollDown-To { param ( [string] $sessionId = $script:currentSessionId, [string] $elementId, [string] $xpath, [int] $scrollTimeout) Test-SessionId $sessionId $scrollToRequest = @{ using = "xpath"; value = $xpath; direction = "Down"; scrollTimeout = $scrollTimeout; } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/quamotion/scrollTo" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $scrollToRequest))) -Headers $headers -Method Post } <# .SYNOPSIS Scrolls up until an element with a matching xpath is visible .DESCRIPTION Scrolls up until an element with a matching xpath is visible .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The identifier of the scroll view. .PARAMETER xpath (marked locator) The value for the marked locator .EXAMPLE ScrollUp-To -elementId $scrollView -xpath "*[@marked='John']" #> function ScrollUp-To { param ( [string] $sessionId = $script:currentSessionId, [string] $elementId, [string] $xpath, [int] $scrollTimeout) Test-SessionId $sessionId $scrollToRequest = @{ using = "xpath"; value = $xpath; direction = "Up"; scrollTimeout = $scrollTimeout; } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/quamotion/scrollTo" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $scrollToRequest))) -Headers $headers -Method Post } function Set-Value { param ( [string] $sessionId = $script:currentSessionId, [Parameter(ValueFromPipeline=$True)] [string] $elementId, [string] $value) Test-SessionId $sessionId $setValueRequest = @{ value = @($value) } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/value" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $setValueRequest))) -Headers $headers -Method Post } <# .SYNOPSIS Clears the active text element .DESCRIPTION Clears the active text element .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Clear-Text #> function Clear-Text { param ( [string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId Invoke-WebDriverRestMethod "$prefix/session/$sessionId/quamotion/clear" -Headers $headers -Method Post } <# .SYNOPSIS Clears the text of an element .DESCRIPTION Clears the text of an element .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The ID of the element to clear .EXAMPLE Clear-ElementText -elementId $elementId #> function Clear-ElementText { param( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory = $true)] [string] $elementId) Test-SessionId $sessionId Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/clear" -Headers $headers -Method Post } <# .SYNOPSIS Gets the text displayed on the alert window. .DESCRIPTION Gets the text displayed on the alert window. Returns: the displayed alert window text .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Get-AlertText #> function Get-AlertText { param ([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId $content = (Invoke-WebDriverWebRequest -Uri "$prefix/session/$sessionId/alert/text" -TimeoutSec 3600 -Method Get).Content $json = ConvertFrom-Json($content) return $json.value } <# .SYNOPSIS Executes JavaScript in the browser. .DESCRIPTION Executes JavaScript in the browser. Returns: the value returned by the JavaScript script. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER script The JavaScript to execute. .EXAMPLE Execute-Script -script "window.alert('Hello, World!');" #> function Execute-Script { param ( [string] $sessionId = $script:currentSessionId, [string] $script) Test-SessionId $sessionId $executeScriptRequest = @{ script = $script } $json = (ConvertTo-Json $executeScriptRequest) Invoke-WebDriverRestMethod "$prefix/session/$sessionId/execute/sync" -Body ([System.Text.Encoding]::UTF8.GetBytes($json)) -Headers $headers -Method Post } <# .SYNOPSIS Deletes the application settings of an installed application. .DESCRIPTION Deletes the application settings of an installed application. .PARAMETER appId The application identifier .PARAMETER deviceId The device identifier .EXAMPLE Delete-AppSettings -appId "demo.quamotion.Acquaint" -deviceId "$iPhone6" #> function Delete-AppSettings { param ( [Parameter(Mandatory=$true)] [string] $deviceId, [Parameter(Mandatory=$true)] [string] $appId) Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/app/$appId/settings" -TimeoutSec 3600 -Method Delete } <# .SYNOPSIS Reboots a device. .DESCRIPTION Reboots a device. .PARAMETER deviceId The device identifier .EXAMPLE Reboot-Device -deviceId $iPhone6 #> function Reboot-Device { param ([Parameter(Mandatory=$true)] [string] $deviceId) Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/reboot" -TimeoutSec 3600 -Method Post } function Get-DeviceScreenshot { param ([Parameter(Mandatory=$true)] [string] $deviceId) $result = (Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/screenshot" -TimeoutSec 3600 -Method Get) return $result.Content } <# .SYNOPSIS Tests whether the element is visible. .DESCRIPTION Tests whether the element is visible. $true or $false depending of the visibility of the element. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER elementId The identifier element. .EXAMPLE Is-Displayed -elementId $loginButton #> function Is-Displayed { param( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory = $true, Position = 1)] [string] $elementId) Test-SessionId $sessionId $response = Invoke-WebDriverRestMethod "$prefix/session/$sessionId/element/$elementId/displayed" -Method Get -Headers $headers return $response.value } <# .SYNOPSIS Takes a screenshot of the device used in the given session. .DESCRIPTION Takes a screenshot of the device used in the given session. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER filePath The file path used to store the screenshot. .EXAMPLE Get-Screenshot -filePath c:\temp\screenhot.jpg #> function Get-Screenshot { param([string] $sessionId = $script:currentSessionId, [string] $filePath) Test-SessionId $sessionId $screenshot = Invoke-WebDriverWebRequest -Uri "$prefix/session/$sessionId/screenshot" -TimeoutSec 3600 -Method Get $jsonScreenshot = ConvertFrom-Json $screenshot.Content $bytes=[System.Convert]::FromBase64String($jsonScreenshot.value) $decodedScreenshot=[System.Text.Encoding]::Default.GetString($bytes) Set-Content $filePath -value $decodedScreenshot } <# .SYNOPSIS Set the amount of time, in milliseconds, are permitted to run before they are aborted and a timeout error is returned to the client. .DESCRIPTION Set the amount of time, in milliseconds, are permitted to run before they are aborted and a timeout error is returned to the client. .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .PARAMETER time The amount of time to wait, in milliseconds. This value has a lower bound of 0. .EXAMPLE Set-Timeout -time 3000 #> function Set-Timeout { param ( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [string] $time) Test-SessionId $sessionId $timeout = @{ implicit = $time; } $result = Invoke-WebDriverWebRequest -Uri "$prefix/session/$sessionId/timeouts" -Headers $headers -Body (ConvertTo-Json $timeout) -Method Post } <# .SYNOPSIS Gets the timeouts for the given session .DESCRIPTION Gets the timeouts for the given session .PARAMETER sessionId (Optional) The identifier of the session to route the command to. .EXAMPLE Get-Timeouts #> function Get-Timeouts { param ( [string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId $content = (Invoke-WebDriverWebRequest -Uri "$prefix/session/$sessionId/timeouts" -Method Get).Content $json = ConvertFrom-Json($content) return $json.value } <# .SYNOPSIS Gets the battery info of a device. .DESCRIPTION Gets the battery info of a device. Returns: the battery info of a device. .PARAMETER deviceId The device identifier. .EXAMPLE Get-BatteryInfo -deviceId $iPhone6 #> function Get-BatteryInfo { param( [Parameter(Mandatory=$true, Position = 1)] [string] $deviceId) return (Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/battery" -TimeoutSec 3600 -Method Get).Content } <# .SYNOPSIS Gets the navigation timing of the current webview window. .DESCRIPTION Gets the navigation timing of the current webview window. .EXAMPLE Get-PerformanceData #> function Get-PerformanceData { param([string] $sessionId = $script:currentSessionId) Test-SessionId $sessionId return (Invoke-WebDriverWebRequest -Uri "$prefix/session/$sessionId/quamotion/performance" -TimeoutSec 3600 -Method Get).Content } <# .SYNOPSIS Gets the disk info of a device. .DESCRIPTION Gets the disk info of a device. Returns: the disk info of a device. .PARAMETER deviceId The device identifier. .EXAMPLE Get-DiskInfo -deviceId $iPhone6 #> function Get-DiskInfo { param( [Parameter(Mandatory=$true, Position = 1)] [string] $deviceId) return (Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/disk" -TimeoutSec 3600 -Method Get).Content } <# .SYNOPSIS Gets the domain settings of a device. .DESCRIPTION Gets the domain settings of a device. Returns: the domain settings of a device. .PARAMETER deviceId The device identifier. .PARAMETER domain The settings domain. .EXAMPLE Get-DeviceSettings -deviceId $iPhone6 -domain "global" #> function Get-DeviceSettings { param( [Parameter(Mandatory=$true, Position = 1)] [string] $deviceId, [Parameter(Mandatory=$true, Position = 2)] [string] $domain) $settings = (Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/settings/$domain" -TimeoutSec 3600 -Method Get).Content return $settings| ConvertFrom-json } <# .SYNOPSIS Gets a setting of a device. .DESCRIPTION Gets a settings of a device. Returns: the settings of the device. .PARAMETER deviceId The device identifier. .PARAMETER domain The settings domain. .PARAMETER key The settings key. .EXAMPLE Get-DeviceSetting -deviceId $iPhone6 -domain "global" -key "ota_disable_automatic_update" #> function Get-DeviceSetting { param( [Parameter(Mandatory=$true, Position = 1)] [string] $deviceId, [Parameter(Mandatory=$true, Position = 2)] [string] $domain, [Parameter(Mandatory=$true, Position = 3)] [string] $key ) $settings = (Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/settings/$domain/$key" -TimeoutSec 3600 -Method Get).Content return $settings| ConvertFrom-json } <# .SYNOPSIS Set a settings of a device. .DESCRIPTION Sets a settings of a device. .PARAMETER deviceId The device identifier. .PARAMETER domain The settings domain. .PARAMETER key The settings key. .PARAMETER value The value to set. .EXAMPLE Set-DeviceSetting -deviceId $iPhone6 -domain "global" -key "ota_disable_automatic_update" -value "0" #> function Set-DeviceSetting { param( [Parameter(Mandatory=$true, Position = 1)] [string] $deviceId, [Parameter(Mandatory=$true, Position = 2)] [string] $domain, [Parameter(Mandatory=$true, Position = 3)] [string] $key, [Parameter(Mandatory=$true, Position = 4)] [string] $value ) $request = @{ value = $value } $settings = (Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/settings/$domain/$key" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $value))) -Headers $headers -Method Post).Content return $settings| ConvertFrom-json } <# .SYNOPSIS Updates the geolocation of the device on which the test is currently running. .PARAMETER latitude The new latitude. .PARAMETER longitude The new longitude. .EXAMPLE Set-GeoLocation 50.838061 4.841535 Set-Geolocation 50.826296 4.399623 Set-GeoLocation 50.983377 3.686608 #> function Set-GeoLocation { param( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [string] $latitude, [Parameter(Mandatory=$true, Position = 21)] [string] $longitude) Test-SessionId $sessionId $setLocationRequest = @{ latitude = $latitude longitude = $longitude } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/location" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $setLocationRequest))) -Headers $headers -Method Post } function Start-App { param( [Parameter(Mandatory=$true, Position = 1)] [string] $deviceId, [Parameter(Mandatory=$true, Position = 2)] [string] $appId, [Parameter(Mandatory=$false, Position = 3)] [string[]] $arguments ) $url = "$prefix/quamotion/device/$deviceId/app/$appId/launch?strict" if($arguments) { Invoke-WebDriverRestMethod $url -Method Post -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $arguments -Compress))) -Headers $headers } else { Invoke-WebDriverRestMethod $url -Method Post -Headers $headers -Body "null" -ContentType "application/json" } } function Stop-Agent { param( [Parameter(Mandatory=$true, Position = 1)] [string] $deviceId ) Invoke-WebDriverRestMethod "$prefix/quamotion/device/$deviceId/stopAgent" -Method Post } function Enable-LocationServices { param( [Parameter(Mandatory=$true, Position = 1)] [string] $deviceId, [Parameter(Mandatory=$true, Position = 2)] [string[]] $locationServices) $locationServiceRequest = @{ location_services = $locationServices; } $result = Invoke-WebDriverWebRequest -Uri "$prefix/quamotion/device/$deviceId/location_services" -Headers $headers -Body (ConvertTo-Json $locationServiceRequest) -Method Post } function Invoke-WebDriverRestMethod { param() try { return Invoke-RestMethod @args -ErrorAction Stop } catch { Rethrow-Exception $_ } } function Invoke-WebDriverWebRequest { param() try { Invoke-WebRequest @args -ErrorAction Stop } catch { Rethrow-Exception $_ } } # Shared error handling function Rethrow-Exception($originalError) { $errorMessage = Get-ErrorMessage($originalError) if($errorMessage) { $status = $errorMessage.status $message = $errorMessage.value.message try { $jsonMessage = $message | ConvertFrom-Json if($jsonMessage.description) { $message = $jsonMessage.description } } catch { } Throw (New-Object WebDriverException $message,$status) } else { Throw $exception } } Function Get-ErrorMessage ($error) { # If something went wrong in the HTTP pipeline, the result may not be JSON, or we may not have a # response at all (if the server was unavailable) # PowerShell "Core" stores error details in the ErrorDetails variable. We first check if this info exists, see # https://github.com/PowerShell/PowerShell/issues/5555 # https://github.com/PowerShell/PowerShell/pull/3089 $errorDetails = $error.ErrorDetails $exception = $error.Exception if($errorDetails) { $errorMessage = $errorDetails.Message | ConvertFrom-Json return $errorMessage } elseif ($exception.Response -and $exception.Response.ContentType -and $exception.Response.ContentType.StartsWith("application/json")) { $result = $exception.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($result) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() $responseBody = $reader.ReadToEnd(); $errorMessage = ConvertFrom-Json $responseBody return $errorMessage } else { Throw $exception } } <# .SYNOPSIS Gets the session log of a specific session. .DESCRIPTION Gets the session log of a specific session. Returns: The session log as JSON. .PARAMETER SessionId (Optional) The session identifier. .EXAMPLE Get-SessionLog -SessionId 0f59edb6-914d-4e24-b77d-dbcfb97008d6 #> function Get-SessionLog { param( [string] $sessionId = $script:currentSessionId) $result = Invoke-WebRequest -Uri "http://localhost:17894/Dashboard/SessionLog?sessionid=$sessionId" -Headers $headers -Method GET $testLogNumber = $result.BaseResponse.ResponseUri.Segments.Get($result.BaseResponse.ResponseUri.Segments.Count-1) Write-Host "testLogNumber $testLogNumber" $testLog = Invoke-RestMethod -Uri "$prefix/quamotion/testlog/$testLogNumber/export" -Headers $headers -Method GET return ConvertTo-Json $testLog } <# .SYNOPSIS Removes an application from the application repository. .DESCRIPTION Removes an application from the application repository. .EXAMPLE Remove-App -operatingSystem "iOS" -appVersion "1.51" -appId "demo.quamotion.Acquaint" #> function Remove-App { param ([string] $operatingSystem, [string] $appId, [string] $appVersion) $result = Invoke-WebDriverRestMethod "$prefix/quamotion/app/$operatingSystem/$appId/$appVersion" -Method Delete return $result } function Execute-Script { param( [string] $sessionId = $script:currentSessionId, [Parameter(Mandatory=$true, Position = 1)] [string] $script, [Parameter(Mandatory=$true, Position = 21)] [object[]] $args) $executeScriptRequest = @{ script = $script args = $args } Invoke-WebDriverRestMethod "$prefix/session/$sessionId/execute/sync" -Body ([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $executeScriptRequest))) -Headers $headers -Method Post } function Test-SessionId { param( [string] $sessionId ) if(-not $sessionId) { Throw "You must specify a valid session id. Did you run Start-Session, Start-DeviceSession or Start-WebSession?" } } Class WebDriverException : System.Exception { [int] $Status = 0 WebDriverException([string] $message, [int] $status) : base($message) { $this.Status = $status } } Enum LocatorStrategy { ClassName CssSelector Id Name LinkText PartialLinkText TagName XPath PredicateString ClassChain } |