Skip to content

Commit 0375bb9

Browse files
committed
Merge Accessibility to EnglishIvy 1.3.1
2 parents 61464c8 + b0b4cde commit 0375bb9

13 files changed

+560
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
namespace LearningHub.Nhs.WebUI.AutomatedUiTests.AccessibilityTests
2+
{
3+
using FluentAssertions;
4+
using LearningHub.Nhs.WebUI.AutomatedUiTests.TestFixtures;
5+
using LearningHub.Nhs.WebUI.Startup;
6+
using OpenQA.Selenium;
7+
using Selenium.Axe;
8+
using Xunit;
9+
10+
/// <summary>
11+
/// Accessibility Tests Base.
12+
/// </summary>
13+
[Collection("Selenium test collection")]
14+
public class AccessibilityTestsBase
15+
{
16+
/// <summary>
17+
/// Gets the base URL for the tests.
18+
/// </summary>
19+
internal readonly string BaseUrl;
20+
21+
/// <summary>
22+
/// Gets the WebDriver used for the tests.
23+
/// </summary>
24+
internal readonly IWebDriver Driver;
25+
26+
/// <summary>
27+
/// Initializes a new instance of the <see cref="AccessibilityTestsBase"/> class.
28+
/// </summary>
29+
/// <param name="fixture">fixture.</param>
30+
public AccessibilityTestsBase(AccessibilityTestsFixture fixture)
31+
{
32+
this.BaseUrl = fixture.BaseUrl;
33+
this.Driver = fixture.Driver;
34+
}
35+
36+
/// <summary>
37+
/// Analyze Page Heading And Accessibility.
38+
/// </summary>
39+
/// <param name="pageTitle">Page Title.</param>
40+
public void AnalyzePageHeadingAndAccessibility(string pageTitle)
41+
{
42+
this.ValidatePageHeading(pageTitle);
43+
44+
// then
45+
var axeResult = new AxeBuilder(this.Driver).Analyze();
46+
axeResult.Violations.Should().BeEmpty();
47+
}
48+
49+
/// <summary>
50+
/// ValidatePageHeading.
51+
/// </summary>
52+
/// <param name="pageTitle">Page Title.</param>
53+
public void ValidatePageHeading(string pageTitle)
54+
{
55+
var h1Element = this.Driver.FindElement(By.TagName("h1"));
56+
h1Element.Text.Should().BeEquivalentTo(pageTitle);
57+
}
58+
}
59+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
namespace LearningHub.Nhs.WebUI.AutomatedUiTests.AccessibilityTests
2+
{
3+
using LearningHub.Nhs.WebUI.AutomatedUiTests.TestFixtures;
4+
using Xunit;
5+
6+
/// <summary>
7+
/// BasicAccessibilityTests.
8+
/// </summary>
9+
public class BasicAccessibilityTests : AccessibilityTestsBase, IClassFixture<AccessibilityTestsFixture>
10+
{
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="BasicAccessibilityTests"/> class.
13+
/// BasicAccessibilityTests.
14+
/// </summary>
15+
/// <param name="fixture">fixture.</param>
16+
public BasicAccessibilityTests(AccessibilityTestsFixture fixture)
17+
: base(fixture)
18+
{
19+
}
20+
21+
[Theory]
22+
[InlineData("/Home/Index", "A platform for learning and sharing resources")]
23+
24+
public void PageHasNoAccessibilityErrors(string url, string pageTitle)
25+
{
26+
// when
27+
this.Driver.Navigate().GoToUrl(this.BaseUrl + url);
28+
29+
// then
30+
this.AnalyzePageHeadingAndAccessibility(pageTitle);
31+
32+
this.Driver.Dispose();
33+
}
34+
}
35+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
namespace LearningHub.Nhs.WebUI.AutomatedUiTests.AccessibilityTests
2+
{
3+
using FluentAssertions;
4+
using LearningHub.Nhs.WebUI.AutomatedUiTests.TestFixtures;
5+
using LearningHub.Nhs.WebUI.AutomatedUiTests.TestHelpers;
6+
using Selenium.Axe;
7+
using Xunit;
8+
9+
/// <summary>
10+
/// MyAccountAccessibiltyTests.
11+
/// </summary>
12+
public class MyAccountAccessibiltyTests : AccessibilityTestsBase,
13+
IClassFixture<AuthenticatedAccessibilityTestsFixture>
14+
{
15+
/// <summary>
16+
/// Initializes a new instance of the <see cref="MyAccountAccessibiltyTests"/> class.
17+
/// MyAccountAccessibiltyTests.
18+
/// </summary>
19+
/// <param name="fixture">fixture.</param>
20+
public MyAccountAccessibiltyTests(AuthenticatedAccessibilityTestsFixture fixture)
21+
: base(fixture)
22+
{
23+
}
24+
25+
/// <summary>
26+
/// MyAccount Page Has Accessibility Errors.
27+
/// </summary>
28+
[Fact]
29+
public void MyAccountPageHasAccessibilityErrors()
30+
{
31+
// given
32+
const string myaccountsUrl = "/myaccount";
33+
34+
// when
35+
this.Driver.Navigate().GoToUrl(this.BaseUrl + myaccountsUrl);
36+
var result = new AxeBuilder(this.Driver).Analyze();
37+
38+
// then
39+
CheckAccessibilityResult(result);
40+
41+
// Dispose driver
42+
this.Driver.LogOutUser(this.BaseUrl);
43+
}
44+
45+
private static void CheckAccessibilityResult(AxeResult result)
46+
{
47+
// Expect axe violation
48+
result.Violations.Should().HaveCount(6);
49+
50+
var violation = result.Violations[1];
51+
52+
violation.Id.Should().Be("landmark-contentinfo-is-top-level");
53+
violation.Nodes.Should().HaveCount(1);
54+
violation.Nodes[0].Target.Should().HaveCount(1);
55+
violation.Nodes[0].Target[0].Selector.Should().Be("footer > footer");
56+
}
57+
}
58+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// This file is used by Code Analysis to maintain SuppressMessage
2+
// attributes that are applied to this project.
3+
// Project-level suppressions either have no target or are given
4+
// a specific target and scoped to a namespace, type, member, etc.
5+
6+
using System.Diagnostics.CodeAnalysis;
7+
8+
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Allowed", Scope = "member", Target = "~F:LearningHub.Nhs.WebUI.AutomatedUiTests.SeleniumServerFactory.RootUri")]
9+
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Allowed", Scope = "member", Target = "~F:LearningHub.Nhs.WebUI.AutomatedUiTests.TestFixtures.AccessibilityTestsFixture.Driver")]
10+
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Allowed", Scope = "member", Target = "~F:LearningHub.Nhs.WebUI.AutomatedUiTests.TestFixtures.AccessibilityTestsFixture.BaseUrl")]
11+
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Allowed", Scope = "member", Target = "~F:LearningHub.Nhs.WebUI.AutomatedUiTests.AccessibilityTests.AccessibilityTestsBase.BaseUrl")]
12+
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Allowed", Scope = "member", Target = "~F:LearningHub.Nhs.WebUI.AutomatedUiTests.AccessibilityTests.AccessibilityTestsBase.Driver")]
13+
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Regions allowed", Scope = "member", Target = "~M:LearningHub.Nhs.WebUI.AutomatedUiTests.AccessibilityTests.BasicAccessibilityTests.PageHasNoAccessibilityErrors(System.String,System.String)")]
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>false</IsPackable>
9+
10+
<GenerateDocumentationFile>True</GenerateDocumentationFile>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<None Remove="appsettings.Development.json" />
15+
<None Remove="appsettings.json" />
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<Content Include="appsettings.Development.json">
20+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
21+
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
22+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
23+
</Content>
24+
<Content Include="appsettings.json">
25+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
26+
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
27+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
28+
</Content>
29+
</ItemGroup>
30+
31+
<ItemGroup>
32+
<PackageReference Include="FluentAssertions" Version="6.12.0" />
33+
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.13" />
34+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
35+
<PackageReference Include="Selenium.Axe" Version="4.0.16" />
36+
<PackageReference Include="Selenium.Support" Version="4.17.0" />
37+
<PackageReference Include="Selenium.WebDriver" Version="4.17.0" />
38+
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="121.0.6167.18400" />
39+
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
40+
<PackageReference Include="xunit" Version="2.4.1" />
41+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
42+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
43+
<PrivateAssets>all</PrivateAssets>
44+
</PackageReference>
45+
<PackageReference Include="coverlet.collector" Version="1.3.0">
46+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
47+
<PrivateAssets>all</PrivateAssets>
48+
</PackageReference>
49+
</ItemGroup>
50+
51+
<ItemGroup>
52+
<ProjectReference Include="..\LearningHub.Nhs.WebUI\LearningHub.Nhs.WebUI.csproj" />
53+
</ItemGroup>
54+
55+
</Project>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
namespace LearningHub.Nhs.WebUI.AutomatedUiTests
2+
{
3+
using System;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.IO;
7+
using System.Linq;
8+
using System.Linq;
9+
using System.Text;
10+
using System.Threading.Tasks;
11+
using LearningHub.Nhs.WebUI.AutomatedUiTests.TestHelpers;
12+
using LearningHub.Nhs.WebUI.Startup;
13+
using Microsoft.AspNetCore;
14+
using Microsoft.AspNetCore.Hosting;
15+
using Microsoft.AspNetCore.Hosting.Server.Features;
16+
using Microsoft.AspNetCore.Mvc.Testing;
17+
using Microsoft.AspNetCore.TestHost;
18+
using Microsoft.Extensions.Configuration;
19+
using Microsoft.Extensions.Configuration.Json;
20+
using Serilog;
21+
22+
/// <summary>
23+
/// SeleniumServerFactory.
24+
/// </summary>
25+
public class SeleniumServerFactory
26+
{
27+
/// <summary>
28+
/// Root Uri.
29+
/// </summary>
30+
public string RootUri;
31+
32+
/// <summary>
33+
/// Initializes a new instance of the <see cref="SeleniumServerFactory"/> class.
34+
/// </summary>
35+
public SeleniumServerFactory()
36+
{
37+
IConfiguration configuration = ConfigurationHelper.GetConfiguration();
38+
this.RootUri = configuration["LearningHubWebUiUrl"];
39+
}
40+
}
41+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
namespace LearningHub.Nhs.WebUI.AutomatedUiTests.TestFixtures
2+
{
3+
using LearningHub.Nhs.WebUI.AutomatedUiTests.TestHelpers;
4+
using OpenQA.Selenium;
5+
6+
/// <summary>
7+
/// Represents a fixture for accessibility tests.
8+
/// </summary>
9+
public class AccessibilityTestsFixture
10+
{
11+
/// <summary>
12+
/// Gets the base URL for the tests.
13+
/// </summary>
14+
internal readonly string BaseUrl;
15+
16+
/// <summary>
17+
/// Gets the WebDriver used for the tests.
18+
/// </summary>
19+
internal readonly IWebDriver Driver;
20+
21+
private readonly SeleniumServerFactory factory;
22+
23+
/// <summary>
24+
/// Initializes a new instance of the <see cref="AccessibilityTestsFixture"/> class.
25+
/// </summary>
26+
public AccessibilityTestsFixture()
27+
{
28+
this.factory = new SeleniumServerFactory();
29+
this.BaseUrl = this.factory.RootUri;
30+
this.Driver = DriverHelper.CreateHeadlessChromeDriver();
31+
}
32+
33+
/// <summary>
34+
/// Dispose.
35+
/// </summary>
36+
public void Dispose()
37+
{
38+
this.Driver.Quit();
39+
this.Driver.Dispose();
40+
}
41+
}
42+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
namespace LearningHub.Nhs.WebUI.AutomatedUiTests.TestFixtures
2+
{
3+
using LearningHub.Nhs.WebUI.AutomatedUiTests.TestHelpers;
4+
using Microsoft.Extensions.Configuration;
5+
6+
/// <summary>
7+
/// AuthenticatedAccessibilityTestsFixture.
8+
/// </summary>
9+
/// <typeparam name="TStartup">TStartup.</typeparam>
10+
public class AuthenticatedAccessibilityTestsFixture : AccessibilityTestsFixture
11+
{
12+
/// <summary>
13+
/// Initializes a new instance of the <see cref="AuthenticatedAccessibilityTestsFixture"/> class.
14+
/// </summary>
15+
public AuthenticatedAccessibilityTestsFixture()
16+
{
17+
IConfiguration configuration = ConfigurationHelper.GetConfiguration();
18+
string adminUsername = configuration["AdminUser:Username"];
19+
string adminPassword = configuration["AdminUser:Password"];
20+
this.Driver.LogUserInAsAdmin(this.BaseUrl, adminUsername, adminPassword);
21+
}
22+
23+
/// <summary>
24+
/// Dispose.
25+
/// </summary>
26+
public new void Dispose()
27+
{
28+
this.Driver.LogOutUser(this.BaseUrl);
29+
base.Dispose();
30+
}
31+
}
32+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace LearningHub.Nhs.WebUI.AutomatedUiTests.TestHelpers
2+
{
3+
using Microsoft.Extensions.Configuration;
4+
5+
/// <summary>
6+
/// ConfigurationHelper.
7+
/// </summary>
8+
public static class ConfigurationHelper
9+
{
10+
/// <summary>
11+
/// GetConfiguration.
12+
/// </summary>
13+
/// <returns>IConfiguration.</returns>
14+
public static IConfiguration GetConfiguration()
15+
{
16+
return new ConfigurationBuilder()
17+
.SetBasePath(Directory.GetCurrentDirectory())
18+
.AddJsonFile("appsettings.Development.json")
19+
.Build();
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)