2

Below code I have try to download PDF from chrome browser using selenium.

public static void main(String args[]) throws InterruptedException, AWTException, IOException, DocumentException {

    System.setProperty("webdriver.chrome.driver", "/home/sejalj/OtherProj/webDrivers/chromedriver_64");
    ChromeOptions ChromeOptions = new ChromeOptions();
    ChromeOptions.addArguments("--headless", "window-size=1024,768", "--no-sandbox");

    WebDriver driver = new ChromeDriver(ChromeOptions);

    String baseUrl = "http://url.com/";

    driver.get(baseUrl);

    driver.findElement(By.name("wl_user_name")).sendKeys("uname");
    driver.findElement(By.name("wl_user_password")).sendKeys("password");
    driver.findElement(By.cssSelector("input[value=Login]")).click();

    String pdfUrl = "https://www.pdfurl.com/displayImageDocs.php?
    f=MjAxODA3MjQxMDUwNzA4Ni5QREY=&p=aW1hZ2UuaW1hZ2ViYW5rLmJsdsaddhbmsxLjIwMTgwNy4yMDE4MDcyNA==&a=MTAwMjM0&POL_NUM=AAS06036999";";

    // Opens pdf of specific URL
    driver.get(pdfUrl);     

    Actions a = new Actions(driver);

    // To press CTRL+S
    a.keyUp(Keys.CONTROL).sendKeys("s").build().perform();

    Robot robot = new java.awt.Robot();     
    robot.keyPress(KeyEvent.VK_BACK_SPACE);     
    robot.keyRelease(KeyEvent.VK_BACK_SPACE);
    int keyInput[] = {KeyEvent.VK_A, KeyEvent.VK_A, KeyEvent.VK_A, KeyEvent.VK_A, KeyEvent.VK_UNDERSCORE,
                      KeyEvent.VK_P, KeyEvent.VK_O, KeyEvent.VK_L, KeyEvent.VK_I, KeyEvent.VK_C, KeyEvent.VK_Y
                     };

    for (int i = 0; i < keyInput.length; i++) {
          robot.keyPress(keyInput[i]);
          robot.keyRelease(keyInput[i]);
    }

    // To press ENTER
    robot.keyPress(KeyEvent.VK_ENTER);
    Thread.sleep(1000);
    robot.keyRelease(KeyEvent.VK_ENTER);

    System.out.println("Preparing Policies document...Please wait");
    System.out.println("Document prepared..");
}

Above code working fine while chrome run without --headless mode. But in --headless mode above code not working.

Robot class does not support in headless mode. Please guide.

Solution that has been mark as working can be found here: Download files in Java, Selenium using ChromeDriver and headless mode

Infern0
  • 2,565
  • 1
  • 8
  • 21
hrdkisback
  • 898
  • 8
  • 19

2 Answers2

0

Try this one and remove code after driver.get(pdfUrl);
this may help you using HashMap of string with objects,

<-- language: lang-java -->

HashMap<String, Object> prefs = new HashMap<>();        
prefs.put("plugins.always_open_pdf_externally", true);
ChromeOptions.setExperimentalOption("prefs", prefs);
Mark
  • 5,994
  • 5
  • 42
  • 55
Prashant Palve
  • 132
  • 2
  • 11
0

I got the solution after referring the below link: Download files in Java, Selenium using ChromeDriver and headless mode

Here is the working code to download PDF file in headless mode.

