I use the Robot Framework.
On my HTML page I have a simple button. When you click on it, it downloads a PDF file.
How can I check with Robot Framework if the file has been downloaded?
I use the Robot Framework.
On my HTML page I have a simple button. When you click on it, it downloads a PDF file.
How can I check with Robot Framework if the file has been downloaded?
The solution is very browser specific. For Chrome, you can tell Chrome where to download files. Choosing a new folder allows you to monitor the status of the download. Also, since you are downloading a PDF, disabling the PDF plugin is necessary to prevent the PDF from being displayed instead of downloaded. Here is a test that worked on my machine using a simple page and PDF file.
*** Settings ***
Test Teardown Close All Browsers
Library Selenium2Library
Library OperatingSystem
*** Test Cases ***
Download PDF
# create unique folder
${now} Get Time epoch
${download directory} Join Path ${OUTPUT DIR} downloads_${now}
Create Directory ${download directory}
${chrome options}= Evaluate sys.modules['selenium.webdriver'].ChromeOptions() sys, selenium.webdriver
# list of plugins to disable. disabling PDF Viewer is necessary so that PDFs are saved rather than displayed
${disabled} Create List Chrome PDF Viewer
${prefs} Create Dictionary download.default_directory=${download directory} plugins.plugins_disabled=${disabled}
Call Method ${chrome options} add_experimental_option prefs ${prefs}
Create Webdriver Chrome chrome_options=${chrome options}
Goto http://localhost/download.html
Click Link link # downloads a file
# wait for download to finish
${file} Wait Until Keyword Succeeds 1 min 2 sec Download should be done ${download directory}
*** Keywords ***
Download should be done
[Arguments] ${directory}
[Documentation] Verifies that the directory has only one folder and it is not a temp file.
...
... Returns path to the file
${files} List Files In Directory ${directory}
Length Should Be ${files} 1 Should be only one file in the download folder
Should Not Match Regexp ${files[0]} (?i).*\\.tmp Chrome is still downloading a file
${file} Join Path ${directory} ${files[0]}
Log File was successfully downloaded to ${file}
[Return] ${file}
Contents of download.html:
<html><body><a href="file.pdf" id="link">Click Here</a></body></html>
${home_dir} Get Environment Variable HOME
${download_dir} Join Path ${home_dir} Downloads
${result} Run Keyword And Return Status File Should Exist
${download_dir}/filename.pdf
To check further on the file ${content} Get File ${download_dir}/filename.pdf ${count_file} Get Line Count ${content}
Above can be used for basic assertion For more keywords please check the link http://robotframework.org/robotframework/latest/libraries/OperatingSystem.html
A way of doing it is to capture and store timestamp before clicking on download and after clicking download, keep checking the folder if a file exists with timestamp later than the stored one(before download is clicked Tstamp). This works when you do not know the name of the file.
Even if you know the file, when run Test case again, file with named as download(1).pdf as previous file exists in the folder.
*** Settings ***
# Library Selenium2Library
Library checkdownload.py
*** Test Cases ***
Download file Check TC
[Documentation] TC to Check file download button is working
${now} Get Time epoch
#Click on download button #add here
Sleep 30s
${res} Check Download ${now}
Log ${res}
Create a py file and add in robot test suite
#checkdownload.py
import os
import glob
import getpass
from datetime import datetime
def Check_download(timestamp):
user_name=getpass.getuser()
default_download_path=r'/Users/'+user_name+'/Downloads/*' #for mac
# default_download_path=r'C:\Users\\'+user_name+'\Downloads\*' #windows
files_list=glob.glob(default_download_path)
for i in files_list:
if(timestamp < os.path.getctime(i)):
return i
return False
Below are test results (simulated the download)
I'm doing this using FOR IN with large number for every file (when you don't know size and how much time will take to download it). e.g.
${range} Set Variable 9999999
FOR ${s} IN RANGE ${range}
${status} Run Keyword And Return Status File Should Not Exist ${path}\\*.zip.part
Sleep 60
So the script is checking every 60sec if download is finished (no *.zip.part (for FF browser) in particular download folder) then exit for loop.
Instead of using Create WebDriver - you can use simply use Open Browser Keyword to change the download directory using options arguments. Please use a relative path instead of a given absolute path.
*** Settings ***
Library SeleniumLibrary
*** Test Cases ***
DownloadDirectoryChangeForSession
${prefs} = Create Dictionary download.default_directory=C:\\Balaji
Open Browser url=https://www.selenium.dev/downloads/ browser=chrome options=add_experimental_option("prefs",${prefs})
Maximize Browser Window
Click Element partial link=32 bit
File Should Exist C:\\Components\\chromedriver_win32.zip
This worked for me fine (declare the the download path as a variable)
${prefs}= Create Dictionary download.default_directory=${DOWNLOAD_DIRECTORY}
SeleniumLibrary.Open browser ${URL} ${browser}
options=add_experimental_option("prefs", ${prefs})
You need to check the MD5 of the file - before download and after download. Both the MD5 should be same.
Assuming file is on Linux machine - before and after download :
Hope so this information was helpful.