Skip to content

Commit

Permalink
Playwright E2E tests (#4709)
Browse files Browse the repository at this point in the history
* Delete Selenium E2E Tests. Add Playwright E2E Tests.

* Carry over more playwright / bunit changes

* update ci

* add .runsettings

* update build.cmd

* remove blank folders for now

* removed failing test on mladen's machine from execution

* ValidateTextEditComponentTest as async

* Autocomplete bunit tests as async

* Clean readme

* Remove unused settings

* Refactor BasicTestApp.Server.Program. Don't Use TopLevelStatements.

---------

Co-authored-by: Mladen Macanovic <[email protected]>
  • Loading branch information
David-Moreira and stsrki authored Mar 31, 2023
1 parent 1081046 commit 8cb5ed9
Show file tree
Hide file tree
Showing 76 changed files with 1,610 additions and 3,188 deletions.
12 changes: 9 additions & 3 deletions .github/workflows/blazorise-ci-basic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Setup .NET 6
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v3
with:
dotnet-version: '6.0.x'
include-prerelease: true

- name: Setup .NET 7
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v3
with:
dotnet-version: '7.0.x'
include-prerelease: true
Expand All @@ -30,3 +30,9 @@ jobs:

- name: Run Unit Tests - Release
run: dotnet test ./Tests/Blazorise.Tests/Blazorise.Tests.csproj --configuration Release --no-restore --no-build --verbosity normal

- name: Prepare E2E Tests Dependencies
run: pwsh ./Tests/Blazorise.E2E.Tests/bin/Release/net7.0/playwright.ps1 install --with-deps

- name: Run E2E Tests - Release
run: dotnet test ./Tests/Blazorise.E2E.Tests/Blazorise.E2E.Tests.csproj --configuration Release --no-restore --no-build --verbosity normal
23 changes: 23 additions & 0 deletions .runsettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<RunSettings>

<NUnit>
<NumberOfTestWorkers>4</NumberOfTestWorkers>
</NUnit>

<RunConfiguration>
<EnvironmentVariables>
<!-- For debugging selectors, it's recommend to set the following environment variable -->
<!--<DEBUG>pw:api</DEBUG>-->
</EnvironmentVariables>
</RunConfiguration>

<Playwright>
<BrowserName>chromium</BrowserName>
<LaunchOptions>
<Headless>true</Headless>
<Args>--disable-gpu --no-sandbox</Args>
<Channel>msedge</Channel>
</LaunchOptions>
</Playwright>
</RunSettings>
15 changes: 8 additions & 7 deletions Blazorise.sln
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D1FF70C6-E002-47C3-B2D0-D0FFEF2BF37A}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.runsettings = .runsettings
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazorise.Charts.Streaming", "Source\Extensions\Blazorise.Charts.Streaming\Blazorise.Charts.Streaming.csproj", "{9AA305DA-A667-49E6-BDDA-7C976AD5BB3B}"
Expand All @@ -62,8 +63,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TodoApp", "Demos\Apps\TodoA
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apps", "Apps", "{47240431-396C-4187-941A-9511D7B79D8D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazorise.E2ETests", "Tests\Blazorise.E2ETests\Blazorise.E2ETests.csproj", "{A4218BB6-81C3-47A6-80F2-6FF6E227D142}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazorise.Tests", "Tests\Blazorise.Tests\Blazorise.Tests.csproj", "{8D91050E-1ACF-40C5-9DA4-5F94AB149A5E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazorise.RichTextEdit", "Source\Extensions\Blazorise.RichTextEdit\Blazorise.RichTextEdit.csproj", "{EB4A0C35-C45D-4F0F-BF03-3ACFB53CB865}"
Expand Down Expand Up @@ -129,6 +128,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazorise.Tailwind", "Sourc
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazorise.Demo.Tailwind", "Demos\Blazorise.Demo.Tailwind\Blazorise.Demo.Tailwind.csproj", "{47EEB5B2-3CA1-436C-8317-E69F611FA1E3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazorise.E2E.Tests", "Tests\Blazorise.E2E.Tests\Blazorise.E2E.Tests.csproj", "{FA75DC9B-32F0-41DC-A51D-F851E79D62DB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -223,10 +224,6 @@ Global
{FD072A38-6D23-49C1-93F9-4D7584A8A4A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD072A38-6D23-49C1-93F9-4D7584A8A4A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD072A38-6D23-49C1-93F9-4D7584A8A4A7}.Release|Any CPU.Build.0 = Release|Any CPU
{A4218BB6-81C3-47A6-80F2-6FF6E227D142}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A4218BB6-81C3-47A6-80F2-6FF6E227D142}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4218BB6-81C3-47A6-80F2-6FF6E227D142}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A4218BB6-81C3-47A6-80F2-6FF6E227D142}.Release|Any CPU.Build.0 = Release|Any CPU
{8D91050E-1ACF-40C5-9DA4-5F94AB149A5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8D91050E-1ACF-40C5-9DA4-5F94AB149A5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8D91050E-1ACF-40C5-9DA4-5F94AB149A5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -339,6 +336,10 @@ Global
{47EEB5B2-3CA1-436C-8317-E69F611FA1E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47EEB5B2-3CA1-436C-8317-E69F611FA1E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{47EEB5B2-3CA1-436C-8317-E69F611FA1E3}.Release|Any CPU.Build.0 = Release|Any CPU
{FA75DC9B-32F0-41DC-A51D-F851E79D62DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA75DC9B-32F0-41DC-A51D-F851E79D62DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA75DC9B-32F0-41DC-A51D-F851E79D62DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA75DC9B-32F0-41DC-A51D-F851E79D62DB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -368,7 +369,6 @@ Global
{4DEB65E7-40BA-409E-9C26-6EF75ADF2601} = {C2D0A89F-530E-413F-9D0E-9EE2129A2275}
{FD072A38-6D23-49C1-93F9-4D7584A8A4A7} = {47240431-396C-4187-941A-9511D7B79D8D}
{47240431-396C-4187-941A-9511D7B79D8D} = {C2D0A89F-530E-413F-9D0E-9EE2129A2275}
{A4218BB6-81C3-47A6-80F2-6FF6E227D142} = {D04C5874-4D6A-493E-8CF4-6C7922198563}
{8D91050E-1ACF-40C5-9DA4-5F94AB149A5E} = {D04C5874-4D6A-493E-8CF4-6C7922198563}
{EB4A0C35-C45D-4F0F-BF03-3ACFB53CB865} = {9731051E-0AA7-411E-A76A-987854F034DA}
{83B3D727-2C23-4A95-8478-85A854BA8325} = {9731051E-0AA7-411E-A76A-987854F034DA}
Expand Down Expand Up @@ -397,6 +397,7 @@ Global
{F9515890-3956-47A7-A8BB-B27333F4FC57} = {C2D0A89F-530E-413F-9D0E-9EE2129A2275}
{452E1C4E-F81A-46EC-AA86-7CC53FB1BCB3} = {73CD9574-5204-442D-A67C-CA7B038057C2}
{47EEB5B2-3CA1-436C-8317-E69F611FA1E3} = {C2D0A89F-530E-413F-9D0E-9EE2129A2275}
{FA75DC9B-32F0-41DC-A51D-F851E79D62DB} = {D04C5874-4D6A-493E-8CF4-6C7922198563}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {205B3EA4-470F-45DA-911E-346AF7D0A9A5}
Expand Down
3 changes: 1 addition & 2 deletions Tests/BasicTestApp.Client/BasicTestApp.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<OutputType>Exe</OutputType>
<LangVersion>10.0</LangVersion>
<GenerateBlazorWebAssemblyDepsFile>true</GenerateBlazorWebAssemblyDepsFile>
</PropertyGroup>

<ItemGroup>
Expand Down
38 changes: 23 additions & 15 deletions Tests/BasicTestApp.Server/Program.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Logging;

namespace BasicTestApp.Server;

public class Program
public partial class Program
{
public static void Main( string[] args )
{
BuildWebHost( args ).Run();
var builder = WebApplication.CreateBuilder( args );
builder.Logging.ClearProviders();

WebApplication app = builder.Build();

//app.UseWebAssemblyDebugging();
//app.UseHttpsRedirection();

app.UseBlazorFrameworkFiles();
app.UseStaticFiles();

app.UseRouting();

app.MapFallbackToFile( "index.html" );

app.Run();
}
}

public partial class Program { }

public static IWebHost BuildWebHost( string[] args ) =>
WebHost.CreateDefaultBuilder( args )
.UseConfiguration( new ConfigurationBuilder()
.AddCommandLine( args )
.Build() )
.UseStartup<Startup>()
.UseStaticWebAssets()
.Build();
}
42 changes: 0 additions & 42 deletions Tests/BasicTestApp.Server/Startup.cs

This file was deleted.

27 changes: 27 additions & 0 deletions Tests/Blazorise.E2E.Tests/Blazorise.E2E.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="Microsoft.Playwright.NUnit" Version="1.31.1" />
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\BasicTestApp.Server\BasicTestApp.Server.csproj" />
</ItemGroup>

</Project>
46 changes: 46 additions & 0 deletions Tests/Blazorise.E2E.Tests/DefaultExampleTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
namespace Blazorise.E2E.Tests;


[Parallelizable( ParallelScope.Self )]
[TestFixture]
public class DefaultExampleTests : PageTest
{
/// <summary>
/// This test serves as simple example of how to use Playwright. This was taken off playwright .NET docs.
/// </summary>
/// <returns></returns>
//[Test]
public async Task HomepageHasPlaywrightInTitleAndGetStartedLinkLinkingtoTheIntroPage()
{
// Pause on the following line.
await Page.PauseAsync();

await Page.GotoAsync( "https://playwright.dev" );

// Expect a title "to contain" a substring.
await Expect( Page ).ToHaveTitleAsync( new Regex( "Playwright" ) );

// create a locator
var getStarted = Page.GetByRole( AriaRole.Link, new() { Name = "Get started" } );

// Expect an attribute "to be strictly equal" to the value.
await Expect( getStarted ).ToHaveAttributeAsync( "href", "/docs/intro" );

// Click the get started link.
await getStarted.ClickAsync();

// Expects the URL to contain intro.
await Expect( Page ).ToHaveURLAsync( new Regex( ".*intro" ) );
}
}

[Parallelizable( ParallelScope.Self )]
[TestFixture]
public class CopyMeTests : BlazorisePageTest
{
[Test]
public async Task CopyMe()
{
await SelectTestComponent<ButtonComponent>();
}
}
61 changes: 61 additions & 0 deletions Tests/Blazorise.E2E.Tests/Infrastructure/BlazorPageTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Microsoft.AspNetCore.Mvc.Testing;

namespace Blazorise.E2E.Tests.Infrastructure;

/// <summary>
/// Credit to : https://www.youtube.com/watch?v=lJa3YlUliEs
/// </summary>
public class BlazorPageTest : PageTest
{

protected static readonly Uri RootUri = new( "http://localhost:14695" );

private readonly WebApplicationFactory<BasicTestApp.Server.Program> _webApplicationFactory = new() { };
private HttpClient _httpClient;

[SetUp]
public async Task Setup()
{
_httpClient = _webApplicationFactory.CreateClient( new()
{
BaseAddress = RootUri,
} );

await Context.RouteAsync( $"{RootUri.AbsoluteUri}**", async route =>
{
var request = route.Request;
var content = request.PostDataBuffer is { } postDataBuffer
? new ByteArrayContent( postDataBuffer )
: null;

var requestMessage = new HttpRequestMessage( new( request.Method ), request.Url )
{
Content = content
};

foreach ( var header in request.Headers )
{
requestMessage.Headers.Add( header.Key, header.Value );
}

var response = await _httpClient.SendAsync( requestMessage );
var responseBody = await response.Content.ReadAsByteArrayAsync();
var responseHeaders = response.Content.Headers.Select( x => KeyValuePair.Create( x.Key, x.Value.FirstOrDefault() ?? string.Empty ) );

await route.FulfillAsync( new()
{
BodyBytes = responseBody,
Headers = responseHeaders,
Status = (int)response.StatusCode
} );

} );
}

[TearDown]
public void TearDown()
{
_httpClient?.Dispose();
}

}
35 changes: 35 additions & 0 deletions Tests/Blazorise.E2E.Tests/Infrastructure/BlazorisePageTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Microsoft.AspNetCore.Components;

namespace Blazorise.E2E.Tests.Infrastructure;


public class BlazorisePageTest : BlazorPageTest
{
/// <summary>
/// Override browser context options if needed.
/// </summary>
/// <returns></returns>
public override BrowserNewContextOptions ContextOptions()
{
return new BrowserNewContextOptions()
{
Locale = "en-US"
};
}

/// <summary>
/// This is an helper specific to our test project, where we have a dropdown selection with the full name of the components.
/// This will also navigate to the root page.
/// </summary>
/// <typeparam name="TComponent"></typeparam>
/// <returns></returns>
protected async Task SelectTestComponent<TComponent>() where TComponent : IComponent
{
await Page.GotoAsync( RootUri.AbsoluteUri );

var componentTypeName = typeof( TComponent ).FullName;
await Page.GetByRole( AriaRole.Combobox ).SelectOptionAsync( new[] { componentTypeName } );
}


}
Loading

0 comments on commit 8cb5ed9

Please sign in to comment.