How to handle print dialog in Selenium?

Viewed 49951

I have to handle print dialog (the same one that appears when clicking ctrl-p in browser). I tried with:

Alert printDialog = driver.switchTo().alert();
printDialog.dismiss();

but it didn't work. Also I couldn't catch its window handle, because it's not a window...

Is it possible to handle these objects and how?

8 Answers

I was able to resolve this issue by adding --kiosk-printing which bypasses the print dialog completely. I have my default print set to pdf, so I end up with a pdf in my Downloads folder, but at least selenium doesn't hang. Here's what the code looks like:

        ChromeOptions cOptions = new ChromeOptions();
        cOptions.addArguments("kiosk-printing");
        RemoteWebDriver driver = new RemoteWebDriver(hostUrl, cOptions);

Another option could be to edit Windows registry for Chrome to disable print window.

--disable-print-preview - flag that will tell Chrome to disable print preview

  1. Go to Registry Editor
  2. Navigate to "Computer\HKEY_CLASSES_ROOT\ChromeBHTML\shell\open\command"
  3. Set value to be: "C:\Program Files (x86)\Google\Chrome Beta\Application\chrome.exe" --disable-print-preview

This solution worked for my specific case.

I was trying to print 100+ pages from a patterned list on a website that did not allow for a 'print-all'. So selenium would help me with this automatically in theory. I came up with a completely unorthodox solution to the print dialog window.

##Python code
import time
import threading
from pynput.mouse import Button, Controller
mouse = Controller()

##selenium starting up website stuff here

def website_print_button():
    browser.find_element_by_id('printButton').click()

def push():
    time.sleep(4)    #4 second delay to give the computer time to open print dialog
    mouse.position = [1131, 733] #where my print button is located
    mouse.click(Button.left, 1)

def letsgo():

    for x in range(printing_amount):
        browser.find_element_by_xpath('/html/body/div[1]/form/table[4]/tbody/tr['+str(x+1)+']/td[1]/a/b').click()
        browser.find_element_by_css_selector('ul.light-green.button').click()
        browser.switch_to.window(browser.window_handles[1])
        t2 = threading.Thread(target=push)
        t2.start()
        t1 = threading.Thread(target=website_print_button)
        t1.start()
        time.sleep(5)
        browser.close()
        browser.switch_to.window(browser.window_handles[0])
        browser.find_element_by_class_name('c').click()

Selenium would usually get stuck waiting for something to happen when the print dialog window opened up. I used something I recently learned called 'Threading' and this allowed me to do two things at once technically. I would call for a click to initiate in 4 seconds (push function) and then immediately after, Selenium would click on the websites print button. When Selenium opened up the print dialog window, it became stuck waiting around, but the delayed click was still running and waiting to click after 4 seconds of selenium opening the print window. Then the click would execute, and selenium retook control because the print window was taken care of.

Related