Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<Project>

<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<!-- Some packages are referenced with floating versions (e.g. RtfPipe 2.0.*, MsgReader 6.0.*,
the locally built MudBlazor.Extensions *-* prerelease). Allow them centrally. -->
<CentralPackageFloatingVersionsEnabled>true</CentralPackageFloatingVersionsEnabled>
</PropertyGroup>

<ItemGroup>
<!-- MudBlazor / UI -->
<PackageVersion Include="MudBlazor" Version="9.5.0" />
<PackageVersion Include="MudBlazor.Markdown" Version="9.0.0" />
<PackageVersion Include="AuralizeBlazor" Version="3.0.4" />
<PackageVersion Include="Bromix.MudBlazor.MaterialDesignIcons" Version="7.4.47.56" />
<PackageVersion Include="BlazorMonaco" Version="3.4.0" />
<PackageVersion Include="BlazorJS" Version="2.2.0" />
<PackageVersion Include="Blazored.LocalStorage" Version="4.5.0" />

<!-- Nextended -->
<PackageVersion Include="Nextended.Blazor" Version="10.1.9" />
<PackageVersion Include="Nextended.Core" Version="10.1.9" />
<PackageVersion Include="Nextended.CodeGen" Version="10.1.9" />

<!-- Microsoft.AspNetCore / Extensions -->
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="10.0.9" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.9" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.9" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="10.0.9" />
<PackageVersion Include="Microsoft.AspNetCore.WebUtilities" Version="10.0.9" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.9" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.9" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.Extensions" Version="6.0.36" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.9" />
<PackageVersion Include="Microsoft.Extensions.Localization" Version="10.0.9" />
<PackageVersion Include="System.Net.Http.Json" Version="10.0.9" />
<PackageVersion Include="System.Runtime.Loader" Version="4.3.0" />

<!-- Roslyn (for the Try compiler) -->
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.3.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="5.3.0" />

<!-- Localization -->
<PackageVersion Include="AKSoftware.Localization.MultiLanguages.Blazor" Version="6.1.0" />

<!-- Validation / utilities -->
<PackageVersion Include="FluentValidation" Version="12.1.1" />
<PackageVersion Include="OneOf" Version="3.0.271" />
<PackageVersion Include="NUglify" Version="1.21.17" />
<PackageVersion Include="BlazorParameterCastingMagic" Version="1.2.25121215" />

<!-- File / document handling -->
<PackageVersion Include="ExcelDataReader" Version="3.8.0" />
<PackageVersion Include="ExcelDataReader.DataSet" Version="3.8.0" />
<PackageVersion Include="SharpCompress" Version="0.49.1" />
<!-- ImageSharp pinned to 3.x: v4 requires a commercial Six Labors license (build-time license check) -->
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.12" />
<PackageVersion Include="MetadataExtractor" Version="2.9.3" />
<PackageVersion Include="Gotho.BlazorPdf" Version="2.2.0" />
<PackageVersion Include="Gotho.BlazorPdf.MudBlazor" Version="2.2.0" />
<PackageVersion Include="RtfPipe" Version="2.0.*" />
<PackageVersion Include="MsgReader" Version="6.0.*" />

<!-- Azure (Try server) -->
<PackageVersion Include="Azure.Identity" Version="1.21.0" />
<PackageVersion Include="Azure.Storage.Blobs" Version="12.29.0" />

<!-- Test stack -->
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.6.0" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="bunit" Version="2.7.2" />
<PackageVersion Include="coverlet.collector" Version="10.0.1" />
<PackageVersion Include="FluentAssertions" Version="8.10.0" />
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="Microsoft.Playwright" Version="1.60.0" />
<PackageVersion Include="NUnit" Version="4.6.1" />
<PackageVersion Include="NUnit3TestAdapter" Version="6.2.0" />

<!-- CodeGator adapter (optional project) -->
<PackageVersion Include="CG.Blazor.Forms._MudBlazor" Version="*" />

<!-- Locally built package, consumed by samples in Release config -->
<PackageVersion Include="MudBlazor.Extensions" Version="*-*" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
Expand Down Expand Up @@ -29,8 +29,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Condition="'$(Configuration)' == 'Release'" Include="MudBlazor.Extensions" Version="*-*" />
<PackageReference Include="CG.Blazor.Forms._MudBlazor" Version="*" />
<PackageReference Condition="'$(Configuration)' == 'Release'" Include="MudBlazor.Extensions" />
<PackageReference Include="CG.Blazor.Forms._MudBlazor" />
</ItemGroup>

<ItemGroup Condition="'$(Configuration)' != 'Release'">
Expand Down
22 changes: 11 additions & 11 deletions MudBlazor.Extensions.Tests/MudBlazor.Extensions.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
Expand All @@ -10,20 +10,20 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.3" />
<PackageReference Include="FluentAssertions" Version="8.8.0" />
<PackageReference Include="Microsoft.Playwright" Version="1.58.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Condition="'$(Configuration)' == 'Release'" Include="MudBlazor.Extensions" Version="*-*" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.Playwright" />
<PackageReference Include="Moq" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Condition="'$(Configuration)' == 'Release'" Include="MudBlazor.Extensions" />

