From 54ed55bc2e201766d779f40e34a35abb0e82a6ab Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 14:00:53 +0000 Subject: [PATCH 01/34] WIP #248 - Initial GitHub actions config --- .github/workflows/dotnetCi.yml | 113 +++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 .github/workflows/dotnetCi.yml diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml new file mode 100644 index 00000000..83874148 --- /dev/null +++ b/.github/workflows/dotnetCi.yml @@ -0,0 +1,113 @@ +name: .NET CI + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + + buildAndRunBasicTests: + runs-on: ubuntu-slim + + # env: + # TODO: put env vars here + + steps: + - name: Checkout + uses: actions/checkout@v4 + + # Install build dependencies + + - name: Install .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - name: Setup Node.js for building JSON-to-HTML report converter + uses: actions/setup-node@v6.2.0 + - name: Setup Java JDK for SonarScanner + uses: actions/setup-java@v5.1.0 + with: + java-version: 17 + + # Environment setup pre-build + + - name: Setup MSBuild.exe + uses: microsoft/setup-msbuild@v2 + - name: Setup SonarScanner + run: dotnet tool install --global dotnet-sonarscanner + - name: Setup Coverlet console + run: dotnet tool install --global coverlet.console + + # Start SonarScanner + + # Build + - name: Build the solution + run: dotnet build --no-incremental + + # Test .NET (with coverage) + + # Test JavaScript (with coverage) + + # Stop SonarScanner + + # Upload test results artifact + + # Convert Screenplay reports to HTML and upload artifacts + + # Upload build-results artifacts + + buildDocs: + # TODO: Build the docco site and package the result as an artifact, don't publish it + + publishDocs: + # TODO: Take the docco site artifact and publish it to master + + runBrowserTests: + # TODO: Use build-results artifacts and run tests on matrix of browsers + + + + + + + + + + + # - name: Execute unit tests + # run: dotnet test + + # # Restore the application to populate the obj folder with RuntimeIdentifiers + # - name: Restore the application + # run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration + # env: + # Configuration: ${{ matrix.configuration }} + + # # Decode the base 64 encoded pfx and save the Signing_Certificate + # - name: Decode the pfx + # run: | + # $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.Base64_Encoded_Pfx }}") + # $certificatePath = Join-Path -Path $env:Wap_Project_Directory -ChildPath GitHubActionsWorkflow.pfx + # [IO.File]::WriteAllBytes("$certificatePath", $pfx_cert_byte) + + # # Create the app package by building and packaging the Windows Application Packaging project + # - name: Create the app package + # run: msbuild $env:Wap_Project_Path /p:Configuration=$env:Configuration /p:UapAppxPackageBuildMode=$env:Appx_Package_Build_Mode /p:AppxBundle=$env:Appx_Bundle /p:PackageCertificateKeyFile=GitHubActionsWorkflow.pfx /p:PackageCertificatePassword=${{ secrets.Pfx_Key }} + # env: + # Appx_Bundle: Always + # Appx_Bundle_Platforms: x86|x64 + # Appx_Package_Build_Mode: StoreUpload + # Configuration: ${{ matrix.configuration }} + + # # Remove the pfx + # - name: Remove the pfx + # run: Remove-Item -path $env:Wap_Project_Directory\GitHubActionsWorkflow.pfx + + # # Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact + # - name: Upload build artifacts + # uses: actions/upload-artifact@v4 + # with: + # name: MSIX Package + # path: ${{ env.Wap_Project_Directory }}\AppPackages From 917e184bf59fc04533ea853ace0b1b2cc728ce32 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 19:11:06 +0000 Subject: [PATCH 02/34] WIP #248 - Initial attempt at GitHub actions I've commented out the AppVeyor build config in this commit to, so that it doesn't run. --- .appveyor.yml | 134 +++++++++++++------------- .github/workflows/dotnetCi.yml | 165 +++++++++++++++++++-------------- 2 files changed, 164 insertions(+), 135 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 5e17168e..68600363 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,76 +1,76 @@ -environment: - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 - JAVA_HOME: C:\Program Files\Java\jdk17 - - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204 - JAVA_HOME: /usr/lib/jvm/jdk15 +# environment: +# matrix: +# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 +# JAVA_HOME: C:\Program Files\Java\jdk17 +# - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204 +# JAVA_HOME: /usr/lib/jvm/jdk15 -skip_branch_with_pr: true +# skip_branch_with_pr: true -# A note/reminder for readers: Script items prefixed "cmd:" are executed on Windows-only environments. -# Items with no prefix (or "ps:" prefix) are run on all environments (Windows & Linux) +# # A note/reminder for readers: Script items prefixed "cmd:" are executed on Windows-only environments. +# # Items with no prefix (or "ps:" prefix) are run on all environments (Windows & Linux) -init: - - cmd: git config --global core.autocrlf true +# init: +# - cmd: git config --global core.autocrlf true -install: - - cmd: dotnet tool install --global dotnet-sonarscanner - - cmd: dotnet tool install --global coverlet.console - - cmd: dotnet tool update -g docfx - - ps: | - cd CSF.Screenplay.JsonToHtmlReport.Template\src - npm ci - cd ..\.. - # This was taken from https://stackoverflow.com/questions/60304251/unable-to-open-x-display-when-trying-to-run-google-chrome-on-centos-rhel-7-5 - # It's the minimum dependencies for running Chrome in a headless environment on Linux - - sh: | - sudo apt-get update - sudo apt install -y xorg xvfb gtk2-engines-pixbuf dbus-x11 xfonts-base xfonts-100dpi xfonts-75dpi xfonts-cyrillic xfonts-scalable +# install: +# - cmd: dotnet tool install --global dotnet-sonarscanner +# - cmd: dotnet tool install --global coverlet.console +# - cmd: dotnet tool update -g docfx +# - ps: | +# cd CSF.Screenplay.JsonToHtmlReport.Template\src +# npm ci +# cd ..\.. +# # This was taken from https://stackoverflow.com/questions/60304251/unable-to-open-x-display-when-trying-to-run-google-chrome-on-centos-rhel-7-5 +# # It's the minimum dependencies for running Chrome in a headless environment on Linux +# - sh: | +# sudo apt-get update +# sudo apt install -y xorg xvfb gtk2-engines-pixbuf dbus-x11 xfonts-base xfonts-100dpi xfonts-75dpi xfonts-cyrillic xfonts-scalable -before_build: - - dotnet --version - - dotnet restore --verbosity m - - dotnet clean - - cmd: Tools\appveyor-setup-sonarscanner.bat - - cmd: Tools\appveyor-setup-selenium.bat - - cmd: > - dotnet-sonarscanner begin - /k:"csf-dev_CSF.Screenplay" - /v:AppVeyor_build_%APPVEYOR_BUILD_NUMBER% - /o:craigfowler-github - /d:sonar.host.url=https://sonarcloud.io - /d:sonar.token=%SONARCLOUD_SECRET_KEY% - /d:%BranchParam%=%BranchName% - %PRParam% - /d:sonar.javascript.lcov.reportPaths=%APPVEYOR_BUILD_FOLDER%\CSF.Screenplay.JsonToHtmlReport.Template\src\TestResults\lcov.info - /s:%APPVEYOR_BUILD_FOLDER%\.sonarqube-analysisproperties.xml - # Activate Xvfb and export a display so that Chrome can run in Linux - - sh: | - Xvfb -ac :99 -screen 0 1280x1024x16 & - export DISPLAY=:99 +# before_build: +# - dotnet --version +# - dotnet restore --verbosity m +# - dotnet clean +# - cmd: Tools\appveyor-setup-sonarscanner.bat +# - cmd: Tools\appveyor-setup-selenium.bat +# - cmd: > +# dotnet-sonarscanner begin +# /k:"csf-dev_CSF.Screenplay" +# /v:AppVeyor_build_%APPVEYOR_BUILD_NUMBER% +# /o:craigfowler-github +# /d:sonar.host.url=https://sonarcloud.io +# /d:sonar.token=%SONARCLOUD_SECRET_KEY% +# /d:%BranchParam%=%BranchName% +# %PRParam% +# /d:sonar.javascript.lcov.reportPaths=%APPVEYOR_BUILD_FOLDER%\CSF.Screenplay.JsonToHtmlReport.Template\src\TestResults\lcov.info +# /s:%APPVEYOR_BUILD_FOLDER%\.sonarqube-analysisproperties.xml +# # Activate Xvfb and export a display so that Chrome can run in Linux +# - sh: | +# Xvfb -ac :99 -screen 0 1280x1024x16 & +# export DISPLAY=:99 -build_script: - - dotnet build --no-incremental +# build_script: +# - dotnet build --no-incremental -test_script: - - ps: if ($isWindows) { Tools\run-tests-with-coverage.ps1 } - - sh: > - dotnet test - --test-adapter-path:. - --logger:nunit - - ps: | - cd CSF.Screenplay.JsonToHtmlReport.Template\src - npm test - cd ..\.. +# test_script: +# - ps: if ($isWindows) { Tools\run-tests-with-coverage.ps1 } +# - sh: > +# dotnet test +# --test-adapter-path:. +# --logger:nunit +# - ps: | +# cd CSF.Screenplay.JsonToHtmlReport.Template\src +# npm test +# cd ..\.. -after_test: - - cmd: > - dotnet-sonarscanner end - /d:"sonar.token=%SONARCLOUD_SECRET_KEY%" - - ps: if ($isWindows) { Tools\appveyor-upload-test-results.ps1 } - - cmd: dotnet build -c Docs - - ps: if ($isWindows) { Tools\appveyor_publish_docs.ps1 } +# after_test: +# - cmd: > +# dotnet-sonarscanner end +# /d:"sonar.token=%SONARCLOUD_SECRET_KEY%" +# - ps: if ($isWindows) { Tools\appveyor-upload-test-results.ps1 } +# - cmd: dotnet build -c Docs +# - ps: if ($isWindows) { Tools\appveyor_publish_docs.ps1 } -artifacts: - - path: Tests\**\ScreenplayReport_*.json - name: Screenplay report +# artifacts: +# - path: Tests\**\ScreenplayReport_*.json +# name: Screenplay report diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 83874148..f44d6b8f 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -11,8 +11,15 @@ jobs: buildAndRunBasicTests: runs-on: ubuntu-slim - # env: - # TODO: put env vars here + env: + RunNumber: ${{ github.run_number }}.${{ github.run_attempt }} + SonarCloudProject: csf-dev_CSF.Screenplay + SonarCloudUsername: craigfowler-github + SonarCloudUrl: https://sonarcloud.io + Configuration: Debug + Tfm: net8.0 + DotnetVersion: 8.0.x + SonarCloudSecretKey: ${{ secrets.SONARCLOUDKEY }} steps: - name: Checkout @@ -23,7 +30,7 @@ jobs: - name: Install .NET Core uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: ${{ env.DotnetVersion }} - name: Setup Node.js for building JSON-to-HTML report converter uses: actions/setup-node@v6.2.0 - name: Setup Java JDK for SonarScanner @@ -39,75 +46,97 @@ jobs: run: dotnet tool install --global dotnet-sonarscanner - name: Setup Coverlet console run: dotnet tool install --global coverlet.console - - # Start SonarScanner - - # Build + - name: Setup SonarScanner for pull request processing + if: ${{ github.event_name == 'pull_request' }} + env: + BranchName: ${{ github.base_ref }} + BranchParam: sonar.pullrequest.branch + PullRequestParam: /d:sonar.pullrequest.key=${{ github.event.number }} + - name: Setup SonarScanner for normal branch processing + if: ${{ github.event_name != 'pull_request' }} + env: + BranchName: ${{ github.ref_name }} + BranchParam: sonar.branch.name + PullRequestParam: + - name: Setup Selenium Manager config + run: | + mkdir ~/.cache/selenium + cp Tools/se-config.toml ~/.cache/selenium + - name: Setup an Xvfb display so Chrome may run + run: | + Xvfb -ac :99 -screen 0 1280x1024x16 & + export DISPLAY=:99 + + # Build and test the solution + + - name: Restore .NET packages + run: dotnet restore -c ${{ env.Configuration }} + - name: Start SonarScanner + run: > + dotnet-sonarscanner begin + /k:${{ env.SonarCloudProject }} + /v:GitHub_build_${{ env.RunNumber }} + /o:${{ env.SonarCloudUsername }} + /d:sonar.host.url=${{ env.SonarCloudUrl }} + /d:sonar.token=${{ env.SonarCloudSecretKey }} + /d:${{ env.BranchParam }}=${{ env.BranchName }} + ${{ env.PullRequestParam }} + /d:sonar.javascript.lcov.reportPaths=CSF.Screenplay.JsonToHtmlReport.Template/src/TestResults/lcov.info + /s:.sonarqube-analysisproperties.xml - name: Build the solution - run: dotnet build --no-incremental - - # Test .NET (with coverage) - - # Test JavaScript (with coverage) - - # Stop SonarScanner - - # Upload test results artifact - - # Convert Screenplay reports to HTML and upload artifacts - - # Upload build-results artifacts + run: dotnet build -c ${{ env.Configuration }} --no-incremental + - name: Run .NET tests with coverage + run: | + AnyFailures=0 + for proj in Tests/*.Tests + do + projNameArray=(${proj//// }) + projName=${projNameArray[1]} + assemblyPath=$proj/bin/$Configuration/$Tfm/$projName.dll + coverlet "$assemblyPath" --target "dotnet" --targetargs "test $proj --no-build --logger:nunit --test-adapter-path:." -f=opencover -o="TestResults/$projName.opencover.xml" + if [ $? -ne 0 ] + then + AnyFailures=1 + fi + done + export AnyFailures + - name: Run JavaScript tests with coverage + run: | + cd CSF.Screenplay.JsonToHtmlReport.Template/src + npm test + if [ $? -ne 0 ] + then + export AnyFailures=1 + fi + cd ../.. + - name: Stop SonarScanner + run: + dotnet-sonarscanner end /d:sonar.token=${{ env.SonarCloudSecretKey }} + - name: Upload test results artifacts + uses: actions/upload-artifact@v4 + with: + name: NUnit test results + path: Tests/*.Tests/**/TestResults.xml + - name: Upload Screenplay JSON report artifact + uses: actions/upload-artifact@v4 + with: + name: Screenplay JSON reports + path: Tests/**/ScreenplayReport_*.json + - name: Fail the build if any test failures + run: | + if [ $AnyFailures -ne 0 ] + then + echo "Failing the build due to test failures" + exit 1 + fi + + # TODO: Convert Screenplay reports to HTML and upload as an artifact - buildDocs: + # buildDocs: # TODO: Build the docco site and package the result as an artifact, don't publish it - publishDocs: + # publishDocs: # TODO: Take the docco site artifact and publish it to master - runBrowserTests: + # runBrowserTests: # TODO: Use build-results artifacts and run tests on matrix of browsers - - - - - - - - - - - # - name: Execute unit tests - # run: dotnet test - - # # Restore the application to populate the obj folder with RuntimeIdentifiers - # - name: Restore the application - # run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration - # env: - # Configuration: ${{ matrix.configuration }} - - # # Decode the base 64 encoded pfx and save the Signing_Certificate - # - name: Decode the pfx - # run: | - # $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.Base64_Encoded_Pfx }}") - # $certificatePath = Join-Path -Path $env:Wap_Project_Directory -ChildPath GitHubActionsWorkflow.pfx - # [IO.File]::WriteAllBytes("$certificatePath", $pfx_cert_byte) - - # # Create the app package by building and packaging the Windows Application Packaging project - # - name: Create the app package - # run: msbuild $env:Wap_Project_Path /p:Configuration=$env:Configuration /p:UapAppxPackageBuildMode=$env:Appx_Package_Build_Mode /p:AppxBundle=$env:Appx_Bundle /p:PackageCertificateKeyFile=GitHubActionsWorkflow.pfx /p:PackageCertificatePassword=${{ secrets.Pfx_Key }} - # env: - # Appx_Bundle: Always - # Appx_Bundle_Platforms: x86|x64 - # Appx_Package_Build_Mode: StoreUpload - # Configuration: ${{ matrix.configuration }} - - # # Remove the pfx - # - name: Remove the pfx - # run: Remove-Item -path $env:Wap_Project_Directory\GitHubActionsWorkflow.pfx - - # # Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact - # - name: Upload build artifacts - # uses: actions/upload-artifact@v4 - # with: - # name: MSIX Package - # path: ${{ env.Wap_Project_Directory }}\AppPackages From 0fd097a6a96e7e4122f1cafd9120af48b8f8fdde Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 19:24:16 +0000 Subject: [PATCH 03/34] WIP #248 - Attempt to fix syntax --- .github/workflows/dotnetCi.yml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index f44d6b8f..c5dcfb6e 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -20,6 +20,9 @@ jobs: Tfm: net8.0 DotnetVersion: 8.0.x SonarCloudSecretKey: ${{ secrets.SONARCLOUDKEY }} + BranchName: ${{ github.event_name == 'pull_request' && github.base_ref || github.ref_name }} + BranchParam: ${{ github.event_name == 'pull_request' && 'sonar.pullrequest.branch' || 'sonar.branch.name' }} + PullRequestParam: ${{ github.event_name == 'pull_request' && format('/d:sonar.pullrequest.key={0}', github.event.number) || '' }} steps: - name: Checkout @@ -46,18 +49,6 @@ jobs: run: dotnet tool install --global dotnet-sonarscanner - name: Setup Coverlet console run: dotnet tool install --global coverlet.console - - name: Setup SonarScanner for pull request processing - if: ${{ github.event_name == 'pull_request' }} - env: - BranchName: ${{ github.base_ref }} - BranchParam: sonar.pullrequest.branch - PullRequestParam: /d:sonar.pullrequest.key=${{ github.event.number }} - - name: Setup SonarScanner for normal branch processing - if: ${{ github.event_name != 'pull_request' }} - env: - BranchName: ${{ github.ref_name }} - BranchParam: sonar.branch.name - PullRequestParam: - name: Setup Selenium Manager config run: | mkdir ~/.cache/selenium From 18f4355a3f4f33bd00c6608fc81269907b10c34b Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 19:28:19 +0000 Subject: [PATCH 04/34] WIP #248 - Fix Java distro --- .github/workflows/dotnetCi.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index c5dcfb6e..243f782a 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -39,7 +39,8 @@ jobs: - name: Setup Java JDK for SonarScanner uses: actions/setup-java@v5.1.0 with: - java-version: 17 + java-version: 21 + distribution: 'zulu' # Environment setup pre-build From 4d1a402b10d25fd5b444cd1f5647c9b877684cfa Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 19:29:47 +0000 Subject: [PATCH 05/34] WIP #248 - Remove unwanted step --- .github/workflows/dotnetCi.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 243f782a..3bc79abb 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -44,8 +44,6 @@ jobs: # Environment setup pre-build - - name: Setup MSBuild.exe - uses: microsoft/setup-msbuild@v2 - name: Setup SonarScanner run: dotnet tool install --global dotnet-sonarscanner - name: Setup Coverlet console From 2cd05e69909d2373799bdfdfdfcc905c96c2b3d2 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 19:33:04 +0000 Subject: [PATCH 06/34] WIP #248 - Fix build failure --- .github/workflows/dotnetCi.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 3bc79abb..bb1bc456 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -60,7 +60,7 @@ jobs: # Build and test the solution - name: Restore .NET packages - run: dotnet restore -c ${{ env.Configuration }} + run: dotnet restore - name: Start SonarScanner run: > dotnet-sonarscanner begin @@ -83,7 +83,7 @@ jobs: projNameArray=(${proj//// }) projName=${projNameArray[1]} assemblyPath=$proj/bin/$Configuration/$Tfm/$projName.dll - coverlet "$assemblyPath" --target "dotnet" --targetargs "test $proj --no-build --logger:nunit --test-adapter-path:." -f=opencover -o="TestResults/$projName.opencover.xml" + coverlet "$assemblyPath" --target "dotnet" --targetargs "test $proj -c $Configuration --no-build --logger:nunit --test-adapter-path:." -f=opencover -o="TestResults/$projName.opencover.xml" if [ $? -ne 0 ] then AnyFailures=1 From 9281f07c9e8793c463cc381c6ffe880423121768 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 19:37:05 +0000 Subject: [PATCH 07/34] WIP #248 - Fix SonarScanner usage --- .github/workflows/dotnetCi.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index bb1bc456..49a4038d 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -63,7 +63,7 @@ jobs: run: dotnet restore - name: Start SonarScanner run: > - dotnet-sonarscanner begin + dotnet sonarscanner begin /k:${{ env.SonarCloudProject }} /v:GitHub_build_${{ env.RunNumber }} /o:${{ env.SonarCloudUsername }} @@ -101,7 +101,7 @@ jobs: cd ../.. - name: Stop SonarScanner run: - dotnet-sonarscanner end /d:sonar.token=${{ env.SonarCloudSecretKey }} + dotnet sonarscanner end /d:sonar.token=${{ env.SonarCloudSecretKey }} - name: Upload test results artifacts uses: actions/upload-artifact@v4 with: From 4fa7de4a7f4c0f6cdc6f966bada1225bfeabf618 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 19:43:40 +0000 Subject: [PATCH 08/34] WIP #248 - Add dotnet tools to path --- .github/workflows/dotnetCi.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 49a4038d..a10b1ed7 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -44,9 +44,11 @@ jobs: # Environment setup pre-build - - name: Setup SonarScanner + - name: Add .NET global tools location to PATH + run: export PATH="$PATH:/home/runner/.dotnet/tools" + - name: Install SonarScanner run: dotnet tool install --global dotnet-sonarscanner - - name: Setup Coverlet console + - name: Install Coverlet console run: dotnet tool install --global coverlet.console - name: Setup Selenium Manager config run: | From 25374971db2c5c2f8040b1886d749f4f67317a0d Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 19:49:23 +0000 Subject: [PATCH 09/34] WIP #248 - Another technique to set path --- .github/workflows/dotnetCi.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index a10b1ed7..cb36f3d5 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -23,6 +23,7 @@ jobs: BranchName: ${{ github.event_name == 'pull_request' && github.base_ref || github.ref_name }} BranchParam: ${{ github.event_name == 'pull_request' && 'sonar.pullrequest.branch' || 'sonar.branch.name' }} PullRequestParam: ${{ github.event_name == 'pull_request' && format('/d:sonar.pullrequest.key={0}', github.event.number) || '' }} + PATH: ${{ env.PATH }} steps: - name: Checkout @@ -45,7 +46,7 @@ jobs: # Environment setup pre-build - name: Add .NET global tools location to PATH - run: export PATH="$PATH:/home/runner/.dotnet/tools" + run: echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH" - name: Install SonarScanner run: dotnet tool install --global dotnet-sonarscanner - name: Install Coverlet console From 787a155f0b3c8daff9c571ac9c1d7d79774d3d46 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 19:50:05 +0000 Subject: [PATCH 10/34] Remove unwanted detritus --- .github/workflows/dotnetCi.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index cb36f3d5..9fccac0b 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -23,7 +23,6 @@ jobs: BranchName: ${{ github.event_name == 'pull_request' && github.base_ref || github.ref_name }} BranchParam: ${{ github.event_name == 'pull_request' && 'sonar.pullrequest.branch' || 'sonar.branch.name' }} PullRequestParam: ${{ github.event_name == 'pull_request' && format('/d:sonar.pullrequest.key={0}', github.event.number) || '' }} - PATH: ${{ env.PATH }} steps: - name: Checkout From a08856fc8526b8a06f9a0dac37b608adfbaf71aa Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 19:55:39 +0000 Subject: [PATCH 11/34] WIP #248 - Attempt to fix SonarScanner invocation --- .github/workflows/dotnetCi.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 9fccac0b..210de8cb 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -30,13 +30,13 @@ jobs: # Install build dependencies - - name: Install .NET Core + - name: Install .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DotnetVersion }} - - name: Setup Node.js for building JSON-to-HTML report converter + - name: Install Node.js for building JSON-to-HTML report converter uses: actions/setup-node@v6.2.0 - - name: Setup Java JDK for SonarScanner + - name: Install Java JDK for SonarScanner uses: actions/setup-java@v5.1.0 with: java-version: 21 @@ -65,7 +65,7 @@ jobs: run: dotnet restore - name: Start SonarScanner run: > - dotnet sonarscanner begin + dotnet sonarscanner begin /k:${{ env.SonarCloudProject }} /v:GitHub_build_${{ env.RunNumber }} /o:${{ env.SonarCloudUsername }} @@ -74,7 +74,7 @@ jobs: /d:${{ env.BranchParam }}=${{ env.BranchName }} ${{ env.PullRequestParam }} /d:sonar.javascript.lcov.reportPaths=CSF.Screenplay.JsonToHtmlReport.Template/src/TestResults/lcov.info - /s:.sonarqube-analysisproperties.xml + /s:${{ env.PWD }}/.sonarqube-analysisproperties.xml - name: Build the solution run: dotnet build -c ${{ env.Configuration }} --no-incremental - name: Run .NET tests with coverage From cfb7c4596fa47272f7f1097519a4aae1e99f0b61 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 19:59:07 +0000 Subject: [PATCH 12/34] WIP #248 - SonarCloud again --- .github/workflows/dotnetCi.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 210de8cb..ba29eaa7 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -71,10 +71,9 @@ jobs: /o:${{ env.SonarCloudUsername }} /d:sonar.host.url=${{ env.SonarCloudUrl }} /d:sonar.token=${{ env.SonarCloudSecretKey }} - /d:${{ env.BranchParam }}=${{ env.BranchName }} - ${{ env.PullRequestParam }} + /d:${{ env.BranchParam }}=${{ env.BranchName }} ${{ env.PullRequestParam }} /d:sonar.javascript.lcov.reportPaths=CSF.Screenplay.JsonToHtmlReport.Template/src/TestResults/lcov.info - /s:${{ env.PWD }}/.sonarqube-analysisproperties.xml + /s:$PWD/.sonarqube-analysisproperties.xml - name: Build the solution run: dotnet build -c ${{ env.Configuration }} --no-incremental - name: Run .NET tests with coverage From eb32ec51f1d47a0633f7865372be24deb9729ff6 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 20:08:44 +0000 Subject: [PATCH 13/34] WIP #248 - Improve build --- .github/workflows/dotnetCi.yml | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index ba29eaa7..b5ae9f6a 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -30,10 +30,16 @@ jobs: # Install build dependencies + - name: Add .NET global tools location to PATH + run: echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH" - name: Install .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DotnetVersion }} + - name: Install SonarScanner + run: dotnet tool install --global dotnet-sonarscanner + - name: Install Coverlet console + run: dotnet tool install --global coverlet.console - name: Install Node.js for building JSON-to-HTML report converter uses: actions/setup-node@v6.2.0 - name: Install Java JDK for SonarScanner @@ -44,25 +50,24 @@ jobs: # Environment setup pre-build - - name: Add .NET global tools location to PATH - run: echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH" - - name: Install SonarScanner - run: dotnet tool install --global dotnet-sonarscanner - - name: Install Coverlet console - run: dotnet tool install --global coverlet.console - name: Setup Selenium Manager config run: | mkdir ~/.cache/selenium cp Tools/se-config.toml ~/.cache/selenium - - name: Setup an Xvfb display so Chrome may run + - name: Start an Xvfb display so Chrome may run run: | Xvfb -ac :99 -screen 0 1280x1024x16 & export DISPLAY=:99 + - name: Restore .NET packages + run: dotnet restore + - name: Restore Node modules + run: | + cd CSF.Screenplay.JsonToHtmlReport.Template/src + npm ci + cd ../.. # Build and test the solution - - name: Restore .NET packages - run: dotnet restore - name: Start SonarScanner run: > dotnet sonarscanner begin From 4f91641e9c2b7fb767aa7ea1d2ed552c521d0d2b Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 20:26:21 +0000 Subject: [PATCH 14/34] Attempt to fix build env --- .github/workflows/dotnetCi.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index b5ae9f6a..f644d23f 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -23,6 +23,7 @@ jobs: BranchName: ${{ github.event_name == 'pull_request' && github.base_ref || github.ref_name }} BranchParam: ${{ github.event_name == 'pull_request' && 'sonar.pullrequest.branch' || 'sonar.branch.name' }} PullRequestParam: ${{ github.event_name == 'pull_request' && format('/d:sonar.pullrequest.key={0}', github.event.number) || '' }} + DISPLAY: :99 steps: - name: Checkout @@ -55,9 +56,7 @@ jobs: mkdir ~/.cache/selenium cp Tools/se-config.toml ~/.cache/selenium - name: Start an Xvfb display so Chrome may run - run: | - Xvfb -ac :99 -screen 0 1280x1024x16 & - export DISPLAY=:99 + run: Xvfb -ac $DISPLAY -screen 0 1280x1024x16 & - name: Restore .NET packages run: dotnet restore - name: Restore Node modules @@ -82,6 +81,8 @@ jobs: - name: Build the solution run: dotnet build -c ${{ env.Configuration }} --no-incremental - name: Run .NET tests with coverage + id: dotnet_tests + continue-on-error: true run: | AnyFailures=0 for proj in Tests/*.Tests @@ -95,14 +96,18 @@ jobs: AnyFailures=1 fi done - export AnyFailures + echo "failures=$AnyFailures" >> $GITHUB_OUTPUT - name: Run JavaScript tests with coverage + id: js_tests + continue-on-error: true run: | cd CSF.Screenplay.JsonToHtmlReport.Template/src npm test if [ $? -ne 0 ] then - export AnyFailures=1 + echo "failures=1" >> $GITHUB_OUTPUT + else + echo "failures=0" >> $GITHUB_OUTPUT fi cd ../.. - name: Stop SonarScanner @@ -119,12 +124,10 @@ jobs: name: Screenplay JSON reports path: Tests/**/ScreenplayReport_*.json - name: Fail the build if any test failures + if: ${{ steps.dotnet_tests.outputs.failures == 1 || steps.js_tests.outputs.failures == 1 }} run: | - if [ $AnyFailures -ne 0 ] - then - echo "Failing the build due to test failures" - exit 1 - fi + echo "Failing the build due to test failures" + exit 1 # TODO: Convert Screenplay reports to HTML and upload as an artifact From 9bffdf64595f5a4734d4cd8b53c3821f078f23a3 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 20:37:47 +0000 Subject: [PATCH 15/34] WIP #248 - Attempt to get bvuild working --- .github/workflows/dotnetCi.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index f644d23f..d59c7be0 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -48,6 +48,10 @@ jobs: with: java-version: 21 distribution: 'zulu' + - name: Install GUI packages so Chrome may run + run: | + sudo apt-get update + sudo apt install -y xorg xvfb gtk2-engines-pixbuf dbus-x11 xfonts-base xfonts-100dpi xfonts-75dpi xfonts-cyrillic xfonts-scalable # Environment setup pre-build @@ -84,7 +88,6 @@ jobs: id: dotnet_tests continue-on-error: true run: | - AnyFailures=0 for proj in Tests/*.Tests do projNameArray=(${proj//// }) @@ -93,10 +96,9 @@ jobs: coverlet "$assemblyPath" --target "dotnet" --targetargs "test $proj -c $Configuration --no-build --logger:nunit --test-adapter-path:." -f=opencover -o="TestResults/$projName.opencover.xml" if [ $? -ne 0 ] then - AnyFailures=1 + echo "failures=true" >> $GITHUB_OUTPUT fi done - echo "failures=$AnyFailures" >> $GITHUB_OUTPUT - name: Run JavaScript tests with coverage id: js_tests continue-on-error: true @@ -105,9 +107,7 @@ jobs: npm test if [ $? -ne 0 ] then - echo "failures=1" >> $GITHUB_OUTPUT - else - echo "failures=0" >> $GITHUB_OUTPUT + echo "failures=true" >> $GITHUB_OUTPUT fi cd ../.. - name: Stop SonarScanner @@ -124,7 +124,7 @@ jobs: name: Screenplay JSON reports path: Tests/**/ScreenplayReport_*.json - name: Fail the build if any test failures - if: ${{ steps.dotnet_tests.outputs.failures == 1 || steps.js_tests.outputs.failures == 1 }} + if: ${{ steps.dotnet_tests.outputs.failures == 'true' || steps.js_tests.outputs.failures == 'true' }} run: | echo "Failing the build due to test failures" exit 1 From bdeab4c4d11b65c27700da8ef7bef015d0400088 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 20:52:58 +0000 Subject: [PATCH 16/34] Update CI badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 871de093..5bd9af04 100755 --- a/README.md +++ b/README.md @@ -16,5 +16,5 @@ Detailed information about Screenplay & how it is used is [available on the docu CI builds are configured via **AppVeyor**, with static code analysis & reporting in **SonarCloud**. -[![AppVeyor status](https://ci.appveyor.com/api/projects/status/y9ejfko3kflosava?svg=true)](https://ci.appveyor.com/project/craigfowler/csf-screenplay) +[![.NET CI](https://github.com/csf-dev/CSF.Screenplay/actions/workflows/dotnetCi.yml/badge.svg)](https://github.com/csf-dev/CSF.Screenplay/actions/workflows/dotnetCi.yml) [![Test coverage](https://sonarcloud.io/api/project_badges/measure?project=csf-dev_CSF.Screenplay&metric=coverage)](https://sonarcloud.io/summary/new_code?id=csf-dev_CSF.Screenplay) From d67f6ae3311d3522d1ad8a20769908ad8008ab0e Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Fri, 16 Jan 2026 20:58:28 +0000 Subject: [PATCH 17/34] Remove unneeded config --- .appveyor.yml | 76 -------------------------- Tools/Appveyor.after_deploy.bat | 14 ----- Tools/Appveyor.before_build.bat | 9 --- Tools/appveyor-setup-selenium.bat | 20 ------- Tools/appveyor-setup-sonarscanner.bat | 13 ----- Tools/appveyor-upload-test-results.ps1 | 17 ------ Tools/run-tests-with-coverage.ps1 | 27 --------- 7 files changed, 176 deletions(-) delete mode 100644 .appveyor.yml delete mode 100755 Tools/Appveyor.after_deploy.bat delete mode 100755 Tools/Appveyor.before_build.bat delete mode 100644 Tools/appveyor-setup-selenium.bat delete mode 100644 Tools/appveyor-setup-sonarscanner.bat delete mode 100644 Tools/appveyor-upload-test-results.ps1 delete mode 100644 Tools/run-tests-with-coverage.ps1 diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 68600363..00000000 --- a/.appveyor.yml +++ /dev/null @@ -1,76 +0,0 @@ -# environment: -# matrix: -# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 -# JAVA_HOME: C:\Program Files\Java\jdk17 -# - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204 -# JAVA_HOME: /usr/lib/jvm/jdk15 - -# skip_branch_with_pr: true - -# # A note/reminder for readers: Script items prefixed "cmd:" are executed on Windows-only environments. -# # Items with no prefix (or "ps:" prefix) are run on all environments (Windows & Linux) - -# init: -# - cmd: git config --global core.autocrlf true - -# install: -# - cmd: dotnet tool install --global dotnet-sonarscanner -# - cmd: dotnet tool install --global coverlet.console -# - cmd: dotnet tool update -g docfx -# - ps: | -# cd CSF.Screenplay.JsonToHtmlReport.Template\src -# npm ci -# cd ..\.. -# # This was taken from https://stackoverflow.com/questions/60304251/unable-to-open-x-display-when-trying-to-run-google-chrome-on-centos-rhel-7-5 -# # It's the minimum dependencies for running Chrome in a headless environment on Linux -# - sh: | -# sudo apt-get update -# sudo apt install -y xorg xvfb gtk2-engines-pixbuf dbus-x11 xfonts-base xfonts-100dpi xfonts-75dpi xfonts-cyrillic xfonts-scalable - -# before_build: -# - dotnet --version -# - dotnet restore --verbosity m -# - dotnet clean -# - cmd: Tools\appveyor-setup-sonarscanner.bat -# - cmd: Tools\appveyor-setup-selenium.bat -# - cmd: > -# dotnet-sonarscanner begin -# /k:"csf-dev_CSF.Screenplay" -# /v:AppVeyor_build_%APPVEYOR_BUILD_NUMBER% -# /o:craigfowler-github -# /d:sonar.host.url=https://sonarcloud.io -# /d:sonar.token=%SONARCLOUD_SECRET_KEY% -# /d:%BranchParam%=%BranchName% -# %PRParam% -# /d:sonar.javascript.lcov.reportPaths=%APPVEYOR_BUILD_FOLDER%\CSF.Screenplay.JsonToHtmlReport.Template\src\TestResults\lcov.info -# /s:%APPVEYOR_BUILD_FOLDER%\.sonarqube-analysisproperties.xml -# # Activate Xvfb and export a display so that Chrome can run in Linux -# - sh: | -# Xvfb -ac :99 -screen 0 1280x1024x16 & -# export DISPLAY=:99 - -# build_script: -# - dotnet build --no-incremental - -# test_script: -# - ps: if ($isWindows) { Tools\run-tests-with-coverage.ps1 } -# - sh: > -# dotnet test -# --test-adapter-path:. -# --logger:nunit -# - ps: | -# cd CSF.Screenplay.JsonToHtmlReport.Template\src -# npm test -# cd ..\.. - -# after_test: -# - cmd: > -# dotnet-sonarscanner end -# /d:"sonar.token=%SONARCLOUD_SECRET_KEY%" -# - ps: if ($isWindows) { Tools\appveyor-upload-test-results.ps1 } -# - cmd: dotnet build -c Docs -# - ps: if ($isWindows) { Tools\appveyor_publish_docs.ps1 } - -# artifacts: -# - path: Tests\**\ScreenplayReport_*.json -# name: Screenplay report diff --git a/Tools/Appveyor.after_deploy.bat b/Tools/Appveyor.after_deploy.bat deleted file mode 100755 index 1bf4c01c..00000000 --- a/Tools/Appveyor.after_deploy.bat +++ /dev/null @@ -1,14 +0,0 @@ -@echo on - -@SET /A exitcode=0 -@SET /A TESTFAILURE_ERROR=1 -@SET /A PUSHARTIFACT_ERROR=2 -@SET /A READREPORT_ERROR=4 - -nunit3-console.exe CSF.Screenplay.Selenium.Tests\bin\Debug\CSF.Screenplay.Selenium.Tests.dll -@IF %ERRORLEVEL% NEQ 0 SET /A exitcode^|=%TESTFAILURE_ERROR% - -appveyor PushArtifact NUnit.report.json -@IF %ERRORLEVEL% NEQ 0 SET /A exitcode^|=%PUSHARTIFACT_ERROR% - -@EXIT /B %exitcode% diff --git a/Tools/Appveyor.before_build.bat b/Tools/Appveyor.before_build.bat deleted file mode 100755 index dc6b1d17..00000000 --- a/Tools/Appveyor.before_build.bat +++ /dev/null @@ -1,9 +0,0 @@ -@echo on - -git submodule update --init --recursive - -nuget restore CSF.Screenplay.Selenium.sln - -copy /y CSF.Screenplay.Selenium.Tests\App.AppVeyor.config CSF.Screenplay.Selenium.Tests\app.config - -@echo off \ No newline at end of file diff --git a/Tools/appveyor-setup-selenium.bat b/Tools/appveyor-setup-selenium.bat deleted file mode 100644 index c7e15335..00000000 --- a/Tools/appveyor-setup-selenium.bat +++ /dev/null @@ -1,20 +0,0 @@ -REM Set up a Selenium Manager config file, so that a fresh browser and driver are -REM downloaded explicitly, ignoring the pre-installed driver on the CI image. - -mkdir %USERPROFILE%\.cache\selenium -cp Tools\se-config.toml %USERPROFILE%\.cache\selenium - -REM Redefines the PATH environment variable, removing the preinstalled Selenium Webdriver. -REM Modern Selenium downloads/fetches the appropriate driver version for the browser, so -REM having this pre-installed driver in the path actually hurts more than helps. - -setlocal enabledelayedexpansion - -SET UNWANTED_PATH=C:\Tools\WebDriver - -REM Remove the unwanted path (handles all of ";path;", ";path" and "path;" cases) -SET "NEW_PATH=%PATH:;%UNWANTED_PATH%;=;%" -SET "NEW_PATH=!NEW_PATH:;%UNWANTED_PATH%=!" -SET "NEW_PATH=!NEW_PATH:%UNWANTED_PATH%;=!" - -endlocal & SET PATH=%NEW_PATH% diff --git a/Tools/appveyor-setup-sonarscanner.bat b/Tools/appveyor-setup-sonarscanner.bat deleted file mode 100644 index 02f08d99..00000000 --- a/Tools/appveyor-setup-sonarscanner.bat +++ /dev/null @@ -1,13 +0,0 @@ -REM Set up some env variables which will help SonarScanner identify the current branch - -IF NOT DEFINED APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH ( - SET BranchName=%APPVEYOR_REPO_BRANCH% - SET BranchParam=sonar.branch.name - SET PRParam= - echo Not building a PR -) ELSE ( - SET BranchName=%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH% - SET BranchParam=sonar.pullrequest.branch - SET PRParam=/d:sonar.pullrequest.key=%APPVEYOR_PULL_REQUEST_NUMBER% - echo Building a PR -) diff --git a/Tools/appveyor-upload-test-results.ps1 b/Tools/appveyor-upload-test-results.ps1 deleted file mode 100644 index e08b6942..00000000 --- a/Tools/appveyor-upload-test-results.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -# Adapted from https://www.appveyor.com/docs/running-tests/#uploading-xml-test-results - -$SolutionRoot = "$PSScriptRoot\.." -$TestProjects = Get-ChildItem -Path $SolutionRoot\Tests\ -Exclude CSF.Screenplay.Selenium.TestWebapp - -$wc = New-Object 'System.Net.WebClient' -$TestEndpoint = "https://ci.appveyor.com/api/testresults/nunit/$env:APPVEYOR_JOB_ID" - -foreach($project in $TestProjects) -{ - $projectName = Split-Path $project -Leaf - $testResultFile = "$project\TestResults\TestResults.xml" - Move-Item $testResultFile "$SolutionRoot\TestResults\$projectName.TestResults.xml" - $wc.UploadFile($TestEndpoint, (Resolve-Path $SolutionRoot\TestResults\$projectName.TestResults.xml)) -} - -exit $env:TESTS_FAILED diff --git a/Tools/run-tests-with-coverage.ps1 b/Tools/run-tests-with-coverage.ps1 deleted file mode 100644 index b7f20822..00000000 --- a/Tools/run-tests-with-coverage.ps1 +++ /dev/null @@ -1,27 +0,0 @@ -$SolutionRoot = "$PSScriptRoot\.." -$TestProjects = Get-ChildItem -Path $SolutionRoot\Tests\ -Exclude CSF.Screenplay.Selenium.TestWebapp -$Tfm = "net8.0" -$Configuration = "Debug" -Remove-Item $SolutionRoot\TestResults\* -ErrorAction Ignore -$TetsFailed = 0 - -foreach($project in $TestProjects) -{ - $projectName = Split-Path $project -Leaf - $projectAssembly = "$project\bin\$Configuration\$Tfm\$projectName.dll" - coverlet ` - "$projectAssembly" ` - --target "dotnet" ` - --targetargs "test $project --no-build --logger:nunit --test-adapter-path:." ` - -f=opencover ` - -o="$SolutionRoot\TestResults\$projectName.opencover.xml" - - if ($LastExitCode -eq 1) { - $TetsFailed = 1 - } - elseif ($LastExitCode -eq 3) { - $TetsFailed = 1 - } -} - -$env:TESTS_FAILED = $TetsFailed From 3f0df732f228cbdf12ceab74b9355ad353938071 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 09:51:00 +0000 Subject: [PATCH 18/34] WIP #248 - Debug build runs on one TFM only This should improve performance of the CI process and improve the analysis that SonarScanner performs. Previously, it was potentially scanning the same code many times, across many TFMs. This build & test workflow doesn't need to build across every TFM. --- .github/workflows/dotnetCi.yml | 4 +- .../CSF.Screenplay.Abstractions.csproj | 6 +- .../CSF.Screenplay.JsonToHtmlReport.csproj | 3 +- .../CSF.Screenplay.NUnit.csproj | 4 +- .../CSF.Screenplay.Selenium.csproj | 12 +- .../Elements/TargetNotFoundException.cs | 18 ++- .../Resources/ScriptResources.cs | 8 +- .../Resources/ScriptResources.restext | 1 + .../Resources/ScriptResources.resx | 124 ------------------ .../CSF.Screenplay.SpecFlow.csproj | 4 +- .../CSF.Screenplay.WebApis.csproj | 2 +- CSF.Screenplay/CSF.Screenplay.csproj | 4 +- .../CSF.Screenplay.NUnit.Tests.csproj | 4 +- .../CSF.Screenplay.Selenium.TestWebapp.csproj | 6 +- .../Program.cs | 2 + .../CSF.Screenplay.Selenium.Tests.csproj | 4 +- .../CSF.Screenplay.SpecFlow.Tests.csproj | 4 +- .../CSF.Screenplay.Tests.csproj | 4 +- Tools/MultiTargeting.props | 12 ++ Tools/TestTfm.props | 8 ++ 20 files changed, 73 insertions(+), 161 deletions(-) create mode 100644 CSF.Screenplay.Selenium/Resources/ScriptResources.restext delete mode 100644 CSF.Screenplay.Selenium/Resources/ScriptResources.resx create mode 100644 Tools/MultiTargeting.props create mode 100644 Tools/TestTfm.props diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index d59c7be0..7c9c2816 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -82,8 +82,8 @@ jobs: /d:${{ env.BranchParam }}=${{ env.BranchName }} ${{ env.PullRequestParam }} /d:sonar.javascript.lcov.reportPaths=CSF.Screenplay.JsonToHtmlReport.Template/src/TestResults/lcov.info /s:$PWD/.sonarqube-analysisproperties.xml - - name: Build the solution - run: dotnet build -c ${{ env.Configuration }} --no-incremental + - name: Build the solution (one TFM only for performance) + run: dotnet build -c ${{ env.Configuration }} --no-incremental -p:TargetFrameworks=${{ env.Tfm }} - name: Run .NET tests with coverage id: dotnet_tests continue-on-error: true diff --git a/CSF.Screenplay.Abstractions/CSF.Screenplay.Abstractions.csproj b/CSF.Screenplay.Abstractions/CSF.Screenplay.Abstractions.csproj index 951262d2..288f006e 100644 --- a/CSF.Screenplay.Abstractions/CSF.Screenplay.Abstractions.csproj +++ b/CSF.Screenplay.Abstractions/CSF.Screenplay.Abstractions.csproj @@ -1,14 +1,14 @@  + + - netstandard2.0;netstandard2.1;net462 CSF.Screenplay $(MSBuildProjectDirectory)\bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml - - + diff --git a/CSF.Screenplay.JsonToHtmlReport/CSF.Screenplay.JsonToHtmlReport.csproj b/CSF.Screenplay.JsonToHtmlReport/CSF.Screenplay.JsonToHtmlReport.csproj index b5b533fb..545d8420 100644 --- a/CSF.Screenplay.JsonToHtmlReport/CSF.Screenplay.JsonToHtmlReport.csproj +++ b/CSF.Screenplay.JsonToHtmlReport/CSF.Screenplay.JsonToHtmlReport.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;net462;netstandard2.0;net6.0;net8.0 + netcoreapp3.1;net462;netstandard2.0;net6.0;net8.0 Exe Library NU1903,NU1902 @@ -15,6 +15,7 @@ + diff --git a/CSF.Screenplay.NUnit/CSF.Screenplay.NUnit.csproj b/CSF.Screenplay.NUnit/CSF.Screenplay.NUnit.csproj index a16b3d38..89176107 100644 --- a/CSF.Screenplay.NUnit/CSF.Screenplay.NUnit.csproj +++ b/CSF.Screenplay.NUnit/CSF.Screenplay.NUnit.csproj @@ -1,7 +1,8 @@  + + - netstandard2.0;net462 CSF.Screenplay $(MSBuildProjectDirectory)\bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml false @@ -10,7 +11,6 @@ - diff --git a/CSF.Screenplay.Selenium/CSF.Screenplay.Selenium.csproj b/CSF.Screenplay.Selenium/CSF.Screenplay.Selenium.csproj index 55df1e89..2e14713d 100644 --- a/CSF.Screenplay.Selenium/CSF.Screenplay.Selenium.csproj +++ b/CSF.Screenplay.Selenium/CSF.Screenplay.Selenium.csproj @@ -1,15 +1,15 @@  + + - netstandard2.0;netstandard2.1;net462 CSF.Screenplay.Selenium $(MSBuildProjectDirectory)\bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml - - - + + @@ -20,4 +20,8 @@ + + + + diff --git a/CSF.Screenplay.Selenium/Elements/TargetNotFoundException.cs b/CSF.Screenplay.Selenium/Elements/TargetNotFoundException.cs index 4c6e0764..0b1fc747 100644 --- a/CSF.Screenplay.Selenium/Elements/TargetNotFoundException.cs +++ b/CSF.Screenplay.Selenium/Elements/TargetNotFoundException.cs @@ -1,5 +1,4 @@ using System; -using System.Runtime.Serialization; using CSF.Screenplay.Reporting; using OpenQA.Selenium; @@ -8,7 +7,9 @@ namespace CSF.Screenplay.Selenium.Elements /// /// Thrown when is used, but no element can be found. /// +#if NET462 || NETSTANDARD [Serializable] +#endif public class TargetNotFoundException : Exception, IFormattableValue { /// @@ -62,12 +63,21 @@ public TargetNotFoundException(string message, Exception inner, ITarget target) { Target = target ?? throw new ArgumentNullException(nameof(target)); } - +#if NET462 || NETSTANDARD /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class from binary serialization. /// + /// + /// Don't use this API, it's for the deprecated binary serialization API, which is known to pose + /// security vulnerabilities. It is removed and unsupported in modern TFMs. + /// See The + /// BinaryFormatter migration guide for more information. + /// /// Serialization info /// Streaming context - protected TargetNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) {} + [Obsolete("Do not use this constructor overload, see the remarks for more info")] + protected TargetNotFoundException(System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) {} +#endif } } \ No newline at end of file diff --git a/CSF.Screenplay.Selenium/Resources/ScriptResources.cs b/CSF.Screenplay.Selenium/Resources/ScriptResources.cs index 5fe8c817..dcafe916 100644 --- a/CSF.Screenplay.Selenium/Resources/ScriptResources.cs +++ b/CSF.Screenplay.Selenium/Resources/ScriptResources.cs @@ -7,11 +7,9 @@ namespace CSF.Screenplay.Selenium.Resources /// static class ScriptResources { - static readonly ResourceManager resourceManager = new ResourceManager(typeof(ScriptResources)); + static readonly ResourceManager resourceManager = new ResourceManager(typeof(ScriptResources).FullName, typeof(ScriptResources).Assembly); - /// - /// Gets a short JavaScript which clears the browser's local storage. - /// - public static string ClearLocalStorage => resourceManager.GetString("ClearLocalStorage"); + /// Gets a short JavaScript for . + internal static string ClearLocalStorage => resourceManager.GetString("ClearLocalStorage"); } } \ No newline at end of file diff --git a/CSF.Screenplay.Selenium/Resources/ScriptResources.restext b/CSF.Screenplay.Selenium/Resources/ScriptResources.restext new file mode 100644 index 00000000..181b93b5 --- /dev/null +++ b/CSF.Screenplay.Selenium/Resources/ScriptResources.restext @@ -0,0 +1 @@ +ClearLocalStorage = localStorage.clear() \ No newline at end of file diff --git a/CSF.Screenplay.Selenium/Resources/ScriptResources.resx b/CSF.Screenplay.Selenium/Resources/ScriptResources.resx deleted file mode 100644 index 62a307b4..00000000 --- a/CSF.Screenplay.Selenium/Resources/ScriptResources.resx +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - localStorage.clear() - - - \ No newline at end of file diff --git a/CSF.Screenplay.SpecFlow/CSF.Screenplay.SpecFlow.csproj b/CSF.Screenplay.SpecFlow/CSF.Screenplay.SpecFlow.csproj index 596a4151..daf11377 100644 --- a/CSF.Screenplay.SpecFlow/CSF.Screenplay.SpecFlow.csproj +++ b/CSF.Screenplay.SpecFlow/CSF.Screenplay.SpecFlow.csproj @@ -1,7 +1,8 @@  + + - netstandard2.0;net462 CSF.Screenplay $(MSBuildProjectDirectory)\bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml false @@ -11,7 +12,6 @@ - diff --git a/CSF.Screenplay.WebApis/CSF.Screenplay.WebApis.csproj b/CSF.Screenplay.WebApis/CSF.Screenplay.WebApis.csproj index 96d4e956..05c7b7f5 100644 --- a/CSF.Screenplay.WebApis/CSF.Screenplay.WebApis.csproj +++ b/CSF.Screenplay.WebApis/CSF.Screenplay.WebApis.csproj @@ -1,7 +1,7 @@  - net5.0;netstandard2.0;net462;net8.0 + net5.0;netstandard2.0;net462;net8.0 CSF.Screenplay.WebApis $(MSBuildProjectDirectory)\bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml \ No newline at end of file diff --git a/CSF.Screenplay.JsonToHtmlReport.Template/CSF.Screenplay.JsonToHtmlReport.Template.proj b/CSF.Screenplay.JsonToHtmlReport.Template/CSF.Screenplay.JsonToHtmlReport.Template.proj index 26db3a3f..af4c781f 100644 --- a/CSF.Screenplay.JsonToHtmlReport.Template/CSF.Screenplay.JsonToHtmlReport.Template.proj +++ b/CSF.Screenplay.JsonToHtmlReport.Template/CSF.Screenplay.JsonToHtmlReport.Template.proj @@ -4,6 +4,7 @@ $(MSBuildProjectDirectory)\src $(MSBuildProjectDirectory)\..\CSF.Screenplay.JsonToHtmlReport\template $(OutputPath)\template.html + false @@ -44,4 +45,6 @@ + + diff --git a/CSF.Screenplay.JsonToHtmlReport/CSF.Screenplay.JsonToHtmlReport.csproj b/CSF.Screenplay.JsonToHtmlReport/CSF.Screenplay.JsonToHtmlReport.csproj index 545d8420..e2bc4026 100644 --- a/CSF.Screenplay.JsonToHtmlReport/CSF.Screenplay.JsonToHtmlReport.csproj +++ b/CSF.Screenplay.JsonToHtmlReport/CSF.Screenplay.JsonToHtmlReport.csproj @@ -1,5 +1,7 @@  + + netcoreapp3.1;net462;netstandard2.0;net6.0;net8.0 Exe @@ -10,6 +12,7 @@ false + A tool which produces human-readable HTML-format reports from the JSON-format reports created by CSF.Screenplay diff --git a/CSF.Screenplay.NUnit/CSF.Screenplay.NUnit.csproj b/CSF.Screenplay.NUnit/CSF.Screenplay.NUnit.csproj index 89176107..85753053 100644 --- a/CSF.Screenplay.NUnit/CSF.Screenplay.NUnit.csproj +++ b/CSF.Screenplay.NUnit/CSF.Screenplay.NUnit.csproj @@ -1,12 +1,14 @@  + CSF.Screenplay $(MSBuildProjectDirectory)\bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml false false + A Test Framework Integration for CSF.Screenplay for NUnit 3.6+ diff --git a/CSF.Screenplay.Selenium/CSF.Screenplay.Selenium.csproj b/CSF.Screenplay.Selenium/CSF.Screenplay.Selenium.csproj index 2e14713d..c387fd6d 100644 --- a/CSF.Screenplay.Selenium/CSF.Screenplay.Selenium.csproj +++ b/CSF.Screenplay.Selenium/CSF.Screenplay.Selenium.csproj @@ -1,10 +1,12 @@  + CSF.Screenplay.Selenium $(MSBuildProjectDirectory)\bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + An Extension for CSF.Screenplay providing Abilities & Performables for Selenium WebDriver 4.0+ diff --git a/CSF.Screenplay.SpecFlow/CSF.Screenplay.SpecFlow.csproj b/CSF.Screenplay.SpecFlow/CSF.Screenplay.SpecFlow.csproj index daf11377..2e431ff1 100644 --- a/CSF.Screenplay.SpecFlow/CSF.Screenplay.SpecFlow.csproj +++ b/CSF.Screenplay.SpecFlow/CSF.Screenplay.SpecFlow.csproj @@ -1,6 +1,7 @@  + CSF.Screenplay @@ -8,6 +9,7 @@ false false CSF.Screenplay.SpecFlowPlugin + A Test Framework Integration for CSF.Screenplay for the legacy SpecFlow 3.4.3+ (recommendation: Switch to Reqnroll) diff --git a/CSF.Screenplay.WebApis/CSF.Screenplay.WebApis.csproj b/CSF.Screenplay.WebApis/CSF.Screenplay.WebApis.csproj index 05c7b7f5..7117f640 100644 --- a/CSF.Screenplay.WebApis/CSF.Screenplay.WebApis.csproj +++ b/CSF.Screenplay.WebApis/CSF.Screenplay.WebApis.csproj @@ -1,5 +1,7 @@  + + net5.0;netstandard2.0;net462;net8.0 CSF.Screenplay.WebApis @@ -7,6 +9,7 @@ false + An Extension for CSF.Screenplay providing Abilities & Performables for interacting with HTTP web API endpoints diff --git a/CSF.Screenplay/CSF.Screenplay.csproj b/CSF.Screenplay/CSF.Screenplay.csproj index 32a7da34..0ee09161 100644 --- a/CSF.Screenplay/CSF.Screenplay.csproj +++ b/CSF.Screenplay/CSF.Screenplay.csproj @@ -1,10 +1,12 @@  + CSF.Screenplay $(MSBuildProjectDirectory)\bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + The core CSF.Screenplay framework package diff --git a/Tests/CSF.Screenplay.Selenium.TestWebapp/CSF.Screenplay.Selenium.TestWebapp.csproj b/Tests/CSF.Screenplay.Selenium.TestWebapp/CSF.Screenplay.Selenium.TestWebapp.csproj index 96046e66..8274139a 100644 --- a/Tests/CSF.Screenplay.Selenium.TestWebapp/CSF.Screenplay.Selenium.TestWebapp.csproj +++ b/Tests/CSF.Screenplay.Selenium.TestWebapp/CSF.Screenplay.Selenium.TestWebapp.csproj @@ -4,6 +4,8 @@ disable + false + false diff --git a/Tools/TestTfm.props b/Tools/TestTfm.props index 10e61dfa..2013ec81 100644 --- a/Tools/TestTfm.props +++ b/Tools/TestTfm.props @@ -1,7 +1,6 @@ - net8.0 - $(TfmForTests) + net8.0 enable diff --git a/Tools/Version.props b/Tools/Version.props new file mode 100644 index 00000000..60332ca1 --- /dev/null +++ b/Tools/Version.props @@ -0,0 +1,17 @@ + + + craigfowler + MIT + https://csf-dev.github.io/CSF.Screenplay/ + https://github.com/csf-dev/CSF.Screenplay/ + 0 + 2.0.0 + dev.$(BuildNumber) + $(VersionPrefix)-$(VersionSuffix) + $(VersionPrefix) + $(VersionPrefix).$(BuildNumber) + $(AssemblyVersion) + $(Version)+commit$(SourceRevisionId) + + + \ No newline at end of file From 2d0393ae03ad6ab4be2e969aab04e8c007dde1be Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 12:13:00 +0000 Subject: [PATCH 23/34] WIP #248 - Another attempt to fix tests --- .github/workflows/dotnetCi.yml | 7 ++++--- Tools/TestTfm.props | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index d289ec10..94e2b3a6 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -94,7 +94,7 @@ jobs: projNameArray=(${proj//// }) projName=${projNameArray[1]} assemblyPath=$proj/bin/$Configuration/$Tfm/$projName.dll - coverlet "$assemblyPath" --target "dotnet" --targetargs "test $proj -c $Configuration --no-build --logger:nunit --test-adapter-path:." -f=opencover -o="TestResults/$projName.opencover.xml" + coverlet "$assemblyPath" --target "dotnet" --targetargs "test $proj -c $Configuration -p:TargetFrameworks=$Tfm --logger:nunit --test-adapter-path:." -f=opencover -o="TestResults/$projName.opencover.xml" if [ $? -ne 0 ] then echo "failures=true" >> $GITHUB_OUTPUT @@ -118,7 +118,7 @@ jobs: run: dotnet sonarscanner end /d:sonar.token=${{ env.SonarCloudSecretKey }} - name: Gracefully stop Xvfb - run: kill $(jobs -l | grep Xvfb | cut -d ' ' -f 2) + run: killall Xvfb continue-on-error: true - name: Upload test results artifacts uses: actions/upload-artifact@v4 @@ -131,12 +131,13 @@ jobs: name: Screenplay JSON reports path: Tests/**/ScreenplayReport_*.json - name: Convert Screenplay reports to HTML + continue-on-error: true run: | for report in Tests/**/ScreenplayReport_*.json do reportDir=$(dirname "$report") outputFile="$reportDir/ScreenplayReport.html" - dotnet run --no-build -p:TargetFrameworks=$Tfm --project CSF.Screenplay.JsonToHtmlReport --ReportPath "$report" --OutputPath $outputFile + dotnet run --no-build --framework $Tfm --project CSF.Screenplay.JsonToHtmlReport --ReportPath "$report" --OutputPath $outputFile done - name: Upload Screenplay HTML report artifact uses: actions/upload-artifact@v4 diff --git a/Tools/TestTfm.props b/Tools/TestTfm.props index 2013ec81..70278cc9 100644 --- a/Tools/TestTfm.props +++ b/Tools/TestTfm.props @@ -3,5 +3,4 @@ net8.0 enable - \ No newline at end of file From 3b2b6e5c12373e1573e4cf8ef16ad552ea307513 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 12:18:42 +0000 Subject: [PATCH 24/34] Rename CI job and add docco --- .github/workflows/dotnetCi.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 94e2b3a6..2f04f260 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -8,7 +8,22 @@ on: jobs: - buildAndRunBasicTests: + # Summary: + # + # * Installs and configures the environment + # * Builds the solution with SonarScanner analysis + # * In Debug configuration + # * For just one TFM (typically the latest LTS .NET release) + # * Runs all .NET and JS tests + # * In Debug configuration (.NET tests) + # * Producing code coverage reports, consumed by SonarScanner + # * For just one TFM (typically the latest LTS .NET release) + # * WebDriver-based tests use a locally-running Chrome browser ONLY + # * Packages test results as build artifacts + # * Builds & packs the solution in Release configuration + # * Uploads the Release config packages as build artifacts + + build_test_and_pack: runs-on: ubuntu-slim env: From 25be2a81c73e35add1e433d9654784a538097f5f Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 12:28:51 +0000 Subject: [PATCH 25/34] WIP #248 - Another attempt to fix the tests Basically, going back to how it used to be in commit d67f6ae3311d3522d1ad8a20769908ad8008ab0e --- .github/workflows/dotnetCi.yml | 2 +- .../CSF.Screenplay.NUnit.Tests.csproj | 4 ++-- .../CSF.Screenplay.Selenium.Tests.csproj | 4 ++-- .../CSF.Screenplay.SpecFlow.Tests.csproj | 4 ++-- Tests/CSF.Screenplay.Tests/CSF.Screenplay.Tests.csproj | 4 ++-- Tools/TestTfm.props | 6 ------ 6 files changed, 9 insertions(+), 15 deletions(-) delete mode 100644 Tools/TestTfm.props diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 2f04f260..9082b755 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -109,7 +109,7 @@ jobs: projNameArray=(${proj//// }) projName=${projNameArray[1]} assemblyPath=$proj/bin/$Configuration/$Tfm/$projName.dll - coverlet "$assemblyPath" --target "dotnet" --targetargs "test $proj -c $Configuration -p:TargetFrameworks=$Tfm --logger:nunit --test-adapter-path:." -f=opencover -o="TestResults/$projName.opencover.xml" + coverlet "$assemblyPath" --target "dotnet" --targetargs "test $proj -c $Configuration --no-build --logger:nunit --test-adapter-path:." -f=opencover -o="TestResults/$projName.opencover.xml" if [ $? -ne 0 ] then echo "failures=true" >> $GITHUB_OUTPUT diff --git a/Tests/CSF.Screenplay.NUnit.Tests/CSF.Screenplay.NUnit.Tests.csproj b/Tests/CSF.Screenplay.NUnit.Tests/CSF.Screenplay.NUnit.Tests.csproj index 4f0691f7..92ac3837 100644 --- a/Tests/CSF.Screenplay.NUnit.Tests/CSF.Screenplay.NUnit.Tests.csproj +++ b/Tests/CSF.Screenplay.NUnit.Tests/CSF.Screenplay.NUnit.Tests.csproj @@ -1,8 +1,8 @@ - - + net8.0 + enable false true CSF.Screenplay diff --git a/Tests/CSF.Screenplay.Selenium.Tests/CSF.Screenplay.Selenium.Tests.csproj b/Tests/CSF.Screenplay.Selenium.Tests/CSF.Screenplay.Selenium.Tests.csproj index 1d9e7694..00908a6b 100644 --- a/Tests/CSF.Screenplay.Selenium.Tests/CSF.Screenplay.Selenium.Tests.csproj +++ b/Tests/CSF.Screenplay.Selenium.Tests/CSF.Screenplay.Selenium.Tests.csproj @@ -1,8 +1,8 @@ - - + net8.0 + enable false true CSF.Screenplay.Selenium diff --git a/Tests/CSF.Screenplay.SpecFlow.Tests/CSF.Screenplay.SpecFlow.Tests.csproj b/Tests/CSF.Screenplay.SpecFlow.Tests/CSF.Screenplay.SpecFlow.Tests.csproj index 01ebfdc7..4be86dfd 100644 --- a/Tests/CSF.Screenplay.SpecFlow.Tests/CSF.Screenplay.SpecFlow.Tests.csproj +++ b/Tests/CSF.Screenplay.SpecFlow.Tests/CSF.Screenplay.SpecFlow.Tests.csproj @@ -1,8 +1,8 @@ - - + net8.0 + enable false true CSF.Screenplay diff --git a/Tests/CSF.Screenplay.Tests/CSF.Screenplay.Tests.csproj b/Tests/CSF.Screenplay.Tests/CSF.Screenplay.Tests.csproj index 57aab935..09f16731 100644 --- a/Tests/CSF.Screenplay.Tests/CSF.Screenplay.Tests.csproj +++ b/Tests/CSF.Screenplay.Tests/CSF.Screenplay.Tests.csproj @@ -1,8 +1,8 @@ - - + net8.0 + enable false true CSF.Screenplay diff --git a/Tools/TestTfm.props b/Tools/TestTfm.props deleted file mode 100644 index 70278cc9..00000000 --- a/Tools/TestTfm.props +++ /dev/null @@ -1,6 +0,0 @@ - - - net8.0 - enable - - \ No newline at end of file From f82349356c2ef4c000dae03fb1bf377b7c30b1da Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 12:34:52 +0000 Subject: [PATCH 26/34] Fix a missing TFM Also, provide a human readable job name --- .github/workflows/dotnetCi.yml | 1 + .../CSF.Screenplay.Selenium.TestWebapp.csproj | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 9082b755..97f8232d 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -24,6 +24,7 @@ jobs: # * Uploads the Release config packages as build artifacts build_test_and_pack: + name: Build, test & package runs-on: ubuntu-slim env: diff --git a/Tests/CSF.Screenplay.Selenium.TestWebapp/CSF.Screenplay.Selenium.TestWebapp.csproj b/Tests/CSF.Screenplay.Selenium.TestWebapp/CSF.Screenplay.Selenium.TestWebapp.csproj index 8274139a..a946f927 100644 --- a/Tests/CSF.Screenplay.Selenium.TestWebapp/CSF.Screenplay.Selenium.TestWebapp.csproj +++ b/Tests/CSF.Screenplay.Selenium.TestWebapp/CSF.Screenplay.Selenium.TestWebapp.csproj @@ -1,8 +1,8 @@ - - + net8.0 + enable disable false false From 7f4109e2e862d5ae2ea3f7a3691bd4463b8565ae Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 12:57:12 +0000 Subject: [PATCH 27/34] WIP #248 - Give up on building in one TFM I can't seem to make this work with tests, so I'm going to abandon the idea. It was a nice-to-have not important. --- .github/workflows/dotnetCi.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 97f8232d..d05c8e6c 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -13,11 +13,9 @@ jobs: # * Installs and configures the environment # * Builds the solution with SonarScanner analysis # * In Debug configuration - # * For just one TFM (typically the latest LTS .NET release) # * Runs all .NET and JS tests # * In Debug configuration (.NET tests) # * Producing code coverage reports, consumed by SonarScanner - # * For just one TFM (typically the latest LTS .NET release) # * WebDriver-based tests use a locally-running Chrome browser ONLY # * Packages test results as build artifacts # * Builds & packs the solution in Release configuration @@ -68,7 +66,7 @@ jobs: - name: Install GUI packages so Chrome may run run: | sudo apt-get update - sudo apt install -y xorg xvfb gtk2-engines-pixbuf dbus-x11 xfonts-base xfonts-100dpi xfonts-75dpi xfonts-cyrillic xfonts-scalable + sudo apt install -y xorg xvfb gtk2-engines-pixbuf dbus-x11 xfonts-base xfonts-100dpi xfonts-75dpi xfonts-cyrillic xfonts-scalable psmisc # Environment setup pre-build @@ -99,8 +97,8 @@ jobs: /d:${{ env.BranchParam }}=${{ env.BranchName }} ${{ env.PullRequestParam }} /d:sonar.javascript.lcov.reportPaths=CSF.Screenplay.JsonToHtmlReport.Template/src/TestResults/lcov.info /s:$PWD/.sonarqube-analysisproperties.xml - - name: Build the solution (one TFM only for performance) - run: dotnet build -c ${{ env.Configuration }} --no-incremental -p:TargetFrameworks=${{ env.Tfm }} + - name: Build the solution + run: dotnet build -c ${{ env.Configuration }} --no-incremental - name: Run .NET tests with coverage id: dotnet_tests continue-on-error: true From f3d9d3140dce323741813285b642ba9ab354cafe Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 13:00:27 +0000 Subject: [PATCH 28/34] #248 - Update TFMs for all non-test projects --- Tools/MultiTargeting.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/MultiTargeting.props b/Tools/MultiTargeting.props index c8b98cea..71572409 100644 --- a/Tools/MultiTargeting.props +++ b/Tools/MultiTargeting.props @@ -1,8 +1,8 @@ net462 - net8.0 - netstandard2.0;netstandard2.1;$(DotNetFrameworkLegacy);$(DotNetLatestLts) + net8.0 + netstandard2.0;netstandard2.1;$(DotNetFrameworkLegacy);$(DotNetLatestLts) From 25a93bcaa2c34598e90213720c8cce2f63ec22f8 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 13:20:13 +0000 Subject: [PATCH 29/34] Change the way HTML reports are produced --- .github/workflows/dotnetCi.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index d05c8e6c..75f1a8f9 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -147,11 +147,11 @@ jobs: - name: Convert Screenplay reports to HTML continue-on-error: true run: | - for report in Tests/**/ScreenplayReport_*.json + for report in $(find Tests/ -type f -name "ScreenplayReport_*.json") do reportDir=$(dirname "$report") outputFile="$reportDir/ScreenplayReport.html" - dotnet run --no-build --framework $Tfm --project CSF.Screenplay.JsonToHtmlReport --ReportPath "$report" --OutputPath $outputFile + dotnet run --no-build --framework $Tfm --project CSF.Screenplay.JsonToHtmlReport --ReportPath "$report" --OutputPath "$outputFile" done - name: Upload Screenplay HTML report artifact uses: actions/upload-artifact@v4 From fef4184da89b2c74b10c2e58831904aab7c41605 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 13:29:50 +0000 Subject: [PATCH 30/34] Add a step to build & package docs This packages them as an artifact, so that they may be reused --- .github/workflows/dotnetCi.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 75f1a8f9..81ddf0c7 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -166,6 +166,8 @@ jobs: # Build the apps in release mode and publish artifacts + - name: Clean the solution ahead of building in release config + run: dotnet clean - name: Build, in release configuration run: dotnet pack -p:VersionSuffix=$VersionSuffix -o packages - name: Upload build result artifacts @@ -173,9 +175,13 @@ jobs: with: name: Build results (NuGet) path: packages/*.nupkg - - # buildDocs: - # TODO: Build the docco site and package the result as an artifact, don't publish it + - name: Build docs website + run: dotnet build -c Docs + - name: Upload docs website artifact + uses: actions/upload-artifact@v4 + with: + name: Docs website + path: docs/**/* # publishDocs: # TODO: Take the docco site artifact and publish it to master From 75a48528e16253eeef05300746e725e8713e90de Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 14:05:57 +0000 Subject: [PATCH 31/34] Update report converter to stop cleanly --- .../ReportConverterApplication.cs | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/CSF.Screenplay.JsonToHtmlReport/ReportConverterApplication.cs b/CSF.Screenplay.JsonToHtmlReport/ReportConverterApplication.cs index 538d1d47..9bc3ce67 100644 --- a/CSF.Screenplay.JsonToHtmlReport/ReportConverterApplication.cs +++ b/CSF.Screenplay.JsonToHtmlReport/ReportConverterApplication.cs @@ -11,34 +11,45 @@ namespace CSF.Screenplay.JsonToHtmlReport /// /// An application/background service that begins the JSON to HTML report conversion process. /// - public class ReportConverterApplication : BackgroundService + public class ReportConverterApplication : IHostedService { readonly IOptions options; readonly IConvertsReportJsonToHtml reportConverter; + readonly IHostApplicationLifetime lifetime; /// /// Initializes a new instance of the class. /// /// The options for performing the conversion. /// The report converter instance to use for conversion. + /// The application lifetime public ReportConverterApplication(IOptions options, - IConvertsReportJsonToHtml reportConverter) + IConvertsReportJsonToHtml reportConverter, + IHostApplicationLifetime lifetime) { - this.options = options ?? throw new System.ArgumentNullException(nameof(options)); - this.reportConverter = reportConverter ?? throw new System.ArgumentNullException(nameof(reportConverter)); + this.options = options ?? throw new ArgumentNullException(nameof(options)); + this.reportConverter = reportConverter ?? throw new ArgumentNullException(nameof(reportConverter)); + this.lifetime = lifetime ?? throw new ArgumentNullException(nameof(lifetime)); } /// - /// Executes the background service operation. + /// Executes the application, to perform its work. /// - /// A token that can be used to stop the operation. - /// A task that represents the asynchronous operation. - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + /// A cancellation token + /// A task + public async Task StartAsync(CancellationToken cancellationToken) { await reportConverter.ConvertAsync(options.Value); Console.WriteLine("Conversion complete; HTML report available at {0}", options.Value.OutputPath); - Environment.Exit(0); + lifetime.StopApplication(); } + + /// + /// Unused, always returns a completed task. + /// + /// A cancellation token + /// A task + public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } } From 36eb621b6a7f43735cea4a4abc31a0c3df832d80 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 14:18:46 +0000 Subject: [PATCH 32/34] Fix build of docs website --- .github/workflows/dotnetCi.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/dotnetCi.yml b/.github/workflows/dotnetCi.yml index 81ddf0c7..ea191c6d 100644 --- a/.github/workflows/dotnetCi.yml +++ b/.github/workflows/dotnetCi.yml @@ -56,6 +56,8 @@ jobs: run: dotnet tool install --global dotnet-sonarscanner - name: Install Coverlet console run: dotnet tool install --global coverlet.console + - name: Install DocFX + run: dotnet tool install --global docfx - name: Install Node.js for building JSON-to-HTML report converter uses: actions/setup-node@v6.2.0 - name: Install Java JDK for SonarScanner From 493e24aebb534dd367fa6f763298f34184b2592e Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 14:38:08 +0000 Subject: [PATCH 33/34] Update docfx build process Attempting to get this working on Linux --- CSF.Screenplay.Docs/CSF.Screenplay.Docs.proj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CSF.Screenplay.Docs/CSF.Screenplay.Docs.proj b/CSF.Screenplay.Docs/CSF.Screenplay.Docs.proj index 61a4b889..722f3af8 100644 --- a/CSF.Screenplay.Docs/CSF.Screenplay.Docs.proj +++ b/CSF.Screenplay.Docs/CSF.Screenplay.Docs.proj @@ -3,7 +3,7 @@ $(MSBuildProjectDirectory)\..\docs\ $(MSBuildProjectDirectory)\api docfx.json - docfx.exe + docfx From 5863619841c15c94d6a1f4f86fcf8cabf50f4886 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 17 Jan 2026 16:26:18 +0000 Subject: [PATCH 34/34] Complete #248 - Add docs publishing from master --- .github/workflows/publishDocsWebsite.yml | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/publishDocsWebsite.yml diff --git a/.github/workflows/publishDocsWebsite.yml b/.github/workflows/publishDocsWebsite.yml new file mode 100644 index 00000000..72fd0edf --- /dev/null +++ b/.github/workflows/publishDocsWebsite.yml @@ -0,0 +1,46 @@ +name: Update docs website + +on: + push: + branches: [ "master" ] + +jobs: + + # This job builds the documentation website + # and the commits that to the master branch, + # which will result in replacing the currently published site + + build_and_commit: + name: Build & commit docs website + runs-on: ubuntu-slim + + env: + DotnetVersion: 8.0.x + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Add .NET global tools location to PATH + run: echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH" + - name: Install .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.DotnetVersion }} + - name: Install DocFX + run: dotnet tool install --global docfx + - name: Remove old docs + run: dotnet clean CSF.Screenplay.Docs + - name: Build new docs + run: dotnet build -c Docs CSF.Screenplay.Docs + - name: Add & Commit + uses: EndBug/add-and-commit@v9.1.4 + with: + add: -A docs/ + default_author: github_actor + committer_name: Github Actions Workflow (bot) + committer_email: github-actions-workflow@bots.noreply.github.com + fetch: true + message: Publish updated documentation website + push: origin master --force + +