Skip to content

Commit e9b6908

Browse files
Merge pull request #436 from NeoCoderMatrix86/414-use-end-to-end-tests
Use end to end tests
2 parents abd3aff + 1164ea9 commit e9b6908

6 files changed

Lines changed: 215 additions & 26 deletions

File tree

.github/workflows/run_tests.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Run tests
2+
3+
on:
4+
pull_request:
5+
6+
jobs:
7+
run-tests:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v4.2.2
11+
12+
- name: Set timestamp variable
13+
id: timestamp
14+
run: echo "datetime=$(date +'%Y-%m-%d_%H-%M-%S')" >> $GITHUB_OUTPUT
15+
16+
# version can be found here https://dotnet.microsoft.com/en-us/download/dotnet/9.0
17+
- name: Setup .NET
18+
uses: actions/setup-dotnet@v4
19+
with:
20+
dotnet-version: 9.0.x
21+
22+
- name: Install wasm-tools
23+
run: dotnet workload install wasm-tools
24+
25+
- name: Build & Install
26+
run: dotnet build
27+
- name: Ensure browsers are installed
28+
run: pwsh AudioCuesheetEditor.End2EndTests/bin/Debug/net9.0/playwright.ps1 install --with-deps
29+
30+
- name: Start App
31+
run: dotnet run --project AudioCuesheetEditor &
32+
33+
- name: Run tests
34+
run: dotnet test
35+
36+
- name: Upload traces
37+
if: always()
38+
uses: actions/upload-artifact@v4
39+
with:
40+
name: playwright-traces-${{ steps.timestamp.outputs.datetime }}
41+
path: AudioCuesheetEditor.End2EndTests/bin/Debug/net9.0/playwright-traces/
42+
if-no-files-found: ignore

