From 9f185e680c00b018ddeddb42cc952bb287204284 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Wed, 15 May 2024 22:14:22 +0200 Subject: [PATCH 1/5] fix: Deprecate AppiumProtocolHandshake class --- .../remote/AppiumCommandExecutor.java | 2 +- .../remote/AppiumProtocolHandshake.java | 105 +----------------- 2 files changed, 5 insertions(+), 102 deletions(-) diff --git a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java index d3310f478..418888b71 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java +++ b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java @@ -173,7 +173,7 @@ private Response createSession(Command command) throws IOException { throw new SessionNotCreatedException("Session already exists"); } - ProtocolHandshake.Result result = new AppiumProtocolHandshake().createSession(getClient(), command); + var result = new AppiumProtocolHandshake().createSession(getClient(), command); Dialect dialect = result.getDialect(); if (!(dialect.getCommandCodec() instanceof W3CHttpCommandCodec)) { throw new SessionNotCreatedException("Only W3C sessions are supported. " diff --git a/src/main/java/io/appium/java_client/remote/AppiumProtocolHandshake.java b/src/main/java/io/appium/java_client/remote/AppiumProtocolHandshake.java index f92a3632d..011acc40a 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumProtocolHandshake.java +++ b/src/main/java/io/appium/java_client/remote/AppiumProtocolHandshake.java @@ -16,108 +16,11 @@ package io.appium.java_client.remote; -import org.openqa.selenium.Capabilities; -import org.openqa.selenium.ImmutableCapabilities; -import org.openqa.selenium.SessionNotCreatedException; -import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.internal.Either; -import org.openqa.selenium.json.Json; -import org.openqa.selenium.json.JsonOutput; -import org.openqa.selenium.remote.Command; -import org.openqa.selenium.remote.NewSessionPayload; import org.openqa.selenium.remote.ProtocolHandshake; -import org.openqa.selenium.remote.http.Contents; -import org.openqa.selenium.remote.http.HttpHandler; -import java.io.IOException; -import java.io.StringWriter; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Map; -import java.util.Set; -import java.util.stream.Stream; - -@SuppressWarnings("UnstableApiUsage") +/** + * @deprecated Use ProtocolHandshake instead. + */ +@Deprecated public class AppiumProtocolHandshake extends ProtocolHandshake { - private static void writeJsonPayload(NewSessionPayload srcPayload, Appendable destination) { - try (JsonOutput json = new Json().newOutput(destination)) { - json.beginObject(); - - json.name("capabilities"); - json.beginObject(); - - json.name("firstMatch"); - json.beginArray(); - json.beginObject(); - json.endObject(); - json.endArray(); - - json.name("alwaysMatch"); - try { - Method getW3CMethod = NewSessionPayload.class.getDeclaredMethod("getW3C"); - getW3CMethod.setAccessible(true); - //noinspection unchecked,resource - ((Stream>) getW3CMethod.invoke(srcPayload)) - .findFirst() - .map(json::write) - .orElseGet(() -> { - json.beginObject(); - json.endObject(); - return null; - }); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new WebDriverException(e); - } - - json.endObject(); // Close "capabilities" object - - try { - Method writeMetaDataMethod = NewSessionPayload.class.getDeclaredMethod( - "writeMetaData", JsonOutput.class); - writeMetaDataMethod.setAccessible(true); - writeMetaDataMethod.invoke(srcPayload, json); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new WebDriverException(e); - } - - json.endObject(); - } - } - - @Override - public Result createSession(HttpHandler client, Command command) throws IOException { - //noinspection unchecked - Capabilities desired = ((Set>) command.getParameters().get("capabilities")) - .stream() - .findAny() - .map(ImmutableCapabilities::new) - .orElseGet(ImmutableCapabilities::new); - try (NewSessionPayload payload = NewSessionPayload.create(desired)) { - Either result = createSession(client, payload); - if (result.isRight()) { - return result.right(); - } - throw result.left(); - } - } - - @Override - public Either createSession(HttpHandler client, NewSessionPayload payload) { - - StringWriter stringWriter = new StringWriter(); - writeJsonPayload(payload, stringWriter); - - try { - Method createSessionMethod = ProtocolHandshake.class.getDeclaredMethod( - "createSession", HttpHandler.class, Contents.Supplier.class - ); - createSessionMethod.setAccessible(true); - //noinspection unchecked - return (Either) createSessionMethod.invoke( - this, client, Contents.utf8String(stringWriter.toString()) - ); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new WebDriverException(e); - } - } } From 11cd0251e3bf940e24fcade275a747da838d78a4 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Wed, 15 May 2024 22:16:22 +0200 Subject: [PATCH 2/5] extra import --- .../java/io/appium/java_client/remote/AppiumCommandExecutor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java index 418888b71..4e8ad8761 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java +++ b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java @@ -28,7 +28,6 @@ import org.openqa.selenium.remote.Dialect; import org.openqa.selenium.remote.DriverCommand; import org.openqa.selenium.remote.HttpCommandExecutor; -import org.openqa.selenium.remote.ProtocolHandshake; import org.openqa.selenium.remote.Response; import org.openqa.selenium.remote.ResponseCodec; import org.openqa.selenium.remote.codec.w3c.W3CHttpCommandCodec; From 96d5375ba554657c7803194cad02e8795f1021fa Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Wed, 15 May 2024 22:24:13 +0200 Subject: [PATCH 3/5] lint --- .../io/appium/java_client/remote/AppiumProtocolHandshake.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/io/appium/java_client/remote/AppiumProtocolHandshake.java b/src/main/java/io/appium/java_client/remote/AppiumProtocolHandshake.java index 011acc40a..ef2f659da 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumProtocolHandshake.java +++ b/src/main/java/io/appium/java_client/remote/AppiumProtocolHandshake.java @@ -19,6 +19,8 @@ import org.openqa.selenium.remote.ProtocolHandshake; /** + * This class is deprecated and should be removed. + * * @deprecated Use ProtocolHandshake instead. */ @Deprecated From 78f06d8e80834a63fd92a48b51ac7dddb0f6ab02 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 16 May 2024 07:57:21 +0200 Subject: [PATCH 4/5] fix --- .../io/appium/java_client/AppiumDriver.java | 41 ++++++++++--------- .../AppiumNewSessionCommandPayload.java | 6 +++ 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index 6d66639c9..c8d660e9f 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -20,7 +20,6 @@ import io.appium.java_client.internal.ReflectionHelpers; import io.appium.java_client.internal.SessionHelpers; import io.appium.java_client.remote.AppiumCommandExecutor; -import io.appium.java_client.remote.AppiumNewSessionCommandPayload; import io.appium.java_client.remote.AppiumW3CHttpCommandCodec; import io.appium.java_client.remote.options.BaseOptions; import io.appium.java_client.service.local.AppiumDriverLocalService; @@ -50,11 +49,13 @@ import java.util.Collections; import java.util.HashSet; import java.util.Map; +import java.util.Optional; import java.util.Set; import static com.google.common.base.Strings.isNullOrEmpty; import static io.appium.java_client.internal.CapabilityHelpers.APPIUM_PREFIX; import static io.appium.java_client.remote.options.SupportsAutomationNameOption.AUTOMATION_NAME_OPTION; +import static java.util.Collections.singleton; import static org.openqa.selenium.remote.CapabilityType.PLATFORM_NAME; /** @@ -265,25 +266,27 @@ public void addCommand(HttpMethod httpMethod, String url, String methodName) { @Override protected void startSession(Capabilities capabilities) { - Response response = execute(new AppiumNewSessionCommandPayload(capabilities)); - if (response == null) { - throw new SessionNotCreatedException( - "The underlying command executor returned a null response."); - } - - Object responseValue = response.getValue(); - if (responseValue == null) { - throw new SessionNotCreatedException( - "The underlying command executor returned a response without payload: " - + response); - } - if (!(responseValue instanceof Map)) { - throw new SessionNotCreatedException( - "The underlying command executor returned a response with a non well formed payload: " - + response); - } + var response = Optional.ofNullable( + execute(DriverCommand.NEW_SESSION(singleton(capabilities))) + ).orElseThrow(() -> new SessionNotCreatedException( + "The underlying command executor returned a null response." + )); + + var rawCapabilities = Optional.ofNullable(response.getValue()) + .map(value -> { + if (!(value instanceof Map)) { + throw new SessionNotCreatedException(String.format( + "The underlying command executor returned a response " + + "with a non well formed payload: %s", response) + ); + } + //noinspection unchecked + return (Map) value; + }) + .orElseThrow(() -> new SessionNotCreatedException( + "The underlying command executor returned a response without payload: " + response) + ); - @SuppressWarnings("unchecked") Map rawCapabilities = (Map) responseValue; // TODO: remove this workaround for Selenium API enforcing some legacy capability values in major version rawCapabilities.remove("platform"); if (rawCapabilities.containsKey(CapabilityType.BROWSER_NAME) diff --git a/src/main/java/io/appium/java_client/remote/AppiumNewSessionCommandPayload.java b/src/main/java/io/appium/java_client/remote/AppiumNewSessionCommandPayload.java index 63fc663a5..31635dabb 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumNewSessionCommandPayload.java +++ b/src/main/java/io/appium/java_client/remote/AppiumNewSessionCommandPayload.java @@ -27,6 +27,12 @@ import static org.openqa.selenium.remote.DriverCommand.NEW_SESSION; +/** + * This class is deprecated and will be removed. + * + * @deprecated Use CommandPayload instead. + */ +@Deprecated public class AppiumNewSessionCommandPayload extends CommandPayload { /** * Appends "appium:" prefix to all non-prefixed non-standard capabilities. From 477f74fcafb6796eca7f83629a9824a0539e18b7 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 16 May 2024 08:43:55 +0200 Subject: [PATCH 5/5] use non-deprecated class --- .../io/appium/java_client/remote/AppiumCommandExecutor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java index 4e8ad8761..118f0ff81 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java +++ b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java @@ -28,6 +28,7 @@ import org.openqa.selenium.remote.Dialect; import org.openqa.selenium.remote.DriverCommand; import org.openqa.selenium.remote.HttpCommandExecutor; +import org.openqa.selenium.remote.ProtocolHandshake; import org.openqa.selenium.remote.Response; import org.openqa.selenium.remote.ResponseCodec; import org.openqa.selenium.remote.codec.w3c.W3CHttpCommandCodec; @@ -172,7 +173,7 @@ private Response createSession(Command command) throws IOException { throw new SessionNotCreatedException("Session already exists"); } - var result = new AppiumProtocolHandshake().createSession(getClient(), command); + var result = new ProtocolHandshake().createSession(getClient(), command); Dialect dialect = result.getDialect(); if (!(dialect.getCommandCodec() instanceof W3CHttpCommandCodec)) { throw new SessionNotCreatedException("Only W3C sessions are supported. "