Skip to content

Commit 7564387

Browse files
fix full page screen shots with CDP
add thread safe logger and settings add tests for smart failure analysis add new AI smart failure analysis
1 parent 230e278 commit 7564387

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+766
-277
lines changed

Bellatrix.LLM/Bellatrix.LLM.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
</ItemGroup>
2121

2222
<ItemGroup>
23+
<Folder Include="failureAnalysis\" />
2324
<Folder Include="plugins\" />
2425
</ItemGroup>
2526

Bellatrix.LLM/cache/LocatorCacheDbContext.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public class LocatorCacheDbContext : DbContext
77
{
88
public DbSet<LocatorCacheEntry> LocatorCache { get; set; }
99
public DbSet<SelfHealingLocatorEntry> SelfHealingLocators { get; set; }
10+
public DbSet<SmartTestExecutionEntry> SmartTestExecutions { get; set; }
1011

1112
private readonly string _connectionString;
1213

@@ -44,5 +45,13 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
4445
modelBuilder.Entity<SelfHealingLocatorEntry>()
4546
.HasIndex(e => new { e.Project, e.AppLocation, e.ValidLocator })
4647
.IsUnique();
48+
49+
50+
modelBuilder.Entity<SmartTestExecutionEntry>()
51+
.Property(e => e.Id)
52+
.ValueGeneratedOnAdd();
53+
54+
modelBuilder.Entity<SmartTestExecutionEntry>()
55+
.HasIndex(e => e.TestFullName);
4756
}
4857
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace Bellatrix.LLM.cache;
2+
public class SmartTestExecutionEntry
3+
{
4+
public int Id { get; set; }
5+
public string TestFullName { get; set; }
6+
public DateTime ExecutionTime { get; set; }
7+
public string BddLog { get; set; }
8+
public string PageSummaryJson { get; set; }
9+
public string Project { get; set; }
10+
}

Bellatrix.LLM/embeddingsPythonServerInstructions.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,6 @@ Configuration needed:
4444
"resetIndexEverytime": false,
4545
"locatorRetryAttempts": 3,
4646
"enableSelfHealing": true,
47+
"enableSmartFailureAnalysis": true,
4748
}
4849
}

