Skip to content

TechnologyEnhancedLearning/TELBlazor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TELBlazor

TEL Blazor Component Library Package

This ReadMe

This readme is the repo readme, it is also used as the package readme as this is the solution for making the TELBlazor.Components package. There is also a cicd readme in the workflow folder.

The MVCBlazor repo readme has exploration of various of the choices and alternatives to what is implemented here, which may be useful along with the other blazor repos, when developing for this repo.

There are specific readmes within the solution for topics like components and cicd

Purpose

Progressive Blazor components, intended for a Hosted Blazor Webassembly architecture with prerendering. They provide clientside functionality with the ability to produce static prerendered html. The prerendered html is written to have server-side interactvity via form posts and fallback mechanism to support browsers without javascript enabled.

Links

Bottom file see tree diagram of solution

Easy viewing of TELBlazor Repo ReadMe (best with Markdown Reader Chrome extension)

Last Published Package

TELBlazor

TELBlazor Production Showcase

TELBlazor Dev Showcase

View Packaged Dev Showcase Code

View Packaged Showcase Code

Code Report Page

NHSE TEL Frontend

Set Up

Prerequisites

  • Visual Studio 2022 (Community or higher)
  • .NET 8 SDK version 8.0.407 or later (see global.json file in the solution)
  • Node.js 18+ and npm
  • Git configured with your credentials
  • PowerShell 5.1+

⚠️ Important: All commands in this guide require PowerShell running as Administrator

Quick Setup ⚡

  • Get the repo: open powershell as admin, cd to where you keep your repos. Run git clone https://github.com/TechnologyEnhancedLearning/TELBlazor.git
  • Create local gitignored configuration files from templates: open the project in Visual Studio
    • search template
      • create a copy of each template removing the '.template' post fix
  • Create GitHub Personal Access Token (PAT) for consuming TEL git hosted nuget packages :
    • go to your GitHub profile tokens section
    • SelectPersonal access tokensTokens classicGenerate new token (classic)
      • give it a Note, e.g. 'TEL Package Access' (we will be storing it as the env var 'TEL_GIT_PACKAGES_TOKEN')
      • set the expiration date to something reasonable (e.g. 90 days)
      • select the scopes you need for the token
        • as a minimum select read:packages and you may wish to increase the expiration date.
        • if you want to publish packages you will need write:packages and delete:packages but this is not recommended for development
      • generate token
      • copy the token immediately (it will not be accessible again)
    • Set system wide environment variables (useful for future projects too):
      • open Start, type 'Environment Variables', and select Edit the system environment variables
      • in the System Properties window, select Environment Variables
      • under System variables, select New
      • enter the variable names and variable values as follows:
        • GITHUB_USERNAME / [Your GitHub username]
        • TEL_GIT_PACKAGES_TOKEN / [The copied token]
      • then select OK
      • select OK again to close all dialogs.
  • Restore Nuget, Npm, Tooling, playwright and build:
    • run a new admin powershell terminal in the TELBlazor repo root
    • run the following commands
     	#1. Restore
     	dotnet clean
     	dotnet restore
     	
     	#2. Nuget TEL Git Feed setups
     	dotnet nuget add source "https://nuget.pkg.github.com/TechnologyEnhancedLearning/index.json" `
     	  --name "github" `
     	  --username $env:GITHUB_USERNAME `
     	  --password $env:TEL_GIT_PACKAGES_TOKEN `
     	  --store-password-in-clear-text
    
     	# 3. Restore .NET CLI tools (Playwright, report manager for code coverage)
     	Write-Output "Restore Tools"
     	dotnet tool restore
    
     	# 4. Install Node dependencies (gulp, playwright, frontend libs)
     	Write-Output "Restore Node"
     	npm install
     	
     	# 5. Build solution or run other commands as needed
     	Write-Output "Build solution without build package, using project references instead of local package or remote package"
     	dotnet build
     	
     	# 6. Setup playwright
     	Write-Output "Playwright setup"
     	& ".\TELBlazor.Components.ShowCase.E2ETests\bin\Debug\net8.0\playwright.ps1" install
    

The project should now work. See other sections for what projects to run, and configuration.

⚠️ read the contribution section before creating a branch or commits ⚠️

Getting Started with the Project following Setup

It is recommended you check setup by reading this section and making sure packages can be created and consumed and all tests pass.

Contributing to the project

Configuring the project

