如何处理Selenium中的打印对话框?

时间:2012-07-18 08:20:54

标签: java selenium webdriver

我必须处理打印对话框(在浏览器中单击ctrl-p时出现的对话框)。我尝试过:

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

但它不起作用。另外,我无法抓住它的窗口把手,因为它不是一个窗口......

是否可以处理这些对象以及如何处理?

8 个答案:

答案 0 :(得分:23)

不幸的是,WebDriver无法处理这些(或任何其他浏览器或操作系统对话框)。此外,它们在浏览器/系统/语言设置方面往往看起来不同,所以可能没有明确的答案。您需要检测并处理每种可能的情况,以使其在任何地方都能正常工作。您的选择包括:

  • Robot类,它允许您以编程方式“按下”键盘上的任何内容(或盲目地点击),从而通过按 Enter 或 Esc 。但是,如上所述,任何高级交互都依赖于OS /语言/打印机。

    // press Escape programatically - the print dialog must have focus, obviously
    Robot r = new Robot();
    r.keyPress(KeyEvent.VK_ESCAPE);
    r.keyRelease(KeyEvent.VK_ESCAPE);
    
  • AutoIt。它是一个Windows程序,可用于处理任何系统级自动化。与上述相同。

这或多或少。如果您可以避开打印对话框,请尝试截取页面并将其打印using standard Java tools

答案 1 :(得分:5)

一个CAN处理Chrome中的Selenium打印对话框。不确定其他浏览器。

ChromeDriver-2.17中添加了“访问打印”对话框。详细信息可以在这里找到: https://bugs.chromium.org/p/chromedriver/issues/detail?id=1087

右键单击“打印”对话框 - >检查元素。因此,“打印”对话框的DOM将在单独的窗口中打开。现在,您可以为对话框中的任何元素生成定位器,并在测试中使用它们。

要关闭“打印”对话框,可以执行以下操作:

//Switch to Print dialog
Set<String> windowHandles = driver.getWindowHandles();
if (!windowHandles.isEmpty()) {
    driver.switchTo().window((String) windowHandles.toArray()[windowHandles.size() - 1]);
}
//Now work with the dialog as with an ordinary page:  
driver.findElement(By.className("cancel")).click();

答案 2 :(得分:2)

Slanec的答案是正确的 - WebDriver没有本机功能。我在Windows中解决这个问题的方法是使用System.Windows.Forms.SendKeys对象:

    SendKeys.SendWait("^p");
    System.Threading.Thread.Sleep(500);
    SendKeys.SendWait("~");

    // give it a minute to spool onto the printer
    System.Threading.Thread.Sleep(5000);

我实际上已经在循环中打印了一堆语句。像魅力一样。

答案 3 :(得分:2)

我能够通过添加--kiosk-printing来解决此问题,它完全绕过了打印对话框。我将默认打印设置为pdf,因此我在“下载”文件夹中最终得到了pdf,但是至少硒没有挂起。代码如下所示:

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

答案 4 :(得分:1)

您可以在出现打印对话框后关闭浏览器。这无疑是一个有点激烈的措施,但优点是:

  • 很简单
  • 它不需要任何外部工具
  • 适用于操作系统和浏览器

请致电:

myWebDriver.quit();

通常,您将运行测试,并像往常一样检查要打印的页面上的元素。即使打印对话框已打开,WebDriver也可以检查页面元素。

完成后,退出浏览器(并为下一次测试启动一个新浏览器)。

我们在项目中成功使用了它。为了简化操作,我们编写了一个包装类,用于跟踪当前的WebDriver实例&#34;。我有方法来检索此实例(根据需要创建一个)并关闭它。这样,您始终可以调用getCurrentWebDriver()并获取有效实例(重复使用或新创建)。

答案 5 :(得分:1)

另一种选择是编辑Windows注册表以使Chrome禁用打印窗口。

-disable-print-preview-标志,将告知Chrome禁用打印预览

  1. 转到注册表编辑器
  2. 导航至“计算机\ HKEY_CLASSES_ROOT \ ChromeBHTML \ shell \ open \ command”
  3. 将值设置为: “ C:\ Program Files(x86)\ Google \ Chrome Beta \ Application \ chrome.exe” --disable-print-preview

此解决方案适用于我的具体情况。

答案 6 :(得分:0)

使用Selenium和Facebook WebDriver与Codeception,我遇到了同样的问题 - 测试场景将停止运行,因为打印对话框阻止了与页面的任何交互。

我最终没有在test环境中打开打印对话框(例如使用Symfony和Twig):

{# Selenium can't interact with the OS native print dialog. #}
{# Therefore, it's disabled in the test environment. #}
{% if app.environment != 'test' %}
    $(document).ready(function () {
        var orderShouldBePrinted = window.location.href.indexOf(
            'print=true'
        ) !== -1;

        if (orderShouldBePrinted) {
            window.print();
        }
    });
{% endif %}

这具有不停止测试的优点。但是,它不允许测试打印对话框实际出现。

作为冒烟测试,我添加了$I->seeInCurrentUrl('print=true');(因为此网址参数会触发window.print())。

答案 7 :(得分:0)

我试图从不允许“全部打印”的网站上的模式列表中打印100多个页面。因此,硒在理论上会自动帮助我。 我为打印对话框窗口提出了一个完全非传统的解决方案。

##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()

当打印对话框窗口打开时,硒通常会被卡住,以等待发生某些事情。我使用了最近学到的“线程”技术,这使我可以在技术上同时做两件事。我要求单击以在4秒钟内启动(推动功能),然后紧接着Selenium会单击网站的打印按钮。当Selenium打开打印对话框窗口时,它停滞不前,但是延迟的单击仍在运行,并且在硒打开打印窗口4秒钟后等待单击。然后单击将执行,并且硒将重新获得控制权,因为已处理了打印窗口。