Bellatrix.LLM/settings/LargeLanguageModelsSettings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ public class LargeLanguageModelsSettings
55
{
66
public List<ModelSettings> ModelSettings { get; set; }
77
public bool EnableSelfHealing { get; set; } = false;
8+
public bool EnableSmartFailureAnalysis { get; set; } = false;
89
public string LocalCacheConnectionString { get; set; } // Postgres connection string
910
public string LocalCacheProjectName { get; set; }
1011
public string QdrantMemoryDbEndpoint { get; set; } = "http://localhost:6333";

src/Bellatrix.Core/Bellatrix.Core.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
<PackageReference Include="NUnit" Version="4.3.2" />
2828
<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
2929
<PackageReference Include="WindowsAzure.Storage" Version="9.3.3" />
30+
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.1-dev-00077" />
31+
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.2" />
32+
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
33+
<PackageReference Include="Serilog.Sinks.Debug" Version="3.0.0" />
34+
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
35+
<PackageReference Include="ReportPortal.Serilog" Version="2.0.0" />
3036
</ItemGroup>
3137

3238
<ItemGroup>

src/Bellatrix.Core/logging/Logger.cs

Lines changed: 89 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,120 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Text;
3+
using Serilog;
4+
using System.Threading;
5+
using ReportPortal.Serilog;
6+
using Bellatrix.Core.logging;
47

58
namespace Bellatrix;
69

710
public static class Logger
811
{
9-
private static readonly object _lockObject = new object();
12+
// ThreadLocal to ensure each test has its own log buffer
13+
private static readonly ThreadLocal<Dictionary<string, List<string>>> s_logBuffer = new ThreadLocal<Dictionary<string, List<string>>>(() => new Dictionary<string, List<string>>());
1014

11-
public static void LogInformation(string message, params object[] args)
15+
// ThreadLocal to ensure each thread has its own logger configuration
16+
private static readonly ThreadLocal<ILogger> s_logger = new ThreadLocal<ILogger>(InitializeLogger);
17+
18+
public static ThreadLocal<string> CurrentTestFullName { get; set; } = new ThreadLocal<string>();
19+
20+
static Logger()
21+
{
22+
s_logBuffer = new ThreadLocal<Dictionary<string, List<string>>>(() => new Dictionary<string, List<string>>());
23+
s_logger = new ThreadLocal<ILogger>(InitializeLogger);
24+
}
25+
26+
private static ILogger InitializeLogger()
1227
{
13-
lock (_lockObject)
28+
var loggerConfiguration = new LoggerConfiguration();
29+
var settings = ConfigurationService.GetSection<LoggingSettings>();
30+
31+
if (settings.IsEnabled)
1432
{
15-
try
33+
if (settings.IsConsoleLoggingEnabled)
34+
{
35+
loggerConfiguration.WriteTo.Console(outputTemplate: settings.OutputTemplate);
36+
}
37+
38+
if (settings.IsDebugLoggingEnabled)
1639
{
17-
Console.WriteLine(message, args);
40+
loggerConfiguration.WriteTo.Debug(outputTemplate: settings.OutputTemplate);
1841
}
19-
catch
42+
43+
if (settings.IsFileLoggingEnabled)
2044
{
21-
// ignore
45+
loggerConfiguration.WriteTo.File("test-log.txt", rollingInterval: RollingInterval.Day, outputTemplate: settings.OutputTemplate);
46+
}
47+
48+
if (settings.IsReportPortalLoggingEnabled)
49+
{
50+
loggerConfiguration.WriteTo.ReportPortal();
2251
}
2352
}
53+
54+
return loggerConfiguration.CreateLogger();
2455
}
2556

26-
public static void LogWarning(string message, params object[] args)
57+
// Method to accumulate logs in the buffer per test/thread
58+
private static void AccumulateLog(string logLevel, string message)
2759
{
28-
try
60+
if (s_logBuffer.Value == null)
2961
{
30-
Console.ForegroundColor = ConsoleColor.Yellow;
31-
Console.WriteLine(message, args);
32-
Console.ResetColor();
62+
s_logBuffer.Value = new Dictionary<string, List<string>>();
3363
}
34-
catch
64+
65+
if (!s_logBuffer.Value.ContainsKey(CurrentTestFullName.Value))
3566
{
36-
// ignore
67+
s_logBuffer.Value.Add(CurrentTestFullName.Value, new List<string>());
3768
}
69+
70+
s_logBuffer.Value[CurrentTestFullName.Value].Add(message);
71+
}
72+
73+
74+
public static void LogInformation(string message, params object[] args)
75+
{
76+
AccumulateLog("INFO", string.Format(message, args));
3877
}
3978

4079
public static void LogError(string message, params object[] args)
4180
{
42-
lock (_lockObject)
81+
AccumulateLog("ERROR", string.Format(message, args));
82+
}
83+
84+
public static void LogWarning(string message, params object[] args)
85+
{
86+
AccumulateLog("WARNING", string.Format(message, args));
87+
}
88+
89+
// Lock object to ensure thread-safe execution of FlushLogs
90+
private static readonly object _flushLock = new object();
91+
92+
public static string GetLogs()
93+
{
94+
if (s_logBuffer.Value.ContainsKey(CurrentTestFullName.Value))
4395
{
44-
try
45-
{
46-
Console.Error.WriteLine(message, args);
47-
}
48-
catch
96+
return string.Join(Environment.NewLine, s_logBuffer.Value[CurrentTestFullName.Value]);
97+
}
98+
99+
return "⚠️ No log entries captured for this test.";
100+
}
101+
102+
// Method to print the accumulated logs at the end of the test
103+
public static void FlushLogs()
104+
{
105+
lock (_flushLock) // Ensure that only one thread can execute FlushLogs at a time
106+
{
107+
// Check if there's anything to flush for the current test
108+
if (s_logBuffer.Value.ContainsKey(CurrentTestFullName.Value))
49109
{
50-
// ignore
110+
// Flush the logs to the configured sinks
111+
foreach (var log in s_logBuffer.Value[CurrentTestFullName.Value])
112+
{
113+
s_logger.Value.Information(log); // This could be switched to appropriate log levels
114+
}
115+
116+
// Clear the log buffer after flushing
117+
s_logBuffer.Value[CurrentTestFullName.Value].Clear();
51118
}
52119
}
53120
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Bellatrix.Plugins;
2+
using System;
3+
4+
namespace Bellatrix.Core.logging;
5+
public class LoggerFlushPlugin : Plugin
6+
{
7+
protected override void PreTestCleanup(object sender, PluginEventArgs e)
8+
{
9+
Logger.FlushLogs();
10+
}
11+
12+
public static void Add()
13+
{
14+
ServicesCollection.Current.RegisterType<Plugin, LoggerFlushPlugin>(Guid.NewGuid().ToString());
15+
}
16+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace Bellatrix.Core.logging;
2+
public class LoggingSettings
3+
{
4+
public bool IsEnabled { get; set; } = true;
5+
public bool IsConsoleLoggingEnabled { get; set; } = true;
6+
public bool IsDebugLoggingEnabled { get; set; } = true;
7+
public bool IsFileLoggingEnabled { get; set; } = false;
8+
public bool IsReportPortalLoggingEnabled { get; set; } = true;
9+
public bool ShouldMaskSensitiveInfo { get; set; } = true;
10+
public string OutputTemplate { get; set; } = "{Message:lj}{NewLine}{Exception}";
11+
}

src/Bellatrix.Plugins.Screenshots/Bellatrix.Plugins.Screenshots.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
<ItemGroup>
55
<PackageReference Include="NUnit" Version="4.3.2" />
6-
<PackageReference Include="Serilog" Version="3.1.1" />
76
<PackageReference Include="System.Drawing.Common" Version="8.0.1" />
87
<PackageReference Include="MSTest" Version="3.2.2" />
98
</ItemGroup>

0 commit comments

Comments
 (0)