2

Here is my scenario:

we run our selenium test suite on selenium grid which was setup in docker containers(linux box) from jenkins.

In one of my test when i click on export option, it downloads an excel file on selenium grid.

Issue:

I am unable to find the location of the downloaded file(everytime test may run in different nodes in selenium grid).

what i am expecting:

Can someone help me, how to find the location of the file and i think i cannot open an excel file in linux box so if i can move that file to one of SFTP location then i can connect to SFTP and can read the content in it for validation.

Thanks

nurav
  • 229
  • 4
  • 19

2 Answers2

2

Assumptions :

  • Since you mentioned you are using Docker and since there is currently no Docker images for either Windows (or) OSX, your browser is either Chrome or Firefox
  • You are using a technique such as this to configure the default download location for your Chrome or Firefox browser.

You would first need to figure out to which node did your Grid route your test execution to. For doing that, you would employ a technique such as below to retrieve this information (I originally posted this as a gist here, then wrote up a blog about this here and finally built a library called talk2Grid which provides this capability out of the box without you having to write any extra amount of code)

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;
 }
}

Now you would have the IP and port information of the Docker node on which your test is running.

You now have two options:

  1. You download the file from the docker container using scp (or)
  2. You build a custom servlet and then inject it into the node as explained here. Then you make a http connection to this node by hitting your servlet and then download the file to your local machine. The node's IP and port are anyway available to you from your session.

That should help you with this.

All said and done you might also want to read this blog that Mark Collins created which talks about why you should not be trying to download files and if at all there's a need, what is the right way of doing it.

Krishnan Mahadevan
  • 13,480
  • 5
  • 33
  • 61
  • Thanks much for the info. I did use the code and figured out where my test where was routing to "Session a8880149-f0f4-4a33-ab5e-8296564ea087 was routed to **GridNode [IP='172.17.0.7', Port=5555]**". But i couldn't figure where exactly the file is getting download on the grid or on which docker container. Any idea where would be the default download location for a remote webdriver – nurav Jun 29 '17 at 20:16
  • There's no default location for the file download that webdriver decides. Its always the browser that defaults to some location. In my answer I have provided links to articles that show you how to control the location as well. So you could employ that to force the browser to download to your choice of location and then get it from there. If my answer has helped, I would request you to please help accept it. – Krishnan Mahadevan Jul 03 '17 at 02:25
0

Thought of sharing the approach to check that the file is downloaded into specific location in selenium grid node (download location need to be specified in chrome options or firefox profile) and checking file is present in specified download directory:

(Written code in python)

Passing download directory and downloaed file name, for example, I have set C:\File_Download as my download directory and capturing downloaded filename from application and checking same file downloaded:

Note: Used robot framework builtin library to get session id, SSH to connect to remote machines and created selenium grid nodes in remote machines.

 import requests, json
 from robot.libraries.BuiltIn import BuiltIn
 import paramiko

 def check_downloaded_file_present_in_remote_machine(dir_location, filename):
    session_id = BuiltIn().get_library_instance('SeleniumLibrary')._current_browser().session_id
    response = requests.get("http://{SeleniumHubIP}:{port}/grid/api/testsession?",params= 
   {'session':session_id})
   json_resp = response.json()
    ip_addr = json_resp['proxyId'].split('://')[1].split(':')[0]
    print ip_addr
    client = paramiko.SSHClient()
    client.load_host_keys('{home\user_directory}\.ssh\known_hosts')
    client.connect(hostname=ip_addr,port=22,username='XXXXX',password='XXXX',look_for_keys=True)
    stdin, stdout, stderr = client.exec_command('cd ' +dir_location+' && ls')
    Is_file_exist = False
    for line in stdout:
        print(line.strip('\n'))
        if filename in line.strip('\n'):
            Is_file_exist = True
    client.exec_command('cd '+dir_location+' && rm -rf *')
    client.close()
    return Is_file_exist
Sathish
  • 33
  • 1
  • 2