question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Triggering file upload from Capybara/poltergeist (ruby) feature tests

See original GitHub issue

I’m writing feature tests using Capybara + Poltergeist in my rails + angular site. It’s all working perfectly in the browser, just not in my tests. My tests are working for other JS (JQuery and Angular) stuff, but I can’t get the upload process to start.

For normal file upload stuff there is the capybara attach_file method (docs). However, that isn’t firing the upload process with this library. It doesn’t fail either, it just does nothing:

#does not fail but does not trigger upload
attach_file "img-file-select", 
  ["#{Rails.root}/spec/fixtures/images/property.jpg",
  "#{Rails.root}/spec/fixtures/images/kitchen.jpg"]

I also tried using the trigger method to fire events manually. These do fail.

#these fail with with 'Capybara::Poltergeist::BrowserError: Unknown event [object Object]'
find("#img-file-select").trigger('ngFileSelect')
find("#img-file-select").trigger('fileSelect')
find("#img-file-select").trigger('change')

View code (HAML):

%input{ng: {"file-select" => "onFileSelect($files)"}, type: "file", multiple: true, id: "img-file-select"}

Coffeescript controller code (lightly modified from your sample app):

$scope.onFileSelect = ($files) ->
  $scope.selectedFiles = []
  $scope.progress = []
  $scope.upload = []
  $scope.uploadResult = []
  $scope.selectedFiles = $files
  $scope.dataUrls = []
  $scope.complete = false
  $scope.aborted = []
  $scope.typeExcluded = []
  $scope.allExcluded = true #will be set to false if any of the files is an image

  for f, i in $files
    if f.type.indexOf('image') <= -1
      $scope.typeExcluded[i] = true
    else
      $scope.allExcluded = false
      if (window.FileReader)
        fileReader = new FileReader()
        fileReader.readAsDataURL(f)
        loadFile = (reader, index) ->
          reader.onload = (e) ->
            $timeout( -> $scope.dataUrls[index] = e.target.result)
        loadFile(fileReader, i)
      $scope.progress[i] = -1
      $scope.start(i)

$scope.start = (index) ->
  $scope.progress[index] = 0
  $scope.errorMsg = null
  $scope.upload[index] = $upload.upload({
    url: upload_url,
    method: 'POST',
    file: $scope.selectedFiles[index]
  }).then(
    (response) ->
      #success
      $scope.uploadResult.push response.data
      $scope.complete = true
      return
    , (response) ->
      #error
      $scope.errorMsg = response.status + ': ' + response.data if (response.status > 0)
      $scope.complete = true
      return
    , (evt) ->
      #progress
      $scope.progress[index] = Math.min(100, parseInt(100.0 * evt.loaded / evt.total))
      return
  ).xhr((xhr) ->
    xhr.upload.addEventListener(
      'abort',
      ->
        return
      , false
  ))

Like I said, it’s all working the browser. You can also see my Stack Overflow question on the same topic here: http://stackoverflow.com/questions/23958713/triggering-angular-directive-from-capybara-poltergeist-feature-test

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

6reactions
gottfroiscommented, Jul 8, 2015

Here is how i’ve done it:

page.execute_script <<-JS
  fakeFileInput = window.$('<input/>').attr({ id: 'fileFileInput', type: 'file' }).appendTo('body');
JS

page.attach_file('fakeFileInput', Rails.root.join('some_path'))

page.execute_script <<-JS
  var scope = angular.element('ngFileUploadElementCssSelectorHere').scope();
  scope.files = [fakeFileInput.get(0).files[0]];
JS
0reactions
rbattacommented, Feb 21, 2017

For future users, gottfrois 's code worked, with some small adjustments (if NOT using multiple file uploads).

Putting it directly into the feature spec file as a method:

def js_fake_file_uploader
  execute_script <<-JS
    fakeFileInput = window.$('<input/>').attr({ id: 'fakeFileInput', type: 'file' }).appendTo('body');
  JS

  attach_file 'fakeFileInput', "#{Rails.root}/spec/support/test-pdf.pdf"

  execute_script <<-JS
    var page_scope = angular.element('#fakeFileInput').scope();
    page_scope.file = fakeFileInput.get(0).files[0];
  JS

  click_on 'Submit'
end
Read more comments on GitHub >

github_iconTop Results From Across the Web

Triggering angular directive from capybara/poltergeist feature ...
My file upload code relies on a directive in that library called ngFileSelect (source for the directive here). This works perfectly when I...
Read more >
Uploading files with Capybara in RSpec tests - Tosbourn
Capybara is a great tool for testing your Rails app. Recently I had cause to test uploading files through a particular UI. Here...
Read more >
Migrating Selenium system tests to Cuprite
Under Cuprite, uploading stopped working and an ERR_ACCESS_DENIED error was shown in the JavaScript console each time a test attempted to upload ......
Read more >
File: README — Documentation for poltergeist (1.1.1) - RubyDoc.info
Poltergeist is a driver for Capybara. It allows you to run your Capybara tests on a headless WebKit browser, provided by PhantomJS.
Read more >
Attach_File Isn'T Working The Right Way With Capybara-Webkit
This utility isn't available in Windows, but comes bundled with Ruby Devkit, ... Triggering file upload from capybarapoltergeist ruby feature tests 230.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found