Skip to content

Commit d941b92

Browse files
authored
Bidi Screenshot support (#3007)
* Bidi Screenshot support * fix * Fix another test * fix * Support NewPageAsync * anoter fix * fix * Good fix
1 parent ee68e9b commit d941b92

File tree

6 files changed

+44
-56
lines changed

6 files changed

+44
-56
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ await Page.SetViewportAsync(new ViewPortOptions
7474
Height = 500
7575
});
7676
```
77-
<sup><a href='https://github.com/hardkoded/puppeteer-sharp/blob/master/lib/PuppeteerSharp.Tests/ScreenshotTests/ElementHandleScreenshotTests.cs#L13-L19' title='Snippet source file'>snippet source</a> | <a href='#snippet-setviewportasync_example' title='Start of snippet'>anchor</a></sup>
77+
<sup><a href='https://github.com/hardkoded/puppeteer-sharp/blob/master/lib/PuppeteerSharp.Tests/ScreenshotTests/ElementHandleScreenshotTests.cs#L12-L18' title='Snippet source file'>snippet source</a> | <a href='#snippet-setviewportasync_example' title='Start of snippet'>anchor</a></sup>
7878
<!-- endSnippet -->
7979

8080
### Generate PDF files

lib/PuppeteerSharp.Nunit/TestExpectations/TestExpectations.local.json

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,6 @@
6262
"parameters": ["firefox"],
6363
"expectations": ["FAIL"]
6464
},
65-
{
66-
"comment": "TODO Review screenshots in firefox",
67-
"testIdPattern": "[screenshot.spec] *",
68-
"platforms": ["darwin", "linux", "win32"],
69-
"parameters": ["firefox"],
70-
"expectations": ["FAIL"]
71-
},
7265
{
7366
"comment": "This is passing on my machine but failing on CI/CD",
7467
"testIdPattern": "[click.spec] Page.click should fire aux event on middle click",
@@ -1095,21 +1088,6 @@
10951088
"FAIL"
10961089
]
10971090
},
1098-
{
1099-
"comment": "This is part of organizing the webdriver bidi implementation, We will remove it one by one",
1100-
"testIdPattern": "[page.spec] *Page.title*",
1101-
"platforms": [
1102-
"darwin",
1103-
"linux",
1104-
"win32"
1105-
],
1106-
"parameters": [
1107-
"webDriverBiDi"
1108-
],
1109-
"expectations": [
1110-
"FAIL"
1111-
]
1112-
},
11131091
{
11141092
"comment": "This is part of organizing the webdriver bidi implementation, We will remove it one by one",
11151093
"testIdPattern": "[page.spec] *Page.url*",
@@ -1245,21 +1223,6 @@
12451223
"FAIL"
12461224
]
12471225
},
1248-
{
1249-
"comment": "This is part of organizing the webdriver bidi implementation, We will remove it one by one",
1250-
"testIdPattern": "[screenshot.spec] *",
1251-
"platforms": [
1252-
"darwin",
1253-
"linux",
1254-
"win32"
1255-
],
1256-
"parameters": [
1257-
"webDriverBiDi"
1258-
],
1259-
"expectations": [
1260-
"FAIL"
1261-
]
1262-
},
12631226
{
12641227
"comment": "This is part of organizing the webdriver bidi implementation, We will remove it one by one",
12651228
"testIdPattern": "[stacktrace.spec] *",

lib/PuppeteerSharp.Tests/ScreenshotTests/ElementHandleScreenshotTests.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Text.Json;
21
using System.Threading.Tasks;
32
using NUnit.Framework;
43
using PuppeteerSharp.Nunit;
@@ -76,9 +75,9 @@ something above
7675

7776
Assert.That(ScreenshotHelper.PixelMatch("screenshot-element-larger-than-viewport.png", screenshot), Is.True);
7877
var currentSize =
79-
await Page.EvaluateExpressionAsync<JsonElement>("({ w: window.innerWidth, h: window.innerHeight })");
80-
Assert.That(currentSize.GetProperty("w").GetInt32(), Is.EqualTo(500));
81-
Assert.That(currentSize.GetProperty("h").GetInt32(), Is.EqualTo(500));
78+
await Page.EvaluateExpressionAsync<int[]>("([window.innerWidth, window.innerHeight])");
79+
Assert.That(currentSize[0], Is.EqualTo(500));
80+
Assert.That(currentSize[1], Is.EqualTo(500));
8281
}
8382

8483
[Test, PuppeteerTest("screenshot.spec", "Screenshots ElementHandle.screenshot", "should scroll element into view")]
@@ -119,7 +118,7 @@ await Page.SetViewportAsync(new ViewPortOptions
119118
Width = 500,
120119
Height = 500
121120
});
122-
await Page.SetContentAsync(@"
121+
await Page.SetContentAsync(@"<!DOCTYPE html>
123122
<div style='position: absolute;
124123
top: 100px;
125124
left: 100px;
@@ -165,7 +164,7 @@ public async Task ShouldWorkForAnElementWithFractionalDimensions()
165164
[Test, PuppeteerTest("screenshot.spec", "Screenshots ElementHandle.screenshot", "should work for an element with an offset")]
166165
public async Task ShouldWorkForAnElementWithAnOffset()
167166
{
168-
await Page.SetContentAsync("<div style=\"position:absolute; top: 10.3px; left: 20.4px;width:50.3px;height:20.2px;border:1px solid black;\"></div>");
167+
await Page.SetContentAsync("<!DOCTYPE html><div style=\"position:absolute; top: 10.3px; left: 20.4px;width:50.3px;height:20.2px;border:1px solid black;\"></div>");
169168
var elementHandle = await Page.QuerySelectorAsync("div");
170169
var screenshot = await elementHandle.ScreenshotDataAsync();
171170
Assert.That(ScreenshotHelper.PixelMatch("screenshot-element-fractional-offset.png", screenshot), Is.True);

lib/PuppeteerSharp.Tests/ScreenshotTests/PageScreenshotTests.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ await page.SetViewportAsync(new ViewPortOptions
100100
Assert.That(ScreenshotHelper.PixelMatch("screenshot-clip-rect.png", screenshot), Is.True);
101101
}
102102

103-
[Test, PuppeteerTest("screenshot.spec", "Screenshots Page.screenshot", "should use scale for clip")]
103+
[Test, PuppeteerTest("screenshot.spec", "Screenshots Cdp", "should use scale for clip")]
104104
public async Task ShouldUseScaleForClip()
105105
{
106106
await using var page = await Context.NewPageAsync();
@@ -152,14 +152,14 @@ await page.SetViewportAsync(new ViewPortOptions
152152
public async Task ShouldClipElementsToTheViewport()
153153
{
154154
await using var page = await Context.NewPageAsync();
155-
await page.SetViewportAsync(new ViewPortOptions { Width = 500, Height = 500 });
155+
await page.SetViewportAsync(new ViewPortOptions { Width = 50, Height = 50 });
156156
await page.GoToAsync(TestConstants.ServerUrl + "/grid.html");
157157
var screenshot = await page.ScreenshotDataAsync(new ScreenshotOptions
158158
{
159159
Clip = new Clip
160160
{
161-
X = 50,
162-
Y = 600,
161+
X = 25,
162+
Y = 25,
163163
Width = 100,
164164
Height = 100
165165
}
@@ -314,6 +314,8 @@ public async Task ShouldWorkWithWebp()
314314
public async Task ShouldWorkWithOddClipSizeOnRetinaDisplays()
315315
{
316316
await using var page = await Context.NewPageAsync();
317+
// Make sure documentElement height is at least 11px.
318+
await page.SetContentAsync("<div style=\"width: 11px; height: 11px;\"></div>");
317319
var screenshot = await page.ScreenshotDataAsync(new ScreenshotOptions
318320
{
319321
Clip = new Clip

lib/PuppeteerSharp/Bidi/BidiBrowser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public override async Task CloseAsync()
123123
}
124124

125125
/// <inheritdoc />
126-
public override Task<IPage> NewPageAsync() => throw new NotImplementedException();
126+
public override Task<IPage> NewPageAsync() => DefaultContext.NewPageAsync();
127127

128128
/// <inheritdoc />
129129
public override ITarget[] Targets()

lib/PuppeteerSharp/Bidi/BidiPage.cs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -491,12 +491,19 @@ protected override async Task<string> PerformScreenshotAsync(ScreenshotType type
491491
throw new PuppeteerException("BiDi does not support 'scale' in 'clip'.");
492492
}
493493

494-
BoundingBox box;
494+
BoundingBox box = null;
495495
if (options.Clip != null)
496496
{
497497
if (options.CaptureBeyondViewport)
498498
{
499-
box = options.Clip;
499+
// Create a new box to avoid reference issues
500+
box = new Clip
501+
{
502+
X = options.Clip.X,
503+
Y = options.Clip.Y,
504+
Width = options.Clip.Width,
505+
Height = options.Clip.Height,
506+
};
500507
}
501508
else
502509
{
@@ -513,8 +520,13 @@ protected override async Task<string> PerformScreenshotAsync(ScreenshotType type
513520
];
514521
}").ConfigureAwait(false);
515522

516-
options.Clip.X += decimal.Floor(points[0]);
517-
options.Clip.Y += decimal.Floor(points[1]);
523+
box = new Clip
524+
{
525+
X = options.Clip.X - points[0],
526+
Y = options.Clip.Y - points[1],
527+
Width = options.Clip.Width,
528+
Height = options.Clip.Height,
529+
};
518530
}
519531
}
520532

@@ -526,16 +538,28 @@ protected override async Task<string> PerformScreenshotAsync(ScreenshotType type
526538
_ => "png",
527539
};
528540

529-
// TODO: Missing box
530-
var data = await BidiMainFrame.BrowsingContext.CaptureScreenshotAsync(new ScreenshotParameters()
541+
var parameters = new ScreenshotParameters()
531542
{
532543
Origin = options.CaptureBeyondViewport ? ScreenshotOrigin.Document : ScreenshotOrigin.Viewport,
533544
Format = new ImageFormat()
534545
{
535546
Type = $"image/{fileType}",
536547
Quality = options.Quality / 100,
537548
},
538-
}).ConfigureAwait(false);
549+
};
550+
551+
if (box != null)
552+
{
553+
parameters.Clip = new BoxClipRectangle
554+
{
555+
X = (double)box.X,
556+
Y = (double)box.Y,
557+
Width = (double)box.Width,
558+
Height = (double)box.Height,
559+
};
560+
}
561+
562+
var data = await BidiMainFrame.BrowsingContext.CaptureScreenshotAsync(parameters).ConfigureAwait(false);
539563

540564
return data;
541565
}

0 commit comments

Comments
 (0)