1+ using AngleSharp ;
2+ using AngleSharp . Css ;
3+
4+ namespace AngleSharp . Renderer . Tests ;
5+
6+ public sealed class VisualConformanceTests
7+ {
8+ [ Fact ]
9+ public async Task RenderToPng_PaintsBoxBackgroundAndBorderAtExpectedPixels ( )
10+ {
11+ var document = await ParseAsync ( """
12+ <html>
13+ <head>
14+ <style>html, body { margin: 0; padding: 0; }</style>
15+ </head>
16+ <body>
17+ <div style="margin-left:10px; margin-top:10px; width:40px; height:20px; padding:5px; border:2px solid rgb(0,0,255); background-color:rgb(255,0,0);"></div>
18+ </body>
19+ </html>
20+ """ ) ;
21+
22+ var renderer = new HtmlRenderer ( ) ;
23+ var image = renderer . RenderToPng ( document , new HtmlRenderOptions
24+ {
25+ Width = 120 ,
26+ Height = 120 ,
27+ Padding = 0f ,
28+ ParagraphSpacing = 0f ,
29+ } ) ;
30+
31+ VisualSnapshotVerifier . VerifyOrCreate (
32+ snapshotName : "paints-box-background-and-border.png" ,
33+ actualPng : image . Data ,
34+ perChannelTolerance : 2 ,
35+ maxDifferentPixels : 0 ) ;
36+ }
37+
38+ [ Fact ]
39+ public async Task RenderToPng_CentersAutoMarginBlock ( )
40+ {
41+ var document = await ParseAsync ( """
42+ <html>
43+ <head>
44+ <style>html, body { margin: 0; padding: 0; }</style>
45+ </head>
46+ <body>
47+ <div style="width:50px; height:20px; margin-left:auto; margin-right:auto; background-color:rgb(0,255,0);"></div>
48+ </body>
49+ </html>
50+ """ ) ;
51+
52+ var renderer = new HtmlRenderer ( ) ;
53+ var image = renderer . RenderToPng ( document , new HtmlRenderOptions
54+ {
55+ Width = 120 ,
56+ Height = 80 ,
57+ Padding = 0f ,
58+ ParagraphSpacing = 0f ,
59+ } ) ;
60+
61+ VisualSnapshotVerifier . VerifyOrCreate (
62+ snapshotName : "centers-auto-margin-block.png" ,
63+ actualPng : image . Data ,
64+ perChannelTolerance : 2 ,
65+ maxDifferentPixels : 0 ) ;
66+ }
67+
68+ [ Fact ]
69+ public async Task RenderToPng_ShowsCollapsedVerticalMarginGap ( )
70+ {
71+ var document = await ParseAsync ( """
72+ <html>
73+ <head>
74+ <style>html, body { margin: 0; padding: 0; }</style>
75+ </head>
76+ <body>
77+ <div style="height:10px; margin-bottom:20px; background-color:rgb(255,0,0);"></div>
78+ <div style="height:10px; margin-top:10px; background-color:rgb(0,0,255);"></div>
79+ </body>
80+ </html>
81+ """ ) ;
82+
83+ var renderer = new HtmlRenderer ( ) ;
84+ var image = renderer . RenderToPng ( document , new HtmlRenderOptions
85+ {
86+ Width = 120 ,
87+ Height = 120 ,
88+ Padding = 0f ,
89+ ParagraphSpacing = 0f ,
90+ } ) ;
91+
92+ VisualSnapshotVerifier . VerifyOrCreate (
93+ snapshotName : "shows-collapsed-vertical-margin-gap.png" ,
94+ actualPng : image . Data ,
95+ perChannelTolerance : 2 ,
96+ maxDifferentPixels : 0 ) ;
97+ }
98+
99+ [ Fact ]
100+ public async Task RenderToPng_PaintsAbsolutePositionedElementOutOfFlow ( )
101+ {
102+ var document = await ParseAsync ( """
103+ <html>
104+ <head>
105+ <style>html, body { margin: 0; padding: 0; }</style>
106+ </head>
107+ <body>
108+ <div style="position:relative; width:100px; height:20px; background-color:#eeeeee;">
109+ <div style="position:absolute; left:12px; top:6px; width:30px; height:10px; background-color:#ff0000;"></div>
110+ </div>
111+ <div style="width:40px; height:10px; background-color:#0000ff;"></div>
112+ </body>
113+ </html>
114+ """ ) ;
115+
116+ var renderer = new HtmlRenderer ( ) ;
117+ var image = renderer . RenderToPng ( document , new HtmlRenderOptions
118+ {
119+ Width = 160 ,
120+ Height = 100 ,
121+ Padding = 0f ,
122+ ParagraphSpacing = 0f ,
123+ } ) ;
124+
125+ VisualSnapshotVerifier . VerifyOrCreate (
126+ snapshotName : "absolute-positioned-out-of-flow.png" ,
127+ actualPng : image . Data ,
128+ perChannelTolerance : 2 ,
129+ maxDifferentPixels : 0 ) ;
130+ }
131+
132+ [ Fact ]
133+ public async Task RenderToPng_PaintsHigherZIndexAboveLowerZIndex ( )
134+ {
135+ var document = await ParseAsync ( """
136+ <html>
137+ <head>
138+ <style>html, body { margin: 0; padding: 0; }</style>
139+ </head>
140+ <body>
141+ <div style="position:relative; width:120px; height:40px;">
142+ <div style="position:absolute; left:10px; top:5px; width:30px; height:20px; background-color:#ff0000; z-index:1;"></div>
143+ <div style="position:absolute; left:10px; top:5px; width:30px; height:20px; background-color:#0000ff; z-index:2;"></div>
144+ </div>
145+ </body>
146+ </html>
147+ """ ) ;
148+
149+ var renderer = new HtmlRenderer ( ) ;
150+ var image = renderer . RenderToPng ( document , new HtmlRenderOptions
151+ {
152+ Width = 160 ,
153+ Height = 100 ,
154+ Padding = 0f ,
155+ ParagraphSpacing = 0f ,
156+ } ) ;
157+
158+ VisualSnapshotVerifier . VerifyOrCreate (
159+ snapshotName : "higher-z-index-over-lower-z-index.png" ,
160+ actualPng : image . Data ,
161+ perChannelTolerance : 2 ,
162+ maxDifferentPixels : 0 ) ;
163+ }
164+
165+ [ Fact ]
166+ public async Task RenderToPng_PaintsNegativeZIndexBehindInFlowContent ( )
167+ {
168+ var document = await ParseAsync ( """
169+ <html>
170+ <head>
171+ <style>html, body { margin: 0; padding: 0; }</style>
172+ </head>
173+ <body>
174+ <div style="position:relative; width:120px; height:30px; background-color:#00ff00;">
175+ <div style="position:absolute; left:0; top:0; width:30px; height:10px; background-color:#ff0000; z-index:-1;"></div>
176+ </div>
177+ </body>
178+ </html>
179+ """ ) ;
180+
181+ var renderer = new HtmlRenderer ( ) ;
182+ var image = renderer . RenderToPng ( document , new HtmlRenderOptions
183+ {
184+ Width = 160 ,
185+ Height = 100 ,
186+ Padding = 0f ,
187+ ParagraphSpacing = 0f ,
188+ } ) ;
189+
190+ VisualSnapshotVerifier . VerifyOrCreate (
191+ snapshotName : "negative-z-index-behind-in-flow.png" ,
192+ actualPng : image . Data ,
193+ perChannelTolerance : 2 ,
194+ maxDifferentPixels : 0 ) ;
195+ }
196+
197+ private static async Task < AngleSharp . Dom . IDocument > ParseAsync ( string html )
198+ {
199+ var context = BrowsingContext . New ( Configuration . Default . WithCss ( ) ) ;
200+ return await context . OpenAsync ( request => request . Content ( html ) ) ;
201+ }
202+ }
0 commit comments