From bbbf6a24416e0bac8cd499e3217fd8c0455724b4 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sat, 29 Oct 2022 01:31:48 +0200 Subject: [PATCH 1/4] fix: Override getScreenshotAs to support the legacy base64 encoding --- .../io/appium/java_client/AppiumDriver.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index d814657c6..d25f86b7c 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -31,6 +31,7 @@ import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.MutableCapabilities; +import org.openqa.selenium.OutputType; import org.openqa.selenium.SessionNotCreatedException; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.remote.CapabilityType; @@ -44,9 +45,15 @@ import org.openqa.selenium.remote.http.HttpClient; import org.openqa.selenium.remote.http.HttpMethod; +import java.io.File; +import java.io.IOException; import java.lang.reflect.Field; import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Arrays; +import java.util.Base64; import java.util.Collections; import java.util.Map; @@ -270,4 +277,48 @@ public Response execute(String driverCommand, Map parameters) { public Response execute(String command) { return super.execute(command, Collections.emptyMap()); } + + private static File saveToFile(byte[] data) { + try { + Path tmpFilePath = Files.createTempFile("screenshot", ".png"); + File tmpFile = tmpFilePath.toFile(); + tmpFile.deleteOnExit(); + Files.write(tmpFilePath, data); + return tmpFile; + } catch (IOException e) { + throw new WebDriverException(e); + } + } + + @Override + public X getScreenshotAs(OutputType outputType) { + Response response = execute(DriverCommand.SCREENSHOT); + Object result = response.getValue(); + final byte[] screenshotBase64Bytes; + if (result instanceof String) { + screenshotBase64Bytes = ((String) result).getBytes(StandardCharsets.UTF_8); + } else if (result instanceof byte[]) { + screenshotBase64Bytes = (byte[]) result; + } else { + throw new RuntimeException( + String.format("Unexpected result for %s command: %s", DriverCommand.SCREENSHOT, + result == null ? "null" : (result.getClass().getName() + " instance")) + ); + } + // TODO: Eventually we should not override this method. + // TODO: Although, we have a legacy burden, + // TODO: so it's impossible to do it the other way as of Oct 29 2022. + // TODO: See https://github.com/SeleniumHQ/selenium/issues/11168 + byte[] screenshotRawBytes = Base64.getMimeDecoder().decode(screenshotBase64Bytes); + if (outputType == OutputType.BYTES) { + return (X) screenshotRawBytes; + } else if (outputType == OutputType.BASE64) { + //noinspection unchecked + return (X) new String(Base64.getEncoder().encode(screenshotRawBytes), StandardCharsets.UTF_8); + } else if (outputType == OutputType.FILE) { + //noinspection unchecked + return (X) saveToFile(screenshotRawBytes); + } + throw new IllegalArgumentException(String.format("Unsupported %s instance", OutputType.class.getName())); + } } From 0ea1518160c5eefa864f6ae1d65513bc2ae84906 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sat, 29 Oct 2022 09:46:13 +0200 Subject: [PATCH 2/4] Use encodeToString --- src/main/java/io/appium/java_client/AppiumDriver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index d25f86b7c..fd6e5b24e 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -314,7 +314,7 @@ public X getScreenshotAs(OutputType outputType) { return (X) screenshotRawBytes; } else if (outputType == OutputType.BASE64) { //noinspection unchecked - return (X) new String(Base64.getEncoder().encode(screenshotRawBytes), StandardCharsets.UTF_8); + return (X) Base64.getEncoder().encodeToString(screenshotRawBytes); } else if (outputType == OutputType.FILE) { //noinspection unchecked return (X) saveToFile(screenshotRawBytes); From f922632e4258f7ffab66a0abdc2fd5491c53f818 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sat, 29 Oct 2022 18:18:17 +0200 Subject: [PATCH 3/4] Add hack --- .../io/appium/java_client/AppiumDriver.java | 54 +++++-------------- 1 file changed, 12 insertions(+), 42 deletions(-) diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index fd6e5b24e..6e3c61141 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -45,15 +45,9 @@ import org.openqa.selenium.remote.http.HttpClient; import org.openqa.selenium.remote.http.HttpMethod; -import java.io.File; -import java.io.IOException; import java.lang.reflect.Field; import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; -import java.util.Base64; import java.util.Collections; import java.util.Map; @@ -278,47 +272,23 @@ public Response execute(String command) { return super.execute(command, Collections.emptyMap()); } - private static File saveToFile(byte[] data) { - try { - Path tmpFilePath = Files.createTempFile("screenshot", ".png"); - File tmpFile = tmpFilePath.toFile(); - tmpFile.deleteOnExit(); - Files.write(tmpFilePath, data); - return tmpFile; - } catch (IOException e) { - throw new WebDriverException(e); - } - } - @Override public X getScreenshotAs(OutputType outputType) { - Response response = execute(DriverCommand.SCREENSHOT); - Object result = response.getValue(); - final byte[] screenshotBase64Bytes; - if (result instanceof String) { - screenshotBase64Bytes = ((String) result).getBytes(StandardCharsets.UTF_8); - } else if (result instanceof byte[]) { - screenshotBase64Bytes = (byte[]) result; - } else { - throw new RuntimeException( - String.format("Unexpected result for %s command: %s", DriverCommand.SCREENSHOT, - result == null ? "null" : (result.getClass().getName() + " instance")) - ); - } // TODO: Eventually we should not override this method. // TODO: Although, we have a legacy burden, // TODO: so it's impossible to do it the other way as of Oct 29 2022. // TODO: See https://github.com/SeleniumHQ/selenium/issues/11168 - byte[] screenshotRawBytes = Base64.getMimeDecoder().decode(screenshotBase64Bytes); - if (outputType == OutputType.BYTES) { - return (X) screenshotRawBytes; - } else if (outputType == OutputType.BASE64) { - //noinspection unchecked - return (X) Base64.getEncoder().encodeToString(screenshotRawBytes); - } else if (outputType == OutputType.FILE) { - //noinspection unchecked - return (X) saveToFile(screenshotRawBytes); - } - throw new IllegalArgumentException(String.format("Unsupported %s instance", OutputType.class.getName())); + return super.getScreenshotAs(new OutputType() { + @Override + public X convertFromBase64Png(String base64Png) { + String rfc4648Base64 = base64Png.replaceAll("\r?\n", ""); + return outputType.convertFromBase64Png(rfc4648Base64); + } + + @Override + public X convertFromPngBytes(byte[] png) { + return outputType.convertFromPngBytes(png); + } + }); } } From 681127889862074a046baca741157fc8307d88bf Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sat, 29 Oct 2022 18:23:42 +0200 Subject: [PATCH 4/4] Tune regexp --- src/main/java/io/appium/java_client/AppiumDriver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index 6e3c61141..450822a69 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -281,7 +281,7 @@ public X getScreenshotAs(OutputType outputType) { return super.getScreenshotAs(new OutputType() { @Override public X convertFromBase64Png(String base64Png) { - String rfc4648Base64 = base64Png.replaceAll("\r?\n", ""); + String rfc4648Base64 = base64Png.replaceAll("\\r?\\n", ""); return outputType.convertFromBase64Png(rfc4648Base64); }