.github/workflows/run_unit_tests.yml

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<LangVersion>latest</LangVersion>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<EnableMSTestRunner>true</EnableMSTestRunner>
9+
<OutputType>Exe</OutputType>
10+
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
11+
<!--
12+
Displays error on console in addition to the log file. Note that this feature comes with a performance impact.
13+
For more information, visit https://learn.microsoft.com/dotnet/core/testing/unit-testing-platform-integration-dotnet-test#show-failure-per-test
14+
-->
15+
<TestingPlatformShowTestsFailure>true</TestingPlatformShowTestsFailure>
16+
</PropertyGroup>
17+
18+
<ItemGroup>
19+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
20+
<PackageReference Include="Microsoft.Playwright.MSTest" Version="1.52.0" />
21+
<PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" Version="17.14.2" />
22+
<PackageReference Include="Microsoft.Testing.Extensions.TrxReport" Version="1.7.0" />
23+
<PackageReference Include="MSTest" Version="3.9.0" />
24+
</ItemGroup>
25+
26+
<ItemGroup>
27+
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
28+
</ItemGroup>
29+
30+
</Project>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Microsoft.Playwright;
2+
using Microsoft.Playwright.MSTest;
3+
4+
namespace AudioCuesheetEditor.End2EndTests.Pages
5+
{
6+
[TestClass]
7+
public class AboutTest : PageTest
8+
{
9+
[TestInitialize]
10+
public async Task TestInitialize()
11+
{
12+
await Context.Tracing.StartAsync(new()
13+
{
14+
Title = $"{TestContext.FullyQualifiedTestClassName}.{TestContext.TestName}",
15+
Screenshots = true,
16+
Snapshots = true,
17+
Sources = true
18+
});
19+
}
20+
21+
[TestCleanup]
22+
public async Task TestCleanup()
23+
{
24+
var failed = new[] { UnitTestOutcome.Failed, UnitTestOutcome.Error, UnitTestOutcome.Timeout, UnitTestOutcome.Aborted }.Contains(TestContext.CurrentTestOutcome);
25+
26+
await Context.Tracing.StopAsync(new()
27+
{
28+
Path = failed ? Path.Combine(
29+
Environment.CurrentDirectory,
30+
"playwright-traces",
31+
$"{TestContext.FullyQualifiedTestClassName}.{TestContext.TestName}.zip"
32+
) : null,
33+
});
34+
}
35+
36+
[TestMethod]
37+
public async Task HasTitle()
38+
{
39+
await Page.GotoAsync("http://localhost:5132/about");
40+
await Expect(Page).ToHaveTitleAsync("AudioCuesheetEditor");
41+
await Expect(Page.GetByRole(AriaRole.Heading, new() { Name = "About AudioCuesheetEditor" })).ToBeVisibleAsync();
42+
}
43+
}
44+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using Microsoft.Playwright;
2+
using Microsoft.Playwright.MSTest;
3+
using System.Text.RegularExpressions;
4+
5+
namespace AudioCuesheetEditor.End2EndTests.Pages
6+
{
7+
[TestClass]
8+
public class IndexTest : PageTest
9+
{
10+
[TestInitialize]
11+
public async Task TestInitialize()
12+
{
13+
await Context.Tracing.StartAsync(new()
14+
{
15+
Title = $"{TestContext.FullyQualifiedTestClassName}.{TestContext.TestName}",
16+
Screenshots = true,
17+
Snapshots = true,
18+
Sources = true
19+
});
20+
}
21+
22+
[TestCleanup]
23+
public async Task TestCleanup()
24+
{
25+
var failed = new[] { UnitTestOutcome.Failed, UnitTestOutcome.Error, UnitTestOutcome.Timeout, UnitTestOutcome.Aborted }.Contains(TestContext.CurrentTestOutcome);
26+
27+
await Context.Tracing.StopAsync(new()
28+
{
29+
Path = failed ? Path.Combine(
30+
Environment.CurrentDirectory,
31+
"playwright-traces",
32+
$"{TestContext.FullyQualifiedTestClassName}.{TestContext.TestName}.zip"
33+
) : null,
34+
});
35+
}
36+
37+
[TestMethod]
38+
public async Task HasTitle()
39+
{
40+
await Page.GotoAsync("http://localhost:5132/");
41+
await Expect(Page).ToHaveTitleAsync("AudioCuesheetEditor");
42+
await Expect(Page.GetByRole(AriaRole.Button, new() { Name = "AudioCuesheetEditor" })).ToBeVisibleAsync();
43+
}
44+
45+
[TestMethod]
46+
public async Task CheckSettings()
47+
{
48+
await Page.GotoAsync("http://localhost:5132/");
49+
await Page.GetByRole(AriaRole.Toolbar).GetByRole(AriaRole.Button).Filter(new() { HasTextRegex = new Regex("^$") }).Nth(3).ClickAsync();
50+
await Page.Locator("div").Filter(new() { HasTextRegex = new Regex("^Settings$") }).ClickAsync();
51+
await Expect(Page.GetByRole(AriaRole.Heading, new() { Name = "Settings" })).ToBeVisibleAsync();
52+
}
53+
54+
[TestMethod]
55+
public async Task Record()
56+
{
57+
await Page.GotoAsync("http://localhost:5132/");
58+
await Page.GetByText("Record view").ClickAsync();
59+
await Page.GetByRole(AriaRole.Button, new() { Name = "Start recording" }).ClickAsync();
60+
await Page.GetByRole(AriaRole.Textbox, new() { Name = "Artist", Exact = true }).ClickAsync();
61+
await Page.GetByRole(AriaRole.Textbox, new() { Name = "Artist", Exact = true }).FillAsync("Test Track 1 Artist");
62+
await Page.GetByRole(AriaRole.Textbox, new() { Name = "Artist", Exact = true }).PressAsync("Tab");
63+
await Page.GetByRole(AriaRole.Textbox, new() { Name = "Title", Exact = true }).FillAsync("Test Track 1 Title");
64+
await Page.GetByRole(AriaRole.Textbox, new() { Name = "Title", Exact = true }).PressAsync("Tab");
65+
await Page.GetByRole(AriaRole.Button, new() { Name = "Add track" }).ClickAsync();
66+
await Page.GetByRole(AriaRole.Textbox, new() { Name = "Artist", Exact = true }).FillAsync("Test Track 2 Artist");
67+
await Page.GetByRole(AriaRole.Textbox, new() { Name = "Artist", Exact = true }).PressAsync("Tab");
68+
await Page.GetByRole(AriaRole.Textbox, new() { Name = "Title", Exact = true }).FillAsync("Test Track 2 Title");
69+
await Page.GetByRole(AriaRole.Textbox, new() { Name = "Title", Exact = true }).PressAsync("Tab");
70+
await Page.GetByRole(AriaRole.Button, new() { Name = "Add track" }).ClickAsync();
71+
await Page.Locator(".mud-overlay").ClickAsync();
72+
await Page.GetByRole(AriaRole.Button, new() { Name = "Stop recording" }).ClickAsync();
73+
await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Test Track 1 Artist Clear" })).ToBeVisibleAsync();
74+
await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Test Track 1 Title Clear" })).ToBeVisibleAsync();
75+
await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Test Track 2 Artist Clear" })).ToBeVisibleAsync();
76+
await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Test Track 2 Title Clear" })).ToBeVisibleAsync();
77+
}
78+
79+
[TestMethod]
80+
public async Task Import()
81+
{
82+
await Page.GotoAsync("http://localhost:5132/");
83+
await Page.GetByText("Import view").ClickAsync();
84+
await Page.GetByRole(AriaRole.Button, new() { Name = "Choose File" }).SetInputFilesAsync(new[] { "../../../../AudioCuesheetEditor/wwwroot/samples/Sample_Inputfile.txt" });
85+
await Page.GetByRole(AriaRole.Button, new() { Name = "Complete" }).ClickAsync();
86+
await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Sample Artist 1 Clear" })).ToBeVisibleAsync();
87+
await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = ":20:13" }).Nth(1)).ToBeVisibleAsync();
88+
await Expect(Page.GetByRole(AriaRole.Textbox, new() { Name = "Cuesheet artist" })).ToHaveValueAsync("CuesheetArtist");
89+
await Page.GetByRole(AriaRole.Textbox, new() { Name = "Cuesheet title" }).ClickAsync();
90+
await Expect(Page.GetByRole(AriaRole.Group).Filter(new() { HasText = "AudiofileAudiofile Search" }).Locator("input[type=\"file\"]")).ToBeEmptyAsync();
91+
}
92+
}
93+
}

