diff --git a/xunit.runner.wpf/Converters/TestStateConverter.cs b/xunit.runner.wpf/Converters/TestStateConverter.cs
new file mode 100644
index 0000000..d267326
--- /dev/null
+++ b/xunit.runner.wpf/Converters/TestStateConverter.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using xunit.runner.wpf.ViewModel;
+
+namespace xunit.runner.wpf.Converters
+{
+ public class TestStateConverter : IValueConverter
+ {
+ private static ImageSource passedSource;
+ private static ImageSource failedSource;
+ private static ImageSource skippedSource;
+ static TestStateConverter()
+ {
+ passedSource = LoadResourceImage("Passed.ico");
+ failedSource = LoadResourceImage("Failed.ico");
+ skippedSource = LoadResourceImage("Skipped.ico");
+ }
+
+ private static BitmapImage LoadResourceImage(string resourceName)
+ {
+ var image = new BitmapImage();
+ image.BeginInit();
+ image.UriSource = new Uri("pack://application:,,,/xunit.runner.wpf;component/Artwork/" + resourceName);
+ image.EndInit();
+ return image;
+ }
+
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var state = (TestState)value;
+ if (targetType == typeof(Brush))
+ {
+ switch (state)
+ {
+ case TestState.Failed:
+ return Brushes.Red;
+ case TestState.Skipped:
+ return Brushes.Yellow;
+ case TestState.Passed:
+ return Brushes.Green;
+ default:
+ return Brushes.Gray;
+ }
+ }
+ else if (targetType == typeof(ImageSource))
+ {
+ switch (state)
+ {
+ case TestState.Failed:
+ return failedSource;
+ case TestState.Skipped:
+ return skippedSource;
+ case TestState.Passed:
+ return passedSource;
+ default:
+ return null;
+ }
+ }
+ else
+ {
+ throw new NotSupportedException();
+ }
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/xunit.runner.wpf/MainWindow.xaml b/xunit.runner.wpf/MainWindow.xaml
index 4c22284..67fd2e6 100644
--- a/xunit.runner.wpf/MainWindow.xaml
+++ b/xunit.runner.wpf/MainWindow.xaml
@@ -4,6 +4,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:xunit.runner.wpf"
+ xmlns:converters="clr-namespace:xunit.runner.wpf.Converters"
xmlns:vm="clr-namespace:xunit.runner.wpf.ViewModel"
mc:Ignorable="d"
DataContext="{Binding Main, Source={StaticResource Locator}}"
@@ -13,6 +14,10 @@
Height="600"
Width="525">
+
+
+
+
@@ -147,12 +152,14 @@
-
+
-
+
@@ -171,11 +178,11 @@
-
diff --git a/xunit.runner.wpf/ViewModel/MainViewModel.cs b/xunit.runner.wpf/ViewModel/MainViewModel.cs
index ee7a24c..849d940 100644
--- a/xunit.runner.wpf/ViewModel/MainViewModel.cs
+++ b/xunit.runner.wpf/ViewModel/MainViewModel.cs
@@ -76,6 +76,13 @@ namespace xunit.runner.wpf.ViewModel
set { Set(ref maximumProgress, value); }
}
+ private TestState currentRunState;
+ public TestState CurrentRunState
+ {
+ get { return currentRunState; }
+ set { Set(ref currentRunState, value); }
+ }
+
private string searchQuery = string.Empty;
public string SearchQuery
{
@@ -204,7 +211,7 @@ namespace xunit.runner.wpf.ViewModel
private readonly Func isCancelRequested;
private readonly IEnumerable testCases;
- public event EventHandler TestFinished;
+ public event EventHandler TestFinished;
public TestRunVisitor(IEnumerable testCases, Func isCancelRequested)
{
@@ -216,7 +223,7 @@ namespace xunit.runner.wpf.ViewModel
{
var testCase = testCases.Single(tc => tc.DisplayName == testFailed.TestCase.DisplayName);
testCase.State = TestState.Failed;
- TestFinished?.Invoke(this, EventArgs.Empty);
+ TestFinished?.Invoke(this, TestStateEventArgs.Failed);
return !isCancelRequested();
}
@@ -224,7 +231,7 @@ namespace xunit.runner.wpf.ViewModel
{
var testCase = testCases.Single(tc => tc.DisplayName == testPassed.TestCase.DisplayName);
testCase.State = TestState.Passed;
- TestFinished?.Invoke(this, EventArgs.Empty);
+ TestFinished?.Invoke(this, TestStateEventArgs.Passed);
return !isCancelRequested();
}
@@ -232,7 +239,7 @@ namespace xunit.runner.wpf.ViewModel
{
var testCase = testCases.Single(tc => tc.DisplayName == testSkipped.TestCase.DisplayName);
testCase.State = TestState.Skipped;
- TestFinished?.Invoke(this, EventArgs.Empty);
+ TestFinished?.Invoke(this, TestStateEventArgs.Skipped);
return !isCancelRequested();
}
}
@@ -312,9 +319,13 @@ namespace xunit.runner.wpf.ViewModel
}
}
- private void TestRunVisitor_TestFinished(object sender, EventArgs e)
+ private void TestRunVisitor_TestFinished(object sender, TestStateEventArgs e)
{
TestsCompleted++;
+ if (e.State > CurrentRunState)
+ {
+ CurrentRunState = e.State;
+ }
}
private bool CanExecuteCancel() => IsBusy && !IsCancelRequested;
@@ -325,13 +336,17 @@ namespace xunit.runner.wpf.ViewModel
}
}
+ ///
+ /// Note: More severe states are higher numbers.
+ ///
+ ///
public enum TestState
{
All = 0,
+ NotRun,
Passed,
- Failed,
Skipped,
- NotRun
+ Failed,
}
public class TestComparer : IComparer
diff --git a/xunit.runner.wpf/ViewModel/TestStateEventArgs.cs b/xunit.runner.wpf/ViewModel/TestStateEventArgs.cs
new file mode 100644
index 0000000..aaf1949
--- /dev/null
+++ b/xunit.runner.wpf/ViewModel/TestStateEventArgs.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace xunit.runner.wpf.ViewModel
+{
+ public class TestStateEventArgs : EventArgs
+ {
+ public static TestStateEventArgs Failed { get; } = new TestStateEventArgs(TestState.Failed);
+ public static TestStateEventArgs Passed { get; } = new TestStateEventArgs(TestState.Passed);
+ public static TestStateEventArgs Skipped { get; } = new TestStateEventArgs(TestState.Skipped);
+ private TestStateEventArgs(TestState state)
+ {
+ this.State = state;
+ }
+
+ public TestState State { get; }
+ }
+}
\ No newline at end of file
diff --git a/xunit.runner.wpf/xunit.runner.wpf.csproj b/xunit.runner.wpf/xunit.runner.wpf.csproj
index 45b5a4e..82671af 100644
--- a/xunit.runner.wpf/xunit.runner.wpf.csproj
+++ b/xunit.runner.wpf/xunit.runner.wpf.csproj
@@ -91,11 +91,13 @@
Designer
+
+
MSBuild:Compile