Skip to content

Commit

Permalink
Merge branch 'main' into tg/webview
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/Cody.Core/Infrastructure/WebViewsManager.cs
#	src/Cody.VisualStudio.Tests/ChatLoggedBasicTests.cs
#	src/Cody.VisualStudio.Tests/ChatNotLoggedStateTests.cs
#	src/Cody.VisualStudio/Client/AgentClientProviderOptions.cs
#	src/Cody.VisualStudio/CodyPackage.cs
  • Loading branch information
Tomasz Gołębiowski committed Sep 30, 2024
2 parents 6018208 + 779619c commit e833ff2
Show file tree
Hide file tree
Showing 16 changed files with 164 additions and 32 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/cake-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ jobs:
dotnet cake
- name: Tests
env:
Access_Token_UI_Tests: ${{ secrets.SRC_ACCESS_TOKEN_DOTCOM }}
run: |
cd src
dotnet cake --target Tests
Expand Down
3 changes: 3 additions & 0 deletions src/Cody.Core/Settings/IUserSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ public interface IUserSettingsService
string AccessToken { get; set; }
string ServerEndpoint { get; set; }
string CodySettings { get; set; }
bool AcceptNonTrustedCert { get; set; }


event EventHandler AuthorizationDetailsChanged;
}
}
10 changes: 10 additions & 0 deletions src/Cody.Core/Settings/UserSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,15 @@ public string CodySettings
get => GetOrDefault(nameof(CodySettings), string.Empty);
set => Set(nameof(CodySettings), value);
}

public bool AcceptNonTrustedCert
{
get
{
var value = GetOrDefault(nameof(AcceptNonTrustedCert), false.ToString());
return bool.Parse(value);
}
set => Set(nameof(AcceptNonTrustedCert), value.ToString());
}
}
}
14 changes: 13 additions & 1 deletion src/Cody.UI/Controls/Options/GeneralOptionsControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
Expand All @@ -42,10 +43,19 @@
Name="ConfigurationsTextBox"
/>

<CheckBox
Name="AcceptNonTrustedCertCheckBox"
Grid.Row="2"
Grid.Column="1"
Margin="0 5 0 0"
IsChecked="{Binding AcceptNonTrustedCert, Mode=TwoWay}"
Content="Accept non-trusted certificates (requires restart)"
/>

<!--Get Help-->
<Button
Margin="0 5 0 0"
Grid.Row="2"
Grid.Row="3"
Grid.Column="1"
Height="25"
Width="100"
Expand All @@ -54,6 +64,8 @@
Command="{Binding ActivateBetaCommand}"
/>



<!--Sourcegraph URL-->
<Label
Grid.Row="0"
Expand Down
1 change: 1 addition & 0 deletions src/Cody.UI/Controls/Options/GeneralOptionsControl.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public void ForceBindingsUpdate()
// This is a workaround to get bindings updated. The second solution is to use NotifyPropertyChange for every TextBox in the Xaml, but current solution is a little more "clean" - everything is clearly visible in a one place.
SourcegraphUrlTextBox.GetBindingExpression(TextBox.TextProperty)?.UpdateSource();
ConfigurationsTextBox.GetBindingExpression(TextBox.TextProperty)?.UpdateSource();
AcceptNonTrustedCertCheckBox.GetBindingExpression(CheckBox.IsCheckedProperty)?.UpdateSource();
}
}
}
13 changes: 13 additions & 0 deletions src/Cody.UI/ViewModels/GeneralOptionsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,18 @@ public string SourcegraphUrl
}
}

private bool _acceptNonTrustedCert;
public bool AcceptNonTrustedCert
{
get => _acceptNonTrustedCert;
set
{
if (SetProperty(ref _acceptNonTrustedCert, value))
{
_logger.Debug($"AcceptNonTrustedCert set:{SourcegraphUrl}");
}
}
}

}
}
17 changes: 9 additions & 8 deletions src/Cody.VisualStudio.Tests/ChatLoggedBasicTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EnvDTE;
using Xunit;
using Xunit.Abstractions;

