feat: implement Sprint 4 Blazor theme system (#81–#86) - #95
Merged
9 commits merged intoApr 23, 2026
Merged
Conversation
Contributor
🏗️ PR Added to Squad Triage QueueThis PR has been labeled with Next steps:
|
Contributor
Test Results Summary174 tests +168 172 ✅ +166 3m 9s ⏱️ + 3m 9s For more details on these failures, see this check. Results for commit cf44636. ± Comparison against base commit 0a0263d. ♻️ This comment has been updated with latest results. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #95 +/- ##
==========================================
+ Coverage 0.00% 68.77% +68.77%
==========================================
Files 49 55 +6
Lines 832 852 +20
Branches 118 120 +2
==========================================
+ Hits 0 586 +586
+ Misses 714 244 -470
+ Partials 118 22 -96
🚀 New features to boost your workflow:
|
Add bUnit test scaffolding for Sprint 4 Theme components ahead of production code (Issues #82 and #83). Tests cover: ThemeProviderTests (9 tests): - Renders child content and renders without error - Calls themeManager.getColor / getBrightness on AfterFirstRender - Loads color and brightness from JS and exposes as CurrentColor/CurrentBrightness - SetColor calls themeManager.setColor with new value - SetBrightness calls themeManager.setBrightness and updates CurrentBrightness - Error resilience when JS throws (swallows exception, uses defaults) ThemeSelectorTests (~20 tests, 4 classes): - ThemeSelectorTests: renders without error, contains both sub-components - ThemeBrightnessToggleTests: renders, sun/moon icons, click toggles brightness, a11y label - ThemeColorDropdownTests: renders, 4 color options, current color selected, color change propagates, Theory for all colors, a11y label - ThemeProviderWithSelectorIntegrationTests: cascaded color/brightness, dropdown change triggers setColor JS, toggle click triggers setBrightness JS NOTE: Build fails with CS0234 until Legolas merges #82 and #83. This branch depends on those PRs to compile and run. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Issue #81: CSS restructuring — move to src/Web/Styles/input.css + themes.css with OKLCH colour palettes and updated package.json scripts - Issue #82: ThemeProvider component with cascading values (typed + named) and JS-backed SetColor/SetBrightness using optimistic state update - Issue #83: ThemeSelector, ThemeColorDropdownComponent, and ThemeBrightnessToggleComponent with EventCallback-based API - Issue #84: App.razor wraps Routes in ThemeProvider; NavMenu fully refactored to use ThemeSelector, removing all inline theme code, IDisposable, and three injections; _Imports.razor updated - Issue #85: Fixed scaffold errors in ThemeSelectorTests.cs; updated NavMenuTests 4th test to render ThemeProvider wrapping NavMenu - Issue #86: ThemeLayerTests.cs architecture tests for theme namespace Working as Legolas (Frontend Developer) Closes #81, #82, #83, #84, #85, #86 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mpaulosky
force-pushed
the
squad/85-bunit-theme-tests
branch
from
April 22, 2026 02:11
d891916 to
e7d1842
Compare
Tests were previously split into Domain.Tests, Web.Tests, Web.Tests.Bunit, Web.Tests.Integration, and AppHost.Tests. These directories no longer exist. Old → New mappings: tests/Domain.Tests → tests/Unit.Tests/Unit.Tests.csproj tests/Web.Tests → tests/Unit.Tests/Unit.Tests.csproj tests/Web.Tests.Bunit → tests/Unit.Tests/Unit.Tests.csproj tests/Web.Tests.Integration → tests/Integration.Tests/Integration.Tests.csproj tests/AppHost.Tests → tests/E2E.Tests/E2E.Tests.csproj Files changed: - .github/workflows/squad-test.yml - .github/workflows/squad-release.yml - .github/workflows/squad-insider-release.yml Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…und_ReturnsFailResult Mixed concrete 'id' value with Arg.Any<CancellationToken>() in GetByIdAsync setup. NSubstitute 5.x can throw RedundantArgumentMatcherException when concrete values are mixed with arg matchers due to the thread-local pending specification queue becoming misaligned across test ordering. Fix: wrap all arguments in explicit matchers using Arg.Is<Guid>() so NSubstitute unambiguously consumes the full specification. Line 63: Arg.Is<Guid>(g => g == id) replaces bare id literal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The E2E.Tests project uses Aspire.Hosting.Testing with HttpClient for integration tests — it does not use Microsoft.Playwright. The 'playwright.ps1 install' step referenced a file that was never generated by the build, causing CI to fail unconditionally. Removed the 'Install Playwright browsers' step entirely. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…gle test-unit job Both jobs were running the exact same test suite (tests/Unit.Tests/Unit.Tests.csproj) after the consolidation of Domain.Tests and Web.Tests. This caused duplicate test reporting and was confusing. Consolidate into a single 'test-unit' job and update job dependencies in coverage and report jobs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The test-bunit job was running the same test suite as test-unit (tests/Unit.Tests/Unit.Tests.csproj), creating duplicate test reports and unnecessary CI time. Remove the separate test-bunit job and consolidate all unit tests into the test-unit job. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The ThemeProvider should render in static SSR context to avoid JS interop issues, while Routes with interactive components are marked with @rendermode="InteractiveServer". This allows the theme to initialize properly in SSR context before interactive rendering begins. Resolves AppHost.Tests 500 error in E2E tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The E2E tests timeout in CI after 100 seconds when starting the Aspire host with MongoDB. Increase timeout to 300 seconds to allow sufficient time for the application to start, especially in resource-constrained CI environments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Working as Legolas (Frontend Developer)
Implements the complete Sprint 4 theme system across all 6 issues.
Closes #81, Closes #82, Closes #83, Closes #84, Closes #85, Closes #86
Changes
#81 — CSS Restructuring
src/Web/Styles/input.css(Tailwind v4@import,@source,@theme inline)src/Web/Styles/themes.css(:root.color-blue/red/green/yellow)package.jsontw:buildandtw:watchto use new input path#82 — ThemeProvider Component
ThemeProvider.razor— three nestedCascadingValuewrappers: typedThemeProvider, named"CurrentColor", named"CurrentBrightness"ThemeProvider.razor.cs—IJSRuntime,SetColor/SetBrightnessusing optimistic state update (property +StateHasChanged()beforeawait) for correct bUnit testability#83 — ThemeSelector Sub-Components
ThemeColorDropdownComponent.razor—[CascadingParameter(Name="CurrentColor")], select with 4 options,aria-label="Colour theme"ThemeBrightnessToggleComponent.razor—[CascadingParameter(Name="CurrentBrightness")], toggle button with moon/sun SVG, interpolatedaria-labelThemeSelector.razor—[CascadingParameter] ThemeProvider? Provider, wires EventCallbacks to null-safe Provider calls#84 — App.razor / NavMenu Integration
App.razor— wraps<Routes />with<ThemeProvider @rendermode="InteractiveServer">NavMenu.razor— removed 3@injectdirectives,@implements IDisposable, 30+ lines of inline theme code; replaced with<ThemeSelector />_Imports.razor— added@using MyBlog.Web.Components.Theme#85 — bUnit Tests
ThemeSelectorTests.cs(positionalbecausearg)NavMenuTests4th test: rendersThemeProviderwrappingNavMenu, usesWaitForAssertionfor async JS-based theme load and set calls#86 — Architecture Tests
ThemeLayerTests.cs— 2 tests verifying Theme namespace isolation in the Web assemblyTest Results