AudioCuesheetEditor.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AudioCuesheetEditor", "Audi
77
EndProject
88
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AudioCuesheetEditor.Tests", "AudioCuesheetEditor.Tests\AudioCuesheetEditor.Tests.csproj", "{12CA5D1F-D758-4016-85D0-A045AC06CFE6}"
99
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AudioCuesheetEditor.End2EndTests", "AudioCuesheetEditor.End2EndTests\AudioCuesheetEditor.End2EndTests.csproj", "{7297DF58-3F83-49E9-B714-B2BE29D08180}"
11+
EndProject
1012
Global
1113
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1214
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,10 @@ Global
2123
{12CA5D1F-D758-4016-85D0-A045AC06CFE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
2224
{12CA5D1F-D758-4016-85D0-A045AC06CFE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
2325
{12CA5D1F-D758-4016-85D0-A045AC06CFE6}.Release|Any CPU.Build.0 = Release|Any CPU
26+
{7297DF58-3F83-49E9-B714-B2BE29D08180}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27+
{7297DF58-3F83-49E9-B714-B2BE29D08180}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{7297DF58-3F83-49E9-B714-B2BE29D08180}.Release|Any CPU.ActiveCfg = Release|Any CPU
29+
{7297DF58-3F83-49E9-B714-B2BE29D08180}.Release|Any CPU.Build.0 = Release|Any CPU
2430
EndGlobalSection
2531
GlobalSection(SolutionProperties) = preSolution
2632
HideSolutionNode = FALSE

0 commit comments

Comments
 (0)