I needed unit testing for a page which allows to upload files by dragging and dropping them from the desktop.


Code example

import base64
import os

from selenium import webdriver

def drop_file(driver, filepath):
    with open(filepath, "rb") as f:
        b64 = base64.b64encode(f.read()).decode()
    filename = os.path.basename(filepath)
    mtime = str(int(os.path.getmtime(filepath)*1000))
        "var byte_characters = atob('"+b64+"');"
        "var byte_numbers = new Array(byte_characters.length);"
        "for (var i = 0; i < byte_characters.length; i++)"
            "byte_numbers[i] = byte_characters.charCodeAt(i);"
        "var byte_array = new Uint8Array(byte_numbers);"
        "var file = new File([byte_array],'"+filename+"', {"
            "type: 'image/jpg',"
            "lastModified: new Date("+mtime+")"
        "var e = $.Event('drop');"
        "e.originalEvent = {dataTransfer: {files: [file]}};"

We start by encoding the file in base64 and we insert it in the script. The Javascript code will then decode the base64 string. atob() returns a string, so we must convert it first to an array of integers, then to a byte array, which we pass as a parameter to the File constructor.

Bytes → base 64 encoded string → string → array of integers → byte array.