Подтвердить что ты не робот

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

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

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

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

Итак:

  • Как создать файл-объект, который должен быть частью ложного падения мероприятие?
  • Как мне запустить событие drop так что он подбирается, как будто я удалил файл в div?
4b9b3361

Ответ 1

Я отправляю тест 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

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

P.P.S: не используйте файл_цены вместо execute_script, иначе селен застрянет, оценивая сложные объекты jQuery!

UPDATE: Я пишу метод, который вы можете повторно использовать, и делайте написанное выше.

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   

Ответ 2

Как пояснил @Shmoopy, здесь С# перевод кода, предоставленного @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);");
}

Ответ 3

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

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

Ответ 4

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

    e.originalEvent.dataTransfer.types = [ 'Files' ];

Кто-нибудь получил это, работая над ng-flow?