5

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?

mia654321
  • 111
  • 1
  • 6
  • ```driver.get("http://yourhost.com/uploadurl"); WebElement upload = driver.findElement(By.id("id-of-file")); upload.sendKeys("/your/file/to/upload.txt"); driver.findElement(By.id("submit")).click();``` – Andrei Sfat Jan 13 '16 at 14:46
  • This doesn't look like it's an IDE issue. Meanwhile you should look at questions like http://sqa.stackexchange.com/questions/12851/how-can-i-work-with-file-uploads-during-a-webdriver-test that address this issue. – DMart Jan 14 '16 at 15:34
  • Thanks for your help. I was looking for selenium IDE solution but in this time I want move my tests to the Webdriver. – mia654321 Jan 15 '16 at 13:39
  • It's an issue whether you use IDE or webdriver. – DMart Jan 18 '16 at 19:36

4 Answers4

2

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!

  • 1
    It helped a lot. The suggested link is overly complicated...and not 100% correct. Dropzone uses the File() API. Here is my simplified script https://gist.github.com/adiroiban/212d61d7cc25a7719d6fc8bc33d702f9 ... no need for base64 – Adi Roiban Apr 17 '18 at 12:25
1

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');
Gal Bracha
  • 19,004
  • 11
  • 72
  • 86
0

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);  "
    );
Yoni
  • 51
  • 1
  • 2
0

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" );
        }
Yehor Androsov
  • 4,885
  • 2
  • 23
  • 40