Skip to content

Instantly share code, notes, and snippets.

@krmahadevan
Created February 8, 2012 08:25
Show Gist options
  • Save krmahadevan/1766772 to your computer and use it in GitHub Desktop.
Save krmahadevan/1766772 to your computer and use it in GitHub Desktop.
A utility class that extracts the actual IP and port to which your remote executions are being routed to by Grid2
public class GridInfoExtracter{
private static String[] getHostNameAndPort(String hostName, int port,
SessionId session) {
String[] hostAndPort = new String[2];
String errorMsg = "Failed to acquire remote webdriver node and port info. Root cause: ";
try {
HttpHost host = new HttpHost(hostName, port);
DefaultHttpClient client = new DefaultHttpClient();
URL sessionURL = new URL("http://" + hostName + ":" + port + "/grid/api/testsession?session=" + session);
BasicHttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", sessionURL.toExternalForm());
HttpResponse response = client.execute(host, r);
JSONObject object = extractObject(response);
URL myURL = new URL(object.getString("proxyId"));
if ((myURL.getHost() != null) && (myURL.getPort() != -1)) {
hostAndPort[0] = myURL.getHost();
hostAndPort[1] = Integer.toString(myURL.getPort());
}
} catch (Exception e) {
logger.log(Level.SEVERE, errorMsg, e);
throw new RuntimeException(errorMsg, e);
}
return hostAndPort;
}
private static JSONObject extractObject(HttpResponse resp) throws IOException, JSONException {
BufferedReader rd = new BufferedReader(new InputStreamReader(resp.getEntity().getContent()));
StringBuffer s = new StringBuffer();
String line;
while ((line = rd.readLine()) != null) {
s.append(line);
}
rd.close();
JSONObject objToReturn = new JSONObject(s.toString());
return objToReturn;
}
}
@krmahadevan
Copy link
Author

A typical call to this would be

GridInfoExtracter.getHostNameAndPort("localhost",4444,myRemoteWebDriver.getSessionId());

@daluu
Copy link

daluu commented Feb 8, 2012

For those who don't use Java with Grid2, I still see value in this code. And rather than port it to another language, except where it is easy for one to port, one could just compile and execute the Java code to get the host and port via a command line / shell call from another language and then make use of that. That would mean of course the need to add to this class a main method that exposes a CLI interface.

Just for kicks a another more complicated method would be to load this class (or its methods) into an XML-RPC server, etc. making it possible to call the method over XML-RPC from any language.

Though of course, it would be nice if this code was ported to other WebDriver languages for native support (.NET/C#, Python, Ruby).

@genevish
Copy link

In c# I used this to get the hostname:

string url = "http://localhost:4444/grid/api/testsession?session=" + this.SessionId;
WebClient client = new WebClient();
Stream stream = client.OpenRead(url);
StreamReader reader = new StreamReader(stream);
Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
string host = new Uri(jObject.GetValue("proxyId").ToString()).Host;
stream.Close();

Console.WriteLine(host);

Note: You have to subclass RemoteWebDriver to get access to the SessionID.

@daluu
Copy link

daluu commented Jan 21, 2015

And here's a snippet for Python 2.x, for getting hostname

import json
import urllib2 
from selenium import webdriver
from urlparse import urlparse
driver = webdriver.Remote( command_executor='http://localhost:4444/wd/hub',desired_capabilities={'browserName':'firefox'})
grid_node_extract_url = "http://localhost:4444/grid/api/testsession?session=%s" % driver.session_id
response = urllib2.urlopen(grid_node_extract_url).read()
node_host = urlparse(json.loads(response).get('proxyId')).hostname # use .port for port
print node_host
driver.quit()

For Python 3.x, making the following substitutions should work

import urllib.request
from urllib.parse import urlparse
from __future__ import print_function
response = urllib.request.urlopen(grid_node_extract_url).read()
print(node_host)

@daluu
Copy link

daluu commented Jan 18, 2016

Here's the Ruby version (for v1.9+, for older versions, may have to resort to require 'net/http' and use that or something else instead of this REST client to make the HTTP request to get proxy URL with hostname)

#gem install rest-client & selenium as needed
require "selenium-webdriver"
require 'rest-client'
require 'json'
require 'uri'

caps = Selenium::WebDriver::Remote::Capabilities.firefox
driver = Selenium::WebDriver.for(:remote, :url => "http://localhost:4444/wd/hub", :desired_capabilities => caps)
grid_node_extract_url = "http://localhost:4444/grid/api/testsession?session=#{driver.session_id}"
response = RestClient.get grid_node_extract_url 
response = JSON.parse(response)
node_host = URI(response['proxyId']).host # use .port for port
puts node_host
driver.quit

@mdsapon
Copy link

mdsapon commented Mar 19, 2022

getting lot of compilation error, can you please add the imported package as well, if possible? or are those still valid as this post is 10 years old?

@krmahadevan
Copy link
Author

@mdsapon - You should perhaps take a look at this library that I built as a follow up to this gist : https://github.com/RationaleEmotions/talk2grid

@mdsapon
Copy link

mdsapon commented Mar 20, 2022

@mdsapon - You should perhaps take a look at this library that I built as a follow up to this gist : https://github.com/RationaleEmotions/talk2grid

Thanks a lot, this is amazing and works great with Selenium 3, but didn't work with Selenium 4. Do you have any plan to upgrade? Btw thanks a ton for creating this library

@krmahadevan
Copy link
Author

@mdsapon - I haven't yet delved into Grid4 completely. But its definitely on the cards. I didnt take this library so seriously because I didn't see many people even have a want to use it :D

I will work on sorting it out hopefully soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment