9

I have to automate a case in which I have to download an Excel file using Selenium IDE.I have done this in Firefox by using custom profile feature which automatically downloads file and saves it into a user-defined folder. To do the same in Internet Explorer (IE), is there anything in IE like custom profile and preferences? how do I prompt IE to automatically download a file? I am using Java for automation. Kindly help.

*If you guys use java selenium, this article will be useful

Selenium WebDriver で IE11/Edge のファイルダウンロードを自動化する (IE11/Edge file download process automation by Selenium WebDriver) https://qiita.com/VA_nakatsu/items/633226898cba4cff564e

1
  • WebElement link = driver.findElement(By.xpath("myxpath")); In the above line of code which xpath are you passing for myxpath?
    – Prabhanjan
    Commented Aug 18, 2017 at 8:05

4 Answers 4

9

Link to my blog where I discuss this in more detail.

Inconsistencies here, are you using Selenium IDE or WebDriver with Java?

Assuming you are using WebDriver with Java and not Selenium IDE(as you state in your post) You can try using:

/*
 * Copyright (c) 2010-2012 Lazery Attack - http://www.lazeryattack.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.selenium.filedownloader;

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Set;

public class FileDownloader {

    private static final Logger LOG = Logger.getLogger(FileDownloader.class);
    private WebDriver driver;
    private String localDownloadPath = System.getProperty("java.io.tmpdir");
    private boolean followRedirects = true;
    private int httpStatusOfLastDownloadAttempt;

    public FileDownloader(WebDriver driverObject) {
        this.driver = driverObject;
    }

    /**
     * Specify if the FileDownloader class should follow redirects when trying to download a file
     *
     * @param value
     */
    public void followRedirectsWhenDownloading(boolean value) {
        this.followRedirects = value;
    }

    /**
     * Get the current location that files will be downloaded to.
     *
     * @return The filepath that the file will be downloaded to.
     */
    public String localDownloadPath() {
        return this.localDownloadPath;
    }

    /**
     * Set the path that files will be downloaded to.
     *
     * @param filePath The filepath that the file will be downloaded to.
     */
    public void localDownloadPath(String filePath) {
        this.localDownloadPath = filePath;
    }

    /**
     * Download the file specified in the href attribute of a WebElement
     *
     * @param element
     * @return
     * @throws Exception
     */
    public String downloadFile(WebElement element) throws Exception {
        return downloader(element, "href");
    }

    /**
     * Download the image specified in the src attribute of a WebElement
     *
     * @param element
     * @return
     * @throws Exception
     */
    public String downloadImage(WebElement element) throws Exception {
        return downloader(element, "src");
    }

    /**
     * Gets the HTTP status code of the last download file attempt
     *
     * @return
     */
    public int httpStatusOfLastDownloadAttempt() {
        return this.httpStatusOfLastDownloadAttempt;
    }

    /**
     * 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;
    }

    /**
     * Set the host configuration based upon the URL of the file/image that will be downloaded
     *
     * @param hostURL
     * @param hostPort
     * @return
     */
    private HostConfiguration setHostDetails(String hostURL, int hostPort) {
        HostConfiguration hostConfig = new HostConfiguration();
        hostConfig.setHost(hostURL, hostPort);

        return hostConfig;
    }

    /**
     * Perform the file/image download.
     *
     * @param element
     * @param attribute
     * @return
     * @throws IOException
     * @throws NullPointerException
     */
    private String downloader(WebElement element, String attribute) throws IOException, NullPointerException {
        String fileToDownloadLocation = element.getAttribute(attribute);
        if (fileToDownloadLocation.trim().equals("")) throw new NullPointerException("The element you have specified does not link to anything!");

        URL fileToDownload = new URL(fileToDownloadLocation);
        File downloadedFile = new File(this.localDownloadPath + fileToDownload.getFile().replaceFirst("/|\\\\", ""));
        if (downloadedFile.canWrite() == false) downloadedFile.setWritable(true);

        HttpClient client = new HttpClient();
        client.getParams().setCookiePolicy(CookiePolicy.RFC_2965);
        client.setHostConfiguration(setHostDetails(fileToDownload.getHost(), fileToDownload.getPort()));
        client.setState(mimicCookieState(this.driver.manage().getCookies()));
        HttpMethod getFileRequest = new GetMethod(fileToDownload.getPath());
        getFileRequest.setFollowRedirects(this.followRedirects);
        LOG.info("Follow redirects when downloading: " + this.followRedirects);

        LOG.info("Sending GET request for: " + fileToDownload.toExternalForm());
        this.httpStatusOfLastDownloadAttempt = client.executeMethod(getFileRequest);
        LOG.info("HTTP GET request status: " + this.httpStatusOfLastDownloadAttempt);
        LOG.info("Downloading file: " + downloadedFile.getName());
        FileUtils.copyInputStreamToFile(getFileRequest.getResponseBodyAsStream(), downloadedFile);
        getFileRequest.releaseConnection();

        String downloadedFileAbsolutePath = downloadedFile.getAbsolutePath();
        LOG.info("File downloaded to '" + downloadedFileAbsolutePath + "'");

        return downloadedFileAbsolutePath;
    }

}

It's quite easy to use, you just need to supply the WebElement of the Image/Hyperlink that you want to download, so instead of trying to perform a click on the WebElement you would instead pass it in to the FileDownloader Object:

