37

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?

vishal_g
  • 3,871
  • 4
  • 21
  • 34
Sankumarsingh
  • 9,889
  • 11
  • 50
  • 74
  • You may use AutoIT alternatively to do this very smoothly without changing or referring to any config or property file, you may refere my reply to [similar post](https://stackoverflow.com/questions/27789023/interacting-with-pop-up-boxes-using-selenium-in-python/45323191#45323191) – eaccmk Jul 27 '17 at 15:18
  • Related question here: https://stackoverflow.com/questions/18439851/downloading-file-using-selenium – stiemannkj1 Nov 09 '17 at 14:36
  • Sikulixapi would allow you to gain access to the dialog box and type in the box where you want to save it as well as push the save button. http://sikulix.com/ – user2117229 May 23 '19 at 20:34

7 Answers7

25

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

Community
  • 1
  • 1
Dirk
  • 3,030
  • 1
  • 34
  • 40
  • 3
    it's possible to access save dialog box you can use robot class for that to access and perform events like ENTER, TABS and ESCAPE using robot class – Luffy Apr 22 '15 at 04:38
  • 1
    @Luffy, thanks. I see you posted an answer in another question. This was not possible when I first answered this question. I've updated the answer to reference your solution. – Dirk Jun 16 '15 at 22:40
  • I don't understand, I used these exact settings and pdf open normally, it doesn't save to disk. Are there alternative apart of using request, after all this work it would be a poor workaround... (info about pdf page set it as "application/pdf" so seems ok)? Thanks – Ando Jurai May 09 '17 at 00:50
  • What if I don't know the type of the download file yet? can it be dynamic? – weefwefwqg3 Jun 12 '18 at 18:51
13

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

Liam
  • 27,717
  • 28
  • 128
  • 190
Abelgo
  • 772
  • 7
  • 7
  • 4
    Wow thanks for emphasizing the fact that one has to really check the actual HEADER CONTENT. Since the file I'm downloading is a csv, I thought it should be `text/csv` but boy was I wrong. In my case, it wasn't even `application/octet-stream` like it was in your case, but `application/csv`. Thanks! – mkab Mar 28 '17 at 02:14
5

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.

stiemannkj1
  • 4,418
  • 3
  • 25
  • 45
4

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();
Liam
  • 27,717
  • 28
  • 128
  • 190
Deepak gupta
  • 291
  • 4
  • 5
  • 15
0
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);
0

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();
}
AutomatedOwl
  • 1,039
  • 1
  • 8
  • 14
0

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();
    }

}
Madhusudan
  • 23
  • 1
  • 4