Skip to content

Commit 49fd472

Browse files
authored
Add screen capture and improved logging to helix tests (#176)
Enable /screencaptureonerror for TAEF tests and upload the screenshots to helix storage. Also upload te.wtl log file. Report uploaded urls of both of these to the Azure DevOps test report so that someone investigating a test failure can link directly to them instead of having to go to through the Mission Control site. Here is an example run showing this in action: https://dev.azure.com/ms/microsoft-ui-xaml/_build/results?buildId=1332&view=ms.vss-test-web.test-result-details
1 parent 9200998 commit 49fd472

File tree

3 files changed

+81
-6
lines changed

3 files changed

+81
-6
lines changed

build/Helix/ConvertWttLogToXUnit.cs

+66-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
5+
using System.Text;
56
using System.Xml.Linq;
67

78
namespace HelixTestHelpers
@@ -16,14 +17,21 @@ public class TestPass
1617

1718
public class TestResult
1819
{
20+
public TestResult()
21+
{
22+
Screenshots = new List<string>();
23+
}
24+
1925
public string Name { get; set; }
2026
public bool Passed { get; set; }
2127
public bool CleanupPassed { get; set; }
2228
public TimeSpan ExecutionTime { get; set; }
2329
public string Details { get; set; }
30+
31+
public List<string> Screenshots { get; private set; }
2432
}
2533

26-
public static void ConvertWttLogToXUnitLog(string wttInputPath, string xunitOutputPath, string testNamePrefix)
34+
public static void ConvertWttLogToXUnitLog(string wttInputPath, string xunitOutputPath, string testNamePrefix, string helixResultsContainerUri, string helixResultsContainerRsas)
2735
{
2836
var testPass = TestResultParser.ParseTestWttFile(wttInputPath, true);
2937
var results = testPass.TestResults;
@@ -80,7 +88,24 @@ public static void ConvertWttLogToXUnitLog(string wttInputPath, string xunitOutp
8088
failure.SetAttributeValue("exception-type", "Exception");
8189

8290
var message = new XElement("message");
83-
message.Add(new XCData(result.Details));
91+
92+
StringBuilder errorMessage = new StringBuilder();
93+
94+
errorMessage.AppendLine("Log: " + GetUploadedFileUrl(wttInputPath, helixResultsContainerUri, helixResultsContainerRsas));
95+
96+
if(result.Screenshots.Any())
97+
{
98+
errorMessage.AppendLine("Screenshots:");
99+
foreach(var screenshot in result.Screenshots)
100+
{
101+
errorMessage.AppendLine(GetUploadedFileUrl(screenshot, helixResultsContainerUri, helixResultsContainerRsas));
102+
}
103+
}
104+
105+
errorMessage.AppendLine("Error Log: ");
106+
errorMessage.AppendLine(result.Details);
107+
108+
message.Add(new XCData(errorMessage.ToString()));
84109
failure.Add(message);
85110

86111
test.Add(failure);
@@ -272,6 +297,26 @@ public static TestPass ParseTestWttFile(string fileName, bool cleanupFailuresAre
272297
currentResult.Details += "]";
273298
}
274299
}
300+
301+
if (currentResult != null && element.Name == "Msg")
302+
{
303+
var dataElement = element.Element("Data");
304+
if (dataElement != null)
305+
{
306+
var supportingInfo = dataElement.Element("SupportingInfo");
307+
if (supportingInfo != null)
308+
{
309+
var screenshots = supportingInfo.Elements("Item")
310+
.Where(item => GetAttributeValue(item, "Name") == "Screenshot")
311+
.Select(item => GetAttributeValue(item, "Value"));
312+
313+
foreach(var screenshot in screenshots)
314+
{
315+
currentResult.Screenshots.Add(screenshot);
316+
}
317+
}
318+
}
319+
}
275320
}
276321

277322
testPassStartTime = Int64.Parse(doc.Root.Descendants("WexTraceInfo").First().Attribute("TimeStamp").Value);
@@ -288,5 +333,23 @@ public static TestPass ParseTestWttFile(string fileName, bool cleanupFailuresAre
288333
return testpass;
289334
}
290335
}
336+
337+
private static string GetAttributeValue(XElement element, string attributeName)
338+
{
339+
if(element.Attribute(attributeName) != null)
340+
{
341+
return element.Attribute(attributeName).Value;
342+
}
343+
344+
return null;
345+
}
346+
347+
private static string GetUploadedFileUrl(string filePath, string helixResultsContainerUri, string helixResultsContainerRsas)
348+
{
349+
var filename = Path.GetFileName(filePath);
350+
return string.Format("{0}/{1}{2}", helixResultsContainerUri, filename, helixResultsContainerRsas);
351+
}
291352
}
353+
354+
292355
}

build/Helix/ConvertWttLogToXUnit.ps1

+6-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ Param(
99
[string]$testNamePrefix
1010
)
1111

12+
# Ideally these would be passed as parameters to the script. However ps makes it difficult to deal with string literals containing '&', so we just
13+
# read the values directly from the environment variables
14+
$helixResultsContainerUri = $Env:HELIX_RESULTS_CONTAINER_URI
15+
$helixResultsContainerRsas = $Env:HELIX_RESULTS_CONTAINER_RSAS
16+
1217
Add-Type -Language CSharp -ReferencedAssemblies System.Xml,System.Xml.Linq (Get-Content .\ConvertWttLogToXUnit.cs -Raw)
1318

14-
[HelixTestHelpers.TestResultParser]::ConvertWttLogToXUnitLog($WttInputPath, $XUnitOutputPath, $testNamePrefix)
19+
[HelixTestHelpers.TestResultParser]::ConvertWttLogToXUnitLog($WttInputPath, $XUnitOutputPath, $testNamePrefix, $helixResultsContainerUri, $helixResultsContainerRsas)

build/Helix/runtests.cmd

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
robocopy %HELIX_CORRELATION_PAYLOAD% . /s
1+
robocopy %HELIX_CORRELATION_PAYLOAD% . /s /NP
22

3-
te MUXControls.Test.dll MUXControlsTestApp.appx IXMPTestApp.appx /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 %*
3+
te MUXControls.Test.dll MUXControlsTestApp.appx IXMPTestApp.appx /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError %*
4+
5+
%HELIX_PYTHONPATH% %HELIX_SCRIPT_ROOT%\upload_result.py -result te.wtl -result_name te.wtl
6+
7+
FOR %%I in (WexLogFileOutput\*.jpg) DO (
8+
echo Uploading %%I to "%HELIX_RESULTS_CONTAINER_URI%/%%I%HELIX_RESULTS_CONTAINER_RSAS%"
9+
%HELIX_PYTHONPATH% %HELIX_SCRIPT_ROOT%\upload_result.py -result %%I -result_name %%~nI%%~xI
10+
)
411

512
cd scripts
613
powershell -ExecutionPolicy Bypass .\ConvertWttLogToXUnit.ps1 ..\te.wtl ..\testResults.xml %testnameprefix%

0 commit comments

Comments
 (0)