File Description Variable Purpose
runsettings configures playwrights headless, tracing make tests more detailed or visible or run faster
nuget.config overwritten in cicd so feel free to change it Remote and local telblazor nuget sources Comment in/out depending which source you need
Package.Settings.Props Used by CICD can receive environment variables or msbuild parameters NugetPackagesOutputPath UseTELBlazorComponentsProjectReference TELBlazorPackageVersion DisablePackageGeneration For CICD
Package.Settings.Props.local overwrite package.settings.props locally NugetPackagesOutputPath Where you want your package creating
Package.Settings.Props.local overwrite package.settings.props locally UseTELBlazorComponentsProjectReference For quick development use the project reference instead of a package
Package.Settings.Props.local overwrite package.settings.props locally TELBlazorPackageVersion local package version you're creating or consuming
Package.Settings.Props.local overwrite package.settings.props locally DisablePackageGeneration Stops package creation on build.
appsettings Serilog configuration

Nb. It is recommended not to build the solution with package generation enabled and project reference disabled at the same time. Nb. Creating your package outside of the project can be convenient for other local solutions consuming it.

Running the projects

  • depending on whether your consuming a package or using a project reference set package.settings.props.local UseTELBlazorComponentsProjectReference to what you want
  • run wasmserverhost to see the showcase as blazor wasm prerendered
  • run wasmstaticclient to see pure wasm site

Building the package

  • to build a package
    • nuget config
      • ensure the feed is still set to local<add key="TELBlazorPackageSource" value="%LOCAL_PACKAGES_PATH%" />
    • package.settings.props.local to create package
      • NugetPackagesOutputPath -> 'LOCAL_PACKAGES_PATH'
      • UseTELBlazorComponentsProjectReference -> 'true'
      • TELBlazorPackageVersion -> '9.9.9-local' or something higher than you have
      • DisablePackageGeneration -> 'false'
    • delete .lock files
    • build solution
    • change package.settings.props.local to consume package
      • UseTELBlazorComponentsProjectReference -> 'false'
      • DisablePackageGeneration -> 'true'
    • build solution

Testing the project

  • you can use the test runner
  • runsettings allows configuration of headless and tracing
  • packagesettings.props sets thresholds
  • running at solution level ./run-tests-and-report-with-env-values.ps1 (see in the file for specific arguments you may want to set)
    • will produce a test coverage site [your repo folder]/TELBlazor/CoverageReport/index.html
    • then look at CoverageReport in solution root and you can bookmark index.html to see your coverage
    • E2E project has a Reports folder for tracings
  • Similarly run-tests-and-report-using-local-props.ps1 runs just using your local props file
  • appsettings.Development can be set in the E2E Host to log to the Logs folder at project route, see template

