Demo page: http://demo.tutorialzine.com/2011/09/html5-file-upload-jquery-php/
This page contains drag and drop area but has no <input type='file'> tags.
So $("#fileInput").uploadFile(file); is not working in this situation.
Drag and drop actions chain is not working too because we need to take files from user`s side.
Here is a workaround.
JavaScript part
1. Create fake input field with type="file" and other necessary attributes
2. Add it to DOM
3. Dispatch drag and drop event
4. Remove the fake input field (optionally)
Java part
1. prepare files
2. execute javascript to get new input field
3. use $("#fileInput").uploadFile(file); from Selenide to send file
4. execute javascript to dispatch drag and drop event
public class DragAndDropFilesTest{
@Test
public void testUserCanDragAndDropFiles() {
open("http://demo.tutorialzine.com/2011/09/html5-file-upload-jquery-php/");
// prepare files
ArrayList<File> files = new ArrayList<File> ();
files.add(new File("/path/to/file/file1.png"));
files.add(new File("/path/to/file/file2.png"));
// drag and drop area
SelenideElement dragTarget = $("#dropbox");
// drag and drop the 1st file
dragAndDropFile(files.get(0), dragTarget);
// drag and drop the 2nd file
// it might be necessary to wait for uploaded files appearing on the page. Css selector ".uploaded"
dragAndDropFile(files.get(1), dragTarget, ".uploaded");
assertEquals($$(".uploaded").size(), files.size(), "Not all files are attached");
}
public void dragAndDropFile(File file, SelenideElement dragTarget) {
/*
* Usage:
* dragAndDropFile(files.get(0), $("#dragAndDropAreaId");
*
*/
createInputFile();
SelenideElement fileInput = $("#selenideUpload");
fileInput.uploadFile(file);
dispatchFileDragAndDropEvent("dragenter", "document", fileInput);
dispatchFileDragAndDropEvent("dragover", "document", fileInput);
dispatchFileDragAndDropEvent("drop", dragTarget, fileInput);
// remove fake input file element
executeJavaScript("arguments[0].parentNode.removeChild(arguments[0]);", fileInput);
}
public void dragAndDropFile(File file, SelenideElement dragTarget, String waitForCss ) {
/*
* Usage:
* dragAndDropFile(files.get(0), $("#dragAndDropAreaId", ".uploaded");
*
*/
createInputFile();
SelenideElement fileInput = $("#selenideUpload");
fileInput.uploadFile(file);
dispatchFileDragAndDropEvent("dragenter", "document", fileInput);
dispatchFileDragAndDropEvent("dragover", "document", fileInput);
dispatchFileDragAndDropEvent("drop", dragTarget, fileInput);
$(waitForCss).waitUntil(appears, 5000); // wait until file appears on the page
// remove fake input file element
executeJavaScript("arguments[0].parentNode.removeChild(arguments[0]);", fileInput);
}
public void dragAndDrop(SelenideElement fileInput, SelenideElement dragTarget) {
/*
* Usage:
*
* // upload the first file
* createInputFile();
* SelenideElement fileInput = $("#selenideUpload");
* fileInput.uploadFile(files.get(0));
*
* // upload the second file
* createInputFile();
* SelenideElement fileInput = $("#selenideUpload");
* fileInput.uploadFile(files.get(1));
*
*/
dispatchFileDragAndDropEvent("dragenter", "document", fileInput);
dispatchFileDragAndDropEvent("dragover", "document", fileInput);
dispatchFileDragAndDropEvent("drop", dragTarget, fileInput);
$(".uploaded").waitUntil(appears, 5000); // wait until file appears on the page
executeJavaScript("arguments[0].parentNode.removeChild(arguments[0]);", fileInput);
}
public void createInputFile() {
// Generate a fake input file selector
executeJavaScript("var input = document.createElement('input');" +
"input.id = 'selenideUpload';" +
"input.type = 'file';" +
"input.style.display = 'block';" +
"input.style.opacity = '1';" +
"input.style['transform']='translate(0px, 0px) scale(1)';" +
"input.style['MozTransform']='translate(0px, 0px) scale(1)';" +
"input.style['WebkitTransform']='translate(0px, 0px) scale(1)';" +
"input.style['msTransform']='translate(0px, 0px) scale(1)';" +
"input.style['OTransform']='translate(0px, 0px) scale(1)';" +
"input.style.visibility = 'visible';" +
"input.style.height = '1px';" +
"input.style.width = '1px';" +
"input.name = 'uploadfile';" +
"if (document.body.childElementCount > 0) {" +
"document.body.insertBefore(input, document.body.childNodes[0]);" +
"} else {" +
"document.body.appendChild(input);" +
"}");
}
public void dispatchFileDragAndDropEvent(String eventName, Object to, SelenideElement fileInputId){
String script = "var files = arguments[0].files;" +
"var items = [];" +
"var types = [];" +
"for (var i = 0; i < files.length; i++) {" +
" items[i] = {kind: 'file', type: files[i].type};" +
" types[i] = 'Files';" +
"}" +
"var event = document.createEvent('CustomEvent');" +
"event.initCustomEvent(arguments[1], true, true, 0);" +
"event.dataTransfer = {" +
" files: files," +
" items: items," +
" types: types" +
"};" +
"arguments[2].dispatchEvent(event);";
if (to instanceof String) { // for "document" in dispatchFileDragAndDropEvent("dragenter", "document", fileInput)
script = script.replace("arguments[2]", to.toString());
} else {
executeJavaScript(script,fileInputId, eventName, to);
}
}
}
JavaScript Source: Thanks for idea to PT024/ProfessionalTester-December2013-Herrmann.pdf
No comments:
Post a Comment