gpt4 book ai didi

javascript - 使用 Selenium 模拟将文件拖到上传元素上

转载 作者:行者123 更新时间:2023-12-03 17:51:37 26 4
gpt4 key购买 nike

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

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

如果找到 interesting article这似乎为我指明了一个有希望的方向,但我仍然没有完全弄清楚。我可以使用 Selenium 的 get_eval 方法将 JavaScript 传递给页面。使用 this.browserbot 调用方法让我得到了我需要的元素。

所以:

  • 如何构建文件对象
    需要成为模拟下降的一部分
    事件?
  • 如何触发 drop 事件
    这样它就会被捡起来,就好像我
    在 div 中删除了一个文件?
  • 最佳答案

    我发布了一个使用 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

    附:请记住将#fileDropArea 替换为放置区域的ID。

    附:不要使用 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

    用法:
    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

    关于javascript - 使用 Selenium 模拟将文件拖到上传元素上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20020345/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com