diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 72cf4cf..91e87fa 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -11,25 +11,98 @@ on: jobs: build: - + name: Builds the entire solution runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive + - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x - name: Restore .NET dependencies - working-directory: ./src/NodeDev.Blazor.Server + working-directory: ./src run: dotnet restore - name: Build - working-directory: ./src/NodeDev.Blazor.Server + working-directory: ./src run: dotnet build --no-restore + + - name: Upload Build Artifact + uses: actions/upload-artifact@v4 + with: + name: buildArtifact + path: ./src + retention-days: 7 + + tests: + name: Run Unit Tests + runs-on: ubuntu-latest + needs: build + + steps: + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + + - uses: actions/download-artifact@v4 + with: + name: buildArtifact + path: ./src + - name: Test working-directory: ./src/NodeDev.Tests - run: dotnet test --verbosity normal + run: dotnet test --no-build --verbosity normal + + e2e-tests: + name: Run End To End Tests + runs-on: ubuntu-latest + needs: build + + steps: + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + + - uses: actions/download-artifact@master + with: + name: buildArtifact + path: ./src + + - name: Build Necessary for Playwright + working-directory: ./src/NodeDev.EndToEndTests + run: dotnet build + + - name: Allow run + run: chmod -R +x ./src/NodeDev.Blazor.Server/bin + + - name: Ensure browsers are installed + run: pwsh ./src/NodeDev.EndToEndTests/bin/Debug/net8.0/playwright.ps1 install --with-deps + + - name: Test + env: + HEADLESS: true + working-directory: ./src/NodeDev.EndToEndTests + run: dotnet test --no-build --verbosity normal + + - name: Upload std Artifact + if: failure() + uses: actions/upload-artifact@v4 + with: + name: logStd + path: ./src/NodeDev.Blazor.Server/logs_std.txt + retention-days: 7 + + - name: Upload err Artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: logErr + path: ./src/NodeDev.Blazor.Server/logs_err.txt + retention-days: 7 diff --git a/.gitignore b/.gitignore index 53f141f..712cd76 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ /src/NodeDev.Core.Types/bin /src/NodeDev.EndToEndTests/bin/Debug/net8.0 /src/NodeDev.EndToEndTests/obj +/src/NodeDev.Blazor.Server/project_backup.json +/src/NodeDev.Blazor.Server/logs_err.txt +/src/NodeDev.Blazor.Server/logs_std.txt diff --git a/src/NodeDev.EndToEndTests/Hooks/Hooks.cs b/src/NodeDev.EndToEndTests/Hooks/Hooks.cs index 2f54614..f15402e 100644 --- a/src/NodeDev.EndToEndTests/Hooks/Hooks.cs +++ b/src/NodeDev.EndToEndTests/Hooks/Hooks.cs @@ -9,20 +9,58 @@ public class Hooks { public IPage User { get; private set; } = null!; //-> We'll call this property in the tests - private static Process App; + private static Process App = null!; + private static StreamWriter StdOutput = null!; + private static StreamWriter StdError = null!; private const int Port = 5166; [BeforeFeature] public static async Task StartServer() { - App = Process.Start(new ProcessStartInfo() + StdOutput = new StreamWriter(File.Open("../../../../NodeDev.Blazor.Server/logs_std.txt", FileMode.Create)); + StdError = new StreamWriter(File.Open("../../../../NodeDev.Blazor.Server/logs_err.txt", FileMode.Create)); + + // start the server using either a environment variable set by the CI, or a default path. + // The default path will work if you're running the tests from Visual Studio. + App = new Process(); + App.StartInfo = new ProcessStartInfo() { - CreateNoWindow = false, FileName = "dotnet", - Arguments = "run --no-build", - WorkingDirectory = @"..\..\..\..\NodeDev.Blazor.Server", - })!; + Arguments = $"run --no-build -- --urls http://localhost:{Port}", + WorkingDirectory = "../../../../NodeDev.Blazor.Server", + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true + }; + + App.OutputDataReceived += App_OutputDataReceived; + App.ErrorDataReceived += App_ErrorDataReceived; + + App.Start(); + App.BeginOutputReadLine(); + App.BeginErrorReadLine(); + + await Task.Delay(1000); + + if(App.HasExited) + { + StdOutput.Flush(); + StdError.Flush(); + throw new Exception("Failed to start the server: " + App.ExitCode); + } + } + + private static void App_ErrorDataReceived(object sender, DataReceivedEventArgs e) + { + if (e.Data != null) + StdError.WriteLine(e.Data); + } + + private static void App_OutputDataReceived(object sender, DataReceivedEventArgs e) + { + if(e.Data != null) + StdOutput.WriteLine(e.Data); } [BeforeScenario] // -> Notice how we're doing these steps before each scenario @@ -33,7 +71,7 @@ public async Task RegisterSingleInstancePractitioner() //Initialise a browser - 'Chromium' can be changed to 'Firefox' or 'Webkit' var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { - Headless = false // -> Use this option to be able to see your test running + Headless = Environment.GetEnvironmentVariable("HEADLESS") == "true" // -> Use this option to be able to see your test running }); //Setup a browser context var context1 = await browser.NewContextAsync(); @@ -50,11 +88,15 @@ public async Task RegisterSingleInstancePractitioner() } catch { - if (i == 5) + if (i == 60) + { + StdOutput.Flush(); + StdError.Flush(); throw; + } } - await Task.Delay(100); + await Task.Delay(1000); } } @@ -67,5 +109,12 @@ public static async Task StopServer() { await Task.Delay(100); } + + + StdOutput.Flush(); + StdError.Flush(); + + StdError.Dispose(); + StdError.Dispose(); } }