diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java index a9e293896..53e7fe729 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java @@ -36,9 +36,6 @@ import static com.microsoft.playwright.impl.Serialization.*; import static com.microsoft.playwright.impl.Utils.*; import static com.microsoft.playwright.impl.Utils.addFilePathUploadParams; -import static com.microsoft.playwright.options.ScreenshotType.JPEG; -import static com.microsoft.playwright.options.ScreenshotType.PNG; -import static com.microsoft.playwright.options.ScreenshotType.WEBP; public class ElementHandleImpl extends JSHandleImpl implements ElementHandle { private final FrameImpl frame; @@ -270,20 +267,8 @@ public byte[] screenshot(ScreenshotOptions options) { if (options == null) { options = new ScreenshotOptions(); } - if (options.type == null) { - options.type = PNG; - if (options.path != null) { - String fileName = options.path.getFileName().toString(); - int extStart = fileName.lastIndexOf('.'); - if (extStart != -1) { - String extension = fileName.substring(extStart).toLowerCase(); - if (".jpeg".equals(extension) || ".jpg".equals(extension)) { - options.type = JPEG; - } else if (".webp".equals(extension)) { - options.type = WEBP; - } - } - } + if (options.type == null && options.path != null) { + options.type = Utils.screenshotTypeForPath(options.path); } JsonObject params = gson().toJsonTree(options).getAsJsonObject(); params.remove("path"); diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java index 218fa80f1..2cec9cd3d 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java @@ -33,9 +33,6 @@ import static com.microsoft.playwright.impl.Serialization.gson; import static com.microsoft.playwright.impl.Serialization.parseError; import static com.microsoft.playwright.impl.Utils.*; -import static com.microsoft.playwright.options.ScreenshotType.JPEG; -import static com.microsoft.playwright.options.ScreenshotType.PNG; -import static com.microsoft.playwright.options.ScreenshotType.WEBP; import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.file.Files.readAllBytes; import static java.util.Arrays.asList; @@ -1273,20 +1270,8 @@ private byte[] screenshotImpl(ScreenshotOptions options) { if (options == null) { options = new ScreenshotOptions(); } - if (options.type == null) { - options.type = PNG; - if (options.path != null) { - String fileName = options.path.getFileName().toString(); - int extStart = fileName.lastIndexOf('.'); - if (extStart != -1) { - String extension = fileName.substring(extStart).toLowerCase(); - if (".jpeg".equals(extension) || ".jpg".equals(extension)) { - options.type = JPEG; - } else if (".webp".equals(extension)) { - options.type = WEBP; - } - } - } + if (options.type == null && options.path != null) { + options.type = Utils.screenshotTypeForPath(options.path); } JsonObject params = gson().toJsonTree(options).getAsJsonObject(); params.remove("path"); diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Utils.java b/playwright/src/main/java/com/microsoft/playwright/impl/Utils.java index 2a3f8d652..9b41c2f4d 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/Utils.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/Utils.java @@ -23,6 +23,7 @@ import com.microsoft.playwright.options.ClientCertificate; import com.microsoft.playwright.options.FilePayload; import com.microsoft.playwright.options.HttpHeader; +import com.microsoft.playwright.options.ScreenshotType; import java.io.FileOutputStream; import java.io.IOException; @@ -30,6 +31,7 @@ import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; @@ -246,6 +248,21 @@ static void mkParentDirs(Path file) { } } + /** The screenshot type for a path when no type is given, from its extension, like the Node.js client. */ + static ScreenshotType screenshotTypeForPath(Path path) { + String fileName = path.getFileName().toString(); + int extStart = fileName.lastIndexOf('.'); + String extension = extStart == -1 ? "" : fileName.substring(extStart + 1).toLowerCase(); + switch (extension) { + case "png": return ScreenshotType.PNG; + case "jpg": + case "jpeg": return ScreenshotType.JPEG; + case "webp": return ScreenshotType.WEBP; + default: + throw new PlaywrightException("path: unsupported mime type \"" + URLConnection.guessContentTypeFromName(fileName) + "\""); + } + } + static void writeToFile(byte[] buffer, Path path) { mkParentDirs(path); try (FileOutputStream out = new FileOutputStream(path.toFile())) { diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java b/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java index 8f07b5e73..eba11cddc 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java @@ -352,4 +352,29 @@ private byte[] expectedScreenshot(BrowserType browserType, String name) throws I Path path = Paths.get("src/test/resources/expectations"); return Files.readAllBytes(path.resolve(name + "-" + browserType.name() + ".png")); } + + @PlaywrightTest + void pathOptionShouldDetectJpeg(Page page, @TempDir Path tmpDir) throws IOException { + Path outputPath = tmpDir.resolve("screenshot.jpg"); + byte[] buffer = page.screenshot(new Page.ScreenshotOptions().setPath(outputPath)); + assertEquals(asList(0xFF, 0xD8, 0xFF), asList(buffer[0] & 0xFF, buffer[1] & 0xFF, buffer[2] & 0xFF)); + assertArrayEquals(buffer, Files.readAllBytes(outputPath)); + } + + @PlaywrightTest + void shouldPreferTypeOverPathExtension(Page page, @TempDir Path tmpDir) { + Path outputPath = tmpDir.resolve("screenshot.png"); + byte[] buffer = page.screenshot(new Page.ScreenshotOptions().setPath(outputPath).setType(ScreenshotType.JPEG)); + assertEquals(asList(0xFF, 0xD8, 0xFF), asList(buffer[0] & 0xFF, buffer[1] & 0xFF, buffer[2] & 0xFF)); + } + + @PlaywrightTest + void pathOptionShouldThrowForUnsupportedExtension(Page page, @TempDir Path tmpDir) { + PlaywrightException e = assertThrows(PlaywrightException.class, + () -> page.screenshot(new Page.ScreenshotOptions().setPath(tmpDir.resolve("screenshot.txt")))); + assertTrue(e.getMessage().contains("path: unsupported mime type \"text/plain\""), e.getMessage()); + e = assertThrows(PlaywrightException.class, + () -> page.locator("body").screenshot(new Locator.ScreenshotOptions().setPath(tmpDir.resolve("screenshot.txt")))); + assertTrue(e.getMessage().contains("path: unsupported mime type \"text/plain\""), e.getMessage()); + } }