namespace Cody.VisualStudio.Tests
{
public class ChatLoggedBasicTests : PlaywrightInitializationTests
public class ChatLoggedBasicTests : PlaywrightTestsBase
{
public ChatLoggedBasicTests(ITestOutputHelper output) : base(output)
{
}

//[VsFact(Version = VsVersion.VS2022)]
[VsFact(Version = VsVersion.VS2022)]
public async Task Solution_Name_Is_Added_To_Chat_Input()
{
// given
OpenSolution(SolutionsPaths.GetConsoleApp1File("ConsoleApp1.sln"));
await WaitForPlaywrightAsync();
await OpenSolution(SolutionsPaths.GetConsoleApp1File("ConsoleApp1.sln"));

// when
var tags = await GetChatContextTags();
Expand All @@ -27,12 +28,12 @@ public async Task Solution_Name_Is_Added_To_Chat_Input()
Assert.Equal("ConsoleApp1", tags.Last().Name);
}

//[VsFact(Version = VsVersion.VS2022)]
[VsFact(Version = VsVersion.VS2022)]
public async Task Active_File_Name_And_Line_Selection_Is_Showing_In_Chat_Input()
{
// given
OpenSolution(SolutionsPaths.GetConsoleApp1File("ConsoleApp1.sln"));
await WaitForPlaywrightAsync();
await OpenSolution(SolutionsPaths.GetConsoleApp1File("ConsoleApp1.sln"));

// when
const int startLine = 3; const int endLine = 5;
Expand All @@ -47,8 +48,8 @@ public async Task Active_File_Name_And_Line_Selection_Is_Showing_In_Chat_Input()
Assert.Equal(endLine, secondTag.EndLine);
}

//[VsFact(Version = VsVersion.VS2022)]
public async Task Can_you_close_and_reopen_chat_tool_window()
[VsFact(Version = VsVersion.VS2022)]
public async Task Can_Chat_Tool_Window_Be_Closed_And_Opened_Again()
{
await WaitForPlaywrightAsync();

Expand All @@ -62,7 +63,7 @@ public async Task Can_you_close_and_reopen_chat_tool_window()
}

//[VsFact(Version = VsVersion.VS2022)]
public async Task Does_chat_history_show_up_after_you_have_submitting_a_chat_close_and_reopen_window()
public async Task Entered_Prompt_Show_Up_In_Today_History()
{
var num = new Random().Next();
var prompt = $"How to create const with value {num}?";
Expand Down
15 changes: 7 additions & 8 deletions src/Cody.VisualStudio.Tests/ChatNotLoggedStateTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
Expand All @@ -17,28 +18,26 @@ public ChatNotLoggedStateTests(ITestOutputHelper output) : base(output)
public async Task Loads_Properly_InNotLoggedState()
{
// given
var codyPackage = await GetPackageAsync();
var settingsService = codyPackage.UserSettingsService;
settingsService.AccessToken = settingsService.AccessToken.Replace("INVALID", "");
var accessToken = codyPackage.UserSettingsService.AccessToken;

var text = "Cody Free or Cody Pro";
IReadOnlyList<string> textContents;
string accessToken = null;
try
{
await WaitForPlaywrightAsync();
codyPackage.UserSettingsService.AccessToken += "INVALID";
await Task.Delay(TimeSpan.FromMilliseconds(500)); // wait for the Chat to response

// when
accessToken = await GetAccessToken();
if (accessToken != null)
await SetAccessToken("INVALID");

// when
var getStarted = Page.GetByText(text);
textContents = await getStarted.AllTextContentsAsync();
}
finally
{
if (accessToken != null)
settingsService.AccessToken = accessToken; // make it valid
await SetAccessToken(accessToken); // make it valid
}

// then
Expand Down
31 changes: 29 additions & 2 deletions src/Cody.VisualStudio.Tests/PlaywrightTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ private async Task InitializeAsync()
await WaitForChat();
WriteLog("Chat initialized and loaded.");

var accessToken = Environment.GetEnvironmentVariable("Access_Token_UI_Tests");
if (accessToken != null)
{
WriteLog("Using Access Token.");
CodyPackage.UserSettingsService.AccessToken = accessToken;
}

Playwright = await Microsoft.Playwright.Playwright.CreateAsync();
WriteLog("Playwright created.");

Expand All @@ -59,6 +66,10 @@ private async Task InitializeAsync()
Context = Browser.Contexts[0];
Page = Context.Pages[0];

//var playwrightTimeout = (float)TimeSpan.FromMinutes(3).TotalMilliseconds;
//Page.SetDefaultNavigationTimeout(playwrightTimeout);
//Page.SetDefaultTimeout(playwrightTimeout);

_isInitialized = true;
}
finally
Expand Down Expand Up @@ -99,6 +110,21 @@ await OnUIThread(() =>
});
}

protected async Task<string> GetAccessToken()
{
await WaitForPlaywrightAsync();

var accessToken = CodyPackage.UserSettingsService.AccessToken;

return accessToken;
}

protected async Task SetAccessToken(string accessToken)
{
CodyPackage.UserSettingsService.AccessToken = accessToken;
await Task.Delay(TimeSpan.FromMilliseconds(2000)); // wait for the Chat to response
}

protected async Task ShowChatTab() => await Page.GetByTestId("tab-chat").ClickAsync();

protected async Task ShowHistoryTab() => await Page.GetByTestId("tab-history").ClickAsync();
Expand All @@ -124,8 +150,7 @@ protected async Task EnterChatTextAndSend(string prompt)

protected async Task<string[]> GetTodayChatHistory()
{
var todaySection = await Page.QuerySelectorAsync("div[id='radix-:r11:']") ??
await Page.QuerySelectorAsync("div[id='radix-:r1b:']");
var todaySection = await Page.QuerySelectorAsync("div[id='history-today-content']");

return (await todaySection.QuerySelectorAllAsync("button span"))
.Select(async x => await x.TextContentAsync())
Expand All @@ -138,6 +163,8 @@ protected async Task<IReadOnlyCollection<ContextTag>> GetChatContextTags()
var tagsList = new List<ContextTag>();

var chatBox = await Page.QuerySelectorAsync("[aria-label='Chat message']");
if (chatBox == null) throw new Exception("ChatBox is null. Probably not authenticated.");

var list = await chatBox.QuerySelectorAllAsync("span[data-lexical-decorator='true']");
foreach (var item in list)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Cody.VisualStudio.Tests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: TestFramework("Xunit.VsTestFramework", "VsixTesting.Xunit")]
[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly, DisableTestParallelization = true)]
[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly, DisableTestParallelization = true, MaxParallelThreads = 1)]
22 changes: 18 additions & 4 deletions src/Cody.VisualStudio.Tests/TestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public abstract class TestsBase : ITestLogger
{
private readonly ITestOutputHelper _logger;

protected CodyPackage CodyPackage;
protected static CodyPackage CodyPackage;

protected TestsBase(ITestOutputHelper output)
{
Expand All @@ -28,7 +28,14 @@ protected TestsBase(ITestOutputHelper output)

public void WriteLog(string message, string type = "", [CallerMemberName] string callerName = "")
{
_logger.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] [{type}] [{callerName}] [ThreadId:{Thread.CurrentThread.ManagedThreadId}] {message}");
try
{
_logger.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] [{type}] [{callerName}] [ThreadId:{Thread.CurrentThread.ManagedThreadId}] {message}");
}
catch
{
// ignored, because of https://github.com/xunit/xunit/issues/2146
}
}

private IVsUIShell _uiShell;
Expand All @@ -37,12 +44,19 @@ public void WriteLog(string message, string type = "", [CallerMemberName] string
private DTE2 _dte;
protected DTE2 Dte => _dte ?? (_dte = (DTE2)Package.GetGlobalService(typeof(DTE)));

protected void OpenSolution(string path) => Dte.Solution.Open(path);
protected async Task OpenSolution(string path)
{
Dte.Solution.Open(path);

await Task.Delay(TimeSpan.FromSeconds(5));
}

protected void CloseSolution() => Dte.Solution.Close();

protected async Task OpenDocument(string path, int? selectLineStart = null, int? selectLineEnd = null)
{
WriteLog($"CodyPackage: {CodyPackage} ");

VsShellUtilities.OpenDocument(CodyPackage, path, Guid.Empty, out _, out _, out IVsWindowFrame frame);
frame.Show();

Expand Down Expand Up @@ -105,7 +119,7 @@ protected async Task<CodyPackage> GetPackageAsync()
protected async Task WaitForAsync(Func<bool> condition)
{
var startTime = DateTime.Now;
var timeout = TimeSpan.FromMinutes(5);
var timeout = TimeSpan.FromMinutes(2);
while (!condition.Invoke())
{
await Task.Delay(TimeSpan.FromSeconds(1));
Expand Down
3 changes: 3 additions & 0 deletions src/Cody.VisualStudio/Client/AgentClientProviderOptions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Cody.Core.Agent;
using Cody.Core.Agent.Protocol;
using System;
using System.Collections.Generic;
Expand All @@ -15,6 +16,8 @@ public class AgentClientProviderOptions
/// </summary>
public int RemoteAgentPort { get; set; } = 3113;

public bool AcceptNonTrustedCertificates { get; set; } = false;

public string AgentDirectory { get; set; }

public List<object> CallbackHandlers { get; set; } = new List<object>();
Expand Down
4 changes: 4 additions & 0 deletions src/Cody.VisualStudio/Client/AgentProcessConnector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public void Connect(AgentClientProviderOptions options)
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.CreateNoWindow = true;
process.EnableRaisingEvents = true;

if (options.AcceptNonTrustedCertificates)
process.StartInfo.EnvironmentVariables["NODE_TLS_REJECT_UNAUTHORIZED"] = "0";

process.Exited += OnProcessExited;
process.ErrorDataReceived += OnErrorDataReceived;

Expand Down
Loading

0 comments on commit e833ff2

Please sign in to comment.