1

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.

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
SacTan
  • 379
  • 2
  • 5
  • 18
  • it seems issue with '"'(double quotes) and '\"' in curl command but not able to get the solution. – SacTan Jul 25 '22 at 15:48
  • try this `"curl", "-X", "POST", "-H", "Content-Type: application/json", "--data", "{\"query\": \"{ session (id: \"\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } \"}", "-s", "http://localhost:4444/graphql"` – Rishal Jul 27 '22 at 19:03
  • @Rishal Thanks for response, I tried it but got the null pointer exception. – SacTan Jul 27 '22 at 20:24
  • Have you passed your session id accordingly, can you show us what you did and what exception you got after modifying the query – Rishal Jul 28 '22 at 07:52

1 Answers1

1

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();
jccampanero
  • 50,989
  • 3
  • 20
  • 49
  • @jccampanera, tried with given command but no luck. directly try to run from curl command but still same error, tried with different combination for session, \"\" , "session-id", '' , session-id every time got the same error. – SacTan Jul 28 '22 at 06:10
  • I think you need to pass the actual session id in place of ``, hope you are doing that. – Rishal Jul 28 '22 at 07:55
  • Thank you very much for the feedback SacTan, and for your comment, @Rishal. Yes, certainly is crucial to provide the actual session id value. I am sorry to hear that it didn't work. What error are you facing now? Please, try using `curl` to obtain some information from Selenium without using the session info: the [documentation](https://www.selenium.dev/documentation/grid/advanced_features/graphql_support/#querying-graphql) provides different examples of that. Try issuing them from the command line and see. In any case, I updated the answer with a different approach. Please, could you try? – jccampanero Jul 28 '22 at 11:14
  • @SacTan Were you able to test the proposed solution? – jccampanero Jul 30 '22 at 18:44
  • @jccampanero Thank you , its working with your sample example. – SacTan Aug 01 '22 at 12:34
  • You are welcome @SacTan. I am very happy to hear that the answer was helpful. – jccampanero Aug 01 '22 at 21:45