Press the physical Escape key in tests

How to close native file chooser window during Choose File simulation in Robot Framework?

Hi everyone!

The main issue I’m trying to solve is:

After clicking the “Import” button, I need to upload a file. However, things get tricky because the standard <input type="file"> element doesn’t appear at all.
**Instead, the file is uploaded via an AJAX request using Dropzone, and the result is stored in a hidden input field like this:

<input type="hidden" name="multilang_image-0-text" value="temp_files/bb255b88-bacf-494c-ab58-8397a0bf743a.jpeg" id="multilang_image-0-undefined">

** So the usual Choose File keyword from SeleniumLibrary doesn’t work as expected. **

Hypothesis 1:

Using

Press Keys None ESC  

doesn’t work — naturally — because pressing physical keyboard keys is outside the scope of SeleniumLibrary.
I’m using robotframework-seleniumlibrary, so this limitation applies.

Hypothesis 2:

I tried using xdotool and a custom Python function to simulate pressing the Escape key. It works, but:

  • On Gitlab CI/CD, I have to install packages like this in my job:
apt-get update && apt-get install -y xvfb xdotool
  • Running the same test locally fails with error:
FileNotFoundError: [Errno 2] No such file or directory: 'xdotool'

Here is my custom Python function:

import os
import subprocess

def press_escape_key():
    display = os.environ.get("DISPLAY", ":99")
    try:
        subprocess.run(["xdotool", "key", "Escape"], check=True, env={"DISPLAY": display})
    except subprocess.CalledProcessError as e:
        raise RuntimeError(f"Failed to send Escape key: {e}")

Additional Context

If anyone is interested in the structure of the image upload widget itself, here is an example of a widget after an image has already been uploaded:

<div class="image-simple-widget js-image-simple-widget" style="position: relative" data-image-settings="{&quot;aspect_ratio&quot;:null,&quot;aspect_ratio_tolerance&quot;:0.03,&quot;min_height&quot;:0,&quot;max_height&quot;:0,&quot;max_width&quot;:0,&quot;min_width&quot;:0,&quot;max_size&quot;:10485760,&quot;allowed_types&quot;:[&quot;image/png&quot;,&quot;image/jpeg&quot;,&quot;image/jpg&quot;]}" data-url="/admin/upload_image">
    <div id="text" class="image-simple-widget-content dropzone-container">
        <input type="hidden" name="multilang_image-0-text" value="temp_files/bb255b88-bacf-494c-ab58-8397a0bf743a.jpeg" id="multilang_image-0-undefined">

        <div class="image js-image" style="background-image: url(&quot;/admin/get_temp_file/temp_files/bb255b88-bacf-494c-ab58-8397a0bf743a.jpeg&quot;);">
            <a class="js-full-image-link" href="/admin/get_temp_file/temp_files/bb255b88-bacf-494c-ab58-8397a0bf743a.jpeg" target="_blank">
                <i class="glyphicon glyphicon-eye-open"></i>
            </a>
            <span class="btn btn-sm btn-danger js-clear-image-btn clear-image-btn">
                <i class="glyphicon glyphicon-trash"></i>
            </span>
        </div>

        <div class="image-placeholder js-image-placeholder hidden">
            <hr class="cross-line">
            <hr class="cross-line">
            <span class="btn btn-primary upload-btn js-upload-btn">
                <i class="glyphicon glyphicon-upload"></i> Upload image
            </span>
        </div>

        <div class="dropzone js-dropzone"></div>
    </div>
</div>

Question:

Has anyone found a simpler or more cross-platform way to simulate a physical ESC key press than using xdotool?

I’ve also checked this related question on the forum, but couldn’t find a working solution there.

Great thanks in advance!

P.S.

Hi Andrew,

Well you could try either SikuliLibrary or ImageHorizonLibrary, which would might be easier than xdotool.

But a better solution might be to figure out what the browser is doing and try to figure out how to get selenium do the same. e.g. maybe you need to call Execute Javascript with the file upload function and the path to the file, but as you’ve said it’s not the standard <input type="file"> element, so it’s some sort of custom solution, so you’ll have to read the html / JS of the page to figure out what it’s doing.

Hope that helps,

Dave.

1 Like

Hi,
For ESC key, have you tried simple?

import pyautogui
pyautogui.press(‘esc’)

Works for win file pickers.

In case of the inupt, and what @damies13 wrote, seek for Execute JS solution, that will disable native window opening after click, maybe this thread will help.

2 Likes

you might even get away with doing that with Evaluate like this:

Evaluate 	pyautogui.press(‘esc’) 	modules=pyautogui

I’d still prefer to use a JS solution and avoid the native dialogue window if possible (anything relying on system level keyboard input has the chance of being [flaky / interrupted by other things running on the OS] and also being a problem if you want to use pabot later)

Dave.

2 Likes

SeleniumTestability ( GitHub - MarketSquare/robotframework-seleniumtestability: Extension for SeleniumLibrary that provides manual and automatic waiting for asyncronous events like fetch, xhr, etc. ) - while it most likely is not in good shape, has support for this sort of file uploads, even the acceptance test for it was written to utilize dropzone: robotframework-seleniumtestability/atest/draganddropfile.robot at ca4679e97f340fe5041932e89a31e90313023cda · MarketSquare/robotframework-seleniumtestability · GitHub and the actual implementation robotframework-seleniumtestability/src/SeleniumTestability/plugin.py at master · MarketSquare/robotframework-seleniumtestability · GitHub and the js side here: robotframework-seleniumtestability/src/SeleniumTestability/javascript.py at master · MarketSquare/robotframework-seleniumtestability · GitHub .. If you are handy with python & some javascript, you can just lift the implementation from the lib or try to use it..

Essentially how it was implemented is here

create a new input element into a the form, upload to file into it and then simulate drag and drop into the real input field and then remove the created input element.

1 Like