2015-10-01 5 views
11

Ich habe das Plugin Dropzone.js für Drag-and-Drop-Datei-Uploads verwendet. Wie kann ich einen Capybara-Test schreiben, um sicherzustellen, dass diese Funktionalität weiterhin funktioniert?Wie testen Sie das Hochladen einer Datei mit Capybara und Dropzone.js?

Früher hatte ich eine Vorlage mit einer Eingabedatei Element:

<input type="file" name="attachments"> 

und der Test war einfach:

When(/^I upload "([^"]*)"$/) do |filename| 
    attach_file("attachments", File.expand_path(filename)) 
    # add assertion here 
end 

dies jedoch nicht mehr funktioniert, weil Dropzone keine sichtbare Datei Eingang hat .

+0

Bitte folgende Antwort überprüfen: https://stackoverflow.com/questions/16722291/ how-to-test-dropzone-js-Upload-mit-Schienen-Gurke-und-Capybara/47141809 # 47141809 –

+0

Bitte überprüfen Sie die folgende Antwort: https://StackOverflow.com/Questions/16722291/How-to-test- dropzone-js-upload-mit-Schienen-Gurke-und-Capybara/47141809 # 47141809 –

Antwort

16

Um dies zu lösen, simulieren Sie einen Drop, um auch einen Anhang auf Dropzone fallen zu lassen. Zuerst fügen Sie diese Funktion, um Ihre Schrittdefinition:

# Upload a file to Dropzone.js 
def drop_in_dropzone(file_path) 
    # Generate a fake input selector 
    page.execute_script <<-JS 
    fakeFileInput = window.$('<input/>').attr(
     {id: 'fakeFileInput', type:'file'} 
    ).appendTo('body'); 
    JS 
    # Attach the file to the fake input selector 
    attach_file("fakeFileInput", file_path) 
    # Add the file to a fileList array 
    page.execute_script("var fileList = [fakeFileInput.get(0).files[0]]") 
    # Trigger the fake drop event 
    page.execute_script <<-JS 
    var e = jQuery.Event('drop', { dataTransfer : { files : [fakeFileInput.get(0).files[0]] } }); 
    $('.dropzone')[0].dropzone.listeners[0].events.drop(e); 
    JS 
end 

Dann testen Sie mit:

When(/^I upload "([^"]*)"$/) do |filename| 
    drop_in_dropzone File.expand_path(filename) 
    # add assertion here 
end 

Hinweis: Sie müssen jQuery haben geladen und das Dropzone Element erfordert die Dropzone Klasse.

3

Falls es jemand interessiert, ich @ Deepwell- der Funktion Javascript portierte, es zu benutzen, mit Javascript aromatisiert Selen:

this.dropInDropzone = function(filePath) { 
    var script = "fakeFileInput = $('#fakeFileInput'); if (fakeFileInput.length === 0) fakeFileInput = window.$('<input/>').attr({id: 'fakeFileInput', type:'file'}).appendTo('body');"; 
    // Generate a fake input selector 
    return driver.executeScript(script).then(function() { 
    // Attach the file to the fake input selector 
    return driver.findElement(webdriver.By.css('#fakeFileInput')).sendKeys(filePath); 
    }).then(function() { 
    // Add the file to a fileList array 
    return driver.executeScript("var fileList = [fakeFileInput.get(0).files[0]]"); 
    }).then(function() { 
    // Trigger the fake drop event 
    script = "var e = jQuery.Event('drop', { dataTransfer : { files : [fakeFileInput.get(0).files[0]] } }); $('.dropzone')[0].dropzone.listeners[0].events.drop(e);" 
    return driver.executeScript(script); 
    }); 
}; 
+0

OP fragt nach Capybara, nicht JS. Dies wäre besser als ein Kommentar zu der ausgewählten Antwort. – Pachonk

+0

Es scheint, dass jede Seite die Dropzone anders implementiert, und wir müssen dieses Skript ein wenig anpassen, damit es funktioniert. In meinem Fall ist das etwas mit dem Attribut "originalEvent" zu tun –