Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pc 686 e2e nieuws werkinstructies #985

Draft
wants to merge 81 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
9247d0e
wip
felixcicatt Dec 19, 2024
b37a72b
refrase
felixcicatt Dec 23, 2024
a69b797
fix test
felixcicatt Dec 23, 2024
5ad0dc6
match aria snapshot
felixcicatt Dec 23, 2024
915b3fb
scenario 8
felixcicatt Dec 23, 2024
a3d98dc
scenario 9
felixcicatt Dec 23, 2024
162fa94
cleanup
felixcicatt Dec 23, 2024
317a6a5
scenario 10
felixcicatt Dec 23, 2024
88fab03
fix test
felixcicatt Dec 23, 2024
7a1d15c
allow only one playwright test at a time
felixcicatt Dec 23, 2024
a16267f
cleanup
felixcicatt Dec 23, 2024
171990a
cleanup
felixcicatt Dec 23, 2024
2621d69
make beheer naviation more robust
felixcicatt Dec 23, 2024
8173cca
cleanup
felixcicatt Dec 23, 2024
cf33a01
comments
felixcicatt Jan 6, 2025
1ae5b6b
rework based on feedback
felixcicatt Jan 6, 2025
5cbb182
move navigation helpers to seperate class
felixcicatt Jan 6, 2025
2eeec06
add styling for inconclusive tests
felixcicatt Jan 6, 2025
8639c7b
add steps for the next scenarios
felixcicatt Jan 6, 2025
13a1566
html encode secenario and step names in the report
felixcicatt Jan 7, 2025
4b8a0a8
add remaining steps
felixcicatt Jan 7, 2025
679f5fb
instructions for running the e2e tests locally
felixcicatt Jan 7, 2025
1cfa669
cleanup
felixcicatt Jan 7, 2025
b1bd06a
fix cleanup steps in traces
felixcicatt Jan 7, 2025
eb03d49
upload playwright traces directly
felixcicatt Jan 7, 2025
a71ea54
test build
felixcicatt Jan 7, 2025
3edfb65
only upload test results on main
felixcicatt Jan 7, 2025
6e796b9
cleanup
felixcicatt Jan 7, 2025
2126492
github pages deployment in separate job
felixcicatt Jan 7, 2025
b35717f
cleanup
felixcicatt Jan 7, 2025
199991b
fix playwright build
felixcicatt Jan 7, 2025
9b0be54
fix playwright build
felixcicatt Jan 7, 2025
a188edc
only deploy from main
felixcicatt Jan 7, 2025
6f4308d
Add new locators and implement Scenario11 test
henokicatt Jan 7, 2025
8c389d6
Merge branch 'PC-686-e2e-nieuws-werkinstructies' of https://github.co…
henokicatt Jan 7, 2025
f689249
Rename methods in Locators.cs and update references
henokicatt Jan 8, 2025
1982007
Refactor element locators in Locators.cs
henokicatt Jan 8, 2025
9f0ab55
Remove GetElementById method from Locators.cs
henokicatt Jan 8, 2025
e411e24
Update Scenario12 test with new steps and verifications
henokicatt Jan 8, 2025
6353d21
Implement Scenario13 test method in NieuwsEnWerkInstructies
henokicatt Jan 8, 2025
963970f
Add search filter by WerkberichtType and update Scenario14
henokicatt Jan 9, 2025
83001e3
Rename method GetSearchResultByWerkberichtType
henokicatt Jan 9, 2025
ef60b03
Expand assertions to check both article count and visibility.
henokicatt Jan 9, 2025
ed58811
Scenario15 in NieuwsEnWerkInstructiesScenarios.cs to generate unique …
henokicatt Jan 9, 2025
64bf0f3
Removed unused function
henokicatt Jan 9, 2025
301502a
Ensure `werkbericht` and `nieuws` objects are properly disposed of us…
henokicatt Jan 9, 2025
2a9904a
Ensure `werkbericht` and `nieuws` objects are properly disposed of us…
henokicatt Jan 9, 2025
f510546
Modified the creation of 'nieuwsbericht' and 'werkinstructie' objects…
henokicatt Jan 9, 2025
ae9e8d8
Implement Scenario17 test in NieuwsEnWerkInstructiesScenarios
henokicatt Jan 9, 2025
d4eac1f
Update GetRowByValue and add Scenario18 test
henokicatt Jan 10, 2025
7d11175
Implement Scenario19 test and update GetRowByValue method
henokicatt Jan 10, 2025
ee48376
Expanded Scenario20 in NieuwsEnWerkInstructiesScenarios.cs to create …
henokicatt Jan 10, 2025
cbbe71e
Add publication dates to Bericht and update tests
henokicatt Jan 13, 2025
6dc5a3d
don't set environment on the test job
felixcicatt Jan 13, 2025
3aba54c
Merge pull request #991 from Klantinteractie-Servicesysteem/PC-686-sc…
mstokericatt Jan 13, 2025
f676f9a
Merge pull request #992 from Klantinteractie-Servicesysteem/PC-686-sc…
mstokericatt Jan 13, 2025
e282cb4
Merge pull request #995 from Klantinteractie-Servicesysteem/PC-686-sc…
mstokericatt Jan 13, 2025
090f994
Merge pull request #998 from Klantinteractie-Servicesysteem/PC-686-sc…
mstokericatt Jan 13, 2025
7f0a489
Merge branch 'PC-686-e2e-nieuws-werkinstructies' into PC-686-scenario-15
henokicatt Jan 13, 2025
0a4233c
Changed the test assertion locator for `Body` content from `.ck-edito…
henokicatt Jan 13, 2025
b958aac
Scenario21 test in NieuwsEnWerkInstructiesScenarios.cs to include new…
henokicatt Jan 13, 2025
2d46387
Updated `Scenario21` to assert "Gewijzigd op" field. Expanded `Scenar…
henokicatt Jan 13, 2025
78cd4fd
Implement Scenario23 test in NieuwsEnWerkInstructiesScenarios
henokicatt Jan 13, 2025
342b216
Update tests and locators;
henokicatt Jan 14, 2025
dc7630b
Add search and verification steps for news items
henokicatt Jan 14, 2025
c59907e
Rename and update GetRowByValue method
henokicatt Jan 14, 2025
43a11cc
Rename method and update tests for consistency
henokicatt Jan 14, 2025
c89ba90
Merge pull request #997 from Klantinteractie-Servicesysteem/PC-686-sc…
mstokericatt Jan 14, 2025
83db6d9
Rename method and update tests for consistency
henokicatt Jan 14, 2025
9edd99b
Replace GetRowByValue and implement new test scenarios
henokicatt Jan 14, 2025
5edea47
resolved merge conflict
henokicatt Jan 14, 2025
347f8f4
Merge branch 'PC-686-scenario-18' into PC-686-scenario-19
henokicatt Jan 14, 2025
cda2e0f
resolved merge conflict
henokicatt Jan 14, 2025
32bbcfd
Merge branch 'PC-686-scenario-19' into PC-686-scenario-20
henokicatt Jan 14, 2025
111bd61
resolved merge conflict
henokicatt Jan 14, 2025
29d15c9
resolved merge conflicts
henokicatt Jan 14, 2025
23ed28d
Merge pull request #1000 from Klantinteractie-Servicesysteem/PC-686-s…
mstokericatt Jan 14, 2025
5f8e629
Merge pull request #1001 from Klantinteractie-Servicesysteem/PC-686-s…
mstokericatt Jan 14, 2025
8b3506b
Merge pull request #1003 from Klantinteractie-Servicesysteem/PC-686-s…
mstokericatt Jan 14, 2025
0c8ceac
Update Kiss.Bff.EndToEndTest/NieuwsEnWerkInstructies/NieuwsEnWerkInst…
mstokericatt Jan 16, 2025
9ca64a6
Merge pull request #1009 from Klantinteractie-Servicesysteem/PC-686-s…
mstokericatt Jan 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 25 additions & 23 deletions .github/workflows/playwright.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ on:
paths: ['Kiss.Bff.EndToEndTest/**']
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false

