Skip to content

Commit

Permalink
Code quality
Browse files Browse the repository at this point in the history
  • Loading branch information
huaxing-yuan committed May 3, 2024
1 parent f0528cf commit a1c95a1
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 89 deletions.
3 changes: 2 additions & 1 deletion src/AxaFrance.AxeExtended.HtmlReport/BaseResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public int? ScoreRotation
{
get
{
if (_scoreRotation == null) GetScore(); return _scoreRotation;
if (_scoreRotation == null) GetScore();
return _scoreRotation;
}
set
{
Expand Down
8 changes: 5 additions & 3 deletions src/AxaFrance.AxeExtended.HtmlReport/Config/Rule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ namespace AxaFrance.AxeExtended.HtmlReport.Config
/// </summary>
public class Rule
{
private static Check[] emptyCheck = new Check[0];

/// <summary>
/// string(required). This uniquely identifies the rule. If the rule already exists, it will be overridden with any of the attributes supplied.
/// The attributes below that are marked required, are only required for new rules.
Expand Down Expand Up @@ -61,16 +63,16 @@ public class Rule
/// array(optional, default []). This is a list of checks that, if none "pass", will generate a violation
/// </summary>
[JsonProperty]
public Check[] Any { get; set; } = new Check[0];
public Check[] Any { get; set; } = emptyCheck;

/// <summary>
/// array(optional, default []). This is a list of checks that, if any "fails", will generate a violation.
/// </summary>
public Check[] All { get; set; } = new Check[0];
public Check[] All { get; set; } = emptyCheck;

/// <summary>
/// array(optional, default []). This is a list of checks that, if any "pass", will generate a violation.
/// </summary>
public Check[] None { get; set; } = new Check[0];
public Check[] None { get; set; } = emptyCheck;
}
}
3 changes: 2 additions & 1 deletion src/AxaFrance.AxeExtended.HtmlReport/Language.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public enum Language
/// French
/// </summary>
French,
//TODO: Other languages, necearry to translate role descriptions into these languages.

//Remark: Other languages, necearry to translate role descriptions into these languages.
}
}
2 changes: 1 addition & 1 deletion src/AxaFrance.AxeExtended.HtmlReport/OutputFormat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace AxaFrance.AxeExtended.HtmlReport
{
/// <summary>
/// Outpur format of the HTML report
/// Output format of the test report.
/// </summary>
public enum OutputFormat
{
Expand Down
16 changes: 5 additions & 11 deletions src/AxaFrance.AxeExtended.HtmlReport/OverallReportBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,7 @@ public OverallReportBuilder Build()
Title = options.Title,
TimeStamp = DateTime.Now
};
foreach(var pageBuilder in PageBuilders)
{
if (pageBuilder.Result != null)
{
overallResult.PageResults.Add(pageBuilder.Result);
}
}
overallResult.PageResults.AddRange(PageBuilders.Where(x=>x.Result != null).Select(x => x.Result));
this.Result = overallResult;
hasBuilt = true;
return this;
Expand Down Expand Up @@ -153,15 +147,15 @@ public string Export(string fileName = null)
ruleResults.AppendLine($"</td>");
foreach (var page in Result.PageResults)
{
if (page.Violations.FirstOrDefault(x => x.Item.Id == ruleId) != null)
if (Array.Find(page.Violations, x => x.Item.Id == ruleId) != null)
{
ruleResults.AppendLine($"<td><span class='Violations'>Violations</span></td>");
}
else if (page.Incomplete.FirstOrDefault(x => x.Item.Id == ruleId) != null)
else if (Array.Find(page.Incomplete, x => x.Item.Id == ruleId) != null)
{
ruleResults.AppendLine($"<td><span class='Incomplele'>Incomplele</span></td>");
}
else if (page.Passes.FirstOrDefault(x=>x.Item.Id == ruleId) != null)
else if (Array.Find(page.Passes, x=>x.Item.Id == ruleId) != null)
{
ruleResults.AppendLine($"<td><span class='Passes'>Passes</span></td>");
}
Expand All @@ -185,7 +179,7 @@ public string Export(string fileName = null)
case OutputFormat.Html:
return fullname;
case OutputFormat.Zip:
var file = Path.GetTempFileName();
var file = Path.GetRandomFileName();
var zipName = Path.Combine(path, "report.zip");
File.Delete(file);
ZipFile.CreateFromDirectory(path, file);
Expand Down
51 changes: 30 additions & 21 deletions src/AxaFrance.AxeExtended.HtmlReport/PageReportBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public class PageReportBuilder
/// </summary>
public JObject Config { get; set; }

/// <summary>
/// Indicate whether Screenshot is available in the currenct context. Internally, it means GetScreenshot delegate is provided.
/// </summary>
public bool CanGetScreenshot => GetScreenshot != EmptyGetScreenshot && GetScreenshot != null;

/// <summary>
Expand All @@ -53,20 +56,14 @@ public PageReportBuilder(PageReportOptions options)
Options = options;
}

public PageReportBuilder WithOptions(PageReportOptions options)
{
Options = options;
return this;
}

/// <summary>
/// Initilaize axe-core engine with custom configuration.
/// Provide a custom test options
/// </summary>
/// <param name="config">axe costom configuration object</param>
/// <returns></returns>
public PageReportBuilder WithConfig(JObject config)
/// <param name="options">Options</param>
/// <returns>ReportBuilder with updated options</returns>
public PageReportBuilder WithOptions(PageReportOptions options)
{
Config = config;
Options = options;
return this;
}

Expand All @@ -84,6 +81,19 @@ public PageReportBuilder WithRgaaExtension()
return this;
}


/// <summary>
/// Initilaize axe-core engine with custom configuration.
/// </summary>
/// <param name="config">axe costom configuration object</param>
/// <returns></returns>
public PageReportBuilder WithConfig(JObject config)
{
Config = config;
return this;
}


/// <summary>
/// Initilaize axe-core engine with customed configuration
/// </summary>
Expand All @@ -98,7 +108,7 @@ public PageReportBuilder WithConfig(string configFile)

private byte[] EmptyGetScreenshot(AxeResultNode node, PageReportOptions options)
{
return null;
return Array.Empty<byte>();
}


Expand Down Expand Up @@ -143,7 +153,7 @@ public string Export(string fileName = null)
{
if (Result == null) throw new InvalidDataException("The report has not been built, please call Build or Analyze before exporting");
var guid = Guid.NewGuid().ToString();
string path = Options.OutputFolder ?? Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
string path = Options.OutputFolder ?? Path.Combine(Path.GetTempPath(), guid);
Directory.CreateDirectory(path);
string violations = GenerateRuleSection(Result.Violations, path);
string passes = GenerateRuleSection(Result.Passes, path);
Expand All @@ -160,12 +170,12 @@ public string Export(string fileName = null)
.Replace("{{Violations}}", violations)
.Replace("{{Passed}}", passes)
.Replace("{{Incomplete}}", incomplete)
.Replace("{{ViolationRules}}", Result.Violations.Count().ToString())
.Replace("{{ViolationNodes}}", Result.Violations.Sum(x => x.Nodes.Count()).ToString())
.Replace("{{ViolationRules}}", Result.Violations.Length.ToString())
.Replace("{{ViolationNodes}}", Result.Violations.Sum(x => x.Nodes.Length).ToString())
.Replace("{{NonApplicable}}", inapplicable)
.Replace("{{IncompleteRules}}", Result.Incomplete.Count().ToString())
.Replace("{{NonApplicableRules}}", Result.Inapplicable.Count().ToString())
.Replace("{{PassedRules}}", Result.Passes.Count().ToString());
.Replace("{{IncompleteRules}}", Result.Incomplete.Length.ToString())
.Replace("{{NonApplicableRules}}", Result.Inapplicable.Length.ToString())
.Replace("{{PassedRules}}", Result.Passes.Length.ToString());

string fullname = Path.Combine(path, fileName ?? "index.html");
File.WriteAllText(fullname, html);
Expand All @@ -175,7 +185,7 @@ public string Export(string fileName = null)
case OutputFormat.Html:
return fullname;
case OutputFormat.Zip:
var file = Path.GetTempFileName();
var file = Path.GetRandomFileName();
var zipName = Path.Combine(path, "report.zip");
File.Delete(file);
ZipFile.CreateFromDirectory(path, file);
Expand All @@ -198,7 +208,7 @@ internal static string GetRessource(string filename)
using (var stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
throw new Exception($"Unable to find resource {resourceName} in assembly {assembly.FullName}");
throw new FileNotFoundException($"Unable to find resource {resourceName} in assembly {assembly.FullName}");
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
Expand Down Expand Up @@ -229,7 +239,6 @@ private string GenerateRuleSection(AxeResultEnhancedItem[] items, string path)
//generate node (occurances of rule)
var nodeTemplate = GetRessource("node-part.html");
var cssSelector = node.Node.Target;
var xpath = node.Node.XPath;
var display = node.Screenshot != null ? "block" : "none";
string filename = string.Empty;
if (node.Screenshot != null)
Expand Down
19 changes: 18 additions & 1 deletion src/AxaFrance.AxeExtended.Selenium/AxeExtendedBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@

namespace AxaFrance.AxeExtended.Selenium
{
/// <summary>
/// ExtendedBuilder for Axe Core. This class is used to configure and run axe against a web page.
/// This class is a fork of original AxeBuilder class from Deque AxeCore.
/// There is no possibility to use a custom configuration file with the original AxeBuilder class, so we need to create this class and expose the WithAxeConfig method.
/// With this method, we can pass a custom configuration file to the axe engine and run custom rules in addition to default axe rules.
/// </summary>
public class AxeExtendedBuilder
{
private readonly WebDriver _webDriver;
Expand All @@ -30,11 +36,22 @@ public class AxeExtendedBuilder
{
}

/// <summary>
/// Initialize an instance of <see cref="AxeBuilder"/>
/// </summary>
/// <param name="webDriver"></param>
/// <param name="config"></param>
public AxeExtendedBuilder(WebDriver webDriver, JObject config) : this(webDriver, new AxeBuilderOptions { ScriptProvider = new BundledAxeScriptProvider() })
{
axeConfig = config;
}

/// <summary>
/// Initialize an instance of <see cref="AxeBuilder"/>
/// </summary>
/// <param name="webDriver"></param>
/// <param name="config"></param>
/// <param name="options"></param>
public AxeExtendedBuilder(WebDriver webDriver, JObject config, AxeBuilderOptions options) : this(webDriver, options)
{
axeConfig = config;
Expand Down Expand Up @@ -457,7 +474,7 @@ private static void ValidateParameters(string[] parameterValue, string parameter

private static void ValidateNotNullParameter<T>(T parameterValue, string parameterName)
{
if (parameterValue == null)
if (parameterValue is null)

Check failure on line 477 in src/AxaFrance.AxeExtended.Selenium/AxeExtendedBuilder.cs

View workflow job for this annotation

GitHub Actions / build

An expression of type 'T' cannot be handled by a pattern of type '<null>'. Please use language version '8.0' or greater to match an open type with a constant pattern.

Check failure on line 477 in src/AxaFrance.AxeExtended.Selenium/AxeExtendedBuilder.cs

View workflow job for this annotation

GitHub Actions / build

An expression of type 'T' cannot be handled by a pattern of type '<null>'. Please use language version '8.0' or greater to match an open type with a constant pattern.
{
throw new ArgumentNullException(parameterName);
}
Expand Down
37 changes: 11 additions & 26 deletions src/AxaFrance.AxeExtended.Selenium/AxeSeleniumHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ private static AxeResult Analyze(PageReportBuilder builder, JObject config, WebD


/// <summary>
/// Takes the screenshot. this function will be called by <see cref="PageReportBuilder.GetScreenshot" delegation/>
/// Takes the screenshot. this function will be called by <see cref="PageReportBuilder.GetScreenshot" />
/// </summary>
/// <param name="driver">WebDriver</param>
/// <param name="node">Node in AxeResult</param>
Expand All @@ -93,24 +93,9 @@ private static byte[] ScreenShot(WebDriver driver, AxeResultNode node, PageRepor
else
{
//it contains iFrame
Console.WriteLine("[Ally] Warning unable to get screenshot of an element inside iFrame.");
var iFrameSelector = node.Target.FrameSelectors.ToArray();

//TODO: Unable to locate and screenshot elements inside frames.
//At current state,
element = driver.FindElement(By.CssSelector(iFrameSelector[0]));
/*
foreach(var s in iFrameSelector)
{
element = driver.FindElement(By.CssSelector(s));
if(element.TagName == "iframe")
{
driver.SwitchTo().Frame(element);
}
else
{
element = driver.FindElement(By.CssSelector(s));
}
}*/
}

}
Expand All @@ -123,19 +108,20 @@ private static byte[] ScreenShot(WebDriver driver, AxeResultNode node, PageRepor
try
{
element = driver.FindElement(By.CssSelector(cssSelector));
if (element == null)
if (element is null)
{
element = driver.FindElement(By.XPath(xPath));
}
}catch(Exception ex)
{
Console.WriteLine("[Ally] Unable to get element from cssSelector or xPath");
//sometimes the cssSelector provided by axe can not be used by selenium.
//in this case can't make screenshot on the element.

Console.WriteLine("[A11y] Unable to get element from cssSelector or xPath");
}
}

if (element != null && element is WebElement we)
if (element is WebElement we)
{
try
{
Expand All @@ -146,15 +132,15 @@ private static byte[] ScreenShot(WebDriver driver, AxeResultNode node, PageRepor
catch (Exception ex)
{
//in some cases (hidden element, 0 height element, etc. the screeshot is not possible, leave these cases behind.
Console.WriteLine("[Ally] Unable to get screenshot:" + ex.ToString());
Console.WriteLine("[A11y] Unable to get screenshot:" + ex.ToString());
return new byte[0];
}
}
else
{
driver.SwitchTo().DefaultContent();
return new byte[0];
//throw new WebDriverException("The element can not be converted to type WebElement for screenshot.");
Console.WriteLine("[A11y] The element can not be converted to type WebElement for screenshot.");
return Array.Empty<byte>();
}


Expand All @@ -163,8 +149,7 @@ private static byte[] ScreenShot(WebDriver driver, AxeResultNode node, PageRepor
private static byte[] AdvancedScreenshot(WebDriver driver, WebElement element, PageReportOptions options)
{
BringToView(element, driver);
var imageViewPort = driver.GetScreenshot();
var windowSize = driver.Manage().Window.Size;
var imageViewPort = driver.GetScreenshot();
var locatable = (ILocatable)element;

var location = locatable.Coordinates.LocationInViewport; //location and size are for 100% dpi
Expand All @@ -175,7 +160,7 @@ private static byte[] AdvancedScreenshot(WebDriver driver, WebElement element, P
return screenshot;
}
Console.WriteLine("[Ally] Unable to get screenshot: Element has 0 height or width.");
return new byte[0];
return Array.Empty<byte>();
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/AxaFrance.WebEngine/EnvironmentVariables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public string GetValue(string name)
else
{
string value = this.Variables.Find(x => x.Name == name).Value;
while (value.StartsWith("$"))
while (value.StartsWith('$'))

Check failure on line 97 in src/AxaFrance.WebEngine/EnvironmentVariables.cs

View workflow job for this annotation

GitHub Actions / build

Argument 1: cannot convert from 'char' to 'string'

Check failure on line 97 in src/AxaFrance.WebEngine/EnvironmentVariables.cs

View workflow job for this annotation

GitHub Actions / build

Argument 1: cannot convert from 'char' to 'string'
{
value = this.Variables.Find(x => x.Name == value.Substring(1)).Value;
}
Expand Down
Loading

0 comments on commit a1c95a1

Please sign in to comment.