Reputation: 1499
I am trying to Save as pdf using the print dialog, a web page where I have already logged on using Selenium and Headless Chrome (v81). All the articles state I should be able to print/save the document as pdf using kiosk mode where the print to pdf happens automatically so the preview dialog is surpressed e.g.
I cannot get Chrome to default to saving as a PDF when using Selenium Selenium Chrome save as pdf change download folder
So far I have the following code:
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.AddArguments("--headless", "--disable-infobars", "--disable-extensions", "--test-type", "--allow-insecure-localhost", "--ignore-certificate-errors", "--ignore-ssl-errors=yes", "--disable-gpu", "--kiosk-printing", "--allow-running-insecure-content");
chromeOptions.AcceptInsecureCertificates = acceptInsecureCertificates;
chromeOptions.UnhandledPromptBehavior = UnhandledPromptBehavior.Ignore;
chromeOptions.AddUserProfilePreference("print.always_print_silent", true);
chromeOptions.AddUserProfilePreference("download.default_directory", @"C:\Temp");
chromeOptions.AddUserProfilePreference("savefile.default_directory", @"C:\Temp");
chromeOptions.AddUserProfilePreference("download.prompt_for_download", false);
chromeOptions.AddUserProfilePreference("printing.default_destination_selection_rules", "{\"kind\": \"local\", \"namePattern\": \"Save as PDF\"}");
chromeOptions.AddUserProfilePreference("printing.print_preview_sticky_settings.appState", "{\"recentDestinations\": [{\"id\": \"Save as PDF\", \"origin\": \"local\", \"account\": \"\" }],\"version\":2,\"isGcpPromoDismissed\":false,\"selectedDestinationId\":\"Save as PDF\"}");
webDriver = new ChromeDriver(ChromeDriverService.CreateDefaultService(), chromeOptions, TimeSpan.FromMinutes(timeoutMinutes));
Then I print the page using this:
var driver = FeatureContext.Current.GetWebDriver();
driver.ExecuteJavaScript("window.print();");
But I get the print preview dialog, always and my default printer is set and not Save as PDF.
I would use the chrome command line however for the fact I need to be logged on to the site. What is wrong with the code above?
Upvotes: 5
Views: 3560
Reputation: 346
Update 20/05/2022 : With Selenium 4, now is possible "Save to PDF" more easly. With one condition : Your application needs to run in headless mode if not, the Selenium will throw a exception PrintToPDF is only supported in headless mode
. But If some reason, you cant run in headless mode, my previous reply still working.
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;
using System.IO;
private static ChromeOptions _chromeOptions;
private static WebDriver _driver;
private static string fileName = "MyPrint";
private static string printFinalPath = Path.Combine($@"C:\Users\{Environment.UserName}\Downloads", string.Concat(fileName, ".pdf"));
static void Main(string[] args)
{
_chromeOptions = new ChromeOptions();
_chromeOptions.AddArguments("headless"); //your chrome driver needs run in headless!
//creating webdriver
_driver = new ChromeDriver(_chromeOptions);
//go to the website
_driver.Navigate().GoToUrl("https://www.google.com/");
//defining configurations for de printing
PrintOptions printOptions = new PrintOptions
{
Orientation = PrintOrientation.Portrait
};
//printing...
PrintDocument printDocument = _driver.Print(printOptions);
//saving the file
printDocument.SaveAsFile(printFinalPath);
}
Original reply Selenium 4, has some new features like, "Executing Command" via ChromeDevTools. With this feature, we can call something like "PdfAsync" directly from chrome (like Puppersharp, but using selenium). But unfortunately, we don't have this option enable yet in c#. 'Print-pdf' will be more easy in the future.
However, using selenium 3.141.0, doing some searching in topics from web, I solved this problem with help of your code. I have some problems to convert strings C# to json object.
Use Logging in chrome, to help.
Update 27/07/2021 : Unfortunately, using argument "headless" the "window.print()" will not work.
My final code is :
public class Program
...
static void Main(string[] args)
{
private static IWebDriver _driver;
private static ChromeOptions _chromeOptions;
private static ChromeDriverService _chromeService;
private static string pathLogChromeDriver = "chrome_driver_logs";
private static string nameFileLog = "chromedriver.log";
//creating chrome service, to logging
_chromeService = ChromeDriverService.CreateDefaultService(".");
//using to see the modifications in google chrome arguments
_chromeService.LogPath = Path.Combine(Directory.GetCurrentDirectory(), pathLogChromeDriver, nameFileLog);
_chromeService.EnableVerboseLogging = true;
//creating chromeOptions, to set the profile preferences
_chromeOptions = new ChromeOptions();
//using Dictionary to pass parameter name (string) and json object to AddUserProfilePreference.
Dictionary<string, object> prefs = new Dictionary<string, object>();
prefs.Add("downloadFile", "{\"recentDestinations\": [{\"id\": \"Save as PDF\", \"origin\": \"local\", \"account\": \"\" }],\"version\":2,\"isGcpPromoDismissed\":false,\"selectedDestinationId\":\"Save as PDF\"}");
prefs.Add("pathFinalFile", "C:\\Users\\" + Environment.UserName + "\\Downloads\\");
//using the dictionary values to set the parameters
_chromeOptions.AddUserProfilePreference("printing.print_preview_sticky_settings.appState", prefs["downloadFile"])
_chromeOptions.AddUserProfilePreference("savefile.default_directory", prefs["pathFinalFile"]);
//disable 'chrome is being controlled by automated test software' bar
_chromeOptions.AddUserProfilePreference("useAutomationExtension", false);
_chromeOptions.AddExcludedArgument("enable-automation");
//using --kiosk-printing to enable "silent printing"
_chromeOptions.AddArgument("--kiosk-printing");
//creating webdriver
_driver = new ChromeDriver(_chromeService, _chromeOptions);
_driver.Navigate().GoToUrl("https://applitools.com/blog/selenium-4-chrome-devtools/");
_driver.Manage().Window.Maximize();
//run javascript to print
_driver.ExecuteJavaScript("window.print();");
//is done!
}
If window "Save As" still open, some argument is incorrect.
Upvotes: 4