<PackageReference Include="bunit" Version="2.6.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<PackageReference Include="bunit" />
<PackageReference Include="xunit.runner.visualstudio">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="8.0.0">
<PackageReference Include="coverlet.collector">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
18 changes: 12 additions & 6 deletions MudBlazor.Extensions.Tests/UITests/PlaywrightFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,20 @@ public async Task DisposeAsync()
/// </summary>
private static void InstallPlaywright()
{
var exitCode = Microsoft.Playwright.Program.Main(
new[] { "install-deps" });
if (exitCode != 0)
// "install-deps" installs the OS-level libraries the browsers need. It is only meaningful
// on Linux (and there usually requires root). On Windows/macOS it is a no-op that can even
// return a non-zero exit code, so treat it as best-effort and never fail the test run on it.
try
{
throw new Exception(
$"Playwright exited with code {exitCode} on install-deps");
Microsoft.Playwright.Program.Main(new[] { "install-deps" });
}
exitCode = Microsoft.Playwright.Program.Main(new[] { "install" });
catch
{
// ignore – browser binaries are installed below; OS deps are environment specific.
}

// "install" downloads the actual browser binaries. This is what the tests really need.
var exitCode = Microsoft.Playwright.Program.Main(new[] { "install" });
if (exitCode != 0)
{
throw new Exception(
Expand Down
33 changes: 18 additions & 15 deletions MudBlazor.Extensions.Tests/UITests/Tests/MainAppTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ public async Task ApiAvailable()
{
await Test(async page =>
{
await page.Locator("li.mud-treeview-item").Filter(new() { HasText = "API" }).ClickAsync();
// The tree renders nested <li> nodes, so a plain "contains API" filter matches the
// leaf plus all of its ancestor nodes (strict-mode violation). Anchor on the exact
// node text so only the actual "API" leaf is clicked.
await page.Locator("li.mud-treeview-item")
.Filter(new() { HasTextRegex = new System.Text.RegularExpressions.Regex(@"^\s*API\s*$") })
.ClickAsync();
await page.WaitForURLAsync($"{Url}/api");
await page.WaitForRequestFinishedAsync();
await Task.Delay(2000);
Expand All @@ -42,24 +47,22 @@ public async Task About()
{
await Test(async page =>
{
var version = MudExResource.MudExVersion().ToString();
// "About / Info" moved into the overflow (⋮) menu in the app bar. Open the menu
// (last button in the banner) and click the "Info" item to open the About dialog.
await page.GetByRole(AriaRole.Banner).GetByRole(AriaRole.Button).Last.ClickAsync();
await page.Locator(".mud-menu-item").Filter(new() { HasText = "Info" }).First.ClickAsync();

await page.GetByRole(AriaRole.Banner).GetByRole(AriaRole.Button).Nth(2).ClickAsync();
var dialog = page.Locator(".mud-dialog");
await dialog.WaitForAsync();

var head = await page.GetByRole(AriaRole.Heading, new() { Name = $"MudBlazor.Extensions {version}" }).TextContentAsync();

head.Should().Contain($"MudBlazor.Extensions {version}");
var head = await dialog.TextContentAsync();
head.Should().Contain("MudBlazor.Extensions");

var dialog = page.Locator(".mud-dialog");

await dialog.WaitForAsync();

// The About dialog slides in, so its close button can sit outside the viewport and is
// not reliably clickable via a real mouse click. Dispatch the click event directly –
// this still verifies the close button exists and is wired up.
var closeBtn = dialog.Locator("button.mud-button-close");

await closeBtn.ScrollIntoViewIfNeededAsync();

await closeBtn.ClickAsync();

await closeBtn.DispatchEventAsync("click");
});

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,42 @@ public void WithoutMinLength_ThumbsShouldMoveFreelyWithinSizeRange()

// Should be able to set start all the way to end
setStartMethod?.Invoke(instance, new object[] { 8, true });

// Assert
Assert.Equal(8, instance.Value.Start);
Assert.Equal(8, instance.Value.End);
}

/// <summary>
/// Regression: AutoZoomRangeMultiplier must not crash when the derived bounds exceed the natural T-domain
/// (e.g. TimeOnly, which is limited to 0..23:59:59). The auto-range should be clamped to the largest valid extent.
/// </summary>
[Fact]
public void AutoZoomRangeMultiplier_ShouldClamp_ForTimeOnly()
{
// Arrange
using var context = new TestContext();
context.Services.AddMudServicesWithExtensions();
context.JSInterop.Mode = JSRuntimeMode.Loose;

// 8h..18h with multiplier=3 would normally extend to -7h..33h, both invalid for TimeOnly.
var sizeRange = new MudExRange<TimeOnly>(new TimeOnly(8, 0), new TimeOnly(18, 0));
var initial = new MudExRange<TimeOnly>(new TimeOnly(9, 0), new TimeOnly(17, 0));

// Act – render must not throw.
var cut = context.Render<MudExRangeSlider<TimeOnly>>(parameters => parameters
.Add(p => p.SizeRange, sizeRange)
.Add(p => p.Value, initial)
.Add(p => p.EnableMouseWheelZoom, true)
.Add(p => p.AutoZoomRangeMultiplier, 3.0)
);

// Assert – auto-derived range got clamped to the TimeOnly domain.
var effective = cut.Instance.EffectiveAbsoluteSizeRange;
Assert.NotNull(effective);
Assert.True(effective!.Start <= sizeRange.Start, "auto-zoom left bound should be at or before SizeRange.Start");
Assert.True(effective.End >= sizeRange.End, "auto-zoom right bound should be at or after SizeRange.End");
Assert.True(effective.Start >= TimeOnly.MinValue, "left bound must be a valid TimeOnly");
Assert.True(effective.End <= TimeOnly.MaxValue, "right bound must be a valid TimeOnly");
}
}
Loading
Loading