From 3b3824a7924d4d5563df0730b778f7b1f20e5218 Mon Sep 17 00:00:00 2001 From: Justin Alink Date: Thu, 1 Aug 2024 10:34:32 +0200 Subject: [PATCH 01/13] eerste opzet met Azure login 2FA base classes opzetten --- KISS-frontend.sln | 6 ++ Kiss.Bff.EndToEndTest/AzureAdLoginHelper.cs | 75 +++++++++++++++++++ Kiss.Bff.EndToEndTest/BaseTestInitializer.cs | 74 ++++++++++++++++++ Kiss.Bff.EndToEndTest/GlobalUsings.cs | 4 + .../Kiss.Bff.EndToEndTest.csproj | 31 ++++++++ 5 files changed, 190 insertions(+) create mode 100644 Kiss.Bff.EndToEndTest/AzureAdLoginHelper.cs create mode 100644 Kiss.Bff.EndToEndTest/BaseTestInitializer.cs create mode 100644 Kiss.Bff.EndToEndTest/GlobalUsings.cs create mode 100644 Kiss.Bff.EndToEndTest/Kiss.Bff.EndToEndTest.csproj diff --git a/KISS-frontend.sln b/KISS-frontend.sln index 9293947ec..818d0daaf 100644 --- a/KISS-frontend.sln +++ b/KISS-frontend.sln @@ -21,6 +21,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution CodeCoverage.runsettings = CodeCoverage.runsettings EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kiss.Bff.EndToEndTest", "Kiss.Bff.EndToEndTest\Kiss.Bff.EndToEndTest.csproj", "{D2EF3BA8-432E-42CE-AE01-04903D2F63FB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -45,6 +47,10 @@ Global {DEB9BEF6-DC5E-42AD-B13E-7B969C619F65}.Debug|Any CPU.Build.0 = Debug|Any CPU {DEB9BEF6-DC5E-42AD-B13E-7B969C619F65}.Release|Any CPU.ActiveCfg = Release|Any CPU {DEB9BEF6-DC5E-42AD-B13E-7B969C619F65}.Release|Any CPU.Build.0 = Release|Any CPU + {D2EF3BA8-432E-42CE-AE01-04903D2F63FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2EF3BA8-432E-42CE-AE01-04903D2F63FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2EF3BA8-432E-42CE-AE01-04903D2F63FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2EF3BA8-432E-42CE-AE01-04903D2F63FB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Kiss.Bff.EndToEndTest/AzureAdLoginHelper.cs b/Kiss.Bff.EndToEndTest/AzureAdLoginHelper.cs new file mode 100644 index 000000000..e835fa98d --- /dev/null +++ b/Kiss.Bff.EndToEndTest/AzureAdLoginHelper.cs @@ -0,0 +1,75 @@ +using Microsoft.Playwright; +using OtpNet; +using System; +using System.Threading.Tasks; + +namespace PlaywrightTests +{ + public class AzureAdLoginHelper + { + private readonly IPage _page; + private readonly string _username; + private readonly string _password; + private readonly string _totpSecret; + + public AzureAdLoginHelper(IPage page, string username, string password, string totpSecret) + { + _page = page; + _username = username; + _password = password; + _totpSecret = totpSecret; + } + + public async Task LoginAsync() + { + await _page.GotoAsync("https://dev.kiss-demo.nl/"); + + await _page.FillAsync("input[name='loginfmt']", _username); + await _page.ClickAsync("input[type='submit']"); + + await _page.WaitForSelectorAsync("input[name='passwd']"); + await _page.FillAsync("input[name='passwd']", _password); + await _page.ClickAsync("input[type='submit']"); + + await Handle2FAAsync(); + + await _page.WaitForURLAsync("https://dev.kiss-demo.nl/**"); + } + + private async Task Handle2FAAsync() + { + // Wait for the TOTP input field to appear + await _page.WaitForSelectorAsync("input[name='otc']", new() { Timeout = 30000 }); + + // Generate TOTP code + var totp = new Totp(Base32Encoding.ToBytes(_totpSecret)); + string totpCode = totp.ComputeTotp(); + + // Check for "Enter Manually" link and click if present + var enterManuallyLink = await _page.QuerySelectorAsync("a:has-text('Ik kan mijn Microsoft Authenticator-app op dit moment niet gebruiken')"); + if (enterManuallyLink != null) + { + await enterManuallyLink.ClickAsync(); + } + + // Fill in the TOTP code + await _page.FillAsync("input[name='otc']", totpCode); + await _page.ClickAsync("input[type='submit']"); + + // Wait for potential "Stay signed in?" prompt + var staySignedInPromptSelector = "input[value='Nee']"; + await Task.Delay(2000); + var staySignedInButton = await _page.QuerySelectorAsync(staySignedInPromptSelector); + + // Handle the prompt if present + if (staySignedInButton != null) + { + await staySignedInButton.ClickAsync(); + } + + // Wait for navigation or some confirmation that the login is successful + await _page.WaitForNavigationAsync(new() { Timeout = 30000 }); + } + + } +} diff --git a/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs new file mode 100644 index 000000000..88c7f9f58 --- /dev/null +++ b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs @@ -0,0 +1,74 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Playwright; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Threading.Tasks; + + +namespace PlaywrightTests +{ + [TestClass] + public class BaseTestInitializer + { + protected IPlaywright Playwright; + protected IBrowser Browser; + protected IBrowserContext Context; + protected IPage Page; + protected IPage FrontendPage; + protected AzureAdLoginHelper LoginHelper; + protected IConfiguration Configuration; + + [TestInitialize] + public virtual async Task TestInitialize() + { + try + { + Configuration = new ConfigurationBuilder() + .AddUserSecrets() + .AddEnvironmentVariables() + .Build(); + + var username = Configuration["TestSettings:TEST_USERNAME"]; + var password = Configuration["TestSettings:TEST_PASSWORD"]; + var totpSecret = Configuration["TestSettings:TEST_TOTP_SECRET"]; + + if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(totpSecret)) + { + throw new InvalidOperationException("One or more required settings are missing from appsettings.json"); + } + + Playwright = await Microsoft.Playwright.Playwright.CreateAsync(); + Browser = await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions + { + Headless = false // Set to true + }); + Context = await Browser.NewContextAsync(); + Page = await Context.NewPageAsync(); + LoginHelper = new AzureAdLoginHelper(Page, + Configuration["TestSettings:TEST_USERNAME"], + Configuration["TestSettings:TEST_PASSWORD"], + Configuration["TestSettings:TEST_TOTP_SECRET"]); + + await LoginHelper.LoginAsync(); + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + throw; + } + + } + + [TestCleanup] + public virtual async Task TestCleanup() + { + await Context.CloseAsync(); + await Browser.CloseAsync(); + Playwright?.Dispose(); + } + + protected virtual async Task OpenNewPageAsync() + { + return await Context.NewPageAsync(); + } + } +} diff --git a/Kiss.Bff.EndToEndTest/GlobalUsings.cs b/Kiss.Bff.EndToEndTest/GlobalUsings.cs new file mode 100644 index 000000000..87d760e4f --- /dev/null +++ b/Kiss.Bff.EndToEndTest/GlobalUsings.cs @@ -0,0 +1,4 @@ +global using Microsoft.Playwright.MSTest; +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using System.Text.RegularExpressions; +global using System.Threading.Tasks; diff --git a/Kiss.Bff.EndToEndTest/Kiss.Bff.EndToEndTest.csproj b/Kiss.Bff.EndToEndTest/Kiss.Bff.EndToEndTest.csproj new file mode 100644 index 000000000..0bdb9a7e8 --- /dev/null +++ b/Kiss.Bff.EndToEndTest/Kiss.Bff.EndToEndTest.csproj @@ -0,0 +1,31 @@ + + + + net8.0 + enable + enable + + false + true + 11d50565-5002-41ee-b700-0b7168235484 + + + + + + + + + + + + + + + + + PreserveNewest + + + + From 30c93acf21cb7effab7b395b87ac10ca93850ea9 Mon Sep 17 00:00:00 2001 From: Justin Alink Date: Thu, 1 Aug 2024 14:50:47 +0200 Subject: [PATCH 02/13] PR aanpassingen --- Kiss.Bff.EndToEndTest/BaseTestInitializer.cs | 27 ++++++++++++------- .../GespreksresultatenTests.cs | 14 ++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 Kiss.Bff.EndToEndTest/GespreksresultatenTests.cs diff --git a/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs index 88c7f9f58..15fc0eab8 100644 --- a/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs +++ b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs @@ -27,9 +27,10 @@ public virtual async Task TestInitialize() .AddEnvironmentVariables() .Build(); - var username = Configuration["TestSettings:TEST_USERNAME"]; - var password = Configuration["TestSettings:TEST_PASSWORD"]; - var totpSecret = Configuration["TestSettings:TEST_TOTP_SECRET"]; + var username = GetRequiredConfig(Configuration, "TestSettings:TEST_USERNAME"); + var password = GetRequiredConfig(Configuration, "TestSettings:TEST_PASSWORD"); + var totpSecret = GetRequiredConfig(Configuration, "TestSettings:TEST_TOTP_SECRET"); + var isHeadless = GetRequiredConfig(Configuration, "TestSettings:TEST_HEADLESS"); if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(totpSecret)) { @@ -39,20 +40,16 @@ public virtual async Task TestInitialize() Playwright = await Microsoft.Playwright.Playwright.CreateAsync(); Browser = await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { - Headless = false // Set to true + Headless = bool.Parse(isHeadless) }); Context = await Browser.NewContextAsync(); Page = await Context.NewPageAsync(); - LoginHelper = new AzureAdLoginHelper(Page, - Configuration["TestSettings:TEST_USERNAME"], - Configuration["TestSettings:TEST_PASSWORD"], - Configuration["TestSettings:TEST_TOTP_SECRET"]); + LoginHelper = new AzureAdLoginHelper(Page, username, password, totpSecret); await LoginHelper.LoginAsync(); } - catch (Exception ex) + catch { - Console.WriteLine(ex.ToString()); throw; } @@ -70,5 +67,15 @@ protected virtual async Task OpenNewPageAsync() { return await Context.NewPageAsync(); } + + private string GetRequiredConfig(IConfiguration configuration, string key) + { + var value = configuration[key]; + if (string.IsNullOrEmpty(value)) + { + throw new InvalidOperationException($"'{key}' is missing from the configuration"); + } + return value; + } } } diff --git a/Kiss.Bff.EndToEndTest/GespreksresultatenTests.cs b/Kiss.Bff.EndToEndTest/GespreksresultatenTests.cs new file mode 100644 index 000000000..db5915ac6 --- /dev/null +++ b/Kiss.Bff.EndToEndTest/GespreksresultatenTests.cs @@ -0,0 +1,14 @@ +namespace PlaywrightTests +{ + [TestClass] + public class GespreksresultatenTests : BaseTestInitializer + { + // dummy test to ensure that the base class functions properly from github actions + [TestMethod] + public async Task DummyTest() + { + var isEditor = await Page.IsVisibleAsync("a[href='/beheer']"); + Assert.IsTrue(isEditor, "User does not have editor role."); + } + } +} From 341855bdcb0ccce09941c6894172f1d0af927c47 Mon Sep 17 00:00:00 2001 From: Justin Alink Date: Thu, 1 Aug 2024 14:51:44 +0200 Subject: [PATCH 03/13] cleanup --- Kiss.Bff.EndToEndTest/BaseTestInitializer.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs index 15fc0eab8..e91942405 100644 --- a/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs +++ b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs @@ -32,10 +32,6 @@ public virtual async Task TestInitialize() var totpSecret = GetRequiredConfig(Configuration, "TestSettings:TEST_TOTP_SECRET"); var isHeadless = GetRequiredConfig(Configuration, "TestSettings:TEST_HEADLESS"); - if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(totpSecret)) - { - throw new InvalidOperationException("One or more required settings are missing from appsettings.json"); - } Playwright = await Microsoft.Playwright.Playwright.CreateAsync(); Browser = await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions From 9ad145b3ce712a7ef1ff60c6bc6cb4ce9228da20 Mon Sep 17 00:00:00 2001 From: Felix Cornelissen Date: Mon, 5 Aug 2024 17:17:25 +0200 Subject: [PATCH 04/13] cleanup --- Kiss.Bff.EndToEndTest/AzureAdLoginHelper.cs | 29 ++++---- Kiss.Bff.EndToEndTest/BaseTestInitializer.cs | 69 ++++--------------- .../GespreksresultatenTests.cs | 3 +- .../Kiss.Bff.EndToEndTest.csproj | 15 ++-- local.runsettings | 8 +++ 5 files changed, 47 insertions(+), 77 deletions(-) create mode 100644 local.runsettings diff --git a/Kiss.Bff.EndToEndTest/AzureAdLoginHelper.cs b/Kiss.Bff.EndToEndTest/AzureAdLoginHelper.cs index e835fa98d..a451d7060 100644 --- a/Kiss.Bff.EndToEndTest/AzureAdLoginHelper.cs +++ b/Kiss.Bff.EndToEndTest/AzureAdLoginHelper.cs @@ -1,20 +1,20 @@ using Microsoft.Playwright; using OtpNet; -using System; -using System.Threading.Tasks; namespace PlaywrightTests { public class AzureAdLoginHelper { private readonly IPage _page; + private readonly Uri _baseUrl; private readonly string _username; private readonly string _password; private readonly string _totpSecret; - public AzureAdLoginHelper(IPage page, string username, string password, string totpSecret) + public AzureAdLoginHelper(IPage page, Uri baseUrl, string username, string password, string totpSecret) { _page = page; + _baseUrl = baseUrl; _username = username; _password = password; _totpSecret = totpSecret; @@ -22,7 +22,7 @@ public AzureAdLoginHelper(IPage page, string username, string password, string t public async Task LoginAsync() { - await _page.GotoAsync("https://dev.kiss-demo.nl/"); + await _page.GotoAsync(_baseUrl.ToString()); await _page.FillAsync("input[name='loginfmt']", _username); await _page.ClickAsync("input[type='submit']"); @@ -33,7 +33,7 @@ public async Task LoginAsync() await Handle2FAAsync(); - await _page.WaitForURLAsync("https://dev.kiss-demo.nl/**"); + await _page.WaitForURLAsync($"{_baseUrl}**"); } private async Task Handle2FAAsync() @@ -43,7 +43,7 @@ private async Task Handle2FAAsync() // Generate TOTP code var totp = new Totp(Base32Encoding.ToBytes(_totpSecret)); - string totpCode = totp.ComputeTotp(); + var totpCode = totp.ComputeTotp(); // Check for "Enter Manually" link and click if present var enterManuallyLink = await _page.QuerySelectorAsync("a:has-text('Ik kan mijn Microsoft Authenticator-app op dit moment niet gebruiken')"); @@ -57,18 +57,17 @@ private async Task Handle2FAAsync() await _page.ClickAsync("input[type='submit']"); // Wait for potential "Stay signed in?" prompt - var staySignedInPromptSelector = "input[value='Nee']"; - await Task.Delay(2000); - var staySignedInButton = await _page.QuerySelectorAsync(staySignedInPromptSelector); + var declineStaySignedInButton = _page.GetByText("Nee").Or(_page.GetByText("No")); + var homePageSelector = _page.GetByText("Nieuw contactmoment"); - // Handle the prompt if present - if (staySignedInButton != null) + // we will either get a decline button, or we will go back to the home page + await declineStaySignedInButton.Or(homePageSelector).WaitForAsync(); + + // check if the decline button is visible, if so, click it + if (await declineStaySignedInButton.IsVisibleAsync()) { - await staySignedInButton.ClickAsync(); + await declineStaySignedInButton.ClickAsync(); } - - // Wait for navigation or some confirmation that the login is successful - await _page.WaitForNavigationAsync(new() { Timeout = 30000 }); } } diff --git a/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs index e91942405..15ce571e1 100644 --- a/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs +++ b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs @@ -1,67 +1,28 @@ using Microsoft.Extensions.Configuration; -using Microsoft.Playwright; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Threading.Tasks; namespace PlaywrightTests { [TestClass] - public class BaseTestInitializer + public class BaseTestInitializer : PageTest { - protected IPlaywright Playwright; - protected IBrowser Browser; - protected IBrowserContext Context; - protected IPage Page; - protected IPage FrontendPage; - protected AzureAdLoginHelper LoginHelper; - protected IConfiguration Configuration; - [TestInitialize] public virtual async Task TestInitialize() { - try - { - Configuration = new ConfigurationBuilder() - .AddUserSecrets() - .AddEnvironmentVariables() - .Build(); - - var username = GetRequiredConfig(Configuration, "TestSettings:TEST_USERNAME"); - var password = GetRequiredConfig(Configuration, "TestSettings:TEST_PASSWORD"); - var totpSecret = GetRequiredConfig(Configuration, "TestSettings:TEST_TOTP_SECRET"); - var isHeadless = GetRequiredConfig(Configuration, "TestSettings:TEST_HEADLESS"); - - - Playwright = await Microsoft.Playwright.Playwright.CreateAsync(); - Browser = await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions - { - Headless = bool.Parse(isHeadless) - }); - Context = await Browser.NewContextAsync(); - Page = await Context.NewPageAsync(); - LoginHelper = new AzureAdLoginHelper(Page, username, password, totpSecret); - - await LoginHelper.LoginAsync(); - } - catch - { - throw; - } - - } - - [TestCleanup] - public virtual async Task TestCleanup() - { - await Context.CloseAsync(); - await Browser.CloseAsync(); - Playwright?.Dispose(); - } - - protected virtual async Task OpenNewPageAsync() - { - return await Context.NewPageAsync(); + var configuration = new ConfigurationBuilder() + .AddUserSecrets() + .AddEnvironmentVariables() + .Build(); + + var username = GetRequiredConfig(configuration, "TestSettings:TEST_USERNAME"); + var password = GetRequiredConfig(configuration, "TestSettings:TEST_PASSWORD"); + var totpSecret = GetRequiredConfig(configuration, "TestSettings:TEST_TOTP_SECRET"); + var isHeadless = GetRequiredConfig(configuration, "TestSettings:TEST_HEADLESS"); + var baseUrl = GetRequiredConfig(configuration, "TestSettings:TEST_BASE_URL"); + var uri = new Uri(baseUrl); + + var loginHelper = new AzureAdLoginHelper(Page, uri, username, password, totpSecret); + await loginHelper.LoginAsync(); } private string GetRequiredConfig(IConfiguration configuration, string key) diff --git a/Kiss.Bff.EndToEndTest/GespreksresultatenTests.cs b/Kiss.Bff.EndToEndTest/GespreksresultatenTests.cs index db5915ac6..2aa0eb44b 100644 --- a/Kiss.Bff.EndToEndTest/GespreksresultatenTests.cs +++ b/Kiss.Bff.EndToEndTest/GespreksresultatenTests.cs @@ -7,8 +7,7 @@ public class GespreksresultatenTests : BaseTestInitializer [TestMethod] public async Task DummyTest() { - var isEditor = await Page.IsVisibleAsync("a[href='/beheer']"); - Assert.IsTrue(isEditor, "User does not have editor role."); + await Expect(Page.Locator("a[href='/beheer']")).ToBeVisibleAsync(); } } } diff --git a/Kiss.Bff.EndToEndTest/Kiss.Bff.EndToEndTest.csproj b/Kiss.Bff.EndToEndTest/Kiss.Bff.EndToEndTest.csproj index 0bdb9a7e8..ea08e3767 100644 --- a/Kiss.Bff.EndToEndTest/Kiss.Bff.EndToEndTest.csproj +++ b/Kiss.Bff.EndToEndTest/Kiss.Bff.EndToEndTest.csproj @@ -13,12 +13,15 @@ - - - - - - + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/local.runsettings b/local.runsettings new file mode 100644 index 000000000..ccef4f454 --- /dev/null +++ b/local.runsettings @@ -0,0 +1,8 @@ + + + + + false + + + \ No newline at end of file From 44f2588108c9501a21d4da4b05a43a55e8d60afb Mon Sep 17 00:00:00 2001 From: Felix Cornelissen Date: Mon, 5 Aug 2024 17:24:40 +0200 Subject: [PATCH 05/13] github action playwright init --- .github/workflows/playwright.yaml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/playwright.yaml diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml new file mode 100644 index 000000000..d324747fa --- /dev/null +++ b/.github/workflows/playwright.yaml @@ -0,0 +1,27 @@ +name: Playwright Tests +on: + schedule: + - cron: '0 23 * * *' + pull_request: + branches: [ main, master ] + paths: ['Kiss.Bff.EndToEndTest'] + workflow_dispatch: + +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./Kiss.Bff.EndToEndTest + steps: + - uses: actions/checkout@v4 + - name: Setup dotnet + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - run: dotnet build + - name: Ensure browsers are installed + run: pwsh bin/Debug/net8.0/playwright.ps1 install --with-deps + - name: Run your tests + run: dotnet test \ No newline at end of file From 7a7906a328646f8580f5d6f7ea5484a8e064b8d6 Mon Sep 17 00:00:00 2001 From: Felix Cornelissen Date: Mon, 5 Aug 2024 17:25:06 +0200 Subject: [PATCH 06/13] cleanup --- .github/workflows/playwright.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml index d324747fa..05ef5ff32 100644 --- a/.github/workflows/playwright.yaml +++ b/.github/workflows/playwright.yaml @@ -4,9 +4,9 @@ on: - cron: '0 23 * * *' pull_request: branches: [ main, master ] - paths: ['Kiss.Bff.EndToEndTest'] + paths: ['Kiss.Bff.EndToEndTest/**'] workflow_dispatch: - + jobs: test: timeout-minutes: 60 From e19d117cc7eba124f14b8c02dbee1821078087d1 Mon Sep 17 00:00:00 2001 From: Felix Cornelissen Date: Mon, 5 Aug 2024 17:36:38 +0200 Subject: [PATCH 07/13] secrets in playwright action --- .github/workflows/playwright.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml index 05ef5ff32..f1bf3ffe2 100644 --- a/.github/workflows/playwright.yaml +++ b/.github/workflows/playwright.yaml @@ -24,4 +24,9 @@ jobs: - name: Ensure browsers are installed run: pwsh bin/Debug/net8.0/playwright.ps1 install --with-deps - name: Run your tests - run: dotnet test \ No newline at end of file + run: dotnet test + env: + 'TestSettings:TEST_USERNAME': ${{ secrets.PLAYWRIGHT_USERNAME }} + 'TestSettings:TEST_PASSWORD': ${{ secrets.PLAYWRIGHT_PASSWORD }} + 'TestSettings:TEST_TOTP_SECRET': ${{ secrets.PLAYWRIGHT_TOTP_SECRET }} + 'TestSettings:TEST_BASE_URL': ${{ secrets.PLAYWRIGHT_BASE_URL }} \ No newline at end of file From f223e07367008cb163dce236f93238dff2ea7c98 Mon Sep 17 00:00:00 2001 From: Felix Cornelissen Date: Mon, 5 Aug 2024 17:38:21 +0200 Subject: [PATCH 08/13] cleanup --- Kiss.Bff.EndToEndTest/BaseTestInitializer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs index 15ce571e1..70d33190c 100644 --- a/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs +++ b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs @@ -17,7 +17,6 @@ public virtual async Task TestInitialize() var username = GetRequiredConfig(configuration, "TestSettings:TEST_USERNAME"); var password = GetRequiredConfig(configuration, "TestSettings:TEST_PASSWORD"); var totpSecret = GetRequiredConfig(configuration, "TestSettings:TEST_TOTP_SECRET"); - var isHeadless = GetRequiredConfig(configuration, "TestSettings:TEST_HEADLESS"); var baseUrl = GetRequiredConfig(configuration, "TestSettings:TEST_BASE_URL"); var uri = new Uri(baseUrl); From 2e9f9b5d43ee700adabccb9fa25b403741d6dbeb Mon Sep 17 00:00:00 2001 From: Felix Cornelissen Date: Mon, 5 Aug 2024 17:53:26 +0200 Subject: [PATCH 09/13] add traces --- .github/workflows/playwright.yaml | 8 +++++++- Kiss.Bff.EndToEndTest/BaseTestInitializer.cs | 21 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml index f1bf3ffe2..ee1e98475 100644 --- a/.github/workflows/playwright.yaml +++ b/.github/workflows/playwright.yaml @@ -29,4 +29,10 @@ jobs: 'TestSettings:TEST_USERNAME': ${{ secrets.PLAYWRIGHT_USERNAME }} 'TestSettings:TEST_PASSWORD': ${{ secrets.PLAYWRIGHT_PASSWORD }} 'TestSettings:TEST_TOTP_SECRET': ${{ secrets.PLAYWRIGHT_TOTP_SECRET }} - 'TestSettings:TEST_BASE_URL': ${{ secrets.PLAYWRIGHT_BASE_URL }} \ No newline at end of file + 'TestSettings:TEST_BASE_URL': ${{ secrets.PLAYWRIGHT_BASE_URL }} + - name: Upload test artifacts + if: ${{ failure() && steps.e2e.conclusion == 'failure' }} + uses: actions/upload-artifact@v4 + with: + name: playwright-traces + path: bin/Debug/net8.0/playwright-traces \ No newline at end of file diff --git a/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs index 70d33190c..c26f7246c 100644 --- a/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs +++ b/Kiss.Bff.EndToEndTest/BaseTestInitializer.cs @@ -20,10 +20,31 @@ public virtual async Task TestInitialize() var baseUrl = GetRequiredConfig(configuration, "TestSettings:TEST_BASE_URL"); var uri = new Uri(baseUrl); + await Context.Tracing.StartAsync(new() + { + Title = $"{TestContext.FullyQualifiedTestClassName}.{TestContext.TestName}", + Screenshots = true, + Snapshots = true, + Sources = true + }); + var loginHelper = new AzureAdLoginHelper(Page, uri, username, password, totpSecret); await loginHelper.LoginAsync(); } + [TestCleanup] + public async Task TestCleanup() + { + await Context.Tracing.StopAsync(new() + { + Path = Path.Combine( + Environment.CurrentDirectory, + "playwright-traces", + $"{TestContext.FullyQualifiedTestClassName}.{TestContext.TestName}.zip" + ) + }); + } + private string GetRequiredConfig(IConfiguration configuration, string key) { var value = configuration[key]; From bac364a9c8e9db3326ddff98fa373c5206fd9bf2 Mon Sep 17 00:00:00 2001 From: Felix Cornelissen Date: Mon, 5 Aug 2024 17:56:34 +0200 Subject: [PATCH 10/13] cleanup --- .github/workflows/playwright.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml index ee1e98475..42157748b 100644 --- a/.github/workflows/playwright.yaml +++ b/.github/workflows/playwright.yaml @@ -24,6 +24,7 @@ jobs: - name: Ensure browsers are installed run: pwsh bin/Debug/net8.0/playwright.ps1 install --with-deps - name: Run your tests + id: e2e run: dotnet test env: 'TestSettings:TEST_USERNAME': ${{ secrets.PLAYWRIGHT_USERNAME }} From 9daaa49337c18d3f89b800c071fd0d09e3358448 Mon Sep 17 00:00:00 2001 From: Felix Cornelissen Date: Mon, 5 Aug 2024 18:02:22 +0200 Subject: [PATCH 11/13] try path --- .github/workflows/playwright.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml index 42157748b..06a4d9903 100644 --- a/.github/workflows/playwright.yaml +++ b/.github/workflows/playwright.yaml @@ -36,4 +36,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: playwright-traces - path: bin/Debug/net8.0/playwright-traces \ No newline at end of file + path: '**/playwright-traces' \ No newline at end of file From 3f11323de04f977a9956ab1f51e75dee7419e1cd Mon Sep 17 00:00:00 2001 From: Felix Cornelissen Date: Mon, 5 Aug 2024 18:05:57 +0200 Subject: [PATCH 12/13] seperate zips --- .github/workflows/playwright.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml index 06a4d9903..e84180565 100644 --- a/.github/workflows/playwright.yaml +++ b/.github/workflows/playwright.yaml @@ -36,4 +36,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: playwright-traces - path: '**/playwright-traces' \ No newline at end of file + path: '**/playwright-traces/*.zip' \ No newline at end of file From a4d0e1ce051b04d7442e3729f9040e560ebcc275 Mon Sep 17 00:00:00 2001 From: Felix Cornelissen Date: Mon, 5 Aug 2024 18:09:51 +0200 Subject: [PATCH 13/13] wrap password with quotes in action --- .github/workflows/playwright.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml index e84180565..0dc227559 100644 --- a/.github/workflows/playwright.yaml +++ b/.github/workflows/playwright.yaml @@ -28,7 +28,7 @@ jobs: run: dotnet test env: 'TestSettings:TEST_USERNAME': ${{ secrets.PLAYWRIGHT_USERNAME }} - 'TestSettings:TEST_PASSWORD': ${{ secrets.PLAYWRIGHT_PASSWORD }} + 'TestSettings:TEST_PASSWORD': '${{ secrets.PLAYWRIGHT_PASSWORD }}' 'TestSettings:TEST_TOTP_SECRET': ${{ secrets.PLAYWRIGHT_TOTP_SECRET }} 'TestSettings:TEST_BASE_URL': ${{ secrets.PLAYWRIGHT_BASE_URL }} - name: Upload test artifacts