FileDownloader downloadTestFile = new FileDownloader(driver);
driver.get(http://www.mysite.com/downloadPage.html");
WebElement downloadLink = driver.findElement(By.id("fileToDownload"));
String downloadedFileAbsoluteLocation = downloadTestFile.downloadFile(downloadLink);

This is all written in Java so it's cross browser/platform compliant.

Code On Github

5

I generally use keyboard shortcuts with Robot class in Java in order to emulate what I would do manually. In IE 8, saving a file would be three steps:

1) Click link  or Press Enter key on the link.
2) type S. 
3) Hit Enter.

I start with doing the same action manually for the first test case ie. save in a certain folder, cleanup the folder and click the checkbox for close this dialog once download finishes. Next, I use the following code :

WebElement link = driver.findElement(By.xpath("myxpath"));
clickAndSaveFileIE(link);


public static void clickAndSaveFileIE(WebElement element) throws InterruptedException{
    try {
            Robot robot = new Robot();
        //get the focus on the element..don't use click since it stalls the driver          
       element.sendKeys("");
       //simulate pressing enter            
      robot.keyPress(KeyEvent.VK_ENTER);
     robot.keyRelease(KeyEvent.VK_ENTER);
     //wait for the modal dialog to open            
    Thread.sleep(2000);
   //press s key to save            
   robot.keyPress(KeyEvent.VK_S);
   robot.keyRelease(KeyEvent.VK_S);
   Thread.sleep(2000);
  //press enter to save the file with default name and in default location
    robot.keyPress(KeyEvent.VK_ENTER);
    robot.keyRelease(KeyEvent.VK_ENTER);
 } catch (AWTException e) {

            e.printStackTrace();
        }
1
  • Robot class is handy while trying to support automation issues in Linux environments as AutoIt was not available Commented Jul 31, 2012 at 12:17
2

The trick to handle any dialogs is to use external tools like AutoIT to deal with the Upload dialog, download Dialog, and NTLM Authentication dialogs. Please note that this solution is intended only for users executing the scripts in Windows environment.

Using AutoIT you can write a simple script to get hold of the Save Dialog, this script can be then converted into an executable program with command line arguments to invoke it anytime from the program.

Following below steps should solve your issue.

  1. Download autoIT tool.
  2. Save the below-mentioned script to a save_dialog.au3 file in the system.
  3. Open "Compile Script to .exe" program from AutoIT setup Directory.
  4. mention the path to save_dialog.au3 and mention the path and name where you want to save .exe file. (lets say c:\save_ie_file.exe)
  5. if you are using Java to write your automation code, use below lines of your code just before you click "download link" or expect a download dialog.

  String[] dialog =  new String[]{ "C:\\save_ie_file.exe","Save to...","Save", "C:\\selenium_downloads\\" }; // path to exe, dialog title, save/cancel/run, path to save file.
  Process pp1 = Runtime.getRuntime().exec(dialog); // run the executable to wait for download link and process
  selenium.click("id=download_link"); // code to click on download link
  pp1.destroy(); // kill the process looking to download

save_dialog.au3 code blatantly Copied from here DISCLAIMER... I am not the author of that blog pointed in this answer:

 
    AutoItSetOption("WinTitleMatchMode","2") ; set the select mode to select using substring

    if $CmdLine[0] < 2 then
    ; Arguments are not enough
    msgbox(0,"Error","Supply all the arguments, Dialog title,Run/Save/Cancel and Path to save(optional)")
    Exit
    EndIf

    ; wait Until dialog box appears
    WinWait($CmdLine[1]) ; match the window with substring
    $title = WinGetTitle($CmdLine[1]) ; retrives whole window title
    WinActivate($title)

    If (StringCompare($CmdLine[2],"Run",0) = 0) Then
    WinActivate($title)
    ControlClick($title,"","Button1")
    EndIf

    If (StringCompare($CmdLine[2],"Save",0) = 0) Then

    WinWaitActive($title)
    ControlClick($title,"","Button2")
    ; Wait for the new dialogbox to open
    Sleep(2)
    WinWait("Save")
    $title = WinGetTitle("Save")
    ;$title = WinGetTitle("[active]")
    if($CmdLine[0] = 2) Then
    ;click on the save button
    WinWaitActive($title)
    ControlClick($title,"","Button2")
    Else
    ;Set path and save file
    WinWaitActive($title)
    ControlSetText($title,"","Edit1",$CmdLine[3])
    ControlClick($title,"","Button2")
    EndIf

    EndIf

    If (StringCompare($CmdLine[2],"Cancel",0) = 0) Then
    WinWaitActive($title)
    ControlClick($title,"","Button3")
    EndIf
1

Instead of using above code I used following code which show if we press "Alt+S" buttons together then internet explorer browser save the downloaded file But one important thing is that we can't use click button method here because the curser may stuck on that button so its very important to remember we have to use send keys method here for clicking button.

WebElement link = driver.findElement(By.xpath("myxpath"));
clickAndSaveFileIE(link);


public static void clickAndSaveFileIE(WebElement element) throws InterruptedException{
    try {
            Robot robot = new Robot();
        //get the focus on the element..don't use click since it stalls the driver          
       element.sendKeys("");
       //simulate pressing enter            
      robot.keyPress(KeyEvent.VK_ENTER);
     robot.keyRelease(KeyEvent.VK_ENTER);
     //wait for the modal dialog to open            
    Thread.sleep(2000);
   //press s key to save            
   robot.keyPress(KeyEvent.VK_ALT);
   robot.keyRelease(KeyEvent.VK_ALT);
   Thread.sleep(2000);
  //press enter to save the file with default name and in default location
    robot.keyPress(KeyEvent.VK_S);
    robot.keyRelease(KeyEvent.VK_S);
 } catch (AWTException e) {

            e.printStackTrace();
        }

Not the answer you're looking for? Browse other questions tagged or ask your own question.