使用Selenium模仿将文件拖到上传元素上

Ben*_*ynn 20 javascript ruby selenium

我有一个网页,当你点击一个按钮时打开一个div.此div允许您将文件从桌面拖到其区域; 然后该文件上传到服务器.我正在使用Selenium的Ruby实现.

通过在Firefox中使用JavaScript调试器,我可以看到一个名为"drop"的事件正被传递给某些JavaScript代码"handleFileDrop(event)".我假设如果我要创建一个模拟事件并以某种方式触发它我可以触发此代码.

如果发现一篇有趣的文章似乎指向了一个充满希望的方向,但我仍然没有把它全部搞清楚.我可以使用Selenium的get_eval方法将JavaScript传递给页面.使用this.browserbot调用方法可以获得我需要的元素.

所以:

  1. 如何构建需要成为模拟放置事件一部分的文件对象?
  2. 如何触发掉落事件,使其被拾取,好像我在div中删除了一个文件?

mic*_*red 29

我发布了一个使用Selenium webdriver模拟文件拖放的RSpec测试.它使用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
Run Code Online (Sandbox Code Playgroud)

PS:记得将#fileDropArea替换为丢弃区域的ID.

PPS:不要使用evaluate_script代替execute_script,否则selenium会卡住评估复杂的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
Run Code Online (Sandbox Code Playgroud)

用法:

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   
Run Code Online (Sandbox Code Playgroud)


San*_*dez 0

您可以使用 Blueduck Sda (http://sda.blueducktesting.com) 是一个已经实现了所有 selenium 功能的 OSS(它与 selenium RC 一起使用),但它允许您自动化 Windows 操作。这样您就可以测试网络并与操作系统交互。因此,您可以进行测试,然后只需告诉鼠标单击该元素并将其放在您想要的位置即可!

不错的测试!