diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt
index e62000b64..4fde5ece1 100644
--- a/.github/actions/spelling/allow.txt
+++ b/.github/actions/spelling/allow.txt
@@ -3,6 +3,7 @@ autorun
barcode
chainable
clickable
+cloudflare
entra
flyout
hackish
diff --git a/.gitignore b/.gitignore
index 5a46f84bc..fe2690d08 100644
--- a/.gitignore
+++ b/.gitignore
@@ -199,3 +199,4 @@ src/*.Web/Localization
/test.out
.ps1-analyzer-stamp
/NDependOut/
+/build.binlog
diff --git a/NuGet.config b/NuGet.config
index a200e1231..2ac919f5f 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -1,8 +1,16 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/NuGetTest/NuGet.config b/NuGetTest/NuGet.config
index 75aab7c26..2e8ae60af 100644
--- a/NuGetTest/NuGet.config
+++ b/NuGetTest/NuGet.config
@@ -1,10 +1,9 @@
-
+
+
-
-
diff --git a/NuGetTest/src/Lombiq.OSOCE.NuGet.Web/Lombiq.OSOCE.NuGet.Web.csproj b/NuGetTest/src/Lombiq.OSOCE.NuGet.Web/Lombiq.OSOCE.NuGet.Web.csproj
index b1871ff1d..69be6c658 100644
--- a/NuGetTest/src/Lombiq.OSOCE.NuGet.Web/Lombiq.OSOCE.NuGet.Web.csproj
+++ b/NuGetTest/src/Lombiq.OSOCE.NuGet.Web/Lombiq.OSOCE.NuGet.Web.csproj
@@ -19,48 +19,49 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
diff --git a/NuGetTest/src/Lombiq.OSOCE.NuGet.Web/Recipes/Lombiq.OSOCE.NuGet.Tests.recipe.json b/NuGetTest/src/Lombiq.OSOCE.NuGet.Web/Recipes/Lombiq.OSOCE.NuGet.Tests.recipe.json
index 262257cfa..5657c7dfe 100644
--- a/NuGetTest/src/Lombiq.OSOCE.NuGet.Web/Recipes/Lombiq.OSOCE.NuGet.Tests.recipe.json
+++ b/NuGetTest/src/Lombiq.OSOCE.NuGet.Web/Recipes/Lombiq.OSOCE.NuGet.Tests.recipe.json
@@ -17,6 +17,7 @@
"name": "feature",
"disable": [],
"enable": [
+ "OrchardCore.Email.Smtp",
"OrchardCore.Localization",
"Lombiq.AuditTrailExtensions",
"Lombiq.ChartJs",
diff --git a/NuGetTest/src/Modules/Lombiq.OSOCE.NuGet.TestModule/Lombiq.OSOCE.NuGet.TestModule.csproj b/NuGetTest/src/Modules/Lombiq.OSOCE.NuGet.TestModule/Lombiq.OSOCE.NuGet.TestModule.csproj
index 666a277ac..780540d17 100644
--- a/NuGetTest/src/Modules/Lombiq.OSOCE.NuGet.TestModule/Lombiq.OSOCE.NuGet.TestModule.csproj
+++ b/NuGetTest/src/Modules/Lombiq.OSOCE.NuGet.TestModule/Lombiq.OSOCE.NuGet.TestModule.csproj
@@ -16,11 +16,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/NuGetTest/src/Themes/Lombiq.OSOCE.NuGet.TestTheme/Lombiq.OSOCE.NuGet.TestTheme.csproj b/NuGetTest/src/Themes/Lombiq.OSOCE.NuGet.TestTheme/Lombiq.OSOCE.NuGet.TestTheme.csproj
index b7816bfba..c9bc36b78 100644
--- a/NuGetTest/src/Themes/Lombiq.OSOCE.NuGet.TestTheme/Lombiq.OSOCE.NuGet.TestTheme.csproj
+++ b/NuGetTest/src/Themes/Lombiq.OSOCE.NuGet.TestTheme/Lombiq.OSOCE.NuGet.TestTheme.csproj
@@ -21,10 +21,10 @@
-
-
-
-
+
+
+
+
diff --git a/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Lombiq.OSOCE.NuGet.Tests.UI.csproj b/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Lombiq.OSOCE.NuGet.Tests.UI.csproj
index 93981b482..b2a82c285 100644
--- a/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Lombiq.OSOCE.NuGet.Tests.UI.csproj
+++ b/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Lombiq.OSOCE.NuGet.Tests.UI.csproj
@@ -13,36 +13,38 @@
PreserveNewest
-
+
PreserveNewest
true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/NoUniqueLandmark.htmlvalidate.json b/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/NoUniqueLandmark.htmlvalidate.json
new file mode 100644
index 000000000..ac824b887
--- /dev/null
+++ b/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/NoUniqueLandmark.htmlvalidate.json
@@ -0,0 +1,11 @@
+{
+ "extends": [
+ "./default.htmlvalidate.json"
+ ],
+
+ "rules": {
+ "unique-landmark": "off"
+ },
+
+ "root": true
+}
diff --git a/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Tests/ModuleTests/BehaviorEmailQuotaTests.cs b/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Tests/ModuleTests/BehaviorEmailQuotaTests.cs
index 51353c09a..6007c074d 100644
--- a/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Tests/ModuleTests/BehaviorEmailQuotaTests.cs
+++ b/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Tests/ModuleTests/BehaviorEmailQuotaTests.cs
@@ -1,4 +1,5 @@
using Lombiq.Hosting.Tenants.EmailQuotaManagement.Tests.UI.Extensions;
+using Lombiq.Tests.UI.Extensions;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
@@ -21,8 +22,14 @@ public Task EmailQuotaShouldBlockEmailsOverLimitAndWarn() =>
[Fact]
public Task EmailQuotaShouldNotBlockEmailsWhenDifferentHostIsUsedThanOriginalFromConfig() =>
ExecuteTestAfterSetupAsync(
- context => context.TestEmailQuotaManagementBehaviorAsync(1, moduleShouldInterfere: false),
- // The default SMTP host is localhost during UI tests, we set it to 127.0.0.1 to be able to send emails,
- // but the Email Quota module shouldn't interfere.
- configuration => configuration.SetEmailQuotaManagementOptionsForUITest(1, "127.0.0.1"));
+ async context =>
+ {
+ // The default SMTP host is localhost during UI tests. We set it to 127.0.0.1 to still be able to send
+ // emails (since localhost and 127.0.0.1 is the same), but the Email Quota module shouldn't interfere,
+ // thinking it's a non-default host.
+ await context.SignInDirectlyAndGoToDashboardAsync();
+ await context.ConfigureSmtpSettingsAsync("sender@example.com", "127.0.0.1");
+ await context.TestEmailQuotaManagementBehaviorAsync(1, moduleShouldInterfere: false);
+ },
+ configuration => configuration.SetEmailQuotaManagementOptionsForUITest(1));
}
diff --git a/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Tests/ModuleTests/BehaviorWalkthroughsTests.cs b/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Tests/ModuleTests/BehaviorWalkthroughsTests.cs
index ddbc50673..1339003aa 100644
--- a/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Tests/ModuleTests/BehaviorWalkthroughsTests.cs
+++ b/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests.UI/Tests/ModuleTests/BehaviorWalkthroughsTests.cs
@@ -1,10 +1,4 @@
-using Lombiq.Tests.UI.Extensions;
-using Lombiq.Tests.UI.Services;
using Lombiq.Walkthroughs.Tests.UI.Extensions;
-using OpenQA.Selenium;
-using Shouldly;
-using System;
-using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
@@ -22,23 +16,7 @@ public BehaviorWalkthroughsTests(ITestOutputHelper testOutputHelper)
public Task WalkthroughsShouldWorkCorrectly() =>
ExecuteTestAsync(
context => context.RunSetupAndTestWalkthroughsBehaviorAsync(),
- // Could be removed if https://github.com/shepherd-pro/shepherd/issues/2555 is fixed.
- changeConfiguration: configuration =>
- {
- configuration.HtmlValidationConfiguration
- .WithRelativeConfigPath("BehaviorWalkthroughsTests.htmlvalidate.json");
-
- configuration.AssertBrowserLog = logEntries => logEntries.ShouldNotContain(
- logEntry => IsValidLogEntry(logEntry),
- logEntries.Where(IsValidLogEntry).ToFormattedString());
- });
-
- private static bool IsValidLogEntry(LogEntry logEntry) =>
- OrchardCoreUITestExecutorConfiguration.IsValidBrowserLogEntry(logEntry) &&
- // See https://github.com/OrchardCMS/OrchardCore/issues/15301.
- !(logEntry.Message.ContainsOrdinalIgnoreCase("/OrchardCore.Resources/Scripts/jquery.js?v=") &&
- logEntry.Message.ContainsOrdinalIgnoreCase("Uncaught")) &&
- // See https://github.com/OrchardCMS/OrchardCore/issues/14598. This error has multiple variations, so targeting
- // the lowest common denominator with the file name.
- !logEntry.Message.ContainsOrdinalIgnoreCase("/monaco/IStandaloneEditorConstructionOptions.json");
+ changeConfiguration: configuration => configuration
+ .HtmlValidationConfiguration
+ .WithRelativeConfigPath("NoUniqueLandmark.htmlvalidate.json"));
}
diff --git a/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests/Lombiq.OSOCE.NuGet.Tests.csproj b/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests/Lombiq.OSOCE.NuGet.Tests.csproj
index c108c3423..6539d91e4 100644
--- a/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests/Lombiq.OSOCE.NuGet.Tests.csproj
+++ b/NuGetTest/test/Lombiq.OSOCE.NuGet.Tests/Lombiq.OSOCE.NuGet.Tests.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/src/Libraries/Lombiq.HelpfulLibraries b/src/Libraries/Lombiq.HelpfulLibraries
index 050e2af84..415b9a659 160000
--- a/src/Libraries/Lombiq.HelpfulLibraries
+++ b/src/Libraries/Lombiq.HelpfulLibraries
@@ -1 +1 @@
-Subproject commit 050e2af84a9f30e45a21010a638f5e0ae4132116
+Subproject commit 415b9a659d7086361c4882146fe5e19d418f11e2
diff --git a/src/Libraries/Lombiq.OrchardCoreApiClient b/src/Libraries/Lombiq.OrchardCoreApiClient
index 1c499e01b..ab9e54675 160000
--- a/src/Libraries/Lombiq.OrchardCoreApiClient
+++ b/src/Libraries/Lombiq.OrchardCoreApiClient
@@ -1 +1 @@
-Subproject commit 1c499e01bfbf0e5918b7054937af08a99378c9a5
+Subproject commit ab9e546755fd6369de347d0d068a75752cbca70d
diff --git a/src/Lombiq.OSOCE.Web/Lombiq.OSOCE.Web.csproj b/src/Lombiq.OSOCE.Web/Lombiq.OSOCE.Web.csproj
index a89602a30..387797cce 100644
--- a/src/Lombiq.OSOCE.Web/Lombiq.OSOCE.Web.csproj
+++ b/src/Lombiq.OSOCE.Web/Lombiq.OSOCE.Web.csproj
@@ -1,67 +1,67 @@
-
-
-
- net8.0
- true
- InProcess
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ net8.0
+ true
+ InProcess
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Lombiq.OSOCE.Web/Recipes/Lombiq.OSOCE.Tests.recipe.json b/src/Lombiq.OSOCE.Web/Recipes/Lombiq.OSOCE.Tests.recipe.json
index 27a3c1c5b..41e00441a 100644
--- a/src/Lombiq.OSOCE.Web/Recipes/Lombiq.OSOCE.Tests.recipe.json
+++ b/src/Lombiq.OSOCE.Web/Recipes/Lombiq.OSOCE.Tests.recipe.json
@@ -58,6 +58,7 @@
"OrchardCore.Localization",
"OrchardCore.Features",
"OrchardCore.Media",
+ "OrchardCore.Email.Smtp",
"TheTheme"
// Not enabling Lombiq.TrainingDemo.Middlewares because that would write to the error log on every request.
]
diff --git a/src/Lombiq.OSOCE.Web/wwwroot/favicon.ico b/src/Lombiq.OSOCE.Web/wwwroot/favicon.ico
new file mode 100644
index 000000000..ef7cf899f
Binary files /dev/null and b/src/Lombiq.OSOCE.Web/wwwroot/favicon.ico differ
diff --git a/src/Modules/Lombiq.AuditTrailExtensions b/src/Modules/Lombiq.AuditTrailExtensions
index 5da091039..21b9bfadf 160000
--- a/src/Modules/Lombiq.AuditTrailExtensions
+++ b/src/Modules/Lombiq.AuditTrailExtensions
@@ -1 +1 @@
-Subproject commit 5da091039708e7a93534bc45a25bfc80b9fb016c
+Subproject commit 21b9bfadf3c40f05ed5b64032c3351a1f4690704
diff --git a/src/Modules/Lombiq.ChartJs b/src/Modules/Lombiq.ChartJs
index d8a96acb8..b818ff1d0 160000
--- a/src/Modules/Lombiq.ChartJs
+++ b/src/Modules/Lombiq.ChartJs
@@ -1 +1 @@
-Subproject commit d8a96acb89a056c0999d3211bb490564918a4870
+Subproject commit b818ff1d0d05d55570ae645f6c3e3b5af2ab3343
diff --git a/src/Modules/Lombiq.ContentEditors b/src/Modules/Lombiq.ContentEditors
index 447bc95e8..85fe79b53 160000
--- a/src/Modules/Lombiq.ContentEditors
+++ b/src/Modules/Lombiq.ContentEditors
@@ -1 +1 @@
-Subproject commit 447bc95e85ef83b262dec85e65ee99529ee2dca0
+Subproject commit 85fe79b5350ecbef2801b51854dcbe4d6703d96a
diff --git a/src/Modules/Lombiq.DataTables b/src/Modules/Lombiq.DataTables
index d7a2ef6c7..a3900984d 160000
--- a/src/Modules/Lombiq.DataTables
+++ b/src/Modules/Lombiq.DataTables
@@ -1 +1 @@
-Subproject commit d7a2ef6c7da1d5921fb17a763ea8f3d774a1b5c7
+Subproject commit a3900984df7f014c08f0eebc4d98df043adba3c7
diff --git a/src/Modules/Lombiq.Hosting.Azure.ApplicationInsights b/src/Modules/Lombiq.Hosting.Azure.ApplicationInsights
index 44ec93ad7..e455d9293 160000
--- a/src/Modules/Lombiq.Hosting.Azure.ApplicationInsights
+++ b/src/Modules/Lombiq.Hosting.Azure.ApplicationInsights
@@ -1 +1 @@
-Subproject commit 44ec93ad70331a89599d4f9e9219787171d8dc99
+Subproject commit e455d929305529a7e35fffaddb036db2f060606b
diff --git a/src/Modules/Lombiq.Hosting.BuildVersionDisplay b/src/Modules/Lombiq.Hosting.BuildVersionDisplay
index 903575473..0abc75d3c 160000
--- a/src/Modules/Lombiq.Hosting.BuildVersionDisplay
+++ b/src/Modules/Lombiq.Hosting.BuildVersionDisplay
@@ -1 +1 @@
-Subproject commit 9035754732f2da8ed37e304201a6b5abc5d61aee
+Subproject commit 0abc75d3cb3296c93c035c97be43322c0f145e26
diff --git a/src/Modules/Lombiq.Hosting.Tenants b/src/Modules/Lombiq.Hosting.Tenants
index 624b4e47d..1c06bf69e 160000
--- a/src/Modules/Lombiq.Hosting.Tenants
+++ b/src/Modules/Lombiq.Hosting.Tenants
@@ -1 +1 @@
-Subproject commit 624b4e47d6344cc912b89ad052b7377cb946a26d
+Subproject commit 1c06bf69e34529131173c43e48f87a1dc2eee7d2
diff --git a/src/Modules/Lombiq.JsonEditor b/src/Modules/Lombiq.JsonEditor
index c804c5cf7..6eac2f729 160000
--- a/src/Modules/Lombiq.JsonEditor
+++ b/src/Modules/Lombiq.JsonEditor
@@ -1 +1 @@
-Subproject commit c804c5cf772bb8f847484af1a70b8585d05bde7a
+Subproject commit 6eac2f729c7336febb7413f7d1b221a2e3086ddb
diff --git a/src/Modules/Lombiq.LoginAsAnybody b/src/Modules/Lombiq.LoginAsAnybody
index 1d01f7cf7..e773d18a6 160000
--- a/src/Modules/Lombiq.LoginAsAnybody
+++ b/src/Modules/Lombiq.LoginAsAnybody
@@ -1 +1 @@
-Subproject commit 1d01f7cf7a7a7a85c86b0b259716c73e13aebb2e
+Subproject commit e773d18a6b8189bb8892b44a846390a95ec1cfff
diff --git a/src/Modules/Lombiq.OSOCE.Samples/Lombiq.OSOCE.Samples.csproj b/src/Modules/Lombiq.OSOCE.Samples/Lombiq.OSOCE.Samples.csproj
index d20591726..04b452436 100644
--- a/src/Modules/Lombiq.OSOCE.Samples/Lombiq.OSOCE.Samples.csproj
+++ b/src/Modules/Lombiq.OSOCE.Samples/Lombiq.OSOCE.Samples.csproj
@@ -11,10 +11,10 @@
-
-
-
-
+
+
+
+
diff --git a/src/Modules/Lombiq.OSOCE.Samples/Startup.cs b/src/Modules/Lombiq.OSOCE.Samples/Startup.cs
index dd1336475..340f1cd3c 100644
--- a/src/Modules/Lombiq.OSOCE.Samples/Startup.cs
+++ b/src/Modules/Lombiq.OSOCE.Samples/Startup.cs
@@ -2,6 +2,6 @@
namespace Lombiq.OSOCE.Samples;
-public class Startup : StartupBase
+public sealed class Startup : StartupBase
{
}
diff --git a/src/Modules/Lombiq.Privacy b/src/Modules/Lombiq.Privacy
index 2063d12f2..dc55955b0 160000
--- a/src/Modules/Lombiq.Privacy
+++ b/src/Modules/Lombiq.Privacy
@@ -1 +1 @@
-Subproject commit 2063d12f2e556df0f03d8b1a60db2db79c535ce1
+Subproject commit dc55955b03a1405d15e320da7b4ea1fcaf61db9e
diff --git a/src/Modules/Lombiq.TrainingDemo b/src/Modules/Lombiq.TrainingDemo
index bdf7fc70a..0684bb884 160000
--- a/src/Modules/Lombiq.TrainingDemo
+++ b/src/Modules/Lombiq.TrainingDemo
@@ -1 +1 @@
-Subproject commit bdf7fc70a43a6b77af853f17c14332297cd1fe2d
+Subproject commit 0684bb884fdc86c510422cc7bc5f4b786899e9bc
diff --git a/src/Modules/Lombiq.UIKit b/src/Modules/Lombiq.UIKit
index c0adfdf96..010d4c92d 160000
--- a/src/Modules/Lombiq.UIKit
+++ b/src/Modules/Lombiq.UIKit
@@ -1 +1 @@
-Subproject commit c0adfdf96432a64f1be94286ccefef418e3dd3dc
+Subproject commit 010d4c92d065d329f09ddd9836dcb8059e0daab1
diff --git a/src/Modules/Lombiq.VueJs b/src/Modules/Lombiq.VueJs
index ce88ec063..d3e10bb2d 160000
--- a/src/Modules/Lombiq.VueJs
+++ b/src/Modules/Lombiq.VueJs
@@ -1 +1 @@
-Subproject commit ce88ec063bfec8f5f6404212e6dad26f7bec8ca4
+Subproject commit d3e10bb2d3e39afb00b9f325856a82aaa7fae1d7
diff --git a/src/Modules/Lombiq.Walkthroughs b/src/Modules/Lombiq.Walkthroughs
index 621fa19a3..f3a88d918 160000
--- a/src/Modules/Lombiq.Walkthroughs
+++ b/src/Modules/Lombiq.Walkthroughs
@@ -1 +1 @@
-Subproject commit 621fa19a3debdccc6e73ff6fef23200a399d774a
+Subproject commit f3a88d918274eceeefeb7bb9a23278047a6ed904
diff --git a/src/Themes/Lombiq.BaseTheme b/src/Themes/Lombiq.BaseTheme
index ed00fde6d..4ed2b1b9c 160000
--- a/src/Themes/Lombiq.BaseTheme
+++ b/src/Themes/Lombiq.BaseTheme
@@ -1 +1 @@
-Subproject commit ed00fde6d8b4d009b63b58190af5c9c3bae35318
+Subproject commit 4ed2b1b9cd6e30dc9fe9c9d706c69099db7f49bf
diff --git a/src/Themes/Lombiq.Hosting.MediaTheme b/src/Themes/Lombiq.Hosting.MediaTheme
index 444b5948d..d84292aa2 160000
--- a/src/Themes/Lombiq.Hosting.MediaTheme
+++ b/src/Themes/Lombiq.Hosting.MediaTheme
@@ -1 +1 @@
-Subproject commit 444b5948d50ea613e875e6c064d879a55036badd
+Subproject commit d84292aa2782041d1fde0b6adaee6fa32d38dd7b
diff --git a/src/Utilities/Lombiq.NodeJs.Extensions b/src/Utilities/Lombiq.NodeJs.Extensions
index 821bb5eb3..e109520e0 160000
--- a/src/Utilities/Lombiq.NodeJs.Extensions
+++ b/src/Utilities/Lombiq.NodeJs.Extensions
@@ -1 +1 @@
-Subproject commit 821bb5eb30d94197ef37eb558dc2045294ec1edc
+Subproject commit e109520e0df3f77fce578eceb84e611bd18ad683
diff --git a/src/Utilities/Lombiq.SetupExtensions b/src/Utilities/Lombiq.SetupExtensions
index a9bfb9eac..080464ed9 160000
--- a/src/Utilities/Lombiq.SetupExtensions
+++ b/src/Utilities/Lombiq.SetupExtensions
@@ -1 +1 @@
-Subproject commit a9bfb9eacf63cdfebcf16e8eba175985d47e37c5
+Subproject commit 080464ed9172b7627b7ad798082d2b730a8ceaae
diff --git a/test/Lombiq.OSOCE.Tests.UI/Helpers/AssertAppLogsHelpers.cs b/test/Lombiq.OSOCE.Tests.UI/Helpers/AssertAppLogsHelpers.cs
new file mode 100644
index 000000000..c44d6c77b
--- /dev/null
+++ b/test/Lombiq.OSOCE.Tests.UI/Helpers/AssertAppLogsHelpers.cs
@@ -0,0 +1,35 @@
+using Lombiq.Tests.UI.Extensions;
+using Lombiq.Tests.UI.Services;
+using Shouldly;
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Lombiq.OSOCE.Tests.UI.Helpers;
+
+public static class AssertAppLogsHelpers
+{
+ public static readonly Func AssertOsoceAppLogsAreEmptyAsync = app =>
+ app.OsoceLogsShouldBeEmptyAsync();
+
+ public static async Task OsoceLogsShouldBeEmptyAsync(
+ this IWebApplicationInstance webApplicationInstance,
+ CancellationToken cancellationToken = default)
+ {
+ var logOutput = await webApplicationInstance.GetLogOutputAsync(cancellationToken);
+
+ if (!string.IsNullOrEmpty(logOutput))
+ {
+ var messages = logOutput.SplitByNewLines().ToList();
+
+ // Temporarily filtering out irrelevant cache errors from logs.
+ var filteredLogOutput = messages.Where(message =>
+ !message.Contains("|Lombiq.TrainingDemo.Services.DemoBackgroundTask|ERROR|Expected non-error") &&
+ !message.Contains("OrchardCore.Media.Core.DefaultMediaFileStoreCacheFileProvider|ERROR|Error deleting cache folder"));
+
+ var errors = filteredLogOutput.Where(item => item.Contains("|ERROR|") || item.Contains("|FATAL|"));
+ errors.ShouldBeEmpty();
+ }
+ }
+}
diff --git a/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorChartJsTests.cs b/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorChartJsTests.cs
index f27d2a10a..ef3ba6790 100644
--- a/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorChartJsTests.cs
+++ b/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorChartJsTests.cs
@@ -1,4 +1,7 @@
+using Lombiq.ChartJs.Models;
using Lombiq.ChartJs.Tests.UI.Extensions;
+using Shouldly;
+using System.Text.Json;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
@@ -15,4 +18,26 @@ public BehaviorChartJsTests(ITestOutputHelper testOutputHelper)
[Fact]
public Task RecipeDataShouldBeDisplayedCorrectly() =>
ExecuteTestAfterSetupAsync(context => context.TestChartJsSampleBehaviorAsync());
+
+ [Fact]
+ public void DataLabelAlignmentConfigurationShouldSerializeCorrectly()
+ {
+ var data = new DataLabelAlignmentConfiguration
+ {
+ Align = DataLabelAlignment.Start,
+ Anchor = DataLabelAlignment.Center,
+ Font = new DataLabelAlignmentConfiguration.FontStyle { IsBold = true, Size = 16.5 },
+ Offset = 3.14,
+ };
+
+ var json = JsonSerializer.Serialize(data);
+ json.ShouldBe("{\"align\":\"start\",\"anchor\":\"center\",\"offset\":3.14,\"font\":{\"size\":16.5,\"weight\":\"bold\"}}");
+
+ var deserialized = JsonSerializer.Deserialize(json);
+ deserialized.Align.ShouldBe(data.Align);
+ deserialized.Anchor.ShouldBe(data.Anchor);
+ deserialized.Font.IsBold.ShouldBe(data.Font.IsBold);
+ deserialized.Font.Size.ShouldBe(data.Font.Size);
+ deserialized.Offset.ShouldBe(data.Offset);
+ }
}
diff --git a/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorEmailQuotaTests.cs b/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorEmailQuotaTests.cs
index 26fdc8def..c8f56e89b 100644
--- a/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorEmailQuotaTests.cs
+++ b/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorEmailQuotaTests.cs
@@ -1,8 +1,8 @@
using Lombiq.Hosting.Tenants.EmailQuotaManagement.Tests.UI.Extensions;
+using Lombiq.Tests.UI.Extensions;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
-
namespace Lombiq.OSOCE.Tests.UI.Tests.ModuleTests;
public class BehaviorEmailQuotaTests : UITestBase
@@ -21,8 +21,14 @@ public Task EmailQuotaShouldBlockEmailsOverLimitAndWarn() =>
[Fact]
public Task EmailQuotaShouldNotBlockEmailsWhenDifferentHostIsUsedThanOriginalFromConfig() =>
ExecuteTestAfterSetupAsync(
- context => context.TestEmailQuotaManagementBehaviorAsync(1, moduleShouldInterfere: false),
- // The default SMTP host is localhost during UI tests, we set it to 127.0.0.1 to be able to send emails,
- // but the Email Quota module shouldn't interfere.
- configuration => configuration.SetEmailQuotaManagementOptionsForUITest(1, "127.0.0.1"));
+ async context =>
+ {
+ // The default SMTP host is localhost during UI tests. We set it to 127.0.0.1 to still be able to send
+ // emails (since localhost and 127.0.0.1 is the same), but the Email Quota module shouldn't interfere,
+ // thinking it's a non-default host.
+ await context.SignInDirectlyAndGoToDashboardAsync();
+ await context.ConfigureSmtpSettingsAsync("sender@example.com", "127.0.0.1");
+ await context.TestEmailQuotaManagementBehaviorAsync(1, moduleShouldInterfere: false);
+ },
+ configuration => configuration.SetEmailQuotaManagementOptionsForUITest(1));
}
diff --git a/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorHelpfulExtensionsTests.cs b/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorHelpfulExtensionsTests.cs
index 0c16fcb98..b4532c0bc 100644
--- a/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorHelpfulExtensionsTests.cs
+++ b/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorHelpfulExtensionsTests.cs
@@ -1,7 +1,4 @@
using Lombiq.HelpfulExtensions.Tests.UI.Extensions;
-using Lombiq.Tests.UI.Services;
-using System;
-using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
@@ -25,17 +22,5 @@ public BehaviorHelpfulExtensionsTests(ITestOutputHelper testOutputHelper)
public Task FeatureCodeGeneration() => ExecuteTestAfterSetupAsync(context => context.TestFeatureCodeGenerationsAsync());
[Fact]
- public Task FeatureContentSets() =>
- ExecuteTestAfterSetupAsync(
- context => context.TestFeatureContentSetsAsync(),
- configuration => configuration.AssertBrowserLog = logEntries =>
- {
- // This is to not fail on a browser error caused by jQuery missing. Can be removed after this issue is
- // resolved and released: https://github.com/OrchardCMS/OrchardCore/issues/15181.
- var messageWithoutJqueryError = logEntries.Where(logEntry =>
- !logEntry.Message.ContainsOrdinalIgnoreCase(
- "Uncaught ReferenceError: $ is not defined"));
-
- OrchardCoreUITestExecutorConfiguration.AssertBrowserLogIsEmpty(messageWithoutJqueryError);
- });
+ public Task FeatureContentSets() => ExecuteTestAfterSetupAsync(context => context.TestFeatureContentSetsAsync());
}
diff --git a/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorJsonEditorTests.cs b/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorJsonEditorTests.cs
index 6ef2341d6..a02cf91fc 100644
--- a/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorJsonEditorTests.cs
+++ b/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorJsonEditorTests.cs
@@ -1,7 +1,4 @@
using Lombiq.JsonEditor.Tests.UI.Extensions;
-using Lombiq.Tests.UI.Services;
-using System;
-using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
@@ -17,17 +14,5 @@ public BehaviorJsonEditorTests(ITestOutputHelper testOutputHelper)
[Fact]
public Task JsonEditorShouldWorkCorrectly() =>
- ExecuteTestAfterSetupAsync(
- context =>
- context.TestJsonEditorBehaviorAsync(),
- configuration => configuration.AssertBrowserLog = logEntries =>
- {
- // This is to not fail on a browser error caused by jQuery missing. Can be removed after this issue is
- // resolved and released: https://github.com/OrchardCMS/OrchardCore/issues/15181.
- var messageWithoutJqueryError = logEntries.Where(logEntry =>
- !logEntry.Message.ContainsOrdinalIgnoreCase(
- "Uncaught ReferenceError: $ is not defined"));
-
- OrchardCoreUITestExecutorConfiguration.AssertBrowserLogIsEmpty(messageWithoutJqueryError);
- });
+ ExecuteTestAfterSetupAsync(context => context.TestJsonEditorBehaviorAsync());
}
diff --git a/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorWalkthroughsTests.cs b/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorWalkthroughsTests.cs
index 6b4ba7b94..e067cff13 100644
--- a/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorWalkthroughsTests.cs
+++ b/test/Lombiq.OSOCE.Tests.UI/Tests/ModuleTests/BehaviorWalkthroughsTests.cs
@@ -1,10 +1,4 @@
-using Lombiq.Tests.UI.Extensions;
-using Lombiq.Tests.UI.Services;
using Lombiq.Walkthroughs.Tests.UI.Extensions;
-using OpenQA.Selenium;
-using Shouldly;
-using System;
-using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
@@ -22,20 +16,7 @@ public BehaviorWalkthroughsTests(ITestOutputHelper testOutputHelper)
public Task WalkthroughsShouldWorkCorrectly() =>
ExecuteTestAsync(
context => context.RunSetupAndTestWalkthroughsBehaviorAsync(),
- // Could be removed if https://github.com/shepherd-pro/shepherd/issues/2555 is fixed.
- changeConfiguration: configuration =>
- {
- configuration.HtmlValidationConfiguration
- .WithRelativeConfigPath("NoUniqueLandmark.htmlvalidate.json");
-
- configuration.AssertBrowserLog = logEntries => logEntries.ShouldNotContain(
- logEntry => IsValidLogEntry(logEntry),
- logEntries.Where(IsValidLogEntry).ToFormattedString());
- });
-
- private static bool IsValidLogEntry(LogEntry logEntry) =>
- OrchardCoreUITestExecutorConfiguration.IsValidBrowserLogEntry(logEntry) &&
- // See https://github.com/OrchardCMS/OrchardCore/issues/15301.
- !(logEntry.Message.ContainsOrdinalIgnoreCase("/OrchardCore.Resources/Scripts/jquery.js?v=") &&
- logEntry.Message.ContainsOrdinalIgnoreCase("Uncaught"));
+ changeConfiguration: configuration => configuration
+ .HtmlValidationConfiguration
+ .WithRelativeConfigPath("NoUniqueLandmark.htmlvalidate.json"));
}
diff --git a/test/Lombiq.OSOCE.Tests.UI/Tests/ThemeTests/BehaviorBlogBaseThemeTests.cs b/test/Lombiq.OSOCE.Tests.UI/Tests/ThemeTests/BehaviorBlogBaseThemeTests.cs
index f22d4f4c7..2f12137a2 100644
--- a/test/Lombiq.OSOCE.Tests.UI/Tests/ThemeTests/BehaviorBlogBaseThemeTests.cs
+++ b/test/Lombiq.OSOCE.Tests.UI/Tests/ThemeTests/BehaviorBlogBaseThemeTests.cs
@@ -4,7 +4,6 @@
using Lombiq.Tests.UI.Services;
using OpenQA.Selenium;
using System;
-using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
@@ -70,16 +69,5 @@ await context.ClickReliablyOnAsync(By.CssSelector(
// Disable HTML validation, because we have no control over the HTML in the Blog and the content added
// by the Blog recipe.
configuration.HtmlValidationConfiguration.RunHtmlValidationAssertionOnAllPageChanges = false;
-
- // This is to not fail on a browser error caused by jQuery missing. Can be removed after this issue is
- // resolved and released: https://github.com/OrchardCMS/OrchardCore/issues/15181.
- configuration.AssertBrowserLog = logEntries =>
- {
- var messageWithoutJqueryError = logEntries.Where(logEntry =>
- !logEntry.Message.ContainsOrdinalIgnoreCase(
- "Uncaught ReferenceError: $ is not defined"));
-
- OrchardCoreUITestExecutorConfiguration.AssertBrowserLogIsEmpty(messageWithoutJqueryError);
- };
});
}
diff --git a/test/Lombiq.OSOCE.Tests.UI/Tests/VisualVerificationTests/VisualVerificationTests_VerifyHomePageAndLayout_By_TagName_-body-1920x1080_Unix.png b/test/Lombiq.OSOCE.Tests.UI/Tests/VisualVerificationTests/VisualVerificationTests_VerifyHomePageAndLayout_By_TagName_-body-1920x1080_Unix.png
index 70eda7560..edfd4fe81 100644
Binary files a/test/Lombiq.OSOCE.Tests.UI/Tests/VisualVerificationTests/VisualVerificationTests_VerifyHomePageAndLayout_By_TagName_-body-1920x1080_Unix.png and b/test/Lombiq.OSOCE.Tests.UI/Tests/VisualVerificationTests/VisualVerificationTests_VerifyHomePageAndLayout_By_TagName_-body-1920x1080_Unix.png differ
diff --git a/test/Lombiq.OSOCE.Tests.UI/Tests/VisualVerificationTests/VisualVerificationTests_VerifyHomePageAndLayout_By_TagName_-body-1920x1080_Win32NT.png b/test/Lombiq.OSOCE.Tests.UI/Tests/VisualVerificationTests/VisualVerificationTests_VerifyHomePageAndLayout_By_TagName_-body-1920x1080_Win32NT.png
index 6d5fca8fc..95f722a88 100644
Binary files a/test/Lombiq.OSOCE.Tests.UI/Tests/VisualVerificationTests/VisualVerificationTests_VerifyHomePageAndLayout_By_TagName_-body-1920x1080_Win32NT.png and b/test/Lombiq.OSOCE.Tests.UI/Tests/VisualVerificationTests/VisualVerificationTests_VerifyHomePageAndLayout_By_TagName_-body-1920x1080_Win32NT.png differ
diff --git a/test/Lombiq.Tests b/test/Lombiq.Tests
index 1194c953d..7d5bca8d4 160000
--- a/test/Lombiq.Tests
+++ b/test/Lombiq.Tests
@@ -1 +1 @@
-Subproject commit 1194c953d85a4c893cd9b54b80c17f73e3169a57
+Subproject commit 7d5bca8d4d8a8758bf43786d5bc4511b167fe036
diff --git a/test/Lombiq.UITestingToolbox b/test/Lombiq.UITestingToolbox
index 7a91a08b6..a89265a54 160000
--- a/test/Lombiq.UITestingToolbox
+++ b/test/Lombiq.UITestingToolbox
@@ -1 +1 @@
-Subproject commit 7a91a08b67409be1ae3692fb631987de3ec8b623
+Subproject commit a89265a546c64646ecc1b1fd707d020e19c82581
diff --git a/tools/Lombiq.GitHub.Actions b/tools/Lombiq.GitHub.Actions
index 78dad9077..1b294d618 160000
--- a/tools/Lombiq.GitHub.Actions
+++ b/tools/Lombiq.GitHub.Actions
@@ -1 +1 @@
-Subproject commit 78dad90770a71973fa6a06158d1bd5ae932ee791
+Subproject commit 1b294d618a8d3c8307fa40e871b8f07be0435c91