How to use ScreenshotHelper class of Microsoft.Playwright.Tests package

Best Playwright-dotnet code snippet using Microsoft.Playwright.Tests.ScreenshotHelper

Run Playwright-dotnet automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

PageScreenshotTests.cs

Source: PageScreenshotTests.cs Github

copy
1/*
2 * MIT License
3 *
4 * Copyright (c) 2020 Darío Kondratiuk
5 * Modifications copyright (c) Microsoft Corporation.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26using System;
27using System.Collections.Generic;
28using System.IO;
29using System.Threading.Tasks;
30using Microsoft.Playwright.NUnit;
31using NUnit.Framework;
32
33namespace Microsoft.Playwright.Tests
34{
35    ///<playwright-file>page-screenshot.spec.ts</playwright-file>
36
37    public class PageScreenshotTests : PageTestEx
38    {
39        [PlaywrightTest("page-screenshot.spec.ts", "should work")]
40        public async Task ShouldWork()
41        {
42            await Page.SetViewportSizeAsync(500, 500);
43            await Page.GotoAsync(Server.Prefix + "/grid.html");
44            byte[] screenshot = await Page.ScreenshotAsync();
45            Assert.True(ScreenshotHelper.PixelMatch("screenshot-sanity.png", screenshot));
46        }
47
48        [PlaywrightTest("page-screenshot.spec.ts", "should clip rect")]
49        public async Task ShouldClipRect()
50        {
51            await Page.SetViewportSizeAsync(500, 500);
52            await Page.GotoAsync(Server.Prefix + "/grid.html");
53            byte[] screenshot = await Page.ScreenshotAsync(new()
54            {
55                Clip = new()
56                {
57                    X = 50,
58                    Y = 100,
59                    Width = 150,
60                    Height = 100
61                }
62            }
63            );
64            Assert.True(ScreenshotHelper.PixelMatch("screenshot-clip-rect.png", screenshot));
65        }
66
67        [PlaywrightTest("page-screenshot.spec.ts", "should clip rect with fullPage")]
68        public async Task ShouldClipRectWithFullPage()
69        {
70            await Page.SetViewportSizeAsync(500, 500);
71            await Page.GotoAsync(Server.Prefix + "/grid.html");
72            await Page.EvaluateAsync("() => window.scrollBy(150, 200)");
73            byte[] screenshot = await Page.ScreenshotAsync(new()
74            {
75                FullPage = true,
76                Clip = new()
77                {
78                    X = 50,
79                    Y = 100,
80                    Width = 150,
81                    Height = 100,
82                }
83            });
84            Assert.True(ScreenshotHelper.PixelMatch("screenshot-clip-rect.png", screenshot));
85        }
86
87        [PlaywrightTest("page-screenshot.spec.ts", "should clip elements to the viewport")]
88        public async Task ShouldClipElementsToTheViewport()
89        {
90            await Page.SetViewportSizeAsync(500, 500);
91            await Page.GotoAsync(Server.Prefix + "/grid.html");
92            byte[] screenshot = await Page.ScreenshotAsync(new()
93            {
94                Clip = new()
95                {
96                    X = 50,
97                    Y = 450,
98                    Width = 1000,
99                    Height = 100,
100                }
101            });
102            Assert.True(ScreenshotHelper.PixelMatch("screenshot-offscreen-clip.png", screenshot));
103        }
104
105        [PlaywrightTest("page-screenshot.spec.ts", "should throw on clip outside the viewport")]
106        public async Task ShouldThrowOnClipOutsideTheViewport()
107        {
108            await Page.SetViewportSizeAsync(500, 500);
109            await Page.GotoAsync(Server.Prefix + "/grid.html");
110            var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => Page.ScreenshotAsync(new()
111            {
112                Clip = new()
113                {
114                    X = 50,
115                    Y = 650,
116                    Width = 100,
117                    Height = 100,
118                }
119            }));
120
121            StringAssert.Contains("Clipped area is either empty or outside the resulting image", exception.Message);
122        }
123
124        [PlaywrightTest("page-screenshot.spec.ts", "should run in parallel")]
125        public async Task ShouldRunInParallel()
126        {
127            await Page.SetViewportSizeAsync(500, 500);
128            await Page.GotoAsync(Server.Prefix + "/grid.html");
129
130            var tasks = new List<Task<byte[]>>();
131            for (int i = 0; i < 3; ++i)
132            {
133                tasks.Add(Page.ScreenshotAsync(new()
134                {
135                    Clip = new()
136                    {
137                        X = 50 * i,
138                        Y = 0,
139                        Width = 50,
140                        Height = 50
141                    }
142                }));
143            }
144
145            await TaskUtils.WhenAll(tasks);
146            Assert.True(ScreenshotHelper.PixelMatch("grid-cell-1.png", tasks[0].Result));
147        }
148
149        [PlaywrightTest("page-screenshot.spec.ts", "should take fullPage screenshots")]
150        public async Task ShouldTakeFullPageScreenshots()
151        {
152            await Page.SetViewportSizeAsync(500, 500);
153            await Page.GotoAsync(Server.Prefix + "/grid.html");
154            byte[] screenshot = await Page.ScreenshotAsync(new() { FullPage = true });
155            Assert.True(ScreenshotHelper.PixelMatch("screenshot-grid-fullpage.png", screenshot));
156        }
157
158        [PlaywrightTest("page-screenshot.spec.ts", "should restore viewport after fullPage screenshot")]
159        public async Task ShouldRestoreViewportAfterFullPageScreenshot()
160        {
161            await Page.SetViewportSizeAsync(500, 500);
162            await Page.GotoAsync(Server.Prefix + "/grid.html");
163            await Page.ScreenshotAsync(new() { FullPage = true });
164
165            Assert.AreEqual(500, Page.ViewportSize.Width);
166            Assert.AreEqual(500, Page.ViewportSize.Height);
167        }
168
169        [PlaywrightTest("page-screenshot.spec.ts", "should run in parallel in multiple pages")]
170        public async Task ShouldRunInParallelInMultiplePages()
171        {
172            int n = 5;
173            var pageTasks = new List<Task<IPage>>();
174            for (int i = 0; i < n; i++)
175            {
176                async Task<IPage> Func()
177                {
178                    var page = await Context.NewPageAsync();
179                    await page.GotoAsync(Server.Prefix + "/grid.html");
180                    return page;
181                }
182
183                pageTasks.Add(Func());
184            }
185
186            await TaskUtils.WhenAll(pageTasks);
187
188            var screenshotTasks = new List<Task<byte[]>>();
189            for (int i = 0; i < n; i++)
190            {
191                screenshotTasks.Add(pageTasks[i].Result.ScreenshotAsync(new()
192                {
193                    Clip = new()
194                    {
195                        X = 50 * (i % 2),
196                        Y = 0,
197                        Width = 50,
198                        Height = 50
199                    }
200                }));
201            }
202
203            await TaskUtils.WhenAll(screenshotTasks);
204
205            for (int i = 0; i < n; i++)
206            {
207                Assert.True(ScreenshotHelper.PixelMatch($"grid-cell-{i % 2}.png", screenshotTasks[i].Result));
208            }
209
210            var closeTasks = new List<Task>();
211            for (int i = 0; i < n; i++)
212            {
213                closeTasks.Add(pageTasks[i].Result.CloseAsync());
214            }
215
216            await TaskUtils.WhenAll(closeTasks);
217        }
218
219        [PlaywrightTest("page-screenshot.spec.ts", "should allow transparency")]
220        [Skip(SkipAttribute.Targets.Firefox)]
221        public async Task ShouldAllowTransparency()
222        {
223            await Page.SetViewportSizeAsync(50, 150);
224            await Page.GotoAsync(Server.EmptyPage);
225            byte[] screenshot = await Page.ScreenshotAsync(new() { OmitBackground = true });
226
227            Assert.True(ScreenshotHelper.PixelMatch("transparent.png", screenshot));
228        }
229
230        [PlaywrightTest("page-screenshot.spec.ts", "should render white background on jpeg file")]
231        public async Task ShouldRenderWhiteBackgroundOnJpegFile()
232        {
233            await Page.SetViewportSizeAsync(100, 100);
234            await Page.GotoAsync(Server.EmptyPage);
235            byte[] screenshot = await Page.ScreenshotAsync(new()
236            {
237                OmitBackground = true,
238                Type = ScreenshotType.Jpeg,
239            });
240            Assert.True(ScreenshotHelper.PixelMatch("white.jpg", screenshot));
241        }
242
243        [PlaywrightTest("page-screenshot.spec.ts", "should work with odd clip size on Retina displays")]
244        public async Task ShouldWorkWithOddClipSizeOnRetinaDisplays()
245        {
246            byte[] screenshot = await Page.ScreenshotAsync(new()
247            {
248                Clip = new()
249                {
250                    X = 0,
251                    Y = 0,
252                    Width = 11,
253                    Height = 11
254                }
255            });
256
257            Assert.True(ScreenshotHelper.PixelMatch("screenshot-clip-odd-size.png", screenshot));
258        }
259
260        [PlaywrightTest("page-screenshot.spec.ts", "should work with a mobile viewport")]
261        [Skip(SkipAttribute.Targets.Firefox)]
262        public async Task ShouldWorkWithAMobileViewport()
263        {
264            await using var context = await Browser.NewContextAsync(new()
265            {
266                ViewportSize = new()
267                {
268                    Width = 320,
269                    Height = 480,
270                },
271                IsMobile = true,
272            });
273            var page = await context.NewPageAsync();
274            await page.GotoAsync(Server.Prefix + "/overflow.html");
275            byte[] screenshot = await page.ScreenshotAsync();
276
277            Assert.True(ScreenshotHelper.PixelMatch("screenshot-mobile.png", screenshot));
278        }
279
280        [PlaywrightTest("page-screenshot.spec.ts", "should work with a mobile viewport and clip")]
281        [Skip(SkipAttribute.Targets.Firefox)]
282        public async Task ShouldWorkWithAMobileViewportAndClip()
283        {
284            await using var context = await Browser.NewContextAsync(new()
285            {
286                ViewportSize = new()
287                {
288                    Width = 320,
289                    Height = 480,
290                },
291                IsMobile = true,
292            });
293            var page = await context.NewPageAsync();
294            await page.GotoAsync(Server.Prefix + "/overflow.html");
295            byte[] screenshot = await page.ScreenshotAsync(new()
296            {
297                Clip = new()
298                {
299                    X = 10,
300                    Y = 10,
301                    Width = 100,
302                    Height = 150
303                }
304            });
305
306            Assert.True(ScreenshotHelper.PixelMatch("screenshot-mobile-clip.png", screenshot));
307        }
308
309        [PlaywrightTest("page-screenshot.spec.ts", "should work with a mobile viewport and fullPage")]
310        [Skip(SkipAttribute.Targets.Firefox)]
311        public async Task ShouldWorkWithAMobileViewportAndFullPage()
312        {
313            await using var context = await Browser.NewContextAsync(new()
314            {
315                ViewportSize = new()
316                {
317                    Width = 320,
318                    Height = 480,
319                },
320                IsMobile = true,
321            });
322            var page = await context.NewPageAsync();
323            await page.GotoAsync(Server.Prefix + "/overflow-large.html");
324            byte[] screenshot = await page.ScreenshotAsync(new() { FullPage = true });
325
326            Assert.True(ScreenshotHelper.PixelMatch("screenshot-mobile-fullpage.png", screenshot));
327        }
328
329        [PlaywrightTest("page-screenshot.spec.ts", "should work for canvas")]
330        public async Task ShouldWorkForCanvas()
331        {
332            await Page.SetViewportSizeAsync(500, 500);
333            await Page.GotoAsync(Server.Prefix + "/screenshots/canvas.html");
334            byte[] screenshot = await Page.ScreenshotAsync();
335
336            Assert.True(ScreenshotHelper.PixelMatch("screenshot-canvas.png", screenshot));
337        }
338
339        [PlaywrightTest("page-screenshot.spec.ts", "should work for webgl")]
340        [Skip(SkipAttribute.Targets.Firefox, SkipAttribute.Targets.Webkit)]
341        public async Task ShouldWorkForWebgl()
342        {
343            await Page.SetViewportSizeAsync(640, 480);
344            await Page.GotoAsync(Server.Prefix + "/screenshots/webgl.html");
345            byte[] screenshot = await Page.ScreenshotAsync();
346
347            Assert.True(ScreenshotHelper.PixelMatch("screenshot-webgl.png", screenshot));
348        }
349
350        [PlaywrightTest("page-screenshot.spec.ts", "should work for translateZ")]
351        public async Task ShouldWorkForTranslateZ()
352        {
353            await Page.SetViewportSizeAsync(500, 500);
354            await Page.GotoAsync(Server.Prefix + "/screenshots/translateZ.html");
355            byte[] screenshot = await Page.ScreenshotAsync();
356
357            Assert.True(ScreenshotHelper.PixelMatch("screenshot-translateZ.png", screenshot));
358        }
359
360        [PlaywrightTest("page-screenshot.spec.ts", "should work while navigating")]
361        public async Task ShouldWorkWhileNavigating()
362        {
363            await Page.SetViewportSizeAsync(500, 500);
364            await Page.GotoAsync(Server.Prefix + "/redirectloop1.html");
365
366            for (int i = 0; i < 10; ++i)
367            {
368                try
369                {
370                    await Page.ScreenshotAsync();
371                }
372                catch (Exception ex) when (ex.Message.Contains("Cannot take a screenshot while page is navigating"))
373                {
374                }
375            }
376        }
377
378        [PlaywrightTest("page-screenshot.spec.ts", "should work with device scale factor")]
379        public async Task ShouldWorkWithDeviceScaleFactor()
380        {
381            await using var context = await Browser.NewContextAsync(new()
382            {
383                ViewportSize = new()
384                {
385                    Width = 320,
386                    Height = 480,
387                },
388                DeviceScaleFactor = 2,
389            });
390            var page = await context.NewPageAsync();
391            await page.GotoAsync(Server.Prefix + "/grid.html");
392            byte[] screenshot = await page.ScreenshotAsync();
393
394            Assert.True(ScreenshotHelper.PixelMatch("screenshot-device-scale-factor.png", screenshot));
395        }
396
397        [PlaywrightTest("page-screenshot.spec.ts", "should work with iframe in shadow")]
398        public async Task ShouldWorkWithiFrameInShadow()
399        {
400            await using var context = await Browser.NewContextAsync(new()
401            {
402                ViewportSize = new()
403                {
404                    Width = 500,
405                    Height = 500,
406                },
407            });
408            var page = await context.NewPageAsync();
409            await page.GotoAsync(Server.Prefix + "/grid-iframe-in-shadow.html");
410            byte[] screenshot = await page.ScreenshotAsync();
411
412            Assert.True(ScreenshotHelper.PixelMatch("screenshot-iframe.png", screenshot));
413        }
414
415        [PlaywrightTest("page-screenshot.spec.ts", "path option should work")]
416        public async Task PathOptionShouldWork()
417        {
418            await Page.SetViewportSizeAsync(500, 500);
419            await Page.GotoAsync(Server.Prefix + "/grid.html");
420            using var tmpDir = new TempDirectory();
421            string outputPath = Path.Combine(tmpDir.Path, "screenshot.png");
422            await Page.ScreenshotAsync(new() { Path = outputPath });
423
424            Assert.True(ScreenshotHelper.PixelMatch("screenshot-sanity.png", outputPath));
425        }
426
427        [PlaywrightTest("page-screenshot.spec.ts", "path option should create subdirectories")]
428        public async Task PathOptionShouldCreateSubdirectories()
429        {
430            await Page.SetViewportSizeAsync(500, 500);
431            await Page.GotoAsync(Server.Prefix + "/grid.html");
432            using var tmpDir = new TempDirectory();
433            string outputPath = Path.Combine(tmpDir.Path, "these", "are", "directories", "screenshot.png");
434            await Page.ScreenshotAsync(new() { Path = outputPath });
435
436            Assert.True(ScreenshotHelper.PixelMatch("screenshot-sanity.png", outputPath));
437        }
438
439        [PlaywrightTest("page-screenshot.spec.ts", "path option should detect joeg")]
440        public async Task PathOptionShouldDetectJpeg()
441        {
442            await Page.SetViewportSizeAsync(100, 100);
443            await Page.GotoAsync(Server.EmptyPage);
444            using var tmpDir = new TempDirectory();
445            string outputPath = Path.Combine(tmpDir.Path, "screenshot.jpg");
446            await Page.ScreenshotAsync(new() { Path = outputPath, OmitBackground = true });
447
448            Assert.True(ScreenshotHelper.PixelMatch("white.jpg", outputPath));
449        }
450
451        [PlaywrightTest("page-screenshot.spec.ts", "path option should throw for unsupported mime type")]
452        public async Task PathOptionShouldThrowForUnsupportedMimeType()
453        {
454            var exception = await PlaywrightAssert.ThrowsAsync<ArgumentException>(() => Page.ScreenshotAsync(new() { Path = "file.txt" }));
455            StringAssert.Contains("path: unsupported mime type \"text/plain\"", exception.Message);
456        }
457    }
458}
459
Full Screen

ElementHandleScreenshotTests.cs

Source: ElementHandleScreenshotTests.cs Github

copy
1/*
2 * MIT License
3 *
4 * Copyright (c) Microsoft Corporation.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25using System;
26using System.IO;
27using System.Linq;
28using System.Threading.Tasks;
29using Microsoft.Playwright.NUnit;
30using NUnit.Framework;
31using SixLabors.ImageSharp;
32
33namespace Microsoft.Playwright.Tests
34{
35    ///<playwright-file>elementhandle-screenshot.spec.ts</playwright-file>
36    public class ElementHandleScreenshotTests : PageTestEx
37    {
38        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should work")]
39        public async Task ShouldWork()
40        {
41            await Page.SetViewportSizeAsync(500, 500);
42            await Page.GotoAsync(Server.Prefix + "/grid.html");
43            await Page.EvaluateAsync("window.scrollBy(50, 100)");
44            var elementHandle = await Page.QuerySelectorAsync(".box:nth-of-type(3)");
45            byte[] screenshot = await elementHandle.ScreenshotAsync();
46            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-bounding-box.png", screenshot));
47        }
48
49        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should take into account padding and border")]
50        public async Task ShouldTakeIntoAccountPaddingAndBorder()
51        {
52            await Page.SetViewportSizeAsync(500, 500);
53            await Page.SetContentAsync(@"
54                <div style=""height: 14px"">oooo</div>
55                <style>div {
56                    border: 2px solid blue;
57                    background: green;
58                    width: 50px;
59                    height: 50px;
60                }
61                </style>
62                <div id=""d""></div>");
63            var elementHandle = await Page.QuerySelectorAsync("div#d");
64            byte[] screenshot = await elementHandle.ScreenshotAsync();
65            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-padding-border.png", screenshot));
66        }
67
68        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should capture full element when larger than viewport in parallel")]
69        public async Task ShouldCaptureFullElementWhenLargerThanViewportInParallel()
70        {
71            await Page.SetViewportSizeAsync(500, 500);
72            await Page.SetContentAsync(@"
73                <div style=""height: 14px"">oooo</div>
74                <style>
75                div.to-screenshot {
76                  border: 1px solid blue;
77                  width: 600px;
78                  height: 600px;
79                  margin-left: 50px;
80                }
81                ::-webkit-scrollbar{
82                  display: none;
83                }
84                </style>
85                <div class=""to-screenshot""></div>
86                <div class=""to-screenshot""></div>
87                <div class=""to-screenshot""></div>
88            ");
89            var elementHandles = await Page.QuerySelectorAllAsync("div.to-screenshot");
90            var screenshotTasks = elementHandles.Select(e => e.ScreenshotAsync()).ToArray();
91            await TaskUtils.WhenAll(screenshotTasks);
92
93            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-larger-than-viewport.png", screenshotTasks.ElementAt(2).Result));
94        }
95
96        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should capture full element when larger than viewport")]
97        public async Task ShouldCaptureFullElementWhenLargerThanViewport()
98        {
99            await Page.SetViewportSizeAsync(500, 500);
100            await Page.SetContentAsync(@"
101                <div style=""height: 14px"">oooo</div>
102                <style>
103                div.to-screenshot {
104                  border: 1px solid blue;
105                  width: 600px;
106                  height: 600px;
107                  margin-left: 50px;
108                }
109                ::-webkit-scrollbar{
110                  display: none;
111                }
112                </style>
113                <div class=""to-screenshot""></div>
114                <div class=""to-screenshot""></div>
115                <div class=""to-screenshot""></div>");
116
117            var elementHandle = await Page.QuerySelectorAsync("div.to-screenshot");
118            byte[] screenshot = await elementHandle.ScreenshotAsync();
119            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-larger-than-viewport.png", screenshot));
120            await TestUtils.VerifyViewportAsync(Page, 500, 500);
121        }
122
123        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should scroll element into view")]
124        public async Task ShouldScrollElementIntoView()
125        {
126            await Page.SetViewportSizeAsync(500, 500);
127            await Page.SetContentAsync(@"
128                <div style=""height: 14px"">oooo</div>
129                <style>div.above {
130                  border: 2px solid blue;
131                  background: red;
132                  height: 1500px;
133                }
134                div.to-screenshot {
135                  border: 2px solid blue;
136                  background: green;
137                  width: 50px;
138                  height: 50px;
139                }
140                </style>
141                <div class=""above""></div>
142                <div class=""to-screenshot""></div>");
143            var elementHandle = await Page.QuerySelectorAsync("div.to-screenshot");
144            byte[] screenshot = await elementHandle.ScreenshotAsync();
145            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-scrolled-into-view.png", screenshot));
146        }
147
148        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should scroll 15000px into view")]
149        public async Task ShouldScroll15000pxIntoView()
150        {
151            await Page.SetViewportSizeAsync(500, 500);
152            await Page.SetContentAsync(@"
153                <div style=""height: 14px"">oooo</div>
154                <style>div.above {
155                  border: 2px solid blue;
156                  background: red;
157                  height: 15000px;
158                }
159                div.to-screenshot {
160                  border: 2px solid blue;
161                  background: green;
162                  width: 50px;
163                  height: 50px;
164                }
165                </style>
166                <div class=""above""></div>
167                <div class=""to-screenshot""></div>");
168            var elementHandle = await Page.QuerySelectorAsync("div.to-screenshot");
169            byte[] screenshot = await elementHandle.ScreenshotAsync();
170            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-scrolled-into-view.png", screenshot));
171        }
172
173        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should work with a rotated element")]
174        public async Task ShouldWorkWithARotatedElement()
175        {
176            await Page.SetViewportSizeAsync(500, 500);
177            await Page.SetContentAsync(@"
178                <div style='position: absolute;
179                top: 100px;
180                left: 100px;
181                width: 100px;
182                height: 100px;
183                background: green;
184                transform: rotateZ(200deg); '>&nbsp;</div>
185            ");
186            var elementHandle = await Page.QuerySelectorAsync("div");
187            byte[] screenshot = await elementHandle.ScreenshotAsync();
188            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-rotate.png", screenshot));
189        }
190
191        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should fail to screenshot a detached element")]
192        public async Task ShouldFailToScreenshotADetachedElement()
193        {
194            await Page.SetContentAsync("<h1>remove this</h1>");
195            var elementHandle = await Page.QuerySelectorAsync("h1");
196            await Page.EvaluateAsync("element => element.remove()", elementHandle);
197
198            var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => elementHandle.ScreenshotAsync());
199            StringAssert.Contains("Element is not attached to the DOM", exception.Message);
200        }
201
202        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should timeout waiting for visible")]
203        public async Task ShouldTimeoutWaitingForVisible()
204        {
205            await Page.SetContentAsync(@"<div style='width: 50px; height: 0'></div>");
206            var elementHandle = await Page.QuerySelectorAsync("div");
207            var exception = await PlaywrightAssert.ThrowsAsync<TimeoutException>(() => elementHandle.ScreenshotAsync(new() { Timeout = 3000 }));
208            StringAssert.Contains("Timeout 3000ms exceeded", exception.Message);
209            StringAssert.Contains("element is not visible", exception.Message);
210        }
211
212        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should wait for visible")]
213        public async Task ShouldWaitForVisible()
214        {
215            await Page.SetViewportSizeAsync(500, 500);
216            await Page.GotoAsync(Server.Prefix + "/grid.html");
217            await Page.EvaluateAsync("() => window.scrollBy(50, 100)");
218            var elementHandle = await Page.QuerySelectorAsync(".box:nth-of-type(3)");
219            await elementHandle.EvaluateAsync("e => e.style.visibility = 'hidden'");
220            var task = elementHandle.ScreenshotAsync();
221
222            for (int i = 0; i < 10; i++)
223            {
224                await Page.EvaluateAsync("() => new Promise(f => requestAnimationFrame(f))");
225            }
226            Assert.False(task.IsCompleted);
227            await elementHandle.EvaluateAsync("e => e.style.visibility = 'visible'");
228
229            byte[] screenshot = await task;
230            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-bounding-box.png", screenshot));
231        }
232
233        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should work for an element with fractional dimensions")]
234        public async Task ShouldWorkForAnElementWithFractionalDimensions()
235        {
236            await Page.SetContentAsync("<div style=\"width:48.51px;height:19.8px;border:1px solid black;\"></div>");
237            var elementHandle = await Page.QuerySelectorAsync("div");
238            byte[] screenshot = await elementHandle.ScreenshotAsync();
239            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-fractional.png", screenshot));
240        }
241
242        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should work with a mobile viewport")]
243        [Skip(SkipAttribute.Targets.Firefox)]
244        public async Task ShouldWorkWithAMobileViewport()
245        {
246            await using var context = await Browser.NewContextAsync(new()
247            {
248                ViewportSize = new()
249                {
250                    Width = 320,
251                    Height = 480,
252                },
253                IsMobile = true,
254            });
255            var page = await context.NewPageAsync();
256            await page.GotoAsync(Server.Prefix + "/grid.html");
257            await page.EvaluateAsync("() => window.scrollBy(50, 100)");
258            var elementHandle = await page.QuerySelectorAsync(".box:nth-of-type(3)");
259            byte[] screenshot = await elementHandle.ScreenshotAsync();
260
261            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-mobile.png", screenshot));
262        }
263
264        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should work with device scale factor")]
265        [Skip(SkipAttribute.Targets.Firefox)]
266        public async Task ShouldWorkWithDeviceScaleFactor()
267        {
268            await using var context = await Browser.NewContextAsync(new()
269            {
270                ViewportSize = new()
271                {
272                    Width = 320,
273                    Height = 480,
274                },
275                DeviceScaleFactor = 2,
276            });
277            var page = await context.NewPageAsync();
278            await page.GotoAsync(Server.Prefix + "/grid.html");
279            await page.EvaluateAsync("() => window.scrollBy(50, 100)");
280            var elementHandle = await page.QuerySelectorAsync(".box:nth-of-type(3)");
281            byte[] screenshot = await elementHandle.ScreenshotAsync();
282
283            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-mobile-dsf.png", screenshot));
284        }
285
286        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should work for an element with an offset")]
287        public async Task ShouldWorkForAnElementWithAnOffset()
288        {
289            await Page.SetContentAsync("<div style=\"position:absolute; top: 10.3px; left: 20.4px;width:50.3px;height:20.2px;border:1px solid black;\"></div>");
290            var elementHandle = await Page.QuerySelectorAsync("div");
291            byte[] screenshot = await elementHandle.ScreenshotAsync();
292            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-fractional-offset.png", screenshot));
293        }
294
295        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should take screenshots when default viewport is null")]
296        public async Task ShouldTakeScreenshotsWhenDefaultViewportIsNull()
297        {
298            await using var context = await Browser.NewContextAsync(new()
299            {
300                ViewportSize = ViewportSize.NoViewport
301            });
302            var page = await context.NewPageAsync();
303            await page.SetContentAsync("<div style='height: 10000px; background: red'></div>");
304            var windowSize = await page.EvaluateAsync<ViewportSize>("() => ({ width: window.innerWidth * window.devicePixelRatio, height: window.innerHeight * window.devicePixelRatio })");
305            var sizeBefore = await page.EvaluateAsync<ViewportSize>("() => ({ width: document.body.offsetWidth, height: document.body.offsetHeight })");
306
307            byte[] screenshot = await page.ScreenshotAsync();
308            Assert.NotNull(screenshot);
309            var decoded = Image.Load(screenshot);
310            Assert.AreEqual(windowSize.Width, decoded.Width);
311            Assert.AreEqual(windowSize.Height, decoded.Height);
312
313            var sizeAfter = await page.EvaluateAsync<ViewportSize>("() => ({ width: document.body.offsetWidth, height: document.body.offsetHeight })");
314            Assert.AreEqual(sizeBefore.Width, sizeAfter.Width);
315            Assert.AreEqual(sizeBefore.Height, sizeAfter.Height);
316        }
317
318        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should take fullPage screenshots when default viewport is null")]
319        public async Task ShouldTakeFullPageScreenshotsWhenDefaultViewportIsNull()
320        {
321            await using var context = await Browser.NewContextAsync(new()
322            {
323                ViewportSize = ViewportSize.NoViewport
324            });
325            var page = await context.NewPageAsync();
326            await page.GotoAsync(Server.Prefix + "/grid.html");
327            var sizeBefore = await page.EvaluateAsync<ViewportSize>("() => ({ width: document.body.offsetWidth, height: document.body.offsetHeight })");
328
329            byte[] screenshot = await page.ScreenshotAsync(new() { FullPage = true });
330            Assert.NotNull(screenshot);
331
332            var sizeAfter = await page.EvaluateAsync<ViewportSize>("() => ({ width: document.body.offsetWidth, height: document.body.offsetHeight })");
333            Assert.AreEqual(sizeBefore.Width, sizeAfter.Width);
334            Assert.AreEqual(sizeBefore.Height, sizeAfter.Height);
335        }
336
337        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should restore default viewport after fullPage screenshot")]
338        public async Task ShouldRestoreDefaultViewportAfterFullPageScreenshot()
339        {
340            await using var context = await Browser.NewContextAsync(new()
341            {
342                ViewportSize = new() { Width = 456, Height = 789 },
343            });
344            var page = await context.NewPageAsync();
345            await TestUtils.VerifyViewportAsync(page, 456, 789);
346            byte[] screenshot = await page.ScreenshotAsync(new() { FullPage = true });
347            Assert.NotNull(screenshot);
348
349            await TestUtils.VerifyViewportAsync(page, 456, 789);
350        }
351
352        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should take element screenshot when default viewport is null and restore back")]
353        public async Task ShouldTakeElementScreenshotWhenDefaultViewportIsNullAndRestoreBack()
354        {
355            await using var context = await Browser.NewContextAsync(new()
356            {
357                ViewportSize = ViewportSize.NoViewport,
358            });
359            var page = await context.NewPageAsync();
360
361            await page.SetContentAsync(@"
362                <div style=""height: 14px"">oooo</div>
363                <style>
364                div.to-screenshot {
365                border: 1px solid blue;
366                width: 600px;
367                height: 600px;
368                margin-left: 50px;
369                }
370                ::-webkit-scrollbar{
371                display: none;
372                }
373                </style>
374                <div class=""to-screenshot""></div>
375                <div class=""to-screenshot""></div>
376                <div class=""to-screenshot""></div>");
377
378            var sizeBefore = await page.EvaluateAsync<ViewportSize>("() => ({ width: document.body.offsetWidth, height: document.body.offsetHeight })");
379            var elementHandle = await page.QuerySelectorAsync("div.to-screenshot");
380            byte[] screenshot = await elementHandle.ScreenshotAsync();
381            Assert.NotNull(screenshot);
382
383            var sizeAfter = await page.EvaluateAsync<ViewportSize>("() => ({ width: document.body.offsetWidth, height: document.body.offsetHeight })");
384            Assert.AreEqual(sizeBefore.Width, sizeAfter.Width);
385            Assert.AreEqual(sizeBefore.Height, sizeAfter.Height);
386        }
387
388        [PlaywrightTest("elementhandle-screenshot.spec.ts", "should take screenshot of disabled button")]
389        public async Task ShouldTakeScreenshotOfDisabledButton()
390        {
391            await Page.SetViewportSizeAsync(500, 500);
392            await Page.SetContentAsync("<button disabled>Click me</button>");
393            var button = await Page.QuerySelectorAsync("button");
394            byte[] screenshot = await button.ScreenshotAsync();
395            Assert.NotNull(screenshot);
396        }
397
398        [PlaywrightTest("elementhandle-screenshot.spec.ts", "path option should create subdirectories")]
399        public async Task PathOptionShouldCreateSubdirectories()
400        {
401            await Page.SetViewportSizeAsync(500, 500);
402            await Page.GotoAsync(Server.Prefix + "/grid.html");
403            await Page.EvaluateAsync("() => window.scrollBy(50, 100)");
404            var elementHandle = await Page.QuerySelectorAsync(".box:nth-of-type(3)");
405            using var tmpDir = new TempDirectory();
406            string outputPath = Path.Combine(tmpDir.Path, "these", "are", "directories", "screenshot.png");
407            await elementHandle.ScreenshotAsync(new() { Path = outputPath });
408            Assert.True(ScreenshotHelper.PixelMatch("screenshot-element-bounding-box.png", outputPath));
409        }
410    }
411}
412
Full Screen

PageRequestFulfillTests.cs

Source: PageRequestFulfillTests.cs Github

copy
1/*
2 * MIT License
3 *
4 * Copyright (c) Microsoft Corporation.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25using System.Collections.Generic;
26using System.IO;
27using System.Linq;
28using System.Net;
29using System.Threading.Tasks;
30using Microsoft.AspNetCore.Http;
31using NUnit.Framework;
32
33namespace Microsoft.Playwright.Tests
34{
35    public class RequestFulfillTests : PageTestEx
36    {
37        [PlaywrightTest("page-request-fulfill.spec.ts", "should work")]
38        public async Task ShouldWork()
39        {
40            await Page.RouteAsync("**/*", (route) =>
41            {
42                route.FulfillAsync(new()
43                {
44                    Status = (int)HttpStatusCode.Created,
45                    Headers = new Dictionary<string, string>
46                    {
47                        ["foo"] = "bar"
48                    },
49                    ContentType = "text/html",
50                    Body = "Yo, page!",
51                });
52            });
53            var response = await Page.GotoAsync(Server.EmptyPage);
54            Assert.AreEqual((int)HttpStatusCode.Created, response.Status);
55#pragma warning disable 0612
56            Assert.AreEqual("bar", response.Headers["foo"]);
57#pragma warning restore 0612
58            Assert.AreEqual("Yo, page!", await Page.EvaluateAsync<string>("() => document.body.textContent"));
59        }
60
61        /// <summary>
62        /// In Playwright this method is called ShouldWorkWithStatusCode422.
63        /// I found that status 422 is not available in all .NET runtime versions (see https://github.com/dotnet/core/blob/4c4642d548074b3fbfd425541a968aadd75fea99/release-notes/2.1/Preview/api-diff/preview2/2.1-preview2_System.Net.md)
64        /// As the goal here is testing HTTP codes that are not in Chromium (see https://cs.chromium.org/chromium/src/net/http/http_status_code_list.h?sq=package:chromium) we will use code 426: Upgrade Required
65        /// </summary>
66        [PlaywrightTest("page-request-fulfill.spec.ts", "should work with status code 422")]
67        public async Task ShouldWorkWithStatusCode422()
68        {
69            await Page.RouteAsync("**/*", (route) =>
70            {
71                route.FulfillAsync(new() { Status = (int)HttpStatusCode.UpgradeRequired, Body = "Yo, page!" });
72            });
73            var response = await Page.GotoAsync(Server.EmptyPage);
74            Assert.AreEqual((int)HttpStatusCode.UpgradeRequired, response.Status);
75            Assert.AreEqual("Upgrade Required", response.StatusText);
76            Assert.AreEqual("Yo, page!", await Page.EvaluateAsync<string>("() => document.body.textContent"));
77        }
78
79        [PlaywrightTest("page-request-fulfill.spec.ts", "should allow mocking binary responses")]
80        [Ignore("We need screenshots for this")]
81        public async Task ShouldAllowMockingBinaryResponses()
82        {
83            await Page.RouteAsync("**/*", (route) =>
84            {
85                byte[] imageBuffer = File.ReadAllBytes(TestUtils.GetAsset("pptr.png"));
86                route.FulfillAsync(new()
87                {
88                    ContentType = "image/png",
89                    BodyBytes = imageBuffer,
90                });
91            });
92            await Page.EvaluateAsync(@"PREFIX => {
93                const img = document.createElement('img');
94                img.src = PREFIX + '/does-not-exist.png';
95                document.body.appendChild(img);
96                return new Promise(fulfill => img.onload = fulfill);
97            }", Server.Prefix);
98            var img = await Page.QuerySelectorAsync("img");
99            Assert.True(ScreenshotHelper.PixelMatch("mock-binary-response.png", await img.ScreenshotAsync()));
100        }
101
102        [PlaywrightTest("page-request-fulfill.spec.ts", "should allow mocking svg with charset")]
103        [Ignore("We need screenshots for this")]
104        public void ShouldAllowMockingSvgWithCharset()
105        {
106        }
107
108        [PlaywrightTest("page-request-fulfill.spec.ts", "should work with file path")]
109        [Ignore("We need screenshots for this")]
110        public async Task ShouldWorkWithFilePath()
111        {
112            await Page.RouteAsync("**/*", (route) =>
113            {
114                route.FulfillAsync(new()
115                {
116                    ContentType = "shouldBeIgnored",
117                    Path = TestUtils.GetAsset("pptr.png"),
118                });
119            });
120
121            await Page.EvaluateAsync(@"PREFIX => {
122                const img = document.createElement('img');
123                img.src = PREFIX + '/does-not-exist.png';
124                document.body.appendChild(img);
125                return new Promise(fulfill => img.onload = fulfill);
126            }", Server.Prefix);
127            var img = await Page.QuerySelectorAsync("img");
128            Assert.True(ScreenshotHelper.PixelMatch("mock-binary-response.png", await img.ScreenshotAsync()));
129        }
130
131        [PlaywrightTest("page-request-fulfill.spec.ts", "should stringify intercepted request response headers")]
132        public async Task ShouldStringifyInterceptedRequestResponseHeaders()
133        {
134            await Page.RouteAsync("**/*", (route) =>
135            {
136                route.FulfillAsync(new()
137                {
138                    Status = (int)HttpStatusCode.OK,
139                    Headers = new Dictionary<string, string>
140                    {
141                        ["foo"] = "true"
142                    },
143                    Body = "Yo, page!",
144                });
145            });
146
147            var response = await Page.GotoAsync(Server.EmptyPage);
148            Assert.AreEqual((int)HttpStatusCode.OK, response.Status);
149#pragma warning disable 0612
150            Assert.AreEqual("true", response.Headers["foo"]);
151#pragma warning restore 0612
152            Assert.AreEqual("Yo, page!", await Page.EvaluateAsync<string>("() => document.body.textContent"));
153        }
154
155        [PlaywrightTest("page-request-fulfill.spec.ts", "should not modify the headers sent to the server")]
156        [Ignore("Flacky with the ASP.NET server")]
157        public async Task ShouldNotModifyTheHeadersSentToTheServer()
158        {
159            await Page.GotoAsync(Server.EmptyPage);
160            var interceptedRequests = new List<Dictionary<string, string>>();
161
162            await Page.GotoAsync(Server.Prefix + "/unused");
163
164            Server.SetRoute("/something", ctx =>
165            {
166                var hh = new Dictionary<string, string>();
167                foreach (var h in ctx.Request.Headers)
168                {
169                    hh[h.Key] = h.Value;
170                }
171                interceptedRequests.Add(hh);
172                ctx.Response.Headers["Access-Control-Allow-Origin"] = "*";
173                return ctx.Response.WriteAsync("done");
174            });
175
176            string text = await Page.EvaluateAsync<string>(@"async url => {
177                const data = await fetch(url);
178                return data.text();
179            }", Server.CrossProcessPrefix + "/something");
180
181            Assert.AreEqual("done", text);
182
183            IRequest playwrightRequest = null;
184
185            await Page.RouteAsync(Server.CrossProcessPrefix + "/something", (route) =>
186            {
187                playwrightRequest = route.Request;
188#pragma warning disable 0612
189                route.ContinueAsync(new() { Headers = route.Request.Headers.ToDictionary(x => x.Key, x => x.Value) });
190#pragma warning restore 0612
191            });
192
193            string textAfterRoute = await Page.EvaluateAsync<string>(@"async url => {
194                const data = await fetch(url);
195                return data.text();
196            }", Server.CrossProcessPrefix + "/something");
197
198            Assert.AreEqual("done", textAfterRoute);
199
200            Assert.AreEqual(2, interceptedRequests.Count);
201            Assert.AreEqual(interceptedRequests[1].OrderBy(kv => kv.Key), interceptedRequests[0].OrderBy(kv => kv.Key));
202        }
203
204        [PlaywrightTest("page-request-fulfill.spec.ts", "should include the origin header")]
205        public async Task ShouldIncludeTheOriginHeader()
206        {
207            await Page.GotoAsync(Server.EmptyPage);
208            IRequest interceptedRequest = null;
209
210            await Page.RouteAsync(Server.CrossProcessPrefix + "/something", (route) =>
211            {
212                interceptedRequest = route.Request;
213                route.FulfillAsync(new()
214                {
215                    Headers = new Dictionary<string, string> { ["Access-Control-Allow-Origin"] = "*" },
216                    ContentType = "text/plain",
217                    Body = "done",
218                });
219            });
220
221            string text = await Page.EvaluateAsync<string>(@"async url => {
222                const data = await fetch(url);
223                return data.text();
224            }", Server.CrossProcessPrefix + "/something");
225
226            Assert.AreEqual("done", text);
227#pragma warning disable 0612
228            Assert.AreEqual(Server.Prefix, interceptedRequest.Headers["origin"]);
229#pragma warning restore 0612
230        }
231    }
232}
233
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Most used methods in ScreenshotHelper

Run Selenium Automation Tests on LambdaTest Cloud Grid

Trigger Selenium automation tests on a cloud-based Grid of 3000+ real browsers and operating systems.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)