Add output pane capture
This commit is contained in:
Ryan Brandenburg 2022-03-28 16:42:08 -07:00 коммит произвёл GitHub
Родитель 8370db2279
Коммит 62d7f0abbb
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 87 добавлений и 1 удалений

Просмотреть файл

@ -98,7 +98,7 @@
<MicrosoftCodeAnalysisTestingVerifiersXunitPackageVersion>$(Tooling_MicrosoftCodeAnalysisTestingVersion)</MicrosoftCodeAnalysisTestingVerifiersXunitPackageVersion>
<OmniSharpMicrosoftExtensionsLoggingPackageVersion>2.0.0</OmniSharpMicrosoftExtensionsLoggingPackageVersion>
<MicrosoftVisualStudioEditorPackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioEditorPackageVersion>
<MicrosoftVisualStudioExtensibilityTestingXunitVersion>0.1.124-beta</MicrosoftVisualStudioExtensibilityTestingXunitVersion>
<MicrosoftVisualStudioExtensibilityTestingXunitVersion>0.1.135-beta</MicrosoftVisualStudioExtensibilityTestingXunitVersion>
<MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion>$(MicrosoftVisualStudioExtensibilityTestingXunitVersion)</MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion>
<MicrosoftVisualStudioLanguagePackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioLanguagePackageVersion>
<MicrosoftVisualStudioLanguageIntellisensePackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioLanguageIntellisensePackageVersion>

Просмотреть файл

@ -2,8 +2,11 @@
// Licensed under the MIT license. See License.txt in the project root for license information.
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host;
using Microsoft.VisualStudio.Razor.IntegrationTests.InProcess;
using Xunit.Harness;
namespace Microsoft.VisualStudio.Razor.IntegrationTests
{
@ -41,8 +44,12 @@ namespace Microsoft.VisualStudio.Razor.IntegrationTests
</div>
";
private const string RazorOutputLogId = "RazorOutputLog";
protected override string LanguageName => LanguageNames.Razor;
private static bool CustomLoggersAdded = false;
public override async Task InitializeAsync()
{
await base.InitializeAsync();
@ -61,6 +68,20 @@ namespace Microsoft.VisualStudio.Razor.IntegrationTests
// Close the file we opened, just in case, so the test can start with a clean slate
await TestServices.Editor.CloseDocumentWindowAsync(HangMitigatingCancellationToken);
// Add custom logs on failure if they haven't already been.
if (!CustomLoggersAdded)
{
DataCollectionService.RegisterCustomLogger(RazorOutputPaneLogger, RazorOutputLogId, "log");
CustomLoggersAdded = true;
}
async void RazorOutputPaneLogger(string filePath)
{
var paneContent = await TestServices.Output.GetRazorOutputPaneContentAsync(CancellationToken.None);
File.WriteAllText(filePath, paneContent);
}
}
}
}

Просмотреть файл

@ -19,5 +19,11 @@ namespace Microsoft.VisualStudio.Razor.IntegrationTests.Extensions
ErrorHandler.ThrowOnFailure(((IVsUserData)textView).GetData(DefGuidList.guidIWpfTextViewHost, out var wpfTextViewHost));
return (IWpfTextViewHost)wpfTextViewHost;
}
public static async Task<string> GetContentAsync(this IVsTextView vsTextView, JoinableTaskFactory joinableTaskFactory, CancellationToken cancellationToken)
{
var textViewHost = await vsTextView.GetTextViewHostAsync(joinableTaskFactory, cancellationToken);
return textViewHost.TextView.TextSnapshot.GetText();
}
}
}

Просмотреть файл

@ -0,0 +1,59 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Razor.IntegrationTests.Extensions;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TextManager.Interop;
namespace Microsoft.VisualStudio.Extensibility.Testing
{
[TestService]
internal partial class OutputInProcess
{
private const string RazorPaneName = "Razor Language Server Client";
/// <summary>
/// This method returns the current content of the "Razor Language Server Client" output pane.
/// </summary>
/// <param name="cancellationToken">A cancellation token.</param>
/// <returns>The contents of the RLSC output pane.</returns>
public Task<string> GetRazorOutputPaneContentAsync(CancellationToken cancellationToken)
{
var outputPaneTextView = GetOutputPaneTextView(RazorPaneName);
return outputPaneTextView.GetContentAsync(JoinableTaskFactory, cancellationToken);
}
private static IVsTextView GetOutputPaneTextView(string paneName)
{
var sVSOutputWindow = ServiceProvider.GlobalProvider.GetService<SVsOutputWindow, IVsOutputWindow>();
var extensibleObject = ServiceProvider.GlobalProvider.GetService<SVsOutputWindow, IVsExtensibleObject>();
// The null propName gives use the OutputWindow object
ErrorHandler.ThrowOnFailure(extensibleObject.GetAutomationObject(pszPropName: null, out var outputWindowObj));
var outputWindow = (EnvDTE.OutputWindow)outputWindowObj;
// This is a public entry point to COutputWindow::GetPaneByName
var pane = outputWindow.OutputWindowPanes.Item(paneName);
var textView = OutputWindowPaneToIVsTextView(pane, sVSOutputWindow);
return textView;
static IVsTextView OutputWindowPaneToIVsTextView(EnvDTE.OutputWindowPane outputWindowPane, IVsOutputWindow sVsOutputWindow)
{
var guid = Guid.Parse(outputWindowPane.Guid);
ErrorHandler.ThrowOnFailure(sVsOutputWindow.GetPane(guid, out var result));
if (result is not IVsTextView textView)
{
throw new InvalidOperationException($"{nameof(IVsOutputWindowPane)} should implement {nameof(IVsTextView)}");
}
return textView;
}
}
}
}