diff --git a/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs b/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs index a01bbe0845..44666fd0b0 100644 --- a/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs +++ b/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs @@ -11,6 +11,7 @@ using System.Threading; using System.Threading.Tasks; using Avalonia.Remote.Protocol; using Avalonia.Remote.Protocol.Designer; +using Avalonia.Remote.Protocol.Viewport; using Xunit; using Xunit.Extensions; @@ -124,5 +125,115 @@ namespace Avalonia.DesignerSupport.Tests proc.WaitForExit(); } } + + [Theory] + [InlineData( + @"../../../../../tests/Avalonia.DesignerSupport.TestApp/bin/$BUILD/netcoreapp2.0/", + "Avalonia.DesignerSupport.TestApp", + "Avalonia.DesignerSupport.TestApp.dll", + @"../../../../../tests/Avalonia.DesignerSupport.TestApp/MainWindow.xaml"), + InlineData( + @"../../../../../samples/ControlCatalog.NetCore/bin/$BUILD/netcoreapp2.0/", + "ControlCatalog.NetCore", + "ControlCatalog.dll", + @"../../../../../samples/ControlCatalog/MainWindow.xaml")] + public async Task Designer_Should_Provide_A_Frame( + string outputDir, + string executableName, + string assemblyName, + string xamlFile) + { + + var xaml = File.ReadAllText(xamlFile); + string buildType; +#if DEBUG + buildType = "Debug"; +#else + buildType = "Release"; +#endif + outputDir = Path.GetFullPath(outputDir.Replace("$BUILD", buildType)); + + var sessionId = Guid.NewGuid(); + FrameMessage receivedFrame = null; + + var resultMessageReceivedToken = new CancellationTokenSource(); + + var tcpListener = new TcpListener(IPAddress.Loopback, 0); + tcpListener.Start(); + var port = ((IPEndPoint)tcpListener.LocalEndpoint).Port; + tcpListener.Stop(); + var transport = new BsonTcpTransport(); + transport.Listen(IPAddress.Loopback, port, conn => + { + conn.OnMessage += async (_, msg) => + { + if (msg is StartDesignerSessionMessage start) + { + Assert.Equal(sessionId, Guid.Parse(start.SessionId)); + await conn.Send(new ClientSupportedPixelFormatsMessage + { + Formats = new[] + { + Avalonia.Remote.Protocol.Viewport.PixelFormat.Bgra8888, + Avalonia.Remote.Protocol.Viewport.PixelFormat.Rgba8888, + } + }); + await conn.Send(new UpdateXamlMessage + { + AssemblyPath = Path.Combine(outputDir, assemblyName), + Xaml = xaml + }); + } + else if (msg is UpdateXamlResultMessage result) + { + if (result.Error != null) + outputHelper.WriteLine(result.Error); + + } + else if (msg is FrameMessage fm) + { + receivedFrame = fm; + resultMessageReceivedToken.Cancel(); + conn.Dispose(); + } + }; + }); + + var cmdline = + $"exec --runtimeconfig \"{outputDir}{executableName}.runtimeconfig.json\" --depsfile \"{outputDir}{executableName}.deps.json\" " + + $" \"{DesignerAppPath.Replace("$BUILD", buildType)}\" " + + $"--transport tcp-bson://127.0.0.1:{port}/ --session-id {sessionId} \"{outputDir}{executableName}.dll\""; + + using (var proc = new Process + { + StartInfo = new ProcessStartInfo("dotnet", cmdline) + { + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true, + WorkingDirectory = outputDir, + }, + EnableRaisingEvents = true + }) + { + proc.Start(); + + var cancelled = false; + try + { + await Task.Delay(1000000, resultMessageReceivedToken.Token); + } + catch (TaskCanceledException) + { + cancelled = true; + } + + Assert.True(cancelled, $"Message Not Received."); + Assert.NotNull(receivedFrame); + proc.Kill(); + proc.WaitForExit(); + } + } } }