Extends Verify with Html verification utilities via AngleSharp.
See Milestones for release notes.
Entity Framework Extensions is a major sponsor and is proud to contribute to the development this project.
Extends Verify to allow comparison of htm and html files via AngleSharp.
Call VerifyAngleSharpDiffing.Initialize() once at assembly load time.
Initialize takes an optional Action<IDiffingStrategyCollection> to control settings at a global level:
[ModuleInitializer]publicstaticvoidInit()=>VerifyAngleSharpDiffing.Initialize();Given an existing verified file:
<!DOCTYPE html><html><body><h1>My First Heading</h1><p>My first paragraph.</p></body></html>And a test:
[Test]publicTaskSample(){varhtml=""" <!DOCTYPE html> <html> <body> <h1>My First Heading</h1> <p>My first paragraph.</p> </body> </html> """;returnVerify(html,"html");}Note that the input html differs from the verified html, but not in a semantically significant way. Hence this test will pass.
If the comparison fails, the resulting differences will be included in the test result displayed to the user.
For example if, in the above html, <h1>My First Heading</h1> changes to <h1>First Heading</h1> then the following will be printed in the test results:
Comparer result:
* Node Diff
Path: h1(0) > #text(0)
Received: First Heading
Verified: My First Heading
Settings can also be controlled for a specific test.
varsettings=newVerifySettings();settings.AngleSharpDiffingSettings(
action =>{staticFilterDecisionSpanFilter(inComparisonSourcesource,FilterDecisiondecision){if(source.Node.NodeName=="SPAN"){returnFilterDecision.Exclude;}returndecision;}varoptions=action.AddDefaultOptions();options.AddFilter(SpanFilter);});VerifyAngleSharpDiffing.Initialize(
action =>{staticFilterDecisionSpanFilter(inComparisonSourcesource,FilterDecisiondecision){if(source.Node.NodeName=="SPAN"){returnFilterDecision.Exclude;}returndecision;}varoptions=action.AddDefaultOptions();options.AddFilter(SpanFilter);});Html can be pretty printed.
[Test]publicTaskPrettyPrintHtml(){varhtml=""" <!DOCTYPE html> <html><body><h1>My First Heading</h1> <p>My first paragraph.</p></body></html> """;returnVerify(html,"html").PrettyPrintHtml();}Results in
<!DOCTYPE html><html><head></head><body><h1>My First Heading</h1><p>My first paragraph.</p></body></html>To apply this to all html files use HtmlPrettyPrint.All();
Nodes can be manipulated as part of the pretty print:
[Test]publicTaskPrettyPrintHtmlWithNodeManipulation(){varhtml=""" <!DOCTYPE html> <html> <body> <h1>My First Heading</h1> <p>My first paragraph.</p> </body> </html> """;returnVerify(html,"html").PrettyPrintHtml(
nodes =>{foreach(varnodeinnodes.QuerySelectorAll("h1")){node.Remove();}});}Results in
<!DOCTYPE html><html><head></head><body><p>My first paragraph.</p></body></html>[Test]publicTaskScrubEmptyDivs(){varhtml=""" <!DOCTYPE html> <html> <body> <div>My First Heading</div> <div></div> </body> </html> """;returnVerify(html,"html").PrettyPrintHtml(nodes =>nodes.ScrubEmptyDivs());}Results in:
<!DOCTYPE html><html><head></head><body><div>My First Heading</div></body></html>[Test]publicTaskScrubAttributes(){varhtml=""" <!DOCTYPE html> <html> <body> <div id='a'>My First Heading</div> </body> </html> """;returnVerify(html,"html").PrettyPrintHtml(nodes =>nodes.ScrubAttributes("id"));}Results in:
<!DOCTYPE html><html><head></head><body><div>My First Heading</div></body></html>[Test]publicTaskScrubAttributeWithNewValue(){varhtml=""" <!DOCTYPE html> <html> <body> <div id='a'>My First Heading</div> </body> </html> """;returnVerify(html,"html").PrettyPrintHtml(
nodes =>nodes.ScrubAttributes(x =>{if(x.Name=="id"){return"new value";}returnnull;}));}Results in:
<!DOCTYPE html><html><head></head><body><divid="new value">My First Heading</div></body></html>