Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload a photo in selenium python when file path input is not visible

This is a html code of upload a photo:

<div id="choose-photo" class="controls avatar-settings inline-upload-avatar dropdown center">
      <div class="uploader-image uploader-avatar clearfix">
        <div class="dropdown-menu">
  <div class="dropdown-caret">
    <span class="caret-outer"></span>
    <span class="caret-inner"></span>
  </div>
  <ul tabindex="-1" role="menu" aria-hidden="true">
    <li id="photo-choose-existing" class="photo-choose-existing upload-photo" role="presentation">
      <button type="button" class="dropdown-link" role="menuitem">Prześlij zdjęcie</button>
      <div class="photo-selector">
  <button class="btn" type="button">
      Zmień zdjęcie
    </button>
  <span class="photo-file-name">Nie wybrano pliku</span>
  <div class="image-selector">
    <input type="hidden" name="media_file_name" class="file-name">
    <input type="hidden" name="media_data_empty" class="file-data">
    <label class="t1-label">
      <span class="u-hiddenVisually">Dodaj zdjęcie</span>
      <input type="file" name="media_empty" class="file-input js-tooltip" tabindex="-1" accept="image/gif,image/jpeg,image/jpg,image/png" data-original-title="Dodaj zdjęcie">
    </label>
  </div>
</div>

    </li>
      <li id="photo-choose-webcam" class="u-hidden" role="presentation">
        <button type="button" class="dropdown-link">Zrób zdjęcie</button>
      </li>
    <li id="photo-delete-image" class="u-hidden" role="presentation">
      <button type="button" class="dropdown-link" role="menuitem">Usuń</button>
    </li>
      <li class="dropdown-divider" role="presentation"></li>
      <li class="cancel-options" role="presentation">
        <button type="button" class="dropdown-link" role="menuitem">Anuluj</button>
      </li>
  </ul>
</div>

</div>
</div>

I've created a simple method to send text to input (it's not visible on screen):

fileInput = driver.find_element_by_name('media_empty')
fileInput.send_keys(path)

But it doesn't do anything. Also I'm getting not any errors.

So, here's a second method, which may work:

<div class="ProfileAvatarEditing-buttonContainer">
<button class="ProfileAvatarEditing-button u-boxShadowInsetUserColorHover" type="button" tabindex="2">
  <div class="ProfileAvatarEditing-addAvatarHelp">
    <span class="Icon Icon--cameraPlus"></span>
    <p>Dodaj zdjęcie profilowe</p>
  </div>
  <div class="ProfileAvatarEditing-changeAvatarHelp">
    <span class="Icon Icon--camera"></span>
    <p>Zmień zdjęcie profilowe</p>
  </div>
  <div class="ProfileAvatarEditing-dropAvatarHelp">
    <span class="Icon Icon--cameraPlus"></span>
    <p>Upuść zdięcie profilowe tutaj</p>
  </div>
</button>

Here user can drap and drop file. I've found this question: Selenium: Drag and Drop from file system to webdriver? however I still don't know how can I use it in this situation.

So the question is how to send file path to the input to trigger file upload. In this case when you choose a file from file dialog or drag and drop it you'll see confirm window with preview on your photo. So then all what's left to do is to click confirm. But I don't know how to send it in the first place.

Any help will be appreciated.

edit: I've found a solution (my own answer below):

fileInput = driver.find_element_by_xpath('//*[@id="photo-choose-existing"]/div/div/label/input')
fileInput.send_keys(path)

but there's one more problem: photo is uploaded but file dialog still opens - I don't know how to close it. I tried accesing it:

dialog = driver.switch_to.active_element['value']

but I don't know how to close it.

like image 447
Makalele Avatar asked Nov 08 '22 21:11

Makalele


1 Answers

Strangely enough I found send_keys do indeed work. When I inspected html code in different browser it wasn't "media_empty" anymore, but a different name ("media[]" or something similar). Instead I've used xpath and I was stunned that it actually worked:

fileInput = driver.find_element_by_xpath('//*[@id="photo-choose-existing"]/div/div/label/input')
fileInput.send_keys(path)
like image 69
Makalele Avatar answered Nov 14 '22 21:11

Makalele