From 8fa9a5478dfccd53293660bae75bebb242c81b5f Mon Sep 17 00:00:00 2001
From: "dependencyupdates[bot]"
<218638057+dependencyupdates[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 09:33:40 +0000
Subject: [PATCH 1/5] Update dependency Particular.PlatformSample.ServicePulse
to 2.11.0
---
src/Particular.PlatformSample/Particular.PlatformSample.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Particular.PlatformSample/Particular.PlatformSample.csproj b/src/Particular.PlatformSample/Particular.PlatformSample.csproj
index d0175ee..baaa62e 100644
--- a/src/Particular.PlatformSample/Particular.PlatformSample.csproj
+++ b/src/Particular.PlatformSample/Particular.PlatformSample.csproj
@@ -11,7 +11,7 @@
-
+
From 9f12fde2d440c42d9678802eaa6532c072cf074d Mon Sep 17 00:00:00 2001
From: Jo Palac
Date: Tue, 8 Sep 2026 10:39:55 +1000
Subject: [PATCH 2/5] Fix tests to make them less flaky
---
.../VisualTests.cs | 79 ++++++++++++++++---
1 file changed, 70 insertions(+), 9 deletions(-)
diff --git a/src/Particular.PlatformSample.Tests/VisualTests.cs b/src/Particular.PlatformSample.Tests/VisualTests.cs
index 32b9cbe..b888394 100644
--- a/src/Particular.PlatformSample.Tests/VisualTests.cs
+++ b/src/Particular.PlatformSample.Tests/VisualTests.cs
@@ -1,6 +1,7 @@
namespace Particular.PlatformSample.Tests;
using System;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
@@ -74,28 +75,88 @@ public async Task TearDown()
[Test]
public async Task ShouldBeConnected()
{
- await Task.Delay(2000);
driver.Navigate().GoToUrl($"http://localhost:{TestPortsInternal.ServicePulse}/#/dashboard");
- await Task.Delay(10_000);
+
+ await WaitUntil(
+ () => IsDocumentReady() &&
+ driver.FindElements(By.CssSelector(".connection-failed")).Count == 0,
+ timeout: TimeSpan.FromSeconds(30),
+ failureMessage: "Expected ServicePulse to show a successful connection state on the dashboard.");
var connectionFailedSpans = driver.FindElements(By.CssSelector(".connection-failed"));
Assert.That(connectionFailedSpans.Count, Is.EqualTo(0));
+ }
+
+ bool IsDocumentReady()
+ {
+ if (driver is not IJavaScriptExecutor js)
+ {
+ return false;
+ }
- var connectionOkSpans = driver.FindElements(By.CssSelector(".pa-connection-success"));
- Assert.That(connectionOkSpans.Count, Is.EqualTo(2));
+ var readyState = js.ExecuteScript("return document.readyState")?.ToString();
+ return string.Equals(readyState, "complete", StringComparison.OrdinalIgnoreCase);
}
[Test]
public async Task CheckMonitoringPage()
{
- await Task.Delay(2000);
driver.Navigate().GoToUrl($"http://localhost:{TestPortsInternal.ServicePulse}/#/monitoring");
- await Task.Delay(10_000);
- var primaryButtons = driver.FindElements(By.CssSelector(".btn.btn-primary"));
- var noEndpointsButton = primaryButtons.Where(b => b.Text.Contains("how to enable endpoint monitoring")).FirstOrDefault();
+ await WaitUntil(
+ () => FindMetricsHelpLink() != null,
+ timeout: TimeSpan.FromSeconds(30),
+ failureMessage: "Expected monitoring page to render a link to metrics setup guidance.");
+
+ var noEndpointsButton = FindMetricsHelpLink();
Assert.That(noEndpointsButton, Is.Not.Null);
- Assert.That(noEndpointsButton.GetAttribute("href"), Is.EqualTo("https://docs.particular.net/monitoring/metrics/"));
+ var href = noEndpointsButton.GetAttribute("href") ?? string.Empty;
+ Assert.That(href, Does.Contain("monitoring/metrics"));
+ }
+
+ IWebElement FindMetricsHelpLink()
+ {
+ var primaryButtons = driver.FindElements(By.CssSelector("a.btn.btn-primary, .btn.btn-primary[href]"));
+
+ return primaryButtons.FirstOrDefault(b =>
+ {
+ var text = (b.Text ?? string.Empty).ToLowerInvariant();
+ var href = (b.GetAttribute("href") ?? string.Empty).ToLowerInvariant();
+
+ return href.Contains("monitoring/metrics") ||
+ (text.Contains("enable") && text.Contains("monitoring")) ||
+ text.Contains("metrics");
+ });
+ }
+
+ static async Task WaitUntil(Func condition, TimeSpan timeout, string failureMessage)
+ {
+ var sw = Stopwatch.StartNew();
+ Exception lastException = null;
+
+ while (sw.Elapsed < timeout)
+ {
+ try
+ {
+ if (condition())
+ {
+ return;
+ }
+ }
+ catch (Exception ex) when (ex is WebDriverException or InvalidOperationException)
+ {
+ lastException = ex;
+ }
+
+ await Task.Delay(250);
+ }
+
+ if (lastException != null)
+ {
+ throw new AssertionException($"{failureMessage} Last error: {lastException.Message}");
+ }
+
+ throw new AssertionException(failureMessage);
}
}
From ceebf48016475c177a475170e3a61c58b818482c Mon Sep 17 00:00:00 2001
From: Jo Palac
Date: Tue, 8 Sep 2026 10:44:23 +1000
Subject: [PATCH 3/5] fix cancellation token
---
src/Particular.PlatformSample.Tests/VisualTests.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Particular.PlatformSample.Tests/VisualTests.cs b/src/Particular.PlatformSample.Tests/VisualTests.cs
index b888394..483d623 100644
--- a/src/Particular.PlatformSample.Tests/VisualTests.cs
+++ b/src/Particular.PlatformSample.Tests/VisualTests.cs
@@ -81,7 +81,7 @@ await WaitUntil(
() => IsDocumentReady() &&
driver.FindElements(By.CssSelector(".connection-failed")).Count == 0,
timeout: TimeSpan.FromSeconds(30),
- failureMessage: "Expected ServicePulse to show a successful connection state on the dashboard.");
+ failureMessage: "Expected ServicePulse to show a successful connection state on the dashboard.", CancellationToken.None);
var connectionFailedSpans = driver.FindElements(By.CssSelector(".connection-failed"));
Assert.That(connectionFailedSpans.Count, Is.EqualTo(0));
@@ -106,7 +106,7 @@ public async Task CheckMonitoringPage()
await WaitUntil(
() => FindMetricsHelpLink() != null,
timeout: TimeSpan.FromSeconds(30),
- failureMessage: "Expected monitoring page to render a link to metrics setup guidance.");
+ failureMessage: "Expected monitoring page to render a link to metrics setup guidance.", CancellationToken.None);
var noEndpointsButton = FindMetricsHelpLink();
@@ -130,7 +130,7 @@ IWebElement FindMetricsHelpLink()
});
}
- static async Task WaitUntil(Func condition, TimeSpan timeout, string failureMessage)
+ static async Task WaitUntil(Func condition, TimeSpan timeout, string failureMessage, CancellationToken cancellationToken)
{
var sw = Stopwatch.StartNew();
Exception lastException = null;
@@ -149,7 +149,7 @@ static async Task WaitUntil(Func condition, TimeSpan timeout, string failu
lastException = ex;
}
- await Task.Delay(250);
+ await Task.Delay(250,cancellationToken);
}
if (lastException != null)
From 8221fce3a1a29bf367136464a9e10f201dda4d45 Mon Sep 17 00:00:00 2001
From: Rhys Bevilaqua
Date: Tue, 8 Sep 2026 08:58:26 +0800
Subject: [PATCH 4/5] Fix formatting
---
src/Particular.PlatformSample.Tests/VisualTests.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Particular.PlatformSample.Tests/VisualTests.cs b/src/Particular.PlatformSample.Tests/VisualTests.cs
index 483d623..daa0ea5 100644
--- a/src/Particular.PlatformSample.Tests/VisualTests.cs
+++ b/src/Particular.PlatformSample.Tests/VisualTests.cs
@@ -149,7 +149,7 @@ static async Task WaitUntil(Func condition, TimeSpan timeout, string failu
lastException = ex;
}
- await Task.Delay(250,cancellationToken);
+ await Task.Delay(250, cancellationToken);
}
if (lastException != null)
From 5a5a25b80fa81d0d9bcc008c676e1ba5b7075393 Mon Sep 17 00:00:00 2001
From: Jo Palac
Date: Tue, 8 Sep 2026 10:59:12 +1000
Subject: [PATCH 5/5] formatting fix
---
src/Particular.PlatformSample.Tests/VisualTests.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Particular.PlatformSample.Tests/VisualTests.cs b/src/Particular.PlatformSample.Tests/VisualTests.cs
index 483d623..daa0ea5 100644
--- a/src/Particular.PlatformSample.Tests/VisualTests.cs
+++ b/src/Particular.PlatformSample.Tests/VisualTests.cs
@@ -149,7 +149,7 @@ static async Task WaitUntil(Func condition, TimeSpan timeout, string failu
lastException = ex;
}
- await Task.Delay(250,cancellationToken);
+ await Task.Delay(250, cancellationToken);
}
if (lastException != null)