Reputation: 303
I am trying to automate file download using Selenium.
Whenever a file is received for download, i want to save that particular file to custom location and save it with custom name.
I want browser to ask to save each file so that i can provide custom path and file name dynamically.
I am able to save the file to custom directory but i could not get control on the file name. I want to use java.awt.Robot
, java.awt.datatransfer.StringSelection
and java.awt.Toolkit
for using custom file name.
My code
ChromeOptions chromeOptions = new ChromeOptions();
HashMap<String, Object> chromePreferences = new HashMap<String, Object>();
chromePreferences.put("profile.default_content_settings.popups", 0);
chromePreferences.put("download.default_directory", browserDownloadDirectoryPath);
chromePreferences.put("safebrowsing.enabled", "true");
chromeOptions.setExperimentalOption("prefs", chromePreferences);
chromeOptions.addArguments("--test-type");
chromeDesiredCapabilities = DesiredCapabilities.chrome();
chromeDesiredCapabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
This is saving file to custom folder.
If the browser ask for file saving, i want to use Robot Class to send path.
StringSelection stringSelection = new StringSelection(
"<file path>" + "<file name>");
Toolkit.getDefaultToolkit().getSystemClipboard()
.setContents(stringSelection, null);
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
robot.keyPress(KeyEvent.VK_DOWN);
robot.keyRelease(KeyEvent.VK_DOWN);
robot.keyPress(KeyEvent.VK_DOWN);
robot.keyRelease(KeyEvent.VK_DOWN);
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
Kindly provide a solution to force browser to ask to save file.
For Firefox, we have about:config
to see all preferences for the browser. Do we have something like this for other browsers as well?
Upvotes: 0
Views: 8323
Reputation: 42518
A better way would be to setup chrome to automatically download the file, then wait for a new file to appear and finally rename it.
Here is an example to download a PDF by clicking on a link and then rename it to "mydocument.pdf" :
// define the download folder
Path download_folder = Paths.get(System.getProperty("user.home") + "/Downloads");
// define the preferences
HashMap<String, Object> prefs = new HashMap<String, Object>();
prefs.put("download.default_directory", download_folder.toAbsolutePath());
prefs.put("download.prompt_for_download", false);
prefs.put("download.directory_upgrade", true);
prefs.put("plugins.plugins_disabled", new String[]{"Chrome PDF Viewer"});
// define the options
HashMap<String, Object> options = new HashMap<String, Object>();
options.put("prefs", prefs);
// define the capabilities
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability("chromeOptions", options);
// start the driver
WebDriver driver = new ChromeDriver(capabilities);
// click on a PDF link
driver.get("http://www.adobe.com/legal/terms.html");
driver.findElement(By.linkText("Adobe Creative SDK")).click();
// wait for the PDF to be downloaded
File file = WaitForNewFile(download_folder, ".pdf", 60);
// rename the downloaded file
file.renameTo(download_folder.resolve("mydocument.pdf").toFile());
// quit
driver.quit();
And for the file waiter :
/**
* Waits for a new file to be downloaded with a file watcher
*/
public static File WaitForNewFile(Path folder, String extension, int timeout_sec) throws InterruptedException, IOException {
long end_time = System.currentTimeMillis() + timeout_sec * 1000;
try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
folder.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
for (WatchKey key; null != (key = watcher.poll(end_time - System.currentTimeMillis(), TimeUnit.MILLISECONDS)); key.reset()) {
for (WatchEvent<?> event : key.pollEvents()) {
File file = folder.resolve(((WatchEvent<Path>)event).context()).toFile();
if (file.toString().toLowerCase().endsWith(extension.toLowerCase()))
return file;
}
}
}
return null;
}
Upvotes: 6
Reputation: 2789
Set the desired capability for chrome browser.
String downloadFilepath = "your path to save file";
HashMap<String, Object> chromePrefs = new HashMap<String, Object>();
chromePrefs.put("profile.default_content_settings.popups", 0);
chromePrefs.put("download.default_directory", downloadFilepath);
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("prefs", chromePrefs);
DesiredCapabilities cap = DesiredCapabilities.chrome();
cap.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
cap.setCapability(ChromeOptions.CAPABILITY, options);
WebDriver driver = new ChromeDriver(cap);
Upvotes: 2