mia654321
mia654321

Reputation: 111

Upload file with selenium ide to the Dropzone.js

I'm creating selenium ide tests and now I have problem. I can't write test for uploading a file from local disk.

My dropzone looks like: http://www.dropzonejs.com/examples/simple.html

Can somebody helps me?

Upvotes: 5

Views: 5581

Answers (4)

AbdEllah Abril
AbdEllah Abril

Reputation: 51

If you could not upload the file using "sendKeys()" method, maybe you can't find the input with type "file" or..., I think the easiest method is by using class Robot of the "java.awt" library:

  1. click on the web element to show the upload dialog, in this case is the drop zone div.
  2. paste the file path by clicking and releasing "ctrl + V".
  3. press "Enter" key.
    public static void main( String[] args ) throws Exception
        {
            System.setProperty("webdriver.gecko.driver", "/home/bril/IdeaProjects/automation/geckodriver");
            WebDriver driver = new FirefoxDriver();
            driver.navigate().to("https://www.dropzonejs.com/");
            WebElement dropZone = driver.findElement(By.id("dropzone"));
            Robot rb = new Robot();
            // copying File path to Clipboard
            StringSelection str = new StringSelection("/home/bril/Downloads/img.jpg");
            Toolkit.getDefaultToolkit().getSystemClipboard().setContents(str, null);
            dropZone.click(); // Click on browse option on the webpage
            Thread.sleep(3000); // suspending e xecution for specified time period
            // press Contol+V for pasting
            rb.keyPress(KeyEvent.VK_CONTROL);
            rb.keyPress(KeyEvent.VK_V);
            // release Contol+V for pasting
            rb.keyRelease(KeyEvent.VK_CONTROL);
            rb.keyRelease(KeyEvent.VK_V);
            Thread.sleep(3000); // suspending execution for specified time period
            // for pressing and releasing Enter
            rb.keyPress(KeyEvent.VK_ENTER);
            rb.keyRelease(KeyEvent.VK_ENTER);
            System.out.println( "Finish" );
        }

Upvotes: 0

Gal Bracha
Gal Bracha

Reputation: 20021

Usually, there is a hidden form input

<input type="file" multiple="multiple" class="dz-hidden-input" accept="image/jpg,image/jpeg style="visibility: hidden>

So you can simply communicate with that hidden element

For example -

const fileSelector = By.xpath("//input[@type='file']");
const fileInput = await this.driver.findElement(fileSelector);
await fileInput.sendKeys('/tmp/myfile.jpg');

Upvotes: 1

Yoni
Yoni

Reputation: 81

You can use this java code that runs JS script using the convertFileToBase64String method from the answer above. You need to provide 4 params:

  1. ID for the Dropzone element ("VUIDropzone96326-dropzone" for example)
  2. New name for the file you are uploading (sometimes the server expect to specific name)
  3. Path to file you are uploading
  4. base64IFile string you have got from convertFileToBase64String merhod

This is the complete solution:

    String id = "Put here the ID of the Dropzone element"
    String fileName = "Put here desired file name";
    String base64IFile = convertFileToBase64String(filePath);
    ((JavascriptExecutor) driver).executeScript("var myZone = Dropzone.forElement('#" + id + "');" +
            "base64Image = '" + base64IFile + "';" +
            "function base64toBlob(b64Data, contentType, sliceSize) {  \n" +
            "    contentType = contentType || '';\n" +
            "    sliceSize = sliceSize || 512;\n" +
            "\n" +
            "    var byteCharacters = atob(b64Data);\n" +
            "    var byteArrays = [];\n" +
            "\n" +
            "    for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {\n" +
            "        var slice = byteCharacters.slice(offset, offset + sliceSize);\n" +
            "\n" +
            "        var byteNumbers = new Array(slice.length);\n" +
            "        for (var i = 0; i < slice.length; i++) {\n" +
            "            byteNumbers[i] = slice.charCodeAt(i);\n" +
            "        }\n" +
            "\n" +
            "        var byteArray = new Uint8Array(byteNumbers);\n" +
            "\n" +
            "        byteArrays.push(byteArray);\n" +
            "    }\n" +
            "\n" +
            "    var blob = new Blob(byteArrays, {type: contentType});\n" +
            "    return blob;\n" +
            "}" +
            "var blob = base64toBlob(base64Image, 'image / png');" +
            "blob.name = '" + fileName + "';" +
            "myZone.addFile(blob);  "
    );

Upvotes: 0

user7788307
user7788307

Reputation:

I ran into the same issue and I found the answer here: How to interact with Dropzone using selenium

I used most of this but I had to create my own method to convert to base64 properly.

public static String convertFileToBase64String(String fileName) throws IOException {

        File file = new File(fileName);
        int length = (int) file.length();
        BufferedInputStream reader = new BufferedInputStream(new FileInputStream(file));
        byte[] bytes = new byte[length];
        reader.read(bytes, 0, length);
        reader.close();
        String encodedFile = Base64.getEncoder().encodeToString(bytes);

        return encodedFile;
    }

Hope this helps!

Upvotes: 2

Related Questions