public static void main(String args[]) throws InterruptedException, AWTException, IOException, DocumentException {

    System.setProperty("webdriver.chrome.driver", "/home/OtherProj/webDrivers/chromedriver_64");
    
    String downloadPath = "/home/Downloads/AAAA/";
    File file = new File(downloadPath);
    if(!file.exists())
        file.mkdirs();
    
    ChromeOptions chromeOptions = new ChromeOptions();
    
    HashMap<String, Object> prefs = new HashMap<>();        
    prefs.put("plugins.always_open_pdf_externally", true);

    chromeOptions.addArguments("--test-type");
    chromeOptions.addArguments("--disable-extensions");
    chromeOptions.setExperimentalOption("prefs", prefs);
    chromeOptions.setHeadless(true);
    
    String pdfUrl = "https://www.dummyurl.com/prod/displayImageDocs.php?f=MjAxODsafdfgsdjhgsjkA3MjQxMDUwNzA4Ni5QREY=&p=aW1hZ2UuaW1hZ2ViYW5rLmJhbmsxLjIwMTgwNy4yMDE4MDcyNA==&a=MTAwMsgsdjM0&POL_NUM=AAS06036999";
    
    ChromeDriverService driverService = ChromeDriverService.createDefaultService();
    WebDriver driver = new ChromeDriver(driverService, chromeOptions);

    // Saves the file on the given path
    PDFDemo.downloadFile(downloadPath, driverService, driver, pdfUrl);
    logger.debug("File Downloded Start");
        
    long fileSizeOne;
    long fileSizeTwo;

    do {

           File downlodedFolder = new File(downloadPath);
           File downlodedFile = downlodedFolder.listFiles()[0];

           fileSizeOne = downlodedFile.length();
           logger.debug("fileSizeOne " + fileSizeOne);
           Thread.sleep(1500);
           fileSizeTwo = downlodedFile.length();
           logger.debug("fileSizeTwo " + fileSizeTwo);
    } while (fileSizeTwo != fileSizeOne);

    logger.debug("File Downloded Completed");       
    System.out.println("Document Downloaded..");
}

private static void downloadFile(String downloadPath, ChromeDriverService driverService, WebDriver driver, String pdfUrl) throws ClientProtocolException, IOException, InterruptedException {
    
    Map<String, Object> commandParams = new HashMap<>();
    commandParams.put("cmd", "Page.setDownloadBehavior");
    Map<String, String> params = new HashMap<>();
    params.put("behavior", "allow");
    params.put("downloadPath", downloadPath);
    commandParams.put("params", params);
    HttpClient httpClient = HttpClientBuilder.create().build();

    ObjectMapper objectMapper = new ObjectMapper();
    String command = objectMapper.writeValueAsString(commandParams);        
    String u = driverService.getUrl().toString() + "/session/" + ((RemoteWebDriver) driver).getSessionId() + "/chromium/send_command";
    HttpPost request = new HttpPost(u);
    request.addHeader("content-type", "application/pdf");
    request.setEntity(new StringEntity(command));
    httpClient.execute(request);

    // Opens pdf of specific URL
    driver.get(pdfUrl);
}
hrdkisback
  • 898
  • 8
  • 19
  • Where you defined the url of file to download ? for example if I click on button download like this, how I can use httpPost ? Actions actions = new Actions(driver); WebElement element = driver.findElement(By.id("downloadPDF")); actions.moveToElement(element).click().perform(); – Molina Henrique Jun 09 '20 at 15:19
  • After `HttpPost` you need to click that btn, So here you need to put your click btn logic `Actions actions = new Actions(driver); WebElement element = driver.findElement(By.id("downloadPDF")); actions.moveToElement(element).click().perform();` after `HttpPost` instead of `driver.get(pdfUrl);`. So it'll start download the pdf on `downloadPath` location. – hrdkisback Jun 10 '20 at 06:18
  • Thanks @hrdkistback, it's working fine! Curiosity, when the download is large file, and differents times to conclude is 5 min left to finish or 10minute left to finish... How I Can monitoring dynamicly ?The selenium can waiting the downloading finished ? – Molina Henrique Jun 24 '20 at 12:44
  • @MolinaHenrique I am verifying the downloading complete by comparing file size. Please check my above updated answer. check code after `logger.debug("File Downloded Start");` – hrdkisback Jun 26 '20 at 06:42
  • Good solution! hrdkisback thks !! you already had experienced in Task schedule on Windows server, in which selenium to do download, without the user using it at the moment? If only set up at options.setHeadless (true); solve this situation? – Molina Henrique Jul 01 '20 at 12:33
  • Do you mean run chrome in headless mode? – hrdkisback Jul 03 '20 at 05:53