Skip to content

Commit

Permalink
fix: Deprecate AppiumProtocolHandshake class (#2173)
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-mokhnach committed May 16, 2024
1 parent 56dc411 commit b1f8bc9
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 121 deletions.
41 changes: 22 additions & 19 deletions src/main/java/io/appium/java_client/AppiumDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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<String, Object>) value;
})
.orElseThrow(() -> new SessionNotCreatedException(
"The underlying command executor returned a response without payload: " + response)
);

@SuppressWarnings("unchecked") Map<String, Object> rawCapabilities = (Map<String, Object>) 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ProtocolHandshake().createSession(getClient(), command);
Dialect dialect = result.getDialect();
if (!(dialect.getCommandCodec() instanceof W3CHttpCommandCodec)) {
throw new SessionNotCreatedException("Only W3C sessions are supported. "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,108 +16,13 @@

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")
/**
* This class is deprecated and should be removed.
*
* @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<Map<String, Object>>) 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<Map<String, Object>>) command.getParameters().get("capabilities"))
.stream()
.findAny()
.map(ImmutableCapabilities::new)
.orElseGet(ImmutableCapabilities::new);
try (NewSessionPayload payload = NewSessionPayload.create(desired)) {
Either<SessionNotCreatedException, Result> result = createSession(client, payload);
if (result.isRight()) {
return result.right();
}
throw result.left();
}
}

@Override
public Either<SessionNotCreatedException, Result> 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<SessionNotCreatedException, Result>) createSessionMethod.invoke(
this, client, Contents.utf8String(stringWriter.toString())
);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new WebDriverException(e);
}
}
}

0 comments on commit b1f8bc9

Please sign in to comment.