Search code examples
seleniumselenium-webdriverselenium-gridselenium-grid2

Downloading a excel file on selenium grid and reading it


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


Solution

  • 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.