首页 > 解决方案 > (已解决)单击使用水豚在无头自动化上调用 ajax 函数的元素时无法下载文件

问题描述

我有一个链接元素,当用户/自动化点击链接时,它会下载一个文件,链接是这样的:

<a target="_blank" href="#!" class="downloadFileAws" data-file="report2020-05-20_2020-05-20_jbkd2a1jYFFTyEEUrjiiQBLCQHsjWqj21375.xls" data-path="report">here</a>

当自动化单击该链接时,它将调用 ajax 函数,如下所示:

$('body').on('click', '.downloadFileAws', function(e){
  e.preventDefault();
  var $this = $(this);
  $this.addClass('disabled');
  var folderName =  $this.attr('data-path');
  var fileName =  $this.attr('data-file');
  $.ajax({
    type: 'POST',
    url : $('#getUrlFileAws').val(),
    data: {
      folderName  : folderName,
      fileName    : fileName
    },
    dataType:'JSON',
    success: function (data)
    {
       $this.removeClass('disabled')
       if(data.status === 'success')
       {
          window.open(data.url,'_blank');
       }
       else
       {
          Materialize.toast('File Not Found.<i class="fa fa-times ml25"></i>', 3000,'red accent-4');
       }
    }
  });
})

该 ajax 函数不直接附加在 html 页面上,而是位于名为“mainscript.js”的 javascript 文件中。并将文件附加在 html 页面的底部,如下所示:

<script type="text/javascript" src="/assets/js/mainscript.js?v=100000301"></script>

但是,当无头自动化尝试单击链接元素时,ajax 函数不会调用。我试过用不同的方式点击,例如:

find(:css, 'a.downloadFileAws').click

或者

page.execute_script('$("a.downloadFileAws").click()')

但似乎没有人在工作,我尝试在非无头模式下运行自动化,它就像一个魅力,下载的文件出现在我的自动化项目目录内的下载目录中。

在这里,我将为您提供有关我在 env.rb 中的配置的更多信息:

browser_options = Selenium::WebDriver::Chrome::Options.new
browser_options.add_preference('download.default_directory', 
File.absolute_path('./features/data/files/downloaded'))
browser_options.add_preference(:download, default_directory: 
File.absolute_path('./features/data/files/downloaded'))
browser_options.add_preference(:browser, set_download_behavior: { 
behavior: 'allow' })

browser_options.add_preference('plugins.always_open_pdf_externally', true)
browser_options.add_preference(:plugins, always_open_pdf_externally: true)

Capybara.register_driver :chrome_headless do |app|
  browser_options.add_argument('--headless')
  browser_options.add_argument('--no-sandbox')
  browser_options.add_argument('--disable-gpu')
  browser_options.add_argument('--disable-dev-shm-usage')

  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    options: browser_options
  )
end

Capybara.register_driver :chrome do |app|
  profile = Selenium::WebDriver::Chrome::Profile.new

  browser_options.add_argument('--user-agent=selenium')
  browser_options.add_argument('--start-maximized')
  client = Selenium::WebDriver::Remote::Http::Default.new
  client.open_timeout = wait_time
  client.read_timeout = wait_time
  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    options: browser_options,
    http_client: client,
    profile: profile
  )
end

任何帮助都会非常感激,因为我已经在这个问题上停留了好几天,所以谢谢大家。

编辑:我已经通过在注册 chrome_headless 驱动程序时添加一些代码解决了这个问题:

Capybara.register_driver :chrome_headless do |app|
  browser_options.add_argument('--headless')
  browser_options.add_argument('--no-sandbox')
  browser_options.add_argument('--disable-gpu')
  browser_options.add_argument('--disable-dev-shm-usage')

  driver = Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    options: browser_options
  )

  driver.browser.download_path = File.expand_path('./features/data/files/downloaded')

  driver
end

标签: jqueryajaxseleniumcapybaragoogle-chrome-headless

解决方案


必须根据 Chrome 版本和模式(无头与非无头)设置不同的下载行为。使用 Capybara 用于自己的测试的配置应该适用于两种模式下的任何最新版本 - 请参阅https://github.com/teamcapybara/capybara/blob/master/spec/selenium_spec_chrome.rb#L13

您也不应该再使用desired_capabilities了,并且您绝对应该停止禁用w3c模式,除非您使用的是非常旧的 Chrome 版本,在这种情况下,以无头模式下载可能根本不起作用。


推荐阅读