Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement AxeResult.ToString based on JsonConvert #75

Merged
merged 5 commits into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions packages/commons/src/AxeJsonSerializerSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace Deque.AxeCore.Commons
{
/// <summary>
/// Provides <see cref="Newtonsoft.Json.JsonSerializerSettings"> values intended for use with the assorted
/// Axe* types in this namespace.
/// </summary>
public static class AxeJsonSerializerSettings
{
/// <summary>
/// The default serialization settings recommended for use with this namespace's Axe* types.
/// </summary>
public static readonly JsonSerializerSettings Default = WithFormatting(Formatting.None);

/// <summary>
/// Produces serialization settings appropriate for use with this namespace's Axe* types with specific formatting settings.
/// </summary>
public static JsonSerializerSettings WithFormatting(Formatting formatting)
{
return new JsonSerializerSettings
{
Formatting = formatting,
NullValueHandling = NullValueHandling.Include,
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
},
};
}
}
}
6 changes: 6 additions & 0 deletions packages/commons/src/AxeResult.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;

Expand Down Expand Up @@ -100,5 +101,10 @@ public AxeResult(JObject result)
TestEngineVersion = testEngineVersion?.ToObject<string>();
ToolOptions = toolOptions?.ToObject<object>();
}

public override string ToString()
{
return JsonConvert.SerializeObject(this, AxeJsonSerializerSettings.WithFormatting(Formatting.Indented));
}
}
}
7 changes: 7 additions & 0 deletions packages/commons/src/AxeResultItem.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Newtonsoft.Json;

namespace Deque.AxeCore.Commons
{
/// <summary>
Expand Down Expand Up @@ -39,5 +41,10 @@ public class AxeResultItem
/// List of all elements the Rule evaluated to the same result for.
/// </summary>
public AxeResultNode[] Nodes { get; set; }

public override string ToString()
{
return JsonConvert.SerializeObject(this, AxeJsonSerializerSettings.WithFormatting(Formatting.Indented));
}
}
}
51 changes: 51 additions & 0 deletions packages/commons/test/AxeResultItemTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using FluentAssertions;
using NUnit.Framework;

namespace Deque.AxeCore.Commons.Test
{
[TestFixture]
public class AxeResultItemTest
{
[Test]
public void ToStringShouldIncludeEnoughInfoToBeActionable()
{
var node = new AxeResultNode
{
All = new AxeResultCheck[] { },
Any = new AxeResultCheck[] { },
None = new AxeResultCheck[] { },
Ancestry = null,
Target = new AxeSelector("#selector"),
Html = "stub-html",
Impact = "stub-impact",
XPath = null,
};

var item = new AxeResultItem
{
Description = "stub desc",
Help = "stub help",
HelpUrl = "http://example.com/help",
Id = "stub-id",
Impact = "stub-impact",
Tags = new string[] { "tag-1", "tag-2" },
Nodes = new AxeResultNode[] { node },
};

var toStringOutput = item.ToString();

toStringOutput.Should().ContainAll(new string[] {
item.Description,
item.Help,
item.HelpUrl,
item.Id,
item.Impact,
item.Tags[0],
item.Tags[1],
node.Target.ToString(),
node.Html,
node.Impact,
});
}
}
}
24 changes: 24 additions & 0 deletions packages/commons/test/AxeResultTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,5 +148,29 @@ public void ToStringShouldBeStable()

result1.ToString().Should().Be(result2.ToString());
}

[Test]
public void ToStringShouldIncludeEnoughInfoToBeActionable()
{
var result = new AxeResult(JObject.FromObject(JsonConvert.DeserializeObject(basicAxeResultJson)));
var toStringOutput = result.ToString();

toStringOutput.Should().ContainAll(new string[] {
"4.4.1",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/100.0.4889.0 Safari/537.36",
"2000-01-02T03:04:05.006+00:00",
"http://localhost/",
"document-title",
"wcag242",
"serious",
"Ensures each HTML document contains a non-empty <title> element",
"https://dequeuniversity.com/rules/axe/4.4/document-title?application=axe-puppeteer",
"<html><head></head><body>",
"</body></html>",
"/html",
"doc-has-title",
"Document does not have a non-empty <title> element",
});
}
}
}
13 changes: 4 additions & 9 deletions packages/commons/test/AxeRunOptionsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ namespace Deque.AxeCore.Commons.Test
[TestFixture]
public class AxeRunOptionsTest
{
private readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.None,
};

