We have recently migrated to selenium 4.3.0 and observed API for getting session Node IP and Port is totally changes and it has to capture through graphql now. Accordingly we have did the changes but still getting an error while running it through Java code.
Updated command in java:
String[] command = {"curl", "-X", "POST", "-H", "Content-Type: application/json", "--data", "{query: { session (id: \"" sessionId "\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } }", "-s", "http://localhost:4444/graphql"};
ProcessBuilder process = new ProcessBuilder(command);
Process p;
try
{
p = process.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ( (line = reader.readLine()) != null) {
builder.append(line);
builder.append(System.getProperty("line.separator"));
}
String result = builder.toString();
System.out.print(result);
}
Console O/P Error:
{
"value": {
"error": "unknown error",
"message": "Unable to parse: {query: { session (id: d5382daee94860671ae972fcba359e03) { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } }",
"stacktrace": "org.openqa.selenium.json.JsonException: Unable to parse: {query: { session (id: d5382daee94860671ae972fcba359e03) { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } }\r\n\tat org.openqa.selenium.json.Json.toType(Json.java:57)\r\n\tat org.openqa.selenium.json.Json.toType(Json.java:50)\r\n\tat org.openqa.selenium.grid.graphql.GraphqlHandler.execute(GraphqlHandler.java:114)\r\n\tat org.openqa.selenium.remote.http.Route$TemplatizedRoute.handle(Route.java:192)\r\n\tat org.openqa.selenium.remote.http.Route.execute(Route.java:68)\r\n\tat org.openqa.selenium.remote.http.Route$CombinedRoute.handle(Route.java:336)\r\n\tat org.openqa.selenium.remote.http.Route.execute(Route.java:68)\r\n\tat org.openqa.selenium.remote.http.Route$CombinedRoute.handle(Route.java:336)\r\n\tat org.openqa.selenium.remote.http.Route.execute(Route.java:68)\r\n\tat org.openqa.selenium.remote.AddWebDriverSpecHeaders.lambda$apply$0(AddWebDriverSpecHeaders.java:35)\r\n\tat org.openqa.selenium.remote.ErrorFilter.lambda$apply$0(ErrorFilter.java:44)\r\n\tat org.openqa.selenium.remote.http.Filter$1.execute(Filter.java:64)\r\n\tat org.openqa.selenium.remote.ErrorFilter.lambda$apply$0(ErrorFilter.java:44)\r\n\tat org.openqa.selenium.remote.http.Filter$1.execute(Filter.java:64)\r\n\tat org.openqa.selenium.netty.server.SeleniumHandler.lambda$channelRead0$0(SeleniumHandler.java:44)\r\n\tat java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)\r\n\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\r\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\r\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\r\n\tat java.lang.Thread.run(Thread.java:748)\r\nCaused by: org.openqa.selenium.json.JsonException: Unable to determine type from: q. Last 2 characters read: {q\nBuild info: version: '4.3.0', revision: 'a4995e2c09*'\nSystem info: host: '13.12.13.14', ip: '127.0.0.1', os.name: 'Windows Server 2019', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_271'\nDriver info: driver.version: unknown\r\n\tat org.openqa.selenium.json.JsonInput.peek(JsonInput.java:126)\r\n\tat org.openqa.selenium.json.JsonInput.hasNext(JsonInput.java:207)\r\n\tat org.openqa.selenium.json.JsonInputIterator.hasNext(JsonInputIterator.java:41)\r\n\tat java.util.Iterator.forEachRemaining(Iterator.java:115)\r\n\tat java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)\r\n\tat java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)\r\n\tat java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)\r\n\tat java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)\r\n\tat java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)\r\n\tat java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)\r\n\tat org.openqa.selenium.json.MapCoercer.lambda$apply$1(MapCoercer.java:72)\r\n\tat org.openqa.selenium.json.JsonTypeCoercer.lambda$buildCoercer$6(JsonTypeCoercer.java:145)\r\n\tat org.openqa.selenium.json.JsonTypeCoercer.coerce(JsonTypeCoercer.java:127)\r\n\tat org.openqa.selenium.json.Json.toType(Json.java:71)\r\n\tat org.openqa.selenium.json.Json.toType(Json.java:55)\r\n\t... 19 more\r\n"
}
Showing error somewhere here in --data ".json.JsonException: Unable to determine type from: q. Last 2 characters read: {q\n
"
We tried with different combination of curl command but still facing the same issues. Please help us to get this resolve.
CodePudding user response:
I think the issue is caused because Selenium is unable to process your request as a valid JSON information, probably as you guessed because you missed the double quotes.
My advice would be that first try issuing the curl
command from a terminal and see if it works.
The Selenium documentation provides exactly one example you can take for reference:
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
Please, note how they defined query
and the GraphQL query itself as a valid JSON object, and how they escaped the session identifier.
In your Java code, it would mean changing your command to something like this:
String[] command = {
"curl",
"-X", "POST",
"-H", "Content-Type: application/json",
"--data", "{ \"query\": \"{ session (id: \\\"" sessionId "\\\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } \"}",
"-s", "http://localhost:4444/graphql"
};
Note the treatment of the session identifier again.
Please, consider reading this related Github issue, I think it could be of help as well.
Additionally, although the Selenium documentation itself recommends using curl
, from Java you can try a different approach and try obtaining the information in other ways. Consider for example the following, based on the excellent article of Mykong:
URL url = new URL("http://localhost:4444/graphql");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
String sessionId = "123456";
String query = "{ \"query\": \"{ session (id: \\\"" sessionId "\\\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } \"}";
OutputStream os = conn.getOutputStream();
os.write(query.getBytes());
os.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append(System.getProperty("line.separator"));
}
String result = sb.toString();
System.out.println("Response from Selenium .... \n" result);
conn.disconnect();