First of all why do you want to download the file? Are you going to do anything with it?
The majority of poeple who want to download files just do it so that they can show an automation framework downloading files because it makes somebody non-technical ooo and ahh.
You can check the header response to check that you get a 200 OK (or maybe a redirect, depends on your expected outcome) and it will tell you that a file exists.
Only download files if you are actually going to do something with them, if you are downloading them for the sake of doing it you are wasting test time, network bandwidth and disk space.
Here is my implementation:
This finds the link on the page and extracts the url being linked to. It then uses apache commons to replicate the browser session used by selenium and then download the file. There are some instances where it won't work (where the link found on the page does not actually link to the download file but a layer to prevent automated file download).
Generally it works well and is cross platform/cross browser complient.
The code is:
/*
* Copyright (c) 2010-2011 Ardesco Solutions - http://www.ardescosolutions.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.lazerycode.ebselen.customhandlers;
import com.google.common.annotations.Beta;
import com.lazerycode.ebselen.EbselenCore;
import com.lazerycode.ebselen.handlers.FileHandler;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import java.io.*;
import java.net.URL;
import java.util.Set;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Beta
public class FileDownloader {
private static final Logger LOGGER = LoggerFactory.getLogger(EbselenCore.class);
private WebDriver driver;
private String downloadPath = System.getProperty("java.io.tmpdir");
public FileDownloader(WebDriver driverObject) {
this.driver = driverObject;
}
/**
* Get the current location that files will be downloaded to.
*
* @return The filepath that the file will be downloaded to.
*/
public String getDownloadPath() {
return this.downloadPath;
}
/**
* Set the path that files will be downloaded to.
*
* @param filePath The filepath that the file will be downloaded to.
*/
public void setDownloadPath(String filePath) {
this.downloadPath = filePath;
}
/**
* Load in all the cookies WebDriver currently knows about so that we can mimic the browser cookie state
*
* @param seleniumCookieSet
* @return
*/
private HttpState mimicCookieState(Set<org.openqa.selenium.Cookie> seleniumCookieSet) {
HttpState mimicWebDriverCookieState = new HttpState();
for (org.openqa.selenium.Cookie seleniumCookie : seleniumCookieSet) {
Cookie httpClientCookie = new Cookie(seleniumCookie.getDomain(), seleniumCookie.getName(), seleniumCookie.getValue(), seleniumCookie.getPath(), seleniumCookie.getExpiry(), seleniumCookie.isSecure());
mimicWebDriverCookieState.addCookie(httpClientCookie);
}
return mimicWebDriverCookieState;
}
/**
* Mimic the WebDriver host configuration
*
* @param hostURL
* @return
*/
private HostConfiguration mimicHostConfiguration(String hostURL, int hostPort) {
HostConfiguration hostConfig = new HostConfiguration();
hostConfig.setHost(hostURL, hostPort);
return hostConfig;
}
public String fileDownloader(WebElement element) throws Exception {
return downloader(element, "href");
}
public String imageDownloader(WebElement element) throws Exception {
return downloader(element, "src");
}
public String downloader(WebElement element, String attribute) throws Exception {
//Assuming that getAttribute does some magic to return a fully qualified URL
String downloadLocation = element.getAttribute(attribute);
if (downloadLocation.trim().equals("")) {
throw new Exception("The element you have specified does not link to anything!");
}
URL downloadURL = new URL(downloadLocation);
HttpClient client = new HttpClient();
client.getParams().setCookiePolicy(CookiePolicy.RFC_2965);
client.setHostConfiguration(mimicHostConfiguration(downloadURL.getHost(), downloadURL.getPort()));
client.setState(mimicCookieState(driver.manage().getCookies()));
HttpMethod getRequest = new GetMethod(downloadURL.getPath());
FileHandler downloadedFile = new FileHandler(downloadPath + downloadURL.getFile().replaceFirst("/|\\\\", ""), true);
try {
int status = client.executeMethod(getRequest);
LOGGER.info("HTTP Status {} when getting '{}'", status, downloadURL.toExternalForm());
BufferedInputStream in = new BufferedInputStream(getRequest.getResponseBodyAsStream());
int offset = 0;
int len = 4096;
int bytes = 0;
byte[] block = new byte[len];
while ((bytes = in.read(block, offset, len)) > -1) {
downloadedFile.getWritableFileOutputStream().write(block, 0, bytes);
}
downloadedFile.close();
in.close();
LOGGER.info("File downloaded to '{}'", downloadedFile.getAbsoluteFile());
} catch (Exception Ex) {
LOGGER.error("Download failed: {}", Ex);
throw new Exception("Download failed!");
} finally {
getRequest.releaseConnection();
}
return downloadedFile.getAbsoluteFile();
}
}