1

I am trying to add failed test attachments in the Test tab in Azure DevOps using VS test task.

I am calling the Create Test Result Attachment rest api,

$AzureDevOpsPAT = {PAT}
$AzureDevOpsAuthenicationHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($AzureDevOpsPAT)")) }
$result = Invoke-RestMethod -Uri https://dev.azure.com/{org}/{proj}/_apis/test/runs/$(runId)/results?api-version=6.0 -Headers $AzureDevOpsAuthenicationHeader -Method Get

#List all test result  get the test result ID via result
foreach($Run in $result.value){

#Get the test result ID via result
If($Run.outcome -eq "Failed"){
$TestResultID = $Run.id
$Name=$Run.testCase.name
Write-Host $TestResultID $Name


#Add attachment via test run ID and test result ID
$TestResultAttachmentURL = "https://dev.azure.com/{org}/{proj}/_apis/test/Runs/$(runId)/results/$($TestResultID)/attachments?api-version=6.0-preview.1" 

$body =@"
{
  "stream": "abc",
  "fileName": "$(System.DefaultWorkingDirectory)/$Name.png",
  "comment": "Test attachment upload",
  "attachmentType": "GeneralAttachment"
}
"@
$TestResultAttachmentResult = Invoke-RestMethod -Uri $TestResultAttachmentURL -ContentType "application/json" -Body $body -Headers $AzureDevOpsAuthenicationHeader -Method POST
}
}

I cant see the respective screenshot, the black flower is showing if I click on .png file in the attachment tab, enter image description here

Though I am capturing a screenshot in my code too,

protected void StopWebDriver()
        {
            if (WebDriver != null)
            {
             string path = Directory.GetCurrentDirectory() + "\\" + BaseConfig.TestCaseName + ".png";
            ((ITakesScreenshot)WebDriver).GetScreenshot().SaveAsFile(path, ScreenshotImageFormat.Png);
            WebDriver.Close();
            WebDriver.Quit();
                
            }
        }

Can anyone please tell me how can I see screenshots?

Gkm
  • 237
  • 1
  • 5
  • 19

2 Answers2

1

Based on my test , the screenshot could show in the Pipeline -> Test -> Attachment tab.

You could use the PowerShell Script to generate the Base64 file Stream instead of hardcode the file stream.

Here is an example:

$file= [IO.File]::ReadAllBytes("filepath\$Name.png")
$Base64file= [Convert]::ToBase64String($file)
echo $Base64file


$token = "PAT"

$url="https://dev.azure.com/{org}/{proj}/_apis/test/Runs/$(runId)/results/$($TestResultID)/attachments?api-version=6.0-preview.1"

$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))

$JSON = "
    {
       `"stream`": `"$Base64file`",
       `"fileName`": `"$Name.png`",
       `"comment`": `"Test attachment upload`",
       `"attachmentType`": `"GeneralAttachment`"
    }"


$response = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Basic $token"} -Method Post -Body $JSON -ContentType application/json

enter image description here

On the other hand, you could directly try to use the Publish screenshots for test failure task from the extension Publish test result screenshot.

In addition, in order to confirm whether the image you uploaded is valid, you can also download and check whether it is the correct content.

Update:

To get the Test case name in a string, you could refer to this sample:

$String= "ooo.iii.kkk.lll"
$a,$b,$c,$d = $String.Split(".",4)

echo $c
Kevin Lu-MSFT
  • 20,786
  • 3
  • 19
  • 28
  • what file path I should give here? $(System.DefaultWorkingDirectory) this?? – Gkm Feb 02 '21 at 07:56
  • Yes. If you save the screenshot in this path $(System.DefaultWorkingDirectory), you could use this variable. – Kevin Lu-MSFT Feb 02 '21 at 07:57
  • Hi @Kevin Lu-MSFT, can you please check the path of the file is correct in both c# code and powershell script? I have updated the question. – Gkm Feb 02 '21 at 08:28
  • Hi @Gkm. If you could determine the file name, you could hardcode the file name. You don't need to add the path to the file name. The path is used to generate the File steam. The **steam** parameter in Body You could try it and check if it could work. You could refer to the body in my code sample. Thanks. – Kevin Lu-MSFT Feb 02 '21 at 08:33
  • In my code, I am saving the file with the test case name, if I hardcode the file name with abc.png it will rewrite the file and in the end, I will get only one screenshot. That's the reason I have to give a unique name to each screenshot. – Gkm Feb 02 '21 at 08:41
  • Hi @Gkm. Thanks for your update. you could set the **$Name.png** as the file name. Please check my update about the code . You don't need to add the path to the file name parameter. Just file name will be ok. In additional, I notice that you are finding the method to get the value in the string xx.x.x.x, please check my update, you could use Powershell script to achieve it. – Kevin Lu-MSFT Feb 02 '21 at 09:12
  • Still, I can't see the images, it shows the filename correctly but if I download the file, its blank. – Gkm Feb 02 '21 at 10:03
  • I got this in log, 2021-02-02T10:31:00.2593453Z [xUnit.net 00:00:40.02] ---- System.IO.IOException : The process cannot access the file 'D:\a\r1\a\_CodedUI-Tests-CI\tests\Project\bin\Release\ValidTransfer.png' because it is being used by another process. What does it mean? – Gkm Feb 02 '21 at 13:05
  • Hi @Gkm. Can you see the image now? Since it is blank when you download the file, the image couldn't be uploaded successfully. The file Stream could have some issue. You could refer to my script and change it in PowerShell Script. – Kevin Lu-MSFT Feb 03 '21 at 01:28
  • The issue: **it is being used by another process**. Two processes may operate this image at the same time. The image could be opened or it is being used by other process. So it couldn't be transferred. – Kevin Lu-MSFT Feb 03 '21 at 01:31
  • If the answer above could give you some help, you may consider [accepting it as answer](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). Thanks . – Kevin Lu-MSFT Feb 03 '21 at 01:34
0

Powershell script task1 to get the run id:

$AzureDevOpsPAT = {PAT}
$AzureDevOpsAuthenicationHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($AzureDevOpsPAT)")) }
$UriOrga = "https://dev.azure.com/{org}/{proj}/" 
$uriAccount = $UriOrga + "_apis/test/runs?api-version=6.0"

$response = Invoke-RestMethod -Uri $uriAccount -Headers $AzureDevOpsAuthenicationHeader -Method Get
$testRunsIdSorted = $response.value | sort-object id -Descending
$result = Invoke-RestMethod -Uri https://dev.azure.com/{org}/{proj}/_apis/test/runs/$($testRunsIdSorted[0].id)?api-version=6.0 -Headers $AzureDevOpsAuthenicationHeader -Method Get
Write-Host "results = $($result | ConvertTo-Json -Depth 100)"
Write-Host "##vso[task.setvariable variable=runId]$($result.id | ConvertTo-Json -Depth 100)"

Powershell task2 to attach the screenshot attachment:

$AzureDevOpsPAT = {PAT}
$AzureDevOpsAuthenicationHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($AzureDevOpsPAT)")) }
$result = Invoke-RestMethod -Uri https://dev.azure.com/{org}/{proj}/_apis/test/runs/$(runId)/results?api-version=6.0 -Headers $AzureDevOpsAuthenicationHeader -Method Get

#List all test result  get the test result ID via result
foreach($Run in $result.value){

#Get the test result ID via result
If($Run.outcome -eq "Failed"){
$TestResultID = $Run.id
$TestTitle=$Run.testCase.name
$CharArray =$TestTitle.Split(".")
$TestCase=$CharArray[6]

$CharArraytwo=$TestCase.Split("(")
$TestName =$CharArraytwo[0]

$file= [IO.File]::ReadAllBytes("$(System.DefaultWorkingDirectory)\{Source alias}\tests\{testproject}\bin\Release\$TestName.png")
$Base64file= [Convert]::ToBase64String($file)

#Add attachment via test run ID and test result ID
$TestResultAttachmentURL = "https://dev.azure.com/{org}/{proj}/_apis/test/Runs/$(runId)/results/$($TestResultID)/attachments?api-version=6.0-preview.1" 

$body =@"
{
  "stream": "$Base64file",
  "fileName": "$TestName.png",
  "comment": "Test attachment upload",
  "attachmentType": "GeneralAttachment"
}
"@
$TestResultAttachmentResult = Invoke-RestMethod -Uri $TestResultAttachmentURL -ContentType "application/json" -Body $body -Headers $AzureDevOpsAuthenicationHeader -Method POST
}
}

The C# code was correct. In VS test task, PowerShell tasks remember to enable "Conitnue on error". Otherwise, if the task failed, others will not execute.

Gkm
  • 237
  • 1
  • 5
  • 19