javascript - test - selenium webdriver chrome node
Usando Selenium para imitar arrastrando un archivo a un elemento de carga (4)
Tengo una página web que abre un div cuando haces clic en un botón. Esta div le permite arrastrar un archivo desde su escritorio a su área; el archivo se carga en el servidor. Estoy trabajando con la implementación Ruby de Selenium.
Al usar el depurador de JavaScript en Firefox, puedo ver que un evento llamado "drop" se está pasando a algún código JavaScript "handleFileDrop (evento)". Supongo que si tuviera que crear un evento simulado y dispararlo de alguna manera, podría activar este código.
Si encontré un artículo interesante que parecía apuntarme en una dirección prometedora, pero todavía me falta entenderlo todo. Puedo pasar JavaScript a la página utilizando el método get_eval de Selenium. Los métodos de llamada que utilizan this.browserbot me proporcionan los elementos que necesito.
Asi que:
- ¿Cómo compilo el objeto de archivo que debe ser parte del evento de simulación de caída?
- ¿Cómo se dispara el evento drop para que sea recogido como si hubiera caído un archivo en el div?
Como @Shmoopy lo solicitó, aquí hay una traducción de C # del código provisto por @micred
private void DropImage(string dropBoxId, string filePath)
{
var javascriptDriver = this.Driver as IJavaScriptExecutor;
var inputId = dropBoxId + "FileUpload";
// append input to HTML to add file path
javascriptDriver.ExecuteScript(inputId + " = window.$(''<input id=/"" + inputId + "/"/>'').attr({type:''file''}).appendTo(''body'');");
this.Driver.FindElement(By.Id(inputId)).SendKeys(filePath);
// fire mock event pointing to inserted file path
javascriptDriver.ExecuteScript("e = $.Event(''drop''); e.originalEvent = {dataTransfer : { files : " + inputId + ".get(0).files } }; $(''#" + dropBoxId + "'').trigger(e);");
}
Nota: también debe agregar
e.originalEvent.dataTransfer.types = [ ''Files'' ];
Publico una prueba de RSpec que simula archivos arrastrando y soltando usando Selenium webdriver. Utiliza jQuery para crear y desencadenar un evento falso de ''caída''.
Este código simula arrastrar y soltar de un solo archivo. En aras de la simplicidad, he eliminado el código que permite la caída de varios archivos. Dime si lo necesitas.
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
PD: recuerde reemplazar #fileDropArea con el ID de su área de colocación.
PPS: no use evaluar_script en lugar de execute_script, de lo contrario, el selenio se atascará evaluando objetos jQuery complejos.
ACTUALIZACIÓN: he escrito un método que puede reutilizar y hacer lo que está escrito arriba.
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
Uso:
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
Puede usar Blueduck Sda (http://sda.blueducktesting.com) Es un OSS que implementó TODAS las funciones de selenio (funciona con selenio RC) pero le permite automatizar las acciones de Windows. Para que puedas probar web, e interactuar con el sistema operativo. Así que puedes hacer tu prueba, y luego, ¡simplemente dile al mouse que haga clic en el elemento y lo suelte donde quieras!
Buena prueba!