[Test]
public void ShouldSerializeRunOnlyOption()
{
Expand All @@ -25,7 +20,7 @@ public void ShouldSerializeRunOnlyOption()
}
};

var serializedObject = JsonConvert.SerializeObject(options, serializerSettings);
var serializedObject = JsonConvert.SerializeObject(options, AxeJsonSerializerSettings.Default);
var expectedObject = "{\"runOnly\":{\"type\":\"tag\",\"values\":[\"tag1\",\"tag2\"]}}";

serializedObject.Should().Be(expectedObject);
Expand All @@ -46,7 +41,7 @@ public void ShouldSerializeRuleOptions()
};
var expectedObject = "{\"rules\":{\"enabledRule\":{\"enabled\":true},\"disabledRule\":{\"enabled\":false},\"rule3WithoutOptionsData\":{}}}";

var serializedObject = JsonConvert.SerializeObject(options, serializerSettings);
var serializedObject = JsonConvert.SerializeObject(options, AxeJsonSerializerSettings.Default);

serializedObject.Should().Be(expectedObject);
JsonConvert.DeserializeObject<AxeRunOptions>(expectedObject).Should().BeEquivalentTo(options);
Expand All @@ -67,7 +62,7 @@ public void ShouldSerializeLiteralTypes()
};
var expectedObject = "{\"selectors\":true,\"ancestry\":true,\"absolutePaths\":true,\"iframes\":true,\"restoreScroll\":true,\"frameWaitTime\":10,\"pingWaitTime\":100}";

var serializedObject = JsonConvert.SerializeObject(options, serializerSettings);
var serializedObject = JsonConvert.SerializeObject(options, AxeJsonSerializerSettings.Default);

serializedObject.Should().Be(expectedObject);
JsonConvert.DeserializeObject<AxeRunOptions>(expectedObject).Should().BeEquivalentTo(options);
Expand All @@ -81,7 +76,7 @@ public void ShouldSerializeResultTypes()
ResultTypes = new HashSet<ResultType>() { ResultType.Inapplicable, ResultType.Incomplete, ResultType.Passes, ResultType.Violations }
};

var serializedObject = JsonConvert.SerializeObject(options, serializerSettings);
var serializedObject = JsonConvert.SerializeObject(options, AxeJsonSerializerSettings.Default);

var expectedObject = "{\"resultTypes\":[\"inapplicable\",\"incomplete\",\"passes\",\"violations\"]}";

Expand Down
27 changes: 5 additions & 22 deletions packages/selenium/src/AxeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,6 @@ public class AxeBuilder
private string outputFilePath = null;
private bool useLegacyMode = false;

private static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.None,
NullValueHandling = NullValueHandling.Include
};

private static readonly DefaultContractResolver camelCaseContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
};
private static readonly JsonSerializerSettings JsonSerializerSettingsFinishRun = new JsonSerializerSettings
{
ContractResolver = camelCaseContractResolver,
Formatting = Formatting.None,
NullValueHandling = NullValueHandling.Include
};

