3

I am trying to download a .pdf to my local so that I can use Apache PDFBox to read the text from it and verify it as a part of my test suite. I have already found some code to download the pdf from Firefox by hitting a URL. This does not work for me since the pdf I am working with is a confidential document so it is not exposed by a URL, instead loaded within PDF Viewer as a popup window. Does anyone know how to hit the download button within the Firefox PDF Viewer after I have loaded the PDF Viewer in the browser?

enter image description here

I have tried looking it up by the element's id which = "download":

(new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("download")));
driver.findElement(By.id("download")).click(); 

Unfortunately this does not work as it says it cannot find the element. Anyone know a workaround?

UPDATE: The pop-up window I described was an iframe element. This caused the inability to find the "download" element. Fixed with @4M01's switchTo() answer.

code_disciple1
  • 121
  • 1
  • 11

4 Answers4

1

As you mentioned,

instead loaded within PDF Viewer as a popup window

You need to handle switching between different windows using switchTo() method of the driver object.

Below code working fine for me without an issue and I'm able to click on download icon.

public class FirefoxPDFTest {
      WebDriver driver;

    @BeforeClass
    void Setup(){
        System.setProperty("webdriver.gecko.driver", "C:\\Automation\\Selenium\\drivers\\geckodriver.exe");
        driver = new FirefoxDriver();
        driver.manage().window().maximize();
    }

    @Test
    void downloadPDF(){
        driver.get("http://www.pdf995.com/samples/pdf.pdf");
        waitTillPageLoad();
        driver.findElement(By.id("download")).click();
    }



    private void waitTillPageLoad(){
        new WebDriverWait(driver, 30).until(driver -> ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));
    }


    @AfterClass
    void tearDown(){
        driver.close();
        driver.quit();
    }

}
Amol Chavan
  • 3,835
  • 1
  • 21
  • 32
  • I understood that, in your case you have to `switch()` to the pop-up browser first and then click on the download icon present in Firefox browser. Even after doing that PDF would not get downloaded right away. You have to make some setting which would help you to download the PDF directly. Those setting are mentioned by @zsbappa. – Amol Chavan Sep 28 '17 at 17:56
  • Also your question was, Selenium was throwing an exception because element was not found. Actually there are *no challenges in finding element*, but you have not switched to pop-up window where your confidential document was opened. – Amol Chavan Sep 28 '17 at 18:00
  • 1
    Sorry, I deleted my comment when I realized. Your answer fixed my problem thanks! I created a Robot (java.awt) to hit the OK button after it asked whether I wanted to save or open file, but it worked like charm. Had to make sure to switchTo.defaultContent() after as well. I would think that I wouldn't have to create the robot by changing the preference "browser.helperApps.neverAsk.saveToDisk". – code_disciple1 Sep 28 '17 at 18:29
  • Glad it helped you :-) – Amol Chavan Sep 28 '17 at 19:15
1

just use following code for clicking download button:

    driver.findElement(By.xpath("//button[@id='download']")).click();

    Thread.sleep(8000);

    Robot robot = new Robot();

    robot.keyPress(KeyEvent.VK_ENTER);
    robot.keyRelease(KeyEvent.VK_ENTER);
Kushal Bhalaik
  • 3,349
  • 5
  • 23
  • 46
  • Unfortunately it can't findElement directly as you suggest. The reason is it's not finding the "download" element (by id nor xpath) was because it was within an iframe. I had to driver.switchTo().frame("nameOfMyFrame") and then driver.switchTo().defaultContent(), after I was done. So this findElement strategy doesn't work for my case. Although the Robot stuff worked fine thanks! – code_disciple1 Sep 28 '17 at 18:37
1

We can handle the download popup in Firefox browser using Firefox browser settings and Firefox Profile setting using WebDriver.

Step 1: Update the setting in Firefox browser.

Open Firefox browser and navigate to Tools -> Options Navigate to Applications. Set the Action type as ‘Save File’ for PDF.

Step 2: Initialize FireFoxDriver using FirefoxProfile

File downloadsDir = new File("");

// Set Preferences for FirefoxProfile.
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("browser.download.folderList", 2);
profile.setPreference("browser.download.dir", downloadsDir.getAbsolutePath());
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("browser.helperApps.neverAsk.saveToDisk",
      "application/msword, application/csv, application/ris, text/csv, image/png, application/pdf, text/html, text/plain, application/zip, application/x-zip, application/x-zip-compressed, application/download, application/octet-stream");
profile.setPreference("browser.download.manager.showWhenStarting", false);
profile.setPreference("browser.download.manager.focusWhenStarting", false);
profile.setPreference("browser.download.useDownloadDir", true);
profile.setPreference("browser.helperApps.alwaysAsk.force", false);
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("browser.download.manager.closeWhenDone", true);
profile.setPreference("browser.download.manager.showAlertOnComplete", false);
profile.setPreference("browser.download.manager.useWindow", false);
profile.setPreference("services.sync.prefs.sync.browser.download.manager.showWhenStarting", false);
profile.setPreference("pdfjs.disabled", true);

// Initialize the FireFoxDriver instance.
FirefoxDriver webDriver = new FirefoxDriver(profile);

Step 3: Execute the Script

Execute the script which clicks on the download PDF icon.

Result: PDF file will be downloaded and the Download popup will not be displayed.

Zakaria Shahed
  • 2,589
  • 6
  • 23
  • 52
  • For Step 1, I am trying to achieve this automatically within the java code instead of manually. Is this possible? My [research](https://stackoverflow.com/questions/12146403/disable-firefox-save-as-dialog-selenium) says you should be able to change this with your "browser.helperApps.neverAsk.saveToDisk" setPreference method call but this doesn't seem to work. – code_disciple1 Sep 28 '17 at 18:40
  • Sorry with the preferences set the way you posted I can't even get the pdf viewer to load the pdf. I identified the specific line that breaks it for me which is the ("pdfjs.disabled","true"). This is using the [driver.get("http://www.pdf995.com/samples/pdf.pdf")] page – code_disciple1 Sep 28 '17 at 18:53
  • 1
    After some more testing I understand what you intended now. These two lines from what you posted is what I used. profile.setPreference("pdfjs.disabled", true); profile.setPreference("browser.helperApps.neverAsk.saveToDisk","application/pdf"). The first one disabled the pdf viewer (like you intended), and the second one disabled the prompt. Without clicking on an element I was able to download the pdf. I'm not sure how to get it to work with my iframe issue but with a straight up pdf URL this works great thanks! – code_disciple1 Sep 28 '17 at 19:02
0

You can handle the download icon (using Firefox), by using the following (C#) code:

IWebElement element = Driver.FindElement(By.Id("download"));
IJavaScriptExecutor executor = (IJavaScriptExecutor)Driver;
executor.ExecuteScript("arguments[0].click();", element);