简体   繁体   中英

Uploading a file without input field in HTML and using only JS Drag and Drop API

How can I pass the file upload path using the DnD javascript Api for python + selenium automation? Previously, for uploads, I used find_element(By.XPATH, '//input[contains(@title, "dropzon")]').send_keys('file_path') , I was bound to input. But the layout has changed and input is no more. I tried to execute a js script with passing the path to the file, but the call ends with an error

删除文件full size

Maybe someone has already done a similar operation?

Examples:

js_upload_file_script = "const element = document.querySelector('.c-audio-dropzone'); " \
                        "const input = document.createElement('input'); " \
                        "input.type = 'file'; " \
                        "input.className = 'my-audio-input'; " \
                        "const dt = new DataTransfer(); " \
                        "dt.items.add(file);"

self.execute_javascript_with_arguments(js_upload_file_script, 'abs_path_to_file', driver)

error -> selenium.common.exceptions.JavascriptException: Message: javascript error: Failed to execute 'add' on 'DataTransferItemList': parameter 1 is not of type 'File'.

and

js_upload_file_script = "const element = document.querySelector('.c-audio-dropzone'); " \
                        "const input = document.createElement('input'); " \
                        "input.type = 'file'; " \
                        "input.className = 'my-audio-input'; " \
                        "const file = input.files[0]; " \
                        "const dt = new DataTransfer(); " \
                        "dt.items.add(file); " \
                        "element.dispatchEvent(new DragEvent('drop', {dataTransfer: dt}))"

self.execute_javascript_with_arguments(js_upload_file_script, 'abs_path_to_file', driver)

error -> selenium.common.exceptions.JavascriptException: Message: javascript error: Failed to execute 'add' on 'DataTransferItemList': parameter 1 is not of type 'File'.

and

js_upload_file_script = "const element = document.querySelector('.c-audio-dropzone'); " \
                        "const input = document.createElement('input'); " \
                        "input.type = 'file'; " \
                        "input.className = 'my-audio-input';" \
                        "const dt = new DataTransfer(); " \
                        "dt.items.add(file); "

self.execute_javascript(js_upload_file_script, driver)
driver.find_element(By.CSS_SELECTOR, '.my-audio-input').send_keys('abs_path_to_file')

nothing is happening

and last

js_upload_file_script = "const element = document.querySelector('.c-audio-dropzone'); " \
                        f"var file = new File(['{resource}'], '{location_file}', " \
                        "{ type: 'file' }); " + "const dt =  new DataTransfer(); dt.items.add(file);" \ 
                        "element.dispatchEvent(new DragEvent('drop', {dataTransfer: dt}))"
self.execute_javascript(js_upload_file_script, driver)

a semi-working option, since I see an attempt to upload a file, and but with an error

上传错误full size

I found a solution:

  • First I created an input in the DOM with attributes and a class for the future file

     create_input = "const element = document.querySelector('.c-audio-dropzone'); " \ "const input = document.createElement('input'); " \ "input.type = 'file'; " \ "input.className = 'my-audio-input'; " \ "document.body.append(input);"
  • called the execution of the JS script for creating input on the page

    self.execute_javascript(create_input, driver)
  • Then I prepared a JS script to upload the file

    upload_file = "const input = document.querySelector('.my-audio-input'); " \ "const file = input.files[0]; " \ "const dt = new DataTransfer(); " \ "dt.items.add(file); " \ "const element = document.querySelector('.c-audio-dropzone'); " \ "element.dispatchEvent(new DragEvent('drop', {dataTransfer: dt}))"
  • Then I found the element where I threw the path to the file through send_keys

    driver.find_element(By.CSS_SELECTOR, self.audio_input).send_keys('absolute_file_path_for_upload')
  • And called the JS script to download the file

    self.execute_javascript(upload_file, driver)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM