Search code examples
pythonseleniumselenium-chromedriverbrowser-automation

Python Selenium: send_keys not sending the actual path to a file input element


I'm using Python Selenium and ChromeDriver to instrument a webpage with an input to upload a file. According to all the documentation and StackOverflow answers I've read, sending the full file path to the input element via send_keys should automate this (I even have something similar working for simple text inputs). But it doesn't work.

I've isolated this to a minimal example:

HTML:

<input type="file" class="the_input">

Python:

import time

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys

options = Options()
options.add_argument('--user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1"')
options.add_argument('--window-size=375,812')
options.add_argument('user-data-dir=selenium')
browser = webdriver.Chrome(options=options)

browser.get('file:///xxxxx.html')
time.sleep(2)

input = browser.find_elements_by_class_name('the_input')[0]
print('attempting to change input')
input.clear()
print('input value:', input.get_attribute('value'))
input.send_keys('/Users/xxxxx/the_image.jpg')
print('input value:', input.get_attribute('value'))
input.send_keys(Keys.ENTER)

print('quitting')
browser.quit()

When the /Users/xxxxx/the_image.jpg path is not valid, running this will throw at the first 'send_keys' line (which sends the path string):

attempting to change input
input value: 
Traceback (most recent call last):
...
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: File not found : /Users/xxxxx/the_image.jpg

This seems reasonable.

However, when the /Users/xxxxx/the_image.jpg path is valid, running the same thing will throw at the second 'send_keys' line (which sends the ENTER):

attempting to change input
input value: 
input value: C:\fakepath\the_file.png
Traceback (most recent call last):
...
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: File not found : 

This blew my mind: it seems that my valid path was swapped for the bogus path C:\fakepath\the_file.png (I'm not even on Windows). I'm guessing this is a security related behavior somewhere between Selenium and ChromeDriver. But if this is the expected behavior, what am I missing, how have others got this working? Is it even possible to fully automate upload flows like this?


UPDATE/ANSWER

There were two separate issues here:

  • Sending the ENTER key is wrong. Simply sending the file path will behave as expected. It is equivalent to the user opening the file selection dialog, choosing a file, and then clicking open. If you also send ENTER after that, it will be equivalent to resetting the input's value to empty (which explains the "File not found : " error I was seeing).
  • If you query the input for its value after sending the file path, you will see your actual file name but with a bogus path ("C:\fakepath\correct_file_name.png"). This is a security measure that avoids leaking information about your directory structure. You can ignore this bogus path, because the correct path is actually sent to the input.

Solution

  • send_keys should upload the file without clicking on the enter keyboard button. When you hit on Enter keyboard, send_keys method for file type input will consider the file path as empty and it will fail as it did in your case.

    So you can take out the step related to hitting the Enter key, which is causing the unnecessary issue in this case.