Tips

  • If you don't want to wait for the pipeline to fail your commit names and for pushes to accidently expose your secrets: you may want to add
    • gitguardian from confluence docs (follow it to the letter) gitguardian global setup instructions

    • and add a pre-commit and push hook (you need both as you cannot lint what hasn't yet been commit) you can add these to your git templates if you want them for every repo, or just to this repos pre- push- commits, or you can be lazy and add them into the gitguardian hook

    • you will need git commitlint globally (angular because it goes with the versioning tool for repo versioning)

       	npm install -g @commitlint/cli @commitlint/config-angular
      
    • You can put into your pre-push, pre-commit hook, commit-ms, or into the gitguardian hooks some logic like the below.

     		#### --- Commitlint Logic (force local config) ---
     		REPO_ROOT=$(git rev-parse --show-toplevel)
     		CONFIG_PATH="$REPO_ROOT/.commitlintrc.json"
     		echo "COMMIT_MSG_FILE is one msg behind it is only set to the commit your trying to commit after the commit succeeds so this script is one behind"
     		echo "so would work best in prepush template"
     		echo "To fix squash out the commit following renaming and renaming commit_editmsg and if pushed to remote git push --force"
     		COMMIT_MSG_FILE="$REPO_ROOT/.git/COMMIT_EDITMSG"
    
     		# Check if the local .commitlintrc.json exists in the repository root
     		if [ -f "$CONFIG_PATH" ]; then
    
     			echo "✅ Local .commitlintrc.json found at: $CONFIG_PATH. Running commitlint..."
     			echo "⚠️ if commit lint fails in precommit its actually reading previous commit name you need to reset or squash make a new commit and change .git/COMMIT_EDITMSG to something that would pass. ⚠️"
    
     			if command -v npx &> /dev/null; then
     			
     					cd "$REPO_ROOT" || exit 1
    
     					# Debug: Print the commit message file content
     					if [ -f "$COMMIT_MSG_FILE" ]; then
     						echo "Commit message content:"
     						cat "$COMMIT_MSG_FILE"
     					else
     						echo "❌ Commit message file not found!"
     						exit 1
     					fi
     					
     					
     					# Run commitlint, explicitly pointing to the local config and providing the commit message via stdin
     					OUTPUT1=$(npx.cmd --no -- commitlint --config=".commitlintrc.json" --edit="$COMMIT_MSG_FILE" 2>&1)
     					
     					EXIT_CODE1=$?
     					# echo "!!!!!!!!!!! OUTPUT1"
     					# echo "$OUTPUT1"
     					
     					
     					# OUTPUT2=$(npx.cmd --no -- commitlint --config=".commitlintrc.json" --from=origin/master --to=HEAD 2>&1)
     					
     					# EXIT_CODE2=$?
     					# echo "!!!!!!!!!!! OUTPUT2"
     					# echo "$OUTPUT2"
     					
     					# OUTPUT3=$(npx.cmd --no -- commitlint --config=".commitlintrc.json"  --from-last-tag 2>&1)
     					
     					
     					# EXIT_CODE3=$?
     					# echo "!!!!!!!!!!! OUTPUT3"
     					# echo "$OUTPUT3"
     					
    
    
     				#if [ "$EXIT_CODE1" -ne 0 ] || [ "$EXIT_CODE2" -ne 0 ] || [ "$EXIT_CODE3" -ne 0 ];  then
     				if [ "$EXIT_CODE1" -ne 0 ];  then
     					echo "❌ Commitlint failed:"
     					
     					echo "$OUTPUT1"
     					exit 1
     				else
     					echo "✅ Commitlint passed!"
     				fi
     			else
     				echo "⚠️ npx not found. Please ensure Node.js and npm are installed to use commitlint."
     				# Optionally fail here
     				# exit 1
     			fi
     		else
     			echo "ℹ️ No local .commitlintrc.json found in $REPO_ROOT. Skipping commitlint."
     		fi
     	``` 
    
    

Troubleshooting

Package build errors

  • delete local TELBlazor.Components packages
  • check TELBlazorPackageVersion has been incremented
  • delete .lock files
  • clean the solution
  • check environment values in props and nuget.config
  • restore nuget packages
  • restore the solution
  • if still not working delete bin and obj
  • if still not working, restart Visual Studio
  • if there are still issues its easier to problem solve by using a random very high TELBlazor.Components package version number and ensuring it fails and says it found the source but not the version

Git commit names

  • git commit names can be caught locally
  • if they are not
    • fetch, pull and squash before the change and then git push origin <your_branch_name> --force

How to consume TELBlazor.Components

  1. select a production version of the package Package list for TELBlazor.Component on git
  2. set up CSS references and dependency injection using lean host examples WasmServerHost, WasmServerHost.Client and WasmStaticClient from the repo and ShowCase project for how to include the package.
  3. you will need a copy of nhsuk.css and a reference see gulp in the previously mentioned projects
  4. see setup notes for instructions on getting a git nuget token for consuming the package.

Solution and Pipeline

Features of CICD

  • there is a readme in the CICD
  • a DevShowCase site is created using a DevPackage and the same in production
    • the dev pipeline also publishes a coverage report

Solution Detail

Architecture

Project Structures used

  • Repo TELBlazor

  • TELBlazor.Components

    • this is a blazor component library
  • TELBlazor.Components.UnitTests

    • Bunit template from bunit site, configured to use Xunit
  • TELBlazor.Components.ShowCase.E2ETests

    • NUnit Playwright Test project
  • TELBlazor.Components.ShowCase.Shared

    • this is a set of example pages to showcase the blazor component and to enable testing with E2E
  • TELBlazor.Components.ShowCase.E2ETests.WasmServerHost

    • Wasm host
  • TELBlazor.Components.ShowCase.E2ETests.WasmServerHost.Client

    • Wasm hosted
  • TELBlazor.Components.ShowCase.WasmStaticClient

    • Wasm standalone

Logging

  • For more detailed dependency injected logging see MVCBlazor project

Notes

Stuff you don't need to know (but may be useful for a specific issue on searching the readme)

  • it is not render auto per components because the intention is to be used in MVC views.
  • Xunit is used with Bunit and Nunit with playwright, either could be changed so that they are using the same and this could be done in future as the libraries improve but currently each is being used with the recommend tool it is designed for though both support the others tool.
  • not using data-testid="TELButton" because we should use aria selectors. We may change this later (first rule of aria dont use aria).
    • e.g. data-attribute-telblazorcomponentname="TelBlazorButton"
  • not using guid id as i have elsewhere either [Parameter] public string ElementId { get; set; } = $"tel-button-{Guid.NewGuid():N}";
  • various things have been cut from mvcblazor so it is worth returning to for potential solutions if developing this solution MVCBlazor repo

Project Structure and Comments

Viewed best raw ReadMe see chrome

Description File Structure
┣ TELBlazor
Test coverage from cicd or .ps1     ┣ AllTestResults
Convenient in solution location     ┣ CICDPackageLocation
Test report site from cicd or .ps1 viewably locally or Dev Report     ┣ CoverageReport
gh-pages site publish folder     ┣ docs
Sets centralised solution a report thresholds     ┣ Directory.Build.props,
Centralised nuget packages     ┣ Directory.Packages.props
CICD setting .net version     ┣ global.json
Uses environment variables to set packed package location locally or remote     ┣ nuget.config
Centralised npm packages used with gulp and for testing     ┣ package.json
Linting config for branch and commit names     ┣ .releaserc.json, .commitlintrc.json
Useful for running tests and generating test report locally     ┣ run-tests-and-report-with-env-values.ps1
Env Setup     ┣ PackageSettings.props
Env Setup, testing, package or project reference     ┣ PackageSettings.props.local
The package create on build     ┣ TELBlazor.Components
All using in imports so can add components by assembly             ┣ _Imports.razor
            ┣ Components
Standard components made to TEL and NoJS requirements                     ┣ BaseComponents
                            ┣ TELButton.razor
Only to support main component TELButton                             ┗ TELButtonSubComponent.razor
Useful components for development                     ┗ TestComponents
            ┣ Core
                    ┣ Compliance
Create a contract of accessibility                             ┗ IAccessibleComponent.cs
                    ┣ Configuration
                            ┣ ITELBlazorBaseComponentConfiguration.cs
Logging, NoJS bool                             ┗ TELBlazorBaseComponentConfiguration.cs
                    ┣ DI
                    ┣ Enums
Enum of css styles for testing and setting component                             ┗ TELButtonStyle.cs
                    ┣ Services
                            ┗ HelperServices
                                    ┗ ILogLevelSwitcherService.cs
Custom component base with configuration injected                     ┗ TELComponentBase.cs
            ┗ TELBlazorPackageVersion
                    ┣ TELBlazorPackageVersionInformation.razor
Programmatically generate via gulp csproj package versions                     ┗ VersionInfo.cs
    ┣ TELBlazor.Components.ShowCase.E2ETests
Enables run blazor pages in E2E             ┣ BlazeWright
                    ┣ BlazorApplicationFactory.cs
                    ┣ BlazorPageExtensions.cs
                    ┗ BlazorPageTest.cs
            ┣ Helpers
Enables using attributes to run same tests with different viewports and browsers                     ┣ BrowserHelper.cs
                    ┗ ViewportHelper.cs
            ┣ Pages
Structure to mirror ShowCase                     ┣ BaseComponentPages
Check NoJs, in view, functionality                             ┗ TELButtonPageTests.cs
                    ┣ ComponentPages
                    ┗ TestComponentPages
            ┣ Reports
            ┣ SnapShots
            ┗ TestDoubles
Serverside so can have prerender behaviour for nojs lean host     ┣ TELBlazor.Components.ShowCase.E2ETests.WasmServerHost
            ┣ TELBlazor.Components.ShowCase.E2ETests.WasmServerHost
                    ┣ _Imports.razor
                    ┣ App.razor
                    ┗ Program.cs
Clientside for the host             ┗ TELBlazor.Components.ShowCase.E2ETests.WasmServerHost.Client
                    ┣ _Imports.razor
                    ┣ App.razor
                    ┣ Program.cs
                    ┗ Routes.razor
ShowCase is an example of implementation also provides site for E2E and showcase     ┣ TELBlazor.Components.ShowCase.Shared
            ┣ _Imports.razor
            ┣ DI
            ┣ Layouts
                    ┣ ComponentLayouts
                            ┣ ComponentNavMenu.razor
                            ┣ ComponentPageLayout.razor
                            ┗ ShowCase.razor
                    ┗ MainLayout.razor
            ┣ Pages
                    ┣ ComponentPages
                            ┣ BaseComponentPages
                                    ┗ TELButtonPage.razor
                            ┗ TestComponentPages
                                    ┣ CssSourceCheckerPage.razor
                                    ┗ LogLevelSwitcherPage.razor
                    ┣ Error.razor
                    ┗ Home.razor
            ┗ Services
                    ┗ HelperServices
                            ┗ SerilogLogLevelSwitcher.cs
Published to create gh-pages DevShowCase ShowCase     ┣ TELBlazor.Components.ShowCase.WasmStaticClient
            ┣ _Imports.razor
            ┣ App.razor
            ┣ Program.cs
            ┗ Routes.razor
    ┣ TELBlazor.Components.UnitTests
            ┣ _Imports.razor
            ┣ Components
                    ┣ BaseComponents
Axe and functionality test, does not simulate nojs or browser                             ┗ TELButtonTests.razor
                    ┗ TestComponents
            ┣ Core
            ┣ DI
                    ┣ DI.cs
                    ┗ FallbackServiceProvider.cs
            ┣ HtmlComparisons
            ┗ TestDoubles

About

TEL Blazor Component Library Package

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors 3

  •  
  •  
  •