From 91d39b8cc3421868c8e664d298bf5efc312d2ccc Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Sat, 21 Feb 2026 09:44:50 -0800 Subject: [PATCH 1/7] Update .npmrc files to use npmjs.org registry WIP Fix --- .github/workflows/Build-Test-And-Deploy.yaml | 21 +++--- .../EditorTests.cs | 1 + .../IntegrationTestFactAttribute.cs | 66 +++++++++---------- ...icrosoft.TryDotNet.IntegrationTests.csproj | 5 +- .../TryDotNetJsIntegrationTests.cs | 1 + .../WasmRunnerTests.cs | 1 + src/microsoft-learn-mock/.npmrc | 2 +- src/microsoft-trydotnet-editor/.npmrc | 2 +- src/microsoft-trydotnet-styles/.npmrc | 2 +- src/microsoft-trydotnet/.npmrc | 2 +- 10 files changed, 55 insertions(+), 48 deletions(-) diff --git a/.github/workflows/Build-Test-And-Deploy.yaml b/.github/workflows/Build-Test-And-Deploy.yaml index e80174049..9cdb60700 100644 --- a/.github/workflows/Build-Test-And-Deploy.yaml +++ b/.github/workflows/Build-Test-And-Deploy.yaml @@ -35,7 +35,7 @@ jobs: - name: Run .NET Tests id: run-dotnet-tests - run: dotnet test --no-build --configuration Release --blame-hang-timeout 15m --blame-hang-dump-type full -l trx --results-directory ./TestResults + run: dotnet test --no-build --configuration Release --blame-hang-timeout 15m --blame-hang-dump-type full -l trx --results-directory ./TestResults --filter TestType!=Integration env: POCKETLOGGER_LOG_PATH: ${{ github.workspace }}/artifacts/logs/pocketlogger.log @@ -93,7 +93,7 @@ jobs: - name: Run .NET Tests id: run-dotnet-tests - run: dotnet test --no-build --configuration Release --blame-hang-timeout 15m --blame-hang-dump-type full -l trx --results-directory ./TestResults + run: dotnet test --no-build --configuration Release --blame-hang-timeout 15m --blame-hang-dump-type full -l trx --results-directory ./TestResults --filter TestType!=Integration env: POCKETLOGGER_LOG_PATH: ${{ github.workspace }}/artifacts/logs/pocketlogger.log @@ -106,11 +106,12 @@ jobs: artifact-name: 'windows-test-playlists' integration-tests: - # Integration tests use Playwright and are gated behind RunIntegrationTests=true. - # IntegrationTestFactAttribute explicitly skips these tests on Linux, so a - # Windows runner is required to actually execute them. - runs-on: windows-latest + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + browser: [chromium, firefox, webkit] + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v6 @@ -122,7 +123,7 @@ jobs: - name: Run .NET Integration Tests id: run-dotnet-integration-tests - run: dotnet test --no-build --configuration Release --blame-hang-timeout 15m --blame-hang-dump-type full -l trx --results-directory ./TestResults + run: dotnet test --no-build --configuration Release --blame-hang-timeout 15m --blame-hang-dump-type full -l trx --results-directory ./TestResults --filter TestType=Integration env: RunIntegrationTests: true POCKETLOGGER_LOG_PATH: ${{ github.workspace }}/artifacts/logs/pocketlogger.log @@ -224,8 +225,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ vars.PRODCONTAINER_REGISTRY }} - username: ${{ secrets.ESSENTIALCSHARP_CLIENT_ID }} - password: ${{ secrets.ESSENTIALCSHARP_CLIENT_SECRET }} + username: ${{ secrets.ESSENTIALCSHARP_ACR_USERNAME }} + password: ${{ secrets.ESSENTIALCSHARP_ACR_PASSWORD }} - name: Push Image to Container Registry run: docker push --all-tags ${{ vars.PRODCONTAINER_REGISTRY }}/try @@ -242,4 +243,4 @@ jobs: with: inlineScript: | az config set extension.use_dynamic_install=yes_without_prompt - az containerapp up -n $CONTAINER_APP_NAME -g $RESOURCEGROUP --image $REGISTRY_URL/try:${{ github.sha }} --environment $CONTAINER_APP_ENVIRONMENT --registry-server $REGISTRY_URL --ingress external --target-port 80 --debug + az containerapp up -n $CONTAINER_APP_NAME -g $RESOURCEGROUP --image $REGISTRY_URL/try:${{ github.sha }} --environment $CONTAINER_APP_ENVIRONMENT --registry-server $REGISTRY_URL --ingress external --registry-username $ACR_USERNAME --registry-password $ACR_PASSWORD --target-port 80 --debug diff --git a/src/Microsoft.TryDotNet.IntegrationTests/EditorTests.cs b/src/Microsoft.TryDotNet.IntegrationTests/EditorTests.cs index 0b40edfaa..68ad4f676 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/EditorTests.cs +++ b/src/Microsoft.TryDotNet.IntegrationTests/EditorTests.cs @@ -15,6 +15,7 @@ namespace Microsoft.TryDotNet.IntegrationTests; [LogToPocketLogger(FileNameEnvironmentVariable = "POCKETLOGGER_LOG_PATH")] +[Trait("TestType", "Integration")] public class EditorTests : PlaywrightTestBase { public EditorTests(IntegratedServicesFixture services, ITestOutputHelper output) : base(services, output) diff --git a/src/Microsoft.TryDotNet.IntegrationTests/IntegrationTestFactAttribute.cs b/src/Microsoft.TryDotNet.IntegrationTests/IntegrationTestFactAttribute.cs index 995adfc48..f8322eaf0 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/IntegrationTestFactAttribute.cs +++ b/src/Microsoft.TryDotNet.IntegrationTests/IntegrationTestFactAttribute.cs @@ -1,33 +1,33 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Runtime.InteropServices; - -using Xunit; - -namespace Microsoft.TryDotNet.IntegrationTests -{ - internal class IntegrationTestFactAttribute : FactAttribute - { - private const string EnvironmentVariableName = "RunIntegrationTests"; - - public IntegrationTestFactAttribute(string? skipReason = null) - { - var variableValue = Environment.GetEnvironmentVariable(EnvironmentVariableName) ?? "false"; - switch (variableValue.ToLowerInvariant()) - { - case "1": - case "true": - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - Skip = string.IsNullOrWhiteSpace(skipReason) ? "Ignored on Linux" : skipReason; - } - break; - default: - Skip = $"Skipping integration tests because environment variable '{EnvironmentVariableName}' was not 'true' or '1'."; - break; - } - } - } -} +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Runtime.InteropServices; + +using Xunit; + +namespace Microsoft.TryDotNet.IntegrationTests +{ + internal class IntegrationTestFactAttribute : FactAttribute + { + private const string EnvironmentVariableName = "RunIntegrationTests"; + + public IntegrationTestFactAttribute(string? skipReason = null) + { + var variableValue = Environment.GetEnvironmentVariable(EnvironmentVariableName) ?? "false"; + switch (variableValue.ToLowerInvariant()) + { + case "1": + case "true": + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Skip = string.IsNullOrWhiteSpace(skipReason) ? "Ignored on Linux" : skipReason; + } + break; + default: + Skip = $"Skipping integration tests because environment variable '{EnvironmentVariableName}' was not 'true' or '1'."; + break; + } + } + } +} diff --git a/src/Microsoft.TryDotNet.IntegrationTests/Microsoft.TryDotNet.IntegrationTests.csproj b/src/Microsoft.TryDotNet.IntegrationTests/Microsoft.TryDotNet.IntegrationTests.csproj index 2d64d056f..b32f2d379 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/Microsoft.TryDotNet.IntegrationTests.csproj +++ b/src/Microsoft.TryDotNet.IntegrationTests/Microsoft.TryDotNet.IntegrationTests.csproj @@ -10,6 +10,10 @@ embedded + + + + @@ -71,6 +75,5 @@ public static class BuildProperties - \ No newline at end of file diff --git a/src/Microsoft.TryDotNet.IntegrationTests/TryDotNetJsIntegrationTests.cs b/src/Microsoft.TryDotNet.IntegrationTests/TryDotNetJsIntegrationTests.cs index a962e35ed..c85d64775 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/TryDotNetJsIntegrationTests.cs +++ b/src/Microsoft.TryDotNet.IntegrationTests/TryDotNetJsIntegrationTests.cs @@ -14,6 +14,7 @@ namespace Microsoft.TryDotNet.IntegrationTests; [LogToPocketLogger(FileNameEnvironmentVariable = "POCKETLOGGER_LOG_PATH")] +[Trait("TestType", "Integration")] public class TryDotNetJsIntegrationTests : PlaywrightTestBase { public TryDotNetJsIntegrationTests(IntegratedServicesFixture services, ITestOutputHelper output) : base(services, output) diff --git a/src/Microsoft.TryDotNet.IntegrationTests/WasmRunnerTests.cs b/src/Microsoft.TryDotNet.IntegrationTests/WasmRunnerTests.cs index 1da87a7b5..81d4f4c6c 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/WasmRunnerTests.cs +++ b/src/Microsoft.TryDotNet.IntegrationTests/WasmRunnerTests.cs @@ -12,6 +12,7 @@ namespace Microsoft.TryDotNet.IntegrationTests; [LogToPocketLogger(FileNameEnvironmentVariable = "POCKETLOGGER_LOG_PATH")] +[Trait("TestType", "Integration")] public class WasmRunnerTests : PlaywrightTestBase { public WasmRunnerTests(IntegratedServicesFixture services, ITestOutputHelper output) : base(services, output) diff --git a/src/microsoft-learn-mock/.npmrc b/src/microsoft-learn-mock/.npmrc index 0beb91c5e..a6a64c110 100644 --- a/src/microsoft-learn-mock/.npmrc +++ b/src/microsoft-learn-mock/.npmrc @@ -1 +1 @@ -;registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ +registry= https://registry.npmjs.org/ diff --git a/src/microsoft-trydotnet-editor/.npmrc b/src/microsoft-trydotnet-editor/.npmrc index 89c3674b2..a46b43a42 100644 --- a/src/microsoft-trydotnet-editor/.npmrc +++ b/src/microsoft-trydotnet-editor/.npmrc @@ -1,2 +1,2 @@ @microsoft:registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/npm/registry/ -;registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ +registry= https://registry.npmjs.org/ diff --git a/src/microsoft-trydotnet-styles/.npmrc b/src/microsoft-trydotnet-styles/.npmrc index 0beb91c5e..a6a64c110 100644 --- a/src/microsoft-trydotnet-styles/.npmrc +++ b/src/microsoft-trydotnet-styles/.npmrc @@ -1 +1 @@ -;registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ +registry= https://registry.npmjs.org/ diff --git a/src/microsoft-trydotnet/.npmrc b/src/microsoft-trydotnet/.npmrc index 89c3674b2..a46b43a42 100644 --- a/src/microsoft-trydotnet/.npmrc +++ b/src/microsoft-trydotnet/.npmrc @@ -1,2 +1,2 @@ @microsoft:registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/npm/registry/ -;registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ +registry= https://registry.npmjs.org/ From b6c25856fa20913a3496ddc3fce1a192e0945e14 Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Sat, 21 Feb 2026 10:27:32 -0800 Subject: [PATCH 2/7] Updates --- .github/actions/setup-dotnet/action.yml | 6 +++++- .github/workflows/Build-Test-And-Deploy.yaml | 7 ++++++- .../IntegrationTestFactAttribute.cs | 5 +---- .../PlaywrightSession.cs | 14 +++++++++++--- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/.github/actions/setup-dotnet/action.yml b/.github/actions/setup-dotnet/action.yml index a344a1538..055ef2910 100644 --- a/.github/actions/setup-dotnet/action.yml +++ b/.github/actions/setup-dotnet/action.yml @@ -5,6 +5,10 @@ inputs: description: 'Whether to run dotnet build after restore' required: false default: 'true' + configuration: + description: 'What configuration to run (e.g., Release or Debug)' + required: false + default: 'Release' runs: using: 'composite' steps: @@ -31,4 +35,4 @@ runs: - name: Build with dotnet if: inputs.build == 'true' shell: bash - run: dotnet build -p:ContinuousIntegrationBuild=True --configuration Release --no-restore + run: dotnet build -p:ContinuousIntegrationBuild=True --configuration ${{ inputs.configuration }} --no-restore diff --git a/.github/workflows/Build-Test-And-Deploy.yaml b/.github/workflows/Build-Test-And-Deploy.yaml index 9cdb60700..cc5c318fa 100644 --- a/.github/workflows/Build-Test-And-Deploy.yaml +++ b/.github/workflows/Build-Test-And-Deploy.yaml @@ -120,10 +120,15 @@ jobs: - name: Set up .NET environment uses: ./.github/actions/setup-dotnet + with: + configuration: Debug + + - name: Ensure browsers are installed + run: pwsh bin/Debug/net10.0/playwright.ps1 install --with-deps - name: Run .NET Integration Tests id: run-dotnet-integration-tests - run: dotnet test --no-build --configuration Release --blame-hang-timeout 15m --blame-hang-dump-type full -l trx --results-directory ./TestResults --filter TestType=Integration + run: dotnet test --no-build --configuration Debug --blame-hang-timeout 15m --blame-hang-dump-type full -l trx --results-directory ./TestResults --filter TestType=Integration -- Playwright.BrowserName=${{ matrix.browser }} env: RunIntegrationTests: true POCKETLOGGER_LOG_PATH: ${{ github.workspace }}/artifacts/logs/pocketlogger.log diff --git a/src/Microsoft.TryDotNet.IntegrationTests/IntegrationTestFactAttribute.cs b/src/Microsoft.TryDotNet.IntegrationTests/IntegrationTestFactAttribute.cs index f8322eaf0..04bc7efb7 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/IntegrationTestFactAttribute.cs +++ b/src/Microsoft.TryDotNet.IntegrationTests/IntegrationTestFactAttribute.cs @@ -19,10 +19,7 @@ public IntegrationTestFactAttribute(string? skipReason = null) { case "1": case "true": - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - Skip = string.IsNullOrWhiteSpace(skipReason) ? "Ignored on Linux" : skipReason; - } + // Run tests break; default: Skip = $"Skipping integration tests because environment variable '{EnvironmentVariableName}' was not 'true' or '1'."; diff --git a/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightSession.cs b/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightSession.cs index a525b54ce..01ec154a6 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightSession.cs +++ b/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightSession.cs @@ -20,9 +20,9 @@ public PlaywrightSession(IPlaywright playwright, IBrowser browser) public IBrowser Browser { get; } - public static async Task StartAsync() + public static async Task StartAsync(string browserName = null) { - var exitCode = Playwright.Program.Main(["install", "chromium"]); + var exitCode = Playwright.Program.Main(["install"]); if (exitCode is not 0) { throw new Exception($"Playwright exited with code {exitCode}"); @@ -37,7 +37,15 @@ public static async Task StartAsync() browserTypeLaunchOptions.Headless = false; } - var browser = await session.Chromium.LaunchAsync(browserTypeLaunchOptions).Timeout(TimeSpan.FromMinutes(5), "Timeout launching browser"); + var selectedBrowser = (browserName ?? Environment.GetEnvironmentVariable("Playwright.BrowserName") ?? "chromium").ToLowerInvariant(); + + IBrowser browser = selectedBrowser switch + { + "chromium" => await session.Chromium.LaunchAsync(browserTypeLaunchOptions).Timeout(TimeSpan.FromMinutes(5), "Timeout launching browser"), + "firefox" => await session.Firefox.LaunchAsync(browserTypeLaunchOptions).Timeout(TimeSpan.FromMinutes(5), "Timeout launching browser"), + "webkit" => await session.Webkit.LaunchAsync(browserTypeLaunchOptions).Timeout(TimeSpan.FromMinutes(5), "Timeout launching browser"), + _ => throw new ArgumentException($"Unknown browser '{selectedBrowser}'. Valid values: chromium, firefox, webkit.") + }; return new PlaywrightSession(session, browser); } From 6c8e6ecba183ab963ade194066d9386ef8b9b4c1 Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Sat, 21 Feb 2026 10:31:34 -0800 Subject: [PATCH 3/7] revert --- .github/workflows/Build-Test-And-Deploy.yaml | 6 +++--- src/microsoft-learn-mock/.npmrc | 2 +- src/microsoft-trydotnet-editor/.npmrc | 2 +- src/microsoft-trydotnet-styles/.npmrc | 2 +- src/microsoft-trydotnet/.npmrc | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/Build-Test-And-Deploy.yaml b/.github/workflows/Build-Test-And-Deploy.yaml index cc5c318fa..eb5cdccea 100644 --- a/.github/workflows/Build-Test-And-Deploy.yaml +++ b/.github/workflows/Build-Test-And-Deploy.yaml @@ -230,8 +230,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ vars.PRODCONTAINER_REGISTRY }} - username: ${{ secrets.ESSENTIALCSHARP_ACR_USERNAME }} - password: ${{ secrets.ESSENTIALCSHARP_ACR_PASSWORD }} + username: ${{ secrets.ESSENTIALCSHARP_CLIENT_ID }} + password: ${{ secrets.ESSENTIALCSHARP_CLIENT_SECRET }} - name: Push Image to Container Registry run: docker push --all-tags ${{ vars.PRODCONTAINER_REGISTRY }}/try @@ -248,4 +248,4 @@ jobs: with: inlineScript: | az config set extension.use_dynamic_install=yes_without_prompt - az containerapp up -n $CONTAINER_APP_NAME -g $RESOURCEGROUP --image $REGISTRY_URL/try:${{ github.sha }} --environment $CONTAINER_APP_ENVIRONMENT --registry-server $REGISTRY_URL --ingress external --registry-username $ACR_USERNAME --registry-password $ACR_PASSWORD --target-port 80 --debug + az containerapp up -n $CONTAINER_APP_NAME -g $RESOURCEGROUP --image $REGISTRY_URL/try:${{ github.sha }} --environment $CONTAINER_APP_ENVIRONMENT --registry-server $REGISTRY_URL --ingress external --target-port 80 --debug diff --git a/src/microsoft-learn-mock/.npmrc b/src/microsoft-learn-mock/.npmrc index a6a64c110..0beb91c5e 100644 --- a/src/microsoft-learn-mock/.npmrc +++ b/src/microsoft-learn-mock/.npmrc @@ -1 +1 @@ -registry= https://registry.npmjs.org/ +;registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ diff --git a/src/microsoft-trydotnet-editor/.npmrc b/src/microsoft-trydotnet-editor/.npmrc index a46b43a42..89c3674b2 100644 --- a/src/microsoft-trydotnet-editor/.npmrc +++ b/src/microsoft-trydotnet-editor/.npmrc @@ -1,2 +1,2 @@ @microsoft:registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/npm/registry/ -registry= https://registry.npmjs.org/ +;registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ diff --git a/src/microsoft-trydotnet-styles/.npmrc b/src/microsoft-trydotnet-styles/.npmrc index a6a64c110..0beb91c5e 100644 --- a/src/microsoft-trydotnet-styles/.npmrc +++ b/src/microsoft-trydotnet-styles/.npmrc @@ -1 +1 @@ -registry= https://registry.npmjs.org/ +;registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ diff --git a/src/microsoft-trydotnet/.npmrc b/src/microsoft-trydotnet/.npmrc index a46b43a42..89c3674b2 100644 --- a/src/microsoft-trydotnet/.npmrc +++ b/src/microsoft-trydotnet/.npmrc @@ -1,2 +1,2 @@ @microsoft:registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/npm/registry/ -registry= https://registry.npmjs.org/ +;registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ From b28975ca9a30cdec48afb411f71c82d31b0ec53d Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Sat, 21 Feb 2026 10:40:26 -0800 Subject: [PATCH 4/7] fix --- .github/workflows/Build-Test-And-Deploy.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/Build-Test-And-Deploy.yaml b/.github/workflows/Build-Test-And-Deploy.yaml index eb5cdccea..13eaa0684 100644 --- a/.github/workflows/Build-Test-And-Deploy.yaml +++ b/.github/workflows/Build-Test-And-Deploy.yaml @@ -123,9 +123,6 @@ jobs: with: configuration: Debug - - name: Ensure browsers are installed - run: pwsh bin/Debug/net10.0/playwright.ps1 install --with-deps - - name: Run .NET Integration Tests id: run-dotnet-integration-tests run: dotnet test --no-build --configuration Debug --blame-hang-timeout 15m --blame-hang-dump-type full -l trx --results-directory ./TestResults --filter TestType=Integration -- Playwright.BrowserName=${{ matrix.browser }} From 097e9640acdda60931d413454c66110ef0fe3e75 Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Sat, 21 Feb 2026 10:45:59 -0800 Subject: [PATCH 5/7] updates --- .github/workflows/Build-Test-And-Deploy.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/Build-Test-And-Deploy.yaml b/.github/workflows/Build-Test-And-Deploy.yaml index 13eaa0684..167a9927a 100644 --- a/.github/workflows/Build-Test-And-Deploy.yaml +++ b/.github/workflows/Build-Test-And-Deploy.yaml @@ -107,9 +107,17 @@ jobs: integration-tests: strategy: + fail-fast: false matrix: os: [windows-latest, ubuntu-latest, macos-latest] browser: [chromium, firefox, webkit] + exclude: + - os: windows-latest + browser: webkit + - os: ubuntu-latest + browser: webkit + - os: macos-latest + browser: firefox runs-on: ${{ matrix.os }} steps: From b111c1cd603512ad90e64d1878f2a8aa3645b231 Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Sat, 21 Feb 2026 11:24:02 -0800 Subject: [PATCH 6/7] Updates --- .github/workflows/Build-Test-And-Deploy.yaml | 41 ++++++++++--------- .../IntegratedServicesFixture.cs | 1 + .../PlaywrightSession.cs | 21 ++++++++-- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/.github/workflows/Build-Test-And-Deploy.yaml b/.github/workflows/Build-Test-And-Deploy.yaml index 167a9927a..15c49a55a 100644 --- a/.github/workflows/Build-Test-And-Deploy.yaml +++ b/.github/workflows/Build-Test-And-Deploy.yaml @@ -43,9 +43,9 @@ jobs: if: ${{ steps.run-dotnet-tests.outcome == 'failure' || failure() }} uses: BenjaminMichaelis/trx-to-vsplaylist@v3 with: - trx-file-path: './TestResults/*.trx' - test-outcomes: 'Failed' - artifact-name: 'linux-test-playlists' + trx-file-path: "./TestResults/*.trx" + test-outcomes: "Failed" + artifact-name: "linux-test-playlists" - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -101,23 +101,23 @@ jobs: if: ${{ steps.run-dotnet-tests.outcome == 'failure' || failure() }} uses: BenjaminMichaelis/trx-to-vsplaylist@v3 with: - trx-file-path: './TestResults/*.trx' - test-outcomes: 'Failed' - artifact-name: 'windows-test-playlists' + trx-file-path: "./TestResults/*.trx" + test-outcomes: "Failed" + artifact-name: "windows-test-playlists" integration-tests: strategy: - fail-fast: false - matrix: - os: [windows-latest, ubuntu-latest, macos-latest] - browser: [chromium, firefox, webkit] - exclude: - - os: windows-latest - browser: webkit - - os: ubuntu-latest - browser: webkit - - os: macos-latest - browser: firefox + fail-fast: false + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + browser: [chromium, firefox, webkit] + exclude: + - os: windows-latest + browser: webkit + - os: ubuntu-latest + browser: webkit + - os: macos-latest + browser: firefox runs-on: ${{ matrix.os }} steps: @@ -138,14 +138,15 @@ jobs: RunIntegrationTests: true POCKETLOGGER_LOG_PATH: ${{ github.workspace }}/artifacts/logs/pocketlogger.log TRYDOTNET_PREBUILDS_PATH: ${{ github.workspace }}/artifacts/trydotnet-prebuilds + Playwright_BrowserName: ${{ matrix.browser }} - name: Convert TRX to Playlist if: ${{ steps.run-dotnet-integration-tests.outcome == 'failure' || failure() }} uses: BenjaminMichaelis/trx-to-vsplaylist@v3 with: - trx-file-path: './TestResults/*.trx' - test-outcomes: 'Failed' - artifact-name: 'integration-test-playlists' + trx-file-path: "./TestResults/*.trx" + test-outcomes: "Failed" + artifact-name: "integration-test-playlists" deploy-development: if: github.event_name != 'pull_request_target' && github.event_name != 'pull_request' diff --git a/src/Microsoft.TryDotNet.IntegrationTests/IntegratedServicesFixture.cs b/src/Microsoft.TryDotNet.IntegrationTests/IntegratedServicesFixture.cs index c18d3d969..359ce3222 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/IntegratedServicesFixture.cs +++ b/src/Microsoft.TryDotNet.IntegrationTests/IntegratedServicesFixture.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using System.Threading; using System.Threading.Tasks; using Microsoft.DotNet.Interactive.CSharpProject.Build; diff --git a/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightSession.cs b/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightSession.cs index 01ec154a6..1b26dc324 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightSession.cs +++ b/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightSession.cs @@ -20,9 +20,24 @@ public PlaywrightSession(IPlaywright playwright, IBrowser browser) public IBrowser Browser { get; } - public static async Task StartAsync(string browserName = null) + public static async Task StartAsync(string? browserName = null) { - var exitCode = Playwright.Program.Main(["install"]); + + string? selectedBrowser = browserName + ?? Environment.GetEnvironmentVariable("Playwright.BrowserName") + ?? Environment.GetEnvironmentVariable("Playwright_BrowserName"); + + int exitCode; + if (!string.IsNullOrWhiteSpace(selectedBrowser)) + { + selectedBrowser = selectedBrowser.ToLowerInvariant(); + exitCode = Playwright.Program.Main(["install", selectedBrowser]); + } + else + { + exitCode = Playwright.Program.Main(["install"]); + selectedBrowser = "chromium"; + } if (exitCode is not 0) { throw new Exception($"Playwright exited with code {exitCode}"); @@ -37,8 +52,6 @@ public static async Task StartAsync(string browserName = null browserTypeLaunchOptions.Headless = false; } - var selectedBrowser = (browserName ?? Environment.GetEnvironmentVariable("Playwright.BrowserName") ?? "chromium").ToLowerInvariant(); - IBrowser browser = selectedBrowser switch { "chromium" => await session.Chromium.LaunchAsync(browserTypeLaunchOptions).Timeout(TimeSpan.FromMinutes(5), "Timeout launching browser"), From e41fc7aff079c0ce4086e633d8dbf248aba2faa6 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Aug 2026 14:11:15 -0400 Subject: [PATCH 7/7] fix: cross-platform integration test failures for macOS and Firefox (#427) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three distinct root causes were breaking matrix integration tests on macOS (both browsers) and Firefox (ubuntu + windows). ## macOS — all code-execution tests fail `ClearMonacoEditor` used `Control+A`, which on macOS is Monaco's Emacs "move to line start" binding, not "Select All". The editor was never cleared; old code remained; combined source failed to compile; every execution test returned `RunCompleted: "Failed"`. ```csharp // Before await editor.PressAsync("Control+a"); // After — Playwright sends Cmd+A on macOS, Ctrl+A elsewhere await editor.PressAsync("ControlOrMeta+a"); ``` ## Firefox — `WaitForLoadStateAsync(NetworkIdle)` timeouts Playwright's 30 s default navigation timeout isn't enough for Firefox loading the Blazor WASM runtime. Raises it to 90 s in `NewPageAsync()`. ```csharp page.SetDefaultNavigationTimeout(90_000f); ``` ## Windows/Firefox — diagnostics test captures empty `setMarkers` call Monaco fires `setMarkers([])` to clear previous markers *before* firing `setMarkers([{error}])` with actual diagnostics. The predicate was resolving on the empty call; the 1 s settle delay was too short for real markers to arrive. ```csharp // Skip the empty clear-call; wait for actual diagnostic data Predicate = message => message.Text.Contains("[MonacoEditorAdapter.setMarkers]") && !message.Text.Contains(": []"), ``` Settle delay also increased from 1 s → 3 s. Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: BenjaminMichaelis <22186029+BenjaminMichaelis@users.noreply.github.com> --- src/Microsoft.TryDotNet.IntegrationTests/EditorTests.cs | 6 ++++-- src/Microsoft.TryDotNet.IntegrationTests/PageExtensions.cs | 3 ++- .../PlaywrightTestBase.cs | 5 ++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.TryDotNet.IntegrationTests/EditorTests.cs b/src/Microsoft.TryDotNet.IntegrationTests/EditorTests.cs index 68ad4f676..299f673a7 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/EditorTests.cs +++ b/src/Microsoft.TryDotNet.IntegrationTests/EditorTests.cs @@ -342,11 +342,13 @@ await editor.PressSequentiallyAsync(@"///////////////////////// }, new PageRunAndWaitForConsoleMessageOptions() { - Predicate = message => message.Text.Contains("[MonacoEditorAdapter.setMarkers]"), + // Skip the initial empty setMarkers([]) call that Monaco fires to clear previous + // markers; wait for a non-empty call that actually contains diagnostic data. + Predicate = message => message.Text.Contains("[MonacoEditorAdapter.setMarkers]") && !message.Text.Contains(": []"), Timeout = Debugger.IsAttached ? 0.0f : (float)TimeSpan.FromMinutes(10).TotalMilliseconds }); - await Task.Delay(TimeSpan.FromSeconds(1)); + await Task.Delay(TimeSpan.FromSeconds(3)); var diagnosticMarker = page.Locator("div .squiggly-error"); await diagnosticMarker.IsVisibleAsync(); diff --git a/src/Microsoft.TryDotNet.IntegrationTests/PageExtensions.cs b/src/Microsoft.TryDotNet.IntegrationTests/PageExtensions.cs index 8f9c3fbc2..46a04e597 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/PageExtensions.cs +++ b/src/Microsoft.TryDotNet.IntegrationTests/PageExtensions.cs @@ -96,7 +96,8 @@ public static async Task ClearMonacoEditor(this IPage page) var editor = page.Locator(@"textarea[role = ""textbox""]"); await editor.IsVisibleAsync(); await editor.FocusAsync(); - await editor.PressAsync("Control+a"); + // Use ControlOrMeta+a so the shortcut works on both macOS (Cmd+A) and other platforms (Ctrl+A). + await editor.PressAsync("ControlOrMeta+a"); await editor.PressAsync("Delete"); } diff --git a/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightTestBase.cs b/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightTestBase.cs index 0bddf5878..f295c9909 100644 --- a/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightTestBase.cs +++ b/src/Microsoft.TryDotNet.IntegrationTests/PlaywrightTestBase.cs @@ -32,7 +32,10 @@ protected PlaywrightTestBase( protected async Task NewPageAsync() { var playwright = await Services.GetPlaywrightAsync(); - return await playwright.Browser.NewPageAsync(); + var page = await playwright.Browser.NewPageAsync(); + // Firefox needs more time to reach NetworkIdle due to Blazor WASM loading. + page.SetDefaultNavigationTimeout(90_000f); + return page; } protected async Task TryDotNetUrlAsync()