Selenium is a widely used open-source automation testing tool offering a plethora of features it allows users to automate their web testing using multiple programming languages like Java, C#, Ruby, Python, etc.
When it comes to test automation we encounter a lot of actions like click, upload file, enter text, download files and a lot more. In this article we will be understanding how we can download a file using Selenium and Python. We will be covering the below points-
- Downloading file from Firefox browser using Selenium
- Downloading file from Chrome browser using Selenium
- Downloading file from Safari browser using Selenium
In this article we will be using a dummy testing website (https://www.lambdatest.com/selenium-playground) to automate our test scenarios.
Downloading file from Firefox browser using Selenium
Though downloading a file seems like a very easy process, if you manually try you will notice how pop-ups and permissions vary from browser to browser. Let us first see what happens if a user clicks on the download button or link. We will be using the file download demo utility for automation available at LambdaTest playground.
- Step #1- Navigate to the file download webpage.
- Step #2- Enter some text in Enter Data text box-
Step #3- Click on the Generate File Button. A file will be created for the text entered and you will see a download link below the Generate File button.
Step #4- Now click on the Download link and you will see a download pop-up like below-
As you all know, that selenium supports only web-based interactions. In order to handle such windows based pop-ups you need to use either Javascript or some other framework like Robot framework or a tool like AutoIt. Now, in order to make things easier we will use the Firefox Options to handle such pop-ups which will eliminate the need of using any other utility. Additionally, we will be automating downloading of this file at a specific folder location in your system. Let us quickly see how the code for it would look like and then we will understand the same
from selenium import webdriver
from selenium.webdriver.common.by import By
#Creating options object of Firefox driver
options = webdriver.FirefoxOptions()
#Setting preferences for Firefox
options.set_preference(“browser.download.folderList”, 2)
options.set_preference(“browser.download.manager.showWhenStarting”, False)
options.set_preference(“browser.download.dir”, ‘D:\\Gunjan\\Selenium\\DownloadedFiles’)
options.set_preference(“browser.helperApps.neverAsk.saveToDisk”, “text/plain”)
#Defining the Gecko driver executable path
driver = webdriver.Firefox(executable_path=’D:\\Gunjan\\Selenium\\geckodriver’,options=options)
#Opening the URL
driver.get(“https://www.lambdatest.com/selenium-playground/generate-file-to-download-demo”)
#Maximising the window
driver.maximize_window()
#Locating the different elements viz- text box, Generate File Button and Download link and performing corresponding actions
driver.find_element(by=By.XPATH, value=’//*[@id=”textbox”]’).send_keys(“This is a dummy download file!!!!”)
driver.find_element(by=By.ID, value=’create’).click()
driver.find_element(by=By.ID, value=’link-to-download’).click()
#Closing the webdriver instance
driver.quit()
Understanding the code
- options = webdriver.FirefoxOptions()
All the preferences corresponding to the firefox browser are set using the Options object.
- options.set_preference(“browser.download.folderList”, 2)
This preference disables the default directory for file downloads.
- options.set_preference(“browser.download.manager.showWhenStarting”, False)
Setting the download manager preference to false disables the download progress display on the browser.
- options.set_preference(“browser.download.dir”,’D:\Gunjan\Selenium\DownloadedFiles’)
The download directory preference sets the directory where the downloaded file should be stored.
- options.set_preference(“browser.helperApps.neverAsk.saveToDisk”, “text/plain”)
The preference tells the browser driver to automatically save the file of a specific mime type. In our case it is a .txt file hence the mime type is text/plain. You may check the mime type of your file from the response header of the API being called on hitting the Download link from the networks tab.
- driver = webdriver.Firefox(executable_path=’D:\Gunjan\Selenium\geckodriver’,options=options)
A firefox driver object is created and all the preferences set above are passed to it so that the browser gets instantiated with the desired preferences. The two parameters used in the above code defines the driver executable path of the Gecko Driver and the Firefox options object used to set the preferences.
- driver.get(“https://www.lambdatest.com/selenium-playground/generate-file-to-download-demo”)
The code opens up the webpage we need to perform automations on.
- driver.maximize_window()
The function maximises the browser window.
- driver.find_element(by=By.XPATH, value=’//*[@id=”textbox”]’).send_keys(“This is a dummy download file!!!!”)
The code locates the text box and enters text in it.
- driver.find_element(by=By.ID, value=’create’).click()
The code locates the Generate File button and performs click action.
- driver.find_element(by=By.ID, value=’link-to-download’).click()
The download link is located and click is performed.
- driver.quit()
The driver instance is closed.
On executing the code as a whole, the download happens and the file is downloaded at the desired system location. Below snapshot shows the execution results.
The file is downloaded with the content as we entered in the text area.
Downloading file from Chrome browser using Selenium
We will now automate a different scenario using the same LambdaTest Playground and download a pdf file through Chrome Browser automation. The tests for automation execution are listed below-
Step #1- Navigate to the file download webpage.
Step #2- Select the PDF button to download the pdf version of the displayed table.
It’s just a two step use case unlike the one we automated for Firefox. The difference would be the browser and the different settings we will be doing for Chrome. Let us now quickly have a look at the code and then we will understand the same.
from selenium.webdriver.common.by import By
from selenium import webdriver
#Creating webdriver instance of Firefox Options
options = webdriver.ChromeOptions()
#Setting preferences for Chrome
opts = {“download.default_directory”: “D:\\Gunjan\\Selenium\\DownloadedFiles”}
options.add_experimental_option(‘prefs’, opts)
#Setting the driver executable path
driver = webdriver.Chrome(executable_path=’D:\\Gunjan\\Selenium\\chromedriver’, chrome_options=options)
#Opening the URL
driver.get(“https://www.lambdatest.com/selenium-playground/table-data-download-demo”)
driver.maximize_window()
#Locating the download button and clicking on it
driver.find_element(by=By.XPATH, value=’//*[@id=”example_wrapper”]/div[1]/a[4]’).click()
#Closing the driver
driver.close()
Understanding the code
- options = webdriver.ChromeOptions()
The options objects help to set the Chrome preferences.
- opts = {“download.default_directory”: D:\Gunjan\Selenium\DownloadedFiles”}
We create a dictionary to set the default download directory in the system. This is then passed as a parameter to add_experimental_options keyword.
- options.add_experimental_option(‘prefs’, opts)
The preferences set above are added to the Selenium webdriver object using the add_experimental_options. It accepts the name and the value of the experimental object being passed. The value can be anything among – string, integer, dictionary or a list.
- driver = webdriver.Chrome(executable_path=’D:\Gunjan\Selenium\chromedriver’, chrome_options=options)
We then set the executable path for the chrome driver along with the chrome options. The driver is then instantiated.
- driver.get(“https://www.lambdatest.com/selenium-playground/table-data-download-demo”)
URL for the desired web page is opened using the get() method.
- driver.find_element(by=By.XPATH, value=’//*[@id=”example_wrapper”]/div[1]/a[4]’).click()
Since we need to just click the download button, we simply locate the element and use the click() method to perform the action.
And once you execute the above code you will see that the pdf file gets downloaded at the default directory location that is used in the preferences without any issues!
We will now see execution of the same test case in the Safari browser of MAC OS.
Downloading file from Safari browser using Selenium on MAC OS through LambdaTest
So far we have seen execution on Windows OS, but there may be times where you need to check on a different operating system and it is not necessary that you have a different system altogether.
This is where you can leverage the capabilities offered by automation testing platforms like LambdaTest. We will execute the same scenario as we did for Chrome above but using the capabilities of LambdaTest cloud grid. All you need to do is use the grid URL along with your user name and access key. Additionally, you can generate the capabilities to be used as per your choice of operating system, browser, version, resolution, etc. from the LambdaTest capability generator. Below code shows how the capabilities can be placed in your source code and be passed to the webdriver instance.
from selenium import webdriver
from selenium.webdriver.common.by import By
gridUrl = “hub.lambdatest.com/wd/hub”
user = “your_user_name”
accessKey = “your_access_key”
capabilities = {
‘LT:Options’: {
“build”: “MAC OS Build”,
“name”: “Safari Test Case”,
“platformName”: “MacOS Monterey”
},
“browserName”: “Opera”,
“browserVersion”: “84.0”,
}
url = “https://” + user + “:” + accessKey + “@” + gridUrl
driver = webdriver.Remote(
command_executor=url,
desired_capabilities=capabilities)
driver.get(“https://www.lambdatest.com/selenium-playground/table-data-download-demo”)
driver.maximize_window()
driver.implicitly_wait(5)
e1 = driver.find_element(By.XPATH, ‘//*[@class=”dt-button buttons-pdf buttons-html5″]’)
#Checking if element scraped is returned as a web element or a dictionary
if type(e1) is dict:
ele = list(e1.values())[0]
e1 = driver.create_web_element(element_id=ele)
e1.click()
driver.quit()
Unlike our previous examples you might see a little bit of a difference in code, which I will walk you through.
Understanding the code
- gridUrl = “hub.lambdatest.com/wd/hub”
user = “your_user_name”
accessKey = “your_access_key”
You need to set the credentials of LambdaTest as variables for later use in the code.
- capabilities = {
‘LT:Options’: {
“build”: “MAC OS Build”,
“name”: “Safari Test Case”,
“platformName”: “MacOS Monterey”
},
“browserName”: “Opera”,
“browserVersion”: “84.0”,
}
Capabilities are defined as LambdaTest Options which specifies the operating system platform, browser name and the browser version. In addition to it you can specify a build name and a test name for your test. You may select the resolution as well as other advanced capabilities using the capability generator.
- url = “https://” + user + “:” + accessKey + “@” + gridUrl
The url is then created as a concatenation of the grid url, your user name and your access token.
- driver = webdriver.Remote(
command_executor=url,
desired_capabilities=capabilities)
Note that we now use the remote webdriver unlike the chrome or firefox driver that we used in our previous examples. This is because we are using the remote grid for execution of our test case and on that remote grid we will be using the Safari browser which is passed as an option in desired capabilities.
- if type(e1) is dict:
ele = list(e1.values())[0]
e1 = driver.create_web_element(element_id=ele)
This is a small addition that we did for our code execution as compared to the previous examples. Here, we validate if the element that we need to click is returned as a dictionary. If yes, we fetch the element at the 0th location of the dictionary and create a web element from it. If you do not do so, then your test execution may fail if the web element is returned as a dictionary. Note that it is not definite that you will get this element as a dictionary as it is not a very probable scenario. But in case you are getting it as a dictionary you may try adding this piece of code to resolve your problem.
Now when you execute this test, you will see the execution on the LambdaTest Console along with a video of execution. You can navigate to the test result from the dashboard.
Key Takeaways
- Any user can download a file using Selenium and Python on any browser. The file download location can also be set using the browser options.
- Default download directory for file download can also be set using the options.
- One can easily use the LambdaTest automation grid to execute a test pertaining to file download and use the options to set preferences.
- We also saw a trick to resolve errors that might occur due to elements being captured as a dictionary.
Also Read : A Complete Guide To Test Automation Cloud