You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Use this reproduction example, run the main method.
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Locator;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import java.util.List;
public class LocatorScreenshotBugReproducer {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create();
Browser browser = playwright.chromium().launch()) {
BrowserContext context = browser.newContext();
Page page = context.newPage();
page.navigate("https://www.playwright.dev");
var heading = page.locator("h1");
heading.waitFor();
// this throws exception, only if a mask is specified
heading.screenshot(
new Locator.ScreenshotOptions()
.setMask(List.of(heading.locator("span"))));
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
Expected behavior
Screenshot should be taken
Actual behavior
The code fails with an exception and the following stack trace:
com.google.gson.JsonIOException: Failed making field 'java.lang.Throwable#detailMessage' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type.
at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:38)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:286)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
at com.google.gson.Gson.getAdapter(Gson.java:556)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:160)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:294)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
at com.google.gson.Gson.getAdapter(Gson.java:556)
at com.google.gson.internal.bind.MapTypeAdapterFactory.create(MapTypeAdapterFactory.java:125)
at com.google.gson.Gson.getAdapter(Gson.java:556)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:160)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:294)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
at com.google.gson.Gson.getAdapter(Gson.java:556)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:160)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:294)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
at com.google.gson.Gson.getAdapter(Gson.java:556)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:160)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:294)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
at com.google.gson.Gson.getAdapter(Gson.java:556)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:160)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:294)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
at com.google.gson.Gson.getAdapter(Gson.java:556)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:160)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:294)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
at com.google.gson.Gson.getAdapter(Gson.java:556)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:55)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:196)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:368)
at com.google.gson.Gson.toJson(Gson.java:842)
at com.google.gson.Gson.toJsonTree(Gson.java:712)
at com.google.gson.Gson.toJsonTree(Gson.java:689)
at com.microsoft.playwright.impl.ElementHandleImpl.screenshotImpl(ElementHandleImpl.java:349)
at com.microsoft.playwright.impl.ElementHandleImpl.lambda$screenshot$25(ElementHandleImpl.java:329)
at com.microsoft.playwright.impl.LoggingSupport.withLogging(LoggingSupport.java:47)
at com.microsoft.playwright.impl.ChannelOwner.withLogging(ChannelOwner.java:97)
at com.microsoft.playwright.impl.ElementHandleImpl.screenshot(ElementHandleImpl.java:329)
at com.microsoft.playwright.impl.LocatorImpl.lambda$screenshot$5(LocatorImpl.java:486)
at com.microsoft.playwright.impl.LocatorImpl.withElement(LocatorImpl.java:85)
at com.microsoft.playwright.impl.LocatorImpl.screenshot(LocatorImpl.java:486)
at LocatorScreenshotBugReproducer.main(LocatorScreenshotBugReproducer.java:22)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private java.lang.String java.lang.Throwable.detailMessage accessible: module java.base does not "opens java.lang" to unnamed module @59fa0ced
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:35)
... 47 more
Additional context
Bug analysis:
The Locator screenshot functionality forgets to remove the mask field from the generic Gson serialization of the options, and Gson finally fails because deep inside the mask field (which is a Locator) is an Exception field which cannot be serialized.
The Page screenshot code has handled this by special-casing the mask field. This needs to be done also for the Locator code (actually located in ElementHandleImpl).
Version
1.52.0
Steps to reproduce
Use this reproduction example, run the main method.
Expected behavior
Screenshot should be taken
Actual behavior
The code fails with an exception and the following stack trace:
Additional context
Bug analysis:
The Locator screenshot functionality forgets to remove the
mask
field from the generic Gson serialization of the options, and Gson finally fails because deep inside themask
field (which is aLocator
) is anException
field which cannot be serialized.The Page screenshot code has handled this by special-casing the
mask
field. This needs to be done also for the Locator code (actually located inElementHandleImpl
).Working screenshot code:
playwright-java/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java
Lines 1211 to 1222 in fddb146
Special handling for
mask
missing:playwright-java/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java
Line 332 in fddb146
Environment
Java 17
The text was updated successfully, but these errors were encountered: