Selenium problems with PDF download in Firefox

…衆ロ難τιáo~ 提交于 2021-02-19 07:15:27

问题


I'm working on an upgrade of our internal Java Selenium framework to the latest version 3.14.0 in combination with Firefox 61.0 and Geckodriver 0.21.0.

I face problems when it comes to an automated download of a PDF file with Firefox. For example at this link there is a download button where I can let selenium perform a click on. Instead of downloading the pdf, a built-in viewer will be opened. The preference pdfjs.disabled should deactivate the viewer so created the driver instance with a profile (and also tried some more preferences).

FirefoxProfile firefoxProfile = new FirefoxProfile();
firefoxProfile.setAcceptUntrustedCertificates(true);
firefoxProfile.setAssumeUntrustedCertificateIssuer(true);
firefoxProfile.setPreference("browser.download.folderList", 2);
firefoxProfile.setPreference("network.cookie.cookieBehavior", 0);
firefoxProfile.setPreference("network.cookie.alwaysAcceptSessionCookies", true);
firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf");
firefoxProfile.setPreference("browser.helperApps.neverAsk.openFile", "application/pdf");
firefoxProfile.setPreference("browser.helperApps.alwaysAsk.force", false);
firefoxProfile.setPreference("browser.download.manager.showAlertOnComplete", false);
firefoxProfile.setPreference("browser.download.manager.showWhenStarting", false);
firefoxProfile.setPreference("browser.download.panel.shown", false);
firefoxProfile.setPreference("browser.download.manager.focusWhenStarting", false);
firefoxProfile.setPreference("browser.download.manager.closeWhenDone", false);
firefoxProfile.setPreference("browser.download.manager.useWindow", false);
firefoxProfile.setPreference("services.sync.prefs.sync.browser.download.manager.showWhenStarting", false);
firefoxProfile.setPreference("browser.download.manager.alertOnEXEOpen", false);
firefoxProfile.setPreference("pdfjs.disabled", true);

FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.setProfile(firefoxProfile);
WebDriver webdriver = new FirefoxDriver(firefoxOptions);

Unfortunately with the used Firefox version this config has no effect. Unless you change pdfjs.disabled to true at runtime within the about:config page. Only when first changed at runtime, the pdf viewer is really disabled. Seems to be a bug in Firefox. Ok anyway, I found a way to change this at runtime with selenium.

But now that the pdf viewer is skipped another popup is interrupting the download. Selenium is not even aware of this popup.

On the preferences page about:preferences under Applications I can see now that for the Content Type PDF document the Action was changed to nothing, which seems to be the same as Always ask. Before it was Preview in Firefox but it has to be Save File in order to reach my goal which is to immediately download the PDF without any questions.

Not with a single config you could possibly change this to "Save File". Am I wrong? But when I checked profile folders for differences I found out that there is a handlers.json that contains the settings from the picture above. It is read in during the browser startup and first adapted on browser close.
Normally selenium creates a new temporary profile folder for each new browser instance. If I want to have an influence on the desired setting, I need to define a custom profile. That was my thought. So I tried this:

firefoxOptions.addArguments("-profile", "/tmp/my.profile");

I think this is correct, but now yet another problem... becauses though Firefox creates the neccessary files in the given directory, the the communication between selenium and firefox fails. The browser window is opened and healthy, but Selenium is not able to start the session.

org.openqa.selenium.WebDriverException: connection refused 

            at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
            at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
            at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
            at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
            at org.openqa.selenium.remote.W3CHandshakeResponse.lambda$new$0(W3CHandshakeResponse.java:57)
            at org.openqa.selenium.remote.W3CHandshakeResponse.lambda$getResponseFunction$2(W3CHandshakeResponse.java:104)
            at org.openqa.selenium.remote.ProtocolHandshake.lambda$createSession$0(ProtocolHandshake.java:122)
            at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
            at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
            at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
            at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
            at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
            at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
            at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
            at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
            at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)
            at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:125)
            at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:73)
            at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:136)
            at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
            at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:548)
            at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:212)
            at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:130)
            at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:140)
            …

So the general question is:
How can I force Firefox (controlled by selenium) to download the PDF file to my file system when clicked on the button?
Any possibilities are reasonable.

As I am running out of ideas it would be great if somebody could help or at least confirm that these things are problems with Firefox.


回答1:


  1. close firefox
  2. run firefox profile manager (Win+R: firefox -p)
  3. create a new firefox profile called let's say selenium_profile
  4. run firefox in selenium_profile
  5. download manualy your desired PDF file and set up to always download such file types

To run webdriver with selenium_profile, use this:

public static void setUpClass() {
    FirefoxOptions options = new FirefoxOptions();
    ProfilesIni allProfiles = new ProfilesIni();         
    FirefoxProfile selenium_profile = allProfiles.getProfile("selenium_profile");
    options.setProfile(selenium_profile);
    options.setBinary("C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
    System.setProperty("webdriver.gecko.driver", "C:\\Users\\pburgr\\Desktop\\geckodriver-v0.20.0-win64\\geckodriver.exe");
    driver = new FirefoxDriver(options);
    driver.manage().window().maximize();}

Just edit paths.




回答2:


Add pdfjs.enabledCache.state to false.

FirefoxOptions options = new FirefoxOptions();
options.addPreference("browser.download.folderList", 2);
options.addPreference("browser.download.dir", pathToDownload);
options.addPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf");
options.addPreference("pdfjs.enabledCache.state",false); 
WebDriver driver = new FirefoxDriver(options);

Geckodriver Selenium Auto Download PDFs



来源:https://stackoverflow.com/questions/52208798/selenium-problems-with-pdf-download-in-firefox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!