Skip to content

Commit d85935a

Browse files
fix: Fix masking in single element screenshots.
Using masks in single element screenshots (`Locator.screenshot()`) never worked, because the mask option failed to be serialized. Add a serializer for `LocatorImpl`, so that this works everywhere correctly. Fixes #1790
1 parent 0cf8c4e commit d85935a

File tree

3 files changed

+20
-11
lines changed

3 files changed

+20
-11
lines changed

playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,18 +1166,8 @@ private byte[] screenshotImpl(ScreenshotOptions options) {
11661166
}
11671167
}
11681168
}
1169-
List<Locator> mask = options.mask;
1170-
options.mask = null;
11711169
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
1172-
options.mask = mask;
11731170
params.remove("path");
1174-
if (mask != null) {
1175-
JsonArray maskArray = new JsonArray();
1176-
for (Locator locator: mask) {
1177-
maskArray.add(((LocatorImpl) locator).toProtocol());
1178-
}
1179-
params.add("mask", maskArray);
1180-
}
11811171
JsonObject json = sendMessage("screenshot", params, timeoutSettings.timeout(options.timeout)).getAsJsonObject();
11821172

11831173
byte[] buffer = Base64.getDecoder().decode(json.get("binary").getAsString());

playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class Serialization {
6666
.registerTypeHierarchyAdapter(JSHandleImpl.class, new HandleSerializer())
6767
.registerTypeAdapter((new TypeToken<Map<String, String>>(){}).getType(), new StringMapSerializer())
6868
.registerTypeAdapter((new TypeToken<Map<String, Object>>(){}).getType(), new FirefoxUserPrefsSerializer())
69+
.registerTypeAdapter(LocatorImpl.class, new LocatorImplSerializer())
6970
.registerTypeHierarchyAdapter(Path.class, new PathSerializer()).create();
7071

7172
static Gson gson() {
@@ -490,6 +491,13 @@ public JsonElement serialize(E src, Type typeOfSrc, JsonSerializationContext con
490491
}
491492
}
492493

494+
private static class LocatorImplSerializer implements JsonSerializer<LocatorImpl> {
495+
@Override
496+
public JsonElement serialize(LocatorImpl src, Type typeOfSrc, JsonSerializationContext context) {
497+
return src.toProtocol();
498+
}
499+
}
500+
493501
private static class SameSiteAdapter extends TypeAdapter<SameSiteAttribute> {
494502
@Override
495503
public void write(JsonWriter out, SameSiteAttribute value) throws IOException {

playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ void shouldNotCaptureInfiniteWebAnimations() {
136136
}
137137

138138
@Test
139-
void maskShouldWork() {
139+
void maskShouldWorkForPage() {
140140
page.setViewportSize(500, 500);
141141
page.navigate(server.PREFIX + "/grid.html");
142142
byte[] screenshot = page.screenshot(new Page.ScreenshotOptions()
@@ -146,6 +146,17 @@ void maskShouldWork() {
146146
assertThrows(AssertionFailedError.class, () -> assertArrayEquals(screenshot, originalScreenshot));
147147
}
148148

149+
@Test
150+
void maskShouldWorkForLocator() {
151+
page.navigate(server.PREFIX + "/grid.html");
152+
Locator locatorToScreenshot = page.locator("div").first();
153+
byte[] screenshot = locatorToScreenshot.screenshot(new Locator.ScreenshotOptions()
154+
.setMask(asList(page.locator("img"))));
155+
// TODO: toMatchSnapshot is not present in java, so we only checks that masked screenshot is different.
156+
byte[] originalScreenshot = locatorToScreenshot.screenshot();
157+
assertThrows(AssertionFailedError.class, () -> assertArrayEquals(screenshot, originalScreenshot));
158+
}
159+
149160
@Test
150161
void shouldWorkWithDeviceScaleFactorAndClip() {
151162
try (BrowserContext context = browser.newContext(new Browser.NewContextOptions()

0 commit comments

Comments
 (0)