Quamotion.Cloud.psm1
$global:VerbosePreference = "Continue" $prefix = "https://cloud.quamotion.mobi" $script:accessToken = "" $headers = @{} $relativeUrl = "" function Login-QuamotionCloud { param ( [Parameter(Mandatory=$true)] [string] $apiKey) $body = @{ "apiKey"=$apiKey } $response = Invoke-QMRestMethod -Uri "$script:prefix/api/login" -Body $body -Method Post $script:accessToken = $response.access_token $script:headers = @{ "Authorization"="Bearer $script:accessToken"; "Content-Type" = "application/json" } $response = Invoke-QMRestMethod -Uri "$script:prefix/api/project" -Headers $script:headers -Method Get $script:relativeUrl = $response.relativeUrl } function Get-CloudApps { return Invoke-QMRestMethod -Uri "$($script:prefix)$($script:relativeUrl)api/app" -Headers $script:headers -Method Get } function Get-TestRunJobs { param ( [Parameter(Mandatory=$true)] [string] $testRunId) return Invoke-QMRestMethod -Uri "$($script:prefix)$($script:relativeUrl)api/testRun/$testRunId/jobs" -Headers $script:headers -Method Get } function Get-TestRunSchedules { return Invoke-QMRestMethod -Uri "$($script:prefix)$($script:relativeUrl)api/schedule" -Headers $script:headers -Method Get } function Delete-TestRunSchedule { param ( [Parameter(Mandatory=$true)] [string] $scheduleId) Invoke-QMRestMethod -Uri "$($script:prefix)$($script:relativeUrl)api/schedule/$scheduleId" -Headers $script:headers -Method Delete } function Delete-TestRunSchedules { $testRunSchedules = Get-TestRunSchedules Foreach ($schedule in $testRunSchedules) { Delete-TestRunSchedule -scheduleId $schedule.id } } function Upload-TestPackage { param ( [Parameter(Mandatory=$true)] [string] $path) Add-Type -AssemblyName System.Net.Http Add-Type -AssemblyName System.IO $fullPath = Resolve-Path $path if(-not (Test-Path $fullPath)) { Throw "The file at $fullPath could not be found" } $fileName = Split-Path $path -leaf $url = "$($script:prefix)$($script:relativeUrl)api/testPackage" $httpClient = New-Object System.Net.Http.Httpclient $fileStream = [System.IO.File]::OpenRead($path) $fileStreamContent = New-Object System.Net.Http.StreamContent $fileStream $formData = New-Object System.Net.Http.MultipartFormDataContent $formData.Add($fileStreamContent, "files", $fileName); $requestMessage = New-Object System.Net.Http.HttpRequestMessage([System.Net.Http.HttpMethod]::Post, $url) $requestMessage.Headers.Authorization = New-Object System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", $script:accessToken); $requestMessage.Content = $formData; $response = $httpClient.SendAsync($requestMessage).Result $fileStream.Dispose() $formData.Dispose() $httpClient.Dispose() $fileStreamContent.Dispose() $requestMessage.Dispose() return $response } function Schedule-TestRun { param ( [Parameter(Mandatory=$true)] [string] $deviceGroupName, [Parameter(Mandatory=$true)] [string[]] $deviceGroupLabels, [Parameter(Mandatory=$true)] [string] $testPackageName, [Parameter(Mandatory=$true)] [string] $testPackageVersion, [string] $appId, [string] $appVersion, [string] $appOperatingSystem, [string] $schedule = "", [hashtable] $environmentVariables, [string] $scriptArguments, [string] $callbackEndpoint, [string] $callbackApiKey) $deviceGroupId = ([guid]::NewGuid()).Guid Write-Host $deviceGroupName if($callbackEndpoint) { $resultsCallBack = @{ apiKey = $callbackApiKey; endPoint = $callbackEndpoint; } } if($appId) { [Array]$apps = Get-CloudApps $apps = $apps | Where-Object {$_.appId -eq $appId} if($appVersion) { $apps = $apps | Where-Object {$_.Version -eq $appVersion} } if($appOperatingSystem) { $apps = $apps | Where-Object {$_.operatingSystem -eq $appOperatingSystem} } if($apps.Count -eq 1) { $app = $apps[0] } if($apps.Count -lt 1) { Throw "The application is not uniquely specified." } if($apps.Count -eq 0) { Throw "No application matches the specification." } } $testRunRequest = @{ testPackage = @{ name = $testPackageName; version = $testPackageVersion; }; app = $app; deviceGroup = @{ deviceGroupId = $deviceGroupId; name = $deviceGroupName; devices = @(@{ deviceSelectionId = $deviceGroupId; name = $deviceGroupName; tags = $deviceGroupLabels; }); } testScriptParameters = $scriptArguments; schedule = $schedule; resultsCallBack = $resultsCallBack; testScriptEnvironmentVariables = $environmentVariables; }; write-Host (ConvertTo-Json $testRunRequest -Depth 10) Invoke-QMRestMethod -Uri "$($script:prefix)$($script:relativeUrl)api/testRun" -Body (ConvertTo-Json $testRunRequest -Depth 10) -Headers $script:headers -Method Post } function Invoke-QMRestMethod { param() try { return Invoke-RestMethod @args -ErrorAction Stop } catch { Rethrow-CloudException $_ } } function Invoke-QMWebRequest { param() try { Invoke-WebRequest @args -ErrorAction Stop } catch { Rethrow-CloudException $_ } } # Shared error handling function Rethrow-CloudException($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) { Throw $error } 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(); Write-Debug($exception.Response.ContentType) Write-Debug($responseBody) $jsonResponseBody = ConvertFrom-Json $responseBody Throw $jsonResponseBody.value.message } else { Throw $exception } } |