Skip to content

Instantly share code, notes, and snippets.

@GeorgDangl
Last active July 26, 2019 20:56
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save GeorgDangl/99d4649000834d825a5f717834a4dca4 to your computer and use it in GitHub Desktop.
Perfoming End-to-End Tests for a .NET Core Web API with an Angular Frontend in Docker with Jenkins
Target E2ETests => _ => _
.DependsOn(BuildDocker)
.DependsOn(Clean)
.Executes(async () =>
{
IProcess dockerComposeProcess = null;
// Start the docker environment in a non-blocking way
var dockerComposeUpTask = Task.Run(() =>
{
dockerComposeProcess = ProcessTasks.StartProcess("docker-compose", "up");
dockerComposeProcess.AssertWaitForExit();
});
await Task.Delay(5_000); // To give the Docker environment time to start
DotNetTest(c => c
.SetWorkingDirectory(SolutionDirectory / "test" / "Dangl.Identity.E2E.Tests")
.SetLogger($"xunit;LogFilePath={OutputDirectory / "testresults.xml"}")
.SetTestAdapterPath(".")
.SetConfiguration("Debug"));
ProcessTasks.StartProcess("docker-compose", "stop").AssertWaitForExit();
await dockerComposeUpTask;
});
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.1" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="75.0.3770.90" />
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
<PackageReference Include="XunitXml.TestLogger" Version="2.1.26" />
</ItemGroup>
</Project>
version: '3.4'
services:
dangl.identity:
image: danglidentity:dev
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:80
- IdentityServerSettings:UseDevelopmentSigningCredentials=true
- IdentityServerSettings:Authorities:0=localhost
- DanglIconsSettings:DanglIconsApiBaseUrl=http://dangl.icons
- DanglIconsSettings:DanglIconsFrontendBaseUrl=http://localhost:44849
- DanglIconsSettings:DanglIconsApiKey=DockerE2ETestsApiKey
- InitialAdminUserEmails:0=info@dangl-it.com
- InitialAdminPassword=DockerE2EAdminPassword
- ConnectionStrings:DefaultConnection=Data Source=sql.data;Initial Catalog=Dangl.Identity;Integrated Security=False;User ID=SA;Password=DockerSqlPass123
depends_on:
- dangl.icons
- sql.data
ports:
- "44848:80"
dangl.icons:
image: danglicons:dev
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:80
- IconAppConfiguration:AppFilesRootPath=/icons/
- IconAppConfiguration:EnforceHttps=false
- IconAppConfiguration:ApiKeys:0=DockerE2ETestsApiKey
ports:
- "44849:80"
expose:
- "80"
sql.data:
image: mcr.microsoft.com/mssql/server:2017-latest
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=DockerSqlPass123
ports:
- "5434:1433"
public class E2eTestsBase : IDisposable
{
protected readonly E2eTestsFixture _e2ETestsFixture;
protected readonly ChromeDriver _chromeDriver;
public E2eTestsBase(E2eTestsFixture e2ETestsFixture)
{
_e2ETestsFixture = e2ETestsFixture;
var assemblyLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var chromeOptions = new ChromeOptions();
chromeOptions.AddArgument("--lang=en");
if (!Debugger.IsAttached)
{
chromeOptions.AddArgument("--headless");
chromeOptions.AddArgument("--window-size=1920,1080");
}
_chromeDriver = new ChromeDriver(assemblyLocation, chromeOptions);
}
public void Dispose()
{
_chromeDriver.Dispose();
}
}
stage ('Docker E2E Tests') {
agent {
node {
label 'linux'
}
}
steps {
sh 'bash build.sh E2ETests'
}
post {
always {
xunit(
testTimeMargin: '3000',
thresholdMode: 1,
thresholds: [
failed(failureNewThreshold: '0', failureThreshold: '0', unstableNewThreshold: '0', unstableThreshold: '0'),
skipped(failureNewThreshold: '0', failureThreshold: '0', unstableNewThreshold: '0', unstableThreshold: '0')
],
tools: [
xUnitDotNet(deleteOutputFiles: true, failIfNotNew: true, pattern: '**/*testresults.xml', stopProcessingIfError: true)
])
}
}
}
public class RegistrationPage : E2eTestsBase
{
public RegistrationPage(E2eTestsFixture e2ETestsFixture) : base(e2ETestsFixture)
{
}
[Fact]
public async Task RegisterButtonDisabledWhenMissingUsername()
{
await NavigateAndFillOutRegistrationForm(string.Empty, "info@dangl-it.com", "LongEnoughPassword");
var registerButtonEnabled = RegisterButtonIsEnabled();
Assert.False(registerButtonEnabled);
}
private async Task NavigateAndFillOutRegistrationForm(string username, string email, string password)
{
_chromeDriver.Url = E2eTestsFixture.DANGL_IDENTITY_BASE_URL;
var registerButton = _chromeDriver.FindElement(By.XPath("//a[.='Register']"));
await registerButton.ClickAndWaitAsync();
var usernameFormField = _chromeDriver.FindElement(By.XPath("//input[@name='username']"));
var emailFormField = _chromeDriver.FindElement(By.XPath("//input[@name='email']"));
var passwordFormField = _chromeDriver.FindElement(By.XPath("//input[@name='password']"));
usernameFormField.SendKeys(username);
emailFormField.SendKeys(email);
passwordFormField.SendKeys(password);
var acceptTosCheckbox = _chromeDriver.FindElement(By.ClassName("mat-checkbox-inner-container"));
acceptTosCheckbox.Click();
await Task.Delay(E2eTestConstants.WAIT_TIME_AFTER_CLICKS);
}
private bool RegisterButtonIsEnabled()
{
var confirmRegisterButton = _chromeDriver.FindElement(By.XPath("//button[.='Register' and not(@routerlink)]"));
return confirmRegisterButton.Enabled;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment