From 469aa062dc94488ba09c5cdb6714fe73c3646717 Mon Sep 17 00:00:00 2001 From: Ashley Wilson Date: Wed, 10 Apr 2024 12:52:22 -0400 Subject: [PATCH 1/7] Scaffold playwright project for end-to-end tests --- README.md | 1 + .../HomepageTests.cs | 17 ++++++++++++++++ .../UDS.Net.Web.MVC.Services.Test.csproj | 12 +++++++++++ src/UDS.Net.sln | 20 ++++++++++++------- 4 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs create mode 100644 src/UDS.Net.Web.MVC.Services.Test/UDS.Net.Web.MVC.Services.Test.csproj diff --git a/README.md b/README.md index c8c5018b..b76ea81b 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ The software is implemented with several .NET tools and includes a development c Thank you for interest in contributing to our project! There are many ways you can help: * Submit bugs and feature requests [here](Discussions) * Submit a fix by forking and submitting a PR Request [here](CONTRIBUTING.md) +* This solution includes automated tooling for linting, unit testing, and end-to-end testing. Powershell is required. Read more in our [wiki](https://github.com/UK-SBCoA/uniform-data-set-dotnet/wiki) ## Security [Security reports](SECURITY.md) diff --git a/src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs b/src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs new file mode 100644 index 00000000..95e9f9fb --- /dev/null +++ b/src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs @@ -0,0 +1,17 @@ +using Microsoft.Playwright.MSTest; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace UDS.Net.Web.MVC.Services.Test; + +[TestClass] +public class HomepageTests : PageTest +{ + [TestMethod] + public async Task HomepageRedirectsIfNotAuthenticated() + { + await Page.GotoAsync(""); + + await Expect(Page).ToHaveURLAsync(""); + } +} + diff --git a/src/UDS.Net.Web.MVC.Services.Test/UDS.Net.Web.MVC.Services.Test.csproj b/src/UDS.Net.Web.MVC.Services.Test/UDS.Net.Web.MVC.Services.Test.csproj new file mode 100644 index 00000000..a7724b2e --- /dev/null +++ b/src/UDS.Net.Web.MVC.Services.Test/UDS.Net.Web.MVC.Services.Test.csproj @@ -0,0 +1,12 @@ + + + + net8.0 + enable + enable + + + + + + diff --git a/src/UDS.Net.sln b/src/UDS.Net.sln index 3c1a0bfa..11fded4a 100644 --- a/src/UDS.Net.sln +++ b/src/UDS.Net.sln @@ -9,13 +9,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UDS.Net.Forms", "UDS.Net.Fo EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UDS.Net.Services", "UDS.Net.Services\UDS.Net.Services.csproj", "{BD35F74B-9134-46F3-850D-7DF05F7397E4}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UDS.Net.Forms.Tests", "UDS.Net.Forms.Tests\UDS.Net.Forms.Tests.csproj", "{7A359BF3-B7F2-4962-A948-DAB0A996DA0F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UDS.Net.Forms.Tests", "UDS.Net.Forms.Tests\UDS.Net.Forms.Tests.csproj", "{7A359BF3-B7F2-4962-A948-DAB0A996DA0F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UDS.Net.Web.MVC.Services", "UDS.Net.Web.MVC.Services\UDS.Net.Web.MVC.Services.csproj", "{10B4A194-D9E4-491B-AF11-FF14F6108F5F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UDS.Net.Services.Test", "UDS.Net.Services.Test\UDS.Net.Services.Test.csproj", "{395296FB-4036-4FC9-A8DC-A50F96D35623}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UDS.Net.Services.Test", "UDS.Net.Services.Test\UDS.Net.Services.Test.csproj", "{395296FB-4036-4FC9-A8DC-A50F96D35623}" EndProject -Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "docker-compose", "docker-compose.dcproj", "{D137052A-E67B-4C5B-88A6-90D37D90653C}" +Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "docker-compose", "docker-compose.dcproj", "{0034C365-1FCA-4C7A-8218-BE84D9E22AC7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UDS.Net.Web.MVC.Services.Test", "UDS.Net.Web.MVC.Services.Test\UDS.Net.Web.MVC.Services.Test.csproj", "{E483538B-BB31-4A58-A3DE-BAF76AA6FE79}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -47,10 +49,14 @@ Global {395296FB-4036-4FC9-A8DC-A50F96D35623}.Debug|Any CPU.Build.0 = Debug|Any CPU {395296FB-4036-4FC9-A8DC-A50F96D35623}.Release|Any CPU.ActiveCfg = Release|Any CPU {395296FB-4036-4FC9-A8DC-A50F96D35623}.Release|Any CPU.Build.0 = Release|Any CPU - {D137052A-E67B-4C5B-88A6-90D37D90653C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D137052A-E67B-4C5B-88A6-90D37D90653C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D137052A-E67B-4C5B-88A6-90D37D90653C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D137052A-E67B-4C5B-88A6-90D37D90653C}.Release|Any CPU.Build.0 = Release|Any CPU + {0034C365-1FCA-4C7A-8218-BE84D9E22AC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0034C365-1FCA-4C7A-8218-BE84D9E22AC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0034C365-1FCA-4C7A-8218-BE84D9E22AC7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0034C365-1FCA-4C7A-8218-BE84D9E22AC7}.Release|Any CPU.Build.0 = Release|Any CPU + {E483538B-BB31-4A58-A3DE-BAF76AA6FE79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E483538B-BB31-4A58-A3DE-BAF76AA6FE79}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E483538B-BB31-4A58-A3DE-BAF76AA6FE79}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E483538B-BB31-4A58-A3DE-BAF76AA6FE79}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From b99c3d74ef96b145f7812941e3392fe3ebcac646 Mon Sep 17 00:00:00 2001 From: Ashley Wilson Date: Wed, 10 Apr 2024 17:19:50 -0400 Subject: [PATCH 2/7] Add to CI pipeline --- .github/workflows/playwright.yml | 30 ++++++++++++++++++++++++++++++ .gitignore | 1 + 2 files changed, 31 insertions(+) create mode 100644 .github/workflows/playwright.yml diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 00000000..1ea7a864 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,30 @@ +name: Playwright Tests + +on: + pull_request: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: '8.0.x' + + - name: Install dependencies + run: dotnet restore + + - name: Build + run: dotnet build --no-restore + + - name: Install Playwright + run: pwsh src/UDS.Net.Web.MVC.Services.Test/bin/Debug/net8.0/playwright.ps1 install --with-deps + + - name: Run tests + run: dotnet test src/UDS.Net.Web.MVC.Services.Test --no-build --verbosity normal \ No newline at end of file diff --git a/.gitignore b/.gitignore index d22f91a0..3b2a736a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .DS_Store appsettings.Development.json +[Pp]laywright/.auth # User-specific files *.rsuser From 39fdceafe37ad0336492d700bea7ccf8af53fee4 Mon Sep 17 00:00:00 2001 From: Ashley Wilson Date: Wed, 10 Apr 2024 17:20:05 -0400 Subject: [PATCH 3/7] Add examples --- .../HomepageTests.cs | 18 ++++++++---- .../UDS.Net.Web.MVC.Services.Test.csproj | 14 ++++++++- .../UnitTest1.cs | 29 +++++++++++++++++++ src/UDS.Net.sln | 20 ++++++------- 4 files changed, 65 insertions(+), 16 deletions(-) create mode 100644 src/UDS.Net.Web.MVC.Services.Test/UnitTest1.cs diff --git a/src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs b/src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs index 95e9f9fb..cd7b615d 100644 --- a/src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs +++ b/src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs @@ -1,5 +1,5 @@ -using Microsoft.Playwright.MSTest; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.Playwright; +using Microsoft.Playwright.MSTest; namespace UDS.Net.Web.MVC.Services.Test; @@ -7,11 +7,19 @@ namespace UDS.Net.Web.MVC.Services.Test; public class HomepageTests : PageTest { [TestMethod] - public async Task HomepageRedirectsIfNotAuthenticated() + public async Task HomepageHasNavigationToParticipations() { - await Page.GotoAsync(""); + await Page.GotoAsync("https://localhost:4811"); - await Expect(Page).ToHaveURLAsync(""); + //var participation = Page.GetByRole(AriaRole.Link, new() { Name = "Participation" }); + + //await Expect(participation).ToHaveAttributeAsync("href", "/Participations"); + + //var createButton = Page.GetByRole(AriaRole.Link, new() { Name = "New participation" }); + + //await Expect(createButton).ToHaveAttributeAsync("href", "/Participations/Create"); + + //await participation.ClickAsync(); } } diff --git a/src/UDS.Net.Web.MVC.Services.Test/UDS.Net.Web.MVC.Services.Test.csproj b/src/UDS.Net.Web.MVC.Services.Test/UDS.Net.Web.MVC.Services.Test.csproj index a7724b2e..9e1e2627 100644 --- a/src/UDS.Net.Web.MVC.Services.Test/UDS.Net.Web.MVC.Services.Test.csproj +++ b/src/UDS.Net.Web.MVC.Services.Test/UDS.Net.Web.MVC.Services.Test.csproj @@ -1,12 +1,24 @@ - + net8.0 enable enable + + false + true + + + + + + + + + diff --git a/src/UDS.Net.Web.MVC.Services.Test/UnitTest1.cs b/src/UDS.Net.Web.MVC.Services.Test/UnitTest1.cs new file mode 100644 index 00000000..72a8323f --- /dev/null +++ b/src/UDS.Net.Web.MVC.Services.Test/UnitTest1.cs @@ -0,0 +1,29 @@ +using Microsoft.Playwright; +using Microsoft.Playwright.MSTest; + +namespace UDS.Net.Web.MVC.Services.Test; + +[TestClass] +public class ParticipationTests : PageTest +{ + [TestMethod] + public async Task ParticipationHasCreateButton() + { + await Page.GotoAsync("https://localhost:4811/Participations"); + + //var createButton = Page.GetByRole(AriaRole.Link, new() { Name = "New participation" }); + + //await Expect(createButton).ToHaveAttributeAsync("href", "/Create"); + + //createButton.ClickAsync(); + //await page.GetByLabel("NACC IdParticipation.LegacyId").ClickAsync(); + //await page.GetByLabel("NACC IdParticipation.LegacyId").FillAsync("2000"); + //await page.GetByRole(AriaRole.Button, new() { Name = "Save" }).ClickAsync(); + //await page.GetByLabel("NACC IdParticipation.LegacyId").ClickAsync(); + //await page.GetByLabel("NACC IdParticipation.LegacyId").FillAsync("2001"); + //await page.GetByRole(AriaRole.Button, new() { Name = "Save" }).ClickAsync(); + //await page.GetByLabel("NACC IdParticipation.LegacyId").ClickAsync(); + //await page.GetByLabel("NACC IdParticipation.LegacyId").FillAsync("5000"); + //await page.GetByRole(AriaRole.Button, new() { Name = "Save" }).ClickAsync(); + } +} diff --git a/src/UDS.Net.sln b/src/UDS.Net.sln index 11fded4a..93443833 100644 --- a/src/UDS.Net.sln +++ b/src/UDS.Net.sln @@ -15,9 +15,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UDS.Net.Web.MVC.Services", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UDS.Net.Services.Test", "UDS.Net.Services.Test\UDS.Net.Services.Test.csproj", "{395296FB-4036-4FC9-A8DC-A50F96D35623}" EndProject -Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "docker-compose", "docker-compose.dcproj", "{0034C365-1FCA-4C7A-8218-BE84D9E22AC7}" +Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "docker-compose", "docker-compose.dcproj", "{EF687CA4-D15B-4E2F-97BA-64AAB218E395}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UDS.Net.Web.MVC.Services.Test", "UDS.Net.Web.MVC.Services.Test\UDS.Net.Web.MVC.Services.Test.csproj", "{E483538B-BB31-4A58-A3DE-BAF76AA6FE79}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UDS.Net.Web.MVC.Services.Test", "UDS.Net.Web.MVC.Services.Test\UDS.Net.Web.MVC.Services.Test.csproj", "{7879003A-AF57-4662-A66B-6A33FA09325C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -49,14 +49,14 @@ Global {395296FB-4036-4FC9-A8DC-A50F96D35623}.Debug|Any CPU.Build.0 = Debug|Any CPU {395296FB-4036-4FC9-A8DC-A50F96D35623}.Release|Any CPU.ActiveCfg = Release|Any CPU {395296FB-4036-4FC9-A8DC-A50F96D35623}.Release|Any CPU.Build.0 = Release|Any CPU - {0034C365-1FCA-4C7A-8218-BE84D9E22AC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0034C365-1FCA-4C7A-8218-BE84D9E22AC7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0034C365-1FCA-4C7A-8218-BE84D9E22AC7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0034C365-1FCA-4C7A-8218-BE84D9E22AC7}.Release|Any CPU.Build.0 = Release|Any CPU - {E483538B-BB31-4A58-A3DE-BAF76AA6FE79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E483538B-BB31-4A58-A3DE-BAF76AA6FE79}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E483538B-BB31-4A58-A3DE-BAF76AA6FE79}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E483538B-BB31-4A58-A3DE-BAF76AA6FE79}.Release|Any CPU.Build.0 = Release|Any CPU + {EF687CA4-D15B-4E2F-97BA-64AAB218E395}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF687CA4-D15B-4E2F-97BA-64AAB218E395}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF687CA4-D15B-4E2F-97BA-64AAB218E395}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF687CA4-D15B-4E2F-97BA-64AAB218E395}.Release|Any CPU.Build.0 = Release|Any CPU + {7879003A-AF57-4662-A66B-6A33FA09325C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7879003A-AF57-4662-A66B-6A33FA09325C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7879003A-AF57-4662-A66B-6A33FA09325C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7879003A-AF57-4662-A66B-6A33FA09325C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 91eba6a9618336d6d902b3d2d188a95339730f21 Mon Sep 17 00:00:00 2001 From: Ashley Wilson Date: Wed, 10 Apr 2024 17:22:10 -0400 Subject: [PATCH 4/7] Fix path to test proj --- .github/workflows/playwright.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 1ea7a864..ee82babf 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -17,11 +17,8 @@ jobs: with: dotnet-version: '8.0.x' - - name: Install dependencies - run: dotnet restore - - name: Build - run: dotnet build --no-restore + run: dotnet build src/UDS.Net.Web.MVC.Services.Test - name: Install Playwright run: pwsh src/UDS.Net.Web.MVC.Services.Test/bin/Debug/net8.0/playwright.ps1 install --with-deps From f35736ad1b855a9171fff72c3afbe2dae568aad1 Mon Sep 17 00:00:00 2001 From: Ashley Wilson Date: Thu, 11 Apr 2024 08:02:48 -0400 Subject: [PATCH 5/7] Run playwright tests on dispatch --- .github/workflows/playwright.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index ee82babf..bc3d2998 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -1,8 +1,10 @@ name: Playwright Tests on: - pull_request: - branches: [ main ] + repository_dispatch: + types: [playwright] + # schedule: + # - cron: '30 6 * * 1-5' jobs: build: From c1f0fe2fc8dd8ebb4510603c3b3a6796f39c688a Mon Sep 17 00:00:00 2001 From: Ashley Wilson Date: Fri, 12 Apr 2024 09:49:23 -0400 Subject: [PATCH 6/7] in-progress --- src/UDS.Net.Web.MVC.Services.Test/Startup.cs | 27 ++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/UDS.Net.Web.MVC.Services.Test/Startup.cs diff --git a/src/UDS.Net.Web.MVC.Services.Test/Startup.cs b/src/UDS.Net.Web.MVC.Services.Test/Startup.cs new file mode 100644 index 00000000..2bf010d0 --- /dev/null +++ b/src/UDS.Net.Web.MVC.Services.Test/Startup.cs @@ -0,0 +1,27 @@ +using System; +using Microsoft.Playwright; +using Microsoft.Playwright.MSTest; + +namespace UDS.Net.Web.MVC.Services.Test +{ + public class Startup : PageTest + { + [TestInitialize] + public async Task TestInitialize() + { + await Page.GotoAsync("Identity/Account/Login?ReturnUrl=%2F"); + + var loginButton = Page.GetByRole(AriaRole.Link, new() { Name = "Login" }); + + if (loginButton != null) + { + + } + else + { + // already authenticated + } + } + } +} + From 1d762f3be7b9d4baa000ca2ab6ec86e642bfcf0c Mon Sep 17 00:00:00 2001 From: Ashley Wilson Date: Fri, 12 Apr 2024 09:49:46 -0400 Subject: [PATCH 7/7] in-progress --- src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs | 2 +- src/UDS.Net.Web.MVC.Services.Test/appsettings.DEFAULT.json | 3 +++ src/UDS.Net.Web.MVC.Services.Test/appsettings.json | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 src/UDS.Net.Web.MVC.Services.Test/appsettings.DEFAULT.json create mode 100644 src/UDS.Net.Web.MVC.Services.Test/appsettings.json diff --git a/src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs b/src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs index cd7b615d..5eaf6682 100644 --- a/src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs +++ b/src/UDS.Net.Web.MVC.Services.Test/HomepageTests.cs @@ -9,7 +9,7 @@ public class HomepageTests : PageTest [TestMethod] public async Task HomepageHasNavigationToParticipations() { - await Page.GotoAsync("https://localhost:4811"); + await Page.GotoAsync("/"); //var participation = Page.GetByRole(AriaRole.Link, new() { Name = "Participation" }); diff --git a/src/UDS.Net.Web.MVC.Services.Test/appsettings.DEFAULT.json b/src/UDS.Net.Web.MVC.Services.Test/appsettings.DEFAULT.json new file mode 100644 index 00000000..593bede0 --- /dev/null +++ b/src/UDS.Net.Web.MVC.Services.Test/appsettings.DEFAULT.json @@ -0,0 +1,3 @@ +{ + "TestUrl": "https://localhost:4811" +} \ No newline at end of file diff --git a/src/UDS.Net.Web.MVC.Services.Test/appsettings.json b/src/UDS.Net.Web.MVC.Services.Test/appsettings.json new file mode 100644 index 00000000..19e338aa --- /dev/null +++ b/src/UDS.Net.Web.MVC.Services.Test/appsettings.json @@ -0,0 +1,3 @@ +{ + "TestUrl": "https://demo-uds.coa.uky.edu" +} \ No newline at end of file