Sankumarsingh
Sankumarsingh

Reputation: 10079

How to download any file and save it to the desired location using Selenium Webdriver

I have to perform following task using Selenium Webdriver given below.

  1. Click on any link/button that start downloading any file (filetype may be anything image, pdf, jar etc)
  2. Click on the "Save" on popup if appeared (e.g. in case of http://selenium.googlecode.com/files/selenium-server-standalone-2.33.0.jar)
  3. Give the desired location to save that file.

Can anyone share, how can we implement this using Java?

Upvotes: 38

Views: 92224

Answers (7)

Madhusudan
Madhusudan

Reputation: 23

You can use the below code to save the file to the required location.

package popups;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class FileDownloadPopup 
{
    WebDriver driver;
    FirefoxProfile prof = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();

    @BeforeMethod
    public void setEnvi() 
    {
        System.setProperty("webdriver.gecko.driver", "E:\\Selenium Dependencies\\BrowserExecutables\\geckodriver_win64_v0.21.0.exe");
        prof.setPreference("browser.download.dir","E:\\Downloads");
        prof.setPreference("browser.download.folderList", 2);
        prof.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        options.setProfile(prof);
        driver = new FirefoxDriver(options);
        driver.get("http://file-examples.com/index.php/sample-documents-download/sample-xls-download/");
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
    }

    @Test
    public void FDPP()
    {
        driver.findElement(By.xpath("(//a[text()='Download sample xlsx file'])[1]")).click();
    }

    @AfterMethod
    public void closeEnvi()
    {
        driver.close();
    }

}

Upvotes: 0

AutomatedOwl
AutomatedOwl

Reputation: 1089

In case you are using Java and Chromdriver, I developed a library which should make your downloads much easier.

Among its features, you can set your download directory in one code line and verify that your file was downloaded successfully:

@Test
void downloadAttachTest() throws InterruptedException {
    adamInternetPage.navigateToPage(driver);
    seleniumDownloadKPI.fileDownloadKPI(
            adamInternetPage.getFileDownloadLink(), "SpeedTest_16MB.dat");
    waitBeforeClosingBrowser();
}

Upvotes: 0

stiemannkj1
stiemannkj1

Reputation: 4549

One potential solution is to obtain the URL for the file via Selenium, create a (non-Selenium) connection, copy Selenium's cookies to the connection (if necessary), and download the file. Most languages have APIs (or libraries) for performing HTTP requests. For example, to accomplish this in Java, you could use URL.openConnection():

String link = linkElement.getAttribute("href");
URL url = new URL(link);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("GET");

You may need to copy over the cookies that Selenium has in order to imitate the Selenium user (for example if you are testing a website that requires a sign-in).

Set<Cookie> cookies = webDriver.manager().getCookies();
String cookieString = "";

for (Cookie cookie : cookies) {
    cookieString += cookie.getName() + "=" + cookie.getValue() + ";";
}

httpURLConnection.addRequestProperty("Cookie", cookieString);

Then you can use HttpURLConnection.getInputStream() to write the file contents to your preferred location.

try (InputStream in = httpURLConnection.getInputStream()) {
    Files.copy(in, new File("/path/to/file.ext").toPath(),
        StandardCopyOption.REPLACE_EXISTING);
}

Although, this method would be different for different programming languages, it works the same for all browsers.

Upvotes: 5

Bittu Choudhary
Bittu Choudhary

Reputation: 65

String path="D:\xyz\abc\";

FirefoxOptions profile = new FirefoxOptions();

profile.addPreference("browser.download.folderList", 2);

profile.addPreference("browser.download.manager.showWhenStarting", false);

profile.addPreference("browser.download.dir", **path**);

profile.addPreference("browser.helperApps.neverAsk.openFile","text/csv,application/x-msexcel,application/excel,application/x-excel,application/vnd.ms-excel,image/png,image/jpeg,text/html,text/plain,application/msword,application/xml");

profile.addPreference("browser.helperApps.neverAsk.saveToDisk","text/csv,application/x-msexcel,application/excel,application/x-excel,application/vnd.ms-excel,image/png,image/jpeg,text/html,text/plain,application/msword,application/xml");

profile.addPreference("browser.helperApps.alwaysAsk.force", false);

profile.addPreference("browser.download.manager.alertOnEXEOpen", false);

profile.addPreference("browser.download.manager.focusWhenStarting", false);

profile.addPreference("browser.download.manager.useWindow", false);

profile.addPreference("browser.download.manager.showAlertOnComplete", false);

profile.addPreference("browser.download.manager.closeWhenDone", false);

new FirefoxDriver(profile);

Upvotes: 0

Abelgo
Abelgo

Reputation: 772

The Cancel/Save dialogue popup may be appearing because the site is sending you a different MIME type.

Check the actual header content.

Using the firefox built in Developer tools, Right click to inspect the element/download link your posting then take a look at the Network monitor to see the ContentType header value returned.. That would be the one you want to use..

enter image description here

Set your profile settings accordingly

 firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk",
                     "application/octet-stream,text/csv");

I was expecting "text/csv" however got "application/octet-stream" once that was added to the accepted types list it all worked as expected, No popups

Upvotes: 13

Deepak gupta
Deepak gupta

Reputation: 291

I think you are looking for something like this

//common to all the cases
FirefoxProfile prof = new FirefoxProfile();

//Case:1 - Use this case to set download this code to your browser's default location
//prof.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/zip");

//Case:2 - Download file to Desktop
//prof.setPreference("browser.download.folderList", 0);
//prof.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/zip");

//Case:3 - Download to custom folder path. Replace d:\\selenium with your Download Location 
prof.setPreference("browser.download.dir","D:\\selenium\\");
prof.setPreference("browser.download.folderList", 2);
prof.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/zip");

//This will work for all cases mentioned above
WebDriver driver = new FirefoxDriver(prof);
driver.get("http://docs.seleniumhq.org/download/");
driver.findElement(By.xpath("//tr[1]/td[4]/a[text()='Download']")).click();

Upvotes: 4

Dirk
Dirk

Reputation: 3093

You won't be able to access the save dialog box. That's controlled by the OS. The only thing you're really going to be able to do is set the default download location for the browser and allow it to automatically download the files. Then check the file in Java.

You should check this answer from this previous SO question. Basically when setting up your Firefox profile you add a call to set the property browser.helperApps.neverAsk.saveToDisk to a comma separated list of MIME types to always download:

firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk","text/csv");

See this Mozilla KB FAQ article on About:configs.

UPDATE It looks like this may now be possible see this answer in another question

Upvotes: 26

Related Questions