Использование Selenium для имитации перетаскивания файла на элемент загрузки - PullRequest
20 голосов
/ 04 марта 2011

У меня есть веб-страница, которая открывает div при нажатии кнопки.Этот div позволяет вам перетащить файл с вашего рабочего стола на его область;Затем файл загружается на сервер.Я работаю с Ruby-реализацией Selenium.

Используя отладчик JavaScript в Firefox, я вижу, что событие с именем drop передается в некоторый код JavaScript handleFileDrop (event).Я предполагаю, что если бы я создал фиктивное событие и каким-то образом запустил его, я мог бы вызвать этот код.

Если бы нашел интересную статью , которая, казалось бы, указывала мне в многообещающем направлении, ноЯ все еще не могу понять все это.Я могу передать JavaScript на страницу с помощью метода Selenium get_eval.Вызов методов с использованием this.browserbot дает мне нужные мне элементы.

Итак:

  1. Как мне построить файловый объект, который должен быть частью события mock drop?
  2. Как вызвать событие сброса, чтобы оно было поднято, как если бы я сбросил файл в div?

Ответы [ 4 ]

29 голосов
/ 26 июня 2012

Я публикую тест RSpec, имитирующий перетаскивание файлов с помощью веб-драйвера Selenium.Он использует jQuery для создания и запуска поддельного события drop.

Этот код имитирует перетаскивание одного файла.Для простоты я удалил код, позволяющий удалять несколько файловСкажите, если вам это нужно.

describe "when user drop files", :js => true do
  before do
    page.execute_script("seleniumUpload = window.$('<input/>').attr({id: 'seleniumUpload', type:'file'}).appendTo('body');")

    attach_file('seleniumUpload', Rails.root + 'spec/support/pdffile/pdfTest.pdf')

    # Trigger the drop event
    page.execute_script("e = $.Event('drop'); e.originalEvent = {dataTransfer : { files : seleniumUpload.get(0).files } }; $('#fileDropArea').trigger(e);")
  end

  it "should ..." do
     should have_content '...'
  end

PS: не забудьте заменить #fileDropArea на идентификатор вашей области перетаскивания.

PPS: не используйте define_script вместо execute_script, в противном случае селен застревает при оценке сложных объектов jQuery!

ОБНОВЛЕНИЕ: Я написал метод, который вы можете использовать повторно, и выполните описанные выше действия.

def drop_files files, drop_area_id
  js_script = "fileList = Array();"
  files.count.times do |i|
    # Generate a fake input selector
    page.execute_script("if ($('#seleniumUpload#{i}').length == 0) { seleniumUpload#{i} = window.$('<input/>').attr({id: 'seleniumUpload#{i}', type:'file'}).appendTo('body'); }")
    # Attach file to the fake input selector through Capybara
    attach_file("seleniumUpload#{i}", files[i])
    # Build up the fake js event
    js_script = "#{js_script} fileList.push(seleniumUpload#{i}.get(0).files[0]);"
  end

  # Trigger the fake drop event
  page.execute_script("#{js_script} e = $.Event('drop'); e.originalEvent = {dataTransfer : { files : fileList } }; $('##{drop_area_id}').trigger(e);")
end

Использование:

describe "when user drop files", :js => true do
  before do
     files = [ Rails.root + 'spec/support/pdffile/pdfTest1.pdf',
               Rails.root + 'spec/support/pdffile/pdfTest2.pdf',
               Rails.root + 'spec/support/pdffile/pdfTest3.pdf' ]
     drop_files files, 'fileDropArea'
  end

  it "should ..." do
     should have_content '...'
  end
end   
3 голосов
/ 05 мая 2014

Как попросил @Shmoopy, вот перевод кода на C #, предоставленный @ micred

private void DropImage(string dropBoxId, string filePath)
{
   var javascriptDriver = this.Driver as IJavaScriptExecutor;
   var inputId = dropBoxId + "FileUpload";

   // append input to HTML to add file path
   javascriptDriver.ExecuteScript(inputId + " = window.$('<input id=\"" + inputId + "\"/>').attr({type:'file'}).appendTo('body');");
   this.Driver.FindElement(By.Id(inputId)).SendKeys(filePath);

   // fire mock event pointing to inserted file path
   javascriptDriver.ExecuteScript("e = $.Event('drop'); e.originalEvent = {dataTransfer : { files : " + inputId + ".get(0).files } }; $('#" + dropBoxId + "').trigger(e);");
}
0 голосов
/ 24 марта 2015

Примечание: вы также должны добавить

    e.originalEvent.dataTransfer.types = [ 'Files' ];
0 голосов
/ 04 марта 2011

Вы можете использовать Blueduck Sda (http://sda.blueducktesting.com) - это OSS, в котором реализованы ВСЕ функции селена (он работает с selenium RC), но он позволяет автоматизировать действия Windows. Таким образом, вы можете тестировать веб и взаимодействовать с ОС.Вы можете сделать свой тест, а затем просто скажите мышью, чтобы щелкнуть элемент и бросить его, где вы хотите!

Хорошее тестирование!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...