/// <summary>
/// Initialize an instance of <see cref="AxeBuilder"/>
/// </summary>
Expand Down Expand Up @@ -230,7 +213,7 @@ public AxeResult Analyze()
{
bool runContextHasData = runContext.Include?.Any() == true || runContext.Exclude?.Any() == true;

string rawContext = runContextHasData ? JsonConvert.SerializeObject(runContext, JsonSerializerSettings) : null;
string rawContext = runContextHasData ? JsonConvert.SerializeObject(runContext, AxeJsonSerializerSettings.Default) : null;

return AnalyzeRawContext(rawContext);
}
Expand Down Expand Up @@ -320,8 +303,8 @@ bool isTopLevel
{
try
{
object frameContext = JsonConvert.SerializeObject(fContext.Context, JsonSerializerSettings);
object frameSelector = JsonConvert.SerializeObject(fContext.Selector, JsonSerializerSettings);
object frameContext = JsonConvert.SerializeObject(fContext.Context, AxeJsonSerializerSettings.Default);
object frameSelector = JsonConvert.SerializeObject(fContext.Selector, AxeJsonSerializerSettings.Default);
var frame = _webDriver.ExecuteScript(EmbeddedResourceProvider.ReadEmbeddedFile("shadowSelect.js"), frameSelector);
_webDriver.SwitchTo().Frame(frame as IWebElement);

Expand Down Expand Up @@ -364,7 +347,7 @@ private JObject IsolatedFinishRun(object[] partialResults, object options)

ConfigureAxe();

var serializedPartials = JsonConvert.SerializeObject(partialResults, JsonSerializerSettingsFinishRun);
var serializedPartials = JsonConvert.SerializeObject(partialResults, AxeJsonSerializerSettings.Default);
// grab result ...
var result = _webDriver.ExecuteAsyncScript(EmbeddedResourceProvider.ReadEmbeddedFile("finishRun.js"), serializedPartials, options);

Expand Down Expand Up @@ -423,7 +406,7 @@ private void ConfigureAxe()

private string SerializedRunOptions()
{
return JsonConvert.SerializeObject(runOptions, JsonSerializerSettings);
return JsonConvert.SerializeObject(runOptions, AxeJsonSerializerSettings.Default);
}

private static void ValidateParameters(string[] parameterValue, string parameterName)
Expand Down
7 changes: 1 addition & 6 deletions packages/selenium/test/AxeBuilderLegacyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ public class LegacyAxeBuilderTest
private static Mock<IWebDriver> webDriverMock = new Mock<IWebDriver>();
private static Mock<IJavaScriptExecutor> jsExecutorMock = webDriverMock.As<IJavaScriptExecutor>();
private static Mock<ITargetLocator> targetLocatorMock = new Mock<ITargetLocator>();
private static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.None,
NullValueHandling = NullValueHandling.Ignore
};

private static readonly AxeBuilderOptions stubAxeBuilderOptions = new AxeBuilderOptions
{
Expand Down Expand Up @@ -333,7 +328,7 @@ private void SetupVerifiableScanElementCall(IWebElement elementContext, string s

private string SerializeObject<T>(T obj)
{
return JsonConvert.SerializeObject(obj, JsonSerializerSettings);
return JsonConvert.SerializeObject(obj, AxeJsonSerializerSettings.Default);
}

}
Expand Down
7 changes: 1 addition & 6 deletions packages/selenium/test/AxeBuilderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ public class AxeBuilderTest
private static Mock<IJavaScriptExecutor> jsExecutorMock = webDriverMock.As<IJavaScriptExecutor>();
private static Mock<ITargetLocator> targetLocatorMock = new Mock<ITargetLocator>();
private static Mock<INavigation> navigationMock = new Mock<INavigation>();
private static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.None,
NullValueHandling = NullValueHandling.Ignore
};

private static readonly AxeBuilderOptions stubAxeBuilderOptions = new AxeBuilderOptions
{
Expand Down Expand Up @@ -352,7 +347,7 @@ private void SetupVerifiableScanElementCall(IWebElement elementContext, string s

private string SerializeObject<T>(T obj)
{
return JsonConvert.SerializeObject(obj, JsonSerializerSettings);
return JsonConvert.SerializeObject(obj, AxeJsonSerializerSettings.Default);
}

}
Expand Down
8 changes: 1 addition & 7 deletions packages/selenium/test/RunPartial/FinishRunTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,9 @@ public void ShouldHaveSameResultsAsLegacy(string browser)
Assert.That(ToJson(legacyResults.ToolOptions), Is.EqualTo(ToJson(runPartialResults.ToolOptions)));
}

private static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.None,
NullValueHandling = NullValueHandling.Include
};

private static string ToJson(object obj)
{
return JsonConvert.SerializeObject(obj, JsonSerializerSettings);
return JsonConvert.SerializeObject(obj, AxeJsonSerializerSettings.Default);
}

private static void AssertAxeItemsEqual(AxeResultItem a, AxeResultItem b, bool compareNodes = false)
Expand Down