Execute scripts on remote node (selenium grid node) from the local

Hello All

Summery
what or how can I execute python or javascript files living in the selenium remote node (Selenium Grid) from the local by using only SeleniumLibrary

Here is some context

I was asked to work on a robotframework project that runs on GitHub/docker and connects to SauceLabs (as a selenium grid) and I need to find a way to persist data/files/folders from one test run to another.

Important points

  1. I cannot use other libraries that are not SeleniumLibrary or AppiumLibrary (it will be difficult to get the approval of any custom library).
  2. SauceLabs has a Storage service and easy-to-use API to upload and download files.
  3. SauceLabs has a pre-run function that allows the execution of a file to prepare the VM/Node before the test case starts.

My idea:

  1. I need to find a way to send files from my local to the selenium remote node :white_check_mark:
  2. I need to find a way to execute either a python script / shell script on the remote node, the script will zip a folder in the remote and later upload it to sauce labs storage. :question:

Questions you might have so far.

Why don’t you use choose file from SeleniumLibrary? Because Choose file is waiting for a locator and a file. I couldn’t find a way to use this keyword without the locator. So pre-run solution seems the way from local->remote I need to figure out the remote->local.
Use a daemon, Ummm I thought about it, but in order to start the test case ( or open the browser) the pre-run step must finish, so either I end with a daemon that stops before the test case start or an orphan one (which I have no idea how to deal with).

Now Where I’m stuck

How can I:

  • Execute a python file on the remote node file system? (I put the script there with the pre-run, and it is just a small script that will zip a directory and use saucelabs API to send it to saucestorage)
  • if the above is not possible, can I use the execute javascript keyword to target the filesystem in the selenium remote node?

PS. :slight_smile: no pressure, I will be fired if I cannot find the way to do this, no pressure … :cry: :cry:

An update.

I couldn’t find a way to execute python scripts by using execute javascript
I wanted to be able to extract files from a sauce labs VM, those files will be the product of the test case or for example, the user-data-dir from chrome or chromium edge.
I decided to do as follow:

  1. I create a form on the flask, and I used to upload directories
  2. The Flask server will get this directory, zip it and send it to storage.

Now few extra details:

  1. I use docker-compose
  2. one service will be the Flask server using gunicorn for the webserver
  3. the second service will be Ngrok to expose the server to the public
  4. On the Robot framework, I made a custom keyword that will query the NGrok API to get the public URL for the flask server
  5. In the test case I use chose file to upload the directory from the sauce VM.

Hi Victor,

Read this:

execute javascript as it’s name suggests is for javascript not python, more specifically it tells the browser to execute some javascript in the current page.

I should also not that browsers don’t know how to execute python, they only can execute javascript (or more accurately ECMAScript )

  • The BuiltIn Evaluate will execute simple 1 line python
  • The Run Process keyword could be used for executing a python script from the command line, though all you’ll get back is what you can read from stdout or a file written by the python script
  • A better option for your case might be to create your own test library of keywords in python ( Supported programming languages )
  • another option is rather than writing a python script just combine keywords to achieve what you want to do (assuming you don’t already have the python code), this option might be easier to understand/maintain by other testers in your team down the track

Hopefully this helps,

Dave.

Hello Dave,
Thank you for the recommendations and the explanation, I will keep it in mind.

Actually, I couldn’t find a way to solve this challenge using the built-in libraries or the external libraries alone.

My Goal was to extract a directory from the Node running the test case, these node was provided by sauce labs.

Since there is no way I can access the filesystem of the remote node, I decided to do the following:

  1. Create a flask server that will have a form that receives directories.
  2. Use choose file from seleniumLibrary to send the directory to the form.
  3. the Flask server will zip and send the directory to saucelabs storage.

Does it solve my challenge? Yes, kind of.
Can it be a breaking point for the test? yes, it can lead to false false results. but this can be solve.

Hi Victor,

I’m not familiar with flasks, but I’m wondering if the remote node can access a common location (e.g. a file or web server)?

  • OperatingSystem Library has tools for manipulating filesystem (create local directories etc)
  • Run Process will let you run commands like rsync (*nix) or robocopy (windows) or even unzip commands
  • requestslibrary will let you download files (like zip files)

Basically the tools are there to instruct the robot to do what ever you want it to.

Dave.

Hi @damies13

  • OperatingSystem In this case I’m trying to access the remote file system, with this library you will access the host that is running the Robotframework, in this case, is my docker, and the remote is a VM on saucelabs.

  • Run Process Interesting, however after trying one more time, It seems the VM does not support it, or there is something wrong in my script, but I suspect the keyword will try to run the process in the local host not in the remote node.

  • requestslibrary In this case I want to extract the files from a remote node, I don’t see how can I use this library to download it locally from a remote node. but I will take a look.

Regarding the tools there, I am not sure, because what I’m trying to do is to extract files from the remote node filesystem but most of the libraries will focus on either with interact with a form to upload a file ( default behavior of choose file keyword, or interact with the localhost or the machine running the robot framework, not the remote node executing the steps. But like always It doesn’t hurt give a second look to what you suggested :slight_smile:

Thanks

Hi Victor,

Ah I see, yes those are robot framework libraries so only run on the host that is running the Robotframework, and I just realised your trying to do the actions on the selenium grid node.

The problem you’re probably facing is selenium talks to the grid server, the grid server passes the selenium (browser) commands to the browsers in the grid nodes

By design the browser can’t manipulate the file system from the javascript running in the browser. The only way you’ll be able to select a file is by using a file path you know in advance will exist on the grid nodes.

If the host that is running the Robotframework can access the grid nodes then you might be able to push the files to a known location on the grid nodes provided you know the hostnames/ip’s of the grid nodes and have access to them.

  • on a windows grid node that would probably be an OS level file copy using unc paths (i.e. \gridnode1\c$\mypath, \gridnode2\c$\mypath, etc)
  • on a mac/linux grid node that would probably an sftp connection (ftp over ssh) create the needed directory and mput the files you need to upload

Otherwise it’s probably going to have to be a manual step to put the needed files on the grid nodes in a known location on the node.

Hope that helps,
Dave.

Hi @damies13

Yes, that is correct, I’m running a selenium grid and what I’m trying to extract is a file in the selenium remote node.

Right now I can place a file in that remote node by using one feature from Sauce Labs called pre-run, I create a bash file that will run before the test case starts, the bash file will download a file from a specific location in the cloud and placed it in a predefined location. I will use user-data-dir to tell the remote browser to use that directory as the starting point for the session.

The issue is the extraction of the modified files on that user-data-dir, meaning the files after the test case finish.

For now, I was able to create a flask server that contains a form that accepts folders, so as part of the teardown for the test case I navigate to the form and upload the content of user-data-dir However this is introducing an extra UI interaction, thus a potential false negative, for example, the flask form is not reachable.

This solution is working but I think I should re-evaluate my idea.

Thanks for the answer.
Victor

1 Like