Search code examples
javascriptpythonseleniumimage-uploadinghidden-field

Selenium Python - Upload image when element seems to be hidden


So basically I have problem uploading some photo using Selenium Python input element seems to be hidden in the page so the .sendkeys method at still I run into some errors.

this is html code of the input element

 <div data-react-class="ImageUploadForm" data-react-props="{}" data-react-cache-id="ImageUploadForm-0">
  <input class="hidden" type="file" accept="image/jpeg, image/jpg, image/png, image/gif">
  <button class="btn btn-lemonfrog text-lg" type="button">Upload photo</button>
 </div>
base_path = Path(file).parent
filepath = (basepath / "../core/attachments/clientstackphoto.jpeg").resolve()
hiddenuploaderinput.sendkeys(filepath)

right now after running above code I'm getting type error : value = (PosixPath('........./core/attachments/clientstackphoto.jpeg'),)

def keys_to_typing(value):
    """Processes the values that will be typed in the element."""
    typing = []
    for val in value:
        if isinstance(val, Keys):
            typing.append(val)
        elif isinstance(val, int):
            val = str(val)
            for i in range(len(val)):
                typing.append(val[i])
        else:
          for i in range(len(val)):

E TypeError: object of type 'PosixPath' has no len()

../../venv/lib/python3.7/site-packages/selenium/webdriver/common/utils.py:150: TypeError

I expect to upload photo successfully, maybe some js injection will help ?


Solution

  • Based on your error message, I'm not entirely convinced the error message is caused by the hidden file input. If it were, I would expect an ElementNotVisibleException.

    However, I do see that the input is hidden, so we should run some JS to reveal the input and perhaps we can rule that out as a potential issue.

    Code to show image input

    fileInput = driver.find_element_by_xpath("//input[@type='file']")
    
    # display file input so we can send keys
    driver.execute_script("arguments[0].style.display = 'block';", fileInput)
    

    Alternatively, you may need to execute script on the class attribute instead:

    driver.execute_script("arguments[0].setAttribute('class', 'visible')", fileInput)
    

    Once you execute JS to make the file input visible, you can just send_keys to it like any other input:

    fileInput.send_keys("PATH/TO/FILE/HERE")