jobs:
test:
timeout-minutes: 60
Expand All @@ -31,27 +40,20 @@ jobs:
'TestSettings:TEST_PASSWORD': '${{ secrets.PLAYWRIGHT_PASSWORD }}'
'TestSettings:TEST_TOTP_SECRET': ${{ secrets.PLAYWRIGHT_TOTP_SECRET }}
'TestSettings:TEST_BASE_URL': ${{ secrets.PLAYWRIGHT_BASE_URL }}
- name: Create html file
if: ${{ failure() && steps.e2e.conclusion == 'failure' }}
run: |
cd bin/Debug/net8.0/playwright-traces
my_string=$(echo *.zip)
IFS=' ' read -ra my_array <<< "$my_string"
result='<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Playwright traces</title></head><body><ul>'

#Print the split string
for i in "${my_array[@]}"
do
result+="<li><a target=\"_blank\" href=\"https://trace.playwright.dev/?trace=https://klantinteractie-servicesysteem.github.io/KISS-frontend/$i\">$i</a></li>"
done

result+="</ul></body></html>"
echo "$result"
echo "$result" > index.html
- name: Deploy to GitHub Pages
if: ${{ failure() && steps.e2e.conclusion == 'failure' }}
uses: peaceiris/actions-gh-pages@v4
- name: Upload artifact
if: ${{ always() }}
uses: actions/upload-pages-artifact@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./Kiss.Bff.EndToEndTest/bin/Debug/net8.0/playwright-traces # directory of your reports
publish_branch: gh-pages/e2e # deploying to gh-pages branch
# directory of your reports
path: './Kiss.Bff.EndToEndTest/bin/Debug/net8.0/playwright-traces'
deploy:
if: ${{ always() && github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}
needs: test
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
19 changes: 19 additions & 0 deletions Kiss.Bff.EndToEndTest/Helpers/AcceptAllDialogs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Kiss.Bff.EndToEndTest.Helpers
{
public static class AcceptAllDialogsExtension
{
public static IDisposable AcceptAllDialogs(this IPage page)
{
page.Dialog += Accept;
return new DoOnDispose(() => page.Dialog -= Accept);
}

private static async void Accept(object? _, IDialog dialog) => await dialog.AcceptAsync();


private sealed class DoOnDispose(Action action) : IDisposable
{
public void Dispose() => action();
}
}
}
25 changes: 25 additions & 0 deletions Kiss.Bff.EndToEndTest/Helpers/Pagination.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Kiss.Bff.EndToEndTest.Helpers
{
internal static class Pagination
{
public static ILocator GetCurrentPageLink(this ILocator locator) => locator.Locator("[aria-current=page]").First;
public static ILocator GetNextPageLink(this ILocator locator) => locator.Locator("[rel='next']").First;
public static ILocator GetPreviousPageLink(this ILocator locator) => locator.Locator("[rel='prev']").First;
public static async Task<bool> IsDisabledPageLink(this ILocator locator)
{
await locator.WaitForAsync();

var classes = await locator.GetAttributeAsync("class");
if (classes == null) return false;
// when the page is disabled it doesn't get a disabled attribute.
// TODO: research if there is a better pattern for this that is compatible with the den haag pagination component:
// https://nl-design-system.github.io/denhaag/?path=/docs/react-navigation-pagination--docs
// Note that their component renders invalid html: a button with a rel attribute.
// this might serve as a source of inspiration:
// https://design.homeoffice.gov.uk/components?name=Pagination
// https://design-system.w3.org/components/pagination.html
return classes.Contains("denhaag-pagination__link--disabled")
|| classes.Contains("denhaag-pagination__link--current");
}
}
}
74 changes: 0 additions & 74 deletions Kiss.Bff.EndToEndTest/Infrastructure/BaseTestInitializer.cs

This file was deleted.

155 changes: 155 additions & 0 deletions Kiss.Bff.EndToEndTest/Infrastructure/KissPlaywrightTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
using System.Collections.Concurrent;
using System.Text.Encodings.Web;
using Microsoft.Extensions.Configuration;


namespace Kiss.Bff.EndToEndTest
{
/// <summary>
/// Inherit this class in each test class. This does the following:<br/>
/// 1. Makes sure the user is logged in before each test starts<br/>
/// 2. Makes sure Playwright records traces for each test<br/>
/// 3. Exposes a <see cref="Step(string)"/> method to define test steps. These show up in the Playwright traces and in the test report.<br/>
/// 4. Builds a html test report after all tests in a test class are done.
/// We upload these to <a href="https://klantinteractie-servicesysteem.github.io/KISS-frontend/">github pages</a>
/// </summary>
[TestClass]
public class KissPlaywrightTest : PageTest
{
private const string StoragePath = "./auth.json";

private static readonly IConfiguration s_configuration = new ConfigurationBuilder()
.AddUserSecrets<KissPlaywrightTest>()
.AddEnvironmentVariables()
.Build();

private static readonly UniqueOtpHelper s_uniqueOtpHelper = new(GetRequiredConfig("TestSettings:TEST_TOTP_SECRET"));

// this is used to build a test report for each test
private static readonly ConcurrentDictionary<string, string> s_testReports = [];

private readonly List<string> _steps = [];

/// <summary>
/// This is run before each test
/// </summary>
/// <returns></returns>
[TestInitialize]
public virtual async Task TestInitialize()
{
// log in with azure ad
var username = GetRequiredConfig("TestSettings:TEST_USERNAME");
var password = GetRequiredConfig("TestSettings:TEST_PASSWORD");

var loginHelper = new AzureAdLoginHelper(Page, username, password, s_uniqueOtpHelper);
await loginHelper.LoginAsync();
// store the cookie so we stay logged in in each test
await Context.StorageStateAsync(new() { Path = StoragePath });

// start tracing. we do this AFTER logging in so the password doesn't end up in the tracing
await Context.Tracing.StartAsync(new()
{
Title = $"{TestContext.FullyQualifiedTestClassName}.{TestContext.TestName}",
Screenshots = true,
Snapshots = true,
Sources = true,
});
}

/// <summary>
/// Start a test step. This ends up in the test report and as group in the playwright tracing
/// </summary>
/// <param name="description"></param>
/// <returns></returns>
protected async Task Step(string description)
{
await Context.Tracing.GroupEndAsync();
await Context.Tracing.GroupAsync(description);
_steps.Add(description);
}

/// <summary>
/// This is run after each test
/// </summary>
/// <returns></returns>
[TestCleanup]
public async Task TestCleanup()
{
// if we are in a group, end it
await Context.Tracing.GroupEndAsync();
var fileName = $"{TestContext.FullyQualifiedTestClassName}.{TestContext.TestName}.zip";
var fullPath = Path.Combine(Environment.CurrentDirectory, "playwright-traces", fileName);

// stop tracing and save a zip file in the output directory
await Context.Tracing.StopAsync(new()
{
Path = fullPath
});

// build a html report containing the test steps and a link to the playwright traces viewer
var html = $"""
<div data-outcome="{TestContext.CurrentTestOutcome}">
<h2>{HtmlEncoder.Default.Encode(TestContext.TestName ?? "")}</h2>
<a target="_blank" href="https://trace.playwright.dev/?trace=https://klantinteractie-servicesysteem.github.io/KISS-frontend/{fileName}">Playwright tracing</a>
<p>Steps:</p>
<ol>{string.Join("", _steps.Select(step => $"""
<li>{HtmlEncoder.Default.Encode(step)}</li>
"""))}
</ol>
</div>
""";

s_testReports.TryAdd(TestContext.TestName!, html);
}

/// <summary>
/// This is run after all tests in a test class are done
/// </summary>
/// <returns></returns>
[ClassCleanup(InheritanceBehavior.BeforeEachDerivedClass)]
public static async Task ClassCleanup()
{
// combine the reports for each test in a single html file
var html = $$"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src https://unpkg.com/[email protected]/simple.min.css 'sha256-l0D//z1BZPnhAdIJ0lA8dsfuil0AB4xBpnOa/BhNVoU=';">
<title>Playwright traces</title>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/simple.min.css" integrity="sha384-Cxvt41nwdtHMOjpCqr+FaCybNL58LeIc0vPSLR4KlFSCBrHTb095iJbbw+hDTklQ" crossorigin="anonymous">
<style>[data-outcome=Failed]{color: var(--code)}[data-outcome=Inconclusive]{color: var(--text-light);font-style: italic;}[data-outcome=Inconclusive] a{display:none}</style>
</head>
<body>
<main>
{{string.Join("", s_testReports.OrderBy(x=> x.Key).Select(x=> x.Value))}}
</main>
</body>
""";

using var writer = File.CreateText(Path.Combine(Environment.CurrentDirectory, "playwright-traces", "index.html"));
await writer.WriteLineAsync(html);
}

private static string GetRequiredConfig(string key)
{
var value = s_configuration[key];
if (string.IsNullOrEmpty(value))
{
throw new InvalidOperationException($"'{key}' is missing from the configuration");
}
return value;
}

public override BrowserNewContextOptions ContextOptions()
{
return new(base.ContextOptions())
{
BaseURL = GetRequiredConfig("TestSettings:TEST_BASE_URL"),
// save auth state so we don't need to log in in every single test
StorageStatePath = File.Exists(StoragePath) ? StoragePath : null,
};
}
}
}
14 changes: 7 additions & 7 deletions Kiss.Bff.EndToEndTest/Kiss.Bff.EndToEndTest.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
Expand All @@ -12,12 +12,12 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.5.0" />
<PackageReference Include="MSTest.TestFramework" Version="3.5.0" />
<PackageReference Include="Microsoft.Playwright.MSTest" Version="1.45.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.6.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.6.4" />
<PackageReference Include="Microsoft.Playwright.MSTest" Version="1.